diff -urN linux-2.4.19-pre8-preempt/arch/mips/config.in linux/arch/mips/config.in --- linux-2.4.19-pre8-preempt/arch/mips/config.in Wed May 8 15:09:53 2002 +++ linux/arch/mips/config.in Wed May 8 15:54:35 2002 @@ -468,6 +468,7 @@ # bool ' Access.Bus support' CONFIG_ACCESSBUS # fi fi +dep_bool 'Preemptible Kernel' CONFIG_PREEMPT $CONFIG_NEW_IRQ endmenu if [ "$CONFIG_ISA" = "y" ]; then diff -urN linux-2.4.19-pre8-preempt/arch/mips/kernel/i8259.c linux/arch/mips/kernel/i8259.c --- linux-2.4.19-pre8-preempt/arch/mips/kernel/i8259.c Wed May 8 15:09:53 2002 +++ linux/arch/mips/kernel/i8259.c Wed May 8 15:54:35 2002 @@ -8,6 +8,7 @@ * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle */ +#include #include #include #include diff -urN linux-2.4.19-pre8-preempt/arch/mips/kernel/irq.c linux/arch/mips/kernel/irq.c --- linux-2.4.19-pre8-preempt/arch/mips/kernel/irq.c Wed May 8 15:09:53 2002 +++ linux/arch/mips/kernel/irq.c Wed May 8 15:56:16 2002 @@ -8,6 +8,8 @@ * Copyright (C) 1992 Linus Torvalds * Copyright (C) 1994 - 2000 Ralf Baechle */ + +#include #include #include #include @@ -19,11 +21,13 @@ #include #include #include -#include +#include +#include #include #include #include +#include /* * Controller mappings for all interrupt sources: @@ -420,6 +424,8 @@ struct irqaction * action; unsigned int status; + preempt_disable(); + kstat.irqs[cpu][irq]++; spin_lock(&desc->lock); desc->handler->ack(irq); @@ -481,6 +487,27 @@ if (softirq_pending(cpu)) do_softirq(); + +#if defined(CONFIG_PREEMPT) + while (--current->preempt_count == 0) { + db_assert(intr_off()); + db_assert(!in_interrupt()); + + if (current->need_resched == 0) { + break; + } + + current->preempt_count ++; + sti(); + if (user_mode(regs)) { + schedule(); + } else { + preempt_schedule(); + } + cli(); + } +#endif + return 1; } diff -urN linux-2.4.19-pre8-preempt/arch/mips/mm/extable.c linux/arch/mips/mm/extable.c --- linux-2.4.19-pre8-preempt/arch/mips/mm/extable.c Wed May 8 15:09:53 2002 +++ linux/arch/mips/mm/extable.c Wed May 8 15:54:35 2002 @@ -3,6 +3,7 @@ */ #include #include +#include #include #include diff -urN linux-2.4.19-pre8-preempt/include/asm-mips/smplock.h linux/include/asm-mips/smplock.h --- linux-2.4.19-pre8-preempt/include/asm-mips/smplock.h Wed May 8 15:09:11 2002 +++ linux/include/asm-mips/smplock.h Wed May 8 15:57:41 2002 @@ -5,12 +5,21 @@ * * Default SMP lock implementation */ +#include #include #include extern spinlock_t kernel_flag; +#ifdef CONFIG_SMP #define kernel_locked() spin_is_locked(&kernel_flag) +#else +#ifdef CONFIG_PREEMPT +#define kernel_locked() preempt_get_count() +#else +#define kernel_locked() 1 +#endif +#endif /* * Release global kernel lock and global interrupt lock @@ -42,8 +51,14 @@ */ extern __inline__ void lock_kernel(void) { +#ifdef CONFIG_PREEMPT + if (current->lock_depth == -1) + spin_lock(&kernel_flag); + ++current->lock_depth; +#else if (!++current->lock_depth) spin_lock(&kernel_flag); +#endif } extern __inline__ void unlock_kernel(void) diff -urN linux-2.4.19-pre8-preempt/include/asm-mips/softirq.h linux/include/asm-mips/softirq.h --- linux-2.4.19-pre8-preempt/include/asm-mips/softirq.h Wed May 8 15:09:11 2002 +++ linux/include/asm-mips/softirq.h Wed May 8 15:54:35 2002 @@ -15,6 +15,7 @@ static inline void cpu_bh_disable(int cpu) { + preempt_disable(); local_bh_count(cpu)++; barrier(); } @@ -23,6 +24,7 @@ { barrier(); local_bh_count(cpu)--; + preempt_enable(); } @@ -36,6 +38,7 @@ cpu = smp_processor_id(); \ if (!--local_bh_count(cpu) && softirq_pending(cpu)) \ do_softirq(); \ + preempt_enable(); \ } while (0) #define in_softirq() (local_bh_count(smp_processor_id()) != 0) diff -urN linux-2.4.19-pre8-preempt/include/asm-mips/system.h linux/include/asm-mips/system.h --- linux-2.4.19-pre8-preempt/include/asm-mips/system.h Wed May 8 15:09:11 2002 +++ linux/include/asm-mips/system.h Wed May 8 15:54:35 2002 @@ -285,4 +285,16 @@ #define die_if_kernel(msg, regs) \ __die_if_kernel(msg, regs, __FILE__ ":"__FUNCTION__, __LINE__) +extern __inline__ int intr_on(void) +{ + unsigned long flags; + save_flags(flags); + return flags & 1; +} + +extern __inline__ int intr_off(void) +{ + return ! intr_on(); +} + #endif /* _ASM_SYSTEM_H */