xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Julien Grall <julien.grall@linaro.org>
To: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>,
	patches@linaro.org, ian.campbell@citrix.com,
	xen-devel@lists.xen.org
Subject: Re: [PATCH 5/5] xen/arm: Only enable physical IRQs when the guest asks
Date: Tue, 25 Jun 2013 17:55:20 +0100	[thread overview]
Message-ID: <51C9CB78.9060502@linaro.org> (raw)
In-Reply-To: <alpine.DEB.2.02.1306251433090.4782@kaball.uk.xensource.com>

On 06/25/2013 05:19 PM, Stefano Stabellini wrote:

> On Tue, 25 Jun 2013, Julien Grall wrote:
>> If the guest VCPU receives an interrupts when it's disabled, it will throw
>                                    ^interrupt
> 
>> away the IRQ with EOIed it.
> 
> What does this mean? I cannot parse the sentence.

"it will throw away the IRQ without EOIing".

> 
>> This is result to lost IRQ forever.
>> Directly EOIed the interrupt doesn't help because the IRQ could be fired
>> again and result to an infinited loop.
>>
>> It happens during dom0 boot on the versatile express TC2 with the ethernet
>> card.
>>
>> Let the interrupt disabled when Xen setups the route and enable it when Linux
>> asks to enable it.
> 
> Is the problem that Xen keeps the interrupt enabled even when Linux
> disables it at the gic level? Is this what this patch is trying to
> address?

This patch only delays the physical IRQ activation until Linux will
enable it. This patch avoids to lose IRQ when a VCPU is disabled.

I tried to also disable the IRQ when Linux asks to disable it but the
versatile express platform hang.

