All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs
@ 2017-04-15 10:08 Hans de Goede
  2017-04-15 13:30 ` Marc Zyngier
  2017-04-15 13:54 ` [tip:irq/core] " tip-bot for Hans de Goede
  0 siblings, 2 replies; 3+ messages in thread
From: Hans de Goede @ 2017-04-15 10:08 UTC (permalink / raw)
  To: Thomas Gleixner; +Cc: Hans de Goede, Marc Zyngier, x86, linux-kernel

When requesting a shared irq with IRQF_TRIGGER_NONE then the irqaction
flags get filled with the trigger type from the irq_data:

        if (!(new->flags & IRQF_TRIGGER_MASK))
                new->flags |= irqd_get_trigger_type(&desc->irq_data);

On the first setup_irq() the trigger type in irq_data is NONE when the
above code executes, then the irq is started up for the first time and
then the actual trigger type gets established, but that's too late to fix
up new->flags.

When then a second user of the irq requests the irq with IRQF_TRIGGER_NONE
its irqaction's triggertype gets set to the actual trigger type and the
following check fails:

        if (!((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))

Resulting in the request_irq failing with -EBUSY even though both
users requested the irq with IRQF_SHARED | IRQF_TRIGGER_NONE

This commit fixes this by comparing the new irqaction's trigger type
to the trigger type stored in the irq_data which correctly reflects
the actual trigger type being used for the irq.

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 kernel/irq/manage.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a4afe5c..d63e91f 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1212,8 +1212,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		 * set the trigger type must match. Also all must
 		 * agree on ONESHOT.
 		 */
+		unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
+
 		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
+		    (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
 		    ((old->flags ^ new->flags) & IRQF_ONESHOT))
 			goto mismatch;
 
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs
  2017-04-15 10:08 [PATCH] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs Hans de Goede
@ 2017-04-15 13:30 ` Marc Zyngier
  2017-04-15 13:54 ` [tip:irq/core] " tip-bot for Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: Marc Zyngier @ 2017-04-15 13:30 UTC (permalink / raw)
  To: Hans de Goede; +Cc: Thomas Gleixner, x86, linux-kernel

On Sat, Apr 15 2017 at 11:08:31 am BST, Hans de Goede <hdegoede@redhat.com> wrote:
> When requesting a shared irq with IRQF_TRIGGER_NONE then the irqaction
> flags get filled with the trigger type from the irq_data:
>
>         if (!(new->flags & IRQF_TRIGGER_MASK))
>                 new->flags |= irqd_get_trigger_type(&desc->irq_data);
>
> On the first setup_irq() the trigger type in irq_data is NONE when the
> above code executes, then the irq is started up for the first time and
> then the actual trigger type gets established, but that's too late to fix
> up new->flags.
>
> When then a second user of the irq requests the irq with IRQF_TRIGGER_NONE
> its irqaction's triggertype gets set to the actual trigger type and the
> following check fails:
>
>         if (!((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))
>
> Resulting in the request_irq failing with -EBUSY even though both
> users requested the irq with IRQF_SHARED | IRQF_TRIGGER_NONE
>
> This commit fixes this by comparing the new irqaction's trigger type
> to the trigger type stored in the irq_data which correctly reflects
> the actual trigger type being used for the irq.
>
> Suggested-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> ---
>  kernel/irq/manage.c | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index a4afe5c..d63e91f 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -1212,8 +1212,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
>  		 * set the trigger type must match. Also all must
>  		 * agree on ONESHOT.
>  		 */
> +		unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
> +
>  		if (!((old->flags & new->flags) & IRQF_SHARED) ||
> -		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
> +		    (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
>  		    ((old->flags ^ new->flags) & IRQF_ONESHOT))
>  			goto mismatch;

Looks sensible to me.

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead, it just smell funny.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [tip:irq/core] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs
  2017-04-15 10:08 [PATCH] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs Hans de Goede
  2017-04-15 13:30 ` Marc Zyngier
@ 2017-04-15 13:54 ` tip-bot for Hans de Goede
  1 sibling, 0 replies; 3+ messages in thread
From: tip-bot for Hans de Goede @ 2017-04-15 13:54 UTC (permalink / raw)
  To: linux-tip-commits; +Cc: linux-kernel, mingo, hdegoede, tglx, marc.zyngier, hpa

Commit-ID:  382bd4de61827dbaaf5fb4fb7b1f4be4a86505e7
Gitweb:     http://git.kernel.org/tip/382bd4de61827dbaaf5fb4fb7b1f4be4a86505e7
Author:     Hans de Goede <hdegoede@redhat.com>
AuthorDate: Sat, 15 Apr 2017 12:08:31 +0200
Committer:  Thomas Gleixner <tglx@linutronix.de>
CommitDate: Sat, 15 Apr 2017 15:42:43 +0200

genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs

When requesting a shared irq with IRQF_TRIGGER_NONE then the irqaction
flags get filled with the trigger type from the irq_data:

        if (!(new->flags & IRQF_TRIGGER_MASK))
                new->flags |= irqd_get_trigger_type(&desc->irq_data);

On the first setup_irq() the trigger type in irq_data is NONE when the
above code executes, then the irq is started up for the first time and
then the actual trigger type gets established, but that's too late to fix
up new->flags.

When then a second user of the irq requests the irq with IRQF_TRIGGER_NONE
its irqaction's triggertype gets set to the actual trigger type and the
following check fails:

        if (!((old->flags ^ new->flags) & IRQF_TRIGGER_MASK))

Resulting in the request_irq failing with -EBUSY even though both
users requested the irq with IRQF_SHARED | IRQF_TRIGGER_NONE

Fix this by comparing the new irqaction's trigger type to the trigger type
stored in the irq_data which correctly reflects the actual trigger type
being used for the irq.

Suggested-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
Link: http://lkml.kernel.org/r/20170415100831.17073-1-hdegoede@redhat.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

---
 kernel/irq/manage.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 155e3c3..ae1c90f 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1212,8 +1212,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
 		 * set the trigger type must match. Also all must
 		 * agree on ONESHOT.
 		 */
+		unsigned int oldtype = irqd_get_trigger_type(&desc->irq_data);
+
 		if (!((old->flags & new->flags) & IRQF_SHARED) ||
-		    ((old->flags ^ new->flags) & IRQF_TRIGGER_MASK) ||
+		    (oldtype != (new->flags & IRQF_TRIGGER_MASK)) ||
 		    ((old->flags ^ new->flags) & IRQF_ONESHOT))
 			goto mismatch;
 

^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2017-04-15 13:56 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-15 10:08 [PATCH] genirq: Use irqd_get_trigger_type to compare the trigger type for shared IRQs Hans de Goede
2017-04-15 13:30 ` Marc Zyngier
2017-04-15 13:54 ` [tip:irq/core] " tip-bot for Hans de Goede

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.