Skip to contentSkip to conversation

softirq_pending()

PATCH In review Christoph Hellwig 3 participants 4 messages Sep 23, 2003 – Sep 24, 2003

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 softirq_pending()

x86-64 currently ignores the cpu argument to softirq_pending() and always uses smp_processor_id(). And indeed that's the only possible argument. So consolidate the old softirq_pending() and local_softirq_pending() into a single one.

arch/cris/kernel/irq.c +1 -1
@@ -153,7 +153,7 @@
         }
         irq_exit();
 
-	if (softirq_pending(cpu))
+	if (softirq_pending())
                 do_softirq();
 
         /* unmasking and bottom half handling is done magically for us. */
arch/ia64/kernel/irq_ia64.c +1 -1
@@ -141,7 +141,7 @@
 	 * handler needs to be able to wait for further keyboard interrupts, which can't
 	 * come through until ia64_eoi() has been done.
 	 */
-	if (local_softirq_pending())
+	if (softirq_pending())
 		do_softirq();
 }
 
arch/sparc/kernel/irq.c +1 -1
@@ -452,7 +452,7 @@
 	irq_exit();
 	enable_pil_irq(irq);
 	// XXX Eek, it's totally changed with preempt_count() and such
-	// if (softirq_pending(cpu))
+	// if (softirq_pending())
 	//	do_softirq();
 }
 #endif
include/asm-alpha/hardirq.h +1 -2
@@ -89,8 +89,7 @@
 #define irq_exit()						\
 do {								\
 		preempt_count() -= IRQ_EXIT_OFFSET;		\
-		if (!in_interrupt() &&				\
-		    softirq_pending(smp_processor_id()))	\
+		if (!in_interrupt() &&	softirq_pending())	\
 			do_softirq();				\
 		preempt_enable_no_resched();			\
 } while (0)
include/asm-arm/hardirq.h +1 -1
@@ -83,7 +83,7 @@
 #define irq_exit()							\
 	do {								\
 		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+		if (!in_interrupt() && softirq_pending())		\
 			__asm__("bl	__do_softirq": : : "lr", "cc");/* out of line */\
 		preempt_enable_no_resched();				\
 	} while (0)
include/asm-arm/mach/irq.h +1 -1
@@ -109,7 +109,7 @@
 	desc->handle(irq, desc, regs);
 	spin_unlock(&irq_controller_lock);
 
-	if (softirq_pending(smp_processor_id()))
+	if (softirq_pending())
 		do_softirq();
 }
 #endif
include/asm-arm26/hardirq.h +1 -1
@@ -80,7 +80,7 @@
 #define irq_exit()							\
 	do {								\
 		preempt_count() -= HARDIRQ_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+		if (!in_interrupt() && softirq_pending())		\
 			__asm__("bl%? __do_softirq": : : "lr");/* out of line */\
 		preempt_enable_no_resched();				\
 	} while (0)
include/asm-arm26/irqchip.h +1 -1
@@ -97,7 +97,7 @@
 	desc->handle(irq, desc, regs);
 	spin_unlock(&irq_controller_lock);
 
-	if (softirq_pending(smp_processor_id()))
+	if (softirq_pending())
 		do_softirq();
 }
 #endif
include/asm-cris/hardirq.h +1 -1
@@ -87,7 +87,7 @@
 #define irq_exit()							\
 do {									\
 		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+		if (!in_interrupt() && softirq_pending())		\
 			do_softirq();					\
 		preempt_enable_no_resched();				\
 } while (0)
include/asm-h8300/hardirq.h +6 -6
@@ -82,12 +82,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-i386/hardirq.h +6 -6
@@ -84,12 +84,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-ia64/hardirq.h +2 -3
@@ -19,12 +19,11 @@
 
 #define __ARCH_IRQ_STAT	1
 
-#define softirq_pending(cpu)		(cpu_data(cpu)->softirq_pending)
 #define syscall_count(cpu)		/* unused on IA-64 */
 #define ksoftirqd_task(cpu)		(cpu_data(cpu)->ksoftirqd)
 #define nmi_count(cpu)			0
 
-#define local_softirq_pending()		(local_cpu_data->softirq_pending)
+#define softirq_pending()		(local_cpu_data->softirq_pending)
 #define local_syscall_count()		/* unused on IA-64 */
 #define local_ksoftirqd_task()		(local_cpu_data->ksoftirqd)
 #define local_nmi_count()		0
@@ -100,7 +99,7 @@
 #define irq_exit()						\
 do {								\
 		preempt_count() -= IRQ_EXIT_OFFSET;		\
-		if (!in_interrupt() && local_softirq_pending())	\
+		if (!in_interrupt() && softirq_pending())	\
 			do_softirq();				\
 		preempt_enable_no_resched();			\
 } while (0)
