Skip to content

Commit 950d0a1

Browse files
committed
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: irq: Track the owner of irq descriptor irq: Always set IRQF_ONESHOT if no primary handler is specified genirq: Fix wrong bit operation
2 parents ab7e2db + b687380 commit 950d0a1

5 files changed

Lines changed: 51 additions & 19 deletions

File tree

include/linux/irq.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <linux/errno.h>
2424
#include <linux/topology.h>
2525
#include <linux/wait.h>
26+
#include <linux/module.h>
2627

2728
#include <asm/irq.h>
2829
#include <asm/ptrace.h>
@@ -547,7 +548,15 @@ static inline struct msi_desc *irq_data_get_msi(struct irq_data *d)
547548
return d->msi_desc;
548549
}
549550

550-
int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node);
551+
int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
552+
struct module *owner);
553+
554+
static inline int irq_alloc_descs(int irq, unsigned int from, unsigned int cnt,
555+
int node)
556+
{
557+
return __irq_alloc_descs(irq, from, cnt, node, THIS_MODULE);
558+
}
559+
551560
void irq_free_descs(unsigned int irq, unsigned int cnt);
552561
int irq_reserve_irqs(unsigned int from, unsigned int cnt);
553562

include/linux/irqdesc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct irq_desc {
6666
#ifdef CONFIG_PROC_FS
6767
struct proc_dir_entry *dir;
6868
#endif
69+
struct module *owner;
6970
const char *name;
7071
} ____cacheline_internodealigned_in_smp;
7172

kernel/irq/generic-chip.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
246246
gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask);
247247

248248
for (i = gc->irq_base; msk; msk >>= 1, i++) {
249-
if (!msk & 0x01)
249+
if (!(msk & 0x01))
250250
continue;
251251

252252
if (flags & IRQ_GC_INIT_NESTED_LOCK)
@@ -301,7 +301,7 @@ void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
301301
raw_spin_unlock(&gc_lock);
302302

303303
for (; msk; msk >>= 1, i++) {
304-
if (!msk & 0x01)
304+
if (!(msk & 0x01))
305305
continue;
306306

307307
/* Remove handler first. That will mask the irq line */

kernel/irq/irqdesc.c

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ static inline void desc_smp_init(struct irq_desc *desc, int node) { }
7070
static inline int desc_node(struct irq_desc *desc) { return 0; }
7171
#endif
7272

73-
static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
73+
static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node,
74+
struct module *owner)
7475
{
7576
int cpu;
7677

@@ -86,6 +87,7 @@ static void desc_set_defaults(unsigned int irq, struct irq_desc *desc, int node)
8687
desc->irq_count = 0;
8788
desc->irqs_unhandled = 0;
8889
desc->name = NULL;
90+
desc->owner = owner;
8991
for_each_possible_cpu(cpu)
9092
*per_cpu_ptr(desc->kstat_irqs, cpu) = 0;
9193
desc_smp_init(desc, node);
@@ -128,7 +130,7 @@ static void free_masks(struct irq_desc *desc)
128130
static inline void free_masks(struct irq_desc *desc) { }
129131
#endif
130132

131-
static struct irq_desc *alloc_desc(int irq, int node)
133+
static struct irq_desc *alloc_desc(int irq, int node, struct module *owner)
132134
{
133135
struct irq_desc *desc;
134136
gfp_t gfp = GFP_KERNEL;
@@ -147,7 +149,7 @@ static struct irq_desc *alloc_desc(int irq, int node)
147149
raw_spin_lock_init(&desc->lock);
148150
lockdep_set_class(&desc->lock, &irq_desc_lock_class);
149151

150-
desc_set_defaults(irq, desc, node);
152+
desc_set_defaults(irq, desc, node, owner);
151153

152154
return desc;
153155

@@ -173,13 +175,14 @@ static void free_desc(unsigned int irq)
173175
kfree(desc);
174176
}
175177

176-
static int alloc_descs(unsigned int start, unsigned int cnt, int node)
178+
static int alloc_descs(unsigned int start, unsigned int cnt, int node,
179+
struct module *owner)
177180
{
178181
struct irq_desc *desc;
179182
int i;
180183

181184
for (i = 0; i < cnt; i++) {
182-
desc = alloc_desc(start + i, node);
185+
desc = alloc_desc(start + i, node, owner);
183186
if (!desc)
184187
goto err;
185188
mutex_lock(&sparse_irq_lock);
@@ -227,7 +230,7 @@ int __init early_irq_init(void)
227230
nr_irqs = initcnt;
228231

229232
for (i = 0; i < initcnt; i++) {
230-
desc = alloc_desc(i, node);
233+
desc = alloc_desc(i, node, NULL);
231234
set_bit(i, allocated_irqs);
232235
irq_insert_desc(i, desc);
233236
}
@@ -261,7 +264,7 @@ int __init early_irq_init(void)
261264
alloc_masks(&desc[i], GFP_KERNEL, node);
262265
raw_spin_lock_init(&desc[i].lock);
263266
lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
264-
desc_set_defaults(i, &desc[i], node);
267+
desc_set_defaults(i, &desc[i], node, NULL);
265268
}
266269
return arch_early_irq_init();
267270
}
@@ -276,8 +279,16 @@ static void free_desc(unsigned int irq)
276279
dynamic_irq_cleanup(irq);
277280
}
278281

279-
static inline int alloc_descs(unsigned int start, unsigned int cnt, int node)
282+
static inline int alloc_descs(unsigned int start, unsigned int cnt, int node,
283+
struct module *owner)
280284
{
285+
u32 i;
286+
287+
for (i = 0; i < cnt; i++) {
288+
struct irq_desc *desc = irq_to_desc(start + i);
289+
290+
desc->owner = owner;
291+
}
281292
return start;
282293
}
283294

@@ -337,7 +348,8 @@ EXPORT_SYMBOL_GPL(irq_free_descs);
337348
* Returns the first irq number or error code
338349
*/
339350
int __ref
340-
irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
351+
__irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
352+
struct module *owner)
341353
{
342354
int start, ret;
343355

@@ -366,13 +378,13 @@ irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node)
366378

