Subject: [PATCH v5 1/2] genirq: add IRQF_NO_AUTOEN for request_irq

Many drivers don't want interrupts enabled automatically due to
request_irq(). So they are handling this issue by either way of
the below two:
(1)
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);
(2)
request_irq(dev, irq...);
disable_irq(irq);

The code in the second way is silly and unsafe. In the small time
gap between request_irq() and disable_irq(), interrupts can still
come.
The code in the first way is safe though we might be able to do it
in the generic irq code.

With this patch, drivers can request_irq with IRQF_NO_AUTOEN flag.
They will need neither irq_set_status_flags() nor disable_irq().

In the meantime, drivers using the below pattern for NMI
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_nmi(dev, irq...);

can also move to request_nmi() with IRQF_NO_AUTOEN flag.

Cc: Dmitry Torokhov <[email protected]>
Signed-off-by: Barry Song <[email protected]>
---
-v5:
* add the same check for IRQF_NO_AUTOEN in request_nmi()

include/linux/interrupt.h | 4 ++++
kernel/irq/manage.c | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e25767153..76f1161a441a 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
* interrupt handler after suspending interrupts. For system
* wakeup devices users need to implement wakeup detection in
* their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ * Users will enable it explicitly by enable_irq() or enable_nmi()
+ * later.
*/
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
@@ -74,6 +77,7 @@
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_COND_SUSPEND 0x00040000
+#define IRQF_NO_AUTOEN 0x00080000

#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73e8db9..97c231a5644c 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
}

