📄 1018.kernel-preempt.patch
字号:
kstat.irqs[cpu][irq]++; spin_lock(&desc->lock); desc->handler->ack(irq);@@ -458,6 +464,7 @@ will take care of it. */ if (!action) {+ printk(KERN_ERR "spurious interrupt detected: %d\n", irq); desc->handler->shutdown(irq); /* Shut off this IRQ */ goto out; }@@ -494,6 +501,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 -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/mips/mm/extable.c linuxmips-2.4.30/arch/mips/mm/extable.c--- linuxmips-2.4.30.ref/arch/mips/mm/extable.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/mips/mm/extable.c 2005-08-29 11:43:45.000000000 -0700@@ -3,6 +3,7 @@ */ #include <linux/config.h> #include <linux/module.h>+#include <linux/sched.h> #include <linux/spinlock.h> #include <asm/uaccess.h> diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/config.in linuxmips-2.4.30/arch/ppc/config.in--- linuxmips-2.4.30.ref/arch/ppc/config.in 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/config.in 2005-08-29 11:43:45.000000000 -0700@@ -167,6 +167,8 @@ int 'Maximum number of CPUs (2-32)' CONFIG_NR_CPUS 32 fi +bool 'Preemptible kernel support' CONFIG_PREEMPT+ if [ "$CONFIG_6xx" = "y" -a "$CONFIG_8260" = "n" ];then bool 'AltiVec Support' CONFIG_ALTIVEC bool 'Thermal Management Support' CONFIG_TAUdiff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/entry.S linuxmips-2.4.30/arch/ppc/kernel/entry.S--- linuxmips-2.4.30.ref/arch/ppc/kernel/entry.S 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/entry.S 2005-08-29 11:43:45.000000000 -0700@@ -287,6 +287,46 @@ */ cmpi 0,r3,0 beq restore+#ifdef CONFIG_PREEMPT+ lwz r3,PREEMPT_COUNT(r2)+ cmpi 0,r3,1+ bge ret_from_except+ lwz r5,_MSR(r1)+ andi. r5,r5,MSR_PR+ bne do_signal_ret+ lwz r5,NEED_RESCHED(r2)+ cmpi 0,r5,0+ beq ret_from_except+ lis r3,irq_stat@h+ ori r3,r3,irq_stat@l+#ifdef CONFIG_SMP+ lwz r5,CPU(r2)+ rlwinm r5,r5,5,0,26+ add r3,r3,r5+#endif+ lwz r5,4(r3)+ lwz r3,8(r3)+ add r3,r3,r5+ cmpi 0,r3,0+ bne ret_from_except+ lwz r3,PREEMPT_COUNT(r2)+ addi r3,r3,1+ stw r3,PREEMPT_COUNT(r2)+ mfmsr r0+ ori r0,r0,MSR_EE+ mtmsr r0+ sync+ bl preempt_schedule+ mfmsr r0+ rlwinm r0,r0,0,17,15+ mtmsr r0+ sync+ lwz r3,PREEMPT_COUNT(r2)+ subi r3,r3,1+ stw r3,PREEMPT_COUNT(r2)+ li r3,1+ b ret_from_intercept+#endif /* CONFIG_PREEMPT */ .globl ret_from_except ret_from_except: lwz r3,_MSR(r1) /* Returning to user mode? */diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/irq.c linuxmips-2.4.30/arch/ppc/kernel/irq.c--- linuxmips-2.4.30.ref/arch/ppc/kernel/irq.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/irq.c 2005-08-29 11:43:45.000000000 -0700@@ -551,6 +551,34 @@ return 1; /* lets ret_from_int know we can do checks */ } +#ifdef CONFIG_PREEMPT+int+preempt_intercept(struct pt_regs *regs)+{+ int ret;++ preempt_disable();++ switch(regs->trap) {+ case 0x500:+ ret = do_IRQ(regs);+ break;+#ifndef CONFIG_4xx+ case 0x900:+#else+ case 0x1000:+#endif+ ret = timer_interrupt(regs);+ break;+ default:+ BUG();+ }++ preempt_enable();+ return ret;+}+#endif /* CONFIG_PREEMPT */+ unsigned long probe_irq_on (void) { return 0;@@ -647,11 +675,13 @@ show("wait_on_irq"); count = ~0; }+ preempt_disable(); __sti(); /* don't worry about the lock race Linus found * on intel here. -- Cort */ __cli();+ preempt_enable_no_resched(); if (atomic_read(&global_irq_count)) continue; if (global_irq_lock)@@ -727,6 +757,8 @@ global_irq_holder = cpu; } +#define EFLAGS_IF_SHIFT 15+ /* * A global "cli()" while in an interrupt context * turns into just a local cli(). Interrupts@@ -744,9 +776,10 @@ unsigned long flags; __save_flags(flags);- if (flags & (1 << 15)) {- int cpu = smp_processor_id();+ if (flags & (1 << EFLAGS_IF_SHIFT)) {+ int cpu; __cli();+ cpu = smp_processor_id(); if (!local_irq_count(cpu)) get_irqlock(cpu); }@@ -754,11 +787,14 @@ void __global_sti(void) {- int cpu = smp_processor_id();+ int cpu; + preempt_disable();+ cpu = smp_processor_id(); if (!local_irq_count(cpu)) release_irqlock(cpu); __sti();+ preempt_enable(); } /*@@ -773,19 +809,23 @@ int retval; int local_enabled; unsigned long flags;+ int cpu; __save_flags(flags);- local_enabled = (flags >> 15) & 1;+ local_enabled = (flags >> EFLAGS_IF_SHIFT) & 1; /* default to local */ retval = 2 + local_enabled; /* check for global flags if we're not in an interrupt */- if (!local_irq_count(smp_processor_id())) {+ preempt_disable();+ cpu = smp_processor_id();+ if (!local_irq_count(cpu)) { if (local_enabled) retval = 1;- if (global_irq_holder == (unsigned char) smp_processor_id())+ if (global_irq_holder == cpu) retval = 0; }+ preempt_enable(); return retval; } diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/mk_defs.c linuxmips-2.4.30/arch/ppc/kernel/mk_defs.c--- linuxmips-2.4.30.ref/arch/ppc/kernel/mk_defs.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/mk_defs.c 2005-08-29 11:43:45.000000000 -0700@@ -39,6 +39,9 @@ DEFINE(SIGPENDING, offsetof(struct task_struct, sigpending)); DEFINE(THREAD, offsetof(struct task_struct, thread)); DEFINE(MM, offsetof(struct task_struct, mm));+#ifdef CONFIG_PREEMPT+ DEFINE(PREEMPT_COUNT, offsetof(struct task_struct, preempt_count));+#endif DEFINE(ACTIVE_MM, offsetof(struct task_struct, active_mm)); DEFINE(TASK_STRUCT_SIZE, sizeof(struct task_struct)); DEFINE(KSP, offsetof(struct thread_struct, ksp));diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/open_pic.c linuxmips-2.4.30/arch/ppc/kernel/open_pic.c--- linuxmips-2.4.30.ref/arch/ppc/kernel/open_pic.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/open_pic.c 2005-08-29 11:43:45.000000000 -0700@@ -601,19 +601,24 @@ void __init do_openpic_setup_cpu(void) { int i;- u32 msk = 1 << smp_hw_index[smp_processor_id()];+#ifdef CONFIG_IRQ_ALL_CPUS+ u32 msk;+#endif /* CONFIG_IRQ_ALL_CPUS */ spin_lock(&openpic_setup_lock); #ifdef CONFIG_IRQ_ALL_CPUS+ msk = 1 << smp_hw_index[smp_processor_id()];+ /* let the openpic know we want intrs. default affinity * is 0xffffffff until changed via /proc * That's how it's done on x86. If we want it differently, then * we should make sure we also change the default values of irq_affinity * in irq.c. */- for (i = 0; i < NumSources; i++)+ for (i = 0; i < NumSources; i++) { openpic_mapirq(i, msk, ~0U);+ } #endif /* CONFIG_IRQ_ALL_CPUS */ openpic_set_priority(0); diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/setup.c linuxmips-2.4.30/arch/ppc/kernel/setup.c--- linuxmips-2.4.30.ref/arch/ppc/kernel/setup.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/setup.c 2005-08-29 11:43:45.000000000 -0700@@ -502,6 +502,20 @@ strcpy(cmd_line, CONFIG_CMDLINE); #endif /* CONFIG_CMDLINE */ +#ifdef CONFIG_PREEMPT+ /* Override the irq routines for external & timer interrupts here,+ * as the MMU has only been minimally setup at this point and+ * there are no protections on page zero.+ */+ {+ extern int preempt_intercept(struct pt_regs *);+ + do_IRQ_intercept = (unsigned long) &preempt_intercept;+ timer_interrupt_intercept = (unsigned long) &preempt_intercept;++ }+#endif /* CONFIG_PREEMPT */+ platform_init(r3, r4, r5, r6, r7); if (ppc_md.progress)diff -Naur --exclude=CVS --exclude='*.o' --exclude='*.a' --exclude='*.so' --exclude='*.elf' --exclude=System.map --exclude=Makefile.d --exclude='*log' --exclude='*log2' --exclude='*~' --exclude='.*~' --exclude='.#*' --exclude='*.bak' --exclude='*.orig' --exclude='*.rej' --exclude='core.[0-9]*' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=.depend --exclude='.*.o.flags' --exclude='*.gz' --exclude=vmlinux --exclude=vmlinux.bin --exclude=yamon-02.06-SIGMADESIGNS-01_el.bin linuxmips-2.4.30.ref/arch/ppc/kernel/temp.c linuxmips-2.4.30/arch/ppc/kernel/temp.c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -