linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] irq_enter/irq_exit consolidation
@ 2004-09-12 11:25 Christoph Hellwig
  2004-09-12 11:44 ` Russell King
  0 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2004-09-12 11:25 UTC (permalink / raw)
  To: akpm; +Cc: spyro, rmk, linux390, linux-kernel

Move irq_enter/irq_exit from <asm/hardirq.h> to <linux/hardirq.h>.
There some fishy things going on with the do_softirq invokation on
arm, arm26 and s390.

arm calls __do_softirq directly without local irq disabling which looks
like a real bug to me.

arm26 has a duplicate __do_softirq entry point (which makes me wonder
whether it still compiles with any 2.6 tree since a few month)

s390 has an assembly wrapper around do_softirq.

I've extended the invoke_softirq mechanism used by s390 (also called
by ksoftirqd) to the two arm variants, but the right thing to do is
probably to use the normal do_softirq call in arm and set
__ARCH_HAS_DO_SOFTIRQ + providing a per-arch do_softirq for all callers
for s390 and maybe arm26.

--- 1.20/arch/ia64/kernel/irq_ia64.c	2004-05-15 04:00:12 +02:00
+++ edited/arch/ia64/kernel/irq_ia64.c	2004-09-11 21:06:21 +02:00
@@ -59,21 +59,6 @@
 };
 EXPORT_SYMBOL(isa_irq_to_vector_map);
 
-static inline void
-irq_enter (void)
-{
-	preempt_count() += HARDIRQ_OFFSET;
-}
-
-static inline void
-irq_exit (void)
-{
-	preempt_count() -= IRQ_EXIT_OFFSET;
-	if (!in_interrupt() && local_softirq_pending())
-		do_softirq();
-	preempt_enable_no_resched();
-}
-
 int
 assign_irq_vector (int irq)
 {
===== include/asm-alpha/hardirq.h 1.9 vs edited =====
--- 1.9/include/asm-alpha/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-alpha/hardirq.h	2004-09-11 21:14:41 +02:00
@@ -50,14 +50,4 @@
 #error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()						\
-do {								\
-		preempt_count() -= IRQ_EXIT_OFFSET;		\
-		if (!in_interrupt() &&				\
-		    softirq_pending(smp_processor_id()))	\
-			do_softirq();				\
-		preempt_enable_no_resched();			\
-} while (0)
-
 #endif /* _ALPHA_HARDIRQ_H */
===== include/asm-arm/hardirq.h 1.13 vs edited =====
--- 1.13/include/asm-arm/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-arm/hardirq.h	2004-09-11 21:09:10 +02:00
@@ -50,18 +50,7 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-
-#ifndef CONFIG_SMP
 extern asmlinkage void __do_softirq(void);
-
-#define irq_exit()							\
-	do {								\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && local_softirq_pending())		\
-			__do_softirq();					\
-		preempt_enable_no_resched();				\
-	} while (0)
-#endif
+#define invoke_softirq()	__do_softirq()
 
 #endif /* __ASM_HARDIRQ_H */
--- 1.3/include/asm-arm26/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-arm26/hardirq.h	2004-09-11 21:09:41 +02:00
@@ -41,17 +41,6 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-
-#ifndef CONFIG_SMP
-#define irq_exit()							\
-	do {								\
-		preempt_count() -= HARDIRQ_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
-		preempt_enable_no_resched();				\
-	} while (0)
-
-#endif
+#define invoke_softirq()	__asm__("bl%? __do_softirq": : : "lr")
 
 #endif /* __ASM_HARDIRQ_H */
===== include/asm-cris/hardirq.h 1.4 vs edited =====
--- 1.4/include/asm-cris/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-cris/hardirq.h	2004-09-11 21:15:19 +02:00
@@ -49,13 +49,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
===== include/asm-h8300/hardirq.h 1.5 vs edited =====
--- 1.5/include/asm-h8300/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-h8300/hardirq.h	2004-09-11 21:09:54 +02:00
@@ -47,13 +47,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif
===== include/asm-i386/hardirq.h 1.22 vs edited =====
--- 1.22/include/asm-i386/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-i386/hardirq.h	2004-09-11 21:25:23 +02:00
@@ -46,16 +46,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define nmi_enter()		(irq_enter())
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
===== include/asm-m68k/hardirq.h 1.7 vs edited =====
--- 1.7/include/asm-m68k/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-m68k/hardirq.h	2004-09-11 21:10:09 +02:00
@@ -44,13 +44,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif
===== include/asm-m68knommu/hardirq.h 1.4 vs edited =====
--- 1.4/include/asm-m68knommu/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-m68knommu/hardirq.h	2004-09-11 21:10:17 +02:00
@@ -45,13 +45,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __M68K_HARDIRQ_H */
===== include/asm-mips/hardirq.h 1.9 vs edited =====
--- 1.9/include/asm-mips/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-mips/hardirq.h	2004-09-11 21:10:24 +02:00
@@ -52,13 +52,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()                                                     \
-do {                                                                   \
-	preempt_count() -= IRQ_EXIT_OFFSET;                     \
-	if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-		do_softirq();                                   \
-	preempt_enable_no_resched();                            \
-} while (0)
-
 #endif /* _ASM_HARDIRQ_H */
===== include/asm-parisc/hardirq.h 1.4 vs edited =====
--- 1.4/include/asm-parisc/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-parisc/hardirq.h	2004-09-11 21:10:30 +02:00
@@ -59,13 +59,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()								\
-do {										\
-		preempt_count() -= IRQ_EXIT_OFFSET;				\
-		if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-			do_softirq();						\
-		preempt_enable_no_resched();					\
-} while (0)
-
 #endif /* _PARISC_HARDIRQ_H */
===== include/asm-ppc/hardirq.h 1.25 vs edited =====
--- 1.25/include/asm-ppc/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-ppc/hardirq.h	2004-09-11 21:11:01 +02:00
@@ -53,14 +53,5 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-	preempt_count() -= IRQ_EXIT_OFFSET;				\
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-		do_softirq();						\
-	preempt_enable_no_resched();					\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
 #endif /* __KERNEL__ */
===== include/asm-ppc64/hardirq.h 1.14 vs edited =====
--- 1.14/include/asm-ppc64/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-ppc64/hardirq.h	2004-09-11 21:11:12 +02:00
@@ -51,13 +51,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
===== include/asm-s390/hardirq.h 1.14 vs edited =====
--- 1.14/include/asm-s390/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-s390/hardirq.h	2004-09-11 21:11:28 +02:00
@@ -66,17 +66,4 @@
 
 #define invoke_softirq() do_call_softirq()
 
-#define irq_enter()							\
-do {									\
-	(preempt_count() += HARDIRQ_OFFSET);				\
-} while(0)
-#define irq_exit()							\
-do {									\
-	preempt_count() -= IRQ_EXIT_OFFSET;				\
-	if (!in_interrupt() && local_softirq_pending())			\
-		/* Use the async. stack for softirq */			\
-		do_call_softirq();					\
-	preempt_enable_no_resched();					\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
===== include/asm-sh/hardirq.h 1.7 vs edited =====
--- 1.7/include/asm-sh/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-sh/hardirq.h	2004-09-11 21:25:35 +02:00
@@ -44,16 +44,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define nmi_enter()		(irq_enter())
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_SH_HARDIRQ_H */
===== include/asm-sparc/hardirq.h 1.15 vs edited =====
--- 1.15/include/asm-sparc/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-sparc/hardirq.h	2004-09-11 21:12:26 +02:00
@@ -42,13 +42,4 @@
 #define SOFTIRQ_SHIFT   (PREEMPT_SHIFT + PREEMPT_BITS)
 #define HARDIRQ_SHIFT   (SOFTIRQ_SHIFT + SOFTIRQ_BITS)
 
-#define irq_enter()             (preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()                                                      \
-do {                                                                    \
-                preempt_count() -= IRQ_EXIT_OFFSET;                     \
-                if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-                        do_softirq();                                   \
-                preempt_enable_no_resched();                            \
-} while (0)
-
 #endif /* __SPARC_HARDIRQ_H */
===== include/asm-sparc64/hardirq.h 1.19 vs edited =====
--- 1.19/include/asm-sparc64/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-sparc64/hardirq.h	2004-09-11 21:12:43 +02:00
@@ -41,13 +41,4 @@
 #define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
 #define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* !(__SPARC64_HARDIRQ_H) */
===== include/asm-v850/hardirq.h 1.5 vs edited =====
--- 1.5/include/asm-v850/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-v850/hardirq.h	2004-09-11 21:13:01 +02:00
@@ -45,13 +45,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							      \
-do {									      \
-	preempt_count() -= IRQ_EXIT_OFFSET;				      \
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	      \
-		do_softirq();						      \
-	preempt_enable_no_resched();					      \
-} while (0)
-
 #endif /* __V850_HARDIRQ_H__ */
===== include/asm-x86_64/hardirq.h 1.7 vs edited =====
--- 1.7/include/asm-x86_64/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/asm-x86_64/hardirq.h	2004-09-11 21:26:04 +02:00
@@ -46,16 +46,4 @@
 # error HARDIRQ_BITS is too low!
 #endif
 
-#define nmi_enter()		(irq_enter())
-#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
-
-#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
-} while (0)
-
 #endif /* __ASM_HARDIRQ_H */
===== include/linux/hardirq.h 1.1 vs edited =====
--- 1.1/include/linux/hardirq.h	2004-09-08 08:32:57 +02:00
+++ edited/include/linux/hardirq.h	2004-09-11 21:26:28 +02:00
@@ -41,6 +36,22 @@
 # define preemptible()	0
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
+
+#ifndef invoke_softirq
+#define invoke_softirq() do_softirq()
+#endif
+
+#define irq_enter()		(preempt_count() += HARDIRQ_OFFSET)
+#define irq_exit()						\
+do {								\
+	preempt_count() -= IRQ_EXIT_OFFSET;			\
+	if (!in_interrupt() && local_softirq_pending())		\
+		invoke_softirq();				\
+	preempt_enable_no_resched();				\
+} while (0)
+
+#define nmi_enter()		(preempt_count() += HARDIRQ_OFFSET)
+#define nmi_exit()		(preempt_count() -= HARDIRQ_OFFSET)
 
 #ifdef CONFIG_SMP
 extern void synchronize_irq(unsigned int irq);
===== include/linux/interrupt.h 1.30 vs edited =====
--- 1.30/include/linux/interrupt.h	2004-09-08 08:32:57 +02:00
+++ edited/include/linux/interrupt.h	2004-09-11 21:24:23 +02:00
@@ -100,11 +100,6 @@
 extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
 extern void FASTCALL(raise_softirq(unsigned int nr));
 
-#ifndef invoke_softirq
-#define invoke_softirq() do_softirq()
-#endif
-
-
 /* Tasklets --- multithreaded analogue of BHs.
 
    Main feature differing them of generic softirqs: tasklet

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

* Re: [PATCH] irq_enter/irq_exit consolidation
  2004-09-12 11:25 [PATCH] irq_enter/irq_exit consolidation Christoph Hellwig
@ 2004-09-12 11:44 ` Russell King
  2004-09-12 22:57   ` David S. Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Russell King @ 2004-09-12 11:44 UTC (permalink / raw)
  To: Christoph Hellwig, akpm, spyro, linux390, linux-kernel

On Sun, Sep 12, 2004 at 01:25:54PM +0200, Christoph Hellwig wrote:
> Move irq_enter/irq_exit from <asm/hardirq.h> to <linux/hardirq.h>.
> There some fishy things going on with the do_softirq invokation on
> arm, arm26 and s390.
> 
> arm calls __do_softirq directly without local irq disabling which looks
> like a real bug to me.

The ARM interrupt subsystem guarantees that local IRQs are disabled
prior to irq_exit() being invoked.  This is a must for reasons other
than softirq semantics - hardware IRQ controllers may require a
nonatomic read-modify-write to update their IRQ masking state.

This guarantee must also exist on every other architecture, otherwise:

> ===== include/linux/hardirq.h 1.1 vs edited =====
> --- 1.1/include/linux/hardirq.h	2004-09-08 08:32:57 +02:00
> +++ edited/include/linux/hardirq.h	2004-09-11 21:26:28 +02:00
> +#define irq_exit()						\
> +do {								\
> +	preempt_count() -= IRQ_EXIT_OFFSET;			\

would be buggy - it's an inherently non-atomic operation.  Not only that
but the behaviour of nested interrupts would change depending on whether
they interrupted before or after preempt count has been updated.

So maybe every other architecture except ARM is buggy? 8)

-- 
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

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

* Re: [PATCH] irq_enter/irq_exit consolidation
  2004-09-12 11:44 ` Russell King