include/asm-m68k/hardirq.h +1 -1
@@ -81,7 +81,7 @@
 #define irq_exit()							\
 do {									\
 		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
+		if (!in_interrupt() && softirq_pending())		\
 			do_softirq();					\
 		preempt_enable_no_resched();				\
 } while (0)
include/asm-m68knommu/hardirq.h +6 -6
@@ -86,12 +86,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-mips/hardirq.h +6 -6
@@ -86,12 +86,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()                                                     \
-do {                                                                   \
-	preempt_count() -= IRQ_EXIT_OFFSET;                     \
-	if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-		do_softirq();                                   \
-	preempt_enable_no_resched();                            \
+#define irq_exit()					\
+do {							\
+	preempt_count() -= IRQ_EXIT_OFFSET;		\
+	if (!in_interrupt() && softirq_pending())	\
+		do_softirq();				\
+	preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-parisc/hardirq.h +6 -6
@@ -96,12 +96,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()								\
-do {										\
-		preempt_count() -= IRQ_EXIT_OFFSET;				\
-		if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-			do_softirq();						\
-		preempt_enable_no_resched();					\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifdef CONFIG_SMP
include/asm-ppc/hardirq.h +6 -6
@@ -88,12 +88,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-	preempt_count() -= IRQ_EXIT_OFFSET;				\
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-		do_softirq();						\
-	preempt_enable_no_resched();					\
+#define irq_exit()					\
+do {							\
+	preempt_count() -= IRQ_EXIT_OFFSET;		\
+	if (!in_interrupt() && softirq_pending())	\
+		do_softirq();				\
+	preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-ppc64/hardirq.h +6 -6
@@ -89,12 +89,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-s390/hardirq.h +7 -7
@@ -90,13 +90,13 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							\
-do {									\
-	preempt_count() -= IRQ_EXIT_OFFSET;				\
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	\
-		/* Use the async. stack for softirq */			\
-		do_call_softirq();					\
-	preempt_enable_no_resched();					\
+#define irq_exit()					\
+do {							\
+	preempt_count() -= IRQ_EXIT_OFFSET;		\
+	if (!in_interrupt() && softirq_pending())	\
+		/* Use the async. stack for softirq */	\
+		do_call_softirq();			\
+	preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-sh/hardirq.h +6 -6
@@ -83,12 +83,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-sparc/hardirq.h +6 -6
@@ -96,12 +96,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()                                                      \
-do {                                                                    \
-                preempt_count() -= IRQ_EXIT_OFFSET;                     \
-                if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-                        do_softirq();                                   \
-                preempt_enable_no_resched();                            \
+#define irq_exit()						\
+do {								\
+                preempt_count() -= IRQ_EXIT_OFFSET;		\
+                if (!in_interrupt() && softirq_pending())	\
+                        do_softirq();				\
+                preempt_enable_no_resched();			\
 } while (0)
 
 #else
include/asm-sparc64/hardirq.h +6 -6
@@ -85,12 +85,12 @@
 # define in_atomic()	(preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-v850/hardirq.h +6 -6
@@ -80,12 +80,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							      \
-do {									      \
-	preempt_count() -= IRQ_EXIT_OFFSET;				      \
-	if (!in_interrupt() && softirq_pending(smp_processor_id()))	      \
-		do_softirq();						      \
-	preempt_enable_no_resched();					      \
+#define irq_exit()					\
+do {							\
+	preempt_count() -= IRQ_EXIT_OFFSET;		\
+	if (!in_interrupt() && softirq_pending())	\
+		do_softirq();				\
+	preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/asm-x86_64/hardirq.h +6 -6
@@ -84,12 +84,12 @@
 # define in_atomic()   (preempt_count() != 0)
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()						\
+do {								\
+		preempt_count() -= IRQ_EXIT_OFFSET;		\
+		if (!in_interrupt() && softirq_pending())	\
+			do_softirq();				\
+		preempt_enable_no_resched();			\
 } while (0)
 
 #ifndef CONFIG_SMP
include/linux/interrupt.h +1 -1
@@ -95,7 +95,7 @@
 asmlinkage void do_softirq(void);
 extern void open_softirq(int nr, void (*action)(struct softirq_action*), void *data);
 extern void softirq_init(void);
-#define __raise_softirq_irqoff(nr) do { local_softirq_pending() |= 1UL << (nr); } while (0)
+#define __raise_softirq_irqoff(nr) do { softirq_pending() |= 1UL << (nr); } while (0)
 extern void FASTCALL(raise_softirq_irqoff(unsigned int nr));
 extern void FASTCALL(raise_softirq(unsigned int nr));
 
include/linux/irq_cpustat.h +1 -2
@@ -27,8 +27,7 @@
 #endif
 
   /* arch independent irq_stat fields */
-#define softirq_pending(cpu)	__IRQ_STAT((cpu), __softirq_pending)
-#define local_softirq_pending()	softirq_pending(smp_processor_id())
+#define softirq_pending()	__IRQ_STAT(smp_processor_id(), __softirq_pending)
 
   /* arch dependent irq_stat fields */
 #define nmi_count(cpu)		__IRQ_STAT((cpu), __nmi_count)	/* i386 */
include/linux/netdevice.h +1 -1
@@ -657,7 +657,7 @@
 static inline int netif_rx_ni(struct sk_buff *skb)
 {
        int err = netif_rx(skb);
-       if (softirq_pending(smp_processor_id()))
+       if (softirq_pending())
                do_softirq();
        return err;
 }
kernel/softirq.c +6 -7
@@ -68,8 +68,7 @@
 
 	local_irq_save(flags);
 
-	pending = local_softirq_pending();
-
+	pending = softirq_pending();
 	if (pending) {
 		struct softirq_action *h;
 
@@ -77,7 +76,7 @@
 		local_bh_disable();
 restart:
 		/* Reset the pending bitmask before enabling irqs */
-		local_softirq_pending() = 0;
+		softirq_pending() = 0;
 
 		local_irq_enable();
 
@@ -92,7 +91,7 @@
 
 		local_irq_disable();
 
-		pending = local_softirq_pending();
+		pending = softirq_pending();
 		if (pending & mask) {
 			mask &= ~pending;
 			goto restart;
@@ -110,7 +109,7 @@
 	__local_bh_enable();
 	WARN_ON(irqs_disabled());
 	if (unlikely(!in_interrupt() &&
-		     local_softirq_pending()))
+		     softirq_pending()))
 		invoke_softirq();
 	preempt_check_resched();
 }
@@ -329,12 +328,12 @@
 	__get_cpu_var(ksoftirqd) = current;
 
 	for (;;) {
-		if (!local_softirq_pending())
+		if (!softirq_pending())
 			schedule();
 
 		__set_current_state(TASK_RUNNING);
 
-		while (local_softirq_pending()) {
+		while (softirq_pending()) {
 			do_softirq();
 			cond_resched();
 		}
#1 lore raw
Quoted 4 lines · On Tue, 23 Sep 2003 16:48:47 +0200 Christoph Hellwig <[email protected]> wrote:

x86-64 currently ignores the cpu argument to softirq_pending() and always uses smp_processor_id(). And indeed that's the only possible argument. So consolidate the old softirq_pending() and local_softirq_pending() into a single one.

The problem is that, on some of the platforms that don't ignore the argument, the code generation is much better.

GCC doesn't consider smp_processor_id() like some const local variable, so multiple invocations are assumed to return different values because in many cases 'current_thread_info()' is obscured.

Your patch is going to make a lot of new code get generated on x86 for example, so I don't think it should be applied even though my own platforms are not effected by this issue.

#2 lore raw
Quoted 10 lines · David S. Miller

The problem is that, on some of the platforms that don't ignore the argument, the code generation is much better.

GCC doesn't consider smp_processor_id() like some const local variable, so multiple invocations are assumed to return different values because in many cases 'current_thread_info()' is obscured.

Your patch is going to make a lot of new code get generated on x86 for example, so I don't think it should be applied even though my own platforms are not effected by this issue.

Okay, thanks forthe explanation. I don't think it matters in this case because there's exactly one case where we pass an variable into softirq_pending() instead of a direct, uncached smp_processor_id() - and that is in arch/cris/ which is UP only.

I'll try to remember the hint so I know what do to this pops up the next time, though :)

#3 lore raw
In reply to Christoph Hellwig
Quoted 4 lines · Christoph Hellwig

x86-64 currently ignores the cpu argument to softirq_pending() and always uses smp_processor_id(). And indeed that's the only possible argument. So consolidate the old softirq_pending() and local_softirq_pending() into a single one.

The issue is that on some architectures it is quite possibly useful to get the cpu number, if we end up having to compute it anyway. An example of this is x86.

On the other hand, some architectures have direct pointers to the "local cpu state", so for them it is better to always know "this is local" (which it indeed always is).

So think of the "cpu" argument as a pre-computed "what cpu am I on now" thing. Especially since we often have it available anyway.

Linus