Skip to contentSkip to conversation

parisc: implement irq stacks - part 2

PATCH In review Helge Deller 1 participant 2 messages May 9, 2013 – May 10, 2013 PA-RISC architecture

lore
Share & tools
lore

Helge Deller

author maintainer
#0 lore raw

PATCH 1/1 parisc: implement irq stacks - part 2

This patch fixes few build issues which were introduced with the last irq stack patch, e.g. the combination of stack overflow check and irq stack.

Furthermore it now does proper locking and changes the irq bh handler to use the irq stack as well.

One issue still needs fixing: The irq stack usage counter will not be incremented and will show zero.

arch/parisc/include/asm/hardirq.h +7 -0
index 12373c4..c4be3c7 100644
@@ -11,10 +11,17 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+#ifdef CONFIG_IRQSTACKS
+#define __ARCH_HAS_DO_SOFTIRQ
+#endif
+
 typedef struct {
 	unsigned int __softirq_pending;
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	unsigned int kernel_stack_usage;
+#ifdef CONFIG_IRQSTACKS
+	unsigned int irq_stack_usage;
+#endif
 #endif
 #ifdef CONFIG_SMP
 	unsigned int irq_resched_count;
arch/parisc/include/asm/processor.h +3 -0
index 0640155..cfbc439 100644
@@ -63,10 +63,13 @@
  */
 #ifdef __KERNEL__
 
+#include <linux/spinlock_types.h>
+
 #define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
 
 union irq_stack_union {
 	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+	raw_spinlock_t lock;
 };
 
 DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
arch/parisc/kernel/irq.c +80 -14

146 lines not on this page · raw message

author maintainer
#1 lore raw

Re: [PATCH] parisc: implement irq stacks - part 2 (v2)

This patch fixes few build issues which were introduced with the last irq stack patch, e.g. the combination of stack overflow check and irq stack.

Furthermore we now do proper locking and change the irq bh handler to use the irq stack as well.

In /proc/interrupts one now can monitor how huge the irq stack has grown and how often it was preferred over the kernel stack.

IRQ stacks are now enabled by default just to make sure that we not overflow the kernel stack by accident.

arch/parisc/Kconfig +1 -1
index cad060f..6507dab 100644
@@ -245,7 +245,7 @@ config SMP
 
 config IRQSTACKS
 	bool "Use separate kernel stacks when processing interrupts"
-	default n
+	default y
 	help
 	  If you say Y here the kernel will use separate kernel stacks
 	  for handling hard and soft interrupts.  This can help avoid
arch/parisc/include/asm/hardirq.h +9 -0
index 12373c4..c19f713 100644
@@ -11,10 +11,18 @@
 #include <linux/threads.h>
 #include <linux/irq.h>
 
+#ifdef CONFIG_IRQSTACKS
+#define __ARCH_HAS_DO_SOFTIRQ
+#endif
+
 typedef struct {
 	unsigned int __softirq_pending;
 #ifdef CONFIG_DEBUG_STACKOVERFLOW
 	unsigned int kernel_stack_usage;
+#ifdef CONFIG_IRQSTACKS
+	unsigned int irq_stack_usage;
+	unsigned int irq_stack_counter;
+#endif
 #endif
 #ifdef CONFIG_SMP
 	unsigned int irq_resched_count;
@@ -28,6 +36,7 @@ DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
 #define __ARCH_IRQ_STAT
 #define __IRQ_STAT(cpu, member) (irq_stat[cpu].member)
 #define inc_irq_stat(member)	this_cpu_inc(irq_stat.member)
+#define __inc_irq_stat(member)	__this_cpu_inc(irq_stat.member)
 #define local_softirq_pending()	this_cpu_read(irq_stat.__softirq_pending)
 
 #define __ARCH_SET_SOFTIRQ_PENDING
arch/parisc/include/asm/processor.h +3 -0
index 0640155..cfbc439 100644
@@ -63,10 +63,13 @@
  */
 #ifdef __KERNEL__
 
+#include <linux/spinlock_types.h>
+
 #define IRQ_STACK_SIZE      (4096 << 2) /* 16k irq stack size */
 
 union irq_stack_union {
 	unsigned long stack[IRQ_STACK_SIZE/sizeof(unsigned long)];
+	raw_spinlock_t lock;
 };
 
 DECLARE_PER_CPU(union irq_stack_union, irq_stack_union);
arch/parisc/kernel/irq.c +87 -14

153 lines not on this page · raw message

arch/parisc/mm/init.c +2 -2
index ce939ac..1c96564 100644
@@ -1069,7 +1069,7 @@ void flush_tlb_all(void)
 {
 	int do_recycle;
 
-	inc_irq_stat(irq_tlb_count);
+	__inc_irq_stat(irq_tlb_count);
 	do_recycle = 0;
 	spin_lock(&sid_lock);
 	if (dirty_space_ids > RECYCLE_THRESHOLD) {
@@ -1090,7 +1090,7 @@ void flush_tlb_all(void)
 #else
 void flush_tlb_all(void)
 {
-	inc_irq_stat(irq_tlb_count);
+	__inc_irq_stat(irq_tlb_count);
 	spin_lock(&sid_lock);
 	flush_tlb_all_local(NULL);
 	recycle_sids();