> 
>> Signed-off-by: Julien Grall <julien.grall@citrix.com>
>> ---
>>  xen/arch/arm/domain_build.c |   14 ++++++++++++++
>>  xen/arch/arm/gic.c          |   25 +++++++++++++++++++++++--
>>  xen/arch/arm/vgic.c         |    7 +++----
>>  xen/include/asm-arm/gic.h   |    4 ++++
>>  xen/include/asm-arm/irq.h   |    6 ++++++
>>  5 files changed, 50 insertions(+), 6 deletions(-)
>>
>> diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
>> index f5befbd..0470a2d 100644
>> --- a/xen/arch/arm/domain_build.c
>> +++ b/xen/arch/arm/domain_build.c
>> @@ -408,6 +408,20 @@ static int map_device(struct domain *d, const struct dt_device_node *dev)
>>          }
>>  
>>          DPRINT("irq %u = %u type = 0x%x\n", i, irq.irq, irq.type);
>> +
>> +        /*
>> +         * Only map SGI interrupt in the guest as XEN won't handle
>> +         * it correctly.
>> +         * TODO: Fix it
>> +         */
>> +        if ( !irq_is_sgi(irq.irq) )
>> +        {
>> +            printk(XENLOG_WARNING "WARNING: Don't map irq %u for %s has "
>> +                   "XEN doesn't handle properly non-SGI interrupt\n",
>> +                   i, dt_node_full_name(dev));
> 
> do you mean SPI?
> 
> 
>> +            continue;
>> +        }
>> +
>>          /* Don't check return because the IRQ can be use by multiple device */
>>          gic_route_irq_to_guest(d, &irq, dt_node_name(dev));
>>      }
>> diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
>> index b16ba8c..e7d082a 100644
>> --- a/xen/arch/arm/gic.c
>> +++ b/xen/arch/arm/gic.c
>> @@ -179,6 +179,17 @@ static hw_irq_controller gic_guest_irq_type = {
>>      .set_affinity = gic_irq_set_affinity,
>>  };
>>  
>> +void gic_irq_enable(struct irq_desc *desc)
>> +{
>> +    spin_lock_irq(&desc->lock);
>> +    spin_lock(&gic.lock);
>> +
>> +    desc->handler->enable(desc);
>> +
>> +    spin_unlock(&gic.lock);
>> +    spin_unlock_irq(&desc->lock);
>> +}
> 
> This function looks a bit too similar to gic_irq_mask and friends,
> except that it takes two locks.
> 
> To make that obvious it's probably better to call it gic_irq_enable_safe
> or gic_irq_enable_locked.
> 
> 
>>  /* needs to be called with gic.lock held */
>>  static void gic_set_irq_properties(unsigned int irq, bool_t level,
>>          unsigned int cpu_mask, unsigned int priority)
>> @@ -543,8 +554,6 @@ static int __setup_irq(struct irq_desc *desc, unsigned int irq,
>>      desc->status &= ~IRQ_DISABLED;
>>      dsb();
>>  
>> -    desc->handler->startup(desc);
>> -
>>      return 0;
>>  }
>>  
>> @@ -560,6 +569,8 @@ int __init setup_dt_irq(const struct dt_irq *irq, struct irqaction *new)
>>  
>>      rc = __setup_irq(desc, irq->irq, new);
>>  
>> +    desc->handler->startup(desc);
>> +
>>      spin_unlock_irqrestore(&desc->lock, flags);
>>  
>>      return rc;
> 
> This two changes make it so guest irqs are not enabled by default, good.
> 
> 
>> @@ -711,6 +722,7 @@ void gic_inject(void)
>>          gic_inject_irq_start();
>>  }
>>  
>> +/* TODO: Handle properly non SGI-interrupt */
>>  int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
>>                             const char * devname)
>>  {
>> @@ -719,11 +731,18 @@ int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
>>      unsigned long flags;
>>      int retval;
>>      bool_t level;
>> +    struct pending_irq *p;
>> +    /* XXX: handler other VCPU than 0 */
>> +    struct vcpu *v = d->vcpu[0];
>>  
>>      action = xmalloc(struct irqaction);
>>      if (!action)
>>          return -ENOMEM;
>>  
>> +    /* XXX: Here we assume a 1:1 interrupt mapping between the host and dom0 */
>> +    BUG_ON(irq->irq >= (d->arch.vgic.nr_lines + NR_LOCAL_IRQS));
>> +    p = irq_to_pending(v, irq->irq);
>> +
>>      action->dev_id = d;
>>      action->name = devname;
>>      action->free_on_release = 1;
>> @@ -744,6 +763,8 @@ int gic_route_irq_to_guest(struct domain *d, const struct dt_irq *irq,
>>          goto out;
>>      }
>>  
>> +    p->desc = desc;
>> +
>>  out:
>>      spin_unlock(&gic.lock);
>>      spin_unlock_irqrestore(&desc->lock, flags);
>> diff --git a/xen/arch/arm/vgic.c b/xen/arch/arm/vgic.c
>> index cea9233..4f3d816 100644
>> --- a/xen/arch/arm/vgic.c
>> +++ b/xen/arch/arm/vgic.c
>> @@ -372,6 +372,9 @@ static void vgic_enable_irqs(struct vcpu *v, uint32_t r, int n)
>>          if ( !list_empty(&p->inflight) && !gic_irq_injected(irq) )
>>              gic_set_guest_irq(v, irq, GICH_LR_PENDING, p->priority);
>>  
>> +        if ( p->desc != NULL )
>> +            gic_irq_enable(p->desc);
>> +
>>          i++;
>>      }
>>  }
> 
> Should we add a gic_irq_disable call when the guest disables irqs?
> 
> 
>> @@ -685,10 +688,6 @@ void vgic_vcpu_inject_irq(struct vcpu *v, unsigned int irq, int virtual)
>>  
>>      n->irq = irq;
>>      n->priority = priority;
>> -    if (!virtual)
>> -        n->desc = irq_to_desc(irq);
>> -    else
>> -        n->desc = NULL;
>>  
>>      /* the irq is enabled */
>>      if ( rank->ienable & (1 << (irq % 32)) )
> 
> I don't quite understand why are you changing where the "desc"
> assignement is done.
> If it is a cleanup you shouldn't mix it with a patch like this that is
> supposed to fix a specific issue. Otherwise please explain why you need
> this change.
> 
> 
>> diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
>> index f9e9ef1..f7f3c1e 100644
>> --- a/xen/include/asm-arm/gic.h
>> +++ b/xen/include/asm-arm/gic.h
>> @@ -134,6 +134,7 @@
>>  
>>  #ifndef __ASSEMBLY__
>>  #include <xen/device_tree.h>
>> +#include <xen/irq.h>
>>  
>>  extern int domain_vgic_init(struct domain *d);
>>  extern void domain_vgic_free(struct domain *d);
>> @@ -154,6 +155,9 @@ extern void gic_inject(void);
>>  extern void gic_clear_pending_irqs(struct vcpu *v);
>>  extern int gic_events_need_delivery(void);
>>  
>> +/* Helper to enable an IRQ and take all the needed locks */
>> +extern void gic_irq_enable(struct irq_desc *desc);
>> +
>>  extern void __cpuinit init_maintenance_interrupt(void);
>>  extern void gic_set_guest_irq(struct vcpu *v, unsigned int irq,
>>          unsigned int state, unsigned int priority);
>> diff --git a/xen/include/asm-arm/irq.h b/xen/include/asm-arm/irq.h
>> index 80ff68d..346dc1d 100644
>> --- a/xen/include/asm-arm/irq.h
>> +++ b/xen/include/asm-arm/irq.h
>> @@ -46,6 +46,12 @@ int __init request_dt_irq(const struct dt_irq *irq,
>>                            void *dev_id);
>>  int __init setup_dt_irq(const struct dt_irq *irq, struct irqaction *new);
>>  
>> +#define FIRST_SGI_IRQ   32
>> +static inline bool_t irq_is_sgi(unsigned int irq)
>> +{
>> +    return (irq >= FIRST_SGI_IRQ);
>> +}
> 
> Aren't SGIs supposed to be between 0 and 15? Aren't you talking about
> SPIs here?

  reply	other threads:[~2013-06-25 16:55 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-24 23:04 [PATCH 0/5] Fix multiple issues with the interrupts on ARM Julien Grall
2013-06-24 23:04 ` [PATCH 1/5] xen/arm: Physical IRQ is not always equal to virtual IRQ Julien Grall
2013-06-25 13:16   ` Stefano Stabellini
2013-06-25 15:21     ` Julien Grall
2013-06-25 16:06       ` Ian Campbell
2013-06-24 23:04 ` [PATCH 2/5] xen/arm: Keep count of inflight interrupts Julien Grall
2013-06-25 16:12   ` Ian Campbell
2013-06-25 16:58     ` Stefano Stabellini
2013-06-25 17:46       ` Julien Grall
2013-06-25 18:38         ` Stefano Stabellini
2013-06-26 10:59           ` Ian Campbell
2013-06-26 11:10             ` Stefano Stabellini
2013-06-26 11:16               ` Ian Campbell
2013-06-26 10:58       ` Ian Campbell
2013-06-26 11:08         ` Stefano Stabellini
2013-06-26 11:15           ` Ian Campbell
2013-06-26 11:23             ` Stefano Stabellini
2013-06-26 11:41               ` Ian Campbell
2013-06-26 11:50                 ` Stefano Stabellini
2013-06-26 11:57                   ` Ian Campbell
2013-06-26 14:02                     ` Stefano Stabellini
2013-06-24 23:04 ` [PATCH 3/5] xen/arm: Don't reinject the IRQ if it's already in LRs Julien Grall
2013-06-25 13:24   ` Stefano Stabellini
2013-06-25 13:55     ` Julien Grall
2013-06-25 16:36       ` Stefano Stabellini
2013-06-25 16:46         ` Ian Campbell
2013-06-25 17:05           ` Stefano Stabellini
2013-06-26 10:53             ` Ian Campbell
2013-06-26 11:19               ` Stefano Stabellini
2013-06-25 16:48         ` Julien Grall
2013-06-25 16:59           ` Stefano Stabellini
2013-06-25 16:14     ` Ian Campbell
2013-06-24 23:04 ` [PATCH 4/5] xen/arm: Rename gic_irq_{startup, shutdown} to gic_irq_{mask, unmask} Julien Grall
2013-06-24 23:04 ` [PATCH 5/5] xen/arm: Only enable physical IRQs when the guest asks Julien Grall
2013-06-25 16:19   ` Stefano Stabellini
2013-06-25 16:55     ` Julien Grall [this message]
2013-06-25 17:07       ` Stefano Stabellini
2013-12-02 17:26     ` Ian Campbell
2013-12-02 17:37       ` Stefano Stabellini
2013-06-25 16:28   ` Ian Campbell
2013-06-25 17:38     ` Julien Grall
2013-06-25 18:27       ` Stefano Stabellini
2013-06-26 10:55       ` Ian Campbell
2013-06-26 13:03         ` Julien Grall
2013-07-31 13:08 ` [PATCH 0/5] Fix multiple issues with the interrupts on ARM Andrii Anisov
2013-07-31 14:00   ` Julien Grall

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=51C9CB78.9060502@linaro.org \
    --to=julien.grall@linaro.org \
    --cc=ian.campbell@citrix.com \
    --cc=julien.grall@citrix.com \
    --cc=patches@linaro.org \
    --cc=stefano.stabellini@eu.citrix.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 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).