diff options
| -rw-r--r-- | arch/i386/kernel/cpu/cpufreq/longhaul.c | 2 | ||||
| -rw-r--r-- | arch/mips/kernel/r2300_switch.S | 10 | ||||
| -rw-r--r-- | arch/mips/kernel/r4k_switch.S | 10 | ||||
| -rw-r--r-- | arch/mips/kernel/signal-common.h | 9 | ||||
| -rw-r--r-- | arch/mips/kernel/signal.c | 52 | ||||
| -rw-r--r-- | arch/mips/kernel/signal32.c | 52 | ||||
| -rw-r--r-- | arch/mips/kernel/traps.c | 25 | ||||
| -rw-r--r-- | arch/mips/sibyte/sb1250/setup.c | 12 | ||||
| -rw-r--r-- | block/cfq-iosched.c | 34 | ||||
| -rw-r--r-- | fs/nfs/write.c | 185 | ||||
| -rw-r--r-- | include/asm-mips/bug.h | 3 | ||||
| -rw-r--r-- | include/asm-mips/checksum.h | 2 | ||||
| -rw-r--r-- | include/asm-mips/fpu.h | 25 | ||||
| -rw-r--r-- | include/asm-mips/sibyte/sb1250_scd.h | 1 | ||||
| -rw-r--r-- | include/asm-mips/thread_info.h | 1 | ||||
| -rw-r--r-- | include/linux/nfs_page.h | 30 | ||||
| -rw-r--r-- | net/sunrpc/clnt.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/xprt.c | 10 |
18 files changed, 264 insertions, 203 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c index a1f1b715bcf8..2b030d6ccbf7 100644 --- a/arch/i386/kernel/cpu/cpufreq/longhaul.c +++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c | |||
| @@ -758,7 +758,7 @@ static int __init longhaul_cpu_init(struct cpufreq_policy *policy) | |||
| 758 | NULL, (void *)&pr); | 758 | NULL, (void *)&pr); |
| 759 | 759 | ||
| 760 | /* Check ACPI support for C3 state */ | 760 | /* Check ACPI support for C3 state */ |
| 761 | if (pr != NULL && longhaul_version != TYPE_LONGHAUL_V1) { | 761 | if (pr != NULL && longhaul_version == TYPE_POWERSAVER) { |
| 762 | cx = &pr->power.states[ACPI_STATE_C3]; | 762 | cx = &pr->power.states[ACPI_STATE_C3]; |
| 763 | if (cx->address > 0 && cx->latency <= 1000) { | 763 | if (cx->address > 0 && cx->latency <= 1000) { |
| 764 | longhaul_flags |= USE_ACPI_C3; | 764 | longhaul_flags |= USE_ACPI_C3; |
diff --git a/arch/mips/kernel/r2300_switch.S b/arch/mips/kernel/r2300_switch.S index 28c2e2e6af73..656bde2e11b1 100644 --- a/arch/mips/kernel/r2300_switch.S +++ b/arch/mips/kernel/r2300_switch.S | |||
| @@ -49,7 +49,8 @@ LEAF(resume) | |||
| 49 | #ifndef CONFIG_CPU_HAS_LLSC | 49 | #ifndef CONFIG_CPU_HAS_LLSC |
| 50 | sw zero, ll_bit | 50 | sw zero, ll_bit |
| 51 | #endif | 51 | #endif |
| 52 | mfc0 t2, CP0_STATUS | 52 | mfc0 t1, CP0_STATUS |
| 53 | sw t1, THREAD_STATUS(a0) | ||
| 53 | cpu_save_nonscratch a0 | 54 | cpu_save_nonscratch a0 |
| 54 | sw ra, THREAD_REG31(a0) | 55 | sw ra, THREAD_REG31(a0) |
| 55 | 56 | ||
| @@ -59,8 +60,8 @@ LEAF(resume) | |||
| 59 | lw t3, TASK_THREAD_INFO(a0) | 60 | lw t3, TASK_THREAD_INFO(a0) |
| 60 | lw t0, TI_FLAGS(t3) | 61 | lw t0, TI_FLAGS(t3) |
| 61 | li t1, _TIF_USEDFPU | 62 | li t1, _TIF_USEDFPU |
| 62 | and t1, t0 | 63 | and t2, t0, t1 |
| 63 | beqz t1, 1f | 64 | beqz t2, 1f |
| 64 | nor t1, zero, t1 | 65 | nor t1, zero, t1 |
| 65 | 66 | ||
| 66 | and t0, t0, t1 | 67 | and t0, t0, t1 |
| @@ -73,13 +74,10 @@ LEAF(resume) | |||
| 73 | li t1, ~ST0_CU1 | 74 | li t1, ~ST0_CU1 |
| 74 | and t0, t0, t1 | 75 | and t0, t0, t1 |
| 75 | sw t0, ST_OFF(t3) | 76 | sw t0, ST_OFF(t3) |
| 76 | /* clear thread_struct CU1 bit */ | ||
| 77 | and t2, t1 | ||
| 78 | 77 | ||
| 79 | fpu_save_single a0, t0 # clobbers t0 | 78 | fpu_save_single a0, t0 # clobbers t0 |
| 80 | 79 | ||
| 81 | 1: | 80 | 1: |
| 82 | sw t2, THREAD_STATUS(a0) | ||
| 83 | /* | 81 | /* |
| 84 | * The order of restoring the registers takes care of the race | 82 | * The order of restoring the registers takes care of the race |
| 85 | * updating $28, $29 and kernelsp without disabling ints. | 83 | * updating $28, $29 and kernelsp without disabling ints. |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index c7698fd9955c..cc566cf12246 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
| @@ -48,7 +48,8 @@ | |||
| 48 | #ifndef CONFIG_CPU_HAS_LLSC | 48 | #ifndef CONFIG_CPU_HAS_LLSC |
| 49 | sw zero, ll_bit | 49 | sw zero, ll_bit |
| 50 | #endif | 50 | #endif |
| 51 | mfc0 t2, CP0_STATUS | 51 | mfc0 t1, CP0_STATUS |
| 52 | LONG_S t1, THREAD_STATUS(a0) | ||
| 52 | cpu_save_nonscratch a0 | 53 | cpu_save_nonscratch a0 |
| 53 | LONG_S ra, THREAD_REG31(a0) | 54 | LONG_S ra, THREAD_REG31(a0) |
| 54 | 55 | ||
| @@ -58,8 +59,8 @@ | |||
| 58 | PTR_L t3, TASK_THREAD_INFO(a0) | 59 | PTR_L t3, TASK_THREAD_INFO(a0) |
| 59 | LONG_L t0, TI_FLAGS(t3) | 60 | LONG_L t0, TI_FLAGS(t3) |
| 60 | li t1, _TIF_USEDFPU | 61 | li t1, _TIF_USEDFPU |
| 61 | and t1, t0 | 62 | and t2, t0, t1 |
| 62 | beqz t1, 1f | 63 | beqz t2, 1f |
| 63 | nor t1, zero, t1 | 64 | nor t1, zero, t1 |
| 64 | 65 | ||
| 65 | and t0, t0, t1 | 66 | and t0, t0, t1 |
| @@ -72,13 +73,10 @@ | |||
| 72 | li t1, ~ST0_CU1 | 73 | li t1, ~ST0_CU1 |
| 73 | and t0, t0, t1 | 74 | and t0, t0, t1 |
| 74 | LONG_S t0, ST_OFF(t3) | 75 | LONG_S t0, ST_OFF(t3) |
| 75 | /* clear thread_struct CU1 bit */ | ||
| 76 | and t2, t1 | ||
| 77 | 76 | ||
| 78 | fpu_save_double a0 t0 t1 # c0_status passed in t0 | 77 | fpu_save_double a0 t0 t1 # c0_status passed in t0 |
| 79 | # clobbers t1 | 78 | # clobbers t1 |
| 80 | 1: | 79 | 1: |
| 81 | LONG_S t2, THREAD_STATUS(a0) | ||
| 82 | 80 | ||
| 83 | /* | 81 | /* |
| 84 | * The order of restoring the registers takes care of the race | 82 | * The order of restoring the registers takes care of the race |
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index 297dfcb97524..c0faabd52010 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
| @@ -34,4 +34,13 @@ extern int install_sigtramp(unsigned int __user *tramp, unsigned int syscall); | |||
| 34 | /* Check and clear pending FPU exceptions in saved CSR */ | 34 | /* Check and clear pending FPU exceptions in saved CSR */ |
| 35 | extern int fpcsr_pending(unsigned int __user *fpcsr); | 35 | extern int fpcsr_pending(unsigned int __user *fpcsr); |
| 36 | 36 | ||
| 37 | /* Make sure we will not lose FPU ownership */ | ||
| 38 | #ifdef CONFIG_PREEMPT | ||
| 39 | #define lock_fpu_owner() preempt_disable() | ||
| 40 | #define unlock_fpu_owner() preempt_enable() | ||
| 41 | #else | ||
| 42 | #define lock_fpu_owner() pagefault_disable() | ||
| 43 | #define unlock_fpu_owner() pagefault_enable() | ||
| 44 | #endif | ||
| 45 | |||
| 37 | #endif /* __SIGNAL_COMMON_H */ | 46 | #endif /* __SIGNAL_COMMON_H */ |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 8c3c5a5789b0..07d67309451a 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
| @@ -20,6 +20,7 @@ | |||
| 20 | #include <linux/ptrace.h> | 20 | #include <linux/ptrace.h> |
| 21 | #include <linux/unistd.h> | 21 | #include <linux/unistd.h> |
| 22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
| 23 | #include <linux/uaccess.h> | ||
| 23 | 24 | ||
| 24 | #include <asm/abi.h> | 25 | #include <asm/abi.h> |
| 25 | #include <asm/asm.h> | 26 | #include <asm/asm.h> |
| @@ -27,7 +28,6 @@ | |||
| 27 | #include <asm/cacheflush.h> | 28 | #include <asm/cacheflush.h> |
| 28 | #include <asm/fpu.h> | 29 | #include <asm/fpu.h> |
| 29 | #include <asm/sim.h> | 30 | #include <asm/sim.h> |
| 30 | #include <asm/uaccess.h> | ||
| 31 | #include <asm/ucontext.h> | 31 | #include <asm/ucontext.h> |
| 32 | #include <asm/cpu-features.h> | 32 | #include <asm/cpu-features.h> |
| 33 | #include <asm/war.h> | 33 | #include <asm/war.h> |
| @@ -78,6 +78,46 @@ struct rt_sigframe { | |||
| 78 | /* | 78 | /* |
| 79 | * Helper routines | 79 | * Helper routines |
| 80 | */ | 80 | */ |
| 81 | static int protected_save_fp_context(struct sigcontext __user *sc) | ||
| 82 | { | ||
| 83 | int err; | ||
| 84 | while (1) { | ||
| 85 | lock_fpu_owner(); | ||
| 86 | own_fpu_inatomic(1); | ||
| 87 | err = save_fp_context(sc); /* this might fail */ | ||
| 88 | unlock_fpu_owner(); | ||
| 89 | if (likely(!err)) | ||
| 90 | break; | ||
| 91 | /* touch the sigcontext and try again */ | ||
| 92 | err = __put_user(0, &sc->sc_fpregs[0]) | | ||
| 93 | __put_user(0, &sc->sc_fpregs[31]) | | ||
| 94 | __put_user(0, &sc->sc_fpc_csr); | ||
| 95 | if (err) | ||
| 96 | break; /* really bad sigcontext */ | ||
| 97 | } | ||
| 98 | return err; | ||
| 99 | } | ||
| 100 | |||
| 101 | static int protected_restore_fp_context(struct sigcontext __user *sc) | ||
| 102 | { | ||
| 103 | int err, tmp; | ||
| 104 | while (1) { | ||
| 105 | lock_fpu_owner(); | ||
| 106 | own_fpu_inatomic(0); | ||
| 107 | err = restore_fp_context(sc); /* this might fail */ | ||
| 108 | unlock_fpu_owner(); | ||
| 109 | if (likely(!err)) | ||
| 110 | break; | ||
| 111 | /* touch the sigcontext and try again */ | ||
| 112 | err = __get_user(tmp, &sc->sc_fpregs[0]) | | ||
| 113 | __get_user(tmp, &sc->sc_fpregs[31]) | | ||
| 114 | __get_user(tmp, &sc->sc_fpc_csr); | ||
| 115 | if (err) | ||
| 116 | break; /* really bad sigcontext */ | ||
| 117 | } | ||
| 118 | return err; | ||
| 119 | } | ||
| 120 | |||
| 81 | int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | 121 | int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) |
| 82 | { | 122 | { |
| 83 | int err = 0; | 123 | int err = 0; |
| @@ -113,10 +153,7 @@ int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
| 113 | * Save FPU state to signal context. Signal handler | 153 | * Save FPU state to signal context. Signal handler |
| 114 | * will "inherit" current FPU state. | 154 | * will "inherit" current FPU state. |
| 115 | */ | 155 | */ |
| 116 | own_fpu(1); | 156 | err |= protected_save_fp_context(sc); |
| 117 | enable_fp_in_kernel(); | ||
| 118 | err |= save_fp_context(sc); | ||
| 119 | disable_fp_in_kernel(); | ||
| 120 | } | 157 | } |
| 121 | return err; | 158 | return err; |
| 122 | } | 159 | } |
| @@ -148,7 +185,7 @@ check_and_restore_fp_context(struct sigcontext __user *sc) | |||
| 148 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); | 185 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); |
| 149 | if (err > 0) | 186 | if (err > 0) |
| 150 | err = 0; | 187 | err = 0; |
| 151 | err |= restore_fp_context(sc); | 188 | err |= protected_restore_fp_context(sc); |
| 152 | return err ?: sig; | 189 | return err ?: sig; |
| 153 | } | 190 | } |
| 154 | 191 | ||
| @@ -187,11 +224,8 @@ int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc) | |||
| 187 | 224 | ||
| 188 | if (used_math) { | 225 | if (used_math) { |
| 189 | /* restore fpu context if we have used it before */ | 226 | /* restore fpu context if we have used it before */ |
| 190 | own_fpu(0); | ||
| 191 | enable_fp_in_kernel(); | ||
| 192 | if (!err) | 227 | if (!err) |
| 193 | err = check_and_restore_fp_context(sc); | 228 | err = check_and_restore_fp_context(sc); |
| 194 | disable_fp_in_kernel(); | ||
| 195 | } else { | 229 | } else { |
| 196 | /* signal handler may have used FPU. Give it up. */ | 230 | /* signal handler may have used FPU. Give it up. */ |
| 197 | lose_fpu(0); | 231 | lose_fpu(0); |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 151fd2f0893a..b9a014411f83 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <linux/compat.h> | 22 | #include <linux/compat.h> |
| 23 | #include <linux/suspend.h> | 23 | #include <linux/suspend.h> |
| 24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
| 25 | #include <linux/uaccess.h> | ||
| 25 | 26 | ||
| 26 | #include <asm/abi.h> | 27 | #include <asm/abi.h> |
| 27 | #include <asm/asm.h> | 28 | #include <asm/asm.h> |
| @@ -29,7 +30,6 @@ | |||
| 29 | #include <linux/bitops.h> | 30 | #include <linux/bitops.h> |
| 30 | #include <asm/cacheflush.h> | 31 | #include <asm/cacheflush.h> |
| 31 | #include <asm/sim.h> | 32 | #include <asm/sim.h> |
| 32 | #include <asm/uaccess.h> | ||
| 33 | #include <asm/ucontext.h> | 33 | #include <asm/ucontext.h> |
| 34 | #include <asm/system.h> | 34 | #include <asm/system.h> |
| 35 | #include <asm/fpu.h> | 35 | #include <asm/fpu.h> |
| @@ -176,6 +176,46 @@ struct rt_sigframe32 { | |||
| 176 | /* | 176 | /* |
| 177 | * sigcontext handlers | 177 | * sigcontext handlers |
| 178 | */ | 178 | */ |
| 179 | static int protected_save_fp_context32(struct sigcontext32 __user *sc) | ||
| 180 | { | ||
| 181 | int err; | ||
| 182 | while (1) { | ||
| 183 | lock_fpu_owner(); | ||
| 184 | own_fpu_inatomic(1); | ||
| 185 | err = save_fp_context32(sc); /* this might fail */ | ||
| 186 | unlock_fpu_owner(); | ||
| 187 | if (likely(!err)) | ||
| 188 | break; | ||
| 189 | /* touch the sigcontext and try again */ | ||
| 190 | err = __put_user(0, &sc->sc_fpregs[0]) | | ||
| 191 | __put_user(0, &sc->sc_fpregs[31]) | | ||
| 192 | __put_user(0, &sc->sc_fpc_csr); | ||
| 193 | if (err) | ||
| 194 | break; /* really bad sigcontext */ | ||
| 195 | } | ||
| 196 | return err; | ||
| 197 | } | ||
| 198 | |||
| 199 | static int protected_restore_fp_context32(struct sigcontext32 __user *sc) | ||
| 200 | { | ||
| 201 | int err, tmp; | ||
| 202 | while (1) { | ||
| 203 | lock_fpu_owner(); | ||
| 204 | own_fpu_inatomic(0); | ||
| 205 | err = restore_fp_context32(sc); /* this might fail */ | ||
| 206 | unlock_fpu_owner(); | ||
| 207 | if (likely(!err)) | ||
| 208 | break; | ||
| 209 | /* touch the sigcontext and try again */ | ||
| 210 | err = __get_user(tmp, &sc->sc_fpregs[0]) | | ||
| 211 | __get_user(tmp, &sc->sc_fpregs[31]) | | ||
| 212 | __get_user(tmp, &sc->sc_fpc_csr); | ||
| 213 | if (err) | ||
| 214 | break; /* really bad sigcontext */ | ||
| 215 | } | ||
| 216 | return err; | ||
| 217 | } | ||
| 218 | |||
| 179 | static int setup_sigcontext32(struct pt_regs *regs, | 219 | static int setup_sigcontext32(struct pt_regs *regs, |
| 180 | struct sigcontext32 __user *sc) | 220 | struct sigcontext32 __user *sc) |
| 181 | { | 221 | { |
| @@ -209,10 +249,7 @@ static int setup_sigcontext32(struct pt_regs *regs, | |||
| 209 | * Save FPU state to signal context. Signal handler | 249 | * Save FPU state to signal context. Signal handler |
| 210 | * will "inherit" current FPU state. | 250 | * will "inherit" current FPU state. |
| 211 | */ | 251 | */ |
| 212 | own_fpu(1); | 252 | err |= protected_save_fp_context32(sc); |
| 213 | enable_fp_in_kernel(); | ||
| 214 | err |= save_fp_context32(sc); | ||
| 215 | disable_fp_in_kernel(); | ||
| 216 | } | 253 | } |
| 217 | return err; | 254 | return err; |
| 218 | } | 255 | } |
| @@ -225,7 +262,7 @@ check_and_restore_fp_context32(struct sigcontext32 __user *sc) | |||
| 225 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); | 262 | err = sig = fpcsr_pending(&sc->sc_fpc_csr); |
| 226 | if (err > 0) | 263 | if (err > 0) |
| 227 | err = 0; | 264 | err = 0; |
| 228 | err |= restore_fp_context32(sc); | 265 | err |= protected_restore_fp_context32(sc); |
| 229 | return err ?: sig; | 266 | return err ?: sig; |
| 230 | } | 267 | } |
| 231 | 268 | ||
| @@ -261,11 +298,8 @@ static int restore_sigcontext32(struct pt_regs *regs, | |||
| 261 | 298 | ||
| 262 | if (used_math) { | 299 | if (used_math) { |
| 263 | /* restore fpu context if we have used it before */ | 300 | /* restore fpu context if we have used it before */ |
| 264 | own_fpu(0); | ||
| 265 | enable_fp_in_kernel(); | ||
| 266 | if (!err) | 301 | if (!err) |
| 267 | err = check_and_restore_fp_context32(sc); | 302 | err = check_and_restore_fp_context32(sc); |
| 268 | disable_fp_in_kernel(); | ||
| 269 | } else { | 303 | } else { |
| 270 | /* signal handler may have used FPU. Give it up. */ | 304 | /* signal handler may have used FPU. Give it up. */ |
| 271 | lose_fpu(0); | 305 | lose_fpu(0); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 7d76a85422b2..493cb29b8a42 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
| @@ -650,7 +650,7 @@ asmlinkage void do_bp(struct pt_regs *regs) | |||
| 650 | unsigned int opcode, bcode; | 650 | unsigned int opcode, bcode; |
| 651 | siginfo_t info; | 651 | siginfo_t info; |
| 652 | 652 | ||
| 653 | if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) | 653 | if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) |
| 654 | goto out_sigsegv; | 654 | goto out_sigsegv; |
| 655 | 655 | ||
| 656 | /* | 656 | /* |
| @@ -700,7 +700,7 @@ asmlinkage void do_tr(struct pt_regs *regs) | |||
| 700 | unsigned int opcode, tcode = 0; | 700 | unsigned int opcode, tcode = 0; |
| 701 | siginfo_t info; | 701 | siginfo_t info; |
| 702 | 702 | ||
| 703 | if (get_user(opcode, (unsigned int __user *) exception_epc(regs))) | 703 | if (__get_user(opcode, (unsigned int __user *) exception_epc(regs))) |
| 704 | goto out_sigsegv; | 704 | goto out_sigsegv; |
| 705 | 705 | ||
| 706 | /* Immediate versions don't provide a code. */ | 706 | /* Immediate versions don't provide a code. */ |
| @@ -757,11 +757,12 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 757 | { | 757 | { |
| 758 | unsigned int cpid; | 758 | unsigned int cpid; |
| 759 | 759 | ||
| 760 | die_if_kernel("do_cpu invoked from kernel context!", regs); | ||
| 761 | |||
| 760 | cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; | 762 | cpid = (regs->cp0_cause >> CAUSEB_CE) & 3; |
| 761 | 763 | ||
| 762 | switch (cpid) { | 764 | switch (cpid) { |
| 763 | case 0: | 765 | case 0: |
| 764 | die_if_kernel("do_cpu invoked from kernel context!", regs); | ||
| 765 | if (!cpu_has_llsc) | 766 | if (!cpu_has_llsc) |
| 766 | if (!simulate_llsc(regs)) | 767 | if (!simulate_llsc(regs)) |
| 767 | return; | 768 | return; |
| @@ -772,9 +773,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 772 | break; | 773 | break; |
| 773 | 774 | ||
| 774 | case 1: | 775 | case 1: |
| 775 | if (!test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) | ||
| 776 | die_if_kernel("do_cpu invoked from kernel context!", | ||
| 777 | regs); | ||
| 778 | if (used_math()) /* Using the FPU again. */ | 776 | if (used_math()) /* Using the FPU again. */ |
| 779 | own_fpu(1); | 777 | own_fpu(1); |
| 780 | else { /* First time FPU user. */ | 778 | else { /* First time FPU user. */ |
| @@ -782,19 +780,7 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 782 | set_used_math(); | 780 | set_used_math(); |
| 783 | } | 781 | } |
| 784 | 782 | ||
| 785 | if (raw_cpu_has_fpu) { | 783 | if (!raw_cpu_has_fpu) { |
| 786 | if (test_thread_flag(TIF_ALLOW_FP_IN_KERNEL)) { | ||
| 787 | local_irq_disable(); | ||
| 788 | if (cpu_has_fpu) | ||
| 789 | regs->cp0_status |= ST0_CU1; | ||
| 790 | /* | ||
| 791 | * We must return without enabling | ||
| 792 | * interrupts to ensure keep FPU | ||
| 793 | * ownership until resume. | ||
| 794 | */ | ||
| 795 | return; | ||
| 796 | } | ||
| 797 | } else { | ||
| 798 | int sig; | 784 | int sig; |
| 799 | sig = fpu_emulator_cop1Handler(regs, | 785 | sig = fpu_emulator_cop1Handler(regs, |
| 800 | ¤t->thread.fpu, 0); | 786 | ¤t->thread.fpu, 0); |
| @@ -836,7 +822,6 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
| 836 | 822 | ||
| 837 | case 2: | 823 | case 2: |
| 838 | case 3: | 824 | case 3: |
| 839 | die_if_kernel("do_cpu invoked from kernel context!", regs); | ||
| 840 | break; | 825 | break; |
| 841 | } | 826 | } |
| 842 | 827 | ||
diff --git a/arch/mips/sibyte/sb1250/setup.c b/arch/mips/sibyte/sb1250/setup.c index 87188f0f6fbe..f4a6169aa0a4 100644 --- a/arch/mips/sibyte/sb1250/setup.c +++ b/arch/mips/sibyte/sb1250/setup.c | |||
| @@ -141,6 +141,18 @@ static int __init setup_bcm112x(void) | |||
| 141 | periph_rev = 3; | 141 | periph_rev = 3; |
| 142 | pass_str = "A2"; | 142 | pass_str = "A2"; |
| 143 | break; | 143 | break; |
| 144 | case K_SYS_REVISION_BCM112x_A3: | ||
| 145 | periph_rev = 3; | ||
| 146 | pass_str = "A3"; | ||
| 147 | break; | ||
| 148 | case K_SYS_REVISION_BCM112x_A4: | ||
| 149 | periph_rev = 3; | ||
| 150 | pass_str = "A4"; | ||
| 151 | break; | ||
| 152 | case K_SYS_REVISION_BCM112x_B0: | ||
| 153 | periph_rev = 3; | ||
| 154 | pass_str = "B0"; | ||
| 155 | break; | ||
| 144 | default: | 156 | default: |
| 145 | printk("Unknown %s rev %x\n", soc_str, soc_pass); | 157 | printk("Unknown %s rev %x\n", soc_str, soc_pass); |
| 146 | ret = 1; | 158 | ret = 1; |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b6491c020f26..9e3797167c81 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
| @@ -986,9 +986,9 @@ __cfq_dispatch_requests(struct cfq_data *cfqd, struct cfq_queue *cfqq, | |||
| 986 | * expire an async queue immediately if it has used up its slice. idle | 986 | * expire an async queue immediately if it has used up its slice. idle |
| 987 | * queue always expire after 1 dispatch round. | 987 | * queue always expire after 1 dispatch round. |
| 988 | */ | 988 | */ |
| 989 | if ((!cfq_cfqq_sync(cfqq) && | 989 | if (cfqd->busy_queues > 1 && ((!cfq_cfqq_sync(cfqq) && |
| 990 | cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) || | 990 | cfqd->dispatch_slice >= cfq_prio_to_maxrq(cfqd, cfqq)) || |
| 991 | cfq_class_idle(cfqq)) { | 991 | cfq_class_idle(cfqq))) { |
| 992 | cfqq->slice_end = jiffies + 1; | 992 | cfqq->slice_end = jiffies + 1; |
| 993 | cfq_slice_expired(cfqd, 0, 0); | 993 | cfq_slice_expired(cfqd, 0, 0); |
| 994 | } | 994 | } |
| @@ -1051,19 +1051,21 @@ cfq_dispatch_requests(request_queue_t *q, int force) | |||
| 1051 | while ((cfqq = cfq_select_queue(cfqd)) != NULL) { | 1051 | while ((cfqq = cfq_select_queue(cfqd)) != NULL) { |
| 1052 | int max_dispatch; | 1052 | int max_dispatch; |
| 1053 | 1053 | ||
| 1054 | /* | 1054 | if (cfqd->busy_queues > 1) { |
| 1055 | * Don't repeat dispatch from the previous queue. | 1055 | /* |
| 1056 | */ | 1056 | * Don't repeat dispatch from the previous queue. |
| 1057 | if (prev_cfqq == cfqq) | 1057 | */ |
| 1058 | break; | 1058 | if (prev_cfqq == cfqq) |
| 1059 | break; | ||
| 1059 | 1060 | ||
| 1060 | /* | 1061 | /* |
| 1061 | * So we have dispatched before in this round, if the | 1062 | * So we have dispatched before in this round, if the |
| 1062 | * next queue has idling enabled (must be sync), don't | 1063 | * next queue has idling enabled (must be sync), don't |
| 1063 | * allow it service until the previous have continued. | 1064 | * allow it service until the previous have continued. |
| 1064 | */ | 1065 | */ |
| 1065 | if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq)) | 1066 | if (cfqd->rq_in_driver && cfq_cfqq_idle_window(cfqq)) |
| 1066 | break; | 1067 | break; |
| 1068 | } | ||
| 1067 | 1069 | ||
| 1068 | cfq_clear_cfqq_must_dispatch(cfqq); | 1070 | cfq_clear_cfqq_must_dispatch(cfqq); |
| 1069 | cfq_clear_cfqq_wait_request(cfqq); | 1071 | cfq_clear_cfqq_wait_request(cfqq); |
| @@ -1370,7 +1372,9 @@ retry: | |||
| 1370 | atomic_set(&cfqq->ref, 0); | 1372 | atomic_set(&cfqq->ref, 0); |
| 1371 | cfqq->cfqd = cfqd; | 1373 | cfqq->cfqd = cfqd; |
| 1372 | 1374 | ||
| 1373 | cfq_mark_cfqq_idle_window(cfqq); | 1375 | if (key != CFQ_KEY_ASYNC) |
| 1376 | cfq_mark_cfqq_idle_window(cfqq); | ||
| 1377 | |||
| 1374 | cfq_mark_cfqq_prio_changed(cfqq); | 1378 | cfq_mark_cfqq_prio_changed(cfqq); |
| 1375 | cfq_mark_cfqq_queue_new(cfqq); | 1379 | cfq_mark_cfqq_queue_new(cfqq); |
| 1376 | cfq_init_prio_data(cfqq); | 1380 | cfq_init_prio_data(cfqq); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index ad2e91b4904f..797558941745 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
| @@ -38,7 +38,6 @@ | |||
| 38 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, | 38 | static struct nfs_page * nfs_update_request(struct nfs_open_context*, |
| 39 | struct page *, | 39 | struct page *, |
| 40 | unsigned int, unsigned int); | 40 | unsigned int, unsigned int); |
| 41 | static void nfs_mark_request_dirty(struct nfs_page *req); | ||
| 42 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); | 41 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); |
| 43 | static const struct rpc_call_ops nfs_write_partial_ops; | 42 | static const struct rpc_call_ops nfs_write_partial_ops; |
| 44 | static const struct rpc_call_ops nfs_write_full_ops; | 43 | static const struct rpc_call_ops nfs_write_full_ops; |
| @@ -255,7 +254,8 @@ static void nfs_end_page_writeback(struct page *page) | |||
| 255 | static int nfs_page_mark_flush(struct page *page) | 254 | static int nfs_page_mark_flush(struct page *page) |
| 256 | { | 255 | { |
| 257 | struct nfs_page *req; | 256 | struct nfs_page *req; |
| 258 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | 257 | struct nfs_inode *nfsi = NFS_I(page->mapping->host); |
| 258 | spinlock_t *req_lock = &nfsi->req_lock; | ||
| 259 | int ret; | 259 | int ret; |
| 260 | 260 | ||
| 261 | spin_lock(req_lock); | 261 | spin_lock(req_lock); |
| @@ -279,11 +279,23 @@ static int nfs_page_mark_flush(struct page *page) | |||
| 279 | return ret; | 279 | return ret; |
| 280 | spin_lock(req_lock); | 280 | spin_lock(req_lock); |
| 281 | } | 281 | } |
| 282 | spin_unlock(req_lock); | 282 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { |
| 283 | /* This request is marked for commit */ | ||
| 284 | spin_unlock(req_lock); | ||
| 285 | nfs_unlock_request(req); | ||
| 286 | return 1; | ||
| 287 | } | ||
| 283 | if (nfs_set_page_writeback(page) == 0) { | 288 | if (nfs_set_page_writeback(page) == 0) { |
| 284 | nfs_list_remove_request(req); | 289 | nfs_list_remove_request(req); |
| 285 | nfs_mark_request_dirty(req); | 290 | /* add the request to the inode's dirty list. */ |
| 286 | } | 291 | radix_tree_tag_set(&nfsi->nfs_page_tree, |
| 292 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
| 293 | nfs_list_add_request(req, &nfsi->dirty); | ||
| 294 | nfsi->ndirty++; | ||
| 295 | spin_unlock(req_lock); | ||
| 296 | __mark_inode_dirty(page->mapping->host, I_DIRTY_PAGES); | ||
| 297 | } else | ||
| 298 | spin_unlock(req_lock); | ||
| 287 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | 299 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); |
| 288 | nfs_unlock_request(req); | 300 | nfs_unlock_request(req); |
| 289 | return ret; | 301 | return ret; |
| @@ -376,6 +388,8 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
| 376 | } | 388 | } |
| 377 | SetPagePrivate(req->wb_page); | 389 | SetPagePrivate(req->wb_page); |
| 378 | set_page_private(req->wb_page, (unsigned long)req); | 390 | set_page_private(req->wb_page, (unsigned long)req); |
| 391 | if (PageDirty(req->wb_page)) | ||
| 392 | set_bit(PG_NEED_FLUSH, &req->wb_flags); | ||
| 379 | nfsi->npages++; | 393 | nfsi->npages++; |
| 380 | atomic_inc(&req->wb_count); | 394 | atomic_inc(&req->wb_count); |
| 381 | return 0; | 395 | return 0; |
| @@ -395,6 +409,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
| 395 | set_page_private(req->wb_page, 0); | 409 | set_page_private(req->wb_page, 0); |
| 396 | ClearPagePrivate(req->wb_page); | 410 | ClearPagePrivate(req->wb_page); |
| 397 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 411 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
| 412 | if (test_and_clear_bit(PG_NEED_FLUSH, &req->wb_flags)) | ||
| 413 | __set_page_dirty_nobuffers(req->wb_page); | ||
| 398 | nfsi->npages--; | 414 | nfsi->npages--; |
| 399 | if (!nfsi->npages) { | 415 | if (!nfsi->npages) { |
| 400 | spin_unlock(&nfsi->req_lock); | 416 | spin_unlock(&nfsi->req_lock); |
| @@ -406,24 +422,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
| 406 | nfs_release_request(req); | 422 | nfs_release_request(req); |
| 407 | } | 423 | } |
| 408 | 424 | ||
| 409 | /* | ||
| 410 | * Add a request to the inode's dirty list. | ||
| 411 | */ | ||
| 412 | static void | ||
| 413 | nfs_mark_request_dirty(struct nfs_page *req) | ||
| 414 | { | ||
| 415 | struct inode *inode = req->wb_context->dentry->d_inode; | ||
| 416 | struct nfs_inode *nfsi = NFS_I(inode); | ||
| 417 | |||
| 418 | spin_lock(&nfsi->req_lock); | ||
| 419 | radix_tree_tag_set(&nfsi->nfs_page_tree, | ||
| 420 | req->wb_index, NFS_PAGE_TAG_DIRTY); | ||
| 421 | nfs_list_add_request(req, &nfsi->dirty); | ||
| 422 | nfsi->ndirty++; | ||
| 423 | spin_unlock(&nfsi->req_lock); | ||
| 424 | __mark_inode_dirty(inode, I_DIRTY_PAGES); | ||
| 425 | } | ||
| 426 | |||
| 427 | static void | 425 | static void |
| 428 | nfs_redirty_request(struct nfs_page *req) | 426 | nfs_redirty_request(struct nfs_page *req) |
| 429 | { | 427 | { |
| @@ -438,7 +436,7 @@ nfs_dirty_request(struct nfs_page *req) | |||
| 438 | { | 436 | { |
| 439 | struct page *page = req->wb_page; | 437 | struct page *page = req->wb_page; |
| 440 | 438 | ||
| 441 | if (page == NULL) | 439 | if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags)) |
| 442 | return 0; | 440 | return 0; |
| 443 | return !PageWriteback(req->wb_page); | 441 | return !PageWriteback(req->wb_page); |
| 444 | } | 442 | } |
| @@ -456,10 +454,48 @@ nfs_mark_request_commit(struct nfs_page *req) | |||
| 456 | spin_lock(&nfsi->req_lock); | 454 | spin_lock(&nfsi->req_lock); |
| 457 | nfs_list_add_request(req, &nfsi->commit); | 455 | nfs_list_add_request(req, &nfsi->commit); |
| 458 | nfsi->ncommit++; | 456 | nfsi->ncommit++; |
| 457 | set_bit(PG_NEED_COMMIT, &(req)->wb_flags); | ||
| 459 | spin_unlock(&nfsi->req_lock); | 458 | spin_unlock(&nfsi->req_lock); |
| 460 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 459 | inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
| 461 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); | 460 | __mark_inode_dirty(inode, I_DIRTY_DATASYNC); |
| 462 | } | 461 | } |
| 462 | |||
| 463 | static inline | ||
| 464 | int nfs_write_need_commit(struct nfs_write_data *data) | ||
| 465 | { | ||
| 466 | return data->verf.committed != NFS_FILE_SYNC; | ||
| 467 | } | ||
| 468 | |||
| 469 | static inline | ||
| 470 | int nfs_reschedule_unstable_write(struct nfs_page *req) | ||
| 471 | { | ||
| 472 | if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) { | ||
| 473 | nfs_mark_request_commit(req); | ||
| 474 | return 1; | ||
| 475 | } | ||
| 476 | if (test_and_clear_bit(PG_NEED_RESCHED, &req->wb_flags)) { | ||
| 477 | nfs_redirty_request(req); | ||
| 478 | return 1; | ||
| 479 | } | ||
| 480 | return 0; | ||
| 481 | } | ||
| 482 | #else | ||
| 483 | static inline void | ||
| 484 | nfs_mark_request_commit(struct nfs_page *req) | ||
| 485 | { | ||
| 486 | } | ||
| 487 | |||
| 488 | static inline | ||
| 489 | int nfs_write_need_commit(struct nfs_write_data *data) | ||
| 490 | { | ||
| 491 | return 0; | ||
| 492 | } | ||
| 493 | |||
| 494 | static inline | ||
| 495 | int nfs_reschedule_unstable_write(struct nfs_page *req) | ||
| 496 | { | ||
| 497 | return 0; | ||
| 498 | } | ||
| 463 | #endif | 499 | #endif |
| 464 | 500 | ||
| 465 | /* | 501 | /* |
| @@ -520,6 +556,7 @@ static void nfs_cancel_commit_list(struct list_head *head) | |||
| 520 | req = nfs_list_entry(head->next); | 556 | req = nfs_list_entry(head->next); |
| 521 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 557 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
| 522 | nfs_list_remove_request(req); | 558 | nfs_list_remove_request(req); |
| 559 | clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); | ||
| 523 | nfs_inode_remove_request(req); | 560 | nfs_inode_remove_request(req); |
| 524 | nfs_unlock_request(req); | 561 | nfs_unlock_request(req); |
| 525 | } | 562 | } |
| @@ -746,26 +783,12 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
| 746 | 783 | ||
| 747 | static void nfs_writepage_release(struct nfs_page *req) | 784 | static void nfs_writepage_release(struct nfs_page *req) |
| 748 | { | 785 | { |
| 749 | nfs_end_page_writeback(req->wb_page); | ||
| 750 | 786 | ||
| 751 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 787 | if (PageError(req->wb_page) || !nfs_reschedule_unstable_write(req)) { |
| 752 | if (!PageError(req->wb_page)) { | 788 | nfs_end_page_writeback(req->wb_page); |
| 753 | if (NFS_NEED_RESCHED(req)) { | 789 | nfs_inode_remove_request(req); |
| 754 | nfs_redirty_request(req); | 790 | } else |
| 755 | goto out; | 791 | nfs_end_page_writeback(req->wb_page); |
| 756 | } else if (NFS_NEED_COMMIT(req)) { | ||
| 757 | nfs_mark_request_commit(req); | ||
| 758 | goto out; | ||
| 759 | } | ||
| 760 | } | ||
| 761 | nfs_inode_remove_request(req); | ||
| 762 | |||
| 763 | out: | ||
| 764 | nfs_clear_commit(req); | ||
| 765 | nfs_clear_reschedule(req); | ||
| 766 | #else | ||
| 767 | nfs_inode_remove_request(req); | ||
| 768 | #endif | ||
| 769 | nfs_clear_page_writeback(req); | 792 | nfs_clear_page_writeback(req); |
| 770 | } | 793 | } |
| 771 | 794 | ||
| @@ -897,8 +920,8 @@ out_bad: | |||
| 897 | list_del(&data->pages); | 920 | list_del(&data->pages); |
| 898 | nfs_writedata_release(data); | 921 | nfs_writedata_release(data); |
| 899 | } | 922 | } |
| 900 | nfs_end_page_writeback(req->wb_page); | ||
| 901 | nfs_redirty_request(req); | 923 | nfs_redirty_request(req); |
| 924 | nfs_end_page_writeback(req->wb_page); | ||
| 902 | nfs_clear_page_writeback(req); | 925 | nfs_clear_page_writeback(req); |
| 903 | return -ENOMEM; | 926 | return -ENOMEM; |
| 904 | } | 927 | } |
| @@ -943,8 +966,8 @@ static int nfs_flush_one(struct inode *inode, struct list_head *head, int how) | |||
| 943 | while (!list_empty(head)) { | 966 | while (!list_empty(head)) { |
| 944 | struct nfs_page *req = nfs_list_entry(head->next); | 967 | struct nfs_page *req = nfs_list_entry(head->next); |
| 945 | nfs_list_remove_request(req); | 968 | nfs_list_remove_request(req); |
| 946 | nfs_end_page_writeback(req->wb_page); | ||
| 947 | nfs_redirty_request(req); | 969 | nfs_redirty_request(req); |
| 970 | nfs_end_page_writeback(req->wb_page); | ||
| 948 | nfs_clear_page_writeback(req); | 971 | nfs_clear_page_writeback(req); |
| 949 | } | 972 | } |
| 950 | return -ENOMEM; | 973 | return -ENOMEM; |
| @@ -979,8 +1002,8 @@ out_err: | |||
| 979 | while (!list_empty(head)) { | 1002 | while (!list_empty(head)) { |
| 980 | req = nfs_list_entry(head->next); | 1003 | req = nfs_list_entry(head->next); |
| 981 | nfs_list_remove_request(req); | 1004 | nfs_list_remove_request(req); |
| 982 | nfs_end_page_writeback(req->wb_page); | ||
| 983 | nfs_redirty_request(req); | 1005 | nfs_redirty_request(req); |
| 1006 | nfs_end_page_writeback(req->wb_page); | ||
| 984 | nfs_clear_page_writeback(req); | 1007 | nfs_clear_page_writeback(req); |
| 985 | } | 1008 | } |
| 986 | return error; | 1009 | return error; |
| @@ -1008,22 +1031,28 @@ static void nfs_writeback_done_partial(struct rpc_task *task, void *calldata) | |||
| 1008 | nfs_set_pageerror(page); | 1031 | nfs_set_pageerror(page); |
| 1009 | req->wb_context->error = task->tk_status; | 1032 | req->wb_context->error = task->tk_status; |
| 1010 | dprintk(", error = %d\n", task->tk_status); | 1033 | dprintk(", error = %d\n", task->tk_status); |
| 1011 | } else { | 1034 | goto out; |
| 1012 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | ||
| 1013 | if (data->verf.committed < NFS_FILE_SYNC) { | ||
| 1014 | if (!NFS_NEED_COMMIT(req)) { | ||
| 1015 | nfs_defer_commit(req); | ||
| 1016 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); | ||
| 1017 | dprintk(" defer commit\n"); | ||
| 1018 | } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) { | ||
| 1019 | nfs_defer_reschedule(req); | ||
| 1020 | dprintk(" server reboot detected\n"); | ||
| 1021 | } | ||
| 1022 | } else | ||
| 1023 | #endif | ||
| 1024 | dprintk(" OK\n"); | ||
| 1025 | } | 1035 | } |
| 1026 | 1036 | ||
| 1037 | if (nfs_write_need_commit(data)) { | ||
| 1038 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
| 1039 | |||
| 1040 | spin_lock(req_lock); | ||
| 1041 | if (test_bit(PG_NEED_RESCHED, &req->wb_flags)) { | ||
| 1042 | /* Do nothing we need to resend the writes */ | ||
| 1043 | } else if (!test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags)) { | ||
| 1044 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); | ||
| 1045 | dprintk(" defer commit\n"); | ||
| 1046 | } else if (memcmp(&req->wb_verf, &data->verf, sizeof(req->wb_verf))) { | ||
| 1047 | set_bit(PG_NEED_RESCHED, &req->wb_flags); | ||
| 1048 | clear_bit(PG_NEED_COMMIT, &req->wb_flags); | ||
| 1049 | dprintk(" server reboot detected\n"); | ||
| 1050 | } | ||
| 1051 | spin_unlock(req_lock); | ||
| 1052 | } else | ||
| 1053 | dprintk(" OK\n"); | ||
| 1054 | |||
| 1055 | out: | ||
| 1027 | if (atomic_dec_and_test(&req->wb_complete)) | 1056 | if (atomic_dec_and_test(&req->wb_complete)) |
| 1028 | nfs_writepage_release(req); | 1057 | nfs_writepage_release(req); |
| 1029 | } | 1058 | } |
| @@ -1064,25 +1093,21 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) | |||
| 1064 | if (task->tk_status < 0) { | 1093 | if (task->tk_status < 0) { |
| 1065 | nfs_set_pageerror(page); | 1094 | nfs_set_pageerror(page); |
| 1066 | req->wb_context->error = task->tk_status; | 1095 | req->wb_context->error = task->tk_status; |
| 1067 | nfs_end_page_writeback(page); | ||
| 1068 | nfs_inode_remove_request(req); | ||
| 1069 | dprintk(", error = %d\n", task->tk_status); | 1096 | dprintk(", error = %d\n", task->tk_status); |
| 1070 | goto next; | 1097 | goto remove_request; |
| 1071 | } | 1098 | } |
| 1072 | nfs_end_page_writeback(page); | ||
| 1073 | 1099 | ||
| 1074 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1100 | if (nfs_write_need_commit(data)) { |
| 1075 | if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { | 1101 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); |
| 1076 | nfs_inode_remove_request(req); | 1102 | nfs_mark_request_commit(req); |
| 1077 | dprintk(" OK\n"); | 1103 | nfs_end_page_writeback(page); |
| 1104 | dprintk(" marked for commit\n"); | ||
| 1078 | goto next; | 1105 | goto next; |
| 1079 | } | 1106 | } |
| 1080 | memcpy(&req->wb_verf, &data->verf, sizeof(req->wb_verf)); | 1107 | dprintk(" OK\n"); |
| 1081 | nfs_mark_request_commit(req); | 1108 | remove_request: |
| 1082 | dprintk(" marked for commit\n"); | 1109 | nfs_end_page_writeback(page); |
| 1083 | #else | ||
| 1084 | nfs_inode_remove_request(req); | 1110 | nfs_inode_remove_request(req); |
| 1085 | #endif | ||
| 1086 | next: | 1111 | next: |
| 1087 | nfs_clear_page_writeback(req); | 1112 | nfs_clear_page_writeback(req); |
| 1088 | } | 1113 | } |
| @@ -1270,6 +1295,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) | |||
| 1270 | while (!list_empty(&data->pages)) { | 1295 | while (!list_empty(&data->pages)) { |
| 1271 | req = nfs_list_entry(data->pages.next); | 1296 | req = nfs_list_entry(data->pages.next); |
| 1272 | nfs_list_remove_request(req); | 1297 | nfs_list_remove_request(req); |
| 1298 | clear_bit(PG_NEED_COMMIT, &(req)->wb_flags); | ||
| 1273 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); | 1299 | dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS); |
| 1274 | 1300 | ||
| 1275 | dprintk("NFS: commit (%s/%Ld %d@%Ld)", | 1301 | dprintk("NFS: commit (%s/%Ld %d@%Ld)", |
| @@ -1505,15 +1531,22 @@ int nfs_wb_page(struct inode *inode, struct page* page) | |||
| 1505 | 1531 | ||
| 1506 | int nfs_set_page_dirty(struct page *page) | 1532 | int nfs_set_page_dirty(struct page *page) |
| 1507 | { | 1533 | { |
| 1534 | spinlock_t *req_lock = &NFS_I(page->mapping->host)->req_lock; | ||
| 1508 | struct nfs_page *req; | 1535 | struct nfs_page *req; |
| 1536 | int ret; | ||
| 1509 | 1537 | ||
| 1510 | req = nfs_page_find_request(page); | 1538 | spin_lock(req_lock); |
| 1539 | req = nfs_page_find_request_locked(page); | ||
| 1511 | if (req != NULL) { | 1540 | if (req != NULL) { |
| 1512 | /* Mark any existing write requests for flushing */ | 1541 | /* Mark any existing write requests for flushing */ |
| 1513 | set_bit(PG_NEED_FLUSH, &req->wb_flags); | 1542 | ret = !test_and_set_bit(PG_NEED_FLUSH, &req->wb_flags); |
| 1543 | spin_unlock(req_lock); | ||
| 1514 | nfs_release_request(req); | 1544 | nfs_release_request(req); |
| 1545 | return ret; | ||
| 1515 | } | 1546 | } |
| 1516 | return __set_page_dirty_nobuffers(page); | 1547 | ret = __set_page_dirty_nobuffers(page); |
| 1548 | spin_unlock(req_lock); | ||
| 1549 | return ret; | ||
| 1517 | } | 1550 | } |
| 1518 | 1551 | ||
| 1519 | 1552 | ||
diff --git a/include/asm-mips/bug.h b/include/asm-mips/bug.h index 4d560a533940..7eb63de808bc 100644 --- a/include/asm-mips/bug.h +++ b/include/asm-mips/bug.h | |||
| @@ -18,7 +18,8 @@ do { \ | |||
| 18 | 18 | ||
| 19 | #define BUG_ON(condition) \ | 19 | #define BUG_ON(condition) \ |
| 20 | do { \ | 20 | do { \ |
| 21 | __asm__ __volatile__("tne $0, %0" : : "r" (condition)); \ | 21 | __asm__ __volatile__("tne $0, %0, %1" \ |
| 22 | : : "r" (condition), "i" (BRK_BUG)); \ | ||
| 22 | } while (0) | 23 | } while (0) |
| 23 | 24 | ||
| 24 | #define HAVE_ARCH_BUG_ON | 25 | #define HAVE_ARCH_BUG_ON |
diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h index 20a81e1548f5..290485ac5407 100644 --- a/include/asm-mips/checksum.h +++ b/include/asm-mips/checksum.h | |||
| @@ -166,7 +166,7 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, | |||
| 166 | #else | 166 | #else |
| 167 | "r" (proto + len), | 167 | "r" (proto + len), |
| 168 | #endif | 168 | #endif |
| 169 | "r" (sum)); | 169 | "r" ((__force unsigned long)sum)); |
| 170 | 170 | ||
| 171 | return sum; | 171 | return sum; |
| 172 | } | 172 | } |
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h index 4e12d1f9534f..b414a7d9db43 100644 --- a/include/asm-mips/fpu.h +++ b/include/asm-mips/fpu.h | |||
| @@ -68,8 +68,6 @@ do { \ | |||
| 68 | /* We don't care about the c0 hazard here */ \ | 68 | /* We don't care about the c0 hazard here */ \ |
| 69 | } while (0) | 69 | } while (0) |
| 70 | 70 | ||
| 71 | #define __fpu_enabled() (read_c0_status() & ST0_CU1) | ||
| 72 | |||
| 73 | #define enable_fpu() \ | 71 | #define enable_fpu() \ |
| 74 | do { \ | 72 | do { \ |
| 75 | if (cpu_has_fpu) \ | 73 | if (cpu_has_fpu) \ |
| @@ -102,14 +100,19 @@ static inline void __own_fpu(void) | |||
| 102 | set_thread_flag(TIF_USEDFPU); | 100 | set_thread_flag(TIF_USEDFPU); |
| 103 | } | 101 | } |
| 104 | 102 | ||
| 105 | static inline void own_fpu(int restore) | 103 | static inline void own_fpu_inatomic(int restore) |
| 106 | { | 104 | { |
| 107 | preempt_disable(); | ||
| 108 | if (cpu_has_fpu && !__is_fpu_owner()) { | 105 | if (cpu_has_fpu && !__is_fpu_owner()) { |
| 109 | __own_fpu(); | 106 | __own_fpu(); |
| 110 | if (restore) | 107 | if (restore) |
| 111 | _restore_fp(current); | 108 | _restore_fp(current); |
| 112 | } | 109 | } |
| 110 | } | ||
| 111 | |||
| 112 | static inline void own_fpu(int restore) | ||
| 113 | { | ||
| 114 | preempt_disable(); | ||
| 115 | own_fpu_inatomic(restore); | ||
| 113 | preempt_enable(); | 116 | preempt_enable(); |
| 114 | } | 117 | } |
| 115 | 118 | ||
| @@ -162,18 +165,4 @@ static inline fpureg_t *get_fpu_regs(struct task_struct *tsk) | |||
| 162 | return tsk->thread.fpu.fpr; | 165 | return tsk->thread.fpu.fpr; |
| 163 | } | 166 | } |
| 164 | 167 | ||
| 165 | static inline void enable_fp_in_kernel(void) | ||
| 166 | { | ||
| 167 | set_thread_flag(TIF_ALLOW_FP_IN_KERNEL); | ||
| 168 | /* make sure CU1 and FPU ownership are consistent */ | ||
| 169 | if (!__is_fpu_owner() && __fpu_enabled()) | ||
| 170 | __disable_fpu(); | ||
| 171 | } | ||
| 172 | |||
| 173 | static inline void disable_fp_in_kernel(void) | ||
| 174 | { | ||
| 175 | BUG_ON(!__is_fpu_owner() && __fpu_enabled()); | ||
| 176 | clear_thread_flag(TIF_ALLOW_FP_IN_KERNEL); | ||
| 177 | } | ||
| 178 | |||
| 179 | #endif /* _ASM_FPU_H */ | 168 | #endif /* _ASM_FPU_H */ |
diff --git a/include/asm-mips/sibyte/sb1250_scd.h b/include/asm-mips/sibyte/sb1250_scd.h index 7ed0bb611e56..b6a7d8f6ced5 100644 --- a/include/asm-mips/sibyte/sb1250_scd.h +++ b/include/asm-mips/sibyte/sb1250_scd.h | |||
| @@ -84,6 +84,7 @@ | |||
| 84 | #define K_SYS_REVISION_BCM112x_A2 0x21 | 84 | #define K_SYS_REVISION_BCM112x_A2 0x21 |
| 85 | #define K_SYS_REVISION_BCM112x_A3 0x22 | 85 | #define K_SYS_REVISION_BCM112x_A3 0x22 |
| 86 | #define K_SYS_REVISION_BCM112x_A4 0x23 | 86 | #define K_SYS_REVISION_BCM112x_A4 0x23 |
| 87 | #define K_SYS_REVISION_BCM112x_B0 0x30 | ||
| 87 | 88 | ||
| 88 | #define K_SYS_REVISION_BCM1480_S0 0x01 | 89 | #define K_SYS_REVISION_BCM1480_S0 0x01 |
| 89 | #define K_SYS_REVISION_BCM1480_A1 0x02 | 90 | #define K_SYS_REVISION_BCM1480_A1 0x02 |
diff --git a/include/asm-mips/thread_info.h b/include/asm-mips/thread_info.h index 6cf05f4a4e7e..fbcda8204473 100644 --- a/include/asm-mips/thread_info.h +++ b/include/asm-mips/thread_info.h | |||
| @@ -119,7 +119,6 @@ register struct thread_info *__current_thread_info __asm__("$28"); | |||
| 119 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ | 119 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling TIF_NEED_RESCHED */ |
| 120 | #define TIF_MEMDIE 18 | 120 | #define TIF_MEMDIE 18 |
| 121 | #define TIF_FREEZE 19 | 121 | #define TIF_FREEZE 19 |
| 122 | #define TIF_ALLOW_FP_IN_KERNEL 20 | ||
| 123 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ | 122 | #define TIF_SYSCALL_TRACE 31 /* syscall trace active */ |
| 124 | 123 | ||
| 125 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | 124 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index d111be639140..16b0266b14fd 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
| @@ -49,8 +49,6 @@ struct nfs_page { | |||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) | 51 | #define NFS_WBACK_BUSY(req) (test_bit(PG_BUSY,&(req)->wb_flags)) |
| 52 | #define NFS_NEED_COMMIT(req) (test_bit(PG_NEED_COMMIT,&(req)->wb_flags)) | ||
| 53 | #define NFS_NEED_RESCHED(req) (test_bit(PG_NEED_RESCHED,&(req)->wb_flags)) | ||
| 54 | 52 | ||
| 55 | extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, | 53 | extern struct nfs_page *nfs_create_request(struct nfs_open_context *ctx, |
| 56 | struct inode *inode, | 54 | struct inode *inode, |
| @@ -121,34 +119,6 @@ nfs_list_remove_request(struct nfs_page *req) | |||
| 121 | req->wb_list_head = NULL; | 119 | req->wb_list_head = NULL; |
| 122 | } | 120 | } |
| 123 | 121 | ||
| 124 | static inline int | ||
| 125 | nfs_defer_commit(struct nfs_page *req) | ||
| 126 | { | ||
| 127 | return !test_and_set_bit(PG_NEED_COMMIT, &req->wb_flags); | ||
| 128 | } | ||
| 129 | |||
| 130 | static inline void | ||
| 131 | nfs_clear_commit(struct nfs_page *req) | ||
| 132 | { | ||
| 133 | smp_mb__before_clear_bit(); | ||
| 134 | clear_bit(PG_NEED_COMMIT, &req->wb_flags); | ||
| 135 | smp_mb__after_clear_bit(); | ||
| 136 | } | ||
| 137 | |||
| 138 | static inline int | ||
| 139 | nfs_defer_reschedule(struct nfs_page *req) | ||
| 140 | { | ||
| 141 | return !test_and_set_bit(PG_NEED_RESCHED, &req->wb_flags); | ||
| 142 | } | ||
| 143 | |||
| 144 | static inline void | ||
| 145 | nfs_clear_reschedule(struct nfs_page *req) | ||
| 146 | { | ||
| 147 | smp_mb__before_clear_bit(); | ||
| 148 | clear_bit(PG_NEED_RESCHED, &req->wb_flags); | ||
| 149 | smp_mb__after_clear_bit(); | ||
| 150 | } | ||
| 151 | |||
| 152 | static inline struct nfs_page * | 122 | static inline struct nfs_page * |
| 153 | nfs_list_entry(struct list_head *head) | 123 | nfs_list_entry(struct list_head *head) |
| 154 | { | 124 | { |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 6d7221fe990a..396cdbe249d1 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1046,6 +1046,8 @@ call_status(struct rpc_task *task) | |||
| 1046 | rpc_delay(task, 3*HZ); | 1046 | rpc_delay(task, 3*HZ); |
| 1047 | case -ETIMEDOUT: | 1047 | case -ETIMEDOUT: |
| 1048 | task->tk_action = call_timeout; | 1048 | task->tk_action = call_timeout; |
| 1049 | if (task->tk_client->cl_discrtry) | ||
| 1050 | xprt_disconnect(task->tk_xprt); | ||
| 1049 | break; | 1051 | break; |
| 1050 | case -ECONNREFUSED: | 1052 | case -ECONNREFUSED: |
| 1051 | case -ENOTCONN: | 1053 | case -ENOTCONN: |
| @@ -1169,6 +1171,8 @@ call_decode(struct rpc_task *task) | |||
| 1169 | out_retry: | 1171 | out_retry: |
| 1170 | req->rq_received = req->rq_private_buf.len = 0; | 1172 | req->rq_received = req->rq_private_buf.len = 0; |
| 1171 | task->tk_status = 0; | 1173 | task->tk_status = 0; |
| 1174 | if (task->tk_client->cl_discrtry) | ||
| 1175 | xprt_disconnect(task->tk_xprt); | ||
| 1172 | } | 1176 | } |
| 1173 | 1177 | ||
| 1174 | /* | 1178 | /* |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index ee6ffa01dfb1..456a14510308 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
| @@ -735,16 +735,6 @@ void xprt_transmit(struct rpc_task *task) | |||
| 735 | xprt_reset_majortimeo(req); | 735 | xprt_reset_majortimeo(req); |
| 736 | /* Turn off autodisconnect */ | 736 | /* Turn off autodisconnect */ |
| 737 | del_singleshot_timer_sync(&xprt->timer); | 737 | del_singleshot_timer_sync(&xprt->timer); |
| 738 | } else { | ||
| 739 | /* If all request bytes have been sent, | ||
| 740 | * then we must be retransmitting this one */ | ||
| 741 | if (!req->rq_bytes_sent) { | ||
| 742 | if (task->tk_client->cl_discrtry) { | ||
| 743 | xprt_disconnect(xprt); | ||
| 744 | task->tk_status = -ENOTCONN; | ||
| 745 | return; | ||
| 746 | } | ||
| 747 | } | ||
| 748 | } | 738 | } |
| 749 | } else if (!req->rq_bytes_sent) | 739 | } else if (!req->rq_bytes_sent) |
| 750 | return; | 740 | return; |