- if (irq_settings_can_autoenable(desc)) {
+ if (!(new->flags & IRQF_NO_AUTOEN) &&
+ irq_settings_can_autoenable(desc)) {
irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
} else {
/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*
+ * Also shared interrupts do not go well with disabling auto enable.
+ * The sharing interrupt might request it while it's still disabled
+ * and then wait for interrupts forever.
+ *
* Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
* it cannot be set along with IRQF_NO_SUSPEND.
*/
if (((irqflags & IRQF_SHARED) && !dev_id) ||
+ ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
(!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,

desc = irq_to_desc(irq);

- if (!desc || irq_settings_can_autoenable(desc) ||
+ if (!desc || (irq_settings_can_autoenable(desc) &&
+ !(irqflags & IRQF_NO_AUTOEN)) ||
!irq_settings_can_request(desc) ||
WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
!irq_supports_nmi(desc))
--
2.25.1


2021-03-04 16:29:40

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

The following commit has been merged into the irq/core branch of tip:

Commit-ID: e749df1bbd23f4472082210650514548d8a39e9b
Gitweb: https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
Author: Barry Song <[email protected]>
AuthorDate: Wed, 03 Mar 2021 11:49:15 +13:00
Committer: Thomas Gleixner <[email protected]>
CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00

genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Many drivers don't want interrupts enabled automatically via request_irq().
So they are handling this issue by either way of the below two:

(1)
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);

(2)
request_irq(dev, irq...);
disable_irq(irq);

The code in the second way is silly and unsafe. In the small time gap
between request_irq() and disable_irq(), interrupts can still come.

The code in the first way is safe though it's subobtimal.

Add a new IRQF_NO_AUTOEN flag which can be handed in by drivers to
request_irq() and request_nmi(). It prevents the automatic enabling of the
requested interrupt/nmi in the same safe way as #1 above. With that the
various usage sites of #1 and #2 above can be simplified and corrected.

Signed-off-by: Barry Song <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/r/[email protected]

---
include/linux/interrupt.h | 4 ++++
kernel/irq/manage.c | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e257..76f1161 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
* interrupt handler after suspending interrupts. For system
* wakeup devices users need to implement wakeup detection in
* their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ * Users will enable it explicitly by enable_irq() or enable_nmi()
+ * later.
*/
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
@@ -74,6 +77,7 @@
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_COND_SUSPEND 0x00040000
+#define IRQF_NO_AUTOEN 0x00080000

#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73..97c231a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
}

- if (irq_settings_can_autoenable(desc)) {
+ if (!(new->flags & IRQF_NO_AUTOEN) &&
+ irq_settings_can_autoenable(desc)) {
irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
} else {
/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*
+ * Also shared interrupts do not go well with disabling auto enable.
+ * The sharing interrupt might request it while it's still disabled
+ * and then wait for interrupts forever.
+ *
* Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
* it cannot be set along with IRQF_NO_SUSPEND.
*/
if (((irqflags & IRQF_SHARED) && !dev_id) ||
+ ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
(!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,

desc = irq_to_desc(irq);

- if (!desc || irq_settings_can_autoenable(desc) ||
+ if (!desc || (irq_settings_can_autoenable(desc) &&
+ !(irqflags & IRQF_NO_AUTOEN)) ||
!irq_settings_can_request(desc) ||
WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
!irq_supports_nmi(desc))

2021-03-04 19:11:28

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Dmitry,

On Thu, Mar 04 2021 at 11:57, Thomas Gleixner wrote:
> On Thu, Mar 04 2021 at 10:53, tip-bot wrote:
>
>> The following commit has been merged into the irq/core branch of tip:
>>
>> Commit-ID: e749df1bbd23f4472082210650514548d8a39e9b
>> Gitweb: https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
>> Author: Barry Song <[email protected]>
>> AuthorDate: Wed, 03 Mar 2021 11:49:15 +13:00
>> Committer: Thomas Gleixner <[email protected]>
>> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
>>
>> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
>
> this commit is immutable and I tagged it so you can pull it into your
> tree to add the input changes on top:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04

Please hold on:

https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%[email protected]

I'll recreate a tag for you once rc2 is out.

Thanks,

tglx

2021-03-05 00:11:08

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Dmitry,

On Thu, Mar 04 2021 at 10:53, tip-bot wrote:

> The following commit has been merged into the irq/core branch of tip:
>
> Commit-ID: e749df1bbd23f4472082210650514548d8a39e9b
> Gitweb: https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
> Author: Barry Song <[email protected]>
> AuthorDate: Wed, 03 Mar 2021 11:49:15 +13:00
> Committer: Thomas Gleixner <[email protected]>
> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
>
> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

this commit is immutable and I tagged it so you can pull it into your
tree to add the input changes on top:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04

Thanks,

tglx

2021-03-06 11:56:32

by tip-bot2 for Jacob Pan

[permalink] [raw]
Subject: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

The following commit has been merged into the irq/core branch of tip:

Commit-ID: cbe16f35bee6880becca6f20d2ebf6b457148552
Gitweb: https://git.kernel.org/tip/cbe16f35bee6880becca6f20d2ebf6b457148552
Author: Barry Song <[email protected]>
AuthorDate: Wed, 03 Mar 2021 11:49:15 +13:00
Committer: Ingo Molnar <[email protected]>
CommitterDate: Sat, 06 Mar 2021 12:48:00 +01:00

genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Many drivers don't want interrupts enabled automatically via request_irq().
So they are handling this issue by either way of the below two:

(1)
irq_set_status_flags(irq, IRQ_NOAUTOEN);
request_irq(dev, irq...);

(2)
request_irq(dev, irq...);
disable_irq(irq);

The code in the second way is silly and unsafe. In the small time gap
between request_irq() and disable_irq(), interrupts can still come.

The code in the first way is safe though it's subobtimal.

Add a new IRQF_NO_AUTOEN flag which can be handed in by drivers to
request_irq() and request_nmi(). It prevents the automatic enabling of the
requested interrupt/nmi in the same safe way as #1 above. With that the
various usage sites of #1 and #2 above can be simplified and corrected.

Signed-off-by: Barry Song <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Signed-off-by: Ingo Molnar <[email protected]>
Cc: [email protected]
Link: https://lore.kernel.org/r/[email protected]
---
include/linux/interrupt.h | 4 ++++
kernel/irq/manage.c | 11 +++++++++--
2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 967e257..76f1161 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -61,6 +61,9 @@
* interrupt handler after suspending interrupts. For system
* wakeup devices users need to implement wakeup detection in
* their interrupt handlers.
+ * IRQF_NO_AUTOEN - Don't enable IRQ or NMI automatically when users request it.
+ * Users will enable it explicitly by enable_irq() or enable_nmi()
+ * later.
*/
#define IRQF_SHARED 0x00000080
#define IRQF_PROBE_SHARED 0x00000100
@@ -74,6 +77,7 @@
#define IRQF_NO_THREAD 0x00010000
#define IRQF_EARLY_RESUME 0x00020000
#define IRQF_COND_SUSPEND 0x00040000
+#define IRQF_NO_AUTOEN 0x00080000

#define IRQF_TIMER (__IRQF_TIMER | IRQF_NO_SUSPEND | IRQF_NO_THREAD)

diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index dec3f73..97c231a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -1693,7 +1693,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
}

- if (irq_settings_can_autoenable(desc)) {
+ if (!(new->flags & IRQF_NO_AUTOEN) &&
+ irq_settings_can_autoenable(desc)) {
irq_startup(desc, IRQ_RESEND, IRQ_START_COND);
} else {
/*
@@ -2086,10 +2087,15 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*
+ * Also shared interrupts do not go well with disabling auto enable.
+ * The sharing interrupt might request it while it's still disabled
+ * and then wait for interrupts forever.
+ *
* Also IRQF_COND_SUSPEND only makes sense for shared interrupts and
* it cannot be set along with IRQF_NO_SUSPEND.
*/
if (((irqflags & IRQF_SHARED) && !dev_id) ||
+ ((irqflags & IRQF_SHARED) && (irqflags & IRQF_NO_AUTOEN)) ||
(!(irqflags & IRQF_SHARED) && (irqflags & IRQF_COND_SUSPEND)) ||
((irqflags & IRQF_NO_SUSPEND) && (irqflags & IRQF_COND_SUSPEND)))
return -EINVAL;
@@ -2245,7 +2251,8 @@ int request_nmi(unsigned int irq, irq_handler_t handler,

desc = irq_to_desc(irq);

- if (!desc || irq_settings_can_autoenable(desc) ||
+ if (!desc || (irq_settings_can_autoenable(desc) &&
+ !(irqflags & IRQF_NO_AUTOEN)) ||
!irq_settings_can_request(desc) ||
WARN_ON(irq_settings_is_per_cpu_devid(desc)) ||
!irq_supports_nmi(desc))

2021-03-24 08:26:59

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Hi Thomas,

On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
> Dmitry,
>
> On Thu, Mar 04 2021 at 11:57, Thomas Gleixner wrote:
> > On Thu, Mar 04 2021 at 10:53, tip-bot wrote:
> >
> >> The following commit has been merged into the irq/core branch of tip:
> >>
> >> Commit-ID: e749df1bbd23f4472082210650514548d8a39e9b
> >> Gitweb: https://git.kernel.org/tip/e749df1bbd23f4472082210650514548d8a39e9b
> >> Author: Barry Song <[email protected]>
> >> AuthorDate: Wed, 03 Mar 2021 11:49:15 +13:00
> >> Committer: Thomas Gleixner <[email protected]>
> >> CommitterDate: Thu, 04 Mar 2021 11:47:52 +01:00
> >>
> >> genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()
> >
> > this commit is immutable and I tagged it so you can pull it into your
> > tree to add the input changes on top:
> >
> > git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-04
>
> Please hold on:
>
> https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%[email protected]
>
> I'll recreate a tag for you once rc2 is out.

It looks like the change has been picked up as
cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
but I don't think there is tag for it?

Thanks!

--
Dmitry

2021-03-25 07:01:15

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

Dmitry,

On Tue, Mar 23 2021 at 15:44, Dmitry Torokhov wrote:
> On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
>> Please hold on:
>>
>> https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%[email protected]
>>
>> I'll recreate a tag for you once rc2 is out.
>
> It looks like the change has been picked up as
> cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
> but I don't think there is tag for it?

Sorry, forgot about it. Here you go:

git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-25

Thanks,

tglx

2021-03-25 22:37:08

by Dmitry Torokhov

[permalink] [raw]
Subject: Re: [tip: irq/core] genirq: Add IRQF_NO_AUTOEN for request_irq/nmi()

On Thu, Mar 25, 2021 at 07:59:44AM +0100, Thomas Gleixner wrote:
> Dmitry,
>
> On Tue, Mar 23 2021 at 15:44, Dmitry Torokhov wrote:
> > On Thu, Mar 04, 2021 at 07:50:31PM +0100, Thomas Gleixner wrote:
> >> Please hold on:
> >>
> >> https://lkml.kernel.org/r/CAHk-=wgZjJ89jeH72TC3i6N%[email protected]
> >>
> >> I'll recreate a tag for you once rc2 is out.
> >
> > It looks like the change has been picked up as
> > cbe16f35bee6880becca6f20d2ebf6b457148552i on top of -rc2,
> > but I don't think there is tag for it?
>
> Sorry, forgot about it. Here you go:
>
> git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq-no-autoen-2021-03-25

Thank you!

--
Dmitry