@ 2004-09-12 22:57   ` David S. Miller
  2004-09-13  8:10     ` Russell King
  0 siblings, 1 reply; 6+ messages in thread
From: David S. Miller @ 2004-09-12 22:57 UTC (permalink / raw)
  To: Russell King; +Cc: hch, akpm, spyro, linux390, linux-kernel

On Sun, 12 Sep 2004 12:44:48 +0100
Russell King <rmk+lkml@arm.linux.org.uk> wrote:

> This guarantee must also exist on every other architecture, otherwise:
> 
> > ===== include/linux/hardirq.h 1.1 vs edited =====
> > --- 1.1/include/linux/hardirq.h	2004-09-08 08:32:57 +02:00
> > +++ edited/include/linux/hardirq.h	2004-09-11 21:26:28 +02:00
> > +#define irq_exit()						\
> > +do {								\
> > +	preempt_count() -= IRQ_EXIT_OFFSET;			\
> 
> would be buggy - it's an inherently non-atomic operation.

It works out actually, if we take an interrupt in the middle
of the operation, that's fine because the preemption count
will be precisely the same as we first read it by the time
we return from that interrupt, work out some example cases
as I think that makes it easier to understand.

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

* Re: [PATCH] irq_enter/irq_exit consolidation
  2004-09-12 22:57   ` David S. Miller
@ 2004-09-13  8:10     ` Russell King
  0 siblings, 0 replies; 6+ messages in thread
From: Russell King @ 2004-09-13  8:10 UTC (permalink / raw)
  To: David S. Miller; +Cc: akpm, spyro, linux390, linux-kernel

On Sun, Sep 12, 2004 at 03:57:20PM -0700, David S. Miller wrote:
> On Sun, 12 Sep 2004 12:44:48 +0100
> Russell King <rmk+lkml@arm.linux.org.uk> wrote:
> 
> > This guarantee must also exist on every other architecture, otherwise:
> > 
> > > ===== include/linux/hardirq.h 1.1 vs edited =====
> > > --- 1.1/include/linux/hardirq.h	2004-09-08 08:32:57 +02:00
> > > +++ edited/include/linux/hardirq.h	2004-09-11 21:26:28 +02:00
> > > +#define irq_exit()						\
> > > +do {								\
> > > +	preempt_count() -= IRQ_EXIT_OFFSET;			\
> > 
> > would be buggy - it's an inherently non-atomic operation.
> 
> It works out actually, if we take an interrupt in the middle
> of the operation, that's fine because the preemption count
> will be precisely the same as we first read it by the time
> we return from that interrupt, work out some example cases
> as I think that makes it easier to understand.

I realise that, and it's precisely why I wrote the sentence following
the one you quoted above.

However, ARM ain't buggy whatever.

-- 
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

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

* Re: [PATCH] irq_enter/irq_exit consolidation
  2004-09-13 13:02 Martin Schwidefsky
@ 2004-09-14 18:31 ` Christoph Hellwig
  0 siblings, 0 replies; 6+ messages in thread
From: Christoph Hellwig @ 2004-09-14 18:31 UTC (permalink / raw)
  To: Martin Schwidefsky; +Cc: hch, akpm, spyro, rmk, linux390, linux-kernel

On Mon, Sep 13, 2004 at 03:02:40PM +0200, Martin Schwidefsky wrote:
> Hi Christoph,
> 
> > s390 has an assembly wrapper around do_softirq.
> > 
> > I've extended the invoke_softirq mechanism used by s390 (also called
> > by ksoftirqd) to the two arm variants, but the right thing to do is
> > probably to use the normal do_softirq call in arm and set
> > __ARCH_HAS_DO_SOFTIRQ + providing a per-arch do_softirq for all callers
> > for s390 and maybe arm26.
> 
> do_call_softirq switches to the asynchronous interrupt stack,
> just what i386 does now as well. Trouble is that on s390 it is
> non-trivial to do the switch in C with inline assembly. We need
> a bit of assembly. But we could get rid of invoke_softirq, define
> __ARCH_HAS_DO_SOFTIRQ and use do_softirq to call the assembly
> wrapper.

Well, the question is do you want the direct do_softirq invocations from
the networking code use the separate stack or not?  If not the current
code is fine.  If yes you should sent the patch to Andrew.


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

* Re: [PATCH] irq_enter/irq_exit consolidation
@ 2004-09-13 13:02 Martin Schwidefsky
  2004-09-14 18:31 ` Christoph Hellwig
  0 siblings, 1 reply; 6+ messages in thread
From: Martin Schwidefsky @ 2004-09-13 13:02 UTC (permalink / raw)
  To: hch; +Cc: akpm, spyro, rmk, linux390, linux-kernel

Hi Christoph,

> s390 has an assembly wrapper around do_softirq.
> 
> I've extended the invoke_softirq mechanism used by s390 (also called
> by ksoftirqd) to the two arm variants, but the right thing to do is
> probably to use the normal do_softirq call in arm and set
> __ARCH_HAS_DO_SOFTIRQ + providing a per-arch do_softirq for all callers
> for s390 and maybe arm26.

do_call_softirq switches to the asynchronous interrupt stack,
just what i386 does now as well. Trouble is that on s390 it is
non-trivial to do the switch in C with inline assembly. We need
a bit of assembly. But we could get rid of invoke_softirq, define
__ARCH_HAS_DO_SOFTIRQ and use do_softirq to call the assembly
wrapper.

blue skies,
  Martin.

---

From: Martin Schwidefsky <schwidefsky@de.ibm.com>

Replace invoke_softirq mechanism by __ARCH_HAS_DO_SOFTIRQ
mechanism for s390.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

diffstat:
 arch/s390/kernel/entry.S      |    4 +---
 arch/s390/kernel/entry64.S    |    4 +---
 arch/s390/kernel/s390_ext.c   |    1 +
 arch/s390/kernel/s390_ksyms.c |    1 -
 arch/s390/kernel/setup.c      |   20 ++++++++++++++++++++
 include/asm-s390/hardirq.h    |    3 +--
 6 files changed, 24 insertions(+), 9 deletions(-)

diff -urN linux-2.6/arch/s390/kernel/entry64.S linux-2.6-s390/arch/s390/kernel/entry64.S
--- linux-2.6/arch/s390/kernel/entry64.S	2004-09-13 14:30:42.000000000 +0200
+++ linux-2.6-s390/arch/s390/kernel/entry64.S	2004-09-13 14:21:29.000000000 +0200
@@ -153,7 +153,6 @@
  */
 	.global do_call_softirq
 do_call_softirq:
-	stnsm	__SF_EMPTY(%r15),0xfc
 	stmg	%r12,%r15,__SF_GPRS(%r15)
 	lgr	%r12,%r15
 	lg	%r0,__LC_ASYNC_STACK
@@ -163,9 +162,8 @@
 	lg	%r15,__LC_ASYNC_STACK
 0:	aghi	%r15,-STACK_FRAME_OVERHEAD
 	stg	%r12,__SF_BACKCHAIN(%r15)	# store back chain
-	brasl	%r14,do_softirq
+	brasl	%r14,__do_softirq
 	lmg	%r12,%r15,__SF_GPRS(%r12)
-	ssm	__SF_EMPTY(%r15)
 	br	%r14
 
 __critical_start:
diff -urN linux-2.6/arch/s390/kernel/entry.S linux-2.6-s390/arch/s390/kernel/entry.S
--- linux-2.6/arch/s390/kernel/entry.S	2004-09-13 14:30:42.000000000 +0200
+++ linux-2.6-s390/arch/s390/kernel/entry.S	2004-09-13 14:21:29.000000000 +0200
@@ -156,7 +156,6 @@
  */
 	.global do_call_softirq
 do_call_softirq:
-	stnsm	__SF_EMPTY(%r15),0xfc
 	stm	%r12,%r15,__SF_GPRS(%r15)
 	lr	%r12,%r15
         basr    %r13,0
@@ -171,7 +170,6 @@
 	l	%r1,.Ldo_softirq-do_call_base(%r13)
 	basr	%r14,%r1
 	lm	%r12,%r15,__SF_GPRS(%r12)
-	ssm	__SF_EMPTY(%r15)
 	br	%r14
 
 __critical_start:
@@ -733,7 +731,7 @@
 .Ldo_IRQ:      .long  do_IRQ
 .Ldo_extint:   .long  do_extint
 .Ldo_signal:   .long  do_signal
-.Ldo_softirq:  .long  do_softirq
+.Ldo_softirq:  .long  __do_softirq
 .Lhandle_per:  .long  do_single_step
 .Ljump_table:  .long  pgm_check_table
 .Lschedule:    .long  schedule
diff -urN linux-2.6/arch/s390/kernel/s390_ext.c linux-2.6-s390/arch/s390/kernel/s390_ext.c
--- linux-2.6/arch/s390/kernel/s390_ext.c	2004-08-14 12:55:32.000000000 +0200
+++ linux-2.6-s390/arch/s390/kernel/s390_ext.c	2004-09-13 14:34:14.000000000 +0200
@@ -12,6 +12,7 @@
 #include <linux/slab.h>
 #include <linux/errno.h>
 #include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
 
 #include <asm/lowcore.h>
 #include <asm/s390_ext.h>
diff -urN linux-2.6/arch/s390/kernel/s390_ksyms.c linux-2.6-s390/arch/s390/kernel/s390_ksyms.c
--- linux-2.6/arch/s390/kernel/s390_ksyms.c	2004-09-13 14:03:55.000000000 +0200
+++ linux-2.6-s390/arch/s390/kernel/s390_ksyms.c	2004-09-13 14:33:34.000000000 +0200
@@ -61,6 +61,5 @@
 EXPORT_SYMBOL(console_mode);
 EXPORT_SYMBOL(console_devno);
 EXPORT_SYMBOL(console_irq);
-EXPORT_SYMBOL(do_call_softirq);
 EXPORT_SYMBOL(sys_wait4);
 EXPORT_SYMBOL(cpcmd);
diff -urN linux-2.6/arch/s390/kernel/setup.c linux-2.6-s390/arch/s390/kernel/setup.c
--- linux-2.6/arch/s390/kernel/setup.c	2004-09-13 14:30:42.000000000 +0200
+++ linux-2.6-s390/arch/s390/kernel/setup.c	2004-09-13 14:31:53.000000000 +0200
@@ -654,3 +654,23 @@
 {
 	/* nothing... */
 }
+
+extern void do_call_softirq(void);
+
+asmlinkage void do_softirq(void)
+{
+	unsigned long flags;
+
+	if (in_interrupt())
+		return;
+
+	local_irq_save(flags);
+
+	if (local_softirq_pending())
+		/* Call __do_softirq on asynchromous interrupt stack. */
+		do_call_softirq();
+
+	local_irq_restore(flags);
+}
+
+EXPORT_SYMBOL(do_softirq);
diff -urN linux-2.6/include/asm-s390/hardirq.h linux-2.6-s390/include/asm-s390/hardirq.h
--- linux-2.6/include/asm-s390/hardirq.h	2004-09-13 14:30:42.000000000 +0200
+++ linux-2.6-s390/include/asm-s390/hardirq.h	2004-09-13 14:31:42.000000000 +0200
@@ -61,9 +61,8 @@
 #define SOFTIRQ_SHIFT	(PREEMPT_SHIFT + PREEMPT_BITS)
 #define HARDIRQ_SHIFT	(SOFTIRQ_SHIFT + SOFTIRQ_BITS)
 
-extern void do_call_softirq(void);
 extern void account_ticks(struct pt_regs *);
 
-#define invoke_softirq() do_call_softirq()
+#define __ARCH_HAS_DO_SOFTIRQ
 
 #endif /* __ASM_HARDIRQ_H */

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

end of thread, other threads:[~2004-09-14 18:32 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-09-12 11:25 [PATCH] irq_enter/irq_exit consolidation Christoph Hellwig
2004-09-12 11:44 ` Russell King
2004-09-12 22:57   ` David S. Miller
2004-09-13  8:10     ` Russell King
2004-09-13 13:02 Martin Schwidefsky
2004-09-14 18:31 ` Christoph Hellwig

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).