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; |