📄 1018.kernel-preempt.patch
字号:
--- linuxmips-2.4.30.ref/arch/ppc/kernel/temp.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/kernel/temp.c 2005-08-29 11:43:45.000000000 -0700@@ -138,7 +138,7 @@ static void tau_timeout(void * info) {- unsigned long cpu = smp_processor_id();+ unsigned long cpu; unsigned long flags; int size; int shrink;@@ -146,6 +146,8 @@ /* disabling interrupts *should* be okay */ save_flags(flags); cli(); + cpu = smp_processor_id();+ #ifndef CONFIG_TAU_INT TAUupdate(cpu); #endif@@ -191,13 +193,15 @@ static void tau_timeout_smp(unsigned long unused) {- /* schedule ourselves to be run again */ mod_timer(&tau_timer, jiffies + shrink_timer) ;++ preempt_disable(); #ifdef CONFIG_SMP smp_call_function(tau_timeout, NULL, 1, 0); #endif tau_timeout(NULL);+ preempt_enable(); } /*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/lib/dec_and_lock.c linuxmips-2.4.30/arch/ppc/lib/dec_and_lock.c--- linuxmips-2.4.30.ref/arch/ppc/lib/dec_and_lock.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/lib/dec_and_lock.c 2005-08-29 11:43:45.000000000 -0700@@ -1,4 +1,5 @@ #include <linux/module.h>+#include <linux/sched.h> #include <linux/spinlock.h> #include <asm/atomic.h> #include <asm/system.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/mm/init.c linuxmips-2.4.30/arch/ppc/mm/init.c--- linuxmips-2.4.30.ref/arch/ppc/mm/init.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/mm/init.c 2005-08-29 11:43:45.000000000 -0700@@ -126,6 +126,9 @@ int do_check_pgt_cache(int low, int high) { int freed = 0;++ preempt_disable();+ if (pgtable_cache_size > high) { do { if (pgd_quicklist) {@@ -138,6 +141,9 @@ } } while (pgtable_cache_size > low); }++ preempt_enable();+ return freed; } 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/mm/tlb.c linuxmips-2.4.30/arch/ppc/mm/tlb.c--- linuxmips-2.4.30.ref/arch/ppc/mm/tlb.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/arch/ppc/mm/tlb.c 2005-08-29 11:43:45.000000000 -0700@@ -58,11 +58,14 @@ * we can and should dispense with flush_tlb_all(). * -- paulus. */++ preempt_disable(); local_flush_tlb_range(&init_mm, TASK_SIZE, ~0UL); #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif /* CONFIG_SMP */+ preempt_enable(); } /*@@ -73,8 +76,10 @@ void local_flush_tlb_mm(struct mm_struct *mm) {+ preempt_disable(); if (Hash == 0) { _tlbia();+ preempt_enable(); return; } @@ -88,6 +93,7 @@ #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif+ preempt_enable(); } void@@ -97,8 +103,10 @@ pmd_t *pmd; pte_t *pte; + preempt_disable(); if (Hash == 0) { _tlbie(vmaddr);+ preempt_enable(); return; } mm = (vmaddr < TASK_SIZE)? vma->vm_mm: &init_mm;@@ -111,6 +119,7 @@ #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif+ preempt_enable(); } @@ -127,13 +136,17 @@ unsigned long pmd_end; unsigned int ctx = mm->context; + preempt_disable(); if (Hash == 0) { _tlbia();+ preempt_enable(); return; } start &= PAGE_MASK;- if (start >= end)+ if (start >= end) {+ preempt_enable(); return;+ } pmd = pmd_offset(pgd_offset(mm, start), start); do { pmd_end = (start + PGDIR_SIZE) & PGDIR_MASK;@@ -156,4 +169,5 @@ #ifdef CONFIG_SMP smp_send_tlb_invalidate(0); #endif+ preempt_enable(); }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/CREDITS linuxmips-2.4.30/CREDITS--- linuxmips-2.4.30.ref/CREDITS 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/CREDITS 2005-08-29 11:43:45.000000000 -0700@@ -1007,8 +1007,8 @@ N: Nigel Gamble E: nigel@nrg.org-E: nigel@sgi.com D: Interrupt-driven printer driver+D: Preemptible kernel S: 120 Alley Way S: Mountain View, California 94040 S: USAdiff -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/Documentation/Configure.help linuxmips-2.4.30/Documentation/Configure.help--- linuxmips-2.4.30.ref/Documentation/Configure.help 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/Documentation/Configure.help 2005-08-29 11:43:45.000000000 -0700@@ -296,6 +296,17 @@ If you have a system with several CPUs, you do not need to say Y here: the local APIC will be used automatically. +Preemptible Kernel+CONFIG_PREEMPT+ This option reduces the latency of the kernel when reacting to+ real-time or interactive events by allowing a low priority process to+ be preempted even if it is in kernel mode executing a system call.+ This allows applications to run more reliably even when the system is+ under load.++ Say Y here if you are building a kernel for a desktop, embedded or+ real-time system. Say N if you are unsure.+ Kernel math emulation CONFIG_MATH_EMULATION Linux can emulate a math coprocessor (used for floating pointdiff -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/Documentation/preempt-locking.txt linuxmips-2.4.30/Documentation/preempt-locking.txt--- linuxmips-2.4.30.ref/Documentation/preempt-locking.txt 1969-12-31 16:00:00.000000000 -0800+++ linuxmips-2.4.30/Documentation/preempt-locking.txt 2005-08-29 11:43:45.000000000 -0700@@ -0,0 +1,104 @@+ Proper Locking Under a Preemptible Kernel:+ Keeping Kernel Code Preempt-Safe+ Robert Love <rml@tech9.net>+ Last Updated: 22 Jan 2002+++INTRODUCTION+++A preemptible kernel creates new locking issues. The issues are the same as+those under SMP: concurrency and reentrancy. Thankfully, the Linux preemptible+kernel model leverages existing SMP locking mechanisms. Thus, the kernel+requires explicit additional locking for very few additional situations.++This document is for all kernel hackers. Developing code in the kernel+requires protecting these situations.+ ++RULE #1: Per-CPU data structures need explicit protection+++Two similar problems arise. An example code snippet:++ struct this_needs_locking tux[NR_CPUS];+ tux[smp_processor_id()] = some_value;+ /* task is preempted here... */+ something = tux[smp_processor_id()];++First, since the data is per-CPU, it may not have explicit SMP locking, but+require it otherwise. Second, when a preempted task is finally rescheduled,+the previous value of smp_processor_id may not equal the current. You must+protect these situations by disabling preemption around them.+++RULE #2: CPU state must be protected.+++Under preemption, the state of the CPU must be protected. This is arch-+dependent, but includes CPU structures and state not preserved over a context+switch. For example, on x86, entering and exiting FPU mode is now a critical+section that must occur while preemption is disabled. Think what would happen+if the kernel is executing a floating-point instruction and is then preempted.+Remember, the kernel does not save FPU state except for user tasks. Therefore,+upon preemption, the FPU registers will be sold to the lowest bidder. Thus,+preemption must be disabled around such regions.++Note, some FPU functions are already explicitly preempt safe. For example,+kernel_fpu_begin and kernel_fpu_end will disable and enable preemption.+However, math_state_restore must be called with preemption disabled.+++RULE #3: Lock acquire and release must be performed by same task+++A lock acquired in one task must be released by the same task. This+means you can't do oddball things like acquire a lock and go off to+play while another task releases it. If you want to do something+like this, acquire and release the task in the same code path and+have the caller wait on an event by the other task.+++SOLUTION+++Data protection under preemption is achieved by disabling preemption for the+duration of the critical region.++preempt_enable() decrement the preempt counter+preempt_disable() increment the preempt counter+preempt_enable_no_resched() decrement, but do not immediately preempt+preempt_get_count() return the preempt counter++The functions are nestable. In other words, you can call preempt_disable+n-times in a code path, and preemption will not be reenabled until the n-th+call to preempt_enable. The preempt statements define to nothing if+preemption is not enabled.++Note that you do not need to explicitly prevent preemption if you are holding+any locks or interrupts are disabled, since preemption is implicitly disabled+in those cases.++Example:++ cpucache_t *cc; /* this is per-CPU */+ preempt_disable();+ cc = cc_data(searchp);+ if (cc && cc->avail) {+ __free_block(searchp, cc_entry(cc), cc->avail);+ cc->avail = 0;+ }+ preempt_enable();+ return 0;++Notice how the preemption statements must encompass every reference of the+critical variables. Another example:++ int buf[NR_CPUS];+ set_cpu_val(buf);+ if (buf[smp_processor_id()] == -1) printf(KERN_INFO "wee!\n");+ spin_lock(&buf_lock);+ /* ... */++This code is not preempt-safe, but see how easily we can fix it by simply+moving the spin_lock up two lines.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/drivers/ieee1394/csr.c linuxmips-2.4.30/drivers/ieee1394/csr.c--- linuxmips-2.4.30.ref/drivers/ieee1394/csr.c 2005-08-29 11:42:15.000000000 -0700+++ linuxmips-2.4.30/drivers/ieee1394/csr.c 2005-08-29 11:43:45.000000000 -0700@@ -18,6 +18,7 @@ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -