Skip to contentSkip to conversation

generic-hardirqs.patch, 2.6.9-rc1-bk14

PATCH In review Ingo Molnar 10 participants 38 messages Sep 8, 2004 – Sep 10, 2004 IRQ

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 generic-hardirqs.patch, 2.6.9-rc1-bk14

the attached patch moves generic hardirq handling bits to kernel/hardirq.c. It is not a replacement for any of the existing IRQ functions, so architectures can use their existing hardirq code in an unmodified form. It is a library of generic functions that an architecture can make use of optionally.

I've fully converted x86's irq.c to use the new functions, and Scott Wood has done the same for ppc/ppc64 as well. (the arch-ppc* changes are not included in this patch because i couldnt test them myself in the current port of this patch - but the generic bits were tested on ppc.)

i have test-compiled and test-booted the patch on x86 and x64, on SMP && PREEMPT and !SMP && !PREEMPT kernels. x64 needed only a single change (a setup_irq() prototype) to work fine, which makes me believe that the patch will not break other architectures either.

(a more complex version of this patch has been tested for weeks as part of the voluntary-preempt patches as well.)

Ingo

the attached patch moves generic hardirq handling bits into kernel/hardirq.c. It is not a replacement for any of the existing IRQ functions, so architectures can use their existing hardirq code in an unmodified form. It is a library of generic functions that an architecture can make use of optionally.

I've fully converted x86's irq.c to use the new functions - and Scott Wood has done the same for ppc/ppc64 as well. (the arch-ppc* changes are not included in this patch because i couldnt test them myself in the current port of this patch - but the generic bits were tested on ppc)

i have test-compiled the patch on x86 and x64, on SMP && PREEMPT and !SMP && !PREEMPT. x64 needed only a single change - a setup_irq() prototype, to work fine, which makes me believe that the patch will not break any other architectures either.

arch/i386/kernel/i386_ksyms.c renamed from arch/i386/kernel/i386_ksyms.c.orig +0 -4
@@ -77,9 +77,6 @@ EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
@@ -147,7 +144,6 @@ EXPORT_SYMBOL_NOVERS(__write_lock_failed
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP stuff */
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(smp_call_function);
 
 /* TLB flushing */
arch/i386/kernel/irq.c renamed from arch/i386/kernel/irq.c.orig +6 -435

498 lines not on this page · raw message

include/asm-x86_64/hardirq.h renamed from include/asm-x86_64/hardirq.h.orig +4 -2
@@ -25,8 +25,8 @@
  * - ( bit 26 is the PREEMPT_ACTIVE flag. )
  *
  * PREEMPT_MASK: 0x000000ff
- * HARDIRQ_MASK: 0x0000ff00
- * SOFTIRQ_MASK: 0x00ff0000
+ * SOFTIRQ_MASK: 0x0000ff00
+ * HARDIRQ_MASK: 0x00ff0000
  */
 
 #define PREEMPT_BITS	8
@@ -99,4 +99,6 @@ do {									\
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
+extern int setup_irq(unsigned int irq, struct irqaction * new);
+
 #endif /* __ASM_HARDIRQ_H */
include/linux/irq.h renamed from include/linux/irq.h.orig +15 -1
@@ -10,12 +10,15 @@
  */
 
 #include <linux/config.h>
+#include <linux/linkage.h>
 
 #if !defined(CONFIG_ARCH_S390)
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
+#include <linux/wait.h>
+#include <linux/signal.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -71,10 +74,21 @@ extern irq_desc_t irq_desc [NR_IRQS];
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 
-extern int setup_irq(unsigned int , struct irqaction * );
+
+extern asmlinkage int generic_handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void generic_synchronize_irq(unsigned int irq);
+extern int generic_setup_irq(unsigned int irq, struct irqaction * new);
+extern void generic_free_irq(unsigned int irq, void *dev_id);
+extern void generic_disable_irq_nosync(unsigned int irq);
+extern void generic_disable_irq(unsigned int irq);
+extern void generic_enable_irq(unsigned int irq);
+extern void generic_note_interrupt(int irq, irq_desc_t *desc, int action_ret);
+extern void generic_init_irq_proc(void);
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 
+extern int noirqdebug;
+
 #endif
 
 #endif /* __irq_h */
include/linux/interrupt.h renamed from include/linux/interrupt.h.orig +2 -0
@@ -40,6 +40,8 @@ struct irqaction {
 	const char *name;
 	void *dev_id;
 	struct irqaction *next;
+	int irq;
+	struct proc_dir_entry *dir;
 };
 
 extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
include/asm-i386/irq.h renamed from include/asm-i386/irq.h.orig +0 -3
@@ -21,9 +21,6 @@ static __inline__ int irq_canonicalize(i
 	return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
 extern void release_x86_irqs(struct task_struct *);
 extern int can_request_irq(unsigned int, unsigned long flags);
 
include/asm-i386/hardirq.h renamed from include/asm-i386/hardirq.h.orig +34 -9

54 lines not on this page · raw message

kernel/Makefile renamed from kernel/Makefile.orig +1 -1
@@ -3,7 +3,7 @@
 #
 
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
-	    exit.o itimer.o time.o softirq.o resource.o \
+	    exit.o itimer.o time.o softirq.o hardirq.o resource.o \
 	    sysctl.o capability.o ptrace.o timer.o user.o \
 	    signal.o sys.o kmod.o workqueue.o pid.o \
 	    rcupdate.o intermodule.o extable.o params.o posix-timers.o \
kernel/hardirq.c renamed from kernel/hardirq.c.orig +529 -0

529 lines not on this page · raw message

#1 lore raw
Quoted 6 lines · Ingo Molnar

the attached patch moves generic hardirq handling bits to kernel/hardirq.c. It is not a replacement for any of the existing IRQ functions, so architectures can use their existing hardirq code in an unmodified form. It is a library of generic functions that an architecture can make use of optionally.

Quoted 6 lines

I've fully converted x86's irq.c to use the new functions, and Scott Wood has done the same for ppc/ppc64 as well. (the arch-ppc* changes are not included in this patch because i couldnt test them myself in the current port of this patch - but the generic bits were tested on ppc.)

In the interests of full provinence, the TimeSys patches are based on work by Andrey Panin.

Quoted 11 lines

i have test-compiled and test-booted the patch on x86 and x64, on SMP && PREEMPT and !SMP && !PREEMPT kernels. x64 needed only a single change (a setup_irq() prototype) to work fine, which makes me believe that the patch will not break other architectures either.

(a more complex version of this patch has been tested for weeks as part of the voluntary-preempt patches as well.)

Ingo

Signature · 1 line
 Anyone who quotes me in their sig is an idiot. -- Rusty Russell's sig
#2 lore raw
Quoted 2 lines · La Monte H.P. Yarroll

In the interests of full provinence, the TimeSys patches are based on work by Andrey Panin.

Btw, Andrey's patches got all the things right I complained about :)

#3 lore raw
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines · La Monte H.P. Yarroll

In the interests of full provinence, the TimeSys patches are based on work by Andrey Panin.

Btw, Andrey's patches got all the things right I complained about :)

do you mean the irq and softirq threading patches? Unfortunately, while they were rather clean the generic bits were also quite substantially broken semantically on SMP so while i carried them for a while in the voluntary-preempt patch i had to drop and redo them all from scratch. Scott Wood then sent ppc bits which might be based on the other code. Anyway, it seems everyone wants roughly the same thing, it only has to actually happen now ;-) Once we have kernel/hardirq.c then the irq-threading patches become nicely local and maintainable.

Ingo

#4 lore raw
Quoted 10 lines · Ingo Molnar
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines · La Monte H.P. Yarroll

In the interests of full provinence, the TimeSys patches are based on work by Andrey Panin.

Btw, Andrey's patches got all the things right I complained about :)

do you mean the irq and softirq threading patches?

No, irq.c consolidation.

#5 lore raw
In reply to Ingo Molnar
Quoted 34 lines · Ingo Molnar

the attached patch moves generic hardirq handling bits to kernel/hardirq.c. It is not a replacement for any of the existing IRQ functions, so architectures can use their existing hardirq code in an unmodified form. It is a library of generic functions that an architecture can make use of optionally.

I've fully converted x86's irq.c to use the new functions, and Scott Wood has done the same for ppc/ppc64 as well. (the arch-ppc* changes are not included in this patch because i couldnt test them myself in the current port of this patch - but the generic bits were tested on ppc.)

i have test-compiled and test-booted the patch on x86 and x64, on SMP && PREEMPT and !SMP && !PREEMPT kernels. x64 needed only a single change (a setup_irq() prototype) to work fine, which makes me believe that the patch will not break other architectures either.

(a more complex version of this patch has been tested for weeks as part of the voluntary-preempt patches as well.)

+++ linux/include/asm-x86_64/hardirq.h

include/asm-x86_64/hardirq.h renamed from include/asm-x86_64/hardirq.h.orig +2 -2
@@ -25,8 +25,8 @@
  * - ( bit 26 is the PREEMPT_ACTIVE flag. )
  *
  * PREEMPT_MASK: 0x000000ff
- * HARDIRQ_MASK: 0x0000ff00
- * SOFTIRQ_MASK: 0x00ff0000
+ * SOFTIRQ_MASK: 0x0000ff00
+ * HARDIRQ_MASK: 0x00ff0000
  */
 
 #define PREEMPT_BITS	8

include/asm-x86_64/hardirq.h do { \ · line 102

Quoted 4 lines
include/asm-x86_64/hardirq.h renamed from include/asm-x86_64/hardirq.h.orig +1 -0
@@ -99,4 +99,6 @@ do {									\
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
+extern int setup_irq(unsigned int irq, struct irqaction * new);

This doesn't apply anymore because most of <asm/hardirq.h> moved to linux/hardirq.h in -mm and a the patch is on it's way to Linus.

Quoted 4 lines
include/linux/irq.h renamed from include/linux/irq.h.orig +0 -0
@@ -71,10 +74,21 @@ extern irq_desc_t irq_desc [NR_IRQS];
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 

include/linux/irq.h extern irq_desc_t irq_desc [NR_IRQS]; · line 85

Quoted 10 lines
include/linux/irq.h renamed from include/linux/irq.h.orig +9 -1
-extern int setup_irq(unsigned int , struct irqaction * );
+
+extern asmlinkage int generic_handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void generic_synchronize_irq(unsigned int irq);
+extern int generic_setup_irq(unsigned int irq, struct irqaction * new);
+extern void generic_free_irq(unsigned int irq, void *dev_id);
+extern void generic_disable_irq_nosync(unsigned int irq);
+extern void generic_disable_irq(unsigned int irq);
+extern void generic_enable_irq(unsigned int irq);
+extern void generic_note_interrupt(int irq, irq_desc_t *desc, int action_ret);

Please don't introduce the generic_ names just to have every arch (in your previous patches, that is) provide a wrapper with normal names again.

kernel/Makefile line 6

Quoted 8 lines
kernel/Makefile renamed from kernel/Makefile.orig +1 -1
@@ -3,7 +3,7 @@
 #
 
 obj-y     = sched.o fork.o exec_domain.o panic.o printk.o profile.o \
-	    exit.o itimer.o time.o softirq.o resource.o \
+	    exit.o itimer.o time.o softirq.o hardirq.o resource.o \

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

#6 lore raw
Quoted 8 lines · Christoph Hellwig

include/asm-x86_64/hardirq.h do { \ · line 102

Quoted 5 lines
include/asm-x86_64/hardirq.h renamed from include/asm-x86_64/hardirq.h.orig +1 -0
@@ -99,4 +99,6 @@ do {									\
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
+extern int setup_irq(unsigned int irq, struct irqaction * new);

This doesn't apply anymore because most of <asm/hardirq.h> moved to linux/hardirq.h in -mm and a the patch is on it's way to Linus.

(yeah. not a big issue - can happen in any order. this patch is against BK-curr.)

Quoted 4 lines
Quoted 4 lines
include/linux/irq.h renamed from include/linux/irq.h.orig +4 -0
+extern asmlinkage int generic_handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void generic_synchronize_irq(unsigned int irq);
+extern int generic_setup_irq(unsigned int irq, struct irqaction * new);
+extern void generic_free_irq(unsigned int irq, void *dev_id);
Quoted 8 lines

include/linux/irq.h extern irq_desc_t irq_desc [NR_IRQS]; · line 85

Quoted 4 lines
include/linux/irq.h renamed from include/linux/irq.h.orig +4 -0
+extern void generic_disable_irq_nosync(unsigned int irq);
+extern void generic_disable_irq(unsigned int irq);
+extern void generic_enable_irq(unsigned int irq);
+extern void generic_note_interrupt(int irq, irq_desc_t *desc, int action_ret);

Please don't introduce the generic_ names just to have every arch (in your previous patches, that is) provide a wrapper with normal names again.

some of the architectures dont want to (and cannot) use the generic functions for one reason or another. So the proper approach i believe is to provide these generic functions the architectures can plug in. I can do an asm-generic/hardirq.h that adds all the definitions, for architectures that dont need any special IRQ logic.

Quoted 7 lines

kernel/Makefile line 6

Quoted 3 lines

obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \

kernel/Makefile renamed from kernel/Makefile.orig +1 -1
-	    exit.o itimer.o time.o softirq.o resource.o \
+	    exit.o itimer.o time.o softirq.o hardirq.o resource.o \

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

it compiles fine on x86, x64, ppc and ppc64. Why do you think it wont compile on others?

wrt. unused generic functions - why dont we drop them link-time?

Ingo

#7 lore raw
Quoted 5 lines · Ingo Molnar

some of the architectures dont want to (and cannot) use the generic functions for one reason or another. So the proper approach i believe is to provide these generic functions the architectures can plug in. I can do an asm-generic/hardirq.h that adds all the definitions, for architectures that dont need any special IRQ logic.

Some architectures definitly can't use it. That's why the prototypes for them arch in arch-headers. No need to introduce totally useless wrappers. The asm-generic one sounds like a good idea, but I'd wait with that one until the consolidation is mostly finished, aka all architectures that currently use more or less a copy of the i386 irq.c are migrated over so we can see it's scope.

Quoted 10 lines
Quoted 7 lines

kernel/Makefile line 6

Quoted 3 lines

obj-y = sched.o fork.o exec_domain.o panic.o printk.o profile.o \

kernel/Makefile renamed from kernel/Makefile.orig +1 -1
-	    exit.o itimer.o time.o softirq.o resource.o \
+	    exit.o itimer.o time.o softirq.o hardirq.o resource.o \

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

it compiles fine on x86, x64, ppc and ppc64. Why do you think it wont compile on others?

linux/irq.h is despite it's name _not_ a public header but a misnamed asm-generic/hw_irq.h. There's quite a few architectures with a completely different interrupt architecture and for tose it won't compile.

Quoted 1 line

wrt. unused generic functions - why dont we drop them link-time?

make explicit what you can do easily instead of relying on the compiler. It allows to get rid of your horrible generic_ hacks, cuts down compile time and makes explicit to anyone looking at the code and Kconfig which architectures use this.

#8 lore raw
Quoted 6 lines · Christoph Hellwig
Quoted 1 line

wrt. unused generic functions - why dont we drop them link-time?

make explicit what you can do easily instead of relying on the compiler. It allows to get rid of your horrible generic_ hacks, cuts down compile time and makes explicit to anyone looking at the code and Kconfig which architectures use this.

i disagree. It's the same as the VFS model: we have generic_block_bmap() which a filesystem might or might not make use of. It's still around even if no filesystem makes use of it but do we care? I'd prefer fixing our linking logic to get rid of unused functions than complicating code and the architecture with conditionals.

is there any architecture that cannot make use of kernel/hardirq.c _at all_?

Ingo

#9 lore raw
Quoted 5 lines · Ingo Molnar

i disagree. It's the same as the VFS model: we have generic_block_bmap() which a filesystem might or might not make use of. It's still around even if no filesystem makes use of it but do we care? I'd prefer fixing our linking logic to get rid of unused functions than complicating code and the architecture with conditionals.

Completley different model. VFS supports lots of filesystem implementation with one interface. IRQ code is a a single implementation for each architecture.

Quoted 2 lines

is there any architecture that cannot make use of kernel/hardirq.c _at all_?

s390 doesn't need it at all because it doesn't have the concept of hardirqs.

At least arm{,26}, m68k{,nommu} and parisc and sparc{,64} use extremly different models for irq handling

#10 lore raw
Quoted 9 lines · Christoph Hellwig
Quoted 5 lines

i disagree. It's the same as the VFS model: we have generic_block_bmap() which a filesystem might or might not make use of. It's still around even if no filesystem makes use of it but do we care? I'd prefer fixing our linking logic to get rid of unused functions than complicating code and the architecture with conditionals.

Completley different model. VFS supports lots of filesystem implementation with one interface. IRQ code is a a single implementation for each architecture.

not at all different model. 90% of the important drivers (no, drivers/s390 doesnt count) are shared between multiple architectures using the same interface: request_irq()/free_irq() and a handler with an enumerated irq vector.

Quoted 7 lines
Quoted 2 lines

is there any architecture that cannot make use of kernel/hardirq.c _at all_?

s390 doesn't need it at all because it doesn't have the concept of hardirqs.

At least arm{,26}, m68k{,nommu} and parisc and sparc{,64} use extremly different models for irq handling

it could be a bit like nommu - a noirq model.

i agree with enabling an architecture to exclude _all_ of hardirq.c, but specifying per-function is excessive - if an architecture can make use of some of them then weak symbols will get rid of the rest.

Ingo

#11 lore raw
Quoted 4 lines · Ingo Molnar

not at all different model. 90% of the important drivers (no, drivers/s390 doesnt count) are shared between multiple architectures using the same interface: request_irq()/free_irq() and a handler with an enumerated irq vector.

Sure, but that's not the level we're talking about. The function we talk about compare to the vfs_* routines (when looking at the arches with i386-style generic irq code)(

Quoted 10 lines
Quoted 4 lines

s390 doesn't need it at all because it doesn't have the concept of hardirqs.

At least arm{,26}, m68k{,nommu} and parisc and sparc{,64} use extremly different models for irq handling

it could be a bit like nommu - a noirq model.

i agree with enabling an architecture to exclude _all_ of hardirq.c, but specifying per-function is excessive - if an architecture can make use of some of them then weak symbols will get rid of the rest.

I never wanted to exclude individual functions. But when you look at arch/*/kernel/irq.c I don't see a reason for doing it at all. It makes sense to make this an all or nothing switch.

#12 lore raw
Quoted 7 lines · Christoph Hellwig
Quoted 7 lines
Quoted 4 lines

s390 doesn't need it at all because it doesn't have the concept of hardirqs.

At least arm{,26}, m68k{,nommu} and parisc and sparc{,64} use extremly different models for irq handling

it could be a bit like nommu - a noirq model.

Quoted 7 lines
Quoted 3 lines

i agree with enabling an architecture to exclude _all_ of hardirq.c, but specifying per-function is excessive - if an architecture can make use of some of them then weak symbols will get rid of the rest.

I never wanted to exclude individual functions. But when you look at arch/*/kernel/irq.c I don't see a reason for doing it at all. It makes sense to make this an all or nothing switch.

ok, agreed. New patch attached. An architecture has to set GENERIC_HARDIRQS in Kconfig to get it compiled by default. x86 does this for now.

Ingo

arch/i386/kernel/i386_ksyms.c renamed from arch/i386/kernel/i386_ksyms.c.orig +0 -4
@@ -77,9 +77,6 @@ EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
@@ -147,7 +144,6 @@ EXPORT_SYMBOL_NOVERS(__write_lock_failed
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP stuff */
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(smp_call_function);
 
 /* TLB flushing */
arch/i386/kernel/irq.c renamed from arch/i386/kernel/irq.c.orig +6 -435

498 lines not on this page · raw message

arch/i386/Kconfig renamed from arch/i386/Kconfig.orig +4 -0
@@ -1190,6 +1190,10 @@ source "crypto/Kconfig"
 
 source "lib/Kconfig"
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
 config X86_SMP
 	bool
 	depends on SMP && !X86_VOYAGER
include/asm-x86_64/hardirq.h renamed from include/asm-x86_64/hardirq.h.orig +2 -0
@@ -99,4 +99,6 @@ do {									\
   extern void synchronize_irq(unsigned int irq);
 #endif /* CONFIG_SMP */
 
+extern int setup_irq(unsigned int irq, struct irqaction * new);
+
 #endif /* __ASM_HARDIRQ_H */
include/linux/irq.h renamed from include/linux/irq.h.orig +15 -1
@@ -10,12 +10,15 @@
  */
 
 #include <linux/config.h>
+#include <linux/linkage.h>
 
 #if !defined(CONFIG_ARCH_S390)
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
+#include <linux/wait.h>
+#include <linux/signal.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -71,10 +74,21 @@ extern irq_desc_t irq_desc [NR_IRQS];
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 
-extern int setup_irq(unsigned int , struct irqaction * );
+
+extern asmlinkage int generic_handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void generic_synchronize_irq(unsigned int irq);
+extern int generic_setup_irq(unsigned int irq, struct irqaction * new);
+extern void generic_free_irq(unsigned int irq, void *dev_id);
+extern void generic_disable_irq_nosync(unsigned int irq);
+extern void generic_disable_irq(unsigned int irq);
+extern void generic_enable_irq(unsigned int irq);
+extern void generic_note_interrupt(int irq, irq_desc_t *desc, int action_ret);
+extern void generic_init_irq_proc(void);
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 
+extern int noirqdebug;
+
 #endif
 
 #endif /* __irq_h */
include/linux/interrupt.h renamed from include/linux/interrupt.h.orig +2 -0
@@ -40,6 +40,8 @@ struct irqaction {
 	const char *name;
 	void *dev_id;
 	struct irqaction *next;
+	int irq;
+	struct proc_dir_entry *dir;
 };
 
 extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
include/asm-i386/irq.h renamed from include/asm-i386/irq.h.orig +0 -3
@@ -21,9 +21,6 @@ static __inline__ int irq_canonicalize(i
 	return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
 extern void release_x86_irqs(struct task_struct *);
 extern int can_request_irq(unsigned int, unsigned long flags);
 
include/asm-i386/hardirq.h renamed from include/asm-i386/hardirq.h.orig +34 -9

54 lines not on this page · raw message

kernel/Makefile renamed from kernel/Makefile.orig +1 -0
@@ -12,6 +12,7 @@ obj-y     = sched.o fork.o exec_domain.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
+obj-$(CONFIG_GENERIC_HARDIRQS) += hardirq.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
kernel/hardirq.c renamed from kernel/hardirq.c.orig +529 -0

529 lines not on this page · raw message

#13 lore raw
In reply to Christoph Hellwig
Quoted 8 lines · Christoph Hellwig
Quoted 2 lines · Ingo Molnar

is there any architecture that cannot make use of kernel/hardirq.c _at all_?

s390 doesn't need it at all because it doesn't have the concept of hardirqs.

At least arm{,26}, m68k{,nommu} and parisc and sparc{,64} use extremly different models for irq handling

They're not irreparably different, though (at least, not all of them); we had generic IRQ code (with threads) running in our 2.4 kernel on arm and sparc64.

-Scott

#14 lore raw
In reply to Ingo Molnar
Quoted 3 lines · Christoph Hellwig
Quoted 3 lines

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

Quoted 3 lines · Ingo Molnar

it compiles fine on x86, x64, ppc and ppc64. Why do you think it wont compile on others?
wrt. unused generic functions - why dont we drop them link-time?

It may be time for a __weak define to abbreviate __attribute__((weak)); we seem to use it in enough places.

-- wli

#15 lore raw
Quoted 5 lines · William Lee Irwin III
Quoted 3 lines · Christoph Hellwig
Quoted 3 lines

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

Quoted 7 lines
Quoted 3 lines · Ingo Molnar

it compiles fine on x86, x64, ppc and ppc64. Why do you think it wont compile on others?
wrt. unused generic functions - why dont we drop them link-time?

It may be time for a __weak define to abbreviate __attribute__((weak)); we seem to use it in enough places.

Personally I'm extremly unhappy with that week model for things like this. There's no reason why architectures could implement irq handling as inlines. Or in case of s390 not at all.

#16 lore raw
Quoted 3 lines · Christoph Hellwig

Personally I'm extremly unhappy with that week model for things like this. There's no reason why architectures could implement irq handling as inlines. Or in case of s390 not at all.

s390 is a special case i agree - no IRQ handling is a special case. We can exclude kernel/hardirq.o on s390 and all virtual-guest platforms.

Ingo

#17 lore raw
In reply to Christoph Hellwig
Quoted 2 lines · William Lee Irwin III
Quoted 2 lines

It may be time for a __weak define to abbreviate __attribute__((weak)); we seem to use it in enough places.

Quoted 3 lines · Christoph Hellwig

Personally I'm extremly unhappy with that week model for things like this. There's no reason why architectures could implement irq handling as inlines. Or in case of s390 not at all.

If there's a question of "not at all" that probably rules out weak symbols as a method of handling it.

-- wli

#18 lore raw
In reply to William Lee Irwin III
Quoted 5 lines · William Lee Irwin III
Quoted 3 lines · Christoph Hellwig
Quoted 3 lines

And make hardirq.o dependent on some symbols the architectures set. Else arches that don't use it carry tons of useless baggage around (and in fact I'm pretty sure it wouldn't even compie for many)

Quoted 7 lines
Quoted 3 lines · Ingo Molnar

it compiles fine on x86, x64, ppc and ppc64. Why do you think it wont compile on others?
wrt. unused generic functions - why dont we drop them link-time?

It may be time for a __weak define to abbreviate __attribute__((weak)); we seem to use it in enough places.

Hmm, whenever i've brought up weak functions in a patch it's never well received. Frankly i prefer it to littering the architectures with similar functions.

Zwane

#19 lore raw
Quoted 3 lines · Zwane Mwaikambo

Hmm, whenever i've brought up weak functions in a patch it's never well received. Frankly i prefer it to littering the architectures with similar functions.

That's what we have asm-generic for.

#20 lore raw
Quoted 6 lines · Christoph Hellwig
Quoted 3 lines · Zwane Mwaikambo

Hmm, whenever i've brought up weak functions in a patch it's never well received. Frankly i prefer it to littering the architectures with similar functions.

That's what we have asm-generic for.

So you have an inline function in a header and include it everywhere? How is that better?

Zwane

#21 lore raw
Quoted 11 lines · Zwane Mwaikambo
Quoted 6 lines · Christoph Hellwig
Quoted 3 lines · Zwane Mwaikambo

Hmm, whenever i've brought up weak functions in a patch it's never well received. Frankly i prefer it to littering the architectures with similar functions.

That's what we have asm-generic for.

So you have an inline function in a header and include it everywhere? How is that better?

the thing is, now with the config option, you don't need the generic_ wrapper thing, just use the full real name. And the prototypes can be generic for the arch's that want it.

#22 lore raw
Quoted 3 lines · Arjan van de Ven

the thing is, now with the config option, you don't need the generic_ wrapper thing, just use the full real name. And the prototypes can be generic for the arch's that want it.

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

Ingo

arch/i386/kernel/i386_ksyms.c renamed from arch/i386/kernel/i386_ksyms.c.orig +0 -4
@@ -77,9 +77,6 @@ EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
@@ -147,7 +144,6 @@ EXPORT_SYMBOL_NOVERS(__write_lock_failed
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP stuff */
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(smp_call_function);
 
 /* TLB flushing */
arch/i386/kernel/irq.c renamed from arch/i386/kernel/irq.c.orig +0 -429

453 lines not on this page · raw message

arch/i386/Kconfig renamed from arch/i386/Kconfig.orig +4 -0
@@ -1190,6 +1190,10 @@ source "crypto/Kconfig"
 
 source "lib/Kconfig"
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
 config X86_SMP
 	bool
 	depends on SMP && !X86_VOYAGER
include/linux/irq.h renamed from include/linux/irq.h.orig +19 -1
@@ -10,12 +10,15 @@
  */
 
 #include <linux/config.h>
+#include <linux/linkage.h>
 
 #if !defined(CONFIG_ARCH_S390)
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
+#include <linux/wait.h>
+#include <linux/signal.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -71,7 +74,22 @@ extern irq_desc_t irq_desc [NR_IRQS];
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 
-extern int setup_irq(unsigned int , struct irqaction * );
+
+extern int setup_irq(unsigned int irq, struct irqaction * new);
+
+#ifdef CONFIG_GENERIC_HARDIRQS
+extern asmlinkage int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void synchronize_irq(unsigned int irq);
+extern void free_irq(unsigned int irq, void *dev_id);
+extern void disable_irq_nosync(unsigned int irq);
+extern void disable_irq(unsigned int irq);
+extern void enable_irq(unsigned int irq);
+extern void note_interrupt(int irq, irq_desc_t *desc, int action_ret);
+extern void init_irq_proc(void);
+
+extern int noirqdebug;
+
+#endif
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 
include/linux/interrupt.h renamed from include/linux/interrupt.h.orig +2 -0
@@ -40,6 +40,8 @@ struct irqaction {
 	const char *name;
 	void *dev_id;
 	struct irqaction *next;
+	int irq;
+	struct proc_dir_entry *dir;
 };
 
 extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
include/asm-i386/irq.h renamed from include/asm-i386/irq.h.orig +0 -3
@@ -21,9 +21,6 @@ static __inline__ int irq_canonicalize(i
 	return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
 extern void release_x86_irqs(struct task_struct *);
 extern int can_request_irq(unsigned int, unsigned long flags);
 
include/asm-i386/hardirq.h renamed from include/asm-i386/hardirq.h.orig +0 -10
@@ -68,10 +68,6 @@ typedef struct {
 #define in_softirq()		(softirq_count())
 #define in_interrupt()		(irq_count())
 
-
-#define hardirq_trylock()	(!in_interrupt())
-#define hardirq_endlock()	do { } while (0)
-
 #define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
 #define nmi_enter()		(irq_enter())
 #define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
@@ -92,10 +88,4 @@ do {									\
 		preempt_enable_no_resched();				\
 } while (0)
 
-#ifndef CONFIG_SMP
-# define synchronize_irq(irq)	barrier()
-#else
-  extern void synchronize_irq(unsigned int irq);
-#endif /* CONFIG_SMP */
-
 #endif /* __ASM_HARDIRQ_H */
kernel/Makefile renamed from kernel/Makefile.orig +1 -0
@@ -12,6 +12,7 @@ obj-y     = sched.o fork.o exec_domain.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
+obj-$(CONFIG_GENERIC_HARDIRQS) += hardirq.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
kernel/hardirq.c renamed from kernel/hardirq.c.orig +529 -0

529 lines not on this page · raw message

#23 lore raw
Quoted 3 lines · Ingo Molnar

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

Apart from very nice? =) It's needed doing for a long time now.

Zwane

#24 lore raw

PATCH 1/1 generic-hardirqs-2.6.9-rc1-mm4.patch

In reply to Ingo Molnar
Quoted 3 lines · Ingo Molnar

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

i've attached generic-hardirqs-2.6.9-rc1-mm4.patch which is a merge against -mm4. x86 and x64 compiles & boots fine. Since there are zero changes to non-x86 architectures it should build fine on all platforms.

Ingo

arch/i386/kernel/irq.c renamed from arch/i386/kernel/irq.c.orig +3 -393
@@ -73,8 +73,6 @@ irq_desc_t irq_desc[NR_IRQS] __cacheline
 	}
 };
 
-static void register_irq_proc (unsigned int irq);
-
 /*
  * per-CPU IRQ handling stacks
  */
@@ -196,89 +194,6 @@ skip:
 	return 0;
 }
 
-
-
-
-#ifdef CONFIG_SMP
-inline void synchronize_irq(unsigned int irq)
-{
-	while (irq_desc[irq].status & IRQ_INPROGRESS)
-		cpu_relax();
-}
-#endif
-
-/*
- * This should really return information about whether
- * we should do bottom half handling etc. Right now we
- * end up _always_ checking the bottom half, which is a
- * waste of time and is not what some drivers would
- * prefer.
- */
-asmlinkage int handle_IRQ_event(unsigned int irq,
-		struct pt_regs *regs, struct irqaction *action)
-{
-	int status = 1;	/* Force the "do bottom halves" bit */
-	int ret, retval = 0;
-
-	if (!(action->flags & SA_INTERRUPT))
-		local_irq_enable();
-
-	do {
-		ret = action->handler(irq, action->dev_id, regs);
-		if (ret == IRQ_HANDLED)
-			status |= action->flags;
-		retval |= ret;
-		action = action->next;
-	} while (action);
-	if (status & SA_SAMPLE_RANDOM)
-		add_interrupt_randomness(irq);
-	local_irq_disable();
-	return retval;
-}
-
-static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	struct irqaction *action;
-
-	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
-		printk(KERN_ERR "irq event %d: bogus return value %x\n",
-				irq, action_ret);
-	} else {
-		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
-	}
-	dump_stack();
-	printk(KERN_ERR "handlers:\n");
-	action = desc->action;
-	do {
-		printk(KERN_ERR "[<%p>]", action->handler);
-		print_symbol(" (%s)",
-			(unsigned long)action->handler);
-		printk("\n");
-		action = action->next;
-	} while (action);
-}
-
-static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
-{
-	static int count = 100;
-
-	if (count) {
-		count--;
-		__report_bad_irq(irq, desc, action_ret);
-	}
-}
-
-static int noirqdebug;
-
-static int __init noirqdebug_setup(char *str)
-{
-	noirqdebug = 1;
-	printk(KERN_INFO "IRQ lockup detection disabled\n");
-	return 1;
-}
-
-__setup("noirqdebug", noirqdebug_setup);
-
 static int irqfixup;
 
 static int __init irqfixup_setup(char *str)
@@ -380,7 +295,7 @@ static asmlinkage int misrouted_irq(int 
  *
  * Called under desc->lock
  */
-static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret, struct pt_regs *regs)
+static void x86_note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret, struct pt_regs *regs)
 {
 	if (action_ret != IRQ_HANDLED) {
 		desc->irqs_unhandled++;
@@ -464,97 +379,6 @@ static void note_interrupt(int irq, irq_
 	desc->irqs_unhandled = 0;
 }
 
-/*
- * Generic enable/disable code: this just calls
- * down into the PIC-specific version for the actual
- * hardware disable after having gotten the irq
- * controller lock. 
- */
- 
-/**
- *	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.
- *
- *	This function may be called from IRQ context.
- */
- 
-inline void disable_irq_nosync(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	if (!desc->depth++) {
-		desc->status |= IRQ_DISABLED;
-		desc->handler->disable(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
-/**
- *	disable_irq - disable an irq and wait for completion
- *	@irq: Interrupt to disable
- *
- *	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 may be called - with care - from IRQ context.
- */
- 
-void disable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	disable_irq_nosync(irq);
-	if (desc->action)
-		synchronize_irq(irq);
-}
-
-/**
- *	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.
- *
- *	This function may be called from IRQ context.
- */
- 
-void enable_irq(unsigned int irq)
-{
-	irq_desc_t *desc = irq_desc + irq;
-	unsigned long flags;
-
-	spin_lock_irqsave(&desc->lock, flags);
-	switch (desc->depth) {
-	case 1: {
-		unsigned int status = desc->status & ~IRQ_DISABLED;
-		desc->status = status;
-		if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
-			desc->status = status | IRQ_REPLAY;
-			hw_resend_irq(desc->handler,irq);
-		}
-		desc->handler->enable(irq);
-		/* fall-through */
-	}
-	default:
-		desc->depth--;
-		break;
-	case 0:
-		printk("enable_irq(%u) unbalanced from %p\n", irq,
-		       __builtin_return_address(0));
-	}
-	spin_unlock_irqrestore(&desc->lock, flags);
-}
-
 #ifdef CONFIG_HOTPLUG_CPU
 static int irqs_stabilizing;
 
@@ -695,7 +519,7 @@ asmlinkage unsigned int do_IRQ(struct pt
 		}
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret, &regs);
+			x86_note_interrupt(irq, desc, action_ret, &regs);
 		if (curctx != irqctx)
 			irqctx->tinfo.task = NULL;
 		if (likely(!(desc->status & IRQ_PENDING)))
@@ -714,7 +538,7 @@ asmlinkage unsigned int do_IRQ(struct pt
 
 		spin_lock(&desc->lock);
 		if (!noirqdebug)
-			note_interrupt(irq, desc, action_ret, &regs);
+			x86_note_interrupt(irq, desc, action_ret, &regs);
 		if (likely(!(desc->status & IRQ_PENDING)))
 			break;
 		desc->status &= ~IRQ_PENDING;
@@ -830,62 +654,6 @@ int request_irq(unsigned int irq, 
 
 EXPORT_SYMBOL(request_irq);
 
-/**
- *	free_irq - free an interrupt
- *	@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. 
- */
- 
-void free_irq(unsigned int irq, void *dev_id)
-{
-	irq_desc_t *desc;
-	struct irqaction **p;
-	unsigned long flags;
-
-	if (irq >= NR_IRQS)
-		return;
-
-	desc = irq_desc + irq;
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	for (;;) {
-		struct irqaction * action = *p;
-		if (action) {
-			struct irqaction **pp = p;
-			p = &action->next;
-			if (action->dev_id != dev_id)
-				continue;
-
-			/* Found it - now remove it from the list of entries */
-			*pp = action->next;
-			if (!desc->action) {
-				desc->status |= IRQ_DISABLED;
-				desc->handler->shutdown(irq);
-			}
-			spin_unlock_irqrestore(&desc->lock,flags);
-
-			/* Wait to make sure it's not being used on another CPU */
-			synchronize_irq(irq);
-			kfree(action);
-			return;
-		}
-		printk("Trying to free free IRQ%d\n",irq);
-		spin_unlock_irqrestore(&desc->lock,flags);
-		return;
-	}
-}
-
-EXPORT_SYMBOL(free_irq);
-
 /*
  * IRQ autodetection code..
  *
@@ -1081,115 +849,6 @@ int probe_irq_off(unsigned long val)
 
 EXPORT_SYMBOL(probe_irq_off);
 
-/* this was setup_x86_irq but it seems pretty generic */
-int setup_irq(unsigned int irq, struct irqaction * new)
-{
-	int shared = 0;
-	unsigned long flags;
-	struct irqaction *old, **p;
-	irq_desc_t *desc = irq_desc + irq;
-
-	if (desc->handler == &no_irq_type)
-		return -ENOSYS;
-	/*
-	 * Some drivers like serial.c use request_irq() heavily,
-	 * so we have to be careful not to interfere with a
-	 * running system.
-	 */
-	if (new->flags & SA_SAMPLE_RANDOM) {
-		/*
-		 * This function might sleep, we want to call it first,
-		 * outside of the atomic block.
-		 * Yes, this might clear the entropy pool if the wrong
-		 * driver is attempted to be loaded, without actually
-		 * installing a new handler, but is this really a problem,
-		 * only the sysadmin is able to do this.
-		 */
-		rand_initialize_irq(irq);
-	}
-
-	/*
-	 * The following block of code has to be executed atomically
-	 */
-	spin_lock_irqsave(&desc->lock,flags);
-	p = &desc->action;
-	if ((old = *p) != NULL) {
-		/* Can't share interrupts unless both agree to */
-		if (!(old->flags & new->flags & SA_SHIRQ)) {
-			spin_unlock_irqrestore(&desc->lock,flags);
-			return -EBUSY;
-		}
-
-		/* add new interrupt at end of irq queue */
-		do {
-			p = &old->next;
-			old = *p;
-		} while (old);
-		shared = 1;
-	}
-
-	*p = new;
-
-	if (!shared) {
-		desc->depth = 0;
-		desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT | IRQ_WAITING | IRQ_INPROGRESS);
-		desc->handler->startup(irq);
-	}
-	spin_unlock_irqrestore(&desc->lock,flags);
-
-	register_irq_proc(irq);
-	return 0;
-}
-
-static struct proc_dir_entry * root_irq_dir;
-static struct proc_dir_entry * irq_dir [NR_IRQS];
-
-#ifdef CONFIG_SMP
-
-static struct proc_dir_entry *smp_affinity_entry[NR_IRQS];
-
-cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
-
-static int irq_affinity_read_proc(char *page, char **start, off_t off,
-			int count, int *eof, void *data)
-{
-	int len = cpumask_scnprintf(page, count, irq_affinity[(long)data]);
-	if (count - len < 2)
-		return -EINVAL;
-	len += sprintf(page + len, "\n");
-	return len;
-}
-
-static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
-					unsigned long count, void *data)
-{
-	int irq = (long)data, full_count = count, err;
-	cpumask_t new_value, tmp;
-
-	if (!irq_desc[irq].handler->set_affinity)
-		return -EIO;
-
-	err = cpumask_parse(buffer, count, new_value);
-	if (err)
-		return err;
-
-	/*
-	 * Do not allow disabling IRQs completely - it's a too easy
-	 * way to make the system unusable accidentally :-) At least
-	 * one online CPU still has to be targeted.
-	 */
-	cpus_and(tmp, new_value, cpu_online_map);
-	if (cpus_empty(tmp))
-		return -EINVAL;
-
-	irq_affinity[irq] = new_value;
-	irq_desc[irq].handler->set_affinity(irq,
-					cpumask_of_cpu(first_cpu(new_value)));
-
-	return full_count;
-}
-#endif
-
 #ifdef CONFIG_HOTPLUG_CPU
 #include <mach_apic.h>
 
@@ -1234,55 +893,6 @@ void fixup_irqs(void)
 #endif
 }
 #endif
-#define MAX_NAMELEN 10
-
-static void register_irq_proc (unsigned int irq)
-{
-	char name [MAX_NAMELEN];
-
-	if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) ||
-			irq_dir[irq])
-		return;
-
-	memset(name, 0, MAX_NAMELEN);
-	sprintf(name, "%d", irq);
-
-	/* create /proc/irq/1234 */
-	irq_dir[irq] = proc_mkdir(name, root_irq_dir);
-
-#ifdef CONFIG_SMP
-	{
-		struct proc_dir_entry *entry;
-
-		/* create /proc/irq/1234/smp_affinity */
-		entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]);
-
-		if (entry) {
-			entry->nlink = 1;
-			entry->data = (void *)(long)irq;
-			entry->read_proc = irq_affinity_read_proc;
-			entry->write_proc = irq_affinity_write_proc;
-		}
-
-		smp_affinity_entry[irq] = entry;
-	}
-#endif
-}
-
-void init_irq_proc (void)
-{
-	int i;
-
-	/* create /proc/irq */
-	root_irq_dir = proc_mkdir("irq", NULL);
-	create_prof_cpu_mask(root_irq_dir);
-	/*
-	 * Create entries for all existing IRQs.
-	 */
-	for (i = 0; i < NR_IRQS; i++)
-		register_irq_proc(i);
-}
-
 
 #ifdef CONFIG_4KSTACKS
 /*
arch/i386/kernel/i386_ksyms.c renamed from arch/i386/kernel/i386_ksyms.c.orig +0 -4
@@ -76,9 +76,6 @@ EXPORT_SYMBOL_GPL(kernel_fpu_begin);
 EXPORT_SYMBOL(__ioremap);
 EXPORT_SYMBOL(ioremap_nocache);
 EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(enable_irq);
-EXPORT_SYMBOL(disable_irq);
-EXPORT_SYMBOL(disable_irq_nosync);
 EXPORT_SYMBOL(probe_irq_mask);
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(pm_idle);
@@ -146,7 +143,6 @@ EXPORT_SYMBOL_NOVERS(__write_lock_failed
 EXPORT_SYMBOL_NOVERS(__read_lock_failed);
 
 /* Global SMP stuff */
-EXPORT_SYMBOL(synchronize_irq);
 EXPORT_SYMBOL(smp_call_function);
 
 /* TLB flushing */
arch/i386/Kconfig renamed from arch/i386/Kconfig.orig +4 -0
@@ -1226,6 +1226,10 @@ source "crypto/Kconfig"
 
 source "lib/Kconfig"
 
+config GENERIC_HARDIRQS
+	bool
+	default y
+
 config X86_SMP
 	bool
 	depends on SMP && !X86_VOYAGER
include/linux/irq.h renamed from include/linux/irq.h.orig +21 -1
@@ -10,12 +10,15 @@
  */
 
 #include <linux/config.h>
+#include <linux/linkage.h>
 
 #if !defined(CONFIG_ARCH_S390)
 
 #include <linux/cache.h>
 #include <linux/spinlock.h>
 #include <linux/cpumask.h>
+#include <linux/wait.h>
+#include <linux/signal.h>
 
 #include <asm/irq.h>
 #include <asm/ptrace.h>
@@ -71,7 +74,24 @@ extern irq_desc_t irq_desc [NR_IRQS];
 
 #include <asm/hw_irq.h> /* the arch dependent stuff */
 
-extern int setup_irq(unsigned int , struct irqaction * );
+
+extern int setup_irq(unsigned int irq, struct irqaction * new);
+
+#ifdef CONFIG_GENERIC_HARDIRQS
+extern asmlinkage int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action);
+extern void synchronize_irq(unsigned int irq);
+extern void free_irq(unsigned int irq, void *dev_id);
+extern void disable_irq_nosync(unsigned int irq);
+extern void disable_irq(unsigned int irq);
+extern void enable_irq(unsigned int irq);
+extern void note_interrupt(int irq, irq_desc_t *desc, int action_ret);
+extern void __report_bad_irq(int irq, irq_desc_t *desc, int action_ret);
+extern void report_bad_irq(int irq, irq_desc_t *desc, int action_ret);
+extern void init_irq_proc(void);
+
+extern int noirqdebug;
+
+#endif
 
 extern hw_irq_controller no_irq_type;  /* needed in every arch ? */
 
include/linux/interrupt.h renamed from include/linux/interrupt.h.orig +2 -0
@@ -40,6 +40,8 @@ struct irqaction {
 	const char *name;
 	void *dev_id;
 	struct irqaction *next;
+	int irq;
+	struct proc_dir_entry *dir;
 };
 
 extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs);
include/asm-i386/irq.h renamed from include/asm-i386/irq.h.orig +0 -3
@@ -21,9 +21,6 @@ static __inline__ int irq_canonicalize(i
 	return ((irq == 2) ? 9 : irq);
 }
 
-extern void disable_irq(unsigned int);
-extern void disable_irq_nosync(unsigned int);
-extern void enable_irq(unsigned int);
 extern void release_x86_irqs(struct task_struct *);
 extern int can_request_irq(unsigned int, unsigned long flags);
 
kernel/Makefile renamed from kernel/Makefile.orig +1 -0
@@ -12,6 +12,7 @@ obj-y     = sched.o fork.o exec_domain.o
 obj-$(CONFIG_FUTEX) += futex.o
 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
 obj-$(CONFIG_SMP) += cpu.o spinlock.o
+obj-$(CONFIG_GENERIC_HARDIRQS) += hardirq.o
 obj-$(CONFIG_UID16) += uid16.o
 obj-$(CONFIG_MODULES) += module.o
 obj-$(CONFIG_KALLSYMS) += kallsyms.o
kernel/hardirq.c renamed from kernel/hardirq.c.orig +529 -0

529 lines not on this page · raw message

#25 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 10 lines · Ingo Molnar
Quoted 3 lines · Ingo Molnar

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

i've attached generic-hardirqs-2.6.9-rc1-mm4.patch which is a merge against -mm4. x86 and x64 compiles & boots fine. Since there are zero changes to non-x86 architectures it should build fine on all platforms.

Looks good to me. I no one else beats me I'll look into converting ppc32/64 this weekend.

#26 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 10 lines · Christoph Hellwig
Quoted 7 lines
Quoted 3 lines

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

i've attached generic-hardirqs-2.6.9-rc1-mm4.patch which is a merge against -mm4. x86 and x64 compiles & boots fine. Since there are zero changes to non-x86 architectures it should build fine on all platforms.

Looks good to me. I no one else beats me I'll look into converting ppc32/64 this weekend.

you can find a pretty good approximation done by Scott Wood (and Andrey Panin?) in the ppc/ppc64 portion of the VP patches:

http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.9-rc1-bk12-S0

basically you only have to zap some of the irq-threading changes such as calls to redirect_hardirq(), do a s/generic_// and zap the PIC changes (these are done for redirection too). Scott has tested those changes so kernel/hardirq.c should work pretty well with ppc/ppc64.

Ingo

#27 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 7 lines · Ingo Molnar

you can find a pretty good approximation done by Scott Wood (and Andrey Panin?) in the ppc/ppc64 portion of the VP patches:
http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.9-rc1-bk12-S0
basically you only have to zap some of the irq-threading changes such as calls to redirect_hardirq(), do a s/generic_// and zap the PIC changes (these are done for redirection too). Scott has tested those changes so kernel/hardirq.c should work pretty well with ppc/ppc64.

By any chance can the generic code be made not to be reliant on irq_desc[] and/or irq_desc[] being an array?

-- wli

#28 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 11 lines · William Lee Irwin III
Quoted 7 lines · Ingo Molnar

you can find a pretty good approximation done by Scott Wood (and Andrey Panin?) in the ppc/ppc64 portion of the VP patches:
http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.9-rc1-bk12-S0
basically you only have to zap some of the irq-threading changes such as calls to redirect_hardirq(), do a s/generic_// and zap the PIC changes (these are done for redirection too). Scott has tested those changes so kernel/hardirq.c should work pretty well with ppc/ppc64.

By any chance can the generic code be made not to be reliant on irq_desc[] and/or irq_desc[] being an array?

I would say one step at a time.
First extract out the code that most arch's share already
only THEN start working on seeing if the few remaining ones can be moved in, and if other cleanups are appropriate

#29 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 2 lines · William Lee Irwin III
Quoted 2 lines

By any chance can the generic code be made not to be reliant on irq_desc[] and/or irq_desc[] being an array?

Quoted 4 lines · Arjan van de Ven

I would say one step at a time.
First extract out the code that most arch's share already
only THEN start working on seeing if the few remaining ones can be moved in, and if other cleanups are appropriate

I suppose that assumption can be swept for afterward.

-- wli

#30 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

In reply to Arjan van de Ven
Quoted 11 lines · Arjan van de Ven
Quoted 9 lines · William Lee Irwin III
Quoted 7 lines · Ingo Molnar

you can find a pretty good approximation done by Scott Wood (and Andrey Panin?) in the ppc/ppc64 portion of the VP patches:
http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.9-rc1-bk12-S0
basically you only have to zap some of the irq-threading changes such as calls to redirect_hardirq(), do a s/generic_// and zap the PIC changes (these are done for redirection too). Scott has tested those changes so kernel/hardirq.c should work pretty well with ppc/ppc64.

Quoted 7 lines
Quoted 2 lines

By any chance can the generic code be made not to be reliant on irq_desc[] and/or irq_desc[] being an array?

I would say one step at a time.
First extract out the code that most arch's share already
only THEN start working on seeing if the few remaining ones can be moved in, and if other cleanups are appropriate

If it uses irq_desc then ARM won't use it. irq_desc is part of the far-too-restrictive x86 IRQ handlign code which is unsuitable for ARM platforms.

Sorry, try again.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#31 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 3 lines · Russell King

If it uses irq_desc then ARM won't use it. irq_desc is part of the far-too-restrictive x86 IRQ handlign code which is unsuitable for ARM platforms.

What does ARM need that irq_desc doesn't provide, and which could not be added? IMHO, it'd be better to fix the generic code than maintain completely separate implementations.

-Scott

#32 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 8 lines · Scott Wood
Quoted 3 lines · Russell King

If it uses irq_desc then ARM won't use it. irq_desc is part of the far-too-restrictive x86 IRQ handlign code which is unsuitable for ARM platforms.

What does ARM need that irq_desc doesn't provide, and which could not be added? IMHO, it'd be better to fix the generic code than maintain completely separate implementations.

Unfortunately, to deal with this issue would mean breaking off from planned work, so I'm not going to be in a position to do an element by element comparison of the structures for some time.

Maybe I can look at it after the weekend though.

However, I think if you just compare:

linux/include/linux/irq.h
linux/include/asm-arm/mach/irq.h

you'll realise how inadequate the "generic" IRQ code is for ARM.

Note that IRQ handling on ARM is a multi-level affair where we have multiple levels of interrupt controllers which need to be traversed in software.

Signature · 4 lines
Russell King
 Linux kernel    2.6 ARM Linux   - http://www.arm.linux.org.uk/
 maintainer of:  2.6 PCMCIA      - http://pcmcia.arm.linux.org.uk/
                 2.6 Serial core
#33 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 5 lines · Russell King

you'll realise how inadequate the "generic" IRQ code is for ARM.

Note that IRQ handling on ARM is a multi-level affair where we have multiple levels of interrupt controllers which need to be traversed in software.

I still propose the plan of action that is to consolidate first all architectures that CAN share the x86 one, and THEN look at making that more generic. The reason is simple; right now there are 20-ish copies; after the initial consolidation there will be 4 or 5. Far easier to work on.

#34 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

In reply to Ingo Molnar
Quoted 10 lines · Ingo Molnar
Quoted 3 lines · Ingo Molnar

latest patch attached - this should compile on every architecture. It's basically what Christoph suggested first time around :-) Compiles/boots on x86. Any other observations?

i've attached generic-hardirqs-2.6.9-rc1-mm4.patch which is a merge against -mm4. x86 and x64 compiles & boots fine. Since there are zero changes to non-x86 architectures it should build fine on all platforms.

I've got this trace (on x86-64):

general protection fault: 0000 [1] PREEMPT
CPU 0
Modules linked in: usbserial parport_pc lp parport joydev sg st sd_mod sr_mod 
scsi_mod snd_seq_oss snd_seq_midi_evend
Pid: 694, comm: kjournald Not tainted 2.6.9-rc1-mm4
RIP: 0010:[<ffffffff802ac605>] 
<ffffffff802ac605>{__journal_clean_checkpoint_list+389}
RSP: 0018:000001001f589b08  EFLAGS: 00010202
RAX: 0000000000000000 RBX: 6b6b6b6b6b6b6b6b RCX: 0000000000000000
RDX: 0000010001b2c4d8 RSI: 000001001fd2e150 RDI: 000001001fbab628
RBP: 00000100110c0708 R08: 000001001fd2e050 R09: 00000100110c0708
R10: 0000000000000000 R11: 0000000000000000 R12: 00000100110c0708
R13: 000001000b4345c8 R14: 000000000000007f R15: 0000010001ae8d70
FS:  0000002a9afefa80(0000) GS:ffffffff805f3580(0000) knlGS:0000000000000000
CS:  0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 0000002a95654000 CR3: 0000000000101000 CR4: 00000000000006e0
Process kjournald (pid: 694, threadinfo 000001001f588000, task 
0000010001ad9270)
Stack: 000001001f589b48 000001001fd2bc58 0000010001b2c4d8 0000010001b2c4d8
       0000000000000001 0000000000000000 0000010001b2c4d8 000001000bc1f910
       0000000000000000 ffffffff802a9039
Call Trace:<ffffffff802a9039>{journal_commit_transaction+2329}
       <ffffffff8042f730>{thread_return+41} <ffffffff802b3465>{kjournald+725}
       <ffffffff8015ece0>{autoremove_wake_function+0} 
<ffffffff8015ece0>{autoremove_wake_function+0}
       <ffffffff802b3a30>{commit_timeout+0} <ffffffff80111afb>{child_rip+8}
       <ffffffff802b3190>{kjournald+0} <ffffffff80111af3>{child_rip+0}
Code: 48 8b 43 48 49 89 45 48 48 8b 54 24 10 4c 8b aa b8 00 00 00

RIP <ffffffff802ac605>{__journal_clean_checkpoint_list+389} RSP <000001001f589b08>

with the patch applied. I don't know if the patch is the reason, but I haven't got anything like that without it (please let me know if you need .config etc.).

Greets,
RJW

Signature · 3 lines
- Would you tell me, please, which way I ought to go from here?
- That depends a good deal on where you want to get to.
		-- Lewis Carroll "Alice's Adventures in Wonderland"
#35 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 10 lines · Rafael J. Wysocki

I've got this trace (on x86-64):

 general protection fault: 0000 [1] PREEMPT
 CPU 0
 Modules linked in: usbserial parport_pc lp parport joydev sg st sd_mod sr_mod 
 scsi_mod snd_seq_oss snd_seq_midi_evend
 Pid: 694, comm: kjournald Not tainted 2.6.9-rc1-mm4
 RIP: 0010:[<ffffffff802ac605>] 
 <ffffffff802ac605>{__journal_clean_checkpoint_list+389}

You should revert ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.9-rc1/2.6.9-rc1-mm4/broken-out/journal_clean_checkpoint_list-latency-fix.patch
- it seems to be sick.

#36 lore raw

Re: [patch] generic-hardirqs-2.6.9-rc1-mm4.patch

Quoted 12 lines · Andrew Morton
Quoted 10 lines · Rafael J. Wysocki

I've got this trace (on x86-64):

 general protection fault: 0000 [1] PREEMPT
 CPU 0
 Modules linked in: usbserial parport_pc lp parport joydev sg st sd_mod sr_mod 
 scsi_mod snd_seq_oss snd_seq_midi_evend
 Pid: 694, comm: kjournald Not tainted 2.6.9-rc1-mm4
 RIP: 0010:[<ffffffff802ac605>] 
 <ffffffff802ac605>{__journal_clean_checkpoint_list+389}
Quoted 3 lines

You should revert ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.9-rc1/2.6.9-rc1-mm4/broken-out/journal_clean_checkpoint_list-latency-fix.patch
- it seems to be sick.

the variant in the VP patch (for this latency) is pretty stable. Will post splitups later.

Ingo

#37 lore raw
In reply to Ingo Molnar
Quoted 2 lines

wrt. unused generic functions - why dont we drop them link-time?

actually if nothing uses ANY function of a .o file then yes the entire .o gets dropped.

(we should make the kernel use -ffunction-sections some day to make it on a per function instead of on a per .o file basis)