* [patch V2 00/45] genirq: Cleanups and conversion to lock guards
@ 2025-04-29 6:54 Thomas Gleixner
2025-04-29 6:54 ` [patch V2 01/45] genirq: Provide conditional " Thomas Gleixner
` (45 more replies)
0 siblings, 46 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
This is V2 of the generic interrupt locking overhaul. V1 can be found here:
https://lore.kernel.org/all/20250313154615.860723120@linutronix.de
The generic interrupt core code has accumulated quite some inconsistencies
over time and a common pattern in various API functions is:
unsigned long flags;
struct irq_desc *desc = irq_get_desc_[bus]lock(irq, &flags, mode);
if (!desc)
return -EINVAL;
....
irq_put_desc_[bus]unlock(desc, flags);
That's awkward and requires gotos in failure paths.
This series provides conditional lock guards and converts the core code
over to use those guards. Along with that it converts the other open coded
lock/unlock pairs and fixes up coding and kernel doc formatting. The
conversions were partially done with Coccinelle where possible.
Changes vs. V1:
- Rebase on latest tip irq/core
- Make coding style consistent (Jiri, Shrikanth)
The series applies on
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git irq/core
and is also available from git:
git://git.kernel.org/pub/scm/linux/kernel/git/tglx/devel.git irq/core
Thanks,
tglx
---
include/linux/irq.h | 2
kernel/irq/autoprobe.c | 26 -
kernel/irq/chip.c | 609 ++++++++++---------------
kernel/irq/cpuhotplug.c | 10
kernel/irq/debugfs.c | 3
kernel/irq/internals.h | 47 -
kernel/irq/irqdesc.c | 127 +----
kernel/irq/manage.c | 1154 ++++++++++++++++++++----------------------------
kernel/irq/pm.c | 38 -
kernel/irq/proc.c | 65 --
kernel/irq/resend.c | 50 --
kernel/irq/spurious.c | 104 +---
12 files changed, 913 insertions(+), 1322 deletions(-)
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 01/45] genirq: Provide conditional lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 02/45] genirq/irqdesc: Switch to " Thomas Gleixner
` (44 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
The interrupt core code has an ever repeating pattern:
unsigned long flags;
struct irq_desc *desc = irq_get_desc_[bus]lock(irq, &flags, mode);
if (!desc)
return -EINVAL;
....
irq_put_desc_[bus]unlock(desc, flags);
That requires gotos in failure paths and just creates visual clutter.
Provide lock guards, which allow to simplify the code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Jiri Slaby <jirislaby@kernel.org>
---
kernel/irq/internals.h | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -141,6 +141,10 @@ extern int irq_setup_affinity(struct irq
static inline int irq_setup_affinity(struct irq_desc *desc) { return 0; }
#endif
+
+#define for_each_action_of_desc(desc, act) \
+ for (act = desc->action; act; act = act->next)
+
/* Inline functions for support of irq chips on slow busses */
static inline void chip_bus_lock(struct irq_desc *desc)
{
@@ -160,14 +164,33 @@ static inline void chip_bus_sync_unlock(
#define IRQ_GET_DESC_CHECK_GLOBAL (_IRQ_DESC_CHECK)
#define IRQ_GET_DESC_CHECK_PERCPU (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU)
-#define for_each_action_of_desc(desc, act) \
- for (act = desc->action; act; act = act->next)
-
-struct irq_desc *
-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
- unsigned int check);
+struct irq_desc *__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
+ unsigned int check);
void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus);
+__DEFINE_CLASS_IS_CONDITIONAL(irqdesc_lock, true);
+__DEFINE_UNLOCK_GUARD(irqdesc_lock, struct irq_desc,
+ __irq_put_desc_unlock(_T->lock, _T->flags, _T->bus),
+ unsigned long flags; bool bus);
+
+static inline class_irqdesc_lock_t class_irqdesc_lock_constructor(unsigned int irq, bool bus,
+ unsigned int check)
+{
+ class_irqdesc_lock_t _t = {
+ .bus = bus,
+ .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
+ };
+ return _t;
+}
+
+#define scoped_irqdesc_get_and_lock(_irq, _check) \
+ scoped_guard(irqdesc_lock, _irq, false, _check)
+
+#define scoped_irqdesc_get_and_buslock(_irq, _check) \
+ scoped_guard(irqdesc_lock, _irq, true, _check)
+
+#define scoped_irqdesc ((struct irq_desc *)(__guard_ptr(irqdesc_lock)(&scope)))
+
static inline struct irq_desc *
irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
{
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 02/45] genirq/irqdesc: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
2025-04-29 6:54 ` [patch V2 01/45] genirq: Provide conditional " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-04-30 5:54 ` Jiri Slaby
2025-04-29 6:54 ` [patch V2 03/45] genirq/autoprobe: " Thomas Gleixner
` (43 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Replace all lock/unlock pairs with lock guards and simplify the code flow.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/irqdesc.c | 127 +++++++++++++++++----------------------------------
1 file changed, 43 insertions(+), 84 deletions(-)
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -246,8 +246,7 @@ static struct kobject *irq_kobj_base;
#define IRQ_ATTR_RO(_name) \
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
-static ssize_t per_cpu_count_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t per_cpu_count_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
ssize_t ret = 0;
@@ -266,99 +265,75 @@ static ssize_t per_cpu_count_show(struct
}
IRQ_ATTR_RO(per_cpu_count);
-static ssize_t chip_name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t chip_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->irq_data.chip && desc->irq_data.chip->name)
- ret = sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
+ return 0;
}
IRQ_ATTR_RO(chip_name);
-static ssize_t hwirq_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t hwirq_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
+ guard(raw_spinlock_irq)(&desc->lock);
raw_spin_lock_irq(&desc->lock);
if (desc->irq_data.domain)
- ret = sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
+ return 0;
}
IRQ_ATTR_RO(hwirq);
-static ssize_t type_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
-
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
- raw_spin_unlock_irq(&desc->lock);
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
}
IRQ_ATTR_RO(type);
-static ssize_t wakeup_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t wakeup_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
-
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
}
IRQ_ATTR_RO(wakeup);
-static ssize_t name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->name)
- ret = sysfs_emit(buf, "%s\n", desc->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->name);
+ return 0;
}
IRQ_ATTR_RO(name);
-static ssize_t actions_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t actions_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
struct irqaction *action;
ssize_t ret = 0;
char *p = "";
- raw_spin_lock_irq(&desc->lock);
- for_each_action_of_desc(desc, action) {
- ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
- p = ",";
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ for_each_action_of_desc(desc, action) {
+ ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
+ p = ",";
+ }
}
- raw_spin_unlock_irq(&desc->lock);
if (ret)
ret += sysfs_emit_at(buf, ret, "\n");
-
return ret;
}
IRQ_ATTR_RO(actions);
@@ -414,19 +389,14 @@ static int __init irq_sysfs_init(void)
int irq;
/* Prevent concurrent irq alloc/free */
- irq_lock_sparse();
-
+ guard(mutex)(&sparse_irq_lock);
irq_kobj_base = kobject_create_and_add("irq", kernel_kobj);
- if (!irq_kobj_base) {
- irq_unlock_sparse();
+ if (!irq_kobj_base)
return -ENOMEM;
- }
/* Add the already allocated interrupts */
for_each_irq_desc(irq, desc)
irq_sysfs_add(irq, desc);
- irq_unlock_sparse();
-
return 0;
}
postcore_initcall(irq_sysfs_init);
@@ -569,12 +539,12 @@ static int alloc_descs(unsigned int star
return -ENOMEM;
}
-static int irq_expand_nr_irqs(unsigned int nr)
+static bool irq_expand_nr_irqs(unsigned int nr)
{
if (nr > MAX_SPARSE_IRQS)
- return -ENOMEM;
+ return false;
nr_irqs = nr;
- return 0;
+ return true;
}
int __init early_irq_init(void)
@@ -652,11 +622,9 @@ EXPORT_SYMBOL(irq_to_desc);
static void free_desc(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
delete_irq_desc(irq);
}
@@ -677,14 +645,13 @@ static inline int alloc_descs(unsigned i
static int irq_expand_nr_irqs(unsigned int nr)
{
- return -ENOMEM;
+ return false;
}
void irq_mark_irq(unsigned int irq)
{
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
irq_insert_desc(irq, irq_desc + irq);
- mutex_unlock(&sparse_irq_lock);
}
#ifdef CONFIG_GENERIC_IRQ_LEGACY
@@ -823,11 +790,9 @@ void irq_free_descs(unsigned int from, u
if (from >= nr_irqs || (from + cnt) > nr_irqs)
return;
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
for (i = 0; i < cnt; i++)
free_desc(from + i);
-
- mutex_unlock(&sparse_irq_lock);
}
EXPORT_SYMBOL_GPL(irq_free_descs);
@@ -844,11 +809,10 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
*
* Returns the first irq number or error code
*/
-int __ref
-__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
- struct module *owner, const struct irq_affinity_desc *affinity)
+int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+ struct module *owner, const struct irq_affinity_desc *affinity)
{
- int start, ret;
+ int start;
if (!cnt)
return -EINVAL;
@@ -866,22 +830,17 @@ int __ref
from = arch_dynirq_lower_bound(from);
}
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
start = irq_find_free_area(from, cnt);
- ret = -EEXIST;
if (irq >=0 && start != irq)
- goto unlock;
+ return -EEXIST;
if (start + cnt > nr_irqs) {
- ret = irq_expand_nr_irqs(start + cnt);
- if (ret)
- goto unlock;
+ if (!irq_expand_nr_irqs(start + cnt))
+ return -ENOMEM;
}
- ret = alloc_descs(start, cnt, node, affinity, owner);
-unlock:
- mutex_unlock(&sparse_irq_lock);
- return ret;
+ return alloc_descs(start, cnt, node, affinity, owner);
}
EXPORT_SYMBOL_GPL(__irq_alloc_descs);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 03/45] genirq/autoprobe: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
2025-04-29 6:54 ` [patch V2 01/45] genirq: Provide conditional " Thomas Gleixner
2025-04-29 6:54 ` [patch V2 02/45] genirq/irqdesc: Switch to " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 04/45] genirq/pm: " Thomas Gleixner
` (42 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/autoprobe.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -43,18 +43,16 @@ unsigned long probe_irq_on(void)
* flush such a longstanding irq before considering it as spurious.
*/
for_each_irq_desc_reverse(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (!desc->action && irq_settings_can_probe(desc)) {
/*
* Some chips need to know about probing in
* progress:
*/
if (desc->irq_data.chip->irq_set_type)
- desc->irq_data.chip->irq_set_type(&desc->irq_data,
- IRQ_TYPE_PROBE);
+ desc->irq_data.chip->irq_set_type(&desc->irq_data, IRQ_TYPE_PROBE);
irq_activate_and_startup(desc, IRQ_NORESEND);
}
- raw_spin_unlock_irq(&desc->lock);
}
/* Wait for longstanding interrupts to trigger. */
@@ -66,13 +64,12 @@ unsigned long probe_irq_on(void)
* happened in the previous stage, it may have masked itself)
*/
for_each_irq_desc_reverse(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (!desc->action && irq_settings_can_probe(desc)) {
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
if (irq_activate_and_startup(desc, IRQ_NORESEND))
desc->istate |= IRQS_PENDING;
}
- raw_spin_unlock_irq(&desc->lock);
}
/*
@@ -84,18 +81,16 @@ unsigned long probe_irq_on(void)
* Now filter out any obviously spurious interrupts
*/
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
-
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
/* It triggered already - consider it spurious. */
if (!(desc->istate & IRQS_WAITING)) {
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
- } else
- if (i < 32)
- mask |= 1 << i;
+ } else if (i < 32) {
+ mask |= 1 << i;
+ }
}
- raw_spin_unlock_irq(&desc->lock);
}
return mask;
@@ -121,7 +116,7 @@ unsigned int probe_irq_mask(unsigned lon
int i;
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
if (i < 16 && !(desc->istate & IRQS_WAITING))
mask |= 1 << i;
@@ -129,7 +124,6 @@ unsigned int probe_irq_mask(unsigned lon
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
}
- raw_spin_unlock_irq(&desc->lock);
}
mutex_unlock(&probing_active);
@@ -160,8 +154,7 @@ int probe_irq_off(unsigned long val)
struct irq_desc *desc;
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
-
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
if (!(desc->istate & IRQS_WAITING)) {
if (!nr_of_irqs)
@@ -171,7 +164,6 @@ int probe_irq_off(unsigned long val)
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
}
- raw_spin_unlock_irq(&desc->lock);
}
mutex_unlock(&probing_active);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 04/45] genirq/pm: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (2 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 03/45] genirq/autoprobe: " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 05/45] genirq/resend: " Thomas Gleixner
` (41 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/pm.c | 38 +++++++++++++-------------------------
1 file changed, 13 insertions(+), 25 deletions(-)
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -46,8 +46,7 @@ void irq_pm_install_action(struct irq_de
desc->cond_suspend_depth++;
WARN_ON_ONCE(desc->no_suspend_depth &&
- (desc->no_suspend_depth +
- desc->cond_suspend_depth) != desc->nr_actions);
+ (desc->no_suspend_depth + desc->cond_suspend_depth) != desc->nr_actions);
}
/*
@@ -134,14 +133,12 @@ void suspend_device_irqs(void)
int irq;
for_each_irq_desc(irq, desc) {
- unsigned long flags;
bool sync;
if (irq_settings_is_nested_thread(desc))
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
- sync = suspend_device_irq(desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ sync = suspend_device_irq(desc);
if (sync)
synchronize_irq(irq);
@@ -186,18 +183,15 @@ static void resume_irqs(bool want_early)
int irq;
for_each_irq_desc(irq, desc) {
- unsigned long flags;
- bool is_early = desc->action &&
- desc->action->flags & IRQF_EARLY_RESUME;
+ bool is_early = desc->action && desc->action->flags & IRQF_EARLY_RESUME;
if (!is_early && want_early)
continue;
if (irq_settings_is_nested_thread(desc))
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
resume_irq(desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -207,22 +201,16 @@ static void resume_irqs(bool want_early)
*/
void rearm_wake_irq(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return;
-
- if (!(desc->istate & IRQS_SUSPENDED) ||
- !irqd_is_wakeup_set(&desc->irq_data))
- goto unlock;
-
- desc->istate &= ~IRQS_SUSPENDED;
- irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
- __enable_irq(desc);
+ if (!(desc->istate & IRQS_SUSPENDED) || !irqd_is_wakeup_set(&desc->irq_data))
+ return;
-unlock:
- irq_put_desc_busunlock(desc, flags);
+ desc->istate &= ~IRQS_SUSPENDED;
+ irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
+ __enable_irq(desc);
+ }
}
/**
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 05/45] genirq/resend: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (3 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 04/45] genirq/pm: " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 06/45] genirq/proc: " Thomas Gleixner
` (40 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/resend.c | 50 +++++++++++++++++++++-----------------------------
1 file changed, 21 insertions(+), 29 deletions(-)
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -30,18 +30,17 @@ static DEFINE_RAW_SPINLOCK(irq_resend_lo
*/
static void resend_irqs(struct tasklet_struct *unused)
{
- struct irq_desc *desc;
-
- raw_spin_lock_irq(&irq_resend_lock);
+ guard(raw_spinlock_irq)(&irq_resend_lock);
while (!hlist_empty(&irq_resend_list)) {
- desc = hlist_entry(irq_resend_list.first, struct irq_desc,
- resend_node);
+ struct irq_desc *desc;
+
+ desc = hlist_entry(irq_resend_list.first, struct irq_desc, resend_node);
hlist_del_init(&desc->resend_node);
+
raw_spin_unlock(&irq_resend_lock);
desc->handle_irq(desc);
raw_spin_lock(&irq_resend_lock);
}
- raw_spin_unlock_irq(&irq_resend_lock);
}
/* Tasklet to handle resend: */
@@ -75,19 +74,18 @@ static int irq_sw_resend(struct irq_desc
}
/* Add to resend_list and activate the softirq: */
- raw_spin_lock(&irq_resend_lock);
- if (hlist_unhashed(&desc->resend_node))
- hlist_add_head(&desc->resend_node, &irq_resend_list);
- raw_spin_unlock(&irq_resend_lock);
+ scoped_guard(raw_spinlock, &irq_resend_lock) {
+ if (hlist_unhashed(&desc->resend_node))
+ hlist_add_head(&desc->resend_node, &irq_resend_list);
+ }
tasklet_schedule(&resend_tasklet);
return 0;
}
void clear_irq_resend(struct irq_desc *desc)
{
- raw_spin_lock(&irq_resend_lock);
+ guard(raw_spinlock)(&irq_resend_lock);
hlist_del_init(&desc->resend_node);
- raw_spin_unlock(&irq_resend_lock);
}
void irq_resend_init(struct irq_desc *desc)
@@ -172,30 +170,24 @@ int check_irq_resend(struct irq_desc *de
*/
int irq_inject_interrupt(unsigned int irq)
{
- struct irq_desc *desc;
- unsigned long flags;
- int err;
+ int err = -EINVAL;
/* Try the state injection hardware interface first */
if (!irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true))
return 0;
/* That failed, try via the resend mechanism */
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
- /*
- * Only try to inject when the interrupt is:
- * - not NMI type
- * - activated
- */
- if (irq_is_nmi(desc) || !irqd_is_activated(&desc->irq_data))
- err = -EINVAL;
- else
- err = check_irq_resend(desc, true);
-
- irq_put_desc_busunlock(desc, flags);
+ /*
+ * Only try to inject when the interrupt is:
+ * - not NMI type
+ * - activated
+ */
+ if (!irq_is_nmi(desc) && irqd_is_activated(&desc->irq_data))
+ err = check_irq_resend(desc, true);
+ }
return err;
}
EXPORT_SYMBOL_GPL(irq_inject_interrupt);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 06/45] genirq/proc: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (4 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 05/45] genirq/resend: " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-06-08 12:45 ` [patch V2 06/45] " Zenghui Yu
2025-04-29 6:54 ` [patch V2 07/45] genirq/spurious: Cleanup code Thomas Gleixner
` (39 subsequent siblings)
45 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/proc.c | 65 +++++++++++++++++++-----------------------------------
1 file changed, 24 insertions(+), 41 deletions(-)
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -81,20 +81,18 @@ static int show_irq_affinity(int type, s
static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long)m->private);
- unsigned long flags;
cpumask_var_t mask;
if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
return -ENOMEM;
- raw_spin_lock_irqsave(&desc->lock, flags);
- if (desc->affinity_hint)
- cpumask_copy(mask, desc->affinity_hint);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ if (desc->affinity_hint)
+ cpumask_copy(mask, desc->affinity_hint);
+ }
seq_printf(m, "%*pb\n", cpumask_pr_args(mask));
free_cpumask_var(mask);
-
return 0;
}
@@ -295,23 +293,18 @@ static int irq_spurious_proc_show(struct
#define MAX_NAMELEN 128
-static int name_unique(unsigned int irq, struct irqaction *new_action)
+static bool name_unique(unsigned int irq, struct irqaction *new_action)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
- int ret = 1;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irq)(&desc->lock);
for_each_action_of_desc(desc, action) {
if ((action != new_action) && action->name &&
- !strcmp(new_action->name, action->name)) {
- ret = 0;
- break;
- }
+ !strcmp(new_action->name, action->name))
+ return false;
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return ret;
+ return true;
}
void register_handler_proc(unsigned int irq, struct irqaction *action)
@@ -319,8 +312,7 @@ void register_handler_proc(unsigned int
char name [MAX_NAMELEN];
struct irq_desc *desc = irq_to_desc(irq);
- if (!desc->dir || action->dir || !action->name ||
- !name_unique(irq, action))
+ if (!desc->dir || action->dir || !action->name || !name_unique(irq, action))
return;
snprintf(name, MAX_NAMELEN, "%s", action->name);
@@ -347,17 +339,16 @@ void register_irq_proc(unsigned int irq,
* added, not when the descriptor is created, so multiple
* tasks might try to register at the same time.
*/
- mutex_lock(®ister_lock);
+ guard(mutex)(®ister_lock);
if (desc->dir)
- goto out_unlock;
-
- sprintf(name, "%d", irq);
+ return;
/* create /proc/irq/1234 */
+ sprintf(name, "%d", irq);
desc->dir = proc_mkdir(name, root_irq_dir);
if (!desc->dir)
- goto out_unlock;
+ return;
#ifdef CONFIG_SMP
umode_t umode = S_IRUGO;
@@ -366,31 +357,27 @@ void register_irq_proc(unsigned int irq,
umode |= S_IWUSR;
/* create /proc/irq/<irq>/smp_affinity */
- proc_create_data("smp_affinity", umode, desc->dir,
- &irq_affinity_proc_ops, irqp);
+ proc_create_data("smp_affinity", umode, desc->dir, &irq_affinity_proc_ops, irqp);
/* create /proc/irq/<irq>/affinity_hint */
proc_create_single_data("affinity_hint", 0444, desc->dir,
- irq_affinity_hint_proc_show, irqp);
+ irq_affinity_hint_proc_show, irqp);
/* create /proc/irq/<irq>/smp_affinity_list */
proc_create_data("smp_affinity_list", umode, desc->dir,
&irq_affinity_list_proc_ops, irqp);
- proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show,
- irqp);
+ proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show, irqp);
# ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
proc_create_single_data("effective_affinity", 0444, desc->dir,
- irq_effective_aff_proc_show, irqp);
+ irq_effective_aff_proc_show, irqp);
proc_create_single_data("effective_affinity_list", 0444, desc->dir,
- irq_effective_aff_list_proc_show, irqp);
+ irq_effective_aff_list_proc_show, irqp);
# endif
#endif
proc_create_single_data("spurious", 0444, desc->dir,
- irq_spurious_proc_show, (void *)(long)irq);
+ irq_spurious_proc_show, (void *)(long)irq);
-out_unlock:
- mutex_unlock(®ister_lock);
}
void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
@@ -468,7 +455,6 @@ int show_interrupts(struct seq_file *p,
int i = *(loff_t *) v, j;
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
if (i > ACTUAL_NR_IRQS)
return 0;
@@ -487,13 +473,13 @@ int show_interrupts(struct seq_file *p,
seq_putc(p, '\n');
}
- rcu_read_lock();
+ guard(rcu)();
desc = irq_to_desc(i);
if (!desc || irq_settings_is_hidden(desc))
- goto outsparse;
+ return 0;
if (!desc->action || irq_desc_is_chained(desc) || !desc->kstat_irqs)
- goto outsparse;
+ return 0;
seq_printf(p, "%*d:", prec, i);
for_each_online_cpu(j) {
@@ -503,7 +489,7 @@ int show_interrupts(struct seq_file *p,
}
seq_putc(p, ' ');
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->irq_data.chip) {
if (desc->irq_data.chip->irq_print_chip)
desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
@@ -532,9 +518,6 @@ int show_interrupts(struct seq_file *p,
}
seq_putc(p, '\n');
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-outsparse:
- rcu_read_unlock();
return 0;
}
#endif
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 07/45] genirq/spurious: Cleanup code
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (5 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 06/45] genirq/proc: " Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 08/45] genirq/spurious: Switch to lock guards Thomas Gleixner
` (38 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Clean up the coding style
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/spurious.c | 74 ++++++++++++++++++--------------------------------
1 file changed, 28 insertions(+), 46 deletions(-)
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -34,8 +34,9 @@ static atomic_t irq_poll_active;
* true and let the handler run.
*/
bool irq_wait_for_poll(struct irq_desc *desc)
- __must_hold(&desc->lock)
{
+ lockdep_assert_held(&desc->lock);
+
if (WARN_ONCE(irq_poll_cpu == smp_processor_id(),
"irq poll in progress on cpu %d for irq %d\n",
smp_processor_id(), desc->irq_data.irq))
@@ -157,8 +158,7 @@ static void poll_spurious_irqs(struct ti
continue;
/* Racy but it doesn't matter */
- state = desc->istate;
- barrier();
+ state = READ_ONCE(desc->istate);
if (!(state & IRQS_SPURIOUS_DISABLED))
continue;
@@ -168,8 +168,7 @@ static void poll_spurious_irqs(struct ti
}
out:
atomic_dec(&irq_poll_active);
- mod_timer(&poll_spurious_irq_timer,
- jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+ mod_timer(&poll_spurious_irq_timer, jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
static inline int bad_action_ret(irqreturn_t action_ret)
@@ -195,15 +194,12 @@ static void __report_bad_irq(struct irq_
struct irqaction *action;
unsigned long flags;
- if (bad_action_ret(action_ret)) {
- printk(KERN_ERR "irq event %d: bogus return value %x\n",
- irq, action_ret);
- } else {
- printk(KERN_ERR "irq %d: nobody cared (try booting with "
- "the \"irqpoll\" option)\n", irq);
- }
+ if (bad_action_ret(action_ret))
+ pr_err("irq event %d: bogus return value %x\n", irq, action_ret);
+ else
+ pr_err("irq %d: nobody cared (try booting with the \"irqpoll\" option)\n", irq);
dump_stack();
- printk(KERN_ERR "handlers:\n");
+ pr_err("handlers:\n");
/*
* We need to take desc->lock here. note_interrupt() is called
@@ -213,11 +209,10 @@ static void __report_bad_irq(struct irq_
*/
raw_spin_lock_irqsave(&desc->lock, flags);
for_each_action_of_desc(desc, action) {
- printk(KERN_ERR "[<%p>] %ps", action->handler, action->handler);
+ pr_err("[<%p>] %ps", action->handler, action->handler);
if (action->thread_fn)
- printk(KERN_CONT " threaded [<%p>] %ps",
- action->thread_fn, action->thread_fn);
- printk(KERN_CONT "\n");
+ pr_cont(" threaded [<%p>] %ps", action->thread_fn, action->thread_fn);
+ pr_cont("\n");
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
@@ -232,18 +227,17 @@ static void report_bad_irq(struct irq_de
}
}
-static inline int
-try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
- irqreturn_t action_ret)
+static inline bool try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
+ irqreturn_t action_ret)
{
struct irqaction *action;
if (!irqfixup)
- return 0;
+ return false;
/* We didn't actually handle the IRQ - see if it was misrouted? */
if (action_ret == IRQ_NONE)
- return 1;
+ return true;
/*
* But for 'irqfixup == 2' we also do it for handled interrupts if
@@ -251,19 +245,16 @@ try_misrouted_irq(unsigned int irq, stru
* traditional PC timer interrupt.. Legacy)
*/
if (irqfixup < 2)
- return 0;
+ return false;
if (!irq)
- return 1;
+ return true;
/*
* Since we don't get the descriptor lock, "action" can
- * change under us. We don't really care, but we don't
- * want to follow a NULL pointer. So tell the compiler to
- * just load it once by using a barrier.
+ * change under us.
*/
- action = desc->action;
- barrier();
+ action = READ_ONCE(desc->action);
return action && (action->flags & IRQF_IRQPOLL);
}
@@ -273,8 +264,7 @@ void note_interrupt(struct irq_desc *des
{
unsigned int irq;
- if (desc->istate & IRQS_POLL_INPROGRESS ||
- irq_settings_is_polled(desc))
+ if (desc->istate & IRQS_POLL_INPROGRESS || irq_settings_is_polled(desc))
return;
if (bad_action_ret(action_ret)) {
@@ -420,13 +410,12 @@ void note_interrupt(struct irq_desc *des
/*
* Now kill the IRQ
*/
- printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
+ pr_emerg("Disabling IRQ #%d\n", irq);
desc->istate |= IRQS_SPURIOUS_DISABLED;
desc->depth++;
irq_disable(desc);
- mod_timer(&poll_spurious_irq_timer,
- jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+ mod_timer(&poll_spurious_irq_timer, jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
desc->irqs_unhandled = 0;
}
@@ -436,11 +425,9 @@ bool noirqdebug __read_mostly;
int noirqdebug_setup(char *str)
{
noirqdebug = 1;
- printk(KERN_INFO "IRQ lockup detection disabled\n");
-
+ pr_info("IRQ lockup detection disabled\n");
return 1;
}
-
__setup("noirqdebug", noirqdebug_setup);
module_param(noirqdebug, bool, 0644);
MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true");
@@ -452,12 +439,10 @@ static int __init irqfixup_setup(char *s
return 1;
}
irqfixup = 1;
- printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
- printk(KERN_WARNING "This may impact system performance.\n");
-
+ pr_warn("Misrouted IRQ fixup support enabled.\n");
+ pr_warn("This may impact system performance.\n");
return 1;
}
-
__setup("irqfixup", irqfixup_setup);
module_param(irqfixup, int, 0644);
@@ -468,11 +453,8 @@ static int __init irqpoll_setup(char *st
return 1;
}
irqfixup = 2;
- printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
- "enabled\n");
- printk(KERN_WARNING "This may significantly impact system "
- "performance\n");
+ pr_warn("Misrouted IRQ fixup and polling support enabled\n");
+ pr_warn("This may significantly impact system performance\n");
return 1;
}
-
__setup("irqpoll", irqpoll_setup);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 08/45] genirq/spurious: Switch to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (6 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 07/45] genirq/spurious: Cleanup code Thomas Gleixner
@ 2025-04-29 6:54 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 09/45] genirq/cpuhotplug: Convert " Thomas Gleixner
` (37 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:54 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/spurious.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -60,37 +60,35 @@ bool irq_wait_for_poll(struct irq_desc *
/*
* Recovery handler for misrouted interrupts.
*/
-static int try_one_irq(struct irq_desc *desc, bool force)
+static bool try_one_irq(struct irq_desc *desc, bool force)
{
- irqreturn_t ret = IRQ_NONE;
struct irqaction *action;
+ bool ret = false;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
/*
* PER_CPU, nested thread interrupts and interrupts explicitly
* marked polled are excluded from polling.
*/
- if (irq_settings_is_per_cpu(desc) ||
- irq_settings_is_nested_thread(desc) ||
+ if (irq_settings_is_per_cpu(desc) || irq_settings_is_nested_thread(desc) ||
irq_settings_is_polled(desc))
- goto out;
+ return false;
/*
* Do not poll disabled interrupts unless the spurious
* disabled poller asks explicitly.
*/
if (irqd_irq_disabled(&desc->irq_data) && !force)
- goto out;
+ return false;
/*
* All handlers must agree on IRQF_SHARED, so we test just the
* first.
*/
action = desc->action;
- if (!action || !(action->flags & IRQF_SHARED) ||
- (action->flags & __IRQF_TIMER))
- goto out;
+ if (!action || !(action->flags & IRQF_SHARED) || (action->flags & __IRQF_TIMER))
+ return false;
/* Already running on another processor */
if (irqd_irq_inprogress(&desc->irq_data)) {
@@ -99,21 +97,19 @@ static int try_one_irq(struct irq_desc *
* CPU to go looking for our mystery interrupt too
*/
desc->istate |= IRQS_PENDING;
- goto out;
+ return false;
}
/* Mark it poll in progress */
desc->istate |= IRQS_POLL_INPROGRESS;
do {
if (handle_irq_event(desc) == IRQ_HANDLED)
- ret = IRQ_HANDLED;
+ ret = true;
/* Make sure that there is still a valid action */
action = desc->action;
} while ((desc->istate & IRQS_PENDING) && action);
desc->istate &= ~IRQS_POLL_INPROGRESS;
-out:
- raw_spin_unlock(&desc->lock);
- return ret == IRQ_HANDLED;
+ return ret;
}
static int misrouted_irq(int irq)
@@ -192,7 +188,6 @@ static void __report_bad_irq(struct irq_
{
unsigned int irq = irq_desc_get_irq(desc);
struct irqaction *action;
- unsigned long flags;
if (bad_action_ret(action_ret))
pr_err("irq event %d: bogus return value %x\n", irq, action_ret);
@@ -207,14 +202,13 @@ static void __report_bad_irq(struct irq_
* with something else removing an action. It's ok to take
* desc->lock here. See synchronize_irq().
*/
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
for_each_action_of_desc(desc, action) {
pr_err("[<%p>] %ps", action->handler, action->handler);
if (action->thread_fn)
pr_cont(" threaded [<%p>] %ps", action->thread_fn, action->thread_fn);
pr_cont("\n");
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
static void report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 09/45] genirq/cpuhotplug: Convert to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (7 preceding siblings ...)
2025-04-29 6:54 ` [patch V2 08/45] genirq/spurious: Switch to lock guards Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508145631eucas1p2f5369234fee8eb86761d70d028d6c82d@eucas1p2.samsung.com>
2025-04-29 6:55 ` [patch V2 10/45] genirq/debugfs: " Thomas Gleixner
` (36 subsequent siblings)
45 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/cpuhotplug.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -177,9 +177,8 @@ void irq_migrate_all_off_this_cpu(void)
bool affinity_broken;
desc = irq_to_desc(irq);
- raw_spin_lock(&desc->lock);
- affinity_broken = migrate_one_irq(desc);
- raw_spin_unlock(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ affinity_broken = migrate_one_irq(desc);
if (affinity_broken) {
pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
@@ -244,9 +243,8 @@ int irq_affinity_online_cpu(unsigned int
irq_lock_sparse();
for_each_active_irq(irq) {
desc = irq_to_desc(irq);
- raw_spin_lock_irq(&desc->lock);
- irq_restore_affinity_of_irq(desc, cpu);
- raw_spin_unlock_irq(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ irq_restore_affinity_of_irq(desc, cpu);
}
irq_unlock_sparse();
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 10/45] genirq/debugfs: Convert to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (8 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 09/45] genirq/cpuhotplug: Convert " Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 11/45] genirq/chip: Prepare for code reduction Thomas Gleixner
` (35 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/debugfs.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/kernel/irq/debugfs.c
+++ b/kernel/irq/debugfs.c
@@ -160,7 +160,7 @@ static int irq_debug_show(struct seq_fil
struct irq_desc *desc = m->private;
struct irq_data *data;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
data = irq_desc_get_irq_data(desc);
seq_printf(m, "handler: %ps\n", desc->handle_irq);
seq_printf(m, "device: %s\n", desc->dev_name);
@@ -178,7 +178,6 @@ static int irq_debug_show(struct seq_fil
seq_printf(m, "node: %d\n", irq_data_get_node(data));
irq_debug_show_masks(m, desc);
irq_debug_show_data(m, data, 0);
- raw_spin_unlock_irq(&desc->lock);
return 0;
}
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 11/45] genirq/chip: Prepare for code reduction
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (9 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 10/45] genirq/debugfs: " Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 12/45] genirq/chip: Rework handle_nested_irq() Thomas Gleixner
` (34 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
The interrupt flow handlers have similar patterns to decide whether to
handle an interrupt or not.
Provide common helper functions to allow removal of duplicated code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -499,7 +499,7 @@ static bool irq_check_poll(struct irq_de
return irq_wait_for_poll(desc);
}
-static bool irq_may_run(struct irq_desc *desc)
+static bool irq_can_handle_pm(struct irq_desc *desc)
{
unsigned int mask = IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARMED;
@@ -524,6 +524,25 @@ static bool irq_may_run(struct irq_desc
return irq_check_poll(desc);
}
+static inline bool irq_can_handle_actions(struct irq_desc *desc)
+{
+ desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+
+ if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+ desc->istate |= IRQS_PENDING;
+ return false;
+ }
+ return true;
+}
+
+static inline bool irq_can_handle(struct irq_desc *desc)
+{
+ if (!irq_can_handle_pm(desc))
+ return false;
+
+ return irq_can_handle_actions(desc);
+}
+
/**
* handle_simple_irq - Simple and software-decoded IRQs.
* @desc: the interrupt description structure for this irq
@@ -539,7 +558,7 @@ void handle_simple_irq(struct irq_desc *
{
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -574,7 +593,7 @@ void handle_untracked_irq(struct irq_des
{
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -630,7 +649,7 @@ void handle_level_irq(struct irq_desc *d
raw_spin_lock(&desc->lock);
mask_ack_irq(desc);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -695,7 +714,7 @@ void handle_fasteoi_irq(struct irq_desc
* can arrive on the new CPU before the original CPU has completed
* handling the previous one - it may need to be resent.
*/
- if (!irq_may_run(desc)) {
+ if (!irq_can_handle_pm(desc)) {
if (irqd_needs_resend_when_in_progress(&desc->irq_data))
desc->istate |= IRQS_PENDING;
goto out;
@@ -790,7 +809,7 @@ void handle_edge_irq(struct irq_desc *de
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
- if (!irq_may_run(desc)) {
+ if (!irq_can_handle_pm(desc)) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
goto out_unlock;
@@ -1166,7 +1185,7 @@ void handle_fasteoi_ack_irq(struct irq_d
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -1218,7 +1237,7 @@ void handle_fasteoi_mask_irq(struct irq_
raw_spin_lock(&desc->lock);
mask_ack_irq(desc);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 12/45] genirq/chip: Rework handle_nested_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (10 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 11/45] genirq/chip: Prepare for code reduction Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508205629eucas1p2f8f2032c2d651be176acdf6ac4aa79cd@eucas1p2.samsung.com>
2025-04-29 6:55 ` [patch V2 13/45] genirq/chip: Rework handle_simple_irq() Thomas Gleixner
` (33 subsequent siblings)
45 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 78 ++++++++++++++++++++++++------------------------------
1 file changed, 36 insertions(+), 42 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -450,48 +450,6 @@ void unmask_threaded_irq(struct irq_desc
unmask_irq(desc);
}
-/*
- * handle_nested_irq - Handle a nested irq from a irq thread
- * @irq: the interrupt number
- *
- * Handle interrupts which are nested into a threaded interrupt
- * handler. The handler function is called inside the calling
- * threads context.
- */
-void handle_nested_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irqaction *action;
- irqreturn_t action_ret;
-
- might_sleep();
-
- raw_spin_lock_irq(&desc->lock);
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- action = desc->action;
- if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- raw_spin_unlock_irq(&desc->lock);
- return;
- }
-
- kstat_incr_irqs_this_cpu(desc);
- atomic_inc(&desc->threads_active);
- raw_spin_unlock_irq(&desc->lock);
-
- action_ret = IRQ_NONE;
- for_each_action_of_desc(desc, action)
- action_ret |= action->thread_fn(action->irq, action->dev_id);
-
- if (!irq_settings_no_debug(desc))
- note_interrupt(desc, action_ret);
-
- wake_threads_waitq(desc);
-}
-EXPORT_SYMBOL_GPL(handle_nested_irq);
-
static bool irq_check_poll(struct irq_desc *desc)
{
if (!(desc->istate & IRQS_POLL_INPROGRESS))
@@ -544,6 +502,42 @@ static inline bool irq_can_handle(struct
}
/**
+ * handle_nested_irq - Handle a nested irq from a irq thread
+ * @irq: the interrupt number
+ *
+ * Handle interrupts which are nested into a threaded interrupt
+ * handler. The handler function is called inside the calling threads
+ * context.
+ */
+void handle_nested_irq(unsigned int irq)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irqaction *action;
+ irqreturn_t action_ret;
+
+ might_sleep();
+
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ if (irq_can_handle_actions(desc))
+ return;
+
+ action = desc->action;
+ kstat_incr_irqs_this_cpu(desc);
+ atomic_inc(&desc->threads_active);
+ }
+
+ action_ret = IRQ_NONE;
+ for_each_action_of_desc(desc, action)
+ action_ret |= action->thread_fn(action->irq, action->dev_id);
+
+ if (!irq_settings_no_debug(desc))
+ note_interrupt(desc, action_ret);
+
+ wake_threads_waitq(desc);
+}
+EXPORT_SYMBOL_GPL(handle_nested_irq);
+
+/**
* handle_simple_irq - Simple and software-decoded IRQs.
* @desc: the interrupt description structure for this irq
*
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 13/45] genirq/chip: Rework handle_simple_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (11 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 12/45] genirq/chip: Rework handle_nested_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 14/45] genirq/chip: Rework handle_untracked_irq() Thomas Gleixner
` (32 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -538,35 +538,25 @@ void handle_nested_irq(unsigned int irq)
EXPORT_SYMBOL_GPL(handle_nested_irq);
/**
- * handle_simple_irq - Simple and software-decoded IRQs.
- * @desc: the interrupt description structure for this irq
+ * handle_simple_irq - Simple and software-decoded IRQs.
+ * @desc: the interrupt description structure for this irq
*
- * Simple interrupts are either sent from a demultiplexing interrupt
- * handler or come from hardware, where no interrupt hardware control
- * is necessary.
+ * Simple interrupts are either sent from a demultiplexing interrupt
+ * handler or come from hardware, where no interrupt hardware control is
+ * necessary.
*
- * Note: The caller is expected to handle the ack, clear, mask and
- * unmask issues if necessary.
+ * Note: The caller is expected to handle the ack, clear, mask and unmask
+ * issues if necessary.
*/
void handle_simple_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
- }
+ if (!irq_can_handle(desc))
+ return;
kstat_incr_irqs_this_cpu(desc);
handle_irq_event(desc);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_simple_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 14/45] genirq/chip: Rework handle_untracked_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (12 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 13/45] genirq/chip: Rework handle_simple_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 15/45] genirq/chip: Rework handle_level_irq() Thomas Gleixner
` (31 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 43 ++++++++++++++++---------------------------
1 file changed, 16 insertions(+), 27 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -561,43 +561,32 @@ void handle_simple_irq(struct irq_desc *
EXPORT_SYMBOL_GPL(handle_simple_irq);
/**
- * handle_untracked_irq - Simple and software-decoded IRQs.
- * @desc: the interrupt description structure for this irq
+ * handle_untracked_irq - Simple and software-decoded IRQs.
+ * @desc: the interrupt description structure for this irq
*
- * Untracked interrupts are sent from a demultiplexing interrupt
- * handler when the demultiplexer does not know which device it its
- * multiplexed irq domain generated the interrupt. IRQ's handled
- * through here are not subjected to stats tracking, randomness, or
- * spurious interrupt detection.
+ * Untracked interrupts are sent from a demultiplexing interrupt handler
+ * when the demultiplexer does not know which device it its multiplexed irq
+ * domain generated the interrupt. IRQ's handled through here are not
+ * subjected to stats tracking, randomness, or spurious interrupt
+ * detection.
*
- * Note: Like handle_simple_irq, the caller is expected to handle
- * the ack, clear, mask and unmask issues if necessary.
+ * Note: Like handle_simple_irq, the caller is expected to handle the ack,
+ * clear, mask and unmask issues if necessary.
*/
void handle_untracked_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock) {
+ if (!irq_can_handle(desc))
+ return;
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
+ desc->istate &= ~IRQS_PENDING;
+ irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
}
- desc->istate &= ~IRQS_PENDING;
- irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
- raw_spin_unlock(&desc->lock);
-
__handle_irq_event_percpu(desc);
- raw_spin_lock(&desc->lock);
- irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
}
EXPORT_SYMBOL_GPL(handle_untracked_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 15/45] genirq/chip: Rework handle_level_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (13 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 14/45] genirq/chip: Rework handle_untracked_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 16/45] genirq/chip: Rework handle_eoi_irq() Thomas Gleixner
` (30 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 32 +++++++++-----------------------
1 file changed, 9 insertions(+), 23 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -609,40 +609,26 @@ static void cond_unmask_irq(struct irq_d
}
/**
- * handle_level_irq - Level type irq handler
- * @desc: the interrupt description structure for this irq
+ * handle_level_irq - Level type irq handler
+ * @desc: the interrupt description structure for this irq
*
- * Level type interrupts are active as long as the hardware line has
- * the active level. This may require to mask the interrupt and unmask
- * it after the associated handler has acknowledged the device, so the
- * interrupt line is back to inactive.
+ * Level type interrupts are active as long as the hardware line has the
+ * active level. This may require to mask the interrupt and unmask it after
+ * the associated handler has acknowledged the device, so the interrupt
+ * line is back to inactive.
*/
void handle_level_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
mask_ack_irq(desc);
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * keep it masked and get out of here
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
- }
+ if (!irq_can_handle(desc))
+ return;
kstat_incr_irqs_this_cpu(desc);
handle_irq_event(desc);
cond_unmask_irq(desc);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_level_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 16/45] genirq/chip: Rework handle_eoi_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (14 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 15/45] genirq/chip: Rework handle_level_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 17/45] genirq/chip: Rework handle_edge_irq() Thomas Gleixner
` (29 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 42 ++++++++++++++++++------------------------
1 file changed, 18 insertions(+), 24 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -653,20 +653,26 @@ static void cond_unmask_eoi_irq(struct i
}
}
+static inline void cond_eoi_irq(struct irq_chip *chip, struct irq_data *data)
+{
+ if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
+ chip->irq_eoi(data);
+}
+
/**
- * handle_fasteoi_irq - irq handler for transparent controllers
- * @desc: the interrupt description structure for this irq
+ * handle_fasteoi_irq - irq handler for transparent controllers
+ * @desc: the interrupt description structure for this irq
*
- * Only a single callback will be issued to the chip: an ->eoi()
- * call when the interrupt has been serviced. This enables support
- * for modern forms of interrupt handlers, which handle the flow
- * details in hardware, transparently.
+ * Only a single callback will be issued to the chip: an ->eoi() call when
+ * the interrupt has been serviced. This enables support for modern forms
+ * of interrupt handlers, which handle the flow details in hardware,
+ * transparently.
*/
void handle_fasteoi_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
/*
* When an affinity change races with IRQ handling, the next interrupt
@@ -676,19 +682,14 @@ void handle_fasteoi_irq(struct irq_desc
if (!irq_can_handle_pm(desc)) {
if (irqd_needs_resend_when_in_progress(&desc->irq_data))
desc->istate |= IRQS_PENDING;
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
+ if (!irq_can_handle_actions(desc)) {
mask_irq(desc);
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
@@ -704,13 +705,6 @@ void handle_fasteoi_irq(struct irq_desc
*/
if (unlikely(desc->istate & IRQS_PENDING))
check_irq_resend(desc, false);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 17/45] genirq/chip: Rework handle_edge_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (15 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 16/45] genirq/chip: Rework handle_eoi_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 18/45] genirq/chip: Rework handle_fasteoi_ack_irq() Thomas Gleixner
` (28 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 49 ++++++++++++++++---------------------------------
1 file changed, 16 insertions(+), 33 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -742,40 +742,27 @@ void handle_fasteoi_nmi(struct irq_desc
EXPORT_SYMBOL_GPL(handle_fasteoi_nmi);
/**
- * handle_edge_irq - edge type IRQ handler
- * @desc: the interrupt description structure for this irq
+ * handle_edge_irq - edge type IRQ handler
+ * @desc: the interrupt description structure for this irq
*
- * Interrupt occurs on the falling and/or rising edge of a hardware
- * signal. The occurrence is latched into the irq controller hardware
- * and must be acked in order to be reenabled. After the ack another
- * interrupt can happen on the same source even before the first one
- * is handled by the associated event handler. If this happens it
- * might be necessary to disable (mask) the interrupt depending on the
- * controller hardware. This requires to reenable the interrupt inside
- * of the loop which handles the interrupts which have arrived while
- * the handler was running. If all pending interrupts are handled, the
- * loop is left.
+ * Interrupt occurs on the falling and/or rising edge of a hardware
+ * signal. The occurrence is latched into the irq controller hardware and
+ * must be acked in order to be reenabled. After the ack another interrupt
+ * can happen on the same source even before the first one is handled by
+ * the associated event handler. If this happens it might be necessary to
+ * disable (mask) the interrupt depending on the controller hardware. This
+ * requires to reenable the interrupt inside of the loop which handles the
+ * interrupts which have arrived while the handler was running. If all
+ * pending interrupts are handled, the loop is left.
*/
void handle_edge_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- if (!irq_can_handle_pm(desc)) {
- desc->istate |= IRQS_PENDING;
- mask_ack_irq(desc);
- goto out_unlock;
- }
-
- /*
- * If its disabled or no action available then mask it and get
- * out of here.
- */
- if (irqd_irq_disabled(&desc->irq_data) || !desc->action) {
+ if (!irq_can_handle(desc)) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
- goto out_unlock;
+ return;
}
kstat_incr_irqs_this_cpu(desc);
@@ -786,7 +773,7 @@ void handle_edge_irq(struct irq_desc *de
do {
if (unlikely(!desc->action)) {
mask_irq(desc);
- goto out_unlock;
+ return;
}
/*
@@ -802,11 +789,7 @@ void handle_edge_irq(struct irq_desc *de
handle_irq_event(desc);
- } while ((desc->istate & IRQS_PENDING) &&
- !irqd_irq_disabled(&desc->irq_data));
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
+ } while ((desc->istate & IRQS_PENDING) && !irqd_irq_disabled(&desc->irq_data));
}
EXPORT_SYMBOL(handle_edge_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 18/45] genirq/chip: Rework handle_fasteoi_ack_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (16 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 17/45] genirq/chip: Rework handle_edge_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 19/45] genirq/chip: Rework handle_fasteoi_mask_irq() Thomas Gleixner
` (27 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 39 +++++++++++++--------------------------
1 file changed, 13 insertions(+), 26 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1138,53 +1138,40 @@ void irq_cpu_offline(void)
#ifdef CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS
/**
- * handle_fasteoi_ack_irq - irq handler for edge hierarchy
- * stacked on transparent controllers
+ * handle_fasteoi_ack_irq - irq handler for edge hierarchy stacked on
+ * transparent controllers
*
- * @desc: the interrupt description structure for this irq
+ * @desc: the interrupt description structure for this irq
*
- * Like handle_fasteoi_irq(), but for use with hierarchy where
- * the irq_chip also needs to have its ->irq_ack() function
- * called.
+ * Like handle_fasteoi_irq(), but for use with hierarchy where the irq_chip
+ * also needs to have its ->irq_ack() function called.
*/
void handle_fasteoi_ack_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
- if (!irq_can_handle_pm(desc))
- goto out;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+ if (!irq_can_handle_pm(desc)) {
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
+ }
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
+ if (unlikely(!irq_can_handle_actions(desc))) {
mask_irq(desc);
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
if (desc->istate & IRQS_ONESHOT)
mask_irq(desc);
- /* Start handling the irq */
desc->irq_data.chip->irq_ack(&desc->irq_data);
handle_irq_event(desc);
cond_unmask_eoi_irq(desc, chip);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 19/45] genirq/chip: Rework handle_fasteoi_mask_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (17 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 18/45] genirq/chip: Rework handle_fasteoi_ack_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 20/45] genirq/chip: Use lock guards where applicable Thomas Gleixner
` (26 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Note: The mask_irq() operation in the second condition was redundant as the
interrupt is already masked right at the beginning of the function.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 38 +++++++++-----------------------------
1 file changed, 9 insertions(+), 29 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1176,51 +1176,31 @@ void handle_fasteoi_ack_irq(struct irq_d
EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq);
/**
- * handle_fasteoi_mask_irq - irq handler for level hierarchy
- * stacked on transparent controllers
+ * handle_fasteoi_mask_irq - irq handler for level hierarchy stacked on
+ * transparent controllers
*
- * @desc: the interrupt description structure for this irq
+ * @desc: the interrupt description structure for this irq
*
- * Like handle_fasteoi_irq(), but for use with hierarchy where
- * the irq_chip also needs to have its ->irq_mask_ack() function
- * called.
+ * Like handle_fasteoi_irq(), but for use with hierarchy where the irq_chip
+ * also needs to have its ->irq_mask_ack() function called.
*/
void handle_fasteoi_mask_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
mask_ack_irq(desc);
- if (!irq_can_handle_pm(desc))
- goto out;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- mask_irq(desc);
- goto out;
+ if (!irq_can_handle(desc)) {
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
- if (desc->istate & IRQS_ONESHOT)
- mask_irq(desc);
handle_irq_event(desc);
cond_unmask_eoi_irq(desc, chip);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_mask_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 20/45] genirq/chip: Use lock guards where applicable
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (18 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 19/45] genirq/chip: Rework handle_fasteoi_mask_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 21/45] genirq/chip: Rework irq_set_chip() Thomas Gleixner
` (25 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1081,25 +1081,21 @@ EXPORT_SYMBOL_GPL(irq_modify_status);
*/
void irq_cpu_online(void)
{
- struct irq_desc *desc;
- struct irq_chip *chip;
- unsigned long flags;
unsigned int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_chip *chip;
+
if (!desc)
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
chip = irq_data_get_irq_chip(&desc->irq_data);
if (chip && chip->irq_cpu_online &&
(!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
!irqd_irq_disabled(&desc->irq_data)))
chip->irq_cpu_online(&desc->irq_data);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -1111,25 +1107,21 @@ void irq_cpu_online(void)
*/
void irq_cpu_offline(void)
{
- struct irq_desc *desc;
- struct irq_chip *chip;
- unsigned long flags;
unsigned int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_chip *chip;
+
if (!desc)
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
chip = irq_data_get_irq_chip(&desc->irq_data);
if (chip && chip->irq_cpu_offline &&
(!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
!irqd_irq_disabled(&desc->irq_data)))
chip->irq_cpu_offline(&desc->irq_data);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
#endif
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 21/45] genirq/chip: Rework irq_set_chip()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (19 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 20/45] genirq/chip: Use lock guards where applicable Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 22/45] genirq/chip: Rework irq_set_irq_type() Thomas Gleixner
` (24 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -34,26 +34,22 @@ struct irqaction chained_action = {
};
/**
- * irq_set_chip - set the irq chip for an irq
- * @irq: irq number
- * @chip: pointer to irq chip description structure
+ * irq_set_chip - set the irq chip for an irq
+ * @irq: irq number
+ * @chip: pointer to irq chip description structure
*/
int irq_set_chip(unsigned int irq, const struct irq_chip *chip)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+ int ret = -EINVAL;
- if (!desc)
- return -EINVAL;
-
- desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
- irq_put_desc_unlock(desc, flags);
- /*
- * For !CONFIG_SPARSE_IRQ make the irq show up in
- * allocated_irqs.
- */
- irq_mark_irq(irq);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
+ ret = 0;
+ }
+ /* For !CONFIG_SPARSE_IRQ make the irq show up in allocated_irqs. */
+ if (!ret)
+ irq_mark_irq(irq);
+ return ret;
}
EXPORT_SYMBOL(irq_set_chip);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 22/45] genirq/chip: Rework irq_set_irq_type()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (20 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 21/45] genirq/chip: Rework irq_set_chip() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 23/45] genirq/chip: Rework irq_set_handler_data() Thomas Gleixner
` (23 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -54,22 +54,15 @@ int irq_set_chip(unsigned int irq, const
EXPORT_SYMBOL(irq_set_chip);
/**
- * irq_set_irq_type - set the irq trigger type for an irq
- * @irq: irq number
- * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
+ * irq_set_irq_type - set the irq trigger type for an irq
+ * @irq: irq number
+ * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
*/
int irq_set_irq_type(unsigned int irq, unsigned int type)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
- int ret = 0;
-
- if (!desc)
- return -EINVAL;
-
- ret = __irq_set_trigger(desc, type);
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL)
+ return __irq_set_trigger(scoped_irqdesc, type);
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_irq_type);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 23/45] genirq/chip: Rework irq_set_handler_data()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (21 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 22/45] genirq/chip: Rework irq_set_irq_type() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 24/45] genirq/chip: Rework irq_set_msi_desc_off() Thomas Gleixner
` (22 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -67,22 +67,19 @@ int irq_set_irq_type(unsigned int irq, u
EXPORT_SYMBOL(irq_set_irq_type);
/**
- * irq_set_handler_data - set irq handler data for an irq
- * @irq: Interrupt number
- * @data: Pointer to interrupt specific data
+ * irq_set_handler_data - set irq handler data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to interrupt specific data
*
- * Set the hardware irq controller data for an irq
+ * Set the hardware irq controller data for an irq
*/
int irq_set_handler_data(unsigned int irq, void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
- desc->irq_common_data.handler_data = data;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_common_data.handler_data = data;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_handler_data);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 24/45] genirq/chip: Rework irq_set_msi_desc_off()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (22 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 23/45] genirq/chip: Rework irq_set_handler_data() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 25/45] genirq/chip: Rework irq_set_chip_data() Thomas Gleixner
` (21 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 38 +++++++++++++++++---------------------
1 file changed, 17 insertions(+), 21 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -84,34 +84,30 @@ int irq_set_handler_data(unsigned int ir
EXPORT_SYMBOL(irq_set_handler_data);
/**
- * irq_set_msi_desc_off - set MSI descriptor data for an irq at offset
- * @irq_base: Interrupt number base
- * @irq_offset: Interrupt number offset
- * @entry: Pointer to MSI descriptor data
+ * irq_set_msi_desc_off - set MSI descriptor data for an irq at offset
+ * @irq_base: Interrupt number base
+ * @irq_offset: Interrupt number offset
+ * @entry: Pointer to MSI descriptor data
*
- * Set the MSI descriptor entry for an irq at offset
+ * Set the MSI descriptor entry for an irq at offset
*/
-int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset,
- struct msi_desc *entry)
+int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset, struct msi_desc *entry)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq_base + irq_offset, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
- if (!desc)
- return -EINVAL;
- desc->irq_common_data.msi_desc = entry;
- if (entry && !irq_offset)
- entry->irq = irq_base;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq_base + irq_offset, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc->irq_common_data.msi_desc = entry;
+ if (entry && !irq_offset)
+ entry->irq = irq_base;
+ return 0;
+ }
+ return -EINVAL;
}
/**
- * irq_set_msi_desc - set MSI descriptor data for an irq
- * @irq: Interrupt number
- * @entry: Pointer to MSI descriptor data
+ * irq_set_msi_desc - set MSI descriptor data for an irq
+ * @irq: Interrupt number
+ * @entry: Pointer to MSI descriptor data
*
- * Set the MSI descriptor entry for an irq
+ * Set the MSI descriptor entry for an irq
*/
int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
{
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 25/45] genirq/chip: Rework irq_set_chip_data()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (23 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 24/45] genirq/chip: Rework irq_set_msi_desc_off() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants Thomas Gleixner
` (20 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -115,22 +115,19 @@ int irq_set_msi_desc(unsigned int irq, s
}
/**
- * irq_set_chip_data - set irq chip data for an irq
- * @irq: Interrupt number
- * @data: Pointer to chip specific data
+ * irq_set_chip_data - set irq chip data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to chip specific data
*
- * Set the hardware irq chip data for an irq
+ * Set the hardware irq chip data for an irq
*/
int irq_set_chip_data(unsigned int irq, void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
- desc->irq_data.chip_data = data;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_data.chip_data = data;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_chip_data);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (24 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 25/45] genirq/chip: Rework irq_set_chip_data() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-09 13:22 ` [patch V2 26/45] " Nathan Chancellor
2025-04-29 6:55 ` [patch V2 27/45] genirq/chip: Rework irq_modify_status() Thomas Gleixner
` (19 subsequent siblings)
45 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 34 +++++++++++-----------------------
1 file changed, 11 insertions(+), 23 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -973,35 +973,23 @@ static void
}
}
-void
-__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
- const char *name)
+void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+ const char *name)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
- if (!desc)
- return;
-
- __irq_do_set_handler(desc, handle, is_chained, name);
- irq_put_desc_busunlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, 0)
+ __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name);
}
EXPORT_SYMBOL_GPL(__irq_set_handler);
-void
-irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
- void *data)
+void irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
+ void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
- if (!desc)
- return;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
- desc->irq_common_data.handler_data = data;
- __irq_do_set_handler(desc, handle, 1, NULL);
-
- irq_put_desc_busunlock(desc, flags);
+ desc->irq_common_data.handler_data = data;
+ __irq_do_set_handler(desc, handle, 1, NULL);
+ }
}
EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 27/45] genirq/chip: Rework irq_modify_status()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (25 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 28/45] genirq/manage: Cleanup kernel doc comments Thomas Gleixner
` (18 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/chip.c | 58 +++++++++++++++++++++++++-----------------------------
1 file changed, 27 insertions(+), 31 deletions(-)
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1004,38 +1004,34 @@ EXPORT_SYMBOL_GPL(irq_set_chip_and_handl
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
{
- unsigned long flags, trigger, tmp;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ unsigned long trigger, tmp;
+ /*
+ * Warn when a driver sets the no autoenable flag on an already
+ * active interrupt.
+ */
+ WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
+
+ irq_settings_clr_and_set(desc, clr, set);
+
+ trigger = irqd_get_trigger_type(&desc->irq_data);
+
+ irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
+ IRQD_TRIGGER_MASK | IRQD_LEVEL);
+ if (irq_settings_has_no_balance_set(desc))
+ irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
+ if (irq_settings_is_per_cpu(desc))
+ irqd_set(&desc->irq_data, IRQD_PER_CPU);
+ if (irq_settings_is_level(desc))
+ irqd_set(&desc->irq_data, IRQD_LEVEL);
+
+ tmp = irq_settings_get_trigger_mask(desc);
+ if (tmp != IRQ_TYPE_NONE)
+ trigger = tmp;
- if (!desc)
- return;
-
- /*
- * Warn when a driver sets the no autoenable flag on an already
- * active interrupt.
- */
- WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
-
- irq_settings_clr_and_set(desc, clr, set);
-
- trigger = irqd_get_trigger_type(&desc->irq_data);
-
- irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
- IRQD_TRIGGER_MASK | IRQD_LEVEL);
- if (irq_settings_has_no_balance_set(desc))
- irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
- if (irq_settings_is_per_cpu(desc))
- irqd_set(&desc->irq_data, IRQD_PER_CPU);
- if (irq_settings_is_level(desc))
- irqd_set(&desc->irq_data, IRQD_LEVEL);
-
- tmp = irq_settings_get_trigger_mask(desc);
- if (tmp != IRQ_TYPE_NONE)
- trigger = tmp;
-
- irqd_set(&desc->irq_data, trigger);
-
- irq_put_desc_unlock(desc, flags);
+ irqd_set(&desc->irq_data, trigger);
+ }
}
EXPORT_SYMBOL_GPL(irq_modify_status);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 28/45] genirq/manage: Cleanup kernel doc comments
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (26 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 27/45] genirq/chip: Rework irq_modify_status() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 29/45] genirq/manage: Convert to lock guards Thomas Gleixner
` (17 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Get rid of the extra tab to make it consistent.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 570 +++++++++++++++++++++++++---------------------------
1 file changed, 276 insertions(+), 294 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -76,26 +76,25 @@ static void __synchronize_hardirq(struct
}
/**
- * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
- * @irq: interrupt number to wait for
+ * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
+ * @irq: interrupt number to wait for
*
- * This function waits for any pending hard IRQ handlers for this
- * interrupt to complete before returning. If you use this
- * function while holding a resource the IRQ handler may need you
- * will deadlock. It does not take associated threaded handlers
- * into account.
- *
- * Do not use this for shutdown scenarios where you must be sure
- * that all parts (hardirq and threaded handler) have completed.
- *
- * Returns: false if a threaded handler is active.
- *
- * This function may be called - with care - from IRQ context.
- *
- * It does not check whether there is an interrupt in flight at the
- * hardware level, but not serviced yet, as this might deadlock when
- * called with interrupts disabled and the target CPU of the interrupt
- * is the current CPU.
+ * This function waits for any pending hard IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock. It does not take
+ * associated threaded handlers into account.
+ *
+ * Do not use this for shutdown scenarios where you must be sure that all
+ * parts (hardirq and threaded handler) have completed.
+ *
+ * Returns: false if a threaded handler is active.
+ *
+ * This function may be called - with care - from IRQ context.
+ *
+ * It does not check whether there is an interrupt in flight at the
+ * hardware level, but not serviced yet, as this might deadlock when called
+ * with interrupts disabled and the target CPU of the interrupt is the
+ * current CPU.
*/
bool synchronize_hardirq(unsigned int irq)
{
@@ -121,19 +120,19 @@ static void __synchronize_irq(struct irq
}
/**
- * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
- * @irq: interrupt number to wait for
+ * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ * @irq: interrupt number to wait for
*
- * This function waits for any pending IRQ handlers for this interrupt
- * to complete before returning. If you use this function while
- * holding a resource the IRQ handler may need you will deadlock.
- *
- * Can only be called from preemptible code as it might sleep when
- * an interrupt thread is associated to @irq.
- *
- * It optionally makes sure (when the irq chip supports that method)
- * that the interrupt is not pending in any CPU and waiting for
- * service.
+ * This function waits for any pending IRQ handlers for this interrupt to
+ * complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock.
+ *
+ * Can only be called from preemptible code as it might sleep when
+ * an interrupt thread is associated to @irq.
+ *
+ * It optionally makes sure (when the irq chip supports that method)
+ * that the interrupt is not pending in any CPU and waiting for
+ * service.
*/
void synchronize_irq(unsigned int irq)
{
@@ -156,8 +155,8 @@ static bool __irq_can_set_affinity(struc
}
/**
- * irq_can_set_affinity - Check if the affinity of a given irq can be set
- * @irq: Interrupt to check
+ * irq_can_set_affinity - Check if the affinity of a given irq can be set
+ * @irq: Interrupt to check
*
*/
int irq_can_set_affinity(unsigned int irq)
@@ -181,13 +180,13 @@ bool irq_can_set_affinity_usr(unsigned i
}
/**
- * irq_set_thread_affinity - Notify irq threads to adjust affinity
- * @desc: irq descriptor which has affinity changed
+ * irq_set_thread_affinity - Notify irq threads to adjust affinity
+ * @desc: irq descriptor which has affinity changed
*
- * We just set IRQTF_AFFINITY and delegate the affinity setting
- * to the interrupt thread itself. We can not call
- * set_cpus_allowed_ptr() here as we hold desc->lock and this
- * code can be called from hard interrupt context.
+ * Just set IRQTF_AFFINITY and delegate the affinity setting to the
+ * interrupt thread itself. We can not call set_cpus_allowed_ptr() here as
+ * we hold desc->lock and this code can be called from hard interrupt
+ * context.
*/
static void irq_set_thread_affinity(struct irq_desc *desc)
{
@@ -543,18 +542,17 @@ static void irq_affinity_notify(struct w
}
/**
- * irq_set_affinity_notifier - control notification of IRQ affinity changes
- * @irq: Interrupt for which to enable/disable notification
- * @notify: Context for notification, or %NULL to disable
- * notification. Function pointers must be initialised;
- * the other fields will be initialised by this function.
- *
- * Must be called in process context. Notification may only be enabled
- * after the IRQ is allocated and must be disabled before the IRQ is
- * freed using free_irq().
+ * irq_set_affinity_notifier - control notification of IRQ affinity changes
+ * @irq: Interrupt for which to enable/disable notification
+ * @notify: Context for notification, or %NULL to disable
+ * notification. Function pointers must be initialised;
+ * the other fields will be initialised by this function.
+ *
+ * Must be called in process context. Notification may only be enabled
+ * after the IRQ is allocated and must be disabled before the IRQ is freed
+ * using free_irq().
*/
-int
-irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
+int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_affinity_notify *old_notify;
@@ -645,15 +643,14 @@ int irq_setup_affinity(struct irq_desc *
/**
- * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
- * @irq: interrupt number to set affinity
- * @vcpu_info: vCPU specific data or pointer to a percpu array of vCPU
- * specific data for percpu_devid interrupts
- *
- * This function uses the vCPU specific data to set the vCPU
- * affinity for an irq. The vCPU specific data is passed from
- * outside, such as KVM. One example code path is as below:
- * KVM -> IOMMU -> irq_set_vcpu_affinity().
+ * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
+ * @irq: interrupt number to set affinity
+ * @vcpu_info: vCPU specific data or pointer to a percpu array of vCPU
+ * specific data for percpu_devid interrupts
+ *
+ * This function uses the vCPU specific data to set the vCPU affinity for
+ * an irq. The vCPU specific data is passed from outside, such as KVM. One
+ * example code path is as below: KVM -> IOMMU -> irq_set_vcpu_affinity().
*/
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
{
@@ -705,15 +702,15 @@ static int __disable_irq_nosync(unsigned
}
/**
- * disable_irq_nosync - disable an irq without waiting
- * @irq: Interrupt to disable
+ * disable_irq_nosync - disable an irq without waiting
+ * @irq: Interrupt to disable
*
- * Disable the selected interrupt line. Disables and Enables are
- * nested.
- * Unlike disable_irq(), this function does not ensure existing
- * instances of the IRQ handler have completed before returning.
+ * Disable the selected interrupt line. Disables and Enables are
+ * nested.
+ * Unlike disable_irq(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
*
- * This function may be called from IRQ context.
+ * This function may be called from IRQ context.
*/
void disable_irq_nosync(unsigned int irq)
{
@@ -722,17 +719,17 @@ void disable_irq_nosync(unsigned int irq
EXPORT_SYMBOL(disable_irq_nosync);
/**
- * disable_irq - disable an irq and wait for completion
- * @irq: Interrupt to disable
+ * disable_irq - disable an irq and wait for completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Enables and Disables are nested.
*
- * Disable the selected interrupt line. Enables and Disables are
- * nested.
- * This function waits for any pending IRQ handlers for this interrupt
- * to complete before returning. If you use this function while
- * holding a resource the IRQ handler may need you will deadlock.
+ * This function waits for any pending IRQ handlers for this interrupt to
+ * complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock.
*
- * Can only be called from preemptible code as it might sleep when
- * an interrupt thread is associated to @irq.
+ * Can only be called from preemptible code as it might sleep when an
+ * interrupt thread is associated to @irq.
*
*/
void disable_irq(unsigned int irq)
@@ -744,40 +741,39 @@ void disable_irq(unsigned int irq)
EXPORT_SYMBOL(disable_irq);
/**
- * disable_hardirq - disables an irq and waits for hardirq completion
- * @irq: Interrupt to disable
+ * disable_hardirq - disables an irq and waits for hardirq completion
+ * @irq: Interrupt to disable
*
- * Disable the selected interrupt line. Enables and Disables are
- * nested.
- * This function waits for any pending hard IRQ handlers for this
- * interrupt to complete before returning. If you use this function while
- * holding a resource the hard IRQ handler may need you will deadlock.
+ * Disable the selected interrupt line. Enables and Disables are nested.
*
- * When used to optimistically disable an interrupt from atomic context
- * the return value must be checked.
+ * This function waits for any pending hard IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while holding a
+ * resource the hard IRQ handler may need you will deadlock.
*
- * Returns: false if a threaded handler is active.
+ * When used to optimistically disable an interrupt from atomic context the
+ * return value must be checked.
*
- * This function may be called - with care - from IRQ context.
+ * Returns: false if a threaded handler is active.
+ *
+ * This function may be called - with care - from IRQ context.
*/
bool disable_hardirq(unsigned int irq)
{
if (!__disable_irq_nosync(irq))
return synchronize_hardirq(irq);
-
return false;
}
EXPORT_SYMBOL_GPL(disable_hardirq);
/**
- * disable_nmi_nosync - disable an nmi without waiting
- * @irq: Interrupt to disable
+ * disable_nmi_nosync - disable an nmi without waiting
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Disables and enables are nested.
*
- * Disable the selected interrupt line. Disables and enables are
- * nested.
- * The interrupt to disable must have been requested through request_nmi.
- * Unlike disable_nmi(), this function does not ensure existing
- * instances of the IRQ handler have completed before returning.
+ * The interrupt to disable must have been requested through request_nmi.
+ * Unlike disable_nmi(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
*/
void disable_nmi_nosync(unsigned int irq)
{
@@ -817,15 +813,14 @@ void __enable_irq(struct irq_desc *desc)
}
/**
- * enable_irq - enable handling of an irq
- * @irq: Interrupt to enable
+ * enable_irq - enable handling of an irq
+ * @irq: Interrupt to enable
*
- * Undoes the effect of one call to disable_irq(). If this
- * matches the last disable, processing of interrupts on this
- * IRQ line is re-enabled.
+ * Undoes the effect of one call to disable_irq(). If this matches the
+ * last disable, processing of interrupts on this IRQ line is re-enabled.
*
- * This function may be called from IRQ context only when
- * desc->irq_data.chip->bus_lock and desc->chip->bus_sync_unlock are NULL !
+ * This function may be called from IRQ context only when
+ * desc->irq_data.chip->bus_lock and desc->chip->bus_sync_unlock are NULL !
*/
void enable_irq(unsigned int irq)
{
@@ -845,13 +840,12 @@ void enable_irq(unsigned int irq)
EXPORT_SYMBOL(enable_irq);
/**
- * enable_nmi - enable handling of an nmi
- * @irq: Interrupt to enable
+ * enable_nmi - enable handling of an nmi
+ * @irq: Interrupt to enable
*
- * The interrupt to enable must have been requested through request_nmi.
- * Undoes the effect of one call to disable_nmi(). If this
- * matches the last disable, processing of interrupts on this
- * IRQ line is re-enabled.
+ * The interrupt to enable must have been requested through request_nmi.
+ * Undoes the effect of one call to disable_nmi(). If this matches the last
+ * disable, processing of interrupts on this IRQ line is re-enabled.
*/
void enable_nmi(unsigned int irq)
{
@@ -873,23 +867,22 @@ static int set_irq_wake_real(unsigned in
}
/**
- * irq_set_irq_wake - control irq power management wakeup
- * @irq: interrupt to control
- * @on: enable/disable power management wakeup
- *
- * Enable/disable power management wakeup mode, which is
- * disabled by default. Enables and disables must match,
- * just as they match for non-wakeup mode support.
- *
- * Wakeup mode lets this IRQ wake the system from sleep
- * states like "suspend to RAM".
- *
- * Note: irq enable/disable state is completely orthogonal
- * to the enable/disable state of irq wake. An irq can be
- * disabled with disable_irq() and still wake the system as
- * long as the irq has wake enabled. If this does not hold,
- * then the underlying irq chip and the related driver need
- * to be investigated.
+ * irq_set_irq_wake - control irq power management wakeup
+ * @irq: interrupt to control
+ * @on: enable/disable power management wakeup
+ *
+ * Enable/disable power management wakeup mode, which is disabled by
+ * default. Enables and disables must match, just as they match for
+ * non-wakeup mode support.
+ *
+ * Wakeup mode lets this IRQ wake the system from sleep states like
+ * "suspend to RAM".
+ *
+ * Note: irq enable/disable state is completely orthogonal to the
+ * enable/disable state of irq wake. An irq can be disabled with
+ * disable_irq() and still wake the system as long as the irq has wake
+ * enabled. If this does not hold, then the underlying irq chip and the
+ * related driver need to be investigated.
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
@@ -1334,10 +1327,9 @@ static int irq_thread(void *data)
}
/**
- * irq_wake_thread - wake the irq thread for the action identified by dev_id
- * @irq: Interrupt line
- * @dev_id: Device identity for which the thread should be woken
- *
+ * irq_wake_thread - wake the irq thread for the action identified by dev_id
+ * @irq: Interrupt line
+ * @dev_id: Device identity for which the thread should be woken
*/
void irq_wake_thread(unsigned int irq, void *dev_id)
{
@@ -2005,20 +1997,19 @@ static struct irqaction *__free_irq(stru
}
/**
- * free_irq - free an interrupt allocated with request_irq
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
- *
- * Remove an interrupt handler. The handler is removed and if the
- * interrupt line is no longer in use by any driver it is disabled.
- * On a shared IRQ the caller must ensure the interrupt is disabled
- * on the card it drives before calling this function. The function
- * does not return until any executing interrupts for this IRQ
- * have completed.
+ * free_irq - free an interrupt allocated with request_irq
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
+ *
+ * Remove an interrupt handler. The handler is removed and if the interrupt
+ * line is no longer in use by any driver it is disabled. On a shared IRQ
+ * the caller must ensure the interrupt is disabled on the card it drives
+ * before calling this function. The function does not return until any
+ * executing interrupts for this IRQ have completed.
*
- * This function must not be called from interrupt context.
+ * This function must not be called from interrupt context.
*
- * Returns the devname argument passed to request_irq.
+ * Returns the devname argument passed to request_irq.
*/
const void *free_irq(unsigned int irq, void *dev_id)
{
@@ -2099,42 +2090,40 @@ const void *free_nmi(unsigned int irq, v
}
/**
- * request_threaded_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Primary handler for threaded interrupts.
- * If handler is NULL and thread_fn != NULL
- * the default primary handler is installed.
- * @thread_fn: Function called from the irq handler thread
- * If NULL, no irq thread is created
- * @irqflags: Interrupt type flags
- * @devname: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. From the point this
- * call is made your handler function may be invoked. Since
- * your handler function must clear any interrupt the board
- * raises, you must take care both to initialise your hardware
- * and to set up the interrupt handler in the right order.
- *
- * If you want to set up a threaded irq handler for your device
- * then you need to supply @handler and @thread_fn. @handler is
- * still called in hard interrupt context and has to check
- * whether the interrupt originates from the device. If yes it
- * needs to disable the interrupt on the device and return
- * IRQ_WAKE_THREAD which will wake up the handler thread and run
- * @thread_fn. This split handler design is necessary to support
- * shared interrupts.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
+ * request_threaded_irq - allocate an interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Primary handler for threaded interrupts.
+ * If handler is NULL and thread_fn != NULL
+ * the default primary handler is installed.
+ * @thread_fn: Function called from the irq handler thread
+ * If NULL, no irq thread is created
+ * @irqflags: Interrupt type flags
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. From the point this call is made your handler function
+ * may be invoked. Since your handler function must clear any interrupt the
+ * board raises, you must take care both to initialise your hardware and to
+ * set up the interrupt handler in the right order.
+ *
+ * If you want to set up a threaded irq handler for your device then you
+ * need to supply @handler and @thread_fn. @handler is still called in hard
+ * interrupt context and has to check whether the interrupt originates from
+ * the device. If yes it needs to disable the interrupt on the device and
+ * return IRQ_WAKE_THREAD which will wake up the handler thread and run
+ * @thread_fn. This split handler design is necessary to support shared
+ * interrupts.
+ *
+ * @dev_id must be globally unique. Normally the address of the device data
+ * structure is used as the cookie. Since the handler receives this value
+ * it makes sense to use it.
*
- * If your interrupt is shared you must pass a non NULL dev_id
- * as this is required when freeing the interrupt.
+ * If your interrupt is shared you must pass a non NULL dev_id as this is
+ * required when freeing the interrupt.
*
- * Flags:
+ * Flags:
*
* IRQF_SHARED Interrupt is shared
* IRQF_TRIGGER_* Specify active edge(s) or level
@@ -2232,21 +2221,20 @@ int request_threaded_irq(unsigned int ir
EXPORT_SYMBOL(request_threaded_irq);
/**
- * request_any_context_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Threaded handler for threaded interrupts.
- * @flags: Interrupt type flags
- * @name: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. It selects either a
- * hardirq or threaded handling method depending on the
- * context.
+ * request_any_context_irq - allocate an interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Threaded handler for threaded interrupts.
+ * @flags: Interrupt type flags
+ * @name: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. It selects either a hardirq or threaded handling
+ * method depending on the context.
*
- * On failure, it returns a negative value. On success,
- * it returns either IRQC_IS_HARDIRQ or IRQC_IS_NESTED.
+ * Returns: On failure, it returns a negative value. On success, it returns either
+ * IRQC_IS_HARDIRQ or IRQC_IS_NESTED.
*/
int request_any_context_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev_id)
@@ -2273,30 +2261,29 @@ int request_any_context_irq(unsigned int
EXPORT_SYMBOL_GPL(request_any_context_irq);
/**
- * request_nmi - allocate an interrupt line for NMI delivery
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Threaded handler for threaded interrupts.
- * @irqflags: Interrupt type flags
- * @name: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. It sets up the IRQ line
- * to be handled as an NMI.
- *
- * An interrupt line delivering NMIs cannot be shared and IRQ handling
- * cannot be threaded.
- *
- * Interrupt lines requested for NMI delivering must produce per cpu
- * interrupts and have auto enabling setting disabled.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
+ * request_nmi - allocate an interrupt line for NMI delivery
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Threaded handler for threaded interrupts.
+ * @irqflags: Interrupt type flags
+ * @name: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. It sets up the IRQ line to be handled as an NMI.
+ *
+ * An interrupt line delivering NMIs cannot be shared and IRQ handling
+ * cannot be threaded.
+ *
+ * Interrupt lines requested for NMI delivering must produce per cpu
+ * interrupts and have auto enabling setting disabled.
+ *
+ * @dev_id must be globally unique. Normally the address of the device data
+ * structure is used as the cookie. Since the handler receives this value
+ * it makes sense to use it.
*
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail and return a negative value.
+ * If the interrupt line cannot be used to deliver NMIs, function will fail
+ * and return a negative value.
*/
int request_nmi(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *name, void *dev_id)
@@ -2498,9 +2485,9 @@ static struct irqaction *__free_percpu_i
}
/**
- * remove_percpu_irq - free a per-cpu interrupt
- * @irq: Interrupt line to free
- * @act: irqaction for the interrupt
+ * remove_percpu_irq - free a per-cpu interrupt
+ * @irq: Interrupt line to free
+ * @act: irqaction for the interrupt
*
* Used to remove interrupts statically setup by the early boot process.
*/
@@ -2509,20 +2496,20 @@ void remove_percpu_irq(unsigned int irq,
struct irq_desc *desc = irq_to_desc(irq);
if (desc && irq_settings_is_per_cpu_devid(desc))
- __free_percpu_irq(irq, act->percpu_dev_id);
+ __free_percpu_irq(irq, act->percpu_dev_id);
}
/**
- * free_percpu_irq - free an interrupt allocated with request_percpu_irq
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
+ * free_percpu_irq - free an interrupt allocated with request_percpu_irq
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
*
- * Remove a percpu interrupt handler. The handler is removed, but
- * the interrupt line is not disabled. This must be done on each
- * CPU before calling this function. The function does not return
- * until any executing interrupts for this IRQ have completed.
+ * Remove a percpu interrupt handler. The handler is removed, but the
+ * interrupt line is not disabled. This must be done on each CPU before
+ * calling this function. The function does not return until any executing
+ * interrupts for this IRQ have completed.
*
- * This function must not be called from interrupt context.
+ * This function must not be called from interrupt context.
*/
void free_percpu_irq(unsigned int irq, void __percpu *dev_id)
{
@@ -2551,9 +2538,9 @@ void free_percpu_nmi(unsigned int irq, v
}
/**
- * setup_percpu_irq - setup a per-cpu interrupt
- * @irq: Interrupt line to setup
- * @act: irqaction for the interrupt
+ * setup_percpu_irq - setup a per-cpu interrupt
+ * @irq: Interrupt line to setup
+ * @act: irqaction for the interrupt
*
* Used to statically setup per-cpu interrupts in the early boot process.
*/
@@ -2578,21 +2565,20 @@ int setup_percpu_irq(unsigned int irq, s
}
/**
- * __request_percpu_irq - allocate a percpu interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * @flags: Interrupt type flags (IRQF_TIMER only)
- * @devname: An ascii name for the claiming device
- * @dev_id: A percpu cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt on the local CPU. If the interrupt is supposed to be
- * enabled on other CPUs, it has to be done on each CPU using
- * enable_percpu_irq().
- *
- * Dev_id must be globally unique. It is a per-cpu variable, and
- * the handler gets called with the interrupted CPU's instance of
- * that variable.
+ * __request_percpu_irq - allocate a percpu interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * @flags: Interrupt type flags (IRQF_TIMER only)
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A percpu cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt on the
+ * local CPU. If the interrupt is supposed to be enabled on other CPUs, it
+ * has to be done on each CPU using enable_percpu_irq().
+ *
+ * @dev_id must be globally unique. It is a per-cpu variable, and
+ * the handler gets called with the interrupted CPU's instance of
+ * that variable.
*/
int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *devname,
@@ -2640,25 +2626,25 @@ int __request_percpu_irq(unsigned int ir
EXPORT_SYMBOL_GPL(__request_percpu_irq);
/**
- * request_percpu_nmi - allocate a percpu interrupt line for NMI delivery
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * @name: An ascii name for the claiming device
- * @dev_id: A percpu cookie passed back to the handler function
- *
- * This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs
- * have to be setup on each CPU by calling prepare_percpu_nmi() before
- * being enabled on the same CPU by using enable_percpu_nmi().
- *
- * Dev_id must be globally unique. It is a per-cpu variable, and
- * the handler gets called with the interrupted CPU's instance of
- * that variable.
+ * request_percpu_nmi - allocate a percpu interrupt line for NMI delivery
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * @name: An ascii name for the claiming device
+ * @dev_id: A percpu cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs
+ * have to be setup on each CPU by calling prepare_percpu_nmi() before
+ * being enabled on the same CPU by using enable_percpu_nmi().
+ *
+ * @dev_id must be globally unique. It is a per-cpu variable, and the
+ * handler gets called with the interrupted CPU's instance of that
+ * variable.
*
- * Interrupt lines requested for NMI delivering should have auto enabling
- * setting disabled.
+ * Interrupt lines requested for NMI delivering should have auto enabling
+ * setting disabled.
*
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail returning a negative value.
+ * If the interrupt line cannot be used to deliver NMIs, function
+ * will fail returning a negative value.
*/
int request_percpu_nmi(unsigned int irq, irq_handler_t handler,
const char *name, void __percpu *dev_id)
@@ -2716,17 +2702,17 @@ int request_percpu_nmi(unsigned int irq,
}
/**
- * prepare_percpu_nmi - performs CPU local setup for NMI delivery
- * @irq: Interrupt line to prepare for NMI delivery
+ * prepare_percpu_nmi - performs CPU local setup for NMI delivery
+ * @irq: Interrupt line to prepare for NMI delivery
*
- * This call prepares an interrupt line to deliver NMI on the current CPU,
- * before that interrupt line gets enabled with enable_percpu_nmi().
+ * This call prepares an interrupt line to deliver NMI on the current CPU,
+ * before that interrupt line gets enabled with enable_percpu_nmi().
*
- * As a CPU local operation, this should be called from non-preemptible
- * context.
+ * As a CPU local operation, this should be called from non-preemptible
+ * context.
*
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail returning a negative value.
+ * If the interrupt line cannot be used to deliver NMIs, function will fail
+ * returning a negative value.
*/
int prepare_percpu_nmi(unsigned int irq)
{
@@ -2760,16 +2746,14 @@ int prepare_percpu_nmi(unsigned int irq)
}
/**
- * teardown_percpu_nmi - undoes NMI setup of IRQ line
- * @irq: Interrupt line from which CPU local NMI configuration should be
- * removed
- *
- * This call undoes the setup done by prepare_percpu_nmi().
+ * teardown_percpu_nmi - undoes NMI setup of IRQ line
+ * @irq: Interrupt line from which CPU local NMI configuration should be removed
*
- * IRQ line should not be enabled for the current CPU.
+ * This call undoes the setup done by prepare_percpu_nmi().
*
- * As a CPU local operation, this should be called from non-preemptible
- * context.
+ * IRQ line should not be enabled for the current CPU.
+ * As a CPU local operation, this should be called from non-preemptible
+ * context.
*/
void teardown_percpu_nmi(unsigned int irq)
{
@@ -2815,17 +2799,16 @@ static int __irq_get_irqchip_state(struc
}
/**
- * irq_get_irqchip_state - returns the irqchip state of a interrupt.
- * @irq: Interrupt line that is forwarded to a VM
- * @which: One of IRQCHIP_STATE_* the caller wants to know about
- * @state: a pointer to a boolean where the state is to be stored
- *
- * This call snapshots the internal irqchip state of an
- * interrupt, returning into @state the bit corresponding to
- * stage @which
+ * irq_get_irqchip_state - returns the irqchip state of a interrupt.
+ * @irq: Interrupt line that is forwarded to a VM
+ * @which: One of IRQCHIP_STATE_* the caller wants to know about
+ * @state: a pointer to a boolean where the state is to be stored
+ *
+ * This call snapshots the internal irqchip state of an interrupt,
+ * returning into @state the bit corresponding to stage @which
*
- * This function should be called with preemption disabled if the
- * interrupt controller has per-cpu registers.
+ * This function should be called with preemption disabled if the interrupt
+ * controller has per-cpu registers.
*/
int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
bool *state)
@@ -2849,19 +2832,18 @@ int irq_get_irqchip_state(unsigned int i
EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
/**
- * irq_set_irqchip_state - set the state of a forwarded interrupt.
- * @irq: Interrupt line that is forwarded to a VM
- * @which: State to be restored (one of IRQCHIP_STATE_*)
- * @val: Value corresponding to @which
+ * irq_set_irqchip_state - set the state of a forwarded interrupt.
+ * @irq: Interrupt line that is forwarded to a VM
+ * @which: State to be restored (one of IRQCHIP_STATE_*)
+ * @val: Value corresponding to @which
*
- * This call sets the internal irqchip state of an interrupt,
- * depending on the value of @which.
+ * This call sets the internal irqchip state of an interrupt, depending on
+ * the value of @which.
*
- * This function should be called with migration disabled if the
- * interrupt controller has per-cpu registers.
+ * This function should be called with migration disabled if the interrupt
+ * controller has per-cpu registers.
*/
-int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
- bool val)
+int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool val)
{
struct irq_desc *desc;
struct irq_data *data;
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 29/45] genirq/manage: Convert to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (27 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 28/45] genirq/manage: Cleanup kernel doc comments Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 30/45] genirq/manage: Rework irq_update_affinity_desc() Thomas Gleixner
` (16 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Convert lock/unlock pairs to guards.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 155 +++++++++++++++++++---------------------------------
1 file changed, 58 insertions(+), 97 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -41,8 +41,6 @@ static void __synchronize_hardirq(struct
bool inprogress;
do {
- unsigned long flags;
-
/*
* Wait until we're out of the critical section. This might
* give the wrong answer due to the lack of memory barriers.
@@ -51,7 +49,7 @@ static void __synchronize_hardirq(struct
cpu_relax();
/* Ok, that indicated we're done: double-check carefully. */
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
inprogress = irqd_irq_inprogress(&desc->irq_data);
/*
@@ -67,8 +65,6 @@ static void __synchronize_hardirq(struct
__irq_get_irqchip_state(irqd, IRQCHIP_STATE_ACTIVE,
&inprogress);
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
/* Oops, that failed? */
} while (inprogress);
}
@@ -456,16 +452,12 @@ static int __irq_set_affinity(unsigned i
bool force)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- int ret;
if (!desc)
return -EINVAL;
- raw_spin_lock_irqsave(&desc->lock, flags);
- ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return ret;
+ guard(raw_spinlock_irqsave)(&desc->lock);
+ return irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
}
/**
@@ -520,17 +512,16 @@ static void irq_affinity_notify(struct w
container_of(work, struct irq_affinity_notify, work);
struct irq_desc *desc = irq_to_desc(notify->irq);
cpumask_var_t cpumask;
- unsigned long flags;
if (!desc || !alloc_cpumask_var(&cpumask, GFP_KERNEL))
goto out;
- raw_spin_lock_irqsave(&desc->lock, flags);
- if (irq_move_pending(&desc->irq_data))
- irq_get_pending(cpumask, desc);
- else
- cpumask_copy(cpumask, desc->irq_common_data.affinity);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ if (irq_move_pending(&desc->irq_data))
+ irq_get_pending(cpumask, desc);
+ else
+ cpumask_copy(cpumask, desc->irq_common_data.affinity);
+ }
notify->notify(notify, cpumask);
@@ -554,7 +545,6 @@ int irq_set_affinity_notifier(unsigned i
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_affinity_notify *old_notify;
- unsigned long flags;
/* The release function is promised process context */
might_sleep();
@@ -569,10 +559,10 @@ int irq_set_affinity_notifier(unsigned i
INIT_WORK(¬ify->work, irq_affinity_notify);
}
- raw_spin_lock_irqsave(&desc->lock, flags);
- old_notify = desc->affinity_notify;
- desc->affinity_notify = notify;
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ old_notify = desc->affinity_notify;
+ desc->affinity_notify = notify;
+ }
if (old_notify) {
if (cancel_work_sync(&old_notify->work)) {
@@ -593,7 +583,8 @@ EXPORT_SYMBOL_GPL(irq_set_affinity_notif
int irq_setup_affinity(struct irq_desc *desc)
{
struct cpumask *set = irq_default_affinity;
- int ret, node = irq_desc_get_node(desc);
+ int node = irq_desc_get_node(desc);
+
static DEFINE_RAW_SPINLOCK(mask_lock);
static struct cpumask mask;
@@ -601,7 +592,7 @@ int irq_setup_affinity(struct irq_desc *
if (!__irq_can_set_affinity(desc))
return 0;
- raw_spin_lock(&mask_lock);
+ guard(raw_spinlock)(&mask_lock);
/*
* Preserve the managed affinity setting and a userspace affinity
* setup, but make sure that one of the targets is online.
@@ -626,9 +617,7 @@ int irq_setup_affinity(struct irq_desc *
if (cpumask_intersects(&mask, nodemask))
cpumask_and(&mask, &mask, nodemask);
}
- ret = irq_do_set_affinity(&desc->irq_data, &mask, false);
- raw_spin_unlock(&mask_lock);
- return ret;
+ return irq_do_set_affinity(&desc->irq_data, &mask, false);
}
#else
/* Wrapper for ALPHA specific affinity selector magic */
@@ -1070,19 +1059,19 @@ static void irq_thread_check_affinity(st
return;
}
- raw_spin_lock_irq(&desc->lock);
- /*
- * This code is triggered unconditionally. Check the affinity
- * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
- */
- if (cpumask_available(desc->irq_common_data.affinity)) {
- const struct cpumask *m;
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ /*
+ * This code is triggered unconditionally. Check the affinity
+ * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
+ */
+ if (cpumask_available(desc->irq_common_data.affinity)) {
+ const struct cpumask *m;
- m = irq_data_get_effective_affinity_mask(&desc->irq_data);
- cpumask_copy(mask, m);
- valid = true;
+ m = irq_data_get_effective_affinity_mask(&desc->irq_data);
+ cpumask_copy(mask, m);
+ valid = true;
+ }
}
- raw_spin_unlock_irq(&desc->lock);
if (valid)
set_cpus_allowed_ptr(current, mask);
@@ -1250,9 +1239,8 @@ static void irq_wake_secondary(struct ir
if (WARN_ON_ONCE(!secondary))
return;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
__irq_wake_thread(desc, secondary);
- raw_spin_unlock_irq(&desc->lock);
}
/*
@@ -1333,12 +1321,11 @@ void irq_wake_thread(unsigned int irq, v
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
for_each_action_of_desc(desc, action) {
if (action->dev_id == dev_id) {
if (action->thread)
@@ -1346,7 +1333,6 @@ void irq_wake_thread(unsigned int irq, v
break;
}
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
EXPORT_SYMBOL_GPL(irq_wake_thread);
@@ -1977,9 +1963,8 @@ static struct irqaction *__free_irq(stru
* There is no interrupt on the fly anymore. Deactivate it
* completely.
*/
- raw_spin_lock_irqsave(&desc->lock, flags);
- irq_domain_deactivate_irq(&desc->irq_data);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ irq_domain_deactivate_irq(&desc->irq_data);
irq_release_resources(desc);
chip_bus_sync_unlock(desc);
@@ -2064,8 +2049,6 @@ static const void *__cleanup_nmi(unsigne
const void *free_nmi(unsigned int irq, void *dev_id)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- const void *devname;
if (!desc || WARN_ON(!irq_is_nmi(desc)))
return NULL;
@@ -2077,14 +2060,9 @@ const void *free_nmi(unsigned int irq, v
if (WARN_ON(desc->depth == 0))
disable_nmi_nosync(irq);
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
irq_nmi_teardown(desc);
- devname = __cleanup_nmi(irq, desc);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
- return devname;
+ return __cleanup_nmi(irq, desc);
}
/**
@@ -2288,7 +2266,6 @@ int request_nmi(unsigned int irq, irq_ha
{
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
int retval;
if (irq == IRQ_NOTCONNECTED)
@@ -2330,21 +2307,17 @@ int request_nmi(unsigned int irq, irq_ha
if (retval)
goto err_irq_setup;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- /* Setup NMI state */
- desc->istate |= IRQS_NMI;
- retval = irq_nmi_setup(desc);
- if (retval) {
- __cleanup_nmi(irq, desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return -EINVAL;
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ /* Setup NMI state */
+ desc->istate |= IRQS_NMI;
+ retval = irq_nmi_setup(desc);
+ if (retval) {
+ __cleanup_nmi(irq, desc);
+ return -EINVAL;
+ }
+ return 0;
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
- return 0;
-
err_irq_setup:
irq_chip_pm_put(&desc->irq_data);
err_out:
@@ -2443,43 +2416,34 @@ static struct irqaction *__free_percpu_i
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
if (!desc)
return NULL;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ action = desc->action;
+ if (!action || action->percpu_dev_id != dev_id) {
+ WARN(1, "Trying to free already-free IRQ %d\n", irq);
+ return NULL;
+ }
- action = desc->action;
- if (!action || action->percpu_dev_id != dev_id) {
- WARN(1, "Trying to free already-free IRQ %d\n", irq);
- goto bad;
- }
+ if (!cpumask_empty(desc->percpu_enabled)) {
+ WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
+ irq, cpumask_first(desc->percpu_enabled));
+ return NULL;
+ }
- if (!cpumask_empty(desc->percpu_enabled)) {
- WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
- irq, cpumask_first(desc->percpu_enabled));
- goto bad;
+ /* Found it - now remove it from the list of entries: */
+ desc->action = NULL;
+ desc->istate &= ~IRQS_NMI;
}
- /* Found it - now remove it from the list of entries: */
- desc->action = NULL;
-
- desc->istate &= ~IRQS_NMI;
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
unregister_handler_proc(irq, action);
-
irq_chip_pm_put(&desc->irq_data);
module_put(desc->owner);
return action;
-
-bad:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return NULL;
}
/**
@@ -2649,7 +2613,6 @@ int request_percpu_nmi(unsigned int irq,
{
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
int retval;
if (!handler)
@@ -2685,10 +2648,8 @@ int request_percpu_nmi(unsigned int irq,
if (retval)
goto err_irq_setup;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
desc->istate |= IRQS_NMI;
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
return 0;
err_irq_setup:
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 30/45] genirq/manage: Rework irq_update_affinity_desc()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (28 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 29/45] genirq/manage: Convert to lock guards Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 31/45] genirq/manage: Rework __irq_apply_affinity_hint() Thomas Gleixner
` (15 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 76 +++++++++++++++++++++-------------------------------
1 file changed, 32 insertions(+), 44 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -393,14 +393,8 @@ int irq_set_affinity_locked(struct irq_d
* an interrupt which is already started or which has already been configured
* as managed will also fail, as these mean invalid init state or double init.
*/
-int irq_update_affinity_desc(unsigned int irq,
- struct irq_affinity_desc *affinity)
+int irq_update_affinity_desc(unsigned int irq, struct irq_affinity_desc *affinity)
{
- struct irq_desc *desc;
- unsigned long flags;
- bool activated;
- int ret = 0;
-
/*
* Supporting this with the reservation scheme used by x86 needs
* some more thought. Fail it for now.
@@ -408,44 +402,38 @@ int irq_update_affinity_desc(unsigned in
if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
return -EOPNOTSUPP;
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return -EINVAL;
-
- /* Requires the interrupt to be shut down */
- if (irqd_is_started(&desc->irq_data)) {
- ret = -EBUSY;
- goto out_unlock;
- }
-
- /* Interrupts which are already managed cannot be modified */
- if (irqd_affinity_is_managed(&desc->irq_data)) {
- ret = -EBUSY;
- goto out_unlock;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ bool activated;
+
+ /* Requires the interrupt to be shut down */
+ if (irqd_is_started(&desc->irq_data))
+ return -EBUSY;
+
+ /* Interrupts which are already managed cannot be modified */
+ if (irqd_affinity_is_managed(&desc->irq_data))
+ return -EBUSY;
+ /*
+ * Deactivate the interrupt. That's required to undo
+ * anything an earlier activation has established.
+ */
+ activated = irqd_is_activated(&desc->irq_data);
+ if (activated)
+ irq_domain_deactivate_irq(&desc->irq_data);
+
+ if (affinity->is_managed) {
+ irqd_set(&desc->irq_data, IRQD_AFFINITY_MANAGED);
+ irqd_set(&desc->irq_data, IRQD_MANAGED_SHUTDOWN);
+ }
+
+ cpumask_copy(desc->irq_common_data.affinity, &affinity->mask);
+
+ /* Restore the activation state */
+ if (activated)
+ irq_domain_activate_irq(&desc->irq_data, false);
+ return 0;
}
-
- /*
- * Deactivate the interrupt. That's required to undo
- * anything an earlier activation has established.
- */
- activated = irqd_is_activated(&desc->irq_data);
- if (activated)
- irq_domain_deactivate_irq(&desc->irq_data);
-
- if (affinity->is_managed) {
- irqd_set(&desc->irq_data, IRQD_AFFINITY_MANAGED);
- irqd_set(&desc->irq_data, IRQD_MANAGED_SHUTDOWN);
- }
-
- cpumask_copy(desc->irq_common_data.affinity, &affinity->mask);
-
- /* Restore the activation state */
- if (activated)
- irq_domain_activate_irq(&desc->irq_data, false);
-
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ return -EINVAL;
}
static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 31/45] genirq/manage: Rework __irq_apply_affinity_hint()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (29 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 30/45] genirq/manage: Rework irq_update_affinity_desc() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity() Thomas Gleixner
` (14 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -478,26 +478,24 @@ int irq_force_affinity(unsigned int irq,
}
EXPORT_SYMBOL_GPL(irq_force_affinity);
-int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
- bool setaffinity)
+int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m, bool setaffinity)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ int ret = -EINVAL;
- if (!desc)
- return -EINVAL;
- desc->affinity_hint = m;
- irq_put_desc_unlock(desc, flags);
- if (m && setaffinity)
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc->affinity_hint = m;
+ ret = 0;
+ }
+
+ if (!ret && m && setaffinity)
__irq_set_affinity(irq, m, false);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
static void irq_affinity_notify(struct work_struct *work)
{
- struct irq_affinity_notify *notify =
- container_of(work, struct irq_affinity_notify, work);
+ struct irq_affinity_notify *notify = container_of(work, struct irq_affinity_notify, work);
struct irq_desc *desc = irq_to_desc(notify->irq);
cpumask_var_t cpumask;
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (30 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 31/45] genirq/manage: Rework __irq_apply_affinity_hint() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-04-30 6:31 ` Jiri Slaby
2025-04-29 6:55 ` [patch V2 33/45] genirq/manage: Rework __disable_irq_nosync() Thomas Gleixner
` (13 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 40 +++++++++++++++++-----------------------
1 file changed, 17 insertions(+), 23 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -627,32 +627,26 @@ int irq_setup_affinity(struct irq_desc *
*/
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
- struct irq_data *data;
- struct irq_chip *chip;
- int ret = -ENOSYS;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ struct irq_data *data;
+ struct irq_chip *chip;
+ int ret = -ENOSYS;
- if (!desc)
- return -EINVAL;
+ data = irq_desc_get_irq_data(desc);
+ do {
+ chip = irq_data_get_irq_chip(data);
+ if (chip && chip->irq_set_vcpu_affinity)
+ break;
- data = irq_desc_get_irq_data(desc);
- do {
- chip = irq_data_get_irq_chip(data);
- if (chip && chip->irq_set_vcpu_affinity)
- break;
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- data = data->parent_data;
-#else
- data = NULL;
-#endif
- } while (data);
+ data = irqd_get_parent_data(data);
+ } while (data);
- if (data)
- ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
- irq_put_desc_unlock(desc, flags);
-
- return ret;
+ if (data)
+ ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
+ return ret;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_vcpu_affinity);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 33/45] genirq/manage: Rework __disable_irq_nosync()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (31 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 34/45] genirq/manage: Rework enable_irq() Thomas Gleixner
` (12 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -658,14 +658,11 @@ void __disable_irq(struct irq_desc *desc
static int __disable_irq_nosync(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
- if (!desc)
- return -EINVAL;
- __disable_irq(desc);
- irq_put_desc_busunlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ __disable_irq(scoped_irqdesc);
+ return 0;
+ }
+ return -EINVAL;
}
/**
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 34/45] genirq/manage: Rework enable_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (32 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 33/45] genirq/manage: Rework __disable_irq_nosync() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake() Thomas Gleixner
` (11 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -788,18 +788,13 @@ void __enable_irq(struct irq_desc *desc)
*/
void enable_irq(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return;
- if (WARN(!desc->irq_data.chip,
- KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
- goto out;
-
- __enable_irq(desc);
-out:
- irq_put_desc_busunlock(desc, flags);
+ if (WARN(!desc->irq_data.chip, "enable_irq before setup/request_irq: irq %u\n", irq))
+ return;
+ __enable_irq(desc);
+ }
}
EXPORT_SYMBOL(enable_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (33 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 34/45] genirq/manage: Rework enable_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-04-30 6:37 ` Jiri Slaby
2025-04-29 6:55 ` [patch V2 36/45] genirq/manage: Rework can_request_irq() Thomas Gleixner
` (10 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 61 +++++++++++++++++++++++-----------------------------
1 file changed, 28 insertions(+), 33 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -845,44 +845,39 @@ static int set_irq_wake_real(unsigned in
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
- int ret = 0;
+ int ret = -EINVAL;
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- /* Don't use NMIs as wake up interrupts please */
- if (irq_is_nmi(desc)) {
- ret = -EINVAL;
- goto out_unlock;
- }
+ /* Don't use NMIs as wake up interrupts please */
+ if (irq_is_nmi(desc))
+ return -EINVAL;
- /* wakeup-capable irqs can be shared between drivers that
- * don't need to have the same sleep mode behaviors.
- */
- if (on) {
- if (desc->wake_depth++ == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 0;
- else
- irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
- }
- } else {
- if (desc->wake_depth == 0) {
- WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
- } else if (--desc->wake_depth == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 1;
- else
- irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ /*
+ * wakeup-capable irqs can be shared between drivers that
+ * don't need to have the same sleep mode behaviors.
+ */
+ if (on) {
+ if (desc->wake_depth++ == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 0;
+ else
+ irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
+ } else {
+ if (desc->wake_depth == 0) {
+ WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
+ } else if (--desc->wake_depth == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 1;
+ else
+ irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
}
}
-
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
return ret;
}
EXPORT_SYMBOL(irq_set_irq_wake);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 36/45] genirq/manage: Rework can_request_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (34 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 37/45] genirq/manage: Rework irq_set_parent() Thomas Gleixner
` (9 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Make the return value boolean to reflect it's meaning.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/irq.h | 2 +-
kernel/irq/manage.c | 21 ++++++++-------------
2 files changed, 9 insertions(+), 14 deletions(-)
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -700,7 +700,7 @@ extern void note_interrupt(struct irq_de
extern int noirqdebug_setup(char *str);
/* Checks whether the interrupt can be requested by request_irq(): */
-extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+extern bool can_request_irq(unsigned int irq, unsigned long irqflags);
/* Dummy irq-chip implementations: */
extern struct irq_chip no_irq_chip;
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -887,22 +887,17 @@ EXPORT_SYMBOL(irq_set_irq_wake);
* particular irq has been exclusively allocated or is available
* for driver use.
*/
-int can_request_irq(unsigned int irq, unsigned long irqflags)
+bool can_request_irq(unsigned int irq, unsigned long irqflags)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
- int canrequest = 0;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return 0;
-
- if (irq_settings_can_request(desc)) {
- if (!desc->action ||
- irqflags & desc->action->flags & IRQF_SHARED)
- canrequest = 1;
+ if (irq_settings_can_request(desc)) {
+ if (!desc->action || irqflags & desc->action->flags & IRQF_SHARED)
+ return true;
+ }
}
- irq_put_desc_unlock(desc, flags);
- return canrequest;
+ return false;
}
int __irq_set_trigger(struct irq_desc *desc, unsigned long flags)
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 37/45] genirq/manage: Rework irq_set_parent()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (35 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 36/45] genirq/manage: Rework can_request_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 38/45] genirq/manage: Rework enable_percpu_irq() Thomas Gleixner
` (8 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -958,16 +958,11 @@ int __irq_set_trigger(struct irq_desc *d
#ifdef CONFIG_HARDIRQS_SW_RESEND
int irq_set_parent(int irq, int parent_irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
-
- desc->parent_irq = parent_irq;
-
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->parent_irq = parent_irq;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_parent);
#endif
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 38/45] genirq/manage: Rework enable_percpu_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (36 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 37/45] genirq/manage: Rework irq_set_parent() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 39/45] genirq/manage: Rework irq_percpu_is_enabled() Thomas Gleixner
` (7 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 42 ++++++++++++++++--------------------------
1 file changed, 16 insertions(+), 26 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2285,35 +2285,25 @@ int request_nmi(unsigned int irq, irq_ha
void enable_percpu_irq(unsigned int irq, unsigned int type)
{
- unsigned int cpu = smp_processor_id();
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return;
-
- /*
- * If the trigger type is not specified by the caller, then
- * use the default for this interrupt.
- */
- type &= IRQ_TYPE_SENSE_MASK;
- if (type == IRQ_TYPE_NONE)
- type = irqd_get_trigger_type(&desc->irq_data);
-
- if (type != IRQ_TYPE_NONE) {
- int ret;
-
- ret = __irq_set_trigger(desc, type);
-
- if (ret) {
- WARN(1, "failed to set type for IRQ%d\n", irq);
- goto out;
+ /*
+ * If the trigger type is not specified by the caller, then
+ * use the default for this interrupt.
+ */
+ type &= IRQ_TYPE_SENSE_MASK;
+ if (type == IRQ_TYPE_NONE)
+ type = irqd_get_trigger_type(&desc->irq_data);
+
+ if (type != IRQ_TYPE_NONE) {
+ if (__irq_set_trigger(desc, type)) {
+ WARN(1, "failed to set type for IRQ%d\n", irq);
+ return;
+ }
}
+ irq_percpu_enable(desc, smp_processor_id());
}
-
- irq_percpu_enable(desc, cpu);
-out:
- irq_put_desc_unlock(desc, flags);
}
EXPORT_SYMBOL_GPL(enable_percpu_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 39/45] genirq/manage: Rework irq_percpu_is_enabled()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (37 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 38/45] genirq/manage: Rework enable_percpu_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 40/45] genirq/manage: Rework disable_percpu_irq() Thomas Gleixner
` (6 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2321,19 +2321,9 @@ void enable_percpu_nmi(unsigned int irq,
*/
bool irq_percpu_is_enabled(unsigned int irq)
{
- unsigned int cpu = smp_processor_id();
- struct irq_desc *desc;
- unsigned long flags;
- bool is_enabled;
-
- desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return false;
-
- is_enabled = cpumask_test_cpu(cpu, desc->percpu_enabled);
- irq_put_desc_unlock(desc, flags);
-
- return is_enabled;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU)
+ return cpumask_test_cpu(smp_processor_id(), scoped_irqdesc->percpu_enabled);
+ return false;
}
EXPORT_SYMBOL_GPL(irq_percpu_is_enabled);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 40/45] genirq/manage: Rework disable_percpu_irq()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (38 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 39/45] genirq/manage: Rework irq_percpu_is_enabled() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 41/45] genirq/manage: Rework prepare_percpu_nmi() Thomas Gleixner
` (5 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2329,15 +2329,8 @@ EXPORT_SYMBOL_GPL(irq_percpu_is_enabled)
void disable_percpu_irq(unsigned int irq)
{
- unsigned int cpu = smp_processor_id();
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
-
- if (!desc)
- return;
-
- irq_percpu_disable(desc, cpu);
- irq_put_desc_unlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU)
+ irq_percpu_disable(scoped_irqdesc, smp_processor_id());
}
EXPORT_SYMBOL_GPL(disable_percpu_irq);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 41/45] genirq/manage: Rework prepare_percpu_nmi()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (39 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 40/45] genirq/manage: Rework disable_percpu_irq() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 42/45] genirq/manage: Rework teardown_percpu_nmi() Thomas Gleixner
` (4 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 31 +++++++++----------------------
1 file changed, 9 insertions(+), 22 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2605,32 +2605,19 @@ int request_percpu_nmi(unsigned int irq,
*/
int prepare_percpu_nmi(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc;
- int ret = 0;
+ int ret = -EINVAL;
WARN_ON(preemptible());
- desc = irq_get_desc_lock(irq, &flags,
- IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return -EINVAL;
-
- if (WARN(!irq_is_nmi(desc),
- KERN_ERR "prepare_percpu_nmi called for a non-NMI interrupt: irq %u\n",
- irq)) {
- ret = -EINVAL;
- goto out;
- }
-
- ret = irq_nmi_setup(desc);
- if (ret) {
- pr_err("Failed to setup NMI delivery: irq %u\n", irq);
- goto out;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ if (WARN(!irq_is_nmi(scoped_irqdesc),
+ "prepare_percpu_nmi called for a non-NMI interrupt: irq %u\n", irq))
+ return -EINVAL;
+
+ ret = irq_nmi_setup(scoped_irqdesc);
+ if (ret)
+ pr_err("Failed to setup NMI delivery: irq %u\n", irq);
}
-
-out:
- irq_put_desc_unlock(desc, flags);
return ret;
}
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 42/45] genirq/manage: Rework teardown_percpu_nmi()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (40 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 41/45] genirq/manage: Rework prepare_percpu_nmi() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 43/45] genirq/manage: Rework irq_get_irqchip_state() Thomas Gleixner
` (3 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2635,22 +2635,13 @@ int prepare_percpu_nmi(unsigned int irq)
*/
void teardown_percpu_nmi(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc;
-
WARN_ON(preemptible());
- desc = irq_get_desc_lock(irq, &flags,
- IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return;
-
- if (WARN_ON(!irq_is_nmi(desc)))
- goto out;
-
- irq_nmi_teardown(desc);
-out:
- irq_put_desc_unlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ if (WARN_ON(!irq_is_nmi(scoped_irqdesc)))
+ return;
+ irq_nmi_teardown(scoped_irqdesc);
+ }
}
static int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state which, bool *state)
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 43/45] genirq/manage: Rework irq_get_irqchip_state()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (41 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 42/45] genirq/manage: Rework teardown_percpu_nmi() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 44/45] genirq/manage: Rework irq_set_irqchip_state() Thomas Gleixner
` (2 subsequent siblings)
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2678,24 +2678,14 @@ int __irq_get_irqchip_state(struct irq_d
* This function should be called with preemption disabled if the interrupt
* controller has per-cpu registers.
*/
-int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
- bool *state)
+int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool *state)
{
- struct irq_desc *desc;
- struct irq_data *data;
- unsigned long flags;
- int err = -EINVAL;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_data *data = irq_desc_get_irq_data(scoped_irqdesc);
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return err;
-
- data = irq_desc_get_irq_data(desc);
-
- err = __irq_get_irqchip_state(data, which, state);
-
- irq_put_desc_busunlock(desc, flags);
- return err;
+ return __irq_get_irqchip_state(data, which, state);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 44/45] genirq/manage: Rework irq_set_irqchip_state()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (42 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 43/45] genirq/manage: Rework irq_get_irqchip_state() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 45/45] genirq: Remove irq_[get|put]_desc*() Thomas Gleixner
2025-05-06 14:24 ` [patch V2 00/45] genirq: Cleanups and conversion to lock guards Peter Zijlstra
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/manage.c | 53 +++++++++++++++++++---------------------------------
1 file changed, 20 insertions(+), 33 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2703,39 +2703,26 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state)
*/
int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool val)
{
- struct irq_desc *desc;
- struct irq_data *data;
- struct irq_chip *chip;
- unsigned long flags;
- int err = -EINVAL;
-
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return err;
-
- data = irq_desc_get_irq_data(desc);
-
- do {
- chip = irq_data_get_irq_chip(data);
- if (WARN_ON_ONCE(!chip)) {
- err = -ENODEV;
- goto out_unlock;
- }
- if (chip->irq_set_irqchip_state)
- break;
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- data = data->parent_data;
-#else
- data = NULL;
-#endif
- } while (data);
-
- if (data)
- err = chip->irq_set_irqchip_state(data, which, val);
-
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return err;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_data *data = irq_desc_get_irq_data(scoped_irqdesc);
+ struct irq_chip *chip;
+
+ do {
+ chip = irq_data_get_irq_chip(data);
+
+ if (WARN_ON_ONCE(!chip))
+ return -ENODEV;
+
+ if (chip->irq_set_irqchip_state)
+ break;
+
+ data = irqd_get_parent_data(data);
+ } while (data);
+
+ if (data)
+ return chip->irq_set_irqchip_state(data, which, val);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_irqchip_state);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2 45/45] genirq: Remove irq_[get|put]_desc*()
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (43 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 44/45] genirq/manage: Rework irq_set_irqchip_state() Thomas Gleixner
@ 2025-04-29 6:55 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-06 14:24 ` [patch V2 00/45] genirq: Cleanups and conversion to lock guards Peter Zijlstra
45 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-29 6:55 UTC (permalink / raw)
To: LKML; +Cc: Jiri Slaby, Peter Zijlstra
All users are converted to the guards. Remove the helpers.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/internals.h | 24 ------------------------
1 file changed, 24 deletions(-)
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -191,30 +191,6 @@ static inline class_irqdesc_lock_t class
#define scoped_irqdesc ((struct irq_desc *)(__guard_ptr(irqdesc_lock)(&scope)))
-static inline struct irq_desc *
-irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
-{
- return __irq_get_desc_lock(irq, flags, true, check);
-}
-
-static inline void
-irq_put_desc_busunlock(struct irq_desc *desc, unsigned long flags)
-{
- __irq_put_desc_unlock(desc, flags, true);
-}
-
-static inline struct irq_desc *
-irq_get_desc_lock(unsigned int irq, unsigned long *flags, unsigned int check)
-{
- return __irq_get_desc_lock(irq, flags, false, check);
-}
-
-static inline void
-irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
-{
- __irq_put_desc_unlock(desc, flags, false);
-}
-
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
static inline unsigned int irqd_get(struct irq_data *d)
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 02/45] genirq/irqdesc: Switch to lock guards
2025-04-29 6:54 ` [patch V2 02/45] genirq/irqdesc: Switch to " Thomas Gleixner
@ 2025-04-30 5:54 ` Jiri Slaby
2025-04-30 6:36 ` [patch V2a " Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Jiri Slaby @ 2025-04-30 5:54 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Peter Zijlstra
On 29. 04. 25, 8:54, Thomas Gleixner wrote:
> Replace all lock/unlock pairs with lock guards and simplify the code flow.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/irqdesc.c | 127 +++++++++++++++++----------------------------------
> 1 file changed, 43 insertions(+), 84 deletions(-)
>
> --- a/kernel/irq/irqdesc.c
> +++ b/kernel/irq/irqdesc.c
...
> @@ -569,12 +539,12 @@ static int alloc_descs(unsigned int star
> return -ENOMEM;
> }
>
> -static int irq_expand_nr_irqs(unsigned int nr)
> +static bool irq_expand_nr_irqs(unsigned int nr)
Here you do ^^^ and:
...
> @@ -677,14 +645,13 @@ static inline int alloc_descs(unsigned i
>
> static int irq_expand_nr_irqs(unsigned int nr)
This was omitted from my prev review -- needs to return bool here too.
> {
> - return -ENOMEM;
> + return false;
> }
thanks,
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity()
2025-04-29 6:55 ` [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity() Thomas Gleixner
@ 2025-04-30 6:31 ` Jiri Slaby
2025-04-30 12:49 ` [patch V2a " Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Jiri Slaby @ 2025-04-30 6:31 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Peter Zijlstra
On 29. 04. 25, 8:55, Thomas Gleixner wrote:
> Use the new guards to get and lock the interrupt descriptor and tidy up the
> code.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/manage.c | 40 +++++++++++++++++-----------------------
> 1 file changed, 17 insertions(+), 23 deletions(-)
>
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -627,32 +627,26 @@ int irq_setup_affinity(struct irq_desc *
> */
> int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
> {
> - unsigned long flags;
> - struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
> - struct irq_data *data;
> - struct irq_chip *chip;
> - int ret = -ENOSYS;
> + scoped_irqdesc_get_and_lock(irq, 0) {
> + struct irq_desc *desc = scoped_irqdesc;
> + struct irq_data *data;
> + struct irq_chip *chip;
> + int ret = -ENOSYS;
>
> - if (!desc)
> - return -EINVAL;
> + data = irq_desc_get_irq_data(desc);
> + do {
> + chip = irq_data_get_irq_chip(data);
> + if (chip && chip->irq_set_vcpu_affinity)
> + break;
>
> - data = irq_desc_get_irq_data(desc);
> - do {
> - chip = irq_data_get_irq_chip(data);
> - if (chip && chip->irq_set_vcpu_affinity)
> - break;
> -#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
> - data = data->parent_data;
> -#else
> - data = NULL;
> -#endif
> - } while (data);
> + data = irqd_get_parent_data(data);
> + } while (data);
>
> - if (data)
> - ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
> - irq_put_desc_unlock(desc, flags);
> -
> - return ret;
> + if (data)
> + ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
> + return ret;
What about simpler:
if (!data)
return -ENOSYS;
return chip->irq_set_vcpu_affinity(data, vcpu_info);
instead? No need for 'ret' at all then: it's always PITA to look up what
ret is set to initially.
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2a 02/45] genirq/irqdesc: Switch to lock guards
2025-04-30 5:54 ` Jiri Slaby
@ 2025-04-30 6:36 ` Thomas Gleixner
2025-04-30 6:51 ` Jiri Slaby
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
0 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-30 6:36 UTC (permalink / raw)
To: Jiri Slaby, LKML; +Cc: Peter Zijlstra
Replace all lock/unlock pairs with lock guards and simplify the code flow.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V2a: Fixup the stub function too - Jiry
---
kernel/irq/irqdesc.c | 129 +++++++++++++++++----------------------------------
1 file changed, 44 insertions(+), 85 deletions(-)
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -246,8 +246,7 @@ static struct kobject *irq_kobj_base;
#define IRQ_ATTR_RO(_name) \
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
-static ssize_t per_cpu_count_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t per_cpu_count_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
ssize_t ret = 0;
@@ -266,99 +265,75 @@ static ssize_t per_cpu_count_show(struct
}
IRQ_ATTR_RO(per_cpu_count);
-static ssize_t chip_name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t chip_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->irq_data.chip && desc->irq_data.chip->name)
- ret = sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
+ return 0;
}
IRQ_ATTR_RO(chip_name);
-static ssize_t hwirq_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t hwirq_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
+ guard(raw_spinlock_irq)(&desc->lock);
raw_spin_lock_irq(&desc->lock);
if (desc->irq_data.domain)
- ret = sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
+ return 0;
}
IRQ_ATTR_RO(hwirq);
-static ssize_t type_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
}
IRQ_ATTR_RO(type);
-static ssize_t wakeup_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t wakeup_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
-
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
}
IRQ_ATTR_RO(wakeup);
-static ssize_t name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->name)
- ret = sysfs_emit(buf, "%s\n", desc->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->name);
+ return 0;
}
IRQ_ATTR_RO(name);
-static ssize_t actions_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t actions_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
struct irqaction *action;
ssize_t ret = 0;
char *p = "";
- raw_spin_lock_irq(&desc->lock);
- for_each_action_of_desc(desc, action) {
- ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
- p = ",";
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ for_each_action_of_desc(desc, action) {
+ ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
+ p = ",";
+ }
}
- raw_spin_unlock_irq(&desc->lock);
if (ret)
ret += sysfs_emit_at(buf, ret, "\n");
-
return ret;
}
IRQ_ATTR_RO(actions);
@@ -414,19 +389,14 @@ static int __init irq_sysfs_init(void)
int irq;
/* Prevent concurrent irq alloc/free */
- irq_lock_sparse();
-
+ guard(mutex)(&sparse_irq_lock);
irq_kobj_base = kobject_create_and_add("irq", kernel_kobj);
- if (!irq_kobj_base) {
- irq_unlock_sparse();
+ if (!irq_kobj_base)
return -ENOMEM;
- }
/* Add the already allocated interrupts */
for_each_irq_desc(irq, desc)
irq_sysfs_add(irq, desc);
- irq_unlock_sparse();
-
return 0;
}
postcore_initcall(irq_sysfs_init);
@@ -569,12 +539,12 @@ static int alloc_descs(unsigned int star
return -ENOMEM;
}
-static int irq_expand_nr_irqs(unsigned int nr)
+static bool irq_expand_nr_irqs(unsigned int nr)
{
if (nr > MAX_SPARSE_IRQS)
- return -ENOMEM;
+ return false;
nr_irqs = nr;
- return 0;
+ return true;
}
int __init early_irq_init(void)
@@ -652,11 +622,9 @@ EXPORT_SYMBOL(irq_to_desc);
static void free_desc(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
delete_irq_desc(irq);
}
@@ -675,16 +643,15 @@ static inline int alloc_descs(unsigned i
return start;
}
-static int irq_expand_nr_irqs(unsigned int nr)
+static inline bool irq_expand_nr_irqs(unsigned int nr)
{
- return -ENOMEM;
+ return false;
}
void irq_mark_irq(unsigned int irq)
{
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
irq_insert_desc(irq, irq_desc + irq);
- mutex_unlock(&sparse_irq_lock);
}
#ifdef CONFIG_GENERIC_IRQ_LEGACY
@@ -823,11 +790,9 @@ void irq_free_descs(unsigned int from, u
if (from >= nr_irqs || (from + cnt) > nr_irqs)
return;
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
for (i = 0; i < cnt; i++)
free_desc(from + i);
-
- mutex_unlock(&sparse_irq_lock);
}
EXPORT_SYMBOL_GPL(irq_free_descs);
@@ -844,11 +809,10 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
*
* Returns the first irq number or error code
*/
-int __ref
-__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
- struct module *owner, const struct irq_affinity_desc *affinity)
+int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+ struct module *owner, const struct irq_affinity_desc *affinity)
{
- int start, ret;
+ int start;
if (!cnt)
return -EINVAL;
@@ -866,22 +830,17 @@ int __ref
from = arch_dynirq_lower_bound(from);
}
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
start = irq_find_free_area(from, cnt);
- ret = -EEXIST;
if (irq >=0 && start != irq)
- goto unlock;
+ return -EEXIST;
if (start + cnt > nr_irqs) {
- ret = irq_expand_nr_irqs(start + cnt);
- if (ret)
- goto unlock;
+ if (!irq_expand_nr_irqs(start + cnt))
+ return -ENOMEM;
}
- ret = alloc_descs(start, cnt, node, affinity, owner);
-unlock:
- mutex_unlock(&sparse_irq_lock);
- return ret;
+ return alloc_descs(start, cnt, node, affinity, owner);
}
EXPORT_SYMBOL_GPL(__irq_alloc_descs);
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-04-29 6:55 ` [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake() Thomas Gleixner
@ 2025-04-30 6:37 ` Jiri Slaby
2025-04-30 12:42 ` Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Jiri Slaby @ 2025-04-30 6:37 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Peter Zijlstra
On 29. 04. 25, 8:55, Thomas Gleixner wrote:
> Use the new guards to get and lock the interrupt descriptor and tidy up the
> code.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/manage.c | 61 +++++++++++++++++++++++-----------------------------
> 1 file changed, 28 insertions(+), 33 deletions(-)
>
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -845,44 +845,39 @@ static int set_irq_wake_real(unsigned in
> */
> int irq_set_irq_wake(unsigned int irq, unsigned int on)
> {
> - unsigned long flags;
> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
> - int ret = 0;
> + int ret = -EINVAL;
Hmm...
> - if (!desc)
> - return -EINVAL;
> + scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> + struct irq_desc *desc = scoped_irqdesc;
>
> - /* Don't use NMIs as wake up interrupts please */
> - if (irq_is_nmi(desc)) {
> - ret = -EINVAL;
> - goto out_unlock;
> - }
> + /* Don't use NMIs as wake up interrupts please */
> + if (irq_is_nmi(desc))
> + return -EINVAL;
>
> - /* wakeup-capable irqs can be shared between drivers that
> - * don't need to have the same sleep mode behaviors.
> - */
> - if (on) {
> - if (desc->wake_depth++ == 0) {
> - ret = set_irq_wake_real(irq, on);
> - if (ret)
> - desc->wake_depth = 0;
> - else
> - irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
> - }
> - } else {
> - if (desc->wake_depth == 0) {
> - WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
> - } else if (--desc->wake_depth == 0) {
> - ret = set_irq_wake_real(irq, on);
> - if (ret)
> - desc->wake_depth = 1;
> - else
> - irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
> + /*
> + * wakeup-capable irqs can be shared between drivers that
> + * don't need to have the same sleep mode behaviors.
> + */
> + if (on) {
> + if (desc->wake_depth++ == 0) {
> + ret = set_irq_wake_real(irq, on);
> + if (ret)
> + desc->wake_depth = 0;
> + else
> + irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
> + }
So in this (imaginary) else branch (i.e. desc->wake_depth++ != 0), you
return EINVAL now?
Previously, it was 0 (correctly), if I am looking correctly.
> + } else {
> + if (desc->wake_depth == 0) {
> + WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
And here too.
> + } else if (--desc->wake_depth == 0) {
> + ret = set_irq_wake_real(irq, on);
> + if (ret)
> + desc->wake_depth = 1;
> + else
> + irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
> + }
> }
> }
> -
> -out_unlock:
> - irq_put_desc_busunlock(desc, flags);
> return ret;
> }
> EXPORT_SYMBOL(irq_set_irq_wake);
>
>
>
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2a 02/45] genirq/irqdesc: Switch to lock guards
2025-04-30 6:36 ` [patch V2a " Thomas Gleixner
@ 2025-04-30 6:51 ` Jiri Slaby
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: Jiri Slaby @ 2025-04-30 6:51 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Peter Zijlstra
On 30. 04. 25, 8:36, Thomas Gleixner wrote:
> Replace all lock/unlock pairs with lock guards and simplify the code flow.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> V2a: Fixup the stub function too - Jiry
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-04-30 6:37 ` Jiri Slaby
@ 2025-04-30 12:42 ` Thomas Gleixner
2025-04-30 12:48 ` [patch V2a " Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-30 12:42 UTC (permalink / raw)
To: Jiri Slaby, LKML; +Cc: Peter Zijlstra
On Wed, Apr 30 2025 at 08:37, Jiri Slaby wrote:
> On 29. 04. 25, 8:55, Thomas Gleixner wrote:
>> Use the new guards to get and lock the interrupt descriptor and tidy up the
>> code.
>> - unsigned long flags;
>> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
>> - int ret = 0;
>> + int ret = -EINVAL;
>
> Hmm...
>
>> - if (!desc)
>> - return -EINVAL;
>> + scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
>> + struct irq_desc *desc = scoped_irqdesc;
>>
>> + /*
>> + * wakeup-capable irqs can be shared between drivers that
>> + * don't need to have the same sleep mode behaviors.
>> + */
>> + if (on) {
>> + if (desc->wake_depth++ == 0) {
>> + ret = set_irq_wake_real(irq, on);
>> + if (ret)
>> + desc->wake_depth = 0;
>> + else
>> + irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
>> + }
>
> So in this (imaginary) else branch (i.e. desc->wake_depth++ != 0), you
> return EINVAL now?
>
> Previously, it was 0 (correctly), if I am looking correctly.
Duh, yes.
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2a 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-04-30 12:42 ` Thomas Gleixner
@ 2025-04-30 12:48 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-13 17:32 ` [patch V2a 35/45] " Jon Hunter
0 siblings, 2 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-30 12:48 UTC (permalink / raw)
To: Jiri Slaby, LKML; +Cc: Peter Zijlstra
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V2a: Fix the return value for the on/off paths - Jiry
---
kernel/irq/manage.c | 65 ++++++++++++++++++++++++----------------------------
1 file changed, 30 insertions(+), 35 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -846,45 +846,40 @@ static int set_irq_wake_real(unsigned in
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
- int ret = 0;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
+ int ret = 0;
- if (!desc)
- return -EINVAL;
+ /* Don't use NMIs as wake up interrupts please */
+ if (irq_is_nmi(desc))
+ return -EINVAL;
- /* Don't use NMIs as wake up interrupts please */
- if (irq_is_nmi(desc)) {
- ret = -EINVAL;
- goto out_unlock;
- }
-
- /* wakeup-capable irqs can be shared between drivers that
- * don't need to have the same sleep mode behaviors.
- */
- if (on) {
- if (desc->wake_depth++ == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 0;
- else
- irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
- }
- } else {
- if (desc->wake_depth == 0) {
- WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
- } else if (--desc->wake_depth == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 1;
- else
- irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ /*
+ * wakeup-capable irqs can be shared between drivers that
+ * don't need to have the same sleep mode behaviors.
+ */
+ if (on) {
+ if (desc->wake_depth++ == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 0;
+ else
+ irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
+ } else {
+ if (desc->wake_depth == 0) {
+ WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
+ } else if (--desc->wake_depth == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 1;
+ else
+ irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
}
+ return ret;
}
-
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_irq_wake);
^ permalink raw reply [flat|nested] 119+ messages in thread
* [patch V2a 32/45] genirq/manage: Rework irq_set_vcpu_affinity()
2025-04-30 6:31 ` Jiri Slaby
@ 2025-04-30 12:49 ` Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-04-30 12:49 UTC (permalink / raw)
To: Jiri Slaby, LKML; +Cc: Peter Zijlstra
From: Thomas Gleixner <tglx@linutronix.de>
Subject: genirq/manage: Rework irq_set_vcpu_affinity()
Date: Thu, 13 Mar 2025 17:00:39 +0100
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
V2a: Get rid of 'ret' - Jiry
---
kernel/irq/manage.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -629,32 +629,25 @@ int irq_setup_affinity(struct irq_desc *
*/
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
- struct irq_data *data;
- struct irq_chip *chip;
- int ret = -ENOSYS;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ struct irq_data *data;
+ struct irq_chip *chip;
- if (!desc)
- return -EINVAL;
+ data = irq_desc_get_irq_data(desc);
+ do {
+ chip = irq_data_get_irq_chip(data);
+ if (chip && chip->irq_set_vcpu_affinity)
+ break;
- data = irq_desc_get_irq_data(desc);
- do {
- chip = irq_data_get_irq_chip(data);
- if (chip && chip->irq_set_vcpu_affinity)
- break;
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- data = data->parent_data;
-#else
- data = NULL;
-#endif
- } while (data);
+ data = irqd_get_parent_data(data);
+ } while (data);
- if (data)
- ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
- irq_put_desc_unlock(desc, flags);
-
- return ret;
+ if (!data)
+ return -ENOSYS;
+ return chip->irq_set_vcpu_affinity(data, vcpu_info);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_vcpu_affinity);
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 00/45] genirq: Cleanups and conversion to lock guards
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
` (44 preceding siblings ...)
2025-04-29 6:55 ` [patch V2 45/45] genirq: Remove irq_[get|put]_desc*() Thomas Gleixner
@ 2025-05-06 14:24 ` Peter Zijlstra
45 siblings, 0 replies; 119+ messages in thread
From: Peter Zijlstra @ 2025-05-06 14:24 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: LKML, Jiri Slaby
On Tue, Apr 29, 2025 at 08:54:47AM +0200, Thomas Gleixner wrote:
> This is V2 of the generic interrupt locking overhaul. V1 can be found here:
>
> https://lore.kernel.org/all/20250313154615.860723120@linutronix.de
>
> The generic interrupt core code has accumulated quite some inconsistencies
> over time and a common pattern in various API functions is:
>
> unsigned long flags;
> struct irq_desc *desc = irq_get_desc_[bus]lock(irq, &flags, mode);
>
> if (!desc)
> return -EINVAL;
> ....
> irq_put_desc_[bus]unlock(desc, flags);
>
> That's awkward and requires gotos in failure paths.
>
> This series provides conditional lock guards and converts the core code
> over to use those guards. Along with that it converts the other open coded
> lock/unlock pairs and fixes up coding and kernel doc formatting. The
> conversions were partially done with Coccinelle where possible.
So while my eyes glazed over near the end of the series, the general
shape of things looks right.
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Jiri found a few nice cases where mixing the conditional scoped guard
with return variables went side-ways. I did a quick scan to see if I
could find more of that same pattern, but I think that's all of them.
^ permalink raw reply [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq: Remove irq_[get|put]_desc*()
2025-04-29 6:55 ` [patch V2 45/45] genirq: Remove irq_[get|put]_desc*() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 104361217c2a2ab7d6a9de756952814af0a8a5ad
Gitweb: https://git.kernel.org/tip/104361217c2a2ab7d6a9de756952814af0a8a5ad
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:54 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:17 +02:00
genirq: Remove irq_[get|put]_desc*()
All users are converted to the guards. Remove the helpers.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.729586582@linutronix.de
---
kernel/irq/internals.h | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index 44d3a67..bd2db6e 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -191,30 +191,6 @@ static inline class_irqdesc_lock_t class_irqdesc_lock_constructor(unsigned int i
#define scoped_irqdesc ((struct irq_desc *)(__guard_ptr(irqdesc_lock)(&scope)))
-static inline struct irq_desc *
-irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
-{
- return __irq_get_desc_lock(irq, flags, true, check);
-}
-
-static inline void
-irq_put_desc_busunlock(struct irq_desc *desc, unsigned long flags)
-{
- __irq_put_desc_unlock(desc, flags, true);
-}
-
-static inline struct irq_desc *
-irq_get_desc_lock(unsigned int irq, unsigned long *flags, unsigned int check)
-{
- return __irq_get_desc_lock(irq, flags, false, check);
-}
-
-static inline void
-irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags)
-{
- __irq_put_desc_unlock(desc, flags, false);
-}
-
#define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
static inline unsigned int irqd_get(struct irq_data *d)
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_set_irqchip_state()
2025-04-29 6:55 ` [patch V2 44/45] genirq/manage: Rework irq_set_irqchip_state() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 193879e28be7bb26abc795e6b5096ef9fe3131cf
Gitweb: https://git.kernel.org/tip/193879e28be7bb26abc795e6b5096ef9fe3131cf
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:53 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework irq_set_irqchip_state()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.670808288@linutronix.de
---
kernel/irq/manage.c | 43 +++++++++++++++----------------------------
1 file changed, 15 insertions(+), 28 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 1783c52..827edc8 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2703,39 +2703,26 @@ EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
*/
int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool val)
{
- struct irq_desc *desc;
- struct irq_data *data;
- struct irq_chip *chip;
- unsigned long flags;
- int err = -EINVAL;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_data *data = irq_desc_get_irq_data(scoped_irqdesc);
+ struct irq_chip *chip;
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return err;
+ do {
+ chip = irq_data_get_irq_chip(data);
- data = irq_desc_get_irq_data(desc);
+ if (WARN_ON_ONCE(!chip))
+ return -ENODEV;
- do {
- chip = irq_data_get_irq_chip(data);
- if (WARN_ON_ONCE(!chip)) {
- err = -ENODEV;
- goto out_unlock;
- }
- if (chip->irq_set_irqchip_state)
- break;
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- data = data->parent_data;
-#else
- data = NULL;
-#endif
- } while (data);
+ if (chip->irq_set_irqchip_state)
+ break;
- if (data)
- err = chip->irq_set_irqchip_state(data, which, val);
+ data = irqd_get_parent_data(data);
+ } while (data);
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return err;
+ if (data)
+ return chip->irq_set_irqchip_state(data, which, val);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_irqchip_state);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_get_irqchip_state()
2025-04-29 6:55 ` [patch V2 43/45] genirq/manage: Rework irq_get_irqchip_state() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 782249a997472acec7e8d8f04177750192712a19
Gitweb: https://git.kernel.org/tip/782249a997472acec7e8d8f04177750192712a19
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:52 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework irq_get_irqchip_state()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.612184618@linutronix.de
---
kernel/irq/manage.c | 22 ++++++----------------
1 file changed, 6 insertions(+), 16 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index fd5fcf3..1783c52 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2678,24 +2678,14 @@ static int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state
* This function should be called with preemption disabled if the interrupt
* controller has per-cpu registers.
*/
-int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
- bool *state)
+int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool *state)
{
- struct irq_desc *desc;
- struct irq_data *data;
- unsigned long flags;
- int err = -EINVAL;
-
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return err;
-
- data = irq_desc_get_irq_data(desc);
-
- err = __irq_get_irqchip_state(data, which, state);
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_data *data = irq_desc_get_irq_data(scoped_irqdesc);
- irq_put_desc_busunlock(desc, flags);
- return err;
+ return __irq_get_irqchip_state(data, which, state);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework teardown_percpu_nmi()
2025-04-29 6:55 ` [patch V2 42/45] genirq/manage: Rework teardown_percpu_nmi() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 5fec6d5cd24a35f5b03612dd02975e3be1b788b8
Gitweb: https://git.kernel.org/tip/5fec6d5cd24a35f5b03612dd02975e3be1b788b8
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:50 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework teardown_percpu_nmi()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.552884529@linutronix.de
---
kernel/irq/manage.c | 19 +++++--------------
1 file changed, 5 insertions(+), 14 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index c6472b1..fd5fcf3 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2634,22 +2634,13 @@ int prepare_percpu_nmi(unsigned int irq)
*/
void teardown_percpu_nmi(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc;
-
WARN_ON(preemptible());
- desc = irq_get_desc_lock(irq, &flags,
- IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return;
-
- if (WARN_ON(!irq_is_nmi(desc)))
- goto out;
-
- irq_nmi_teardown(desc);
-out:
- irq_put_desc_unlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ if (WARN_ON(!irq_is_nmi(scoped_irqdesc)))
+ return;
+ irq_nmi_teardown(scoped_irqdesc);
+ }
}
static int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state which, bool *state)
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework prepare_percpu_nmi()
2025-04-29 6:55 ` [patch V2 41/45] genirq/manage: Rework prepare_percpu_nmi() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 65dd1f7ca94fde615684827af285a0475d177b9a
Gitweb: https://git.kernel.org/tip/65dd1f7ca94fde615684827af285a0475d177b9a
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:49 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework prepare_percpu_nmi()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.494561120@linutronix.de
---
kernel/irq/manage.c | 29 ++++++++---------------------
1 file changed, 8 insertions(+), 21 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a57e952..c6472b1 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2606,32 +2606,19 @@ err_out:
*/
int prepare_percpu_nmi(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc;
- int ret = 0;
+ int ret = -EINVAL;
WARN_ON(preemptible());
- desc = irq_get_desc_lock(irq, &flags,
- IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return -EINVAL;
-
- if (WARN(!irq_is_nmi(desc),
- KERN_ERR "prepare_percpu_nmi called for a non-NMI interrupt: irq %u\n",
- irq)) {
- ret = -EINVAL;
- goto out;
- }
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ if (WARN(!irq_is_nmi(scoped_irqdesc),
+ "prepare_percpu_nmi called for a non-NMI interrupt: irq %u\n", irq))
+ return -EINVAL;
- ret = irq_nmi_setup(desc);
- if (ret) {
- pr_err("Failed to setup NMI delivery: irq %u\n", irq);
- goto out;
+ ret = irq_nmi_setup(scoped_irqdesc);
+ if (ret)
+ pr_err("Failed to setup NMI delivery: irq %u\n", irq);
}
-
-out:
- irq_put_desc_unlock(desc, flags);
return ret;
}
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework disable_percpu_irq()
2025-04-29 6:55 ` [patch V2 40/45] genirq/manage: Rework disable_percpu_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 8e3f672b1949d58462e23abdc41c039a82e685fd
Gitweb: https://git.kernel.org/tip/8e3f672b1949d58462e23abdc41c039a82e685fd
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:47 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework disable_percpu_irq()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.435932527@linutronix.de
---
kernel/irq/manage.c | 11 ++---------
1 file changed, 2 insertions(+), 9 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 3a491c7..a57e952 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2330,15 +2330,8 @@ EXPORT_SYMBOL_GPL(irq_percpu_is_enabled);
void disable_percpu_irq(unsigned int irq)
{
- unsigned int cpu = smp_processor_id();
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
-
- if (!desc)
- return;
-
- irq_percpu_disable(desc, cpu);
- irq_put_desc_unlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU)
+ irq_percpu_disable(scoped_irqdesc, smp_processor_id());
}
EXPORT_SYMBOL_GPL(disable_percpu_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_percpu_is_enabled()
2025-04-29 6:55 ` [patch V2 39/45] genirq/manage: Rework irq_percpu_is_enabled() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: b171f712d6ef1ae073d18e8ea9df1e96eb34f226
Gitweb: https://git.kernel.org/tip/b171f712d6ef1ae073d18e8ea9df1e96eb34f226
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:46 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework irq_percpu_is_enabled()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.376836282@linutronix.de
---
kernel/irq/manage.c | 16 +++-------------
1 file changed, 3 insertions(+), 13 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index e27fa4e..3a491c7 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2322,19 +2322,9 @@ void enable_percpu_nmi(unsigned int irq, unsigned int type)
*/
bool irq_percpu_is_enabled(unsigned int irq)
{
- unsigned int cpu = smp_processor_id();
- struct irq_desc *desc;
- unsigned long flags;
- bool is_enabled;
-
- desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
- if (!desc)
- return false;
-
- is_enabled = cpumask_test_cpu(cpu, desc->percpu_enabled);
- irq_put_desc_unlock(desc, flags);
-
- return is_enabled;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU)
+ return cpumask_test_cpu(smp_processor_id(), scoped_irqdesc->percpu_enabled);
+ return false;
}
EXPORT_SYMBOL_GPL(irq_percpu_is_enabled);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework enable_percpu_irq()
2025-04-29 6:55 ` [patch V2 38/45] genirq/manage: Rework enable_percpu_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 508bd94c3ad4bd8b5dba8280198ce1eb31eb625a
Gitweb: https://git.kernel.org/tip/508bd94c3ad4bd8b5dba8280198ce1eb31eb625a
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:44 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:16 +02:00
genirq/manage: Rework enable_percpu_irq()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.315844964@linutronix.de
---
kernel/irq/manage.c | 42 ++++++++++++++++--------------------------
1 file changed, 16 insertions(+), 26 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index a08bbad..e27fa4e 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -2286,35 +2286,25 @@ err_out:
void enable_percpu_irq(unsigned int irq, unsigned int type)
{
- unsigned int cpu = smp_processor_id();
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_PERCPU);
-
- if (!desc)
- return;
-
- /*
- * If the trigger type is not specified by the caller, then
- * use the default for this interrupt.
- */
- type &= IRQ_TYPE_SENSE_MASK;
- if (type == IRQ_TYPE_NONE)
- type = irqd_get_trigger_type(&desc->irq_data);
-
- if (type != IRQ_TYPE_NONE) {
- int ret;
-
- ret = __irq_set_trigger(desc, type);
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_PERCPU) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (ret) {
- WARN(1, "failed to set type for IRQ%d\n", irq);
- goto out;
+ /*
+ * If the trigger type is not specified by the caller, then
+ * use the default for this interrupt.
+ */
+ type &= IRQ_TYPE_SENSE_MASK;
+ if (type == IRQ_TYPE_NONE)
+ type = irqd_get_trigger_type(&desc->irq_data);
+
+ if (type != IRQ_TYPE_NONE) {
+ if (__irq_set_trigger(desc, type)) {
+ WARN(1, "failed to set type for IRQ%d\n", irq);
+ return;
+ }
}
+ irq_percpu_enable(desc, smp_processor_id());
}
-
- irq_percpu_enable(desc, cpu);
-out:
- irq_put_desc_unlock(desc, flags);
}
EXPORT_SYMBOL_GPL(enable_percpu_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_set_parent()
2025-04-29 6:55 ` [patch V2 37/45] genirq/manage: Rework irq_set_parent() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 90140d08ac7a1e1ea3136132e1fab9baec174c25
Gitweb: https://git.kernel.org/tip/90140d08ac7a1e1ea3136132e1fab9baec174c25
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:43 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework irq_set_parent()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.258216558@linutronix.de
---
kernel/irq/manage.c | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b6f057a..a08bbad 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -959,16 +959,11 @@ int __irq_set_trigger(struct irq_desc *desc, unsigned long flags)
#ifdef CONFIG_HARDIRQS_SW_RESEND
int irq_set_parent(int irq, int parent_irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
-
- desc->parent_irq = parent_irq;
-
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->parent_irq = parent_irq;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_parent);
#endif
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework can_request_irq()
2025-04-29 6:55 ` [patch V2 36/45] genirq/manage: Rework can_request_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: a1ceb831417b8e23bd041d3e7021e235fa845128
Gitweb: https://git.kernel.org/tip/a1ceb831417b8e23bd041d3e7021e235fa845128
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:41 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework can_request_irq()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Make the return value boolean to reflect it's meaning.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.187250840@linutronix.de
---
include/linux/irq.h | 2 +-
kernel/irq/manage.c | 21 ++++++++-------------
2 files changed, 9 insertions(+), 14 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index dd5df1e..df93b23 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -700,7 +700,7 @@ extern void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret);
extern int noirqdebug_setup(char *str);
/* Checks whether the interrupt can be requested by request_irq(): */
-extern int can_request_irq(unsigned int irq, unsigned long irqflags);
+extern bool can_request_irq(unsigned int irq, unsigned long irqflags);
/* Dummy irq-chip implementations: */
extern struct irq_chip no_irq_chip;
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index d1ff1e8..b6f057a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -888,22 +888,17 @@ EXPORT_SYMBOL(irq_set_irq_wake);
* particular irq has been exclusively allocated or is available
* for driver use.
*/
-int can_request_irq(unsigned int irq, unsigned long irqflags)
+bool can_request_irq(unsigned int irq, unsigned long irqflags)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
- int canrequest = 0;
-
- if (!desc)
- return 0;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (irq_settings_can_request(desc)) {
- if (!desc->action ||
- irqflags & desc->action->flags & IRQF_SHARED)
- canrequest = 1;
+ if (irq_settings_can_request(desc)) {
+ if (!desc->action || irqflags & desc->action->flags & IRQF_SHARED)
+ return true;
+ }
}
- irq_put_desc_unlock(desc, flags);
- return canrequest;
+ return false;
}
int __irq_set_trigger(struct irq_desc *desc, unsigned long flags)
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_set_irq_wake()
2025-04-30 12:48 ` [patch V2a " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
2025-05-13 17:32 ` [patch V2a 35/45] " Jon Hunter
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 8589e325ba4f3effe0d47924d38a5c6aef7a5512
Gitweb: https://git.kernel.org/tip/8589e325ba4f3effe0d47924d38a5c6aef7a5512
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 30 Apr 2025 14:48:15 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework irq_set_irq_wake()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/87ldrhq0hc.ffs@tglx
---
kernel/irq/manage.c | 65 ++++++++++++++++++++------------------------
1 file changed, 30 insertions(+), 35 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index b8f5985..d1ff1e8 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -846,45 +846,40 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
- int ret = 0;
-
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
+ int ret = 0;
- /* Don't use NMIs as wake up interrupts please */
- if (irq_is_nmi(desc)) {
- ret = -EINVAL;
- goto out_unlock;
- }
+ /* Don't use NMIs as wake up interrupts please */
+ if (irq_is_nmi(desc))
+ return -EINVAL;
- /* wakeup-capable irqs can be shared between drivers that
- * don't need to have the same sleep mode behaviors.
- */
- if (on) {
- if (desc->wake_depth++ == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 0;
- else
- irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
- }
- } else {
- if (desc->wake_depth == 0) {
- WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
- } else if (--desc->wake_depth == 0) {
- ret = set_irq_wake_real(irq, on);
- if (ret)
- desc->wake_depth = 1;
- else
- irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ /*
+ * wakeup-capable irqs can be shared between drivers that
+ * don't need to have the same sleep mode behaviors.
+ */
+ if (on) {
+ if (desc->wake_depth++ == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 0;
+ else
+ irqd_set(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
+ } else {
+ if (desc->wake_depth == 0) {
+ WARN(1, "Unbalanced IRQ %d wake disable\n", irq);
+ } else if (--desc->wake_depth == 0) {
+ ret = set_irq_wake_real(irq, on);
+ if (ret)
+ desc->wake_depth = 1;
+ else
+ irqd_clear(&desc->irq_data, IRQD_WAKEUP_STATE);
+ }
}
+ return ret;
}
-
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_irq_wake);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework enable_irq()
2025-04-29 6:55 ` [patch V2 34/45] genirq/manage: Rework enable_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: bddd10c554073ba0c036b97b4f430119e2137aa4
Gitweb: https://git.kernel.org/tip/bddd10c554073ba0c036b97b4f430119e2137aa4
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:38 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework enable_irq()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.071157729@linutronix.de
---
kernel/irq/manage.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index edc8118..b8f5985 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -789,18 +789,13 @@ void __enable_irq(struct irq_desc *desc)
*/
void enable_irq(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
- if (!desc)
- return;
- if (WARN(!desc->irq_data.chip,
- KERN_ERR "enable_irq before setup/request_irq: irq %u\n", irq))
- goto out;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- __enable_irq(desc);
-out:
- irq_put_desc_busunlock(desc, flags);
+ if (WARN(!desc->irq_data.chip, "enable_irq before setup/request_irq: irq %u\n", irq))
+ return;
+ __enable_irq(desc);
+ }
}
EXPORT_SYMBOL(enable_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework __disable_irq_nosync()
2025-04-29 6:55 ` [patch V2 33/45] genirq/manage: Rework __disable_irq_nosync() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 1b74444467240d9ff11cf109efdfb2af2f0b60c7
Gitweb: https://git.kernel.org/tip/1b74444467240d9ff11cf109efdfb2af2f0b60c7
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:37 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework __disable_irq_nosync()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065422.013088277@linutronix.de
---
kernel/irq/manage.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index c18440d..edc8118 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -659,14 +659,11 @@ void __disable_irq(struct irq_desc *desc)
static int __disable_irq_nosync(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
- if (!desc)
- return -EINVAL;
- __disable_irq(desc);
- irq_put_desc_busunlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ __disable_irq(scoped_irqdesc);
+ return 0;
+ }
+ return -EINVAL;
}
/**
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_set_vcpu_affinity()
2025-04-30 12:49 ` [patch V2a " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 55ac0ad22fec0c5c5a76112725804957a62f5af7
Gitweb: https://git.kernel.org/tip/55ac0ad22fec0c5c5a76112725804957a62f5af7
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Thu, 13 Mar 2025 17:00:39 +01:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework irq_set_vcpu_affinity()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/87ikmlq0fk.ffs@tglx
---
kernel/irq/manage.c | 39 ++++++++++++++++-----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 4d08a09..c18440d 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -629,32 +629,25 @@ int irq_setup_affinity(struct irq_desc *desc)
*/
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
- struct irq_data *data;
- struct irq_chip *chip;
- int ret = -ENOSYS;
-
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ struct irq_data *data;
+ struct irq_chip *chip;
- data = irq_desc_get_irq_data(desc);
- do {
- chip = irq_data_get_irq_chip(data);
- if (chip && chip->irq_set_vcpu_affinity)
- break;
-#ifdef CONFIG_IRQ_DOMAIN_HIERARCHY
- data = data->parent_data;
-#else
- data = NULL;
-#endif
- } while (data);
+ data = irq_desc_get_irq_data(desc);
+ do {
+ chip = irq_data_get_irq_chip(data);
+ if (chip && chip->irq_set_vcpu_affinity)
+ break;
- if (data)
- ret = chip->irq_set_vcpu_affinity(data, vcpu_info);
- irq_put_desc_unlock(desc, flags);
+ data = irqd_get_parent_data(data);
+ } while (data);
- return ret;
+ if (!data)
+ return -ENOSYS;
+ return chip->irq_set_vcpu_affinity(data, vcpu_info);
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL_GPL(irq_set_vcpu_affinity);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework __irq_apply_affinity_hint()
2025-04-29 6:55 ` [patch V2 31/45] genirq/manage: Rework __irq_apply_affinity_hint() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 7e04e5c6f6158d5528f0591cc6b3fc1a2b771a90
Gitweb: https://git.kernel.org/tip/7e04e5c6f6158d5528f0591cc6b3fc1a2b771a90
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:34 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework __irq_apply_affinity_hint()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.897188799@linutronix.de
---
kernel/irq/manage.c | 22 ++++++++++------------
1 file changed, 10 insertions(+), 12 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 81f786d..4d08a09 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -480,26 +480,24 @@ int irq_force_affinity(unsigned int irq, const struct cpumask *cpumask)
}
EXPORT_SYMBOL_GPL(irq_force_affinity);
-int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m,
- bool setaffinity)
+int __irq_apply_affinity_hint(unsigned int irq, const struct cpumask *m, bool setaffinity)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ int ret = -EINVAL;
- if (!desc)
- return -EINVAL;
- desc->affinity_hint = m;
- irq_put_desc_unlock(desc, flags);
- if (m && setaffinity)
+ scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc->affinity_hint = m;
+ ret = 0;
+ }
+
+ if (!ret && m && setaffinity)
__irq_set_affinity(irq, m, false);
- return 0;
+ return ret;
}
EXPORT_SYMBOL_GPL(__irq_apply_affinity_hint);
static void irq_affinity_notify(struct work_struct *work)
{
- struct irq_affinity_notify *notify =
- container_of(work, struct irq_affinity_notify, work);
+ struct irq_affinity_notify *notify = container_of(work, struct irq_affinity_notify, work);
struct irq_desc *desc = irq_to_desc(notify->irq);
cpumask_var_t cpumask;
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Rework irq_update_affinity_desc()
2025-04-29 6:55 ` [patch V2 30/45] genirq/manage: Rework irq_update_affinity_desc() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: b0561582ea1eaa4d778b2baed18b0cc2b48674bb
Gitweb: https://git.kernel.org/tip/b0561582ea1eaa4d778b2baed18b0cc2b48674bb
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:32 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:15 +02:00
genirq/manage: Rework irq_update_affinity_desc()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.830357569@linutronix.de
---
kernel/irq/manage.c | 68 ++++++++++++++++++--------------------------
1 file changed, 28 insertions(+), 40 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 8b4b960..81f786d 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -395,14 +395,8 @@ int irq_set_affinity_locked(struct irq_data *data, const struct cpumask *mask,
* an interrupt which is already started or which has already been configured
* as managed will also fail, as these mean invalid init state or double init.
*/
-int irq_update_affinity_desc(unsigned int irq,
- struct irq_affinity_desc *affinity)
+int irq_update_affinity_desc(unsigned int irq, struct irq_affinity_desc *affinity)
{
- struct irq_desc *desc;
- unsigned long flags;
- bool activated;
- int ret = 0;
-
/*
* Supporting this with the reservation scheme used by x86 needs
* some more thought. Fail it for now.
@@ -410,44 +404,38 @@ int irq_update_affinity_desc(unsigned int irq,
if (IS_ENABLED(CONFIG_GENERIC_IRQ_RESERVATION_MODE))
return -EOPNOTSUPP;
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ bool activated;
- /* Requires the interrupt to be shut down */
- if (irqd_is_started(&desc->irq_data)) {
- ret = -EBUSY;
- goto out_unlock;
- }
-
- /* Interrupts which are already managed cannot be modified */
- if (irqd_affinity_is_managed(&desc->irq_data)) {
- ret = -EBUSY;
- goto out_unlock;
- }
+ /* Requires the interrupt to be shut down */
+ if (irqd_is_started(&desc->irq_data))
+ return -EBUSY;
- /*
- * Deactivate the interrupt. That's required to undo
- * anything an earlier activation has established.
- */
- activated = irqd_is_activated(&desc->irq_data);
- if (activated)
- irq_domain_deactivate_irq(&desc->irq_data);
-
- if (affinity->is_managed) {
- irqd_set(&desc->irq_data, IRQD_AFFINITY_MANAGED);
- irqd_set(&desc->irq_data, IRQD_MANAGED_SHUTDOWN);
- }
+ /* Interrupts which are already managed cannot be modified */
+ if (irqd_affinity_is_managed(&desc->irq_data))
+ return -EBUSY;
+ /*
+ * Deactivate the interrupt. That's required to undo
+ * anything an earlier activation has established.
+ */
+ activated = irqd_is_activated(&desc->irq_data);
+ if (activated)
+ irq_domain_deactivate_irq(&desc->irq_data);
- cpumask_copy(desc->irq_common_data.affinity, &affinity->mask);
+ if (affinity->is_managed) {
+ irqd_set(&desc->irq_data, IRQD_AFFINITY_MANAGED);
+ irqd_set(&desc->irq_data, IRQD_MANAGED_SHUTDOWN);
+ }
- /* Restore the activation state */
- if (activated)
- irq_domain_activate_irq(&desc->irq_data, false);
+ cpumask_copy(desc->irq_common_data.affinity, &affinity->mask);
-out_unlock:
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ /* Restore the activation state */
+ if (activated)
+ irq_domain_activate_irq(&desc->irq_data, false);
+ return 0;
+ }
+ return -EINVAL;
}
static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Convert to lock guards
2025-04-29 6:55 ` [patch V2 29/45] genirq/manage: Convert to lock guards Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 17c1953567ebe08c88effb053df13744d0952cd1
Gitweb: https://git.kernel.org/tip/17c1953567ebe08c88effb053df13744d0952cd1
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:31 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/manage: Convert to lock guards
Convert lock/unlock pairs to guards.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.771476066@linutronix.de
---
kernel/irq/manage.c | 155 ++++++++++++++++---------------------------
1 file changed, 58 insertions(+), 97 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 570fa5a..8b4b960 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -43,8 +43,6 @@ static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
bool inprogress;
do {
- unsigned long flags;
-
/*
* Wait until we're out of the critical section. This might
* give the wrong answer due to the lack of memory barriers.
@@ -53,7 +51,7 @@ static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
cpu_relax();
/* Ok, that indicated we're done: double-check carefully. */
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
inprogress = irqd_irq_inprogress(&desc->irq_data);
/*
@@ -69,8 +67,6 @@ static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
__irq_get_irqchip_state(irqd, IRQCHIP_STATE_ACTIVE,
&inprogress);
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
/* Oops, that failed? */
} while (inprogress);
}
@@ -458,16 +454,12 @@ static int __irq_set_affinity(unsigned int irq, const struct cpumask *mask,
bool force)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- int ret;
if (!desc)
return -EINVAL;
- raw_spin_lock_irqsave(&desc->lock, flags);
- ret = irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return ret;
+ guard(raw_spinlock_irqsave)(&desc->lock);
+ return irq_set_affinity_locked(irq_desc_get_irq_data(desc), mask, force);
}
/**
@@ -522,17 +514,16 @@ static void irq_affinity_notify(struct work_struct *work)
container_of(work, struct irq_affinity_notify, work);
struct irq_desc *desc = irq_to_desc(notify->irq);
cpumask_var_t cpumask;
- unsigned long flags;
if (!desc || !alloc_cpumask_var(&cpumask, GFP_KERNEL))
goto out;
- raw_spin_lock_irqsave(&desc->lock, flags);
- if (irq_move_pending(&desc->irq_data))
- irq_get_pending(cpumask, desc);
- else
- cpumask_copy(cpumask, desc->irq_common_data.affinity);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ if (irq_move_pending(&desc->irq_data))
+ irq_get_pending(cpumask, desc);
+ else
+ cpumask_copy(cpumask, desc->irq_common_data.affinity);
+ }
notify->notify(notify, cpumask);
@@ -556,7 +547,6 @@ int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *noti
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_affinity_notify *old_notify;
- unsigned long flags;
/* The release function is promised process context */
might_sleep();
@@ -571,10 +561,10 @@ int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *noti
INIT_WORK(¬ify->work, irq_affinity_notify);
}
- raw_spin_lock_irqsave(&desc->lock, flags);
- old_notify = desc->affinity_notify;
- desc->affinity_notify = notify;
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ old_notify = desc->affinity_notify;
+ desc->affinity_notify = notify;
+ }
if (old_notify) {
if (cancel_work_sync(&old_notify->work)) {
@@ -595,7 +585,8 @@ EXPORT_SYMBOL_GPL(irq_set_affinity_notifier);
int irq_setup_affinity(struct irq_desc *desc)
{
struct cpumask *set = irq_default_affinity;
- int ret, node = irq_desc_get_node(desc);
+ int node = irq_desc_get_node(desc);
+
static DEFINE_RAW_SPINLOCK(mask_lock);
static struct cpumask mask;
@@ -603,7 +594,7 @@ int irq_setup_affinity(struct irq_desc *desc)
if (!__irq_can_set_affinity(desc))
return 0;
- raw_spin_lock(&mask_lock);
+ guard(raw_spinlock)(&mask_lock);
/*
* Preserve the managed affinity setting and a userspace affinity
* setup, but make sure that one of the targets is online.
@@ -628,9 +619,7 @@ int irq_setup_affinity(struct irq_desc *desc)
if (cpumask_intersects(&mask, nodemask))
cpumask_and(&mask, &mask, nodemask);
}
- ret = irq_do_set_affinity(&desc->irq_data, &mask, false);
- raw_spin_unlock(&mask_lock);
- return ret;
+ return irq_do_set_affinity(&desc->irq_data, &mask, false);
}
#else
/* Wrapper for ALPHA specific affinity selector magic */
@@ -1072,19 +1061,19 @@ static void irq_thread_check_affinity(struct irq_desc *desc, struct irqaction *a
return;
}
- raw_spin_lock_irq(&desc->lock);
- /*
- * This code is triggered unconditionally. Check the affinity
- * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
- */
- if (cpumask_available(desc->irq_common_data.affinity)) {
- const struct cpumask *m;
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ /*
+ * This code is triggered unconditionally. Check the affinity
+ * mask pointer. For CPU_MASK_OFFSTACK=n this is optimized out.
+ */
+ if (cpumask_available(desc->irq_common_data.affinity)) {
+ const struct cpumask *m;
- m = irq_data_get_effective_affinity_mask(&desc->irq_data);
- cpumask_copy(mask, m);
- valid = true;
+ m = irq_data_get_effective_affinity_mask(&desc->irq_data);
+ cpumask_copy(mask, m);
+ valid = true;
+ }
}
- raw_spin_unlock_irq(&desc->lock);
if (valid)
set_cpus_allowed_ptr(current, mask);
@@ -1252,9 +1241,8 @@ static void irq_wake_secondary(struct irq_desc *desc, struct irqaction *action)
if (WARN_ON_ONCE(!secondary))
return;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
__irq_wake_thread(desc, secondary);
- raw_spin_unlock_irq(&desc->lock);
}
/*
@@ -1335,12 +1323,11 @@ void irq_wake_thread(unsigned int irq, void *dev_id)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
if (!desc || WARN_ON(irq_settings_is_per_cpu_devid(desc)))
return;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
for_each_action_of_desc(desc, action) {
if (action->dev_id == dev_id) {
if (action->thread)
@@ -1348,7 +1335,6 @@ void irq_wake_thread(unsigned int irq, void *dev_id)
break;
}
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
EXPORT_SYMBOL_GPL(irq_wake_thread);
@@ -1979,9 +1965,8 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)
* There is no interrupt on the fly anymore. Deactivate it
* completely.
*/
- raw_spin_lock_irqsave(&desc->lock, flags);
- irq_domain_deactivate_irq(&desc->irq_data);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ irq_domain_deactivate_irq(&desc->irq_data);
irq_release_resources(desc);
chip_bus_sync_unlock(desc);
@@ -2066,8 +2051,6 @@ static const void *__cleanup_nmi(unsigned int irq, struct irq_desc *desc)
const void *free_nmi(unsigned int irq, void *dev_id)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- const void *devname;
if (!desc || WARN_ON(!irq_is_nmi(desc)))
return NULL;
@@ -2079,14 +2062,9 @@ const void *free_nmi(unsigned int irq, void *dev_id)
if (WARN_ON(desc->depth == 0))
disable_nmi_nosync(irq);
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
irq_nmi_teardown(desc);
- devname = __cleanup_nmi(irq, desc);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
- return devname;
+ return __cleanup_nmi(irq, desc);
}
/**
@@ -2290,7 +2268,6 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
{
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
int retval;
if (irq == IRQ_NOTCONNECTED)
@@ -2332,21 +2309,17 @@ int request_nmi(unsigned int irq, irq_handler_t handler,
if (retval)
goto err_irq_setup;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
- /* Setup NMI state */
- desc->istate |= IRQS_NMI;
- retval = irq_nmi_setup(desc);
- if (retval) {
- __cleanup_nmi(irq, desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return -EINVAL;
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ /* Setup NMI state */
+ desc->istate |= IRQS_NMI;
+ retval = irq_nmi_setup(desc);
+ if (retval) {
+ __cleanup_nmi(irq, desc);
+ return -EINVAL;
+ }
+ return 0;
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
- return 0;
-
err_irq_setup:
irq_chip_pm_put(&desc->irq_data);
err_out:
@@ -2445,43 +2418,34 @@ static struct irqaction *__free_percpu_irq(unsigned int irq, void __percpu *dev_
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
WARN(in_interrupt(), "Trying to free IRQ %d from IRQ context!\n", irq);
if (!desc)
return NULL;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
+ action = desc->action;
+ if (!action || action->percpu_dev_id != dev_id) {
+ WARN(1, "Trying to free already-free IRQ %d\n", irq);
+ return NULL;
+ }
- action = desc->action;
- if (!action || action->percpu_dev_id != dev_id) {
- WARN(1, "Trying to free already-free IRQ %d\n", irq);
- goto bad;
- }
+ if (!cpumask_empty(desc->percpu_enabled)) {
+ WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
+ irq, cpumask_first(desc->percpu_enabled));
+ return NULL;
+ }
- if (!cpumask_empty(desc->percpu_enabled)) {
- WARN(1, "percpu IRQ %d still enabled on CPU%d!\n",
- irq, cpumask_first(desc->percpu_enabled));
- goto bad;
+ /* Found it - now remove it from the list of entries: */
+ desc->action = NULL;
+ desc->istate &= ~IRQS_NMI;
}
- /* Found it - now remove it from the list of entries: */
- desc->action = NULL;
-
- desc->istate &= ~IRQS_NMI;
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
unregister_handler_proc(irq, action);
-
irq_chip_pm_put(&desc->irq_data);
module_put(desc->owner);
return action;
-
-bad:
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return NULL;
}
/**
@@ -2651,7 +2615,6 @@ int request_percpu_nmi(unsigned int irq, irq_handler_t handler,
{
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
int retval;
if (!handler)
@@ -2687,10 +2650,8 @@ int request_percpu_nmi(unsigned int irq, irq_handler_t handler,
if (retval)
goto err_irq_setup;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
desc->istate |= IRQS_NMI;
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-
return 0;
err_irq_setup:
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_modify_status()
2025-04-29 6:55 ` [patch V2 27/45] genirq/chip: Rework irq_modify_status() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 95a3645893bceb18475c3bea4afaf47d23d11ab6
Gitweb: https://git.kernel.org/tip/95a3645893bceb18475c3bea4afaf47d23d11ab6
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:28 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/chip: Rework irq_modify_status()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.650454052@linutronix.de
---
kernel/irq/chip.c | 50 +++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 27 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 7f1c640..865cf74 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -972,38 +972,34 @@ EXPORT_SYMBOL_GPL(irq_set_chip_and_handler_name);
void irq_modify_status(unsigned int irq, unsigned long clr, unsigned long set)
{
- unsigned long flags, trigger, tmp;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return;
-
- /*
- * Warn when a driver sets the no autoenable flag on an already
- * active interrupt.
- */
- WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
-
- irq_settings_clr_and_set(desc, clr, set);
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
+ unsigned long trigger, tmp;
+ /*
+ * Warn when a driver sets the no autoenable flag on an already
+ * active interrupt.
+ */
+ WARN_ON_ONCE(!desc->depth && (set & _IRQ_NOAUTOEN));
- trigger = irqd_get_trigger_type(&desc->irq_data);
+ irq_settings_clr_and_set(desc, clr, set);
- irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
- IRQD_TRIGGER_MASK | IRQD_LEVEL);
- if (irq_settings_has_no_balance_set(desc))
- irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
- if (irq_settings_is_per_cpu(desc))
- irqd_set(&desc->irq_data, IRQD_PER_CPU);
- if (irq_settings_is_level(desc))
- irqd_set(&desc->irq_data, IRQD_LEVEL);
+ trigger = irqd_get_trigger_type(&desc->irq_data);
- tmp = irq_settings_get_trigger_mask(desc);
- if (tmp != IRQ_TYPE_NONE)
- trigger = tmp;
+ irqd_clear(&desc->irq_data, IRQD_NO_BALANCING | IRQD_PER_CPU |
+ IRQD_TRIGGER_MASK | IRQD_LEVEL);
+ if (irq_settings_has_no_balance_set(desc))
+ irqd_set(&desc->irq_data, IRQD_NO_BALANCING);
+ if (irq_settings_is_per_cpu(desc))
+ irqd_set(&desc->irq_data, IRQD_PER_CPU);
+ if (irq_settings_is_level(desc))
+ irqd_set(&desc->irq_data, IRQD_LEVEL);
- irqd_set(&desc->irq_data, trigger);
+ tmp = irq_settings_get_trigger_mask(desc);
+ if (tmp != IRQ_TYPE_NONE)
+ trigger = tmp;
- irq_put_desc_unlock(desc, flags);
+ irqd_set(&desc->irq_data, trigger);
+ }
}
EXPORT_SYMBOL_GPL(irq_modify_status);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/manage: Cleanup kernel doc comments
2025-04-29 6:55 ` [patch V2 28/45] genirq/manage: Cleanup kernel doc comments Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 0c169edf3607c74caf22aba844737348bd2381cc
Gitweb: https://git.kernel.org/tip/0c169edf3607c74caf22aba844737348bd2381cc
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:29 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/manage: Cleanup kernel doc comments
Get rid of the extra tab to make it consistent.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.710273122@linutronix.de
---
kernel/irq/manage.c | 560 ++++++++++++++++++++-----------------------
1 file changed, 271 insertions(+), 289 deletions(-)
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 753eef8..570fa5a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -76,26 +76,25 @@ static void __synchronize_hardirq(struct irq_desc *desc, bool sync_chip)
}
/**
- * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
- * @irq: interrupt number to wait for
+ * synchronize_hardirq - wait for pending hard IRQ handlers (on other CPUs)
+ * @irq: interrupt number to wait for
*
- * This function waits for any pending hard IRQ handlers for this
- * interrupt to complete before returning. If you use this
- * function while holding a resource the IRQ handler may need you
- * will deadlock. It does not take associated threaded handlers
- * into account.
+ * This function waits for any pending hard IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock. It does not take
+ * associated threaded handlers into account.
*
- * Do not use this for shutdown scenarios where you must be sure
- * that all parts (hardirq and threaded handler) have completed.
+ * Do not use this for shutdown scenarios where you must be sure that all
+ * parts (hardirq and threaded handler) have completed.
*
- * Returns: false if a threaded handler is active.
+ * Returns: false if a threaded handler is active.
*
- * This function may be called - with care - from IRQ context.
+ * This function may be called - with care - from IRQ context.
*
- * It does not check whether there is an interrupt in flight at the
- * hardware level, but not serviced yet, as this might deadlock when
- * called with interrupts disabled and the target CPU of the interrupt
- * is the current CPU.
+ * It does not check whether there is an interrupt in flight at the
+ * hardware level, but not serviced yet, as this might deadlock when called
+ * with interrupts disabled and the target CPU of the interrupt is the
+ * current CPU.
*/
bool synchronize_hardirq(unsigned int irq)
{
@@ -121,19 +120,19 @@ static void __synchronize_irq(struct irq_desc *desc)
}
/**
- * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
- * @irq: interrupt number to wait for
+ * synchronize_irq - wait for pending IRQ handlers (on other CPUs)
+ * @irq: interrupt number to wait for
*
- * This function waits for any pending IRQ handlers for this interrupt
- * to complete before returning. If you use this function while
- * holding a resource the IRQ handler may need you will deadlock.
+ * This function waits for any pending IRQ handlers for this interrupt to
+ * complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock.
*
- * Can only be called from preemptible code as it might sleep when
- * an interrupt thread is associated to @irq.
+ * Can only be called from preemptible code as it might sleep when
+ * an interrupt thread is associated to @irq.
*
- * It optionally makes sure (when the irq chip supports that method)
- * that the interrupt is not pending in any CPU and waiting for
- * service.
+ * It optionally makes sure (when the irq chip supports that method)
+ * that the interrupt is not pending in any CPU and waiting for
+ * service.
*/
void synchronize_irq(unsigned int irq)
{
@@ -156,8 +155,8 @@ static bool __irq_can_set_affinity(struct irq_desc *desc)
}
/**
- * irq_can_set_affinity - Check if the affinity of a given irq can be set
- * @irq: Interrupt to check
+ * irq_can_set_affinity - Check if the affinity of a given irq can be set
+ * @irq: Interrupt to check
*
*/
int irq_can_set_affinity(unsigned int irq)
@@ -181,13 +180,13 @@ bool irq_can_set_affinity_usr(unsigned int irq)
}
/**
- * irq_set_thread_affinity - Notify irq threads to adjust affinity
- * @desc: irq descriptor which has affinity changed
+ * irq_set_thread_affinity - Notify irq threads to adjust affinity
+ * @desc: irq descriptor which has affinity changed
*
- * We just set IRQTF_AFFINITY and delegate the affinity setting
- * to the interrupt thread itself. We can not call
- * set_cpus_allowed_ptr() here as we hold desc->lock and this
- * code can be called from hard interrupt context.
+ * Just set IRQTF_AFFINITY and delegate the affinity setting to the
+ * interrupt thread itself. We can not call set_cpus_allowed_ptr() here as
+ * we hold desc->lock and this code can be called from hard interrupt
+ * context.
*/
static void irq_set_thread_affinity(struct irq_desc *desc)
{
@@ -543,18 +542,17 @@ out:
}
/**
- * irq_set_affinity_notifier - control notification of IRQ affinity changes
- * @irq: Interrupt for which to enable/disable notification
- * @notify: Context for notification, or %NULL to disable
- * notification. Function pointers must be initialised;
- * the other fields will be initialised by this function.
- *
- * Must be called in process context. Notification may only be enabled
- * after the IRQ is allocated and must be disabled before the IRQ is
- * freed using free_irq().
+ * irq_set_affinity_notifier - control notification of IRQ affinity changes
+ * @irq: Interrupt for which to enable/disable notification
+ * @notify: Context for notification, or %NULL to disable
+ * notification. Function pointers must be initialised;
+ * the other fields will be initialised by this function.
+ *
+ * Must be called in process context. Notification may only be enabled
+ * after the IRQ is allocated and must be disabled before the IRQ is freed
+ * using free_irq().
*/
-int
-irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
+int irq_set_affinity_notifier(unsigned int irq, struct irq_affinity_notify *notify)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irq_affinity_notify *old_notify;
@@ -645,15 +643,14 @@ int irq_setup_affinity(struct irq_desc *desc)
/**
- * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
- * @irq: interrupt number to set affinity
- * @vcpu_info: vCPU specific data or pointer to a percpu array of vCPU
- * specific data for percpu_devid interrupts
- *
- * This function uses the vCPU specific data to set the vCPU
- * affinity for an irq. The vCPU specific data is passed from
- * outside, such as KVM. One example code path is as below:
- * KVM -> IOMMU -> irq_set_vcpu_affinity().
+ * irq_set_vcpu_affinity - Set vcpu affinity for the interrupt
+ * @irq: interrupt number to set affinity
+ * @vcpu_info: vCPU specific data or pointer to a percpu array of vCPU
+ * specific data for percpu_devid interrupts
+ *
+ * This function uses the vCPU specific data to set the vCPU affinity for
+ * an irq. The vCPU specific data is passed from outside, such as KVM. One
+ * example code path is as below: KVM -> IOMMU -> irq_set_vcpu_affinity().
*/
int irq_set_vcpu_affinity(unsigned int irq, void *vcpu_info)
{
@@ -705,15 +702,15 @@ static int __disable_irq_nosync(unsigned int irq)
}
/**
- * disable_irq_nosync - disable an irq without waiting
- * @irq: Interrupt to disable
+ * disable_irq_nosync - disable an irq without waiting
+ * @irq: Interrupt to disable
*
- * Disable the selected interrupt line. Disables and Enables are
- * nested.
- * Unlike disable_irq(), this function does not ensure existing
- * instances of the IRQ handler have completed before returning.
+ * Disable the selected interrupt line. Disables and Enables are
+ * nested.
+ * Unlike disable_irq(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
*
- * This function may be called from IRQ context.
+ * This function may be called from IRQ context.
*/
void disable_irq_nosync(unsigned int irq)
{
@@ -722,17 +719,17 @@ void disable_irq_nosync(unsigned int irq)
EXPORT_SYMBOL(disable_irq_nosync);
/**
- * disable_irq - disable an irq and wait for completion
- * @irq: Interrupt to disable
+ * disable_irq - disable an irq and wait for completion
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Enables and Disables are nested.
*
- * Disable the selected interrupt line. Enables and Disables are
- * nested.
- * This function waits for any pending IRQ handlers for this interrupt
- * to complete before returning. If you use this function while
- * holding a resource the IRQ handler may need you will deadlock.
+ * This function waits for any pending IRQ handlers for this interrupt to
+ * complete before returning. If you use this function while holding a
+ * resource the IRQ handler may need you will deadlock.
*
- * Can only be called from preemptible code as it might sleep when
- * an interrupt thread is associated to @irq.
+ * Can only be called from preemptible code as it might sleep when an
+ * interrupt thread is associated to @irq.
*
*/
void disable_irq(unsigned int irq)
@@ -744,40 +741,39 @@ void disable_irq(unsigned int irq)
EXPORT_SYMBOL(disable_irq);
/**
- * disable_hardirq - disables an irq and waits for hardirq completion
- * @irq: Interrupt to disable
+ * disable_hardirq - disables an irq and waits for hardirq completion
+ * @irq: Interrupt to disable
*
- * Disable the selected interrupt line. Enables and Disables are
- * nested.
- * This function waits for any pending hard IRQ handlers for this
- * interrupt to complete before returning. If you use this function while
- * holding a resource the hard IRQ handler may need you will deadlock.
+ * Disable the selected interrupt line. Enables and Disables are nested.
*
- * When used to optimistically disable an interrupt from atomic context
- * the return value must be checked.
+ * This function waits for any pending hard IRQ handlers for this interrupt
+ * to complete before returning. If you use this function while holding a
+ * resource the hard IRQ handler may need you will deadlock.
*
- * Returns: false if a threaded handler is active.
+ * When used to optimistically disable an interrupt from atomic context the
+ * return value must be checked.
*
- * This function may be called - with care - from IRQ context.
+ * Returns: false if a threaded handler is active.
+ *
+ * This function may be called - with care - from IRQ context.
*/
bool disable_hardirq(unsigned int irq)
{
if (!__disable_irq_nosync(irq))
return synchronize_hardirq(irq);
-
return false;
}
EXPORT_SYMBOL_GPL(disable_hardirq);
/**
- * disable_nmi_nosync - disable an nmi without waiting
- * @irq: Interrupt to disable
- *
- * Disable the selected interrupt line. Disables and enables are
- * nested.
- * The interrupt to disable must have been requested through request_nmi.
- * Unlike disable_nmi(), this function does not ensure existing
- * instances of the IRQ handler have completed before returning.
+ * disable_nmi_nosync - disable an nmi without waiting
+ * @irq: Interrupt to disable
+ *
+ * Disable the selected interrupt line. Disables and enables are nested.
+ *
+ * The interrupt to disable must have been requested through request_nmi.
+ * Unlike disable_nmi(), this function does not ensure existing
+ * instances of the IRQ handler have completed before returning.
*/
void disable_nmi_nosync(unsigned int irq)
{
@@ -817,15 +813,14 @@ void __enable_irq(struct irq_desc *desc)
}
/**
- * enable_irq - enable handling of an irq
- * @irq: Interrupt to enable
+ * enable_irq - enable handling of an irq
+ * @irq: Interrupt to enable
*
- * Undoes the effect of one call to disable_irq(). If this
- * matches the last disable, processing of interrupts on this
- * IRQ line is re-enabled.
+ * Undoes the effect of one call to disable_irq(). If this matches the
+ * last disable, processing of interrupts on this IRQ line is re-enabled.
*
- * This function may be called from IRQ context only when
- * desc->irq_data.chip->bus_lock and desc->chip->bus_sync_unlock are NULL !
+ * This function may be called from IRQ context only when
+ * desc->irq_data.chip->bus_lock and desc->chip->bus_sync_unlock are NULL !
*/
void enable_irq(unsigned int irq)
{
@@ -845,13 +840,12 @@ out:
EXPORT_SYMBOL(enable_irq);
/**
- * enable_nmi - enable handling of an nmi
- * @irq: Interrupt to enable
+ * enable_nmi - enable handling of an nmi
+ * @irq: Interrupt to enable
*
- * The interrupt to enable must have been requested through request_nmi.
- * Undoes the effect of one call to disable_nmi(). If this
- * matches the last disable, processing of interrupts on this
- * IRQ line is re-enabled.
+ * The interrupt to enable must have been requested through request_nmi.
+ * Undoes the effect of one call to disable_nmi(). If this matches the last
+ * disable, processing of interrupts on this IRQ line is re-enabled.
*/
void enable_nmi(unsigned int irq)
{
@@ -873,23 +867,22 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
}
/**
- * irq_set_irq_wake - control irq power management wakeup
- * @irq: interrupt to control
- * @on: enable/disable power management wakeup
- *
- * Enable/disable power management wakeup mode, which is
- * disabled by default. Enables and disables must match,
- * just as they match for non-wakeup mode support.
- *
- * Wakeup mode lets this IRQ wake the system from sleep
- * states like "suspend to RAM".
- *
- * Note: irq enable/disable state is completely orthogonal
- * to the enable/disable state of irq wake. An irq can be
- * disabled with disable_irq() and still wake the system as
- * long as the irq has wake enabled. If this does not hold,
- * then the underlying irq chip and the related driver need
- * to be investigated.
+ * irq_set_irq_wake - control irq power management wakeup
+ * @irq: interrupt to control
+ * @on: enable/disable power management wakeup
+ *
+ * Enable/disable power management wakeup mode, which is disabled by
+ * default. Enables and disables must match, just as they match for
+ * non-wakeup mode support.
+ *
+ * Wakeup mode lets this IRQ wake the system from sleep states like
+ * "suspend to RAM".
+ *
+ * Note: irq enable/disable state is completely orthogonal to the
+ * enable/disable state of irq wake. An irq can be disabled with
+ * disable_irq() and still wake the system as long as the irq has wake
+ * enabled. If this does not hold, then the underlying irq chip and the
+ * related driver need to be investigated.
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
@@ -1334,10 +1327,9 @@ static int irq_thread(void *data)
}
/**
- * irq_wake_thread - wake the irq thread for the action identified by dev_id
- * @irq: Interrupt line
- * @dev_id: Device identity for which the thread should be woken
- *
+ * irq_wake_thread - wake the irq thread for the action identified by dev_id
+ * @irq: Interrupt line
+ * @dev_id: Device identity for which the thread should be woken
*/
void irq_wake_thread(unsigned int irq, void *dev_id)
{
@@ -2005,20 +1997,19 @@ static struct irqaction *__free_irq(struct irq_desc *desc, void *dev_id)
}
/**
- * free_irq - free an interrupt allocated with request_irq
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
+ * free_irq - free an interrupt allocated with request_irq
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
*
- * Remove an interrupt handler. The handler is removed and if the
- * interrupt line is no longer in use by any driver it is disabled.
- * On a shared IRQ the caller must ensure the interrupt is disabled
- * on the card it drives before calling this function. The function
- * does not return until any executing interrupts for this IRQ
- * have completed.
+ * Remove an interrupt handler. The handler is removed and if the interrupt
+ * line is no longer in use by any driver it is disabled. On a shared IRQ
+ * the caller must ensure the interrupt is disabled on the card it drives
+ * before calling this function. The function does not return until any
+ * executing interrupts for this IRQ have completed.
*
- * This function must not be called from interrupt context.
+ * This function must not be called from interrupt context.
*
- * Returns the devname argument passed to request_irq.
+ * Returns the devname argument passed to request_irq.
*/
const void *free_irq(unsigned int irq, void *dev_id)
{
@@ -2099,42 +2090,40 @@ const void *free_nmi(unsigned int irq, void *dev_id)
}
/**
- * request_threaded_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Primary handler for threaded interrupts.
- * If handler is NULL and thread_fn != NULL
- * the default primary handler is installed.
- * @thread_fn: Function called from the irq handler thread
- * If NULL, no irq thread is created
- * @irqflags: Interrupt type flags
- * @devname: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. From the point this
- * call is made your handler function may be invoked. Since
- * your handler function must clear any interrupt the board
- * raises, you must take care both to initialise your hardware
- * and to set up the interrupt handler in the right order.
- *
- * If you want to set up a threaded irq handler for your device
- * then you need to supply @handler and @thread_fn. @handler is
- * still called in hard interrupt context and has to check
- * whether the interrupt originates from the device. If yes it
- * needs to disable the interrupt on the device and return
- * IRQ_WAKE_THREAD which will wake up the handler thread and run
- * @thread_fn. This split handler design is necessary to support
- * shared interrupts.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
- *
- * If your interrupt is shared you must pass a non NULL dev_id
- * as this is required when freeing the interrupt.
- *
- * Flags:
+ * request_threaded_irq - allocate an interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Primary handler for threaded interrupts.
+ * If handler is NULL and thread_fn != NULL
+ * the default primary handler is installed.
+ * @thread_fn: Function called from the irq handler thread
+ * If NULL, no irq thread is created
+ * @irqflags: Interrupt type flags
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. From the point this call is made your handler function
+ * may be invoked. Since your handler function must clear any interrupt the
+ * board raises, you must take care both to initialise your hardware and to
+ * set up the interrupt handler in the right order.
+ *
+ * If you want to set up a threaded irq handler for your device then you
+ * need to supply @handler and @thread_fn. @handler is still called in hard
+ * interrupt context and has to check whether the interrupt originates from
+ * the device. If yes it needs to disable the interrupt on the device and
+ * return IRQ_WAKE_THREAD which will wake up the handler thread and run
+ * @thread_fn. This split handler design is necessary to support shared
+ * interrupts.
+ *
+ * @dev_id must be globally unique. Normally the address of the device data
+ * structure is used as the cookie. Since the handler receives this value
+ * it makes sense to use it.
+ *
+ * If your interrupt is shared you must pass a non NULL dev_id as this is
+ * required when freeing the interrupt.
+ *
+ * Flags:
*
* IRQF_SHARED Interrupt is shared
* IRQF_TRIGGER_* Specify active edge(s) or level
@@ -2232,21 +2221,20 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
EXPORT_SYMBOL(request_threaded_irq);
/**
- * request_any_context_irq - allocate an interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Threaded handler for threaded interrupts.
- * @flags: Interrupt type flags
- * @name: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. It selects either a
- * hardirq or threaded handling method depending on the
- * context.
- *
- * On failure, it returns a negative value. On success,
- * it returns either IRQC_IS_HARDIRQ or IRQC_IS_NESTED.
+ * request_any_context_irq - allocate an interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Threaded handler for threaded interrupts.
+ * @flags: Interrupt type flags
+ * @name: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. It selects either a hardirq or threaded handling
+ * method depending on the context.
+ *
+ * Returns: On failure, it returns a negative value. On success, it returns either
+ * IRQC_IS_HARDIRQ or IRQC_IS_NESTED.
*/
int request_any_context_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *name, void *dev_id)
@@ -2273,30 +2261,29 @@ int request_any_context_irq(unsigned int irq, irq_handler_t handler,
EXPORT_SYMBOL_GPL(request_any_context_irq);
/**
- * request_nmi - allocate an interrupt line for NMI delivery
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * Threaded handler for threaded interrupts.
- * @irqflags: Interrupt type flags
- * @name: An ascii name for the claiming device
- * @dev_id: A cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt line and IRQ handling. It sets up the IRQ line
- * to be handled as an NMI.
- *
- * An interrupt line delivering NMIs cannot be shared and IRQ handling
- * cannot be threaded.
- *
- * Interrupt lines requested for NMI delivering must produce per cpu
- * interrupts and have auto enabling setting disabled.
- *
- * Dev_id must be globally unique. Normally the address of the
- * device data structure is used as the cookie. Since the handler
- * receives this value it makes sense to use it.
- *
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail and return a negative value.
+ * request_nmi - allocate an interrupt line for NMI delivery
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * Threaded handler for threaded interrupts.
+ * @irqflags: Interrupt type flags
+ * @name: An ascii name for the claiming device
+ * @dev_id: A cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt line
+ * and IRQ handling. It sets up the IRQ line to be handled as an NMI.
+ *
+ * An interrupt line delivering NMIs cannot be shared and IRQ handling
+ * cannot be threaded.
+ *
+ * Interrupt lines requested for NMI delivering must produce per cpu
+ * interrupts and have auto enabling setting disabled.
+ *
+ * @dev_id must be globally unique. Normally the address of the device data
+ * structure is used as the cookie. Since the handler receives this value
+ * it makes sense to use it.
+ *
+ * If the interrupt line cannot be used to deliver NMIs, function will fail
+ * and return a negative value.
*/
int request_nmi(unsigned int irq, irq_handler_t handler,
unsigned long irqflags, const char *name, void *dev_id)
@@ -2498,9 +2485,9 @@ bad:
}
/**
- * remove_percpu_irq - free a per-cpu interrupt
- * @irq: Interrupt line to free
- * @act: irqaction for the interrupt
+ * remove_percpu_irq - free a per-cpu interrupt
+ * @irq: Interrupt line to free
+ * @act: irqaction for the interrupt
*
* Used to remove interrupts statically setup by the early boot process.
*/
@@ -2509,20 +2496,20 @@ void remove_percpu_irq(unsigned int irq, struct irqaction *act)
struct irq_desc *desc = irq_to_desc(irq);
if (desc && irq_settings_is_per_cpu_devid(desc))
- __free_percpu_irq(irq, act->percpu_dev_id);
+ __free_percpu_irq(irq, act->percpu_dev_id);
}
/**
- * free_percpu_irq - free an interrupt allocated with request_percpu_irq
- * @irq: Interrupt line to free
- * @dev_id: Device identity to free
+ * free_percpu_irq - free an interrupt allocated with request_percpu_irq
+ * @irq: Interrupt line to free
+ * @dev_id: Device identity to free
*
- * Remove a percpu interrupt handler. The handler is removed, but
- * the interrupt line is not disabled. This must be done on each
- * CPU before calling this function. The function does not return
- * until any executing interrupts for this IRQ have completed.
+ * Remove a percpu interrupt handler. The handler is removed, but the
+ * interrupt line is not disabled. This must be done on each CPU before
+ * calling this function. The function does not return until any executing
+ * interrupts for this IRQ have completed.
*
- * This function must not be called from interrupt context.
+ * This function must not be called from interrupt context.
*/
void free_percpu_irq(unsigned int irq, void __percpu *dev_id)
{
@@ -2551,9 +2538,9 @@ void free_percpu_nmi(unsigned int irq, void __percpu *dev_id)
}
/**
- * setup_percpu_irq - setup a per-cpu interrupt
- * @irq: Interrupt line to setup
- * @act: irqaction for the interrupt
+ * setup_percpu_irq - setup a per-cpu interrupt
+ * @irq: Interrupt line to setup
+ * @act: irqaction for the interrupt
*
* Used to statically setup per-cpu interrupts in the early boot process.
*/
@@ -2578,21 +2565,20 @@ int setup_percpu_irq(unsigned int irq, struct irqaction *act)
}
/**
- * __request_percpu_irq - allocate a percpu interrupt line
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * @flags: Interrupt type flags (IRQF_TIMER only)
- * @devname: An ascii name for the claiming device
- * @dev_id: A percpu cookie passed back to the handler function
- *
- * This call allocates interrupt resources and enables the
- * interrupt on the local CPU. If the interrupt is supposed to be
- * enabled on other CPUs, it has to be done on each CPU using
- * enable_percpu_irq().
- *
- * Dev_id must be globally unique. It is a per-cpu variable, and
- * the handler gets called with the interrupted CPU's instance of
- * that variable.
+ * __request_percpu_irq - allocate a percpu interrupt line
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * @flags: Interrupt type flags (IRQF_TIMER only)
+ * @devname: An ascii name for the claiming device
+ * @dev_id: A percpu cookie passed back to the handler function
+ *
+ * This call allocates interrupt resources and enables the interrupt on the
+ * local CPU. If the interrupt is supposed to be enabled on other CPUs, it
+ * has to be done on each CPU using enable_percpu_irq().
+ *
+ * @dev_id must be globally unique. It is a per-cpu variable, and
+ * the handler gets called with the interrupted CPU's instance of
+ * that variable.
*/
int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
unsigned long flags, const char *devname,
@@ -2640,25 +2626,25 @@ int __request_percpu_irq(unsigned int irq, irq_handler_t handler,
EXPORT_SYMBOL_GPL(__request_percpu_irq);
/**
- * request_percpu_nmi - allocate a percpu interrupt line for NMI delivery
- * @irq: Interrupt line to allocate
- * @handler: Function to be called when the IRQ occurs.
- * @name: An ascii name for the claiming device
- * @dev_id: A percpu cookie passed back to the handler function
+ * request_percpu_nmi - allocate a percpu interrupt line for NMI delivery
+ * @irq: Interrupt line to allocate
+ * @handler: Function to be called when the IRQ occurs.
+ * @name: An ascii name for the claiming device
+ * @dev_id: A percpu cookie passed back to the handler function
*
- * This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs
- * have to be setup on each CPU by calling prepare_percpu_nmi() before
- * being enabled on the same CPU by using enable_percpu_nmi().
+ * This call allocates interrupt resources for a per CPU NMI. Per CPU NMIs
+ * have to be setup on each CPU by calling prepare_percpu_nmi() before
+ * being enabled on the same CPU by using enable_percpu_nmi().
*
- * Dev_id must be globally unique. It is a per-cpu variable, and
- * the handler gets called with the interrupted CPU's instance of
- * that variable.
+ * @dev_id must be globally unique. It is a per-cpu variable, and the
+ * handler gets called with the interrupted CPU's instance of that
+ * variable.
*
- * Interrupt lines requested for NMI delivering should have auto enabling
- * setting disabled.
+ * Interrupt lines requested for NMI delivering should have auto enabling
+ * setting disabled.
*
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail returning a negative value.
+ * If the interrupt line cannot be used to deliver NMIs, function
+ * will fail returning a negative value.
*/
int request_percpu_nmi(unsigned int irq, irq_handler_t handler,
const char *name, void __percpu *dev_id)
@@ -2716,17 +2702,17 @@ err_out:
}
/**
- * prepare_percpu_nmi - performs CPU local setup for NMI delivery
- * @irq: Interrupt line to prepare for NMI delivery
+ * prepare_percpu_nmi - performs CPU local setup for NMI delivery
+ * @irq: Interrupt line to prepare for NMI delivery
*
- * This call prepares an interrupt line to deliver NMI on the current CPU,
- * before that interrupt line gets enabled with enable_percpu_nmi().
+ * This call prepares an interrupt line to deliver NMI on the current CPU,
+ * before that interrupt line gets enabled with enable_percpu_nmi().
*
- * As a CPU local operation, this should be called from non-preemptible
- * context.
+ * As a CPU local operation, this should be called from non-preemptible
+ * context.
*
- * If the interrupt line cannot be used to deliver NMIs, function
- * will fail returning a negative value.
+ * If the interrupt line cannot be used to deliver NMIs, function will fail
+ * returning a negative value.
*/
int prepare_percpu_nmi(unsigned int irq)
{
@@ -2760,16 +2746,14 @@ out:
}
/**
- * teardown_percpu_nmi - undoes NMI setup of IRQ line
- * @irq: Interrupt line from which CPU local NMI configuration should be
- * removed
- *
- * This call undoes the setup done by prepare_percpu_nmi().
+ * teardown_percpu_nmi - undoes NMI setup of IRQ line
+ * @irq: Interrupt line from which CPU local NMI configuration should be removed
*
- * IRQ line should not be enabled for the current CPU.
+ * This call undoes the setup done by prepare_percpu_nmi().
*
- * As a CPU local operation, this should be called from non-preemptible
- * context.
+ * IRQ line should not be enabled for the current CPU.
+ * As a CPU local operation, this should be called from non-preemptible
+ * context.
*/
void teardown_percpu_nmi(unsigned int irq)
{
@@ -2815,17 +2799,16 @@ static int __irq_get_irqchip_state(struct irq_data *data, enum irqchip_irq_state
}
/**
- * irq_get_irqchip_state - returns the irqchip state of a interrupt.
- * @irq: Interrupt line that is forwarded to a VM
- * @which: One of IRQCHIP_STATE_* the caller wants to know about
- * @state: a pointer to a boolean where the state is to be stored
+ * irq_get_irqchip_state - returns the irqchip state of a interrupt.
+ * @irq: Interrupt line that is forwarded to a VM
+ * @which: One of IRQCHIP_STATE_* the caller wants to know about
+ * @state: a pointer to a boolean where the state is to be stored
*
- * This call snapshots the internal irqchip state of an
- * interrupt, returning into @state the bit corresponding to
- * stage @which
+ * This call snapshots the internal irqchip state of an interrupt,
+ * returning into @state the bit corresponding to stage @which
*
- * This function should be called with preemption disabled if the
- * interrupt controller has per-cpu registers.
+ * This function should be called with preemption disabled if the interrupt
+ * controller has per-cpu registers.
*/
int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
bool *state)
@@ -2849,19 +2832,18 @@ int irq_get_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
EXPORT_SYMBOL_GPL(irq_get_irqchip_state);
/**
- * irq_set_irqchip_state - set the state of a forwarded interrupt.
- * @irq: Interrupt line that is forwarded to a VM
- * @which: State to be restored (one of IRQCHIP_STATE_*)
- * @val: Value corresponding to @which
+ * irq_set_irqchip_state - set the state of a forwarded interrupt.
+ * @irq: Interrupt line that is forwarded to a VM
+ * @which: State to be restored (one of IRQCHIP_STATE_*)
+ * @val: Value corresponding to @which
*
- * This call sets the internal irqchip state of an interrupt,
- * depending on the value of @which.
+ * This call sets the internal irqchip state of an interrupt, depending on
+ * the value of @which.
*
- * This function should be called with migration disabled if the
- * interrupt controller has per-cpu registers.
+ * This function should be called with migration disabled if the interrupt
+ * controller has per-cpu registers.
*/
-int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which,
- bool val)
+int irq_set_irqchip_state(unsigned int irq, enum irqchip_irq_state which, bool val)
{
struct irq_desc *desc;
struct irq_data *data;
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_handler() variants
2025-04-29 6:55 ` [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
2025-05-09 13:22 ` [patch V2 26/45] " Nathan Chancellor
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 5cd05f3e23152b97e0be09938c78058395c3ee19
Gitweb: https://git.kernel.org/tip/5cd05f3e23152b97e0be09938c78058395c3ee19
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:26 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/chip: Rework irq_set_handler() variants
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.590753128@linutronix.de
---
kernel/irq/chip.c | 34 +++++++++++-----------------------
1 file changed, 11 insertions(+), 23 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 2041225..7f1c640 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -941,35 +941,23 @@ __irq_do_set_handler(struct irq_desc *desc, irq_flow_handler_t handle,
}
}
-void
-__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
- const char *name)
+void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
+ const char *name)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
-
- if (!desc)
- return;
-
- __irq_do_set_handler(desc, handle, is_chained, name);
- irq_put_desc_busunlock(desc, flags);
+ scoped_irqdesc_get_and_lock(irq, 0)
+ __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name);
}
EXPORT_SYMBOL_GPL(__irq_set_handler);
-void
-irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
- void *data)
+void irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
+ void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return;
-
- desc->irq_common_data.handler_data = data;
- __irq_do_set_handler(desc, handle, 1, NULL);
-
- irq_put_desc_busunlock(desc, flags);
+ desc->irq_common_data.handler_data = data;
+ __irq_do_set_handler(desc, handle, 1, NULL);
+ }
}
EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_chip_data()
2025-04-29 6:55 ` [patch V2 25/45] genirq/chip: Rework irq_set_chip_data() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: b3801ddc6883169a2e020dbf06da3723446808ee
Gitweb: https://git.kernel.org/tip/b3801ddc6883169a2e020dbf06da3723446808ee
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:25 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/chip: Rework irq_set_chip_data()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.532308759@linutronix.de
---
kernel/irq/chip.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 13d8c89..2041225 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -115,22 +115,19 @@ int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
}
/**
- * irq_set_chip_data - set irq chip data for an irq
- * @irq: Interrupt number
- * @data: Pointer to chip specific data
+ * irq_set_chip_data - set irq chip data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to chip specific data
*
- * Set the hardware irq chip data for an irq
+ * Set the hardware irq chip data for an irq
*/
int irq_set_chip_data(unsigned int irq, void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
- desc->irq_data.chip_data = data;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_data.chip_data = data;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_chip_data);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_msi_desc_off()
2025-04-29 6:55 ` [patch V2 24/45] genirq/chip: Rework irq_set_msi_desc_off() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: c836e5a70c59a361559d57ad02ececa40d160cb9
Gitweb: https://git.kernel.org/tip/c836e5a70c59a361559d57ad02ececa40d160cb9
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:23 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/chip: Rework irq_set_msi_desc_off()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.473563978@linutronix.de
---
kernel/irq/chip.c | 38 +++++++++++++++++---------------------
1 file changed, 17 insertions(+), 21 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 7694e3e..13d8c89 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -84,34 +84,30 @@ int irq_set_handler_data(unsigned int irq, void *data)
EXPORT_SYMBOL(irq_set_handler_data);
/**
- * irq_set_msi_desc_off - set MSI descriptor data for an irq at offset
- * @irq_base: Interrupt number base
- * @irq_offset: Interrupt number offset
- * @entry: Pointer to MSI descriptor data
+ * irq_set_msi_desc_off - set MSI descriptor data for an irq at offset
+ * @irq_base: Interrupt number base
+ * @irq_offset: Interrupt number offset
+ * @entry: Pointer to MSI descriptor data
*
- * Set the MSI descriptor entry for an irq at offset
+ * Set the MSI descriptor entry for an irq at offset
*/
-int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset,
- struct msi_desc *entry)
+int irq_set_msi_desc_off(unsigned int irq_base, unsigned int irq_offset, struct msi_desc *entry)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq_base + irq_offset, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
-
- if (!desc)
- return -EINVAL;
- desc->irq_common_data.msi_desc = entry;
- if (entry && !irq_offset)
- entry->irq = irq_base;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq_base + irq_offset, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc->irq_common_data.msi_desc = entry;
+ if (entry && !irq_offset)
+ entry->irq = irq_base;
+ return 0;
+ }
+ return -EINVAL;
}
/**
- * irq_set_msi_desc - set MSI descriptor data for an irq
- * @irq: Interrupt number
- * @entry: Pointer to MSI descriptor data
+ * irq_set_msi_desc - set MSI descriptor data for an irq
+ * @irq: Interrupt number
+ * @entry: Pointer to MSI descriptor data
*
- * Set the MSI descriptor entry for an irq
+ * Set the MSI descriptor entry for an irq
*/
int irq_set_msi_desc(unsigned int irq, struct msi_desc *entry)
{
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_handler_data()
2025-04-29 6:55 ` [patch V2 23/45] genirq/chip: Rework irq_set_handler_data() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 321a0fdf1337c5449a589b3d8186b23ecd36b240
Gitweb: https://git.kernel.org/tip/321a0fdf1337c5449a589b3d8186b23ecd36b240
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:22 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:14 +02:00
genirq/chip: Rework irq_set_handler_data()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.415072350@linutronix.de
---
kernel/irq/chip.c | 21 +++++++++------------
1 file changed, 9 insertions(+), 12 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 0904886..7694e3e 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -67,22 +67,19 @@ int irq_set_irq_type(unsigned int irq, unsigned int type)
EXPORT_SYMBOL(irq_set_irq_type);
/**
- * irq_set_handler_data - set irq handler data for an irq
- * @irq: Interrupt number
- * @data: Pointer to interrupt specific data
+ * irq_set_handler_data - set irq handler data for an irq
+ * @irq: Interrupt number
+ * @data: Pointer to interrupt specific data
*
- * Set the hardware irq controller data for an irq
+ * Set the hardware irq controller data for an irq
*/
int irq_set_handler_data(unsigned int irq, void *data)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
- desc->irq_common_data.handler_data = data;
- irq_put_desc_unlock(desc, flags);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_common_data.handler_data = data;
+ return 0;
+ }
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_handler_data);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_irq_type()
2025-04-29 6:55 ` [patch V2 22/45] genirq/chip: Rework irq_set_irq_type() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: fa870e0f3551cfff90c7d0261e8f208a83097946
Gitweb: https://git.kernel.org/tip/fa870e0f3551cfff90c7d0261e8f208a83097946
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:20 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework irq_set_irq_type()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.355673840@linutronix.de
---
kernel/irq/chip.c | 19 ++++++-------------
1 file changed, 6 insertions(+), 13 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 92bf81a..0904886 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -54,22 +54,15 @@ int irq_set_chip(unsigned int irq, const struct irq_chip *chip)
EXPORT_SYMBOL(irq_set_chip);
/**
- * irq_set_irq_type - set the irq trigger type for an irq
- * @irq: irq number
- * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
+ * irq_set_irq_type - set the irq trigger type for an irq
+ * @irq: irq number
+ * @type: IRQ_TYPE_{LEVEL,EDGE}_* value - see include/linux/irq.h
*/
int irq_set_irq_type(unsigned int irq, unsigned int type)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
- int ret = 0;
-
- if (!desc)
- return -EINVAL;
-
- ret = __irq_set_trigger(desc, type);
- irq_put_desc_busunlock(desc, flags);
- return ret;
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL)
+ return __irq_set_trigger(scoped_irqdesc, type);
+ return -EINVAL;
}
EXPORT_SYMBOL(irq_set_irq_type);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework irq_set_chip()
2025-04-29 6:55 ` [patch V2 21/45] genirq/chip: Rework irq_set_chip() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 46ff4d11f081ef9bc3df3d56f54a10e955dba733
Gitweb: https://git.kernel.org/tip/46ff4d11f081ef9bc3df3d56f54a10e955dba733
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:19 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework irq_set_chip()
Use the new guards to get and lock the interrupt descriptor and tidy up the
code.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.295400891@linutronix.de
---
kernel/irq/chip.c | 28 ++++++++++++----------------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index daa356a..92bf81a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -34,26 +34,22 @@ struct irqaction chained_action = {
};
/**
- * irq_set_chip - set the irq chip for an irq
- * @irq: irq number
- * @chip: pointer to irq chip description structure
+ * irq_set_chip - set the irq chip for an irq
+ * @irq: irq number
+ * @chip: pointer to irq chip description structure
*/
int irq_set_chip(unsigned int irq, const struct irq_chip *chip)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_lock(irq, &flags, 0);
-
- if (!desc)
- return -EINVAL;
+ int ret = -EINVAL;
- desc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
- irq_put_desc_unlock(desc, flags);
- /*
- * For !CONFIG_SPARSE_IRQ make the irq show up in
- * allocated_irqs.
- */
- irq_mark_irq(irq);
- return 0;
+ scoped_irqdesc_get_and_lock(irq, 0) {
+ scoped_irqdesc->irq_data.chip = (struct irq_chip *)(chip ?: &no_irq_chip);
+ ret = 0;
+ }
+ /* For !CONFIG_SPARSE_IRQ make the irq show up in allocated_irqs. */
+ if (!ret)
+ irq_mark_irq(irq);
+ return ret;
}
EXPORT_SYMBOL(irq_set_chip);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Use lock guards where applicable
2025-04-29 6:55 ` [patch V2 20/45] genirq/chip: Use lock guards where applicable Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: e7c654255791e9a95b62b992ef3540dfee00e8d5
Gitweb: https://git.kernel.org/tip/e7c654255791e9a95b62b992ef3540dfee00e8d5
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:17 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Use lock guards where applicable
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.236248749@linutronix.de
---
kernel/irq/chip.c | 24 ++++++++----------------
1 file changed, 8 insertions(+), 16 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 2b23630..daa356a 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1049,25 +1049,21 @@ EXPORT_SYMBOL_GPL(irq_modify_status);
*/
void irq_cpu_online(void)
{
- struct irq_desc *desc;
- struct irq_chip *chip;
- unsigned long flags;
unsigned int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_chip *chip;
+
if (!desc)
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
chip = irq_data_get_irq_chip(&desc->irq_data);
if (chip && chip->irq_cpu_online &&
(!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
!irqd_irq_disabled(&desc->irq_data)))
chip->irq_cpu_online(&desc->irq_data);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -1079,25 +1075,21 @@ void irq_cpu_online(void)
*/
void irq_cpu_offline(void)
{
- struct irq_desc *desc;
- struct irq_chip *chip;
- unsigned long flags;
unsigned int irq;
for_each_active_irq(irq) {
- desc = irq_to_desc(irq);
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irq_chip *chip;
+
if (!desc)
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
-
+ guard(raw_spinlock_irqsave)(&desc->lock);
chip = irq_data_get_irq_chip(&desc->irq_data);
if (chip && chip->irq_cpu_offline &&
(!(chip->flags & IRQCHIP_ONOFFLINE_ENABLED) ||
!irqd_irq_disabled(&desc->irq_data)))
chip->irq_cpu_offline(&desc->irq_data);
-
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
#endif
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_fasteoi_ack_irq()
2025-04-29 6:55 ` [patch V2 18/45] genirq/chip: Rework handle_fasteoi_ack_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 2beb01cbb75e5849b6ebc15917c7dd3e46264b48
Gitweb: https://git.kernel.org/tip/2beb01cbb75e5849b6ebc15917c7dd3e46264b48
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:14 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework handle_fasteoi_ack_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.105015800@linutronix.de
---
kernel/irq/chip.c | 39 +++++++++++++--------------------------
1 file changed, 13 insertions(+), 26 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 6c33679..2b60542 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1106,53 +1106,40 @@ void irq_cpu_offline(void)
#ifdef CONFIG_IRQ_FASTEOI_HIERARCHY_HANDLERS
/**
- * handle_fasteoi_ack_irq - irq handler for edge hierarchy
- * stacked on transparent controllers
+ * handle_fasteoi_ack_irq - irq handler for edge hierarchy stacked on
+ * transparent controllers
*
- * @desc: the interrupt description structure for this irq
+ * @desc: the interrupt description structure for this irq
*
- * Like handle_fasteoi_irq(), but for use with hierarchy where
- * the irq_chip also needs to have its ->irq_ack() function
- * called.
+ * Like handle_fasteoi_irq(), but for use with hierarchy where the irq_chip
+ * also needs to have its ->irq_ack() function called.
*/
void handle_fasteoi_ack_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
-
- if (!irq_can_handle_pm(desc))
- goto out;
+ guard(raw_spinlock)(&desc->lock);
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+ if (!irq_can_handle_pm(desc)) {
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
+ }
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
+ if (unlikely(!irq_can_handle_actions(desc))) {
mask_irq(desc);
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
if (desc->istate & IRQS_ONESHOT)
mask_irq(desc);
- /* Start handling the irq */
desc->irq_data.chip->irq_ack(&desc->irq_data);
handle_irq_event(desc);
cond_unmask_eoi_irq(desc, chip);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_fasteoi_mask_irq()
2025-04-29 6:55 ` [patch V2 19/45] genirq/chip: Rework handle_fasteoi_mask_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: f71d7c45edadfa98edac74bfdf820cce5482673a
Gitweb: https://git.kernel.org/tip/f71d7c45edadfa98edac74bfdf820cce5482673a
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:16 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework handle_fasteoi_mask_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Note: The mask_irq() operation in the second condition was redundant as the
interrupt is already masked right at the beginning of the function.
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.175652864@linutronix.de
---
kernel/irq/chip.c | 38 +++++++++-----------------------------
1 file changed, 9 insertions(+), 29 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 2b60542..2b23630 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -1144,51 +1144,31 @@ void handle_fasteoi_ack_irq(struct irq_desc *desc)
EXPORT_SYMBOL_GPL(handle_fasteoi_ack_irq);
/**
- * handle_fasteoi_mask_irq - irq handler for level hierarchy
- * stacked on transparent controllers
+ * handle_fasteoi_mask_irq - irq handler for level hierarchy stacked on
+ * transparent controllers
*
- * @desc: the interrupt description structure for this irq
+ * @desc: the interrupt description structure for this irq
*
- * Like handle_fasteoi_irq(), but for use with hierarchy where
- * the irq_chip also needs to have its ->irq_mask_ack() function
- * called.
+ * Like handle_fasteoi_irq(), but for use with hierarchy where the irq_chip
+ * also needs to have its ->irq_mask_ack() function called.
*/
void handle_fasteoi_mask_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
mask_ack_irq(desc);
- if (!irq_can_handle_pm(desc))
- goto out;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- mask_irq(desc);
- goto out;
+ if (!irq_can_handle(desc)) {
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
- if (desc->istate & IRQS_ONESHOT)
- mask_irq(desc);
handle_irq_event(desc);
cond_unmask_eoi_irq(desc, chip);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_mask_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_edge_irq()
2025-04-29 6:55 ` [patch V2 17/45] genirq/chip: Rework handle_edge_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 2d46aea52c02612d1b49aa562162eee58fa1968d
Gitweb: https://git.kernel.org/tip/2d46aea52c02612d1b49aa562162eee58fa1968d
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:13 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework handle_edge_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065421.045492336@linutronix.de
---
kernel/irq/chip.c | 49 +++++++++++++++-------------------------------
1 file changed, 16 insertions(+), 33 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 1ca9b50..6c33679 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -742,40 +742,27 @@ void handle_fasteoi_nmi(struct irq_desc *desc)
EXPORT_SYMBOL_GPL(handle_fasteoi_nmi);
/**
- * handle_edge_irq - edge type IRQ handler
- * @desc: the interrupt description structure for this irq
+ * handle_edge_irq - edge type IRQ handler
+ * @desc: the interrupt description structure for this irq
*
- * Interrupt occurs on the falling and/or rising edge of a hardware
- * signal. The occurrence is latched into the irq controller hardware
- * and must be acked in order to be reenabled. After the ack another
- * interrupt can happen on the same source even before the first one
- * is handled by the associated event handler. If this happens it
- * might be necessary to disable (mask) the interrupt depending on the
- * controller hardware. This requires to reenable the interrupt inside
- * of the loop which handles the interrupts which have arrived while
- * the handler was running. If all pending interrupts are handled, the
- * loop is left.
+ * Interrupt occurs on the falling and/or rising edge of a hardware
+ * signal. The occurrence is latched into the irq controller hardware and
+ * must be acked in order to be reenabled. After the ack another interrupt
+ * can happen on the same source even before the first one is handled by
+ * the associated event handler. If this happens it might be necessary to
+ * disable (mask) the interrupt depending on the controller hardware. This
+ * requires to reenable the interrupt inside of the loop which handles the
+ * interrupts which have arrived while the handler was running. If all
+ * pending interrupts are handled, the loop is left.
*/
void handle_edge_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- if (!irq_can_handle_pm(desc)) {
- desc->istate |= IRQS_PENDING;
- mask_ack_irq(desc);
- goto out_unlock;
- }
+ guard(raw_spinlock)(&desc->lock);
- /*
- * If its disabled or no action available then mask it and get
- * out of here.
- */
- if (irqd_irq_disabled(&desc->irq_data) || !desc->action) {
+ if (!irq_can_handle(desc)) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
- goto out_unlock;
+ return;
}
kstat_incr_irqs_this_cpu(desc);
@@ -786,7 +773,7 @@ void handle_edge_irq(struct irq_desc *desc)
do {
if (unlikely(!desc->action)) {
mask_irq(desc);
- goto out_unlock;
+ return;
}
/*
@@ -802,11 +789,7 @@ void handle_edge_irq(struct irq_desc *desc)
handle_irq_event(desc);
- } while ((desc->istate & IRQS_PENDING) &&
- !irqd_irq_disabled(&desc->irq_data));
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
+ } while ((desc->istate & IRQS_PENDING) && !irqd_irq_disabled(&desc->irq_data));
}
EXPORT_SYMBOL(handle_edge_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_eoi_irq()
2025-04-29 6:55 ` [patch V2 16/45] genirq/chip: Rework handle_eoi_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 15d772e2eebd297e3714abad8bf1d424d3d700fc
Gitweb: https://git.kernel.org/tip/15d772e2eebd297e3714abad8bf1d424d3d700fc
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:11 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework handle_eoi_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.986002418@linutronix.de
---
kernel/irq/chip.c | 42 ++++++++++++++++++------------------------
1 file changed, 18 insertions(+), 24 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index eddf0c6..1ca9b50 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -653,20 +653,26 @@ static void cond_unmask_eoi_irq(struct irq_desc *desc, struct irq_chip *chip)
}
}
+static inline void cond_eoi_irq(struct irq_chip *chip, struct irq_data *data)
+{
+ if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
+ chip->irq_eoi(data);
+}
+
/**
- * handle_fasteoi_irq - irq handler for transparent controllers
- * @desc: the interrupt description structure for this irq
+ * handle_fasteoi_irq - irq handler for transparent controllers
+ * @desc: the interrupt description structure for this irq
*
- * Only a single callback will be issued to the chip: an ->eoi()
- * call when the interrupt has been serviced. This enables support
- * for modern forms of interrupt handlers, which handle the flow
- * details in hardware, transparently.
+ * Only a single callback will be issued to the chip: an ->eoi() call when
+ * the interrupt has been serviced. This enables support for modern forms
+ * of interrupt handlers, which handle the flow details in hardware,
+ * transparently.
*/
void handle_fasteoi_irq(struct irq_desc *desc)
{
struct irq_chip *chip = desc->irq_data.chip;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
/*
* When an affinity change races with IRQ handling, the next interrupt
@@ -676,19 +682,14 @@ void handle_fasteoi_irq(struct irq_desc *desc)
if (!irq_can_handle_pm(desc)) {
if (irqd_needs_resend_when_in_progress(&desc->irq_data))
desc->istate |= IRQS_PENDING;
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * then mask it and get out of here:
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
+ if (!irq_can_handle_actions(desc)) {
mask_irq(desc);
- goto out;
+ cond_eoi_irq(chip, &desc->irq_data);
+ return;
}
kstat_incr_irqs_this_cpu(desc);
@@ -704,13 +705,6 @@ void handle_fasteoi_irq(struct irq_desc *desc)
*/
if (unlikely(desc->istate & IRQS_PENDING))
check_irq_resend(desc, false);
-
- raw_spin_unlock(&desc->lock);
- return;
-out:
- if (!(chip->flags & IRQCHIP_EOI_IF_HANDLED))
- chip->irq_eoi(&desc->irq_data);
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_fasteoi_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_level_irq()
2025-04-29 6:55 ` [patch V2 15/45] genirq/chip: Rework handle_level_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 2334c45521033772fd808e54814f5844ac35c9d0
Gitweb: https://git.kernel.org/tip/2334c45521033772fd808e54814f5844ac35c9d0
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:10 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:13 +02:00
genirq/chip: Rework handle_level_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.926362488@linutronix.de
---
kernel/irq/chip.c | 32 +++++++++-----------------------
1 file changed, 9 insertions(+), 23 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 48f62fc..eddf0c6 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -609,40 +609,26 @@ static void cond_unmask_irq(struct irq_desc *desc)
}
/**
- * handle_level_irq - Level type irq handler
- * @desc: the interrupt description structure for this irq
+ * handle_level_irq - Level type irq handler
+ * @desc: the interrupt description structure for this irq
*
- * Level type interrupts are active as long as the hardware line has
- * the active level. This may require to mask the interrupt and unmask
- * it after the associated handler has acknowledged the device, so the
- * interrupt line is back to inactive.
+ * Level type interrupts are active as long as the hardware line has the
+ * active level. This may require to mask the interrupt and unmask it after
+ * the associated handler has acknowledged the device, so the interrupt
+ * line is back to inactive.
*/
void handle_level_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
mask_ack_irq(desc);
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- /*
- * If its disabled or no action available
- * keep it masked and get out of here
- */
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
- }
+ if (!irq_can_handle(desc))
+ return;
kstat_incr_irqs_this_cpu(desc);
handle_irq_event(desc);
cond_unmask_irq(desc);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_level_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_untracked_irq()
2025-04-29 6:55 ` [patch V2 14/45] genirq/chip: Rework handle_untracked_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: a155777175bb3d0e93f8605d4d93ae6abf3484ab
Gitweb: https://git.kernel.org/tip/a155777175bb3d0e93f8605d4d93ae6abf3484ab
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:08 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/chip: Rework handle_untracked_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.865212916@linutronix.de
---
kernel/irq/chip.c | 43 ++++++++++++++++---------------------------
1 file changed, 16 insertions(+), 27 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 8a1e54e..48f62fc 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -561,43 +561,32 @@ void handle_simple_irq(struct irq_desc *desc)
EXPORT_SYMBOL_GPL(handle_simple_irq);
/**
- * handle_untracked_irq - Simple and software-decoded IRQs.
- * @desc: the interrupt description structure for this irq
+ * handle_untracked_irq - Simple and software-decoded IRQs.
+ * @desc: the interrupt description structure for this irq
*
- * Untracked interrupts are sent from a demultiplexing interrupt
- * handler when the demultiplexer does not know which device it its
- * multiplexed irq domain generated the interrupt. IRQ's handled
- * through here are not subjected to stats tracking, randomness, or
- * spurious interrupt detection.
+ * Untracked interrupts are sent from a demultiplexing interrupt handler
+ * when the demultiplexer does not know which device it its multiplexed irq
+ * domain generated the interrupt. IRQ's handled through here are not
+ * subjected to stats tracking, randomness, or spurious interrupt
+ * detection.
*
- * Note: Like handle_simple_irq, the caller is expected to handle
- * the ack, clear, mask and unmask issues if necessary.
+ * Note: Like handle_simple_irq, the caller is expected to handle the ack,
+ * clear, mask and unmask issues if necessary.
*/
void handle_untracked_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
-
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+ scoped_guard(raw_spinlock, &desc->lock) {
+ if (!irq_can_handle(desc))
+ return;
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
+ desc->istate &= ~IRQS_PENDING;
+ irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
}
- desc->istate &= ~IRQS_PENDING;
- irqd_set(&desc->irq_data, IRQD_IRQ_INPROGRESS);
- raw_spin_unlock(&desc->lock);
-
__handle_irq_event_percpu(desc);
- raw_spin_lock(&desc->lock);
- irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ irqd_clear(&desc->irq_data, IRQD_IRQ_INPROGRESS);
}
EXPORT_SYMBOL_GPL(handle_untracked_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_simple_irq()
2025-04-29 6:55 ` [patch V2 13/45] genirq/chip: Rework handle_simple_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 1a3678675f6945f97945dc453352c9c1fa26c470
Gitweb: https://git.kernel.org/tip/1a3678675f6945f97945dc453352c9c1fa26c470
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:07 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/chip: Rework handle_simple_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.804683349@linutronix.de
---
kernel/irq/chip.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 87add4b..8a1e54e 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -538,35 +538,25 @@ void handle_nested_irq(unsigned int irq)
EXPORT_SYMBOL_GPL(handle_nested_irq);
/**
- * handle_simple_irq - Simple and software-decoded IRQs.
- * @desc: the interrupt description structure for this irq
+ * handle_simple_irq - Simple and software-decoded IRQs.
+ * @desc: the interrupt description structure for this irq
*
- * Simple interrupts are either sent from a demultiplexing interrupt
- * handler or come from hardware, where no interrupt hardware control
- * is necessary.
+ * Simple interrupts are either sent from a demultiplexing interrupt
+ * handler or come from hardware, where no interrupt hardware control is
+ * necessary.
*
- * Note: The caller is expected to handle the ack, clear, mask and
- * unmask issues if necessary.
+ * Note: The caller is expected to handle the ack, clear, mask and unmask
+ * issues if necessary.
*/
void handle_simple_irq(struct irq_desc *desc)
{
- raw_spin_lock(&desc->lock);
-
- if (!irq_can_handle_pm(desc))
- goto out_unlock;
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+ guard(raw_spinlock)(&desc->lock);
- if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- goto out_unlock;
- }
+ if (!irq_can_handle(desc))
+ return;
kstat_incr_irqs_this_cpu(desc);
handle_irq_event(desc);
-
-out_unlock:
- raw_spin_unlock(&desc->lock);
}
EXPORT_SYMBOL_GPL(handle_simple_irq);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Rework handle_nested_irq()
2025-04-29 6:55 ` [patch V2 12/45] genirq/chip: Rework handle_nested_irq() Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508205629eucas1p2f8f2032c2d651be176acdf6ac4aa79cd@eucas1p2.samsung.com>
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 2ef2e13094c7510c40833951c2ec36cf8574331a
Gitweb: https://git.kernel.org/tip/2ef2e13094c7510c40833951c2ec36cf8574331a
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:05 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/chip: Rework handle_nested_irq()
Use the new helpers to decide whether the interrupt should be handled and
switch the descriptor locking to guard().
Fixup the kernel doc comment while at it.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.744042890@linutronix.de
---
kernel/irq/chip.c | 78 +++++++++++++++++++++-------------------------
1 file changed, 36 insertions(+), 42 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 4b4ce38..87add4b 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -450,48 +450,6 @@ void unmask_threaded_irq(struct irq_desc *desc)
unmask_irq(desc);
}
-/*
- * handle_nested_irq - Handle a nested irq from a irq thread
- * @irq: the interrupt number
- *
- * Handle interrupts which are nested into a threaded interrupt
- * handler. The handler function is called inside the calling
- * threads context.
- */
-void handle_nested_irq(unsigned int irq)
-{
- struct irq_desc *desc = irq_to_desc(irq);
- struct irqaction *action;
- irqreturn_t action_ret;
-
- might_sleep();
-
- raw_spin_lock_irq(&desc->lock);
-
- desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
-
- action = desc->action;
- if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
- desc->istate |= IRQS_PENDING;
- raw_spin_unlock_irq(&desc->lock);
- return;
- }
-
- kstat_incr_irqs_this_cpu(desc);
- atomic_inc(&desc->threads_active);
- raw_spin_unlock_irq(&desc->lock);
-
- action_ret = IRQ_NONE;
- for_each_action_of_desc(desc, action)
- action_ret |= action->thread_fn(action->irq, action->dev_id);
-
- if (!irq_settings_no_debug(desc))
- note_interrupt(desc, action_ret);
-
- wake_threads_waitq(desc);
-}
-EXPORT_SYMBOL_GPL(handle_nested_irq);
-
static bool irq_check_poll(struct irq_desc *desc)
{
if (!(desc->istate & IRQS_POLL_INPROGRESS))
@@ -544,6 +502,42 @@ static inline bool irq_can_handle(struct irq_desc *desc)
}
/**
+ * handle_nested_irq - Handle a nested irq from a irq thread
+ * @irq: the interrupt number
+ *
+ * Handle interrupts which are nested into a threaded interrupt
+ * handler. The handler function is called inside the calling threads
+ * context.
+ */
+void handle_nested_irq(unsigned int irq)
+{
+ struct irq_desc *desc = irq_to_desc(irq);
+ struct irqaction *action;
+ irqreturn_t action_ret;
+
+ might_sleep();
+
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ if (irq_can_handle_actions(desc))
+ return;
+
+ action = desc->action;
+ kstat_incr_irqs_this_cpu(desc);
+ atomic_inc(&desc->threads_active);
+ }
+
+ action_ret = IRQ_NONE;
+ for_each_action_of_desc(desc, action)
+ action_ret |= action->thread_fn(action->irq, action->dev_id);
+
+ if (!irq_settings_no_debug(desc))
+ note_interrupt(desc, action_ret);
+
+ wake_threads_waitq(desc);
+}
+EXPORT_SYMBOL_GPL(handle_nested_irq);
+
+/**
* handle_simple_irq - Simple and software-decoded IRQs.
* @desc: the interrupt description structure for this irq
*
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/chip: Prepare for code reduction
2025-04-29 6:55 ` [patch V2 11/45] genirq/chip: Prepare for code reduction Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: a6d8d0d12e1942a9403a0e79c87c161aa801d1a7
Gitweb: https://git.kernel.org/tip/a6d8d0d12e1942a9403a0e79c87c161aa801d1a7
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:04 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/chip: Prepare for code reduction
The interrupt flow handlers have similar patterns to decide whether to
handle an interrupt or not.
Provide common helper functions to allow removal of duplicated code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.682547546@linutronix.de
---
kernel/irq/chip.c | 35 +++++++++++++++++++++++++++--------
1 file changed, 27 insertions(+), 8 deletions(-)
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index 36cf1b0..4b4ce38 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -499,7 +499,7 @@ static bool irq_check_poll(struct irq_desc *desc)
return irq_wait_for_poll(desc);
}
-static bool irq_may_run(struct irq_desc *desc)
+static bool irq_can_handle_pm(struct irq_desc *desc)
{
unsigned int mask = IRQD_IRQ_INPROGRESS | IRQD_WAKEUP_ARMED;
@@ -524,6 +524,25 @@ static bool irq_may_run(struct irq_desc *desc)
return irq_check_poll(desc);
}
+static inline bool irq_can_handle_actions(struct irq_desc *desc)
+{
+ desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
+
+ if (unlikely(!desc->action || irqd_irq_disabled(&desc->irq_data))) {
+ desc->istate |= IRQS_PENDING;
+ return false;
+ }
+ return true;
+}
+
+static inline bool irq_can_handle(struct irq_desc *desc)
+{
+ if (!irq_can_handle_pm(desc))
+ return false;
+
+ return irq_can_handle_actions(desc);
+}
+
/**
* handle_simple_irq - Simple and software-decoded IRQs.
* @desc: the interrupt description structure for this irq
@@ -539,7 +558,7 @@ void handle_simple_irq(struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -574,7 +593,7 @@ void handle_untracked_irq(struct irq_desc *desc)
{
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -630,7 +649,7 @@ void handle_level_irq(struct irq_desc *desc)
raw_spin_lock(&desc->lock);
mask_ack_irq(desc);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out_unlock;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -695,7 +714,7 @@ void handle_fasteoi_irq(struct irq_desc *desc)
* can arrive on the new CPU before the original CPU has completed
* handling the previous one - it may need to be resent.
*/
- if (!irq_may_run(desc)) {
+ if (!irq_can_handle_pm(desc)) {
if (irqd_needs_resend_when_in_progress(&desc->irq_data))
desc->istate |= IRQS_PENDING;
goto out;
@@ -790,7 +809,7 @@ void handle_edge_irq(struct irq_desc *desc)
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
- if (!irq_may_run(desc)) {
+ if (!irq_can_handle_pm(desc)) {
desc->istate |= IRQS_PENDING;
mask_ack_irq(desc);
goto out_unlock;
@@ -1166,7 +1185,7 @@ void handle_fasteoi_ack_irq(struct irq_desc *desc)
raw_spin_lock(&desc->lock);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
@@ -1218,7 +1237,7 @@ void handle_fasteoi_mask_irq(struct irq_desc *desc)
raw_spin_lock(&desc->lock);
mask_ack_irq(desc);
- if (!irq_may_run(desc))
+ if (!irq_can_handle_pm(desc))
goto out;
desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/debugfs: Convert to lock guards
2025-04-29 6:55 ` [patch V2 10/45] genirq/debugfs: " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: ecb84a3e7e7cccd7578d8b4c57035e98cd89901f
Gitweb: https://git.kernel.org/tip/ecb84a3e7e7cccd7578d8b4c57035e98cd89901f
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:02 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/debugfs: Convert to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.620200108@linutronix.de
---
kernel/irq/debugfs.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/kernel/irq/debugfs.c b/kernel/irq/debugfs.c
index ca142b9..9004a17 100644
--- a/kernel/irq/debugfs.c
+++ b/kernel/irq/debugfs.c
@@ -160,7 +160,7 @@ static int irq_debug_show(struct seq_file *m, void *p)
struct irq_desc *desc = m->private;
struct irq_data *data;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
data = irq_desc_get_irq_data(desc);
seq_printf(m, "handler: %ps\n", desc->handle_irq);
seq_printf(m, "device: %s\n", desc->dev_name);
@@ -178,7 +178,6 @@ static int irq_debug_show(struct seq_file *m, void *p)
seq_printf(m, "node: %d\n", irq_data_get_node(data));
irq_debug_show_masks(m, desc);
irq_debug_show_data(m, data, 0);
- raw_spin_unlock_irq(&desc->lock);
return 0;
}
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/cpuhotplug: Convert to lock guards
2025-04-29 6:55 ` [patch V2 09/45] genirq/cpuhotplug: Convert " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508145631eucas1p2f5369234fee8eb86761d70d028d6c82d@eucas1p2.samsung.com>
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 88a4df117ad66100d0f870aa02032dfb9cb29179
Gitweb: https://git.kernel.org/tip/88a4df117ad66100d0f870aa02032dfb9cb29179
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:55:01 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/cpuhotplug: Convert to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.560083665@linutronix.de
---
kernel/irq/cpuhotplug.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/cpuhotplug.c b/kernel/irq/cpuhotplug.c
index 15a7654..7bd4c2a 100644
--- a/kernel/irq/cpuhotplug.c
+++ b/kernel/irq/cpuhotplug.c
@@ -177,9 +177,8 @@ void irq_migrate_all_off_this_cpu(void)
bool affinity_broken;
desc = irq_to_desc(irq);
- raw_spin_lock(&desc->lock);
- affinity_broken = migrate_one_irq(desc);
- raw_spin_unlock(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ affinity_broken = migrate_one_irq(desc);
if (affinity_broken) {
pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
@@ -244,9 +243,8 @@ int irq_affinity_online_cpu(unsigned int cpu)
irq_lock_sparse();
for_each_active_irq(irq) {
desc = irq_to_desc(irq);
- raw_spin_lock_irq(&desc->lock);
- irq_restore_affinity_of_irq(desc, cpu);
- raw_spin_unlock_irq(&desc->lock);
+ scoped_guard(raw_spinlock, &desc->lock)
+ irq_restore_affinity_of_irq(desc, cpu);
}
irq_unlock_sparse();
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/spurious: Switch to lock guards
2025-04-29 6:54 ` [patch V2 08/45] genirq/spurious: Switch to lock guards Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 113332a865530c8ab89d8292e59293b6c9301f96
Gitweb: https://git.kernel.org/tip/113332a865530c8ab89d8292e59293b6c9301f96
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:59 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/spurious: Switch to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.497714413@linutronix.de
---
kernel/irq/spurious.c | 30 ++++++++++++------------------
1 file changed, 12 insertions(+), 18 deletions(-)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 296cb48..8f26982 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -60,37 +60,35 @@ bool irq_wait_for_poll(struct irq_desc *desc)
/*
* Recovery handler for misrouted interrupts.
*/
-static int try_one_irq(struct irq_desc *desc, bool force)
+static bool try_one_irq(struct irq_desc *desc, bool force)
{
- irqreturn_t ret = IRQ_NONE;
struct irqaction *action;
+ bool ret = false;
- raw_spin_lock(&desc->lock);
+ guard(raw_spinlock)(&desc->lock);
/*
* PER_CPU, nested thread interrupts and interrupts explicitly
* marked polled are excluded from polling.
*/
- if (irq_settings_is_per_cpu(desc) ||
- irq_settings_is_nested_thread(desc) ||
+ if (irq_settings_is_per_cpu(desc) || irq_settings_is_nested_thread(desc) ||
irq_settings_is_polled(desc))
- goto out;
+ return false;
/*
* Do not poll disabled interrupts unless the spurious
* disabled poller asks explicitly.
*/
if (irqd_irq_disabled(&desc->irq_data) && !force)
- goto out;
+ return false;
/*
* All handlers must agree on IRQF_SHARED, so we test just the
* first.
*/
action = desc->action;
- if (!action || !(action->flags & IRQF_SHARED) ||
- (action->flags & __IRQF_TIMER))
- goto out;
+ if (!action || !(action->flags & IRQF_SHARED) || (action->flags & __IRQF_TIMER))
+ return false;
/* Already running on another processor */
if (irqd_irq_inprogress(&desc->irq_data)) {
@@ -99,21 +97,19 @@ static int try_one_irq(struct irq_desc *desc, bool force)
* CPU to go looking for our mystery interrupt too
*/
desc->istate |= IRQS_PENDING;
- goto out;
+ return false;
}
/* Mark it poll in progress */
desc->istate |= IRQS_POLL_INPROGRESS;
do {
if (handle_irq_event(desc) == IRQ_HANDLED)
- ret = IRQ_HANDLED;
+ ret = true;
/* Make sure that there is still a valid action */
action = desc->action;
} while ((desc->istate & IRQS_PENDING) && action);
desc->istate &= ~IRQS_POLL_INPROGRESS;
-out:
- raw_spin_unlock(&desc->lock);
- return ret == IRQ_HANDLED;
+ return ret;
}
static int misrouted_irq(int irq)
@@ -192,7 +188,6 @@ static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
{
unsigned int irq = irq_desc_get_irq(desc);
struct irqaction *action;
- unsigned long flags;
if (bad_action_ret(action_ret))
pr_err("irq event %d: bogus return value %x\n", irq, action_ret);
@@ -207,14 +202,13 @@ static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
* with something else removing an action. It's ok to take
* desc->lock here. See synchronize_irq().
*/
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
for_each_action_of_desc(desc, action) {
pr_err("[<%p>] %ps", action->handler, action->handler);
if (action->thread_fn)
pr_cont(" threaded [<%p>] %ps", action->thread_fn, action->thread_fn);
pr_cont("\n");
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
static void report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/spurious: Cleanup code
2025-04-29 6:54 ` [patch V2 07/45] genirq/spurious: Cleanup code Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: e815ffc759fb810672b9d90badae928534cde78a
Gitweb: https://git.kernel.org/tip/e815ffc759fb810672b9d90badae928534cde78a
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:58 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:12 +02:00
genirq/spurious: Cleanup code
Clean up the coding style
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.437285102@linutronix.de
---
kernel/irq/spurious.c | 74 +++++++++++++++---------------------------
1 file changed, 28 insertions(+), 46 deletions(-)
diff --git a/kernel/irq/spurious.c b/kernel/irq/spurious.c
index 02b2daf..296cb48 100644
--- a/kernel/irq/spurious.c
+++ b/kernel/irq/spurious.c
@@ -34,8 +34,9 @@ static atomic_t irq_poll_active;
* true and let the handler run.
*/
bool irq_wait_for_poll(struct irq_desc *desc)
- __must_hold(&desc->lock)
{
+ lockdep_assert_held(&desc->lock);
+
if (WARN_ONCE(irq_poll_cpu == smp_processor_id(),
"irq poll in progress on cpu %d for irq %d\n",
smp_processor_id(), desc->irq_data.irq))
@@ -157,8 +158,7 @@ static void poll_spurious_irqs(struct timer_list *unused)
continue;
/* Racy but it doesn't matter */
- state = desc->istate;
- barrier();
+ state = READ_ONCE(desc->istate);
if (!(state & IRQS_SPURIOUS_DISABLED))
continue;
@@ -168,8 +168,7 @@ static void poll_spurious_irqs(struct timer_list *unused)
}
out:
atomic_dec(&irq_poll_active);
- mod_timer(&poll_spurious_irq_timer,
- jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+ mod_timer(&poll_spurious_irq_timer, jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
static inline int bad_action_ret(irqreturn_t action_ret)
@@ -195,15 +194,12 @@ static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
struct irqaction *action;
unsigned long flags;
- if (bad_action_ret(action_ret)) {
- printk(KERN_ERR "irq event %d: bogus return value %x\n",
- irq, action_ret);
- } else {
- printk(KERN_ERR "irq %d: nobody cared (try booting with "
- "the \"irqpoll\" option)\n", irq);
- }
+ if (bad_action_ret(action_ret))
+ pr_err("irq event %d: bogus return value %x\n", irq, action_ret);
+ else
+ pr_err("irq %d: nobody cared (try booting with the \"irqpoll\" option)\n", irq);
dump_stack();
- printk(KERN_ERR "handlers:\n");
+ pr_err("handlers:\n");
/*
* We need to take desc->lock here. note_interrupt() is called
@@ -213,11 +209,10 @@ static void __report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
*/
raw_spin_lock_irqsave(&desc->lock, flags);
for_each_action_of_desc(desc, action) {
- printk(KERN_ERR "[<%p>] %ps", action->handler, action->handler);
+ pr_err("[<%p>] %ps", action->handler, action->handler);
if (action->thread_fn)
- printk(KERN_CONT " threaded [<%p>] %ps",
- action->thread_fn, action->thread_fn);
- printk(KERN_CONT "\n");
+ pr_cont(" threaded [<%p>] %ps", action->thread_fn, action->thread_fn);
+ pr_cont("\n");
}
raw_spin_unlock_irqrestore(&desc->lock, flags);
}
@@ -232,18 +227,17 @@ static void report_bad_irq(struct irq_desc *desc, irqreturn_t action_ret)
}
}
-static inline int
-try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
- irqreturn_t action_ret)
+static inline bool try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
+ irqreturn_t action_ret)
{
struct irqaction *action;
if (!irqfixup)
- return 0;
+ return false;
/* We didn't actually handle the IRQ - see if it was misrouted? */
if (action_ret == IRQ_NONE)
- return 1;
+ return true;
/*
* But for 'irqfixup == 2' we also do it for handled interrupts if
@@ -251,19 +245,16 @@ try_misrouted_irq(unsigned int irq, struct irq_desc *desc,
* traditional PC timer interrupt.. Legacy)
*/
if (irqfixup < 2)
- return 0;
+ return false;
if (!irq)
- return 1;
+ return true;
/*
* Since we don't get the descriptor lock, "action" can
- * change under us. We don't really care, but we don't
- * want to follow a NULL pointer. So tell the compiler to
- * just load it once by using a barrier.
+ * change under us.
*/
- action = desc->action;
- barrier();
+ action = READ_ONCE(desc->action);
return action && (action->flags & IRQF_IRQPOLL);
}
@@ -273,8 +264,7 @@ void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret)
{
unsigned int irq;
- if (desc->istate & IRQS_POLL_INPROGRESS ||
- irq_settings_is_polled(desc))
+ if (desc->istate & IRQS_POLL_INPROGRESS || irq_settings_is_polled(desc))
return;
if (bad_action_ret(action_ret)) {
@@ -420,13 +410,12 @@ void note_interrupt(struct irq_desc *desc, irqreturn_t action_ret)
/*
* Now kill the IRQ
*/
- printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
+ pr_emerg("Disabling IRQ #%d\n", irq);
desc->istate |= IRQS_SPURIOUS_DISABLED;
desc->depth++;
irq_disable(desc);
- mod_timer(&poll_spurious_irq_timer,
- jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
+ mod_timer(&poll_spurious_irq_timer, jiffies + POLL_SPURIOUS_IRQ_INTERVAL);
}
desc->irqs_unhandled = 0;
}
@@ -436,11 +425,9 @@ bool noirqdebug __read_mostly;
int noirqdebug_setup(char *str)
{
noirqdebug = 1;
- printk(KERN_INFO "IRQ lockup detection disabled\n");
-
+ pr_info("IRQ lockup detection disabled\n");
return 1;
}
-
__setup("noirqdebug", noirqdebug_setup);
module_param(noirqdebug, bool, 0644);
MODULE_PARM_DESC(noirqdebug, "Disable irq lockup detection when true");
@@ -452,12 +439,10 @@ static int __init irqfixup_setup(char *str)
return 1;
}
irqfixup = 1;
- printk(KERN_WARNING "Misrouted IRQ fixup support enabled.\n");
- printk(KERN_WARNING "This may impact system performance.\n");
-
+ pr_warn("Misrouted IRQ fixup support enabled.\n");
+ pr_warn("This may impact system performance.\n");
return 1;
}
-
__setup("irqfixup", irqfixup_setup);
module_param(irqfixup, int, 0644);
@@ -468,11 +453,8 @@ static int __init irqpoll_setup(char *str)
return 1;
}
irqfixup = 2;
- printk(KERN_WARNING "Misrouted IRQ fixup and polling support "
- "enabled\n");
- printk(KERN_WARNING "This may significantly impact system "
- "performance\n");
+ pr_warn("Misrouted IRQ fixup and polling support enabled\n");
+ pr_warn("This may significantly impact system performance\n");
return 1;
}
-
__setup("irqpoll", irqpoll_setup);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/resend: Switch to lock guards
2025-04-29 6:54 ` [patch V2 05/45] genirq/resend: " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 4bcdf07467fab54a5dfbb0fb8546b5e59c87c497
Gitweb: https://git.kernel.org/tip/4bcdf07467fab54a5dfbb0fb8546b5e59c87c497
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:55 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq/resend: Switch to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.312487167@linutronix.de
---
kernel/irq/resend.c | 50 ++++++++++++++++++--------------------------
1 file changed, 21 insertions(+), 29 deletions(-)
diff --git a/kernel/irq/resend.c b/kernel/irq/resend.c
index 1b7fa72..ca9cc1b 100644
--- a/kernel/irq/resend.c
+++ b/kernel/irq/resend.c
@@ -30,18 +30,17 @@ static DEFINE_RAW_SPINLOCK(irq_resend_lock);
*/
static void resend_irqs(struct tasklet_struct *unused)
{
- struct irq_desc *desc;
-
- raw_spin_lock_irq(&irq_resend_lock);
+ guard(raw_spinlock_irq)(&irq_resend_lock);
while (!hlist_empty(&irq_resend_list)) {
- desc = hlist_entry(irq_resend_list.first, struct irq_desc,
- resend_node);
+ struct irq_desc *desc;
+
+ desc = hlist_entry(irq_resend_list.first, struct irq_desc, resend_node);
hlist_del_init(&desc->resend_node);
+
raw_spin_unlock(&irq_resend_lock);
desc->handle_irq(desc);
raw_spin_lock(&irq_resend_lock);
}
- raw_spin_unlock_irq(&irq_resend_lock);
}
/* Tasklet to handle resend: */
@@ -75,19 +74,18 @@ static int irq_sw_resend(struct irq_desc *desc)
}
/* Add to resend_list and activate the softirq: */
- raw_spin_lock(&irq_resend_lock);
- if (hlist_unhashed(&desc->resend_node))
- hlist_add_head(&desc->resend_node, &irq_resend_list);
- raw_spin_unlock(&irq_resend_lock);
+ scoped_guard(raw_spinlock, &irq_resend_lock) {
+ if (hlist_unhashed(&desc->resend_node))
+ hlist_add_head(&desc->resend_node, &irq_resend_list);
+ }
tasklet_schedule(&resend_tasklet);
return 0;
}
void clear_irq_resend(struct irq_desc *desc)
{
- raw_spin_lock(&irq_resend_lock);
+ guard(raw_spinlock)(&irq_resend_lock);
hlist_del_init(&desc->resend_node);
- raw_spin_unlock(&irq_resend_lock);
}
void irq_resend_init(struct irq_desc *desc)
@@ -172,30 +170,24 @@ int check_irq_resend(struct irq_desc *desc, bool inject)
*/
int irq_inject_interrupt(unsigned int irq)
{
- struct irq_desc *desc;
- unsigned long flags;
- int err;
+ int err = -EINVAL;
/* Try the state injection hardware interface first */
if (!irq_set_irqchip_state(irq, IRQCHIP_STATE_PENDING, true))
return 0;
/* That failed, try via the resend mechanism */
- desc = irq_get_desc_buslock(irq, &flags, 0);
- if (!desc)
- return -EINVAL;
+ scoped_irqdesc_get_and_buslock(irq, 0) {
+ struct irq_desc *desc = scoped_irqdesc;
- /*
- * Only try to inject when the interrupt is:
- * - not NMI type
- * - activated
- */
- if (irq_is_nmi(desc) || !irqd_is_activated(&desc->irq_data))
- err = -EINVAL;
- else
- err = check_irq_resend(desc, true);
-
- irq_put_desc_busunlock(desc, flags);
+ /*
+ * Only try to inject when the interrupt is:
+ * - not NMI type
+ * - activated
+ */
+ if (!irq_is_nmi(desc) && irqd_is_activated(&desc->irq_data))
+ err = check_irq_resend(desc, true);
+ }
return err;
}
EXPORT_SYMBOL_GPL(irq_inject_interrupt);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/proc: Switch to lock guards
2025-04-29 6:54 ` [patch V2 06/45] genirq/proc: " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
2025-06-08 12:45 ` [patch V2 06/45] " Zenghui Yu
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 659ff9c9d77b8ad9d9c18e264abc9a56bd19230e
Gitweb: https://git.kernel.org/tip/659ff9c9d77b8ad9d9c18e264abc9a56bd19230e
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:56 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq/proc: Switch to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.373998838@linutronix.de
---
kernel/irq/proc.c | 65 ++++++++++++++++------------------------------
1 file changed, 24 insertions(+), 41 deletions(-)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 8e29809..94eba9a 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -81,20 +81,18 @@ static int show_irq_affinity(int type, struct seq_file *m)
static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long)m->private);
- unsigned long flags;
cpumask_var_t mask;
if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
return -ENOMEM;
- raw_spin_lock_irqsave(&desc->lock, flags);
- if (desc->affinity_hint)
- cpumask_copy(mask, desc->affinity_hint);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ if (desc->affinity_hint)
+ cpumask_copy(mask, desc->affinity_hint);
+ }
seq_printf(m, "%*pb\n", cpumask_pr_args(mask));
free_cpumask_var(mask);
-
return 0;
}
@@ -295,23 +293,18 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v)
#define MAX_NAMELEN 128
-static int name_unique(unsigned int irq, struct irqaction *new_action)
+static bool name_unique(unsigned int irq, struct irqaction *new_action)
{
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- unsigned long flags;
- int ret = 1;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irq)(&desc->lock);
for_each_action_of_desc(desc, action) {
if ((action != new_action) && action->name &&
- !strcmp(new_action->name, action->name)) {
- ret = 0;
- break;
- }
+ !strcmp(new_action->name, action->name))
+ return false;
}
- raw_spin_unlock_irqrestore(&desc->lock, flags);
- return ret;
+ return true;
}
void register_handler_proc(unsigned int irq, struct irqaction *action)
@@ -319,8 +312,7 @@ void register_handler_proc(unsigned int irq, struct irqaction *action)
char name [MAX_NAMELEN];
struct irq_desc *desc = irq_to_desc(irq);
- if (!desc->dir || action->dir || !action->name ||
- !name_unique(irq, action))
+ if (!desc->dir || action->dir || !action->name || !name_unique(irq, action))
return;
snprintf(name, MAX_NAMELEN, "%s", action->name);
@@ -347,17 +339,16 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
* added, not when the descriptor is created, so multiple
* tasks might try to register at the same time.
*/
- mutex_lock(®ister_lock);
+ guard(mutex)(®ister_lock);
if (desc->dir)
- goto out_unlock;
-
- sprintf(name, "%d", irq);
+ return;
/* create /proc/irq/1234 */
+ sprintf(name, "%d", irq);
desc->dir = proc_mkdir(name, root_irq_dir);
if (!desc->dir)
- goto out_unlock;
+ return;
#ifdef CONFIG_SMP
umode_t umode = S_IRUGO;
@@ -366,31 +357,27 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
umode |= S_IWUSR;
/* create /proc/irq/<irq>/smp_affinity */
- proc_create_data("smp_affinity", umode, desc->dir,
- &irq_affinity_proc_ops, irqp);
+ proc_create_data("smp_affinity", umode, desc->dir, &irq_affinity_proc_ops, irqp);
/* create /proc/irq/<irq>/affinity_hint */
proc_create_single_data("affinity_hint", 0444, desc->dir,
- irq_affinity_hint_proc_show, irqp);
+ irq_affinity_hint_proc_show, irqp);
/* create /proc/irq/<irq>/smp_affinity_list */
proc_create_data("smp_affinity_list", umode, desc->dir,
&irq_affinity_list_proc_ops, irqp);
- proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show,
- irqp);
+ proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show, irqp);
# ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
proc_create_single_data("effective_affinity", 0444, desc->dir,
- irq_effective_aff_proc_show, irqp);
+ irq_effective_aff_proc_show, irqp);
proc_create_single_data("effective_affinity_list", 0444, desc->dir,
- irq_effective_aff_list_proc_show, irqp);
+ irq_effective_aff_list_proc_show, irqp);
# endif
#endif
proc_create_single_data("spurious", 0444, desc->dir,
- irq_spurious_proc_show, (void *)(long)irq);
+ irq_spurious_proc_show, (void *)(long)irq);
-out_unlock:
- mutex_unlock(®ister_lock);
}
void unregister_irq_proc(unsigned int irq, struct irq_desc *desc)
@@ -468,7 +455,6 @@ int show_interrupts(struct seq_file *p, void *v)
int i = *(loff_t *) v, j;
struct irqaction *action;
struct irq_desc *desc;
- unsigned long flags;
if (i > ACTUAL_NR_IRQS)
return 0;
@@ -487,13 +473,13 @@ int show_interrupts(struct seq_file *p, void *v)
seq_putc(p, '\n');
}
- rcu_read_lock();
+ guard(rcu)();
desc = irq_to_desc(i);
if (!desc || irq_settings_is_hidden(desc))
- goto outsparse;
+ return 0;
if (!desc->action || irq_desc_is_chained(desc) || !desc->kstat_irqs)
- goto outsparse;
+ return 0;
seq_printf(p, "%*d:", prec, i);
for_each_online_cpu(j) {
@@ -503,7 +489,7 @@ int show_interrupts(struct seq_file *p, void *v)
}
seq_putc(p, ' ');
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->irq_data.chip) {
if (desc->irq_data.chip->irq_print_chip)
desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
@@ -532,9 +518,6 @@ int show_interrupts(struct seq_file *p, void *v)
}
seq_putc(p, '\n');
- raw_spin_unlock_irqrestore(&desc->lock, flags);
-outsparse:
- rcu_read_unlock();
return 0;
}
#endif
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/pm: Switch to lock guards
2025-04-29 6:54 ` [patch V2 04/45] genirq/pm: " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 19b4b14428338775d8c0d0e725ecfb14e10121c3
Gitweb: https://git.kernel.org/tip/19b4b14428338775d8c0d0e725ecfb14e10121c3
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:53 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq/pm: Switch to lock guards
Convert all lock/unlock pairs to guards and tidy up the code.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.251299112@linutronix.de
---
kernel/irq/pm.c | 38 +++++++++++++-------------------------
1 file changed, 13 insertions(+), 25 deletions(-)
diff --git a/kernel/irq/pm.c b/kernel/irq/pm.c
index c556bc4..445912d 100644
--- a/kernel/irq/pm.c
+++ b/kernel/irq/pm.c
@@ -46,8 +46,7 @@ void irq_pm_install_action(struct irq_desc *desc, struct irqaction *action)
desc->cond_suspend_depth++;
WARN_ON_ONCE(desc->no_suspend_depth &&
- (desc->no_suspend_depth +
- desc->cond_suspend_depth) != desc->nr_actions);
+ (desc->no_suspend_depth + desc->cond_suspend_depth) != desc->nr_actions);
}
/*
@@ -134,14 +133,12 @@ void suspend_device_irqs(void)
int irq;
for_each_irq_desc(irq, desc) {
- unsigned long flags;
bool sync;
if (irq_settings_is_nested_thread(desc))
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
- sync = suspend_device_irq(desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ sync = suspend_device_irq(desc);
if (sync)
synchronize_irq(irq);
@@ -186,18 +183,15 @@ static void resume_irqs(bool want_early)
int irq;
for_each_irq_desc(irq, desc) {
- unsigned long flags;
- bool is_early = desc->action &&
- desc->action->flags & IRQF_EARLY_RESUME;
+ bool is_early = desc->action && desc->action->flags & IRQF_EARLY_RESUME;
if (!is_early && want_early)
continue;
if (irq_settings_is_nested_thread(desc))
continue;
- raw_spin_lock_irqsave(&desc->lock, flags);
+ guard(raw_spinlock_irqsave)(&desc->lock);
resume_irq(desc);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -207,22 +201,16 @@ static void resume_irqs(bool want_early)
*/
void rearm_wake_irq(unsigned int irq)
{
- unsigned long flags;
- struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ struct irq_desc *desc = scoped_irqdesc;
- if (!desc)
- return;
-
- if (!(desc->istate & IRQS_SUSPENDED) ||
- !irqd_is_wakeup_set(&desc->irq_data))
- goto unlock;
-
- desc->istate &= ~IRQS_SUSPENDED;
- irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
- __enable_irq(desc);
+ if (!(desc->istate & IRQS_SUSPENDED) || !irqd_is_wakeup_set(&desc->irq_data))
+ return;
-unlock:
- irq_put_desc_busunlock(desc, flags);
+ desc->istate &= ~IRQS_SUSPENDED;
+ irqd_set(&desc->irq_data, IRQD_WAKEUP_ARMED);
+ __enable_irq(desc);
+ }
}
/**
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/autoprobe: Switch to lock guards
2025-04-29 6:54 ` [patch V2 03/45] genirq/autoprobe: " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: e80618b27a008839e3b61c1efa0b915b155f2a8d
Gitweb: https://git.kernel.org/tip/e80618b27a008839e3b61c1efa0b915b155f2a8d
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:52 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq/autoprobe: Switch to lock guards
Convert all lock/unlock pairs to guards.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.188866381@linutronix.de
---
kernel/irq/autoprobe.c | 26 +++++++++-----------------
1 file changed, 9 insertions(+), 17 deletions(-)
diff --git a/kernel/irq/autoprobe.c b/kernel/irq/autoprobe.c
index ae60cae..d0af8a8 100644
--- a/kernel/irq/autoprobe.c
+++ b/kernel/irq/autoprobe.c
@@ -43,18 +43,16 @@ unsigned long probe_irq_on(void)
* flush such a longstanding irq before considering it as spurious.
*/
for_each_irq_desc_reverse(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (!desc->action && irq_settings_can_probe(desc)) {
/*
* Some chips need to know about probing in
* progress:
*/
if (desc->irq_data.chip->irq_set_type)
- desc->irq_data.chip->irq_set_type(&desc->irq_data,
- IRQ_TYPE_PROBE);
+ desc->irq_data.chip->irq_set_type(&desc->irq_data, IRQ_TYPE_PROBE);
irq_activate_and_startup(desc, IRQ_NORESEND);
}
- raw_spin_unlock_irq(&desc->lock);
}
/* Wait for longstanding interrupts to trigger. */
@@ -66,13 +64,12 @@ unsigned long probe_irq_on(void)
* happened in the previous stage, it may have masked itself)
*/
for_each_irq_desc_reverse(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (!desc->action && irq_settings_can_probe(desc)) {
desc->istate |= IRQS_AUTODETECT | IRQS_WAITING;
if (irq_activate_and_startup(desc, IRQ_NORESEND))
desc->istate |= IRQS_PENDING;
}
- raw_spin_unlock_irq(&desc->lock);
}
/*
@@ -84,18 +81,16 @@ unsigned long probe_irq_on(void)
* Now filter out any obviously spurious interrupts
*/
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
-
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
/* It triggered already - consider it spurious. */
if (!(desc->istate & IRQS_WAITING)) {
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
- } else
- if (i < 32)
- mask |= 1 << i;
+ } else if (i < 32) {
+ mask |= 1 << i;
+ }
}
- raw_spin_unlock_irq(&desc->lock);
}
return mask;
@@ -121,7 +116,7 @@ unsigned int probe_irq_mask(unsigned long val)
int i;
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
if (i < 16 && !(desc->istate & IRQS_WAITING))
mask |= 1 << i;
@@ -129,7 +124,6 @@ unsigned int probe_irq_mask(unsigned long val)
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
}
- raw_spin_unlock_irq(&desc->lock);
}
mutex_unlock(&probing_active);
@@ -160,8 +154,7 @@ int probe_irq_off(unsigned long val)
struct irq_desc *desc;
for_each_irq_desc(i, desc) {
- raw_spin_lock_irq(&desc->lock);
-
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->istate & IRQS_AUTODETECT) {
if (!(desc->istate & IRQS_WAITING)) {
if (!nr_of_irqs)
@@ -171,7 +164,6 @@ int probe_irq_off(unsigned long val)
desc->istate &= ~IRQS_AUTODETECT;
irq_shutdown_and_deactivate(desc);
}
- raw_spin_unlock_irq(&desc->lock);
}
mutex_unlock(&probing_active);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq/irqdesc: Switch to lock guards
2025-04-30 6:36 ` [patch V2a " Thomas Gleixner
2025-04-30 6:51 ` Jiri Slaby
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Jiri Slaby, Peter Zijlstra (Intel), x86,
linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 5d964a9f7cd8f669db588d9d0db61b4f81af4978
Gitweb: https://git.kernel.org/tip/5d964a9f7cd8f669db588d9d0db61b4f81af4978
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Wed, 30 Apr 2025 08:36:39 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq/irqdesc: Switch to lock guards
Replace all lock/unlock pairs with lock guards and simplify the code flow.
No functional change.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Reviewed-by: Jiri Slaby <jirislaby@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/871ptaqhoo.ffs@tglx
---
kernel/irq/irqdesc.c | 129 ++++++++++++++----------------------------
1 file changed, 44 insertions(+), 85 deletions(-)
diff --git a/kernel/irq/irqdesc.c b/kernel/irq/irqdesc.c
index 5b3aee2..6d006a6 100644
--- a/kernel/irq/irqdesc.c
+++ b/kernel/irq/irqdesc.c
@@ -246,8 +246,7 @@ static struct kobject *irq_kobj_base;
#define IRQ_ATTR_RO(_name) \
static struct kobj_attribute _name##_attr = __ATTR_RO(_name)
-static ssize_t per_cpu_count_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t per_cpu_count_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
ssize_t ret = 0;
@@ -266,99 +265,75 @@ static ssize_t per_cpu_count_show(struct kobject *kobj,
}
IRQ_ATTR_RO(per_cpu_count);
-static ssize_t chip_name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t chip_name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->irq_data.chip && desc->irq_data.chip->name)
- ret = sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->irq_data.chip->name);
+ return 0;
}
IRQ_ATTR_RO(chip_name);
-static ssize_t hwirq_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t hwirq_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
+ guard(raw_spinlock_irq)(&desc->lock);
raw_spin_lock_irq(&desc->lock);
if (desc->irq_data.domain)
- ret = sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%lu\n", desc->irq_data.hwirq);
+ return 0;
}
IRQ_ATTR_RO(hwirq);
-static ssize_t type_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t type_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
-
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
- raw_spin_unlock_irq(&desc->lock);
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", irqd_is_level_type(&desc->irq_data) ? "level" : "edge");
}
IRQ_ATTR_RO(type);
-static ssize_t wakeup_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t wakeup_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
-
- raw_spin_lock_irq(&desc->lock);
- ret = sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ guard(raw_spinlock_irq)(&desc->lock);
+ return sysfs_emit(buf, "%s\n", str_enabled_disabled(irqd_is_wakeup_set(&desc->irq_data)));
}
IRQ_ATTR_RO(wakeup);
-static ssize_t name_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t name_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
- ssize_t ret = 0;
- raw_spin_lock_irq(&desc->lock);
+ guard(raw_spinlock_irq)(&desc->lock);
if (desc->name)
- ret = sysfs_emit(buf, "%s\n", desc->name);
- raw_spin_unlock_irq(&desc->lock);
-
- return ret;
+ return sysfs_emit(buf, "%s\n", desc->name);
+ return 0;
}
IRQ_ATTR_RO(name);
-static ssize_t actions_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
+static ssize_t actions_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf)
{
struct irq_desc *desc = container_of(kobj, struct irq_desc, kobj);
struct irqaction *action;
ssize_t ret = 0;
char *p = "";
- raw_spin_lock_irq(&desc->lock);
- for_each_action_of_desc(desc, action) {
- ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
- p = ",";
+ scoped_guard(raw_spinlock_irq, &desc->lock) {
+ for_each_action_of_desc(desc, action) {
+ ret += sysfs_emit_at(buf, ret, "%s%s", p, action->name);
+ p = ",";
+ }
}
- raw_spin_unlock_irq(&desc->lock);
if (ret)
ret += sysfs_emit_at(buf, ret, "\n");
-
return ret;
}
IRQ_ATTR_RO(actions);
@@ -414,19 +389,14 @@ static int __init irq_sysfs_init(void)
int irq;
/* Prevent concurrent irq alloc/free */
- irq_lock_sparse();
-
+ guard(mutex)(&sparse_irq_lock);
irq_kobj_base = kobject_create_and_add("irq", kernel_kobj);
- if (!irq_kobj_base) {
- irq_unlock_sparse();
+ if (!irq_kobj_base)
return -ENOMEM;
- }
/* Add the already allocated interrupts */
for_each_irq_desc(irq, desc)
irq_sysfs_add(irq, desc);
- irq_unlock_sparse();
-
return 0;
}
postcore_initcall(irq_sysfs_init);
@@ -569,12 +539,12 @@ err:
return -ENOMEM;
}
-static int irq_expand_nr_irqs(unsigned int nr)
+static bool irq_expand_nr_irqs(unsigned int nr)
{
if (nr > MAX_SPARSE_IRQS)
- return -ENOMEM;
+ return false;
nr_irqs = nr;
- return 0;
+ return true;
}
int __init early_irq_init(void)
@@ -652,11 +622,9 @@ EXPORT_SYMBOL(irq_to_desc);
static void free_desc(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- unsigned long flags;
- raw_spin_lock_irqsave(&desc->lock, flags);
- desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
- raw_spin_unlock_irqrestore(&desc->lock, flags);
+ scoped_guard(raw_spinlock_irqsave, &desc->lock)
+ desc_set_defaults(irq, desc, irq_desc_get_node(desc), NULL, NULL);
delete_irq_desc(irq);
}
@@ -675,16 +643,15 @@ static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
return start;
}
-static int irq_expand_nr_irqs(unsigned int nr)
+static inline bool irq_expand_nr_irqs(unsigned int nr)
{
- return -ENOMEM;
+ return false;
}
void irq_mark_irq(unsigned int irq)
{
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
irq_insert_desc(irq, irq_desc + irq);
- mutex_unlock(&sparse_irq_lock);
}
#ifdef CONFIG_GENERIC_IRQ_LEGACY
@@ -823,11 +790,9 @@ void irq_free_descs(unsigned int from, unsigned int cnt)
if (from >= nr_irqs || (from + cnt) > nr_irqs)
return;
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
for (i = 0; i < cnt; i++)
free_desc(from + i);
-
- mutex_unlock(&sparse_irq_lock);
}
EXPORT_SYMBOL_GPL(irq_free_descs);
@@ -844,11 +809,10 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
*
* Returns the first irq number or error code
*/
-int __ref
-__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
- struct module *owner, const struct irq_affinity_desc *affinity)
+int __ref __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
+ struct module *owner, const struct irq_affinity_desc *affinity)
{
- int start, ret;
+ int start;
if (!cnt)
return -EINVAL;
@@ -866,22 +830,17 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
from = arch_dynirq_lower_bound(from);
}
- mutex_lock(&sparse_irq_lock);
+ guard(mutex)(&sparse_irq_lock);
start = irq_find_free_area(from, cnt);
- ret = -EEXIST;
if (irq >=0 && start != irq)
- goto unlock;
+ return -EEXIST;
if (start + cnt > nr_irqs) {
- ret = irq_expand_nr_irqs(start + cnt);
- if (ret)
- goto unlock;
+ if (!irq_expand_nr_irqs(start + cnt))
+ return -ENOMEM;
}
- ret = alloc_descs(start, cnt, node, affinity, owner);
-unlock:
- mutex_unlock(&sparse_irq_lock);
- return ret;
+ return alloc_descs(start, cnt, node, affinity, owner);
}
EXPORT_SYMBOL_GPL(__irq_alloc_descs);
^ permalink raw reply related [flat|nested] 119+ messages in thread
* [tip: irq/core] genirq: Provide conditional lock guards
2025-04-29 6:54 ` [patch V2 01/45] genirq: Provide conditional " Thomas Gleixner
@ 2025-05-07 9:07 ` tip-bot2 for Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: tip-bot2 for Thomas Gleixner @ 2025-05-07 9:07 UTC (permalink / raw)
To: linux-tip-commits
Cc: Thomas Gleixner, Peter Zijlstra (Intel), x86, linux-kernel, maz
The following commit has been merged into the irq/core branch of tip:
Commit-ID: 0f70a49f3fa386d34203efd426a2937592cd26c6
Gitweb: https://git.kernel.org/tip/0f70a49f3fa386d34203efd426a2937592cd26c6
Author: Thomas Gleixner <tglx@linutronix.de>
AuthorDate: Tue, 29 Apr 2025 08:54:49 +02:00
Committer: Thomas Gleixner <tglx@linutronix.de>
CommitterDate: Wed, 07 May 2025 09:08:11 +02:00
genirq: Provide conditional lock guards
The interrupt core code has an ever repeating pattern:
unsigned long flags;
struct irq_desc *desc = irq_get_desc_[bus]lock(irq, &flags, mode);
if (!desc)
return -EINVAL;
....
irq_put_desc_[bus]unlock(desc, flags);
That requires gotos in failure paths and just creates visual clutter.
Provide lock guards, which allow to simplify the code.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/all/20250429065420.061659985@linutronix.de
---
kernel/irq/internals.h | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index b029084..44d3a67 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -141,6 +141,10 @@ extern int irq_setup_affinity(struct irq_desc *desc);
static inline int irq_setup_affinity(struct irq_desc *desc) { return 0; }
#endif
+
+#define for_each_action_of_desc(desc, act) \
+ for (act = desc->action; act; act = act->next)
+
/* Inline functions for support of irq chips on slow busses */
static inline void chip_bus_lock(struct irq_desc *desc)
{
@@ -160,14 +164,33 @@ static inline void chip_bus_sync_unlock(struct irq_desc *desc)
#define IRQ_GET_DESC_CHECK_GLOBAL (_IRQ_DESC_CHECK)
#define IRQ_GET_DESC_CHECK_PERCPU (_IRQ_DESC_CHECK | _IRQ_DESC_PERCPU)
-#define for_each_action_of_desc(desc, act) \
- for (act = desc->action; act; act = act->next)
-
-struct irq_desc *
-__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
- unsigned int check);
+struct irq_desc *__irq_get_desc_lock(unsigned int irq, unsigned long *flags, bool bus,
+ unsigned int check);
void __irq_put_desc_unlock(struct irq_desc *desc, unsigned long flags, bool bus);
+__DEFINE_CLASS_IS_CONDITIONAL(irqdesc_lock, true);
+__DEFINE_UNLOCK_GUARD(irqdesc_lock, struct irq_desc,
+ __irq_put_desc_unlock(_T->lock, _T->flags, _T->bus),
+ unsigned long flags; bool bus);
+
+static inline class_irqdesc_lock_t class_irqdesc_lock_constructor(unsigned int irq, bool bus,
+ unsigned int check)
+{
+ class_irqdesc_lock_t _t = {
+ .bus = bus,
+ .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
+ };
+ return _t;
+}
+
+#define scoped_irqdesc_get_and_lock(_irq, _check) \
+ scoped_guard(irqdesc_lock, _irq, false, _check)
+
+#define scoped_irqdesc_get_and_buslock(_irq, _check) \
+ scoped_guard(irqdesc_lock, _irq, true, _check)
+
+#define scoped_irqdesc ((struct irq_desc *)(__guard_ptr(irqdesc_lock)(&scope)))
+
static inline struct irq_desc *
irq_get_desc_buslock(unsigned int irq, unsigned long *flags, unsigned int check)
{
^ permalink raw reply related [flat|nested] 119+ messages in thread
* Re: [patch V2 09/45] genirq/cpuhotplug: Convert to lock guards
[not found] ` <CGME20250508145631eucas1p2f5369234fee8eb86761d70d028d6c82d@eucas1p2.samsung.com>
@ 2025-05-08 14:56 ` Marek Szyprowski
2025-05-08 17:53 ` Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Marek Szyprowski @ 2025-05-08 14:56 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Jiri Slaby, Peter Zijlstra
Hi Thomas,
On 29.04.2025 08:55, Thomas Gleixner wrote:
> Convert all lock/unlock pairs to guards and tidy up the code.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/cpuhotplug.c | 10 ++++------
> 1 file changed, 4 insertions(+), 6 deletions(-)
>
> --- a/kernel/irq/cpuhotplug.c
> +++ b/kernel/irq/cpuhotplug.c
> @@ -177,9 +177,8 @@ void irq_migrate_all_off_this_cpu(void)
> bool affinity_broken;
>
> desc = irq_to_desc(irq);
> - raw_spin_lock(&desc->lock);
> - affinity_broken = migrate_one_irq(desc);
> - raw_spin_unlock(&desc->lock);
> + scoped_guard(raw_spinlock, &desc->lock)
> + affinity_broken = migrate_one_irq(desc);
>
> if (affinity_broken) {
> pr_debug_ratelimited("IRQ %u: no longer affine to CPU%u\n",
> @@ -244,9 +243,8 @@ int irq_affinity_online_cpu(unsigned int
> irq_lock_sparse();
> for_each_active_irq(irq) {
> desc = irq_to_desc(irq);
> - raw_spin_lock_irq(&desc->lock);
> - irq_restore_affinity_of_irq(desc, cpu);
> - raw_spin_unlock_irq(&desc->lock);
> + scoped_guard(raw_spinlock, &desc->lock)
The above should be "scoped_guard(raw_spinlock_irq, &desc->lock)", otherwise the cpu hotplug is broken as in today's linux-next.
> + irq_restore_affinity_of_irq(desc, cpu);
> }
> irq_unlock_sparse();
>
>
>
>
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 09/45] genirq/cpuhotplug: Convert to lock guards
2025-05-08 14:56 ` [patch V2 09/45] " Marek Szyprowski
@ 2025-05-08 17:53 ` Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-05-08 17:53 UTC (permalink / raw)
To: Marek Szyprowski, LKML; +Cc: Jiri Slaby, Peter Zijlstra
On Thu, May 08 2025 at 16:56, Marek Szyprowski wrote:
>> irq_lock_sparse();
>> for_each_active_irq(irq) {
>> desc = irq_to_desc(irq);
>> - raw_spin_lock_irq(&desc->lock);
>> - irq_restore_affinity_of_irq(desc, cpu);
>> - raw_spin_unlock_irq(&desc->lock);
>> + scoped_guard(raw_spinlock, &desc->lock)
>
> The above should be "scoped_guard(raw_spinlock_irq, &desc->lock)", otherwise the cpu hotplug is broken as in today's linux-next.
https://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git/commit/?h=irq/core&id=c855506257063f444044d0a85a2e9ad9ab1c7ecd
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 12/45] genirq/chip: Rework handle_nested_irq()
[not found] ` <CGME20250508205629eucas1p2f8f2032c2d651be176acdf6ac4aa79cd@eucas1p2.samsung.com>
@ 2025-05-08 20:56 ` Marek Szyprowski
2025-05-09 18:37 ` Thomas Gleixner
0 siblings, 1 reply; 119+ messages in thread
From: Marek Szyprowski @ 2025-05-08 20:56 UTC (permalink / raw)
To: Thomas Gleixner, LKML; +Cc: Jiri Slaby, Peter Zijlstra
On 29.04.2025 08:55, Thomas Gleixner wrote:
> Use the new helpers to decide whether the interrupt should be handled and
> switch the descriptor locking to guard().
>
> Fixup the kernel doc comment while at it.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/chip.c | 78 ++++++++++++++++++++++++------------------------------
> 1 file changed, 36 insertions(+), 42 deletions(-)
>
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -450,48 +450,6 @@ void unmask_threaded_irq(struct irq_desc
> unmask_irq(desc);
> }
>
> -/*
> - * handle_nested_irq - Handle a nested irq from a irq thread
> - * @irq: the interrupt number
> - *
> - * Handle interrupts which are nested into a threaded interrupt
> - * handler. The handler function is called inside the calling
> - * threads context.
> - */
> -void handle_nested_irq(unsigned int irq)
> -{
> - struct irq_desc *desc = irq_to_desc(irq);
> - struct irqaction *action;
> - irqreturn_t action_ret;
> -
> - might_sleep();
> -
> - raw_spin_lock_irq(&desc->lock);
> -
> - desc->istate &= ~(IRQS_REPLAY | IRQS_WAITING);
> -
> - action = desc->action;
> - if (unlikely(!action || irqd_irq_disabled(&desc->irq_data))) {
> - desc->istate |= IRQS_PENDING;
> - raw_spin_unlock_irq(&desc->lock);
> - return;
> - }
> -
> - kstat_incr_irqs_this_cpu(desc);
> - atomic_inc(&desc->threads_active);
> - raw_spin_unlock_irq(&desc->lock);
> -
> - action_ret = IRQ_NONE;
> - for_each_action_of_desc(desc, action)
> - action_ret |= action->thread_fn(action->irq, action->dev_id);
> -
> - if (!irq_settings_no_debug(desc))
> - note_interrupt(desc, action_ret);
> -
> - wake_threads_waitq(desc);
> -}
> -EXPORT_SYMBOL_GPL(handle_nested_irq);
> -
> static bool irq_check_poll(struct irq_desc *desc)
> {
> if (!(desc->istate & IRQS_POLL_INPROGRESS))
> @@ -544,6 +502,42 @@ static inline bool irq_can_handle(struct
> }
>
> /**
> + * handle_nested_irq - Handle a nested irq from a irq thread
> + * @irq: the interrupt number
> + *
> + * Handle interrupts which are nested into a threaded interrupt
> + * handler. The handler function is called inside the calling threads
> + * context.
> + */
> +void handle_nested_irq(unsigned int irq)
> +{
> + struct irq_desc *desc = irq_to_desc(irq);
> + struct irqaction *action;
> + irqreturn_t action_ret;
> +
> + might_sleep();
> +
> + scoped_guard(raw_spinlock_irq, &desc->lock) {
> + if (irq_can_handle_actions(desc))
This should be "if (!irq_can_handle_actions(desc))" to fix nested irqs handling in today's linux-next.
> + return;
> +
> + action = desc->action;
> + kstat_incr_irqs_this_cpu(desc);
> + atomic_inc(&desc->threads_active);
> + }
> +
> + action_ret = IRQ_NONE;
> + for_each_action_of_desc(desc, action)
> + action_ret |= action->thread_fn(action->irq, action->dev_id);
> +
> + if (!irq_settings_no_debug(desc))
> + note_interrupt(desc, action_ret);
> +
> + wake_threads_waitq(desc);
> +}
> +EXPORT_SYMBOL_GPL(handle_nested_irq);
> +
> +/**
> * handle_simple_irq - Simple and software-decoded IRQs.
> * @desc: the interrupt description structure for this irq
> *
>
>
>
>
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-04-29 6:55 ` [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
@ 2025-05-09 13:22 ` Nathan Chancellor
2025-05-11 17:29 ` Miguel Ojeda
1 sibling, 1 reply; 119+ messages in thread
From: Nathan Chancellor @ 2025-05-09 13:22 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: LKML, Jiri Slaby, Peter Zijlstra
Hi Thomas,
On Tue, Apr 29, 2025 at 08:55:26AM +0200, Thomas Gleixner wrote:
> Use the new guards to get and lock the interrupt descriptor and tidy up the
> code.
>
> Fixup the kernel doc comment while at it.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/chip.c | 34 +++++++++++-----------------------
> 1 file changed, 11 insertions(+), 23 deletions(-)
>
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -973,35 +973,23 @@ static void
> }
> }
>
> -void
> -__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
> - const char *name)
> +void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
> + const char *name)
> {
> - unsigned long flags;
> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
> -
> - if (!desc)
> - return;
> -
> - __irq_do_set_handler(desc, handle, is_chained, name);
> - irq_put_desc_busunlock(desc, flags);
> + scoped_irqdesc_get_and_lock(irq, 0)
I am investigating some cases where
WARN(!irqs_disabled(), "Interrupts were enabled early\n");
in start_kernel() in init/main.c is triggered in certain builds with
clang after patch 23 of this series (very bizarre since the conversion
seems to be correct) and I happened to notice that this conversion seems
to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
below?
> + __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name);
> }
> EXPORT_SYMBOL_GPL(__irq_set_handler);
>
> -void
> -irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
> - void *data)
> +void irq_set_chained_handler_and_data(unsigned int irq, irq_flow_handler_t handle,
> + void *data)
> {
> - unsigned long flags;
> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);
> -
> - if (!desc)
> - return;
> + scoped_irqdesc_get_and_buslock(irq, 0) {
> + struct irq_desc *desc = scoped_irqdesc;
>
> - desc->irq_common_data.handler_data = data;
> - __irq_do_set_handler(desc, handle, 1, NULL);
> -
> - irq_put_desc_busunlock(desc, flags);
> + desc->irq_common_data.handler_data = data;
> + __irq_do_set_handler(desc, handle, 1, NULL);
> + }
> }
> EXPORT_SYMBOL_GPL(irq_set_chained_handler_and_data);
>
>
>
>
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 12/45] genirq/chip: Rework handle_nested_irq()
2025-05-08 20:56 ` [patch V2 12/45] " Marek Szyprowski
@ 2025-05-09 18:37 ` Thomas Gleixner
0 siblings, 0 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-05-09 18:37 UTC (permalink / raw)
To: Marek Szyprowski, LKML; +Cc: Jiri Slaby, Peter Zijlstra
On Thu, May 08 2025 at 22:56, Marek Szyprowski wrote:
> On 29.04.2025 08:55, Thomas Gleixner wrote:
>> +void handle_nested_irq(unsigned int irq)
>> +{
>> + struct irq_desc *desc = irq_to_desc(irq);
>> + struct irqaction *action;
>> + irqreturn_t action_ret;
>> +
>> + might_sleep();
>> +
>> + scoped_guard(raw_spinlock_irq, &desc->lock) {
>> + if (irq_can_handle_actions(desc))
>
> This should be "if (!irq_can_handle_actions(desc))" to fix nested irqs handling in today's linux-next.
Ooops.
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-09 13:22 ` [patch V2 26/45] " Nathan Chancellor
@ 2025-05-11 17:29 ` Miguel Ojeda
2025-05-11 17:49 ` Nathan Chancellor
0 siblings, 1 reply; 119+ messages in thread
From: Miguel Ojeda @ 2025-05-11 17:29 UTC (permalink / raw)
To: nathan; +Cc: jirislaby, linux-kernel, peterz, tglx
On Fri, 09 May 2025 14:22:11 +0100 Nathan Chancellor <nathan@kernel.org> wrote:
>
> I am investigating some cases where
>
> WARN(!irqs_disabled(), "Interrupts were enabled early\n");
>
> in start_kernel() in init/main.c is triggered in certain builds with
> clang after patch 23 of this series (very bizarre since the conversion
> seems to be correct) and I happened to notice that this conversion seems
> to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
> below?
Yeah, I am also seeing this in next-20250509 in a LLVM=1 arm64 defconfig + Rust
build under QEMU.
Cheers,
Miguel
[ 0.007387] ------------[ cut here ]------------
[ 0.007414] Interrupts were enabled early
[ 0.007833] WARNING: CPU: 0 PID: 0 at init/main.c:1023 start_kernel+0x31c/0x394
[ 0.008001] Modules linked in:
[ 0.008340] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.15.0-rc5-next-20250509 #1 PREEMPT
[ 0.008458] Hardware name: linux,dummy-virt (DT)
[ 0.008610] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.008641] pc : start_kernel+0x31c/0x394
[ 0.008657] lr : start_kernel+0x31c/0x394
[ 0.008670] sp : ffffdcd810333e80
[ 0.008688] x29: ffffdcd810333e90 x28: 0000000000000000 x27: 0000000000000000
[ 0.008748] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
[ 0.008762] x23: 0000000000000000 x22: 0000000000000000 x21: 0000000044200000
[ 0.008775] x20: ffffdcd81033a000 x19: ffffdcd810345940 x18: 00000000000000b0
[ 0.008789] x17: 0000000000000000 x16: 0000000000000008 x15: 0000000000000004
[ 0.008802] x14: ffffdcd81036e830 x13: 0000000000000003 x12: 0000000000000003
[ 0.008815] x11: 00000000ffffefff x10: 0000000000000000 x9 : 77ed5dd15956fc00
[ 0.008849] x8 : 77ed5dd15956fc00 x7 : 2065726577207374 x6 : 7075727265746e49
[ 0.008862] x5 : ffffdcd810886ef6 x4 : ffffdcd80fe025f2 x3 : 0000000000000000
[ 0.008875] x2 : 0000000000000000 x1 : ffffdcd810333b80 x0 : 000000000000001d
[ 0.008985] Call trace:
[ 0.009142] start_kernel+0x31c/0x394 (P)
[ 0.009320] __primary_switched+0x88/0x90
[ 0.009501] ---[ end trace 0000000000000000 ]---
[ 0.007587] ------------[ cut here ]------------
[ 0.007623] Interrupts were enabled early
[ 0.008277] WARNING: CPU: 0 PID: 0 at init/main.c:1023 start_kernel+0x31c/0x394
[ 0.008526] Modules linked in:
[ 0.009030] CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.15.0-rc5-next-20250509 #1 PREEMPT
[ 0.009228] Hardware name: linux,dummy-virt (DT)
[ 0.009459] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 0.009507] pc : start_kernel+0x31c/0x394
[ 0.009531] lr : start_kernel+0x31c/0x394
[ 0.009554] sp : ffffd5bfd7933e80
[ 0.009585] x29: ffffd5bfd7933e90 x28: 0000000000000000 x27: 0000000000000000
[ 0.009672] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000
[ 0.009687] x23: 0000000000000000 x22: 0000000000000000 x21: 0000000044200000
[ 0.009701] x20: ffffd5bfd793a000 x19: ffffd5bfd7945940 x18: 00000000000000b0
[ 0.009715] x17: 0000000000000000 x16: 0000000000000008 x15: 0000000000000004
[ 0.009729] x14: ffffd5bfd796e830 x13: 0000000000000003 x12: 0000000000000003
[ 0.009743] x11: 00000000ffffefff x10: 0000000000000000 x9 : 2d9976f44ddcd000
[ 0.009778] x8 : 2d9976f44ddcd000 x7 : 2065726577207374 x6 : 7075727265746e49
[ 0.009792] x5 : ffffd5bfd7e86ef6 x4 : ffffd5bfd74025f2 x3 : 0000000000000000
[ 0.009806] x2 : 0000000000000000 x1 : ffffd5bfd7933b80 x0 : 000000000000001d
[ 0.009914] Call trace:
[ 0.010060] start_kernel+0x31c/0x394 (P)
[ 0.010250] __primary_switched+0x88/0x90
[ 0.010458] ---[ end trace 0000000000000000 ]---
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-11 17:29 ` Miguel Ojeda
@ 2025-05-11 17:49 ` Nathan Chancellor
2025-05-12 7:25 ` Jiri Slaby
0 siblings, 1 reply; 119+ messages in thread
From: Nathan Chancellor @ 2025-05-11 17:49 UTC (permalink / raw)
To: Miguel Ojeda; +Cc: jirislaby, linux-kernel, peterz, tglx
On Sun, May 11, 2025 at 07:29:11PM +0200, Miguel Ojeda wrote:
> On Fri, 09 May 2025 14:22:11 +0100 Nathan Chancellor <nathan@kernel.org> wrote:
> >
> > I am investigating some cases where
> >
> > WARN(!irqs_disabled(), "Interrupts were enabled early\n");
> >
> > in start_kernel() in init/main.c is triggered in certain builds with
> > clang after patch 23 of this series (very bizarre since the conversion
> > seems to be correct) and I happened to notice that this conversion seems
> > to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
> > below?
>
> Yeah, I am also seeing this in next-20250509 in a LLVM=1 arm64 defconfig + Rust
> build under QEMU.
I noticed that the warning was reproducible with just the first patch of
the series that adds the lock guards and patch 23 but also several other
individual patches within the series, as I could not just revert patch
23 on next-20250509 to fix it. I have no idea why yet because I have not
had the chance to actually sit down and dig into it but this diff fixes
every instance of the warning that I saw in my tests... :/ could be a
compiler bug or just some difference in behavior between compilers.
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index bd2db6ebb98e..94f463de8f26 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -176,10 +176,9 @@ __DEFINE_UNLOCK_GUARD(irqdesc_lock, struct irq_desc,
static inline class_irqdesc_lock_t class_irqdesc_lock_constructor(unsigned int irq, bool bus,
unsigned int check)
{
- class_irqdesc_lock_t _t = {
- .bus = bus,
- .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
- };
+ class_irqdesc_lock_t _t = {};
+ _t.bus = bus;
+ _t.lock = __irq_get_desc_lock(irq, &_t.flags, bus, check);
return _t;
}
^ permalink raw reply related [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-11 17:49 ` Nathan Chancellor
@ 2025-05-12 7:25 ` Jiri Slaby
2025-05-12 7:32 ` Jiri Slaby
2025-05-12 18:39 ` Thomas Gleixner
0 siblings, 2 replies; 119+ messages in thread
From: Jiri Slaby @ 2025-05-12 7:25 UTC (permalink / raw)
To: Nathan Chancellor, Miguel Ojeda; +Cc: linux-kernel, peterz, tglx
On 11. 05. 25, 19:49, Nathan Chancellor wrote:
> On Sun, May 11, 2025 at 07:29:11PM +0200, Miguel Ojeda wrote:
>> On Fri, 09 May 2025 14:22:11 +0100 Nathan Chancellor <nathan@kernel.org> wrote:
>>>
>>> I am investigating some cases where
>>>
>>> WARN(!irqs_disabled(), "Interrupts were enabled early\n");
>>>
>>> in start_kernel() in init/main.c is triggered in certain builds with
>>> clang after patch 23 of this series (very bizarre since the conversion
>>> seems to be correct) and I happened to notice that this conversion seems
>>> to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
>>> below?
>>
>> Yeah, I am also seeing this in next-20250509 in a LLVM=1 arm64 defconfig + Rust
>> build under QEMU.
>
> I noticed that the warning was reproducible with just the first patch of
> the series that adds the lock guards and patch 23 but also several other
> individual patches within the series, as I could not just revert patch
> 23 on next-20250509 to fix it. I have no idea why yet because I have not
> had the chance to actually sit down and dig into it but this diff fixes
> every instance of the warning that I saw in my tests... :/ could be a
> compiler bug or just some difference in behavior between compilers.
>
> diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
> index bd2db6ebb98e..94f463de8f26 100644
> --- a/kernel/irq/internals.h
> +++ b/kernel/irq/internals.h
> @@ -176,10 +176,9 @@ __DEFINE_UNLOCK_GUARD(irqdesc_lock, struct irq_desc,
> static inline class_irqdesc_lock_t class_irqdesc_lock_constructor(unsigned int irq, bool bus,
> unsigned int check)
> {
> - class_irqdesc_lock_t _t = {
> - .bus = bus,
> - .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
I assume the value stored by __irq_get_desc_lock() to &_t.flags is
overwritten by 0 by the initializer. class_irqdesc_lock_t::flags is
later than ::lock in the structure, so __irq_get_desc_lock() should be
called, setting ::flags, then the initializer should set flags to 0.
> - };
> + class_irqdesc_lock_t _t = {};
> + _t.bus = bus;
> + _t.lock = __irq_get_desc_lock(irq, &_t.flags, bus, check);
That's why this works ^^.
> return _t;
> }
>
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-12 7:25 ` Jiri Slaby
@ 2025-05-12 7:32 ` Jiri Slaby
2025-05-12 8:06 ` Jiri Slaby
2025-05-12 18:39 ` Thomas Gleixner
1 sibling, 1 reply; 119+ messages in thread
From: Jiri Slaby @ 2025-05-12 7:32 UTC (permalink / raw)
To: Nathan Chancellor, Miguel Ojeda; +Cc: linux-kernel, peterz, tglx
On 12. 05. 25, 9:25, Jiri Slaby wrote:
> On 11. 05. 25, 19:49, Nathan Chancellor wrote:
>> On Sun, May 11, 2025 at 07:29:11PM +0200, Miguel Ojeda wrote:
>>> On Fri, 09 May 2025 14:22:11 +0100 Nathan Chancellor
>>> <nathan@kernel.org> wrote:
>>>>
>>>> I am investigating some cases where
>>>>
>>>> WARN(!irqs_disabled(), "Interrupts were enabled early\n");
>>>>
>>>> in start_kernel() in init/main.c is triggered in certain builds with
>>>> clang after patch 23 of this series (very bizarre since the conversion
>>>> seems to be correct) and I happened to notice that this conversion
>>>> seems
>>>> to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
>>>> below?
>>>
>>> Yeah, I am also seeing this in next-20250509 in a LLVM=1 arm64
>>> defconfig + Rust
>>> build under QEMU.
>>
>> I noticed that the warning was reproducible with just the first patch of
>> the series that adds the lock guards and patch 23 but also several other
>> individual patches within the series, as I could not just revert patch
>> 23 on next-20250509 to fix it. I have no idea why yet because I have not
>> had the chance to actually sit down and dig into it but this diff fixes
>> every instance of the warning that I saw in my tests... :/ could be a
>> compiler bug or just some difference in behavior between compilers.
>>
>> diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
>> index bd2db6ebb98e..94f463de8f26 100644
>> --- a/kernel/irq/internals.h
>> +++ b/kernel/irq/internals.h
>> @@ -176,10 +176,9 @@ __DEFINE_UNLOCK_GUARD(irqdesc_lock, struct irq_desc,
>> static inline class_irqdesc_lock_t
>> class_irqdesc_lock_constructor(unsigned int irq, bool bus,
>> unsigned int check)
>> {
>> - class_irqdesc_lock_t _t = {
>> - .bus = bus,
>> - .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
>
> I assume the value stored by __irq_get_desc_lock() to &_t.flags is
> overwritten by 0 by the initializer. class_irqdesc_lock_t::flags is
> later than ::lock in the structure, so __irq_get_desc_lock() should be
> called, setting ::flags, then the initializer should set flags to 0.
>
>> - };
>> + class_irqdesc_lock_t _t = {};
>> + _t.bus = bus;
>> + _t.lock = __irq_get_desc_lock(irq, &_t.flags, bus, check);
>
> That's why this works ^^.
In fact, this should work around the issue too:
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -178,6 +178,7 @@ static inline class_irqdesc_lock_t
class_irqdesc_lock_constructor(unsigned int i
{
class_irqdesc_lock_t _t = {
.bus = bus,
+ .flags = 0,
.lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
};
return _t;
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-12 7:32 ` Jiri Slaby
@ 2025-05-12 8:06 ` Jiri Slaby
0 siblings, 0 replies; 119+ messages in thread
From: Jiri Slaby @ 2025-05-12 8:06 UTC (permalink / raw)
To: Nathan Chancellor, Miguel Ojeda; +Cc: linux-kernel, peterz, tglx
On 12. 05. 25, 9:32, Jiri Slaby wrote:
> On 12. 05. 25, 9:25, Jiri Slaby wrote:
>> On 11. 05. 25, 19:49, Nathan Chancellor wrote:
>>> On Sun, May 11, 2025 at 07:29:11PM +0200, Miguel Ojeda wrote:
>>>> On Fri, 09 May 2025 14:22:11 +0100 Nathan Chancellor
>>>> <nathan@kernel.org> wrote:
>>>>>
>>>>> I am investigating some cases where
>>>>>
>>>>> WARN(!irqs_disabled(), "Interrupts were enabled early\n");
>>>>>
>>>>> in start_kernel() in init/main.c is triggered in certain builds with
>>>>> clang after patch 23 of this series (very bizarre since the conversion
>>>>> seems to be correct) and I happened to notice that this conversion
>>>>> seems
>>>>> to be incorrect? Should this be scoped_irqdesc_get_and_buslock() like
>>>>> below?
>>>>
>>>> Yeah, I am also seeing this in next-20250509 in a LLVM=1 arm64
>>>> defconfig + Rust
>>>> build under QEMU.
>>>
>>> I noticed that the warning was reproducible with just the first patch of
>>> the series that adds the lock guards and patch 23 but also several other
>>> individual patches within the series, as I could not just revert patch
>>> 23 on next-20250509 to fix it. I have no idea why yet because I have not
>>> had the chance to actually sit down and dig into it but this diff fixes
>>> every instance of the warning that I saw in my tests... :/ could be a
>>> compiler bug or just some difference in behavior between compilers.
>>>
>>> diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
>>> index bd2db6ebb98e..94f463de8f26 100644
>>> --- a/kernel/irq/internals.h
>>> +++ b/kernel/irq/internals.h
>>> @@ -176,10 +176,9 @@ __DEFINE_UNLOCK_GUARD(irqdesc_lock, struct
>>> irq_desc,
>>> static inline class_irqdesc_lock_t
>>> class_irqdesc_lock_constructor(unsigned int irq, bool bus,
>>> unsigned int check)
>>> {
>>> - class_irqdesc_lock_t _t = {
>>> - .bus = bus,
>>> - .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
>>
>> I assume the value stored by __irq_get_desc_lock() to &_t.flags is
>> overwritten by 0 by the initializer. class_irqdesc_lock_t::flags is
>> later than ::lock in the structure, so __irq_get_desc_lock() should be
>> called, setting ::flags, then the initializer should set flags to 0.
>>
>>> - };
>>> + class_irqdesc_lock_t _t = {};
>>> + _t.bus = bus;
>>> + _t.lock = __irq_get_desc_lock(irq, &_t.flags, bus, check);
>>
>> That's why this works ^^.
>
> In fact, this should work around the issue too:
Or not. While the order of initializers is in order as specified, the
order of side effects wrt to initialization is _unspecified_. So that
&_t.flags setting can happen any time during initialization.
In sum, _t.flags has to be set out of the initialization for this to be
working (as you suggested in the code above). Either before or after.
(Setting of .bus can remain in the initializer.)
> --- a/kernel/irq/internals.h
> +++ b/kernel/irq/internals.h
> @@ -178,6 +178,7 @@ static inline class_irqdesc_lock_t
> class_irqdesc_lock_constructor(unsigned int i
> {
> class_irqdesc_lock_t _t = {
> .bus = bus,
> + .flags = 0,
> .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
> };
> return _t;
>
>
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants
2025-05-12 7:25 ` Jiri Slaby
2025-05-12 7:32 ` Jiri Slaby
@ 2025-05-12 18:39 ` Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-05-12 18:39 UTC (permalink / raw)
To: Jiri Slaby, Nathan Chancellor, Miguel Ojeda; +Cc: linux-kernel, peterz
On Mon, May 12 2025 at 09:25, Jiri Slaby wrote:
> On 11. 05. 25, 19:49, Nathan Chancellor wrote:
>> {
>> - class_irqdesc_lock_t _t = {
>> - .bus = bus,
>> - .lock = __irq_get_desc_lock(irq, &_t.flags, bus, check),
>
> I assume the value stored by __irq_get_desc_lock() to &_t.flags is
> overwritten by 0 by the initializer. class_irqdesc_lock_t::flags is
> later than ::lock in the structure, so __irq_get_desc_lock() should be
> called, setting ::flags, then the initializer should set flags to 0.
That's what you'd assume. But indeed the compiler might decide that
flags is uninitialized and then overwrite it after the initialized
fields :(
Nathan, can you please send a patch with a proper change log?
Thanks,
tglx
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2a 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-04-30 12:48 ` [patch V2a " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
@ 2025-05-13 17:32 ` Jon Hunter
2025-05-13 22:55 ` Thomas Gleixner
1 sibling, 1 reply; 119+ messages in thread
From: Jon Hunter @ 2025-05-13 17:32 UTC (permalink / raw)
To: Thomas Gleixner, Jiri Slaby, LKML
Cc: Peter Zijlstra, linux-tegra@vger.kernel.org
Hi Thomas,
On 30/04/2025 13:48, Thomas Gleixner wrote:
> Use the new guards to get and lock the interrupt descriptor and tidy up the
> code.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> ---
> V2a: Fix the return value for the on/off paths - Jiry
> ---
> kernel/irq/manage.c | 65 ++++++++++++++++++++++++----------------------------
> 1 file changed, 30 insertions(+), 35 deletions(-)
>
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -846,45 +846,40 @@ static int set_irq_wake_real(unsigned in
> */
> int irq_set_irq_wake(unsigned int irq, unsigned int on)
> {
> - unsigned long flags;
> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
> - int ret = 0;
> + scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
I noticed a suspend regression on some of our Tegra boards and bisect
pointed to this commit. I made the following change and this does appear
to fix it ...
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index 2861e11acf3a..c94837382037 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -846,7 +846,7 @@ static int set_irq_wake_real(unsigned int irq,
unsigned int on)
*/
int irq_set_irq_wake(unsigned int irq, unsigned int on)
{
- scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
struct irq_desc *desc = scoped_irqdesc;
int ret = 0;
Hence, I wanted to ask if this should still be using the buslock scope here?
Thanks!
Jon
--
nvpublic
^ permalink raw reply related [flat|nested] 119+ messages in thread
* Re: [patch V2a 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-05-13 17:32 ` [patch V2a 35/45] " Jon Hunter
@ 2025-05-13 22:55 ` Thomas Gleixner
2025-05-14 7:14 ` Jon Hunter
0 siblings, 1 reply; 119+ messages in thread
From: Thomas Gleixner @ 2025-05-13 22:55 UTC (permalink / raw)
To: Jon Hunter, Jiri Slaby, LKML; +Cc: Peter Zijlstra, linux-tegra@vger.kernel.org
On Tue, May 13 2025 at 18:32, Jon Hunter wrote:
> On 30/04/2025 13:48, Thomas Gleixner wrote:
>> @@ -846,45 +846,40 @@ static int set_irq_wake_real(unsigned in
>> */
>> int irq_set_irq_wake(unsigned int irq, unsigned int on)
>> {
>> - unsigned long flags;
>> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
>> - int ret = 0;
>> + scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
>
>
> I noticed a suspend regression on some of our Tegra boards and bisect
> pointed to this commit. I made the following change and this does appear
> to fix it ...
>
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index 2861e11acf3a..c94837382037 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -846,7 +846,7 @@ static int set_irq_wake_real(unsigned int irq,
> unsigned int on)
> */
> int irq_set_irq_wake(unsigned int irq, unsigned int on)
> {
> - scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> + scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> struct irq_desc *desc = scoped_irqdesc;
> int ret = 0;
>
> Hence, I wanted to ask if this should still be using the buslock scope here?
Of course. My bad. Care to send a patch with a proper change log?
Thanks
tglx
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2a 35/45] genirq/manage: Rework irq_set_irq_wake()
2025-05-13 22:55 ` Thomas Gleixner
@ 2025-05-14 7:14 ` Jon Hunter
0 siblings, 0 replies; 119+ messages in thread
From: Jon Hunter @ 2025-05-14 7:14 UTC (permalink / raw)
To: Thomas Gleixner, Jiri Slaby, LKML
Cc: Peter Zijlstra, linux-tegra@vger.kernel.org
On 13/05/2025 23:55, Thomas Gleixner wrote:
> On Tue, May 13 2025 at 18:32, Jon Hunter wrote:
>> On 30/04/2025 13:48, Thomas Gleixner wrote:
>>> @@ -846,45 +846,40 @@ static int set_irq_wake_real(unsigned in
>>> */
>>> int irq_set_irq_wake(unsigned int irq, unsigned int on)
>>> {
>>> - unsigned long flags;
>>> - struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, IRQ_GET_DESC_CHECK_GLOBAL);
>>> - int ret = 0;
>>> + scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
>>
>>
>> I noticed a suspend regression on some of our Tegra boards and bisect
>> pointed to this commit. I made the following change and this does appear
>> to fix it ...
>>
>> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
>> index 2861e11acf3a..c94837382037 100644
>> --- a/kernel/irq/manage.c
>> +++ b/kernel/irq/manage.c
>> @@ -846,7 +846,7 @@ static int set_irq_wake_real(unsigned int irq,
>> unsigned int on)
>> */
>> int irq_set_irq_wake(unsigned int irq, unsigned int on)
>> {
>> - scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
>> + scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
>> struct irq_desc *desc = scoped_irqdesc;
>> int ret = 0;
>>
>> Hence, I wanted to ask if this should still be using the buslock scope here?
>
> Of course. My bad. Care to send a patch with a proper change log?
Yes no problem! Thanks for confirming.
Jon
--
nvpublic
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 06/45] genirq/proc: Switch to lock guards
2025-04-29 6:54 ` [patch V2 06/45] genirq/proc: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
@ 2025-06-08 12:45 ` Zenghui Yu
2025-06-09 7:15 ` Zenghui Yu
2025-06-09 9:50 ` Thomas Gleixner
1 sibling, 2 replies; 119+ messages in thread
From: Zenghui Yu @ 2025-06-08 12:45 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: LKML, Jiri Slaby, Peter Zijlstra
Hi Thomas,
On 2025/4/29 14:54, Thomas Gleixner wrote:
> Convert all lock/unlock pairs to guards and tidy up the code.
>
> No functional change.
>
> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
>
> ---
> kernel/irq/proc.c | 65 +++++++++++++++++++-----------------------------------
> 1 file changed, 24 insertions(+), 41 deletions(-)
>
> --- a/kernel/irq/proc.c
> +++ b/kernel/irq/proc.c
> @@ -81,20 +81,18 @@ static int show_irq_affinity(int type, s
> static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
> {
> struct irq_desc *desc = irq_to_desc((long)m->private);
> - unsigned long flags;
> cpumask_var_t mask;
>
> if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
> return -ENOMEM;
>
> - raw_spin_lock_irqsave(&desc->lock, flags);
> - if (desc->affinity_hint)
> - cpumask_copy(mask, desc->affinity_hint);
> - raw_spin_unlock_irqrestore(&desc->lock, flags);
> + scoped_guard(raw_spinlock_irq, &desc->lock) {
Any reason it has been switched to a raw_spinlock_irq?
I've hit some random Oops with the backtrace looks like:
Call trace:
string+0x110/0x3b8 (P)
vsnprintf+0x2f0/0xac8
seq_printf+0x180/0x220
show_interrupts+0x4e0/0x7e0
seq_read_iter+0x350/0xd80
proc_reg_read_iter+0x194/0x248
vfs_read+0x5b0/0x940
ksys_read+0xf0/0x1e8
__arm64_sys_read+0x74/0xb0
invoke_syscall+0x74/0x270
el0_svc_common.constprop.0+0xb4/0x240
do_el0_svc+0x48/0x68
el0_svc+0x4c/0xe8
el0t_64_sync_handler+0xc8/0xd0
el0t_64_sync+0x1ac/0x1b0
I haven't dig further. But it looks to me that this patch had introduced
functional change and I'm planning to give the following diff a go on
the same box.
Thanks,
Zenghui
From cfad0937ffb724c2c51c8656c212ccefb09c8990 Mon Sep 17 00:00:00 2001
From: Zenghui Yu <yuzenghui@huawei.com>
Date: Sun, 8 Jun 2025 19:41:41 +0800
Subject: [PATCH] fixup! genirq/proc: Switch to lock guards
Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
---
kernel/irq/proc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index 29c2404e743b..5af8bd1f3ab4 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -86,7 +86,7 @@ static int irq_affinity_hint_proc_show(struct seq_file
*m, void *v)
if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
return -ENOMEM;
- scoped_guard(raw_spinlock_irq, &desc->lock) {
+ scoped_guard(raw_spinlock_irqsave, &desc->lock) {
if (desc->affinity_hint)
cpumask_copy(mask, desc->affinity_hint);
}
@@ -298,7 +298,7 @@ static bool name_unique(unsigned int irq, struct
irqaction *new_action)
struct irq_desc *desc = irq_to_desc(irq);
struct irqaction *action;
- guard(raw_spinlock_irq)(&desc->lock);
+ guard(raw_spinlock_irqsave)(&desc->lock);
for_each_action_of_desc(desc, action) {
if ((action != new_action) && action->name &&
!strcmp(new_action->name, action->name))
@@ -489,7 +489,7 @@ int show_interrupts(struct seq_file *p, void *v)
}
seq_putc(p, ' ');
- guard(raw_spinlock_irq)(&desc->lock);
+ guard(raw_spinlock_irqsave)(&desc->lock);
if (desc->irq_data.chip) {
if (desc->irq_data.chip->irq_print_chip)
desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
--
2.33.0
^ permalink raw reply related [flat|nested] 119+ messages in thread
* Re: [patch V2 06/45] genirq/proc: Switch to lock guards
2025-06-08 12:45 ` [patch V2 06/45] " Zenghui Yu
@ 2025-06-09 7:15 ` Zenghui Yu
2025-06-09 7:28 ` Jiri Slaby
2025-06-09 10:00 ` Thomas Gleixner
2025-06-09 9:50 ` Thomas Gleixner
1 sibling, 2 replies; 119+ messages in thread
From: Zenghui Yu @ 2025-06-09 7:15 UTC (permalink / raw)
To: Thomas Gleixner; +Cc: LKML, Jiri Slaby, Peter Zijlstra
On 2025/6/8 20:45, Zenghui Yu wrote:
> Hi Thomas,
>
> On 2025/4/29 14:54, Thomas Gleixner wrote:
> > Convert all lock/unlock pairs to guards and tidy up the code.
> >
> > No functional change.
> >
> > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
> >
> > ---
> > kernel/irq/proc.c | 65 +++++++++++++++++++-----------------------------------
> > 1 file changed, 24 insertions(+), 41 deletions(-)
> >
> > --- a/kernel/irq/proc.c
> > +++ b/kernel/irq/proc.c
> > @@ -81,20 +81,18 @@ static int show_irq_affinity(int type, s
> > static int irq_affinity_hint_proc_show(struct seq_file *m, void *v)
> > {
> > struct irq_desc *desc = irq_to_desc((long)m->private);
> > - unsigned long flags;
> > cpumask_var_t mask;
> >
> > if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
> > return -ENOMEM;
> >
> > - raw_spin_lock_irqsave(&desc->lock, flags);
> > - if (desc->affinity_hint)
> > - cpumask_copy(mask, desc->affinity_hint);
> > - raw_spin_unlock_irqrestore(&desc->lock, flags);
> > + scoped_guard(raw_spinlock_irq, &desc->lock) {
>
> Any reason it has been switched to a raw_spinlock_irq?
>
> I've hit some random Oops with the backtrace looks like:
>
> Call trace:
> string+0x110/0x3b8 (P)
> vsnprintf+0x2f0/0xac8
> seq_printf+0x180/0x220
> show_interrupts+0x4e0/0x7e0
> seq_read_iter+0x350/0xd80
> proc_reg_read_iter+0x194/0x248
> vfs_read+0x5b0/0x940
> ksys_read+0xf0/0x1e8
> __arm64_sys_read+0x74/0xb0
> invoke_syscall+0x74/0x270
> el0_svc_common.constprop.0+0xb4/0x240
> do_el0_svc+0x48/0x68
> el0_svc+0x4c/0xe8
> el0t_64_sync_handler+0xc8/0xd0
> el0t_64_sync+0x1ac/0x1b0
>
> I haven't dig further. But it looks to me that this patch had introduced
> functional change and I'm planning to give the following diff a go on
> the same box.
>
> Thanks,
> Zenghui
>
>>From cfad0937ffb724c2c51c8656c212ccefb09c8990 Mon Sep 17 00:00:00 2001
> From: Zenghui Yu <yuzenghui@huawei.com>
> Date: Sun, 8 Jun 2025 19:41:41 +0800
> Subject: [PATCH] fixup! genirq/proc: Switch to lock guards
>
> Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
> ---
> kernel/irq/proc.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
> index 29c2404e743b..5af8bd1f3ab4 100644
> --- a/kernel/irq/proc.c
> +++ b/kernel/irq/proc.c
> @@ -86,7 +86,7 @@ static int irq_affinity_hint_proc_show(struct seq_file
> *m, void *v)
> if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
> return -ENOMEM;
>
> - scoped_guard(raw_spinlock_irq, &desc->lock) {
> + scoped_guard(raw_spinlock_irqsave, &desc->lock) {
> if (desc->affinity_hint)
> cpumask_copy(mask, desc->affinity_hint);
> }
> @@ -298,7 +298,7 @@ static bool name_unique(unsigned int irq, struct
> irqaction *new_action)
> struct irq_desc *desc = irq_to_desc(irq);
> struct irqaction *action;
>
> - guard(raw_spinlock_irq)(&desc->lock);
> + guard(raw_spinlock_irqsave)(&desc->lock);
> for_each_action_of_desc(desc, action) {
> if ((action != new_action) && action->name &&
> !strcmp(new_action->name, action->name))
> @@ -489,7 +489,7 @@ int show_interrupts(struct seq_file *p, void *v)
> }
> seq_putc(p, ' ');
>
> - guard(raw_spinlock_irq)(&desc->lock);
> + guard(raw_spinlock_irqsave)(&desc->lock);
> if (desc->irq_data.chip) {
> if (desc->irq_data.chip->irq_print_chip)
> desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
Plus,
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index b0e0a7332993..57facdc30d55 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -964,7 +964,7 @@ __irq_do_set_handler(struct irq_desc *desc,
irq_flow_handler_t handle,
void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int
is_chained,
const char *name)
{
- scoped_irqdesc_get_and_lock(irq, 0)
+ scoped_irqdesc_get_and_buslock(irq, 0)
__irq_do_set_handler(scoped_irqdesc, handle, is_chained, name);
}
EXPORT_SYMBOL_GPL(__irq_set_handler);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index c94837382037..400856abf672 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -659,7 +659,7 @@ void __disable_irq(struct irq_desc *desc)
static int __disable_irq_nosync(unsigned int irq)
{
- scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
__disable_irq(scoped_irqdesc);
return 0;
}
@@ -789,7 +789,7 @@ void __enable_irq(struct irq_desc *desc)
*/
void enable_irq(unsigned int irq)
{
- scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
+ scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
struct irq_desc *desc = scoped_irqdesc;
if (WARN(!desc->irq_data.chip, "enable_irq before setup/request_irq:
irq %u\n", irq))
^ permalink raw reply related [flat|nested] 119+ messages in thread
* Re: [patch V2 06/45] genirq/proc: Switch to lock guards
2025-06-09 7:15 ` Zenghui Yu
@ 2025-06-09 7:28 ` Jiri Slaby
2025-06-09 10:00 ` Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: Jiri Slaby @ 2025-06-09 7:28 UTC (permalink / raw)
To: Zenghui Yu, Thomas Gleixner; +Cc: LKML, Peter Zijlstra
On 09. 06. 25, 9:15, Zenghui Yu wrote:
>> >From cfad0937ffb724c2c51c8656c212ccefb09c8990 Mon Sep 17 00:00:00 2001
>> From: Zenghui Yu <yuzenghui@huawei.com>
>> Date: Sun, 8 Jun 2025 19:41:41 +0800
>> Subject: [PATCH] fixup! genirq/proc: Switch to lock guards
>>
>> Signed-off-by: Zenghui Yu <yuzenghui@huawei.com>
>> ---
>> kernel/irq/proc.c | 6 +++---
>> 1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
>> index 29c2404e743b..5af8bd1f3ab4 100644
>> --- a/kernel/irq/proc.c
>> +++ b/kernel/irq/proc.c
>> @@ -86,7 +86,7 @@ static int irq_affinity_hint_proc_show(struct seq_file
>> *m, void *v)
>> if (!zalloc_cpumask_var(&mask, GFP_KERNEL))
>> return -ENOMEM;
>>
>> - scoped_guard(raw_spinlock_irq, &desc->lock) {
>> + scoped_guard(raw_spinlock_irqsave, &desc->lock) {
>> if (desc->affinity_hint)
>> cpumask_copy(mask, desc->affinity_hint);
>> }
>> @@ -298,7 +298,7 @@ static bool name_unique(unsigned int irq, struct
>> irqaction *new_action)
>> struct irq_desc *desc = irq_to_desc(irq);
>> struct irqaction *action;
>>
>> - guard(raw_spinlock_irq)(&desc->lock);
>> + guard(raw_spinlock_irqsave)(&desc->lock);
>> for_each_action_of_desc(desc, action) {
>> if ((action != new_action) && action->name &&
>> !strcmp(new_action->name, action->name))
>> @@ -489,7 +489,7 @@ int show_interrupts(struct seq_file *p, void *v)
>> }
>> seq_putc(p, ' ');
>>
>> - guard(raw_spinlock_irq)(&desc->lock);
>> + guard(raw_spinlock_irqsave)(&desc->lock);
>> if (desc->irq_data.chip) {
>> if (desc->irq_data.chip->irq_print_chip)
>> desc->irq_data.chip->irq_print_chip(&desc->irq_data, p);
>
> Plus,
Could you send proper patches, pls?
--
js
suse labs
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 06/45] genirq/proc: Switch to lock guards
2025-06-08 12:45 ` [patch V2 06/45] " Zenghui Yu
2025-06-09 7:15 ` Zenghui Yu
@ 2025-06-09 9:50 ` Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-06-09 9:50 UTC (permalink / raw)
To: Zenghui Yu; +Cc: LKML, Jiri Slaby, Peter Zijlstra
On Sun, Jun 08 2025 at 20:45, Zenghui Yu wrote:
> On 2025/4/29 14:54, Thomas Gleixner wrote:
>> - raw_spin_lock_irqsave(&desc->lock, flags);
>> - if (desc->affinity_hint)
>> - cpumask_copy(mask, desc->affinity_hint);
>> - raw_spin_unlock_irqrestore(&desc->lock, flags);
>> + scoped_guard(raw_spinlock_irq, &desc->lock) {
>
> Any reason it has been switched to a raw_spinlock_irq?
Yes. This code is always thread context and can never be invoked with
interrupts disabled. So there is zero reason to use irqsave().
> I've hit some random Oops with the backtrace looks like:
>
> Call trace:
> string+0x110/0x3b8 (P)
> vsnprintf+0x2f0/0xac8
> seq_printf+0x180/0x220
> show_interrupts+0x4e0/0x7e0
> seq_read_iter+0x350/0xd80
> proc_reg_read_iter+0x194/0x248
> vfs_read+0x5b0/0x940
> ksys_read+0xf0/0x1e8
> __arm64_sys_read+0x74/0xb0
> invoke_syscall+0x74/0x270
> el0_svc_common.constprop.0+0xb4/0x240
> do_el0_svc+0x48/0x68
> el0_svc+0x4c/0xe8
> el0t_64_sync_handler+0xc8/0xd0
> el0t_64_sync+0x1ac/0x1b0
>
> I haven't dig further. But it looks to me that this patch had introduced
> functional change and I'm planning to give the following diff a go on
> the same box.
That won't help at all because the actual crash is within show_interrupts()....
Thanks,
tglx
^ permalink raw reply [flat|nested] 119+ messages in thread
* Re: [patch V2 06/45] genirq/proc: Switch to lock guards
2025-06-09 7:15 ` Zenghui Yu
2025-06-09 7:28 ` Jiri Slaby
@ 2025-06-09 10:00 ` Thomas Gleixner
1 sibling, 0 replies; 119+ messages in thread
From: Thomas Gleixner @ 2025-06-09 10:00 UTC (permalink / raw)
To: Zenghui Yu; +Cc: LKML, Jiri Slaby, Peter Zijlstra
On Mon, Jun 09 2025 at 15:15, Zenghui Yu wrote:
> On 2025/6/8 20:45, Zenghui Yu wrote:
>> On 2025/4/29 14:54, Thomas Gleixner wrote:
> Plus,
>
> diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
> index b0e0a7332993..57facdc30d55 100644
> --- a/kernel/irq/chip.c
> +++ b/kernel/irq/chip.c
> @@ -964,7 +964,7 @@ __irq_do_set_handler(struct irq_desc *desc,
> irq_flow_handler_t handle,
> void __irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int
> is_chained,
> const char *name)
> {
> - scoped_irqdesc_get_and_lock(irq, 0)
> + scoped_irqdesc_get_and_buslock(irq, 0)
What for? Which problem are you trying to solve here?
> __irq_do_set_handler(scoped_irqdesc, handle, is_chained, name);
> }
> EXPORT_SYMBOL_GPL(__irq_set_handler);
> diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
> index c94837382037..400856abf672 100644
> --- a/kernel/irq/manage.c
> +++ b/kernel/irq/manage.c
> @@ -659,7 +659,7 @@ void __disable_irq(struct irq_desc *desc)
>
> static int __disable_irq_nosync(unsigned int irq)
> {
> - scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> + scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
That's broken as __disable_irq_nosync() can be invoked from
non-preemtible contexts.
> __disable_irq(scoped_irqdesc);
> return 0;
> }
> @@ -789,7 +789,7 @@ void __enable_irq(struct irq_desc *desc)
> */
> void enable_irq(unsigned int irq)
> {
> - scoped_irqdesc_get_and_lock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
> + scoped_irqdesc_get_and_buslock(irq, IRQ_GET_DESC_CHECK_GLOBAL) {
Ditto.
Can you stop making random changes and instead provide the actual
information to decode the OOPS?
> string+0x110/0x3b8 (P)
> vsnprintf+0x2f0/0xac8
> seq_printf+0x180/0x220
> show_interrupts+0x4e0/0x7e0
This means the print in show_interrupts() accesses an invalid
pointer. So the obvious thing to do is:
scripts/faddr2line vmlinux show_interrupts+0x4e0/0x7e0
and provide the information, which of the gazillions of seq_printf()'s
in that function causes the problem.
I'm pretty sure that is has absolutely nothing to do with the guard()
conversions.
Thanks,
tglx
^ permalink raw reply [flat|nested] 119+ messages in thread
end of thread, other threads:[~2025-06-09 10:00 UTC | newest]
Thread overview: 119+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-29 6:54 [patch V2 00/45] genirq: Cleanups and conversion to lock guards Thomas Gleixner
2025-04-29 6:54 ` [patch V2 01/45] genirq: Provide conditional " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 02/45] genirq/irqdesc: Switch to " Thomas Gleixner
2025-04-30 5:54 ` Jiri Slaby
2025-04-30 6:36 ` [patch V2a " Thomas Gleixner
2025-04-30 6:51 ` Jiri Slaby
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 03/45] genirq/autoprobe: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 04/45] genirq/pm: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 05/45] genirq/resend: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 06/45] genirq/proc: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-06-08 12:45 ` [patch V2 06/45] " Zenghui Yu
2025-06-09 7:15 ` Zenghui Yu
2025-06-09 7:28 ` Jiri Slaby
2025-06-09 10:00 ` Thomas Gleixner
2025-06-09 9:50 ` Thomas Gleixner
2025-04-29 6:54 ` [patch V2 07/45] genirq/spurious: Cleanup code Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:54 ` [patch V2 08/45] genirq/spurious: Switch to lock guards Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 09/45] genirq/cpuhotplug: Convert " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508145631eucas1p2f5369234fee8eb86761d70d028d6c82d@eucas1p2.samsung.com>
2025-05-08 14:56 ` [patch V2 09/45] " Marek Szyprowski
2025-05-08 17:53 ` Thomas Gleixner
2025-04-29 6:55 ` [patch V2 10/45] genirq/debugfs: " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 11/45] genirq/chip: Prepare for code reduction Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 12/45] genirq/chip: Rework handle_nested_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
[not found] ` <CGME20250508205629eucas1p2f8f2032c2d651be176acdf6ac4aa79cd@eucas1p2.samsung.com>
2025-05-08 20:56 ` [patch V2 12/45] " Marek Szyprowski
2025-05-09 18:37 ` Thomas Gleixner
2025-04-29 6:55 ` [patch V2 13/45] genirq/chip: Rework handle_simple_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 14/45] genirq/chip: Rework handle_untracked_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 15/45] genirq/chip: Rework handle_level_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 16/45] genirq/chip: Rework handle_eoi_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 17/45] genirq/chip: Rework handle_edge_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 18/45] genirq/chip: Rework handle_fasteoi_ack_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 19/45] genirq/chip: Rework handle_fasteoi_mask_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 20/45] genirq/chip: Use lock guards where applicable Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 21/45] genirq/chip: Rework irq_set_chip() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 22/45] genirq/chip: Rework irq_set_irq_type() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 23/45] genirq/chip: Rework irq_set_handler_data() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 24/45] genirq/chip: Rework irq_set_msi_desc_off() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 25/45] genirq/chip: Rework irq_set_chip_data() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 26/45] genirq/chip: Rework irq_set_handler() variants Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-09 13:22 ` [patch V2 26/45] " Nathan Chancellor
2025-05-11 17:29 ` Miguel Ojeda
2025-05-11 17:49 ` Nathan Chancellor
2025-05-12 7:25 ` Jiri Slaby
2025-05-12 7:32 ` Jiri Slaby
2025-05-12 8:06 ` Jiri Slaby
2025-05-12 18:39 ` Thomas Gleixner
2025-04-29 6:55 ` [patch V2 27/45] genirq/chip: Rework irq_modify_status() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 28/45] genirq/manage: Cleanup kernel doc comments Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 29/45] genirq/manage: Convert to lock guards Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 30/45] genirq/manage: Rework irq_update_affinity_desc() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 31/45] genirq/manage: Rework __irq_apply_affinity_hint() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 32/45] genirq/manage: Rework irq_set_vcpu_affinity() Thomas Gleixner
2025-04-30 6:31 ` Jiri Slaby
2025-04-30 12:49 ` [patch V2a " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 33/45] genirq/manage: Rework __disable_irq_nosync() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 34/45] genirq/manage: Rework enable_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 35/45] genirq/manage: Rework irq_set_irq_wake() Thomas Gleixner
2025-04-30 6:37 ` Jiri Slaby
2025-04-30 12:42 ` Thomas Gleixner
2025-04-30 12:48 ` [patch V2a " Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-13 17:32 ` [patch V2a 35/45] " Jon Hunter
2025-05-13 22:55 ` Thomas Gleixner
2025-05-14 7:14 ` Jon Hunter
2025-04-29 6:55 ` [patch V2 36/45] genirq/manage: Rework can_request_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 37/45] genirq/manage: Rework irq_set_parent() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 38/45] genirq/manage: Rework enable_percpu_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 39/45] genirq/manage: Rework irq_percpu_is_enabled() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 40/45] genirq/manage: Rework disable_percpu_irq() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 41/45] genirq/manage: Rework prepare_percpu_nmi() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 42/45] genirq/manage: Rework teardown_percpu_nmi() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 43/45] genirq/manage: Rework irq_get_irqchip_state() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 44/45] genirq/manage: Rework irq_set_irqchip_state() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-04-29 6:55 ` [patch V2 45/45] genirq: Remove irq_[get|put]_desc*() Thomas Gleixner
2025-05-07 9:07 ` [tip: irq/core] " tip-bot2 for Thomas Gleixner
2025-05-06 14:24 ` [patch V2 00/45] genirq: Cleanups and conversion to lock guards Peter Zijlstra
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).