All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@suse.com>
To: Julien Grall <julien.grall@linaro.org>
Cc: xen-devel@lists.xenproject.org, Keir Fraser <keir@xen.org>,
	stefano.stabellini@citrix.com, ian.campbell@citrix.com,
	tim@xen.org
Subject: Re: [PATCH v4 18/18] xen/arm: IRQ: Handle multiple action per IRQ
Date: Tue, 22 Apr 2014 14:36:10 +0100	[thread overview]
Message-ID: <53568C6A020000780000AD9A@nat28.tlf.novell.com> (raw)
In-Reply-To: <1398171530-27391-19-git-send-email-julien.grall@linaro.org>

>>> On 22.04.14 at 14:58, <julien.grall@linaro.org> wrote:
> On ARM, it may happen (eg ARM SMMU) to setup multiple handler for the same
> interrupt.
> 
> To be able to use multiple action, the driver has to explicitly call
> {setup,request}_irq with IRQF_SHARED as 2nd parameter.
> 
> The behavior stays the same on x86, e.g only one action is handled.
> 
> Signed-off-by: Julien Grall <julien.grall@linaro.org>

For the non-ARM part:
Acked-by: Jan Beulich <jbeulich@suse.com>

> ---
>     Changes in v4:
>         - Go back to a single custom linked list. The double linked-list
>         doesn't fit the requirements (i.e browsing safely without look) and
>         the llist.h from Linux doesn't allow use to delete a node in the 
> middle
>         of the list.
> 
>     Changes in v3:
>         - Drop {setup,request}_irq_flags, the current function has been
>         extended on an earlier patch.
>         - Rename IRQ_SHARED into IRQF_SHARED
> 
>     Changes in v2:
>         - Explain design choice
>         - Introduce CONFIG_IRQ_HAS_MULTIPLE_ACTION
>         - Use list instead of custom pointer
>         - release_irq should not shutdown the IRQ at the beginning
>         - Add IRQ_SHARED flags
>         - Introduce request_irq_flags and setup_irq_flags
>         - Fix compilation on x86. Some code are creating the irqaction
>         via = { ... } so the "next" field should be moved
>         toward the end
> ---
>  xen/arch/arm/irq.c           |   79 +++++++++++++++++++++++++++++++++---------
>  xen/include/asm-arm/config.h |    2 ++
>  xen/include/xen/irq.h        |    4 +++
>  3 files changed, 68 insertions(+), 17 deletions(-)
> 
> diff --git a/xen/arch/arm/irq.c b/xen/arch/arm/irq.c
> index 1bc960d..d05c0be 100644
> --- a/xen/arch/arm/irq.c
> +++ b/xen/arch/arm/irq.c
> @@ -155,7 +155,6 @@ int request_irq(unsigned int irq, unsigned int irqflags,
>  void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, int is_fiq)
>  {
>      struct irq_desc *desc = irq_to_desc(irq);
> -    struct irqaction *action = desc->action;
>  
>      /* TODO: perfc_incr(irqs); */
>  
> @@ -166,7 +165,7 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, 
> int is_fiq)
>      spin_lock(&desc->lock);
>      desc->handler->ack(desc);
>  
> -    if ( action == NULL )
> +    if ( !desc->action )
>      {
>          printk("Unknown %s %#3.3x\n",
>                 is_fiq ? "FIQ" : "IRQ", irq);
> @@ -198,12 +197,21 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int 
> irq, int is_fiq)
>  
>      desc->status |= IRQ_INPROGRESS;
>  
> -    action = desc->action;
>      while ( desc->status & IRQ_PENDING )
>      {
> +        struct irqaction *action;
> +
>          desc->status &= ~IRQ_PENDING;
> +        action = desc->action;
> +
>          spin_unlock_irq(&desc->lock);
> -        action->handler(irq, action->dev_id, regs);
> +
> +        do
> +        {
> +            action->handler(irq, action->dev_id, regs);
> +            action = action->next;
> +        } while ( action );
> +
>          spin_lock_irq(&desc->lock);
>      }
>  
> @@ -220,34 +228,71 @@ void release_irq(unsigned int irq, const void *dev_id)
>  {
>      struct irq_desc *desc;
>      unsigned long flags;
> -   struct irqaction *action;
> +    struct irqaction *action, **action_ptr;
>  
>      desc = irq_to_desc(irq);
>  
>      spin_lock_irqsave(&desc->lock,flags);
>  
> -    desc->handler->shutdown(desc);
> +    action_ptr = &desc->action;
> +    for ( ;; )
> +    {
> +        action = *action_ptr;
> +        if ( !action )
> +        {
> +            printk(XENLOG_WARNING "Trying to free already-free IRQ %u\n", 
> irq);
> +            spin_unlock_irqrestore(&desc->lock, flags);
> +            return;
> +        }
> +
> +        if ( action->dev_id == dev_id )
> +            break;
> +
> +        action_ptr = &action->next;
> +    }
> +
> +    /* Found it - remove it from the action list */
> +    *action_ptr = action->next;
>  
> -    action = desc->action;
> -    desc->action  = NULL;
> -    desc->status &= ~IRQ_GUEST;
> +    /* If this was the last action, shut down the IRQ */
> +    if ( !desc->action )
> +    {
> +        desc->handler->shutdown(desc);
> +        desc->status &= ~IRQ_GUEST;
> +    }
>  
>      spin_unlock_irqrestore(&desc->lock,flags);
>  
>      /* Wait to make sure it's not being used on another CPU */
>      do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS );
>  
> -    if ( action && action->free_on_release )
> +    if ( action->free_on_release )
>          xfree(action);
>  }
>  
> -static int __setup_irq(struct irq_desc *desc, struct irqaction *new)
> +static int __setup_irq(struct irq_desc *desc, unsigned int irqflags,
> +                       struct irqaction *new)
>  {
> -    if ( desc->action != NULL )
> -        return -EBUSY;
> +    bool_t shared = !!(irqflags & IRQF_SHARED);
> +
> +    ASSERT(new != NULL);
> +
> +    /* Sanity checks:
> +     *  - if the IRQ is marked as shared
> +     *  - dev_id is not NULL when IRQF_SHARED is set
> +     */
> +    if ( desc->action != NULL && (!(desc->status & IRQF_SHARED) || !shared) )
> +        return -EINVAL;
> +    if ( shared && new->dev_id == NULL )
> +        return -EINVAL;
> +
> +    if ( shared )
> +        desc->status |= IRQF_SHARED;
>  
> -    desc->action  = new;
> -    dsb(sy);
> +    new->next = desc->action;
> +    dsb(ish);
> +    desc->action = new;
> +    dsb(ish);
>  
>      return 0;
>  }
> @@ -275,7 +320,7 @@ int setup_irq(unsigned int irq, unsigned int irqflags, 
> struct irqaction *new)
>  
>      disabled = (desc->action == NULL);
>  
> -    rc = __setup_irq(desc, new);
> +    rc = __setup_irq(desc, irqflags, new);
>      if ( rc )
>          goto err;
>  
> @@ -340,7 +385,7 @@ int route_dt_irq_to_guest(struct domain *d, const struct 
> dt_irq *irq,
>          goto out;
>      }
>  
> -    retval = __setup_irq(desc, action);
> +    retval = __setup_irq(desc, 0, action);
>      if ( retval )
>          goto out;
>  
> diff --git a/xen/include/asm-arm/config.h b/xen/include/asm-arm/config.h
> index ef291ff..1c3abcf 100644
> --- a/xen/include/asm-arm/config.h
> +++ b/xen/include/asm-arm/config.h
> @@ -37,6 +37,8 @@
>  
>  #define CONFIG_VIDEO 1
>  
> +#define CONFIG_IRQ_HAS_MULTIPLE_ACTION 1
> +
>  #define OPT_CONSOLE_STR "dtuart"
>  
>  #ifdef MAX_PHYS_CPUS
> diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h
> index f9a18d8..40c0f3f 100644
> --- a/xen/include/xen/irq.h
> +++ b/xen/include/xen/irq.h
> @@ -14,6 +14,9 @@ struct irqaction {
>      const char *name;
>      void *dev_id;
>      bool_t free_on_release;
> +#ifdef CONFIG_IRQ_HAS_MULTIPLE_ACTION
> +    struct irqaction *next;
> +#endif
>  };
>  
>  /*
> @@ -27,6 +30,7 @@ struct irqaction {
>  #define IRQ_MOVE_PENDING  (1u<<5) /* IRQ is migrating to another CPUs */
>  #define IRQ_PER_CPU       (1u<<6) /* IRQ is per CPU */
>  #define IRQ_GUEST_EOI_PENDING (1u<<7) /* IRQ was disabled, pending a guest 
> EOI */
> +#define IRQF_SHARED       (1<<8)  /* IRQ is shared */
>  
>  /* Special IRQ numbers. */
>  #define AUTO_ASSIGN_IRQ         (-1)
> -- 
> 1.7.10.4

  reply	other threads:[~2014-04-22 13:36 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-04-22 12:58 [PATCH v4 00/18] xen/arm: Interrupt management reworking Julien Grall
2014-04-22 12:58 ` [PATCH v4 01/18] xen/arm: timer: replace timer_dt_irq by timer_get_irq Julien Grall
2014-04-22 12:58 ` [PATCH v4 02/18] xen/arm: IRQ: Use default irq callback from common code for no_irq_type Julien Grall
2014-04-22 12:58 ` [PATCH v4 03/18] xen/arm: IRQ: Rename irq_cfg into arch_irq_desc Julien Grall
2014-04-22 12:58 ` [PATCH v4 04/18] xen/arm: IRQ: move gic {, un}lock in gic_set_irq_properties Julien Grall
2014-04-22 12:58 ` [PATCH v4 05/18] xen/arm: IRQ: drop irq parameter in __setup_irq Julien Grall
2014-04-22 12:58 ` [PATCH v4 06/18] xen/arm: IRQ: remove __init from setup_dt_irq, request_dt_irq and release_irq Julien Grall
2014-04-22 12:58 ` [PATCH v4 07/18] xen/arm: IRQ: Rework gic_route_irq_to_guest function Julien Grall
2014-04-22 12:58 ` [PATCH v4 08/18] xen/arm: IRQ: Move IRQ management from gic.c to irq.c Julien Grall
2014-04-22 12:58 ` [PATCH v4 09/18] xen/arm: IRQ Introduce irq_get_domain Julien Grall
2014-04-22 12:58 ` [PATCH v4 10/18] xen/arm: IRQ: Require desc.lock be held by callers of hw_irq_controller callbacks Julien Grall
2014-04-22 12:58 ` [PATCH v4 11/18] xen/arm: IRQ: Defer routing IRQ to Xen until setup_irq() call Julien Grall
2014-04-22 12:58 ` [PATCH v4 12/18] xen/arm: IRQ: Do not allow IRQ to be shared between domains and XEN Julien Grall
2014-04-22 12:58 ` [PATCH v4 13/18] xen/serial: remove serial_dt_irq Julien Grall
2014-04-22 12:58 ` [PATCH v4 14/18] xen/arm: IRQ: Store IRQ type in arch_irq_desc Julien Grall
2014-04-23 12:26   ` Julien Grall
2014-04-23 14:04   ` Ian Campbell
2014-05-02  8:49     ` Julien Grall
2014-05-02  8:57       ` Ian Campbell
2014-05-02  9:00         ` Julien Grall
2014-04-22 12:58 ` [PATCH v4 15/18] xen/arm: IRQ: Replace {request, setup}_dt_irq by {request, setup}_irq Julien Grall
2014-04-22 13:26   ` Julien Grall
2014-04-22 12:58 ` [PATCH v4 16/18] xen: IRQ: Add dev_id parameter to release_irq Julien Grall
2014-04-22 12:58 ` [PATCH v4 17/18] xen/arm: IRQ: extend {request, setup}_irq to take an irqflags in parameter Julien Grall
2014-04-22 12:58 ` [PATCH v4 18/18] xen/arm: IRQ: Handle multiple action per IRQ Julien Grall
2014-04-22 13:36   ` Jan Beulich [this message]
2014-04-23 14:07   ` Ian Campbell
2014-04-23 14:56     ` Julien Grall
2014-04-23 15:16       ` Ian Campbell
2014-04-23 15:28         ` Julien Grall
2014-04-23 15:28         ` Julien Grall
2014-05-02  8:52 ` [PATCH v4 00/18] xen/arm: Interrupt management reworking Julien Grall
2014-05-02 12:51 ` Ian Campbell

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=53568C6A020000780000AD9A@nat28.tlf.novell.com \
    --to=jbeulich@suse.com \
    --cc=ian.campbell@citrix.com \
    --cc=julien.grall@linaro.org \
    --cc=keir@xen.org \
    --cc=stefano.stabellini@citrix.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xenproject.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.