We actually have two separate bad bugs
1. The read_lock implementation spins with disabled interrupts. This is
completely wrong
2. Our spin_lock_irqsave should check to see if interrupts were enabled
before the call and re-enable interrupts around the inner spin loop.
The problem is that if we spin with interrupts off, we can't receive
IPIs. This has resulted in a bug where SMP machines suddenly spit
smp_call_function timeout messages and hang.
The scenario I've caught is
CPU0 does a flush_tlb_all holding the vmlist_lock for write.
CPU1 tries a cat of /proc/meminfo which tries to acquire vmlist_lock for
read
CPU1 is now spinning with interrupts disabled
CPU0 tries to execute a smp_call_function to flush the local tlb caches
This is now a deadlock because CPU1 is spinning with interrupts disabled
and can never receive the IPI
Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
This really only adds them for the machines I can check SMP on, which
is CPU interrupts and IOSAPIC (so not any of the GSC based machines).
With this patch, irqbalanced can be used to maintain irq balancing.
Unfortunately, irqbalanced is a bit x86 centric, so it doesn't do an
incredibly good job, but it does work.
Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Since irq.c uses smp_send_all_nop, we must define it for UP builds
as well. Make it a static inline so it gets optimized away. This forces
irq.c to include <asm/smp.h> though.
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Fix our interrupts not to use smp_call_function
On K and D class smp, the generic code calls this under an irq
spinlock, which causes the WARN_ON() message in smp_call_function()
(and is also illegal because it could deadlock).
The fix is to use a new scheme based on the IPI_NOP.
Signed-off-by: James Bottomley <jejb@parisc-linux.org>
Signed-off-by: Kyle McMartin <kyle@parisc-linux.org>
Due to incomplete memory constraints, gcc would miscompile code with
sigaddset on i386 if sig arg was const.
A quote form Jakub to make the issue clear:
"You need either
__asm__("btsl %1,%0" : "+m"(*set) : "Ir"(_sig-1) : "cc");
or
__asm__("btsl %1,%0" : "=m"(*set) : "Ir"(_sig-1), "m"(*set) : "cc");
because the btsl instruction doesn't just set the memory to some
value, but needs to read its previous content as well. If you don't
tell that fact to GCC, GCC is of course free to optimize as if the asm
was just setting the value and not depended on the previous value."
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
There is no definition for seadint_init() and the unprotected prototype
breaks compilation of assembler files.
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
In the old days when arm26/arm32 was combined into the same
architecture, proc-fns.h provided the xchg implementation for
arm26 CPUs. Since we no longer combine these two, this include
is no longer required. Remove it.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Since atomic.h does not include types.h, u32 may not be defined.
Since atomics are supposed to work on unsigned long quantities,
use unsigned long instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Unfortunately, using PAGE_SHIFT in asm/arch/memory.h is unsafe, and we
can't include asm/page.h into this file because then we have a circular
dependency. Move the offending code to arch/arm/common/sa1111.c
instead.
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>