diff options
author | Steven Rostedt <srostedt@redhat.com> | 2009-02-12 10:53:37 -0500 |
---|---|---|
committer | Steven Rostedt <srostedt@redhat.com> | 2009-02-12 11:19:05 -0500 |
commit | 5a5fb7dbe88dd57dc2bef0f3be9da991e789612d (patch) | |
tree | c1645341b09cc4259255991bd74a7aa708db9413 /arch | |
parent | d524e03207591a6de7e6b5069aabc778e3f0f5f8 (diff) |
preempt-count: force hardirq-count to max of 10
To add a bit in the preempt_count to be set when in NMI context, we
found that some archs did not have enough bits to spare. This is
due to the hardirq_count being a mask that can hold NR_IRQS.
Some archs allow for over 16000 IRQs, and that would require a mask
of 14 bits. The sofitrq mask is 8 bits and the preempt disable mask
is also 8 bits. The PREEMP_ACTIVE bit is bit 30, and bit 31 would
make the preempt_count (which is type int) a negative number.
A negative preempt_count is a sign of failure.
Add them up 14+8+8+1+1 you get 32 bits. No room for the NMI bit.
But the hardirq_count is to track the number of nested IRQs, not
the number of total IRQs. This originally took the paranoid approach
of setting the max nesting to NR_IRQS. But when we have archs with
over 1000 IRQs, it is not practical to think they will ever all
nest on a single CPU. Not to mention that this would most definitely
cause a stack overflow.
This patch sets a max of 10 bits to be used for IRQ nesting.
I did a 'git grep HARDIRQ' to examine all users of HARDIRQ_BITS and
HARDIRQ_MASK, and found that making it a max of 10 would not hurt
anyone. I did find that the m68k expected it to be 8 bits, so
I allow for the archs to set the number to be less than 10.
I removed the setting of HARDIRQ_BITS from the archs that set it
to more than 10. This includes ALPHA, ia64 and avr32.
This will always allow room for the NMI bit, and if we need to allow
for NMI nesting, we have 4 bits to play with.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/alpha/include/asm/hardirq.h | 13 | ||||
-rw-r--r-- | arch/avr32/include/asm/hardirq.h | 11 | ||||
-rw-r--r-- | arch/ia64/include/asm/hardirq.h | 10 |
3 files changed, 0 insertions, 34 deletions
diff --git a/arch/alpha/include/asm/hardirq.h b/arch/alpha/include/asm/hardirq.h index d953e234daa8..88971460fa6c 100644 --- a/arch/alpha/include/asm/hardirq.h +++ b/arch/alpha/include/asm/hardirq.h | |||
@@ -14,17 +14,4 @@ typedef struct { | |||
14 | 14 | ||
15 | void ack_bad_irq(unsigned int irq); | 15 | void ack_bad_irq(unsigned int irq); |
16 | 16 | ||
17 | #define HARDIRQ_BITS 12 | ||
18 | |||
19 | /* | ||
20 | * The hardirq mask has to be large enough to have | ||
21 | * space for potentially nestable IRQ sources in the system | ||
22 | * to nest on a single CPU. On Alpha, interrupts are masked at the CPU | ||
23 | * by IPL as well as at the system level. We only have 8 IPLs (UNIX PALcode) | ||
24 | * so we really only have 8 nestable IRQs, but allow some overhead | ||
25 | */ | ||
26 | #if (1 << HARDIRQ_BITS) < 16 | ||
27 | #error HARDIRQ_BITS is too low! | ||
28 | #endif | ||
29 | |||
30 | #endif /* _ALPHA_HARDIRQ_H */ | 17 | #endif /* _ALPHA_HARDIRQ_H */ |
diff --git a/arch/avr32/include/asm/hardirq.h b/arch/avr32/include/asm/hardirq.h index 267354356f60..015bc75ea798 100644 --- a/arch/avr32/include/asm/hardirq.h +++ b/arch/avr32/include/asm/hardirq.h | |||
@@ -20,15 +20,4 @@ void ack_bad_irq(unsigned int irq); | |||
20 | 20 | ||
21 | #endif /* __ASSEMBLY__ */ | 21 | #endif /* __ASSEMBLY__ */ |
22 | 22 | ||
23 | #define HARDIRQ_BITS 12 | ||
24 | |||
25 | /* | ||
26 | * The hardirq mask has to be large enough to have | ||
27 | * space for potentially all IRQ sources in the system | ||
28 | * nesting on a single CPU: | ||
29 | */ | ||
30 | #if (1 << HARDIRQ_BITS) < NR_IRQS | ||
31 | # error HARDIRQ_BITS is too low! | ||
32 | #endif | ||
33 | |||
34 | #endif /* __ASM_AVR32_HARDIRQ_H */ | 23 | #endif /* __ASM_AVR32_HARDIRQ_H */ |
diff --git a/arch/ia64/include/asm/hardirq.h b/arch/ia64/include/asm/hardirq.h index 140e495b8e0e..d514cd9edb49 100644 --- a/arch/ia64/include/asm/hardirq.h +++ b/arch/ia64/include/asm/hardirq.h | |||
@@ -20,16 +20,6 @@ | |||
20 | 20 | ||
21 | #define local_softirq_pending() (local_cpu_data->softirq_pending) | 21 | #define local_softirq_pending() (local_cpu_data->softirq_pending) |
22 | 22 | ||
23 | #define HARDIRQ_BITS 14 | ||
24 | |||
25 | /* | ||
26 | * The hardirq mask has to be large enough to have space for potentially all IRQ sources | ||
27 | * in the system nesting on a single CPU: | ||
28 | */ | ||
29 | #if (1 << HARDIRQ_BITS) < NR_IRQS | ||
30 | # error HARDIRQ_BITS is too low! | ||
31 | #endif | ||
32 | |||
33 | extern void __iomem *ipi_base_addr; | 23 | extern void __iomem *ipi_base_addr; |
34 | 24 | ||
35 | void ack_bad_irq(unsigned int irq); | 25 | void ack_bad_irq(unsigned int irq); |