367379
bitmap_set(allocated_irqs, start, cnt);
368380
mutex_unlock(&sparse_irq_lock);
369-
return alloc_descs(start, cnt, node);
381+
return alloc_descs(start, cnt, node, owner);
370382

371383
err:
372384
mutex_unlock(&sparse_irq_lock);
373385
return ret;
374386
}
375-
EXPORT_SYMBOL_GPL(irq_alloc_descs);
387+
EXPORT_SYMBOL_GPL(__irq_alloc_descs);
376388

377389
/**
378390
* irq_reserve_irqs - mark irqs allocated
@@ -440,7 +452,7 @@ void dynamic_irq_cleanup(unsigned int irq)
440452
unsigned long flags;
441453

442454
raw_spin_lock_irqsave(&desc->lock, flags);
443-
desc_set_defaults(irq, desc, desc_node(desc));
455+
desc_set_defaults(irq, desc, desc_node(desc), NULL);
444456
raw_spin_unlock_irqrestore(&desc->lock, flags);
445457
}
446458

kernel/irq/manage.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
883883

884884
if (desc->irq_data.chip == &no_irq_chip)
885885
return -ENOSYS;
886+
if (!try_module_get(desc->owner))
887+
return -ENODEV;
886888
/*
887889
* Some drivers like serial.c use request_irq() heavily,
888890
* so we have to be careful not to interfere with a
@@ -906,8 +908,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
906908
*/
907909
nested = irq_settings_is_nested_thread(desc);
908910
if (nested) {
909-
if (!new->thread_fn)
910-
return -EINVAL;
911+
if (!new->thread_fn) {
912+
ret = -EINVAL;
913+
goto out_mput;
914+
}
911915
/*
912916
* Replace the primary handler which was provided from
913917
* the driver for non nested interrupt handling by the
@@ -929,8 +933,10 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
929933

930934
t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
931935
new->name);
932-
if (IS_ERR(t))
933-
return PTR_ERR(t);
936+
if (IS_ERR(t)) {
937+
ret = PTR_ERR(t);
938+
goto out_mput;
939+
}
934940
/*
935941
* We keep the reference to the task struct even if
936942
* the thread dies to avoid that the interrupt code
@@ -1095,6 +1101,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
10951101
kthread_stop(t);
10961102
put_task_struct(t);
10971103
}
1104+
out_mput:
1105+
module_put(desc->owner);
10981106
return ret;
10991107
}
11001108

@@ -1203,6 +1211,7 @@ static struct irqaction *__free_irq(unsigned int irq, void *dev_id)
12031211
put_task_struct(action->thread);
12041212
}
12051213

1214+
module_put(desc->owner);
12061215
return action;
12071216
}
12081217

@@ -1322,6 +1331,7 @@ int request_threaded_irq(unsigned int irq, irq_handler_t handler,
13221331
if (!thread_fn)
13231332
return -EINVAL;
13241333
handler = irq_default_primary_handler;
1334+
irqflags |= IRQF_ONESHOT;
13251335
}
13261336

13271337
action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);

0 commit comments

Comments
 (0)