diff options
author | Mike Pagano <mpagano@gentoo.org> | 2017-09-27 06:38:21 -0400 |
---|---|---|
committer | Mike Pagano <mpagano@gentoo.org> | 2017-09-27 06:38:21 -0400 |
commit | c6f3d3e1793a3838f6ad87a32e56d8cc22451dee (patch) | |
tree | 754caf70cff78fe45a4f2e8b9a4db1952f854117 | |
parent | Remove redundant patch (diff) | |
download | linux-patches-c6f3d3e1793a3838f6ad87a32e56d8cc22451dee.tar.gz linux-patches-c6f3d3e1793a3838f6ad87a32e56d8cc22451dee.tar.bz2 linux-patches-c6f3d3e1793a3838f6ad87a32e56d8cc22451dee.zip |
Linux patch 4.4.894.4-93
-rw-r--r-- | 0000_README | 4 | ||||
-rw-r--r-- | 1088_linux-4.4.89.patch | 2820 |
2 files changed, 2824 insertions, 0 deletions
diff --git a/0000_README b/0000_README index 44fa8917..43c1c6e8 100644 --- a/0000_README +++ b/0000_README @@ -395,6 +395,10 @@ Patch: 1087_linux-4.4.88.patch From: http://www.kernel.org Desc: Linux 4.4.88 +Patch: 1088_linux-4.4.89.patch +From: http://www.kernel.org +Desc: Linux 4.4.89 + Patch: 1500_XATTR_USER_PREFIX.patch From: https://bugs.gentoo.org/show_bug.cgi?id=470644 Desc: Support for namespace user.pax.* on tmpfs. diff --git a/1088_linux-4.4.89.patch b/1088_linux-4.4.89.patch new file mode 100644 index 00000000..6b0d92eb --- /dev/null +++ b/1088_linux-4.4.89.patch @@ -0,0 +1,2820 @@ +diff --git a/Makefile b/Makefile +index 788d90a0051b..7e4c46b375b3 100644 +--- a/Makefile ++++ b/Makefile +@@ -1,6 +1,6 @@ + VERSION = 4 + PATCHLEVEL = 4 +-SUBLEVEL = 88 ++SUBLEVEL = 89 + EXTRAVERSION = + NAME = Blurry Fish Butt + +diff --git a/arch/arc/kernel/entry.S b/arch/arc/kernel/entry.S +index 2efb0625331d..db1eee5fe502 100644 +--- a/arch/arc/kernel/entry.S ++++ b/arch/arc/kernel/entry.S +@@ -104,6 +104,12 @@ ENTRY(EV_MachineCheck) + lr r0, [efa] + mov r1, sp + ++ ; hardware auto-disables MMU, re-enable it to allow kernel vaddr ++ ; access for say stack unwinding of modules for crash dumps ++ lr r3, [ARC_REG_PID] ++ or r3, r3, MMU_ENABLE ++ sr r3, [ARC_REG_PID] ++ + lsr r3, r2, 8 + bmsk r3, r3, 7 + brne r3, ECR_C_MCHK_DUP_TLB, 1f +diff --git a/arch/arc/mm/tlb.c b/arch/arc/mm/tlb.c +index daf2bf52b984..97e9582dcf99 100644 +--- a/arch/arc/mm/tlb.c ++++ b/arch/arc/mm/tlb.c +@@ -885,9 +885,6 @@ void do_tlb_overlap_fault(unsigned long cause, unsigned long address, + + local_irq_save(flags); + +- /* re-enable the MMU */ +- write_aux_reg(ARC_REG_PID, MMU_ENABLE | read_aux_reg(ARC_REG_PID)); +- + /* loop thru all sets of TLB */ + for (set = 0; set < mmu->sets; set++) { + +diff --git a/arch/mips/math-emu/dp_fmax.c b/arch/mips/math-emu/dp_fmax.c +index fd71b8daaaf2..5bec64f2884e 100644 +--- a/arch/mips/math-emu/dp_fmax.c ++++ b/arch/mips/math-emu/dp_fmax.c +@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + return ys ? x : y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmax(union ieee754dp x, union ieee754dp y) + else if (xs < ys) + return x; + +- /* Compare exponent */ +- if (xe > ye) +- return x; +- else if (xe < ye) +- return y; ++ /* Signs of inputs are equal, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return y; ++ return x; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return y; +- return x; ++ return x; ++ return y; + } + + union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) +@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,6 +202,9 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754dp_inf(xs & ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): +@@ -171,7 +212,6 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + return x; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +@@ -180,9 +220,7 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + return y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmaxa(union ieee754dp x, union ieee754dp y) + return y; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) + return y; +- return x; ++ else if (xm > ym) ++ return x; ++ else if (xs == 0) ++ return x; ++ return y; + } +diff --git a/arch/mips/math-emu/dp_fmin.c b/arch/mips/math-emu/dp_fmin.c +index c1072b0dfb95..a287b23818d8 100644 +--- a/arch/mips/math-emu/dp_fmin.c ++++ b/arch/mips/math-emu/dp_fmin.c +@@ -47,14 +47,26 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + return ys ? y : x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -106,16 +116,32 @@ union ieee754dp ieee754dp_fmin(union ieee754dp x, union ieee754dp y) + else if (xs < ys) + return y; + +- /* Compare exponent */ +- if (xe > ye) +- return y; +- else if (xe < ye) +- return x; ++ /* Signs of inputs are the same, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return x; ++ return y; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return x; +- return y; ++ return y; ++ return x; + } + + union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) +@@ -147,14 +173,26 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754dp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,25 +202,25 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754dp_inf(xs | ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): +- return x; ++ return y; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): +- return y; ++ return x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754dp_zero(1); ++ return ieee754dp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + DPDNORMX; +@@ -207,7 +245,11 @@ union ieee754dp ieee754dp_fmina(union ieee754dp x, union ieee754dp y) + return x; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) ++ return x; ++ else if (xm > ym) ++ return y; ++ else if (xs == 1) + return x; + return y; + } +diff --git a/arch/mips/math-emu/sp_fmax.c b/arch/mips/math-emu/sp_fmax.c +index 4d000844e48e..74a5a00d2f22 100644 +--- a/arch/mips/math-emu/sp_fmax.c ++++ b/arch/mips/math-emu/sp_fmax.c +@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + return ys ? x : y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmax(union ieee754sp x, union ieee754sp y) + else if (xs < ys) + return x; + +- /* Compare exponent */ +- if (xe > ye) +- return x; +- else if (xe < ye) +- return y; ++ /* Signs of inputs are equal, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return y; ++ return x; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return y; +- return x; ++ return x; ++ return y; + } + + union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) +@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,6 +202,9 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754sp_inf(xs & ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): +@@ -171,7 +212,6 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): + return x; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): +@@ -180,9 +220,7 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + return y; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs & ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmaxa(union ieee754sp x, union ieee754sp y) + return y; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) + return y; +- return x; ++ else if (xm > ym) ++ return x; ++ else if (xs == 0) ++ return x; ++ return y; + } +diff --git a/arch/mips/math-emu/sp_fmin.c b/arch/mips/math-emu/sp_fmin.c +index 4eb1bb9e9dec..c51385f46b09 100644 +--- a/arch/mips/math-emu/sp_fmin.c ++++ b/arch/mips/math-emu/sp_fmin.c +@@ -47,14 +47,26 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -80,9 +92,7 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + return ys ? y : x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -106,16 +116,32 @@ union ieee754sp ieee754sp_fmin(union ieee754sp x, union ieee754sp y) + else if (xs < ys) + return y; + +- /* Compare exponent */ +- if (xe > ye) +- return y; +- else if (xe < ye) +- return x; ++ /* Signs of inputs are the same, let's compare exponents */ ++ if (xs == 0) { ++ /* Inputs are both positive */ ++ if (xe > ye) ++ return y; ++ else if (xe < ye) ++ return x; ++ } else { ++ /* Inputs are both negative */ ++ if (xe > ye) ++ return x; ++ else if (xe < ye) ++ return y; ++ } + +- /* Compare mantissa */ ++ /* Signs and exponents of inputs are equal, let's compare mantissas */ ++ if (xs == 0) { ++ /* Inputs are both positive, with equal signs and exponents */ ++ if (xm <= ym) ++ return x; ++ return y; ++ } ++ /* Inputs are both negative, with equal signs and exponents */ + if (xm <= ym) +- return x; +- return y; ++ return y; ++ return x; + } + + union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) +@@ -147,14 +173,26 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): + return ieee754sp_nanxcpt(x); + +- /* numbers are preferred to NaNs */ ++ /* ++ * Quiet NaN handling ++ */ ++ ++ /* ++ * The case of both inputs quiet NaNs ++ */ ++ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): ++ return x; ++ ++ /* ++ * The cases of exactly one input quiet NaN (numbers ++ * are here preferred as returned values to NaNs) ++ */ + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): + return x; + +- case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): +@@ -164,25 +202,25 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + /* + * Infinity and zero handling + */ ++ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): ++ return ieee754sp_inf(xs | ys); ++ + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): +- return x; ++ return y; + +- case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): +- return y; ++ return x; + + case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): +- if (xs == ys) +- return x; +- return ieee754sp_zero(1); ++ return ieee754sp_zero(xs | ys); + + case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): + SPDNORMX; +@@ -207,7 +245,11 @@ union ieee754sp ieee754sp_fmina(union ieee754sp x, union ieee754sp y) + return x; + + /* Compare mantissa */ +- if (xm <= ym) ++ if (xm < ym) ++ return x; ++ else if (xm > ym) ++ return y; ++ else if (xs == 1) + return x; + return y; + } +diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c +index 91e5c1758b5c..64e016abb2a5 100644 +--- a/arch/powerpc/kernel/align.c ++++ b/arch/powerpc/kernel/align.c +@@ -236,6 +236,28 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr) + + #define SWIZ_PTR(p) ((unsigned char __user *)((p) ^ swiz)) + ++#define __get_user_or_set_dar(_regs, _dest, _addr) \ ++ ({ \ ++ int rc = 0; \ ++ typeof(_addr) __addr = (_addr); \ ++ if (__get_user_inatomic(_dest, __addr)) { \ ++ _regs->dar = (unsigned long)__addr; \ ++ rc = -EFAULT; \ ++ } \ ++ rc; \ ++ }) ++ ++#define __put_user_or_set_dar(_regs, _src, _addr) \ ++ ({ \ ++ int rc = 0; \ ++ typeof(_addr) __addr = (_addr); \ ++ if (__put_user_inatomic(_src, __addr)) { \ ++ _regs->dar = (unsigned long)__addr; \ ++ rc = -EFAULT; \ ++ } \ ++ rc; \ ++ }) ++ + static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + unsigned int reg, unsigned int nb, + unsigned int flags, unsigned int instr, +@@ -264,9 +286,10 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + } else { + unsigned long pc = regs->nip ^ (swiz & 4); + +- if (__get_user_inatomic(instr, +- (unsigned int __user *)pc)) ++ if (__get_user_or_set_dar(regs, instr, ++ (unsigned int __user *)pc)) + return -EFAULT; ++ + if (swiz == 0 && (flags & SW)) + instr = cpu_to_le32(instr); + nb = (instr >> 11) & 0x1f; +@@ -310,31 +333,31 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + ((nb0 + 3) / 4) * sizeof(unsigned long)); + + for (i = 0; i < nb; ++i, ++p) +- if (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__get_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + if (nb0 > 0) { + rptr = ®s->gpr[0]; + addr += nb; + for (i = 0; i < nb0; ++i, ++p) +- if (__get_user_inatomic(REG_BYTE(rptr, +- i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__get_user_or_set_dar(regs, ++ REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + } + + } else { + for (i = 0; i < nb; ++i, ++p) +- if (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__put_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + if (nb0 > 0) { + rptr = ®s->gpr[0]; + addr += nb; + for (i = 0; i < nb0; ++i, ++p) +- if (__put_user_inatomic(REG_BYTE(rptr, +- i ^ bswiz), +- SWIZ_PTR(p))) ++ if (__put_user_or_set_dar(regs, ++ REG_BYTE(rptr, i ^ bswiz), ++ SWIZ_PTR(p))) + return -EFAULT; + } + } +@@ -346,29 +369,32 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr, + * Only POWER6 has these instructions, and it does true little-endian, + * so we don't need the address swizzling. + */ +-static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg, +- unsigned int flags) ++static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr, ++ unsigned int reg, unsigned int flags) + { + char *ptr0 = (char *) ¤t->thread.TS_FPR(reg); + char *ptr1 = (char *) ¤t->thread.TS_FPR(reg+1); +- int i, ret, sw = 0; ++ int i, sw = 0; + + if (reg & 1) + return 0; /* invalid form: FRS/FRT must be even */ + if (flags & SW) + sw = 7; +- ret = 0; ++ + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { +- ret |= __get_user(ptr0[i^sw], addr + i); +- ret |= __get_user(ptr1[i^sw], addr + i + 8); ++ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } else { +- ret |= __put_user(ptr0[i^sw], addr + i); +- ret |= __put_user(ptr1[i^sw], addr + i + 8); ++ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } + } +- if (ret) +- return -EFAULT; ++ + return 1; /* exception handled and fixed up */ + } + +@@ -378,24 +404,27 @@ static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr, + { + char *ptr0 = (char *)®s->gpr[reg]; + char *ptr1 = (char *)®s->gpr[reg+1]; +- int i, ret, sw = 0; ++ int i, sw = 0; + + if (reg & 1) + return 0; /* invalid form: GPR must be even */ + if (flags & SW) + sw = 7; +- ret = 0; ++ + for (i = 0; i < 8; ++i) { + if (!(flags & ST)) { +- ret |= __get_user(ptr0[i^sw], addr + i); +- ret |= __get_user(ptr1[i^sw], addr + i + 8); ++ if (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } else { +- ret |= __put_user(ptr0[i^sw], addr + i); +- ret |= __put_user(ptr1[i^sw], addr + i + 8); ++ if (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i)) ++ return -EFAULT; ++ if (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8)) ++ return -EFAULT; + } + } +- if (ret) +- return -EFAULT; ++ + return 1; /* exception handled and fixed up */ + } + #endif /* CONFIG_PPC64 */ +@@ -688,9 +717,14 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg, + for (j = 0; j < length; j += elsize) { + for (i = 0; i < elsize; ++i) { + if (flags & ST) +- ret |= __put_user(ptr[i^sw], addr + i); ++ ret = __put_user_or_set_dar(regs, ptr[i^sw], ++ addr + i); + else +- ret |= __get_user(ptr[i^sw], addr + i); ++ ret = __get_user_or_set_dar(regs, ptr[i^sw], ++ addr + i); ++ ++ if (ret) ++ return ret; + } + ptr += elsize; + #ifdef __LITTLE_ENDIAN__ +@@ -740,7 +774,7 @@ int fix_alignment(struct pt_regs *regs) + unsigned int dsisr; + unsigned char __user *addr; + unsigned long p, swiz; +- int ret, i; ++ int i; + union data { + u64 ll; + double dd; +@@ -923,7 +957,7 @@ int fix_alignment(struct pt_regs *regs) + if (flags & F) { + /* Special case for 16-byte FP loads and stores */ + PPC_WARN_ALIGNMENT(fp_pair, regs); +- return emulate_fp_pair(addr, reg, flags); ++ return emulate_fp_pair(regs, addr, reg, flags); + } else { + #ifdef CONFIG_PPC64 + /* Special case for 16-byte loads and stores */ +@@ -953,15 +987,12 @@ int fix_alignment(struct pt_regs *regs) + } + + data.ll = 0; +- ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) +- ret |= __get_user_inatomic(data.v[start + i], +- SWIZ_PTR(p++)); +- +- if (unlikely(ret)) +- return -EFAULT; ++ if (__get_user_or_set_dar(regs, data.v[start + i], ++ SWIZ_PTR(p++))) ++ return -EFAULT; + + } else if (flags & F) { + data.ll = current->thread.TS_FPR(reg); +@@ -1031,15 +1062,13 @@ int fix_alignment(struct pt_regs *regs) + break; + } + +- ret = 0; + p = (unsigned long)addr; + + for (i = 0; i < nb; i++) +- ret |= __put_user_inatomic(data.v[start + i], +- SWIZ_PTR(p++)); ++ if (__put_user_or_set_dar(regs, data.v[start + i], ++ SWIZ_PTR(p++))) ++ return -EFAULT; + +- if (unlikely(ret)) +- return -EFAULT; + } else if (flags & F) + current->thread.TS_FPR(reg) = data.ll; + else +diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h +index bcd3d6199464..bb16a58cf7e4 100644 +--- a/arch/x86/include/asm/elf.h ++++ b/arch/x86/include/asm/elf.h +@@ -204,6 +204,7 @@ void set_personality_ia32(bool); + + #define ELF_CORE_COPY_REGS(pr_reg, regs) \ + do { \ ++ unsigned long base; \ + unsigned v; \ + (pr_reg)[0] = (regs)->r15; \ + (pr_reg)[1] = (regs)->r14; \ +@@ -226,8 +227,8 @@ do { \ + (pr_reg)[18] = (regs)->flags; \ + (pr_reg)[19] = (regs)->sp; \ + (pr_reg)[20] = (regs)->ss; \ +- (pr_reg)[21] = current->thread.fs; \ +- (pr_reg)[22] = current->thread.gs; \ ++ rdmsrl(MSR_FS_BASE, base); (pr_reg)[21] = base; \ ++ rdmsrl(MSR_KERNEL_GS_BASE, base); (pr_reg)[22] = base; \ + asm("movl %%ds,%0" : "=r" (v)); (pr_reg)[23] = v; \ + asm("movl %%es,%0" : "=r" (v)); (pr_reg)[24] = v; \ + asm("movl %%fs,%0" : "=r" (v)); (pr_reg)[25] = v; \ +diff --git a/block/blk-core.c b/block/blk-core.c +index ef083e7a37c5..119658534dfd 100644 +--- a/block/blk-core.c ++++ b/block/blk-core.c +@@ -233,7 +233,7 @@ EXPORT_SYMBOL(blk_start_queue_async); + **/ + void blk_start_queue(struct request_queue *q) + { +- WARN_ON(!irqs_disabled()); ++ WARN_ON(!in_interrupt() && !irqs_disabled()); + + queue_flag_clear(QUEUE_FLAG_STOPPED, q); + __blk_run_queue(q); +diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c +index b3b0004ea8ac..d12782dc9683 100644 +--- a/crypto/algif_skcipher.c ++++ b/crypto/algif_skcipher.c +@@ -143,8 +143,10 @@ static int skcipher_alloc_sgl(struct sock *sk) + sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); + sgl->cur = 0; + +- if (sg) ++ if (sg) { + sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); ++ sg_unmark_end(sg + (MAX_SGL_ENTS - 1)); ++ } + + list_add_tail(&sgl->list, &ctx->tsgl); + } +diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c +index 586f9168ffa4..47d1e834f3f4 100644 +--- a/drivers/block/skd_main.c ++++ b/drivers/block/skd_main.c +@@ -2214,6 +2214,9 @@ static void skd_send_fitmsg(struct skd_device *skdev, + */ + qcmd |= FIT_QCMD_MSGSIZE_64; + ++ /* Make sure skd_msg_buf is written before the doorbell is triggered. */ ++ smp_wmb(); ++ + SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND); + + } +@@ -2260,6 +2263,9 @@ static void skd_send_special_fitmsg(struct skd_device *skdev, + qcmd = skspcl->mb_dma_address; + qcmd |= FIT_QCMD_QID_NORMAL + FIT_QCMD_MSGSIZE_128; + ++ /* Make sure skd_msg_buf is written before the doorbell is triggered. */ ++ smp_wmb(); ++ + SKD_WRITEQ(skdev, qcmd, FIT_Q_COMMAND); + } + +@@ -4679,15 +4685,16 @@ static void skd_free_disk(struct skd_device *skdev) + { + struct gendisk *disk = skdev->disk; + +- if (disk != NULL) { +- struct request_queue *q = disk->queue; ++ if (disk && (disk->flags & GENHD_FL_UP)) ++ del_gendisk(disk); + +- if (disk->flags & GENHD_FL_UP) +- del_gendisk(disk); +- if (q) +- blk_cleanup_queue(q); +- put_disk(disk); ++ if (skdev->queue) { ++ blk_cleanup_queue(skdev->queue); ++ skdev->queue = NULL; ++ disk->queue = NULL; + } ++ ++ put_disk(disk); + skdev->disk = NULL; + } + +diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h +index 5be14ad29d46..dbf09836ff30 100644 +--- a/drivers/input/serio/i8042-x86ia64io.h ++++ b/drivers/input/serio/i8042-x86ia64io.h +@@ -904,6 +904,13 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "P34"), + }, + }, ++ { ++ /* Gigabyte P57 - Elantech touchpad */ ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "P57"), ++ }, ++ }, + { + /* Schenker XMG C504 - Elantech touchpad */ + .matches = { +diff --git a/drivers/md/bcache/bcache.h b/drivers/md/bcache/bcache.h +index c3ea03c9a1a8..02619cabda8b 100644 +--- a/drivers/md/bcache/bcache.h ++++ b/drivers/md/bcache/bcache.h +@@ -333,6 +333,7 @@ struct cached_dev { + /* Limit number of writeback bios in flight */ + struct semaphore in_flight; + struct task_struct *writeback_thread; ++ struct workqueue_struct *writeback_write_wq; + + struct keybuf writeback_keys; + +diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c +index 2410df1c2a05..6c4c7caea693 100644 +--- a/drivers/md/bcache/request.c ++++ b/drivers/md/bcache/request.c +@@ -196,12 +196,12 @@ static void bch_data_insert_start(struct closure *cl) + struct data_insert_op *op = container_of(cl, struct data_insert_op, cl); + struct bio *bio = op->bio, *n; + +- if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) +- wake_up_gc(op->c); +- + if (op->bypass) + return bch_data_invalidate(cl); + ++ if (atomic_sub_return(bio_sectors(bio), &op->c->sectors_to_gc) < 0) ++ wake_up_gc(op->c); ++ + /* + * Journal writes are marked REQ_FLUSH; if the original write was a + * flush, it'll wait on the journal write. +diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c +index 7b5880b8874c..c5ceea9222ff 100644 +--- a/drivers/md/bcache/super.c ++++ b/drivers/md/bcache/super.c +@@ -1023,7 +1023,7 @@ int bch_cached_dev_attach(struct cached_dev *dc, struct cache_set *c) + } + + if (BDEV_STATE(&dc->sb) == BDEV_STATE_DIRTY) { +- bch_sectors_dirty_init(dc); ++ bch_sectors_dirty_init(&dc->disk); + atomic_set(&dc->has_dirty, 1); + atomic_inc(&dc->count); + bch_writeback_queue(dc); +@@ -1056,6 +1056,8 @@ static void cached_dev_free(struct closure *cl) + cancel_delayed_work_sync(&dc->writeback_rate_update); + if (!IS_ERR_OR_NULL(dc->writeback_thread)) + kthread_stop(dc->writeback_thread); ++ if (dc->writeback_write_wq) ++ destroy_workqueue(dc->writeback_write_wq); + + mutex_lock(&bch_register_lock); + +@@ -1227,6 +1229,7 @@ static int flash_dev_run(struct cache_set *c, struct uuid_entry *u) + goto err; + + bcache_device_attach(d, c, u - c->uuids); ++ bch_sectors_dirty_init(d); + bch_flash_dev_request_init(d); + add_disk(d->disk); + +@@ -1959,6 +1962,8 @@ static ssize_t register_bcache(struct kobject *k, struct kobj_attribute *attr, + else + err = "device busy"; + mutex_unlock(&bch_register_lock); ++ if (!IS_ERR(bdev)) ++ bdput(bdev); + if (attr == &ksysfs_register_quiet) + goto out; + } +diff --git a/drivers/md/bcache/sysfs.c b/drivers/md/bcache/sysfs.c +index b3ff57d61dde..4fbb5532f24c 100644 +--- a/drivers/md/bcache/sysfs.c ++++ b/drivers/md/bcache/sysfs.c +@@ -191,7 +191,7 @@ STORE(__cached_dev) + { + struct cached_dev *dc = container_of(kobj, struct cached_dev, + disk.kobj); +- unsigned v = size; ++ ssize_t v = size; + struct cache_set *c; + struct kobj_uevent_env *env; + +@@ -226,7 +226,7 @@ STORE(__cached_dev) + bch_cached_dev_run(dc); + + if (attr == &sysfs_cache_mode) { +- ssize_t v = bch_read_string_list(buf, bch_cache_modes + 1); ++ v = bch_read_string_list(buf, bch_cache_modes + 1); + + if (v < 0) + return v; +diff --git a/drivers/md/bcache/util.c b/drivers/md/bcache/util.c +index db3ae4c2b223..6c18e3ec3e48 100644 +--- a/drivers/md/bcache/util.c ++++ b/drivers/md/bcache/util.c +@@ -73,24 +73,44 @@ STRTO_H(strtouint, unsigned int) + STRTO_H(strtoll, long long) + STRTO_H(strtoull, unsigned long long) + ++/** ++ * bch_hprint() - formats @v to human readable string for sysfs. ++ * ++ * @v - signed 64 bit integer ++ * @buf - the (at least 8 byte) buffer to format the result into. ++ * ++ * Returns the number of bytes used by format. ++ */ + ssize_t bch_hprint(char *buf, int64_t v) + { + static const char units[] = "?kMGTPEZY"; +- char dec[4] = ""; +- int u, t = 0; +- +- for (u = 0; v >= 1024 || v <= -1024; u++) { +- t = v & ~(~0 << 10); +- v >>= 10; +- } +- +- if (!u) +- return sprintf(buf, "%llu", v); +- +- if (v < 100 && v > -100) +- snprintf(dec, sizeof(dec), ".%i", t / 100); +- +- return sprintf(buf, "%lli%s%c", v, dec, units[u]); ++ int u = 0, t; ++ ++ uint64_t q; ++ ++ if (v < 0) ++ q = -v; ++ else ++ q = v; ++ ++ /* For as long as the number is more than 3 digits, but at least ++ * once, shift right / divide by 1024. Keep the remainder for ++ * a digit after the decimal point. ++ */ ++ do { ++ u++; ++ ++ t = q & ~(~0 << 10); ++ q >>= 10; ++ } while (q >= 1000); ++ ++ if (v < 0) ++ /* '-', up to 3 digits, '.', 1 digit, 1 character, null; ++ * yields 8 bytes. ++ */ ++ return sprintf(buf, "-%llu.%i%c", q, t * 10 / 1024, units[u]); ++ else ++ return sprintf(buf, "%llu.%i%c", q, t * 10 / 1024, units[u]); + } + + ssize_t bch_snprint_string_list(char *buf, size_t size, const char * const list[], +diff --git a/drivers/md/bcache/writeback.c b/drivers/md/bcache/writeback.c +index b9346cd9cda1..bbb1dc9e1639 100644 +--- a/drivers/md/bcache/writeback.c ++++ b/drivers/md/bcache/writeback.c +@@ -21,7 +21,8 @@ + static void __update_writeback_rate(struct cached_dev *dc) + { + struct cache_set *c = dc->disk.c; +- uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size; ++ uint64_t cache_sectors = c->nbuckets * c->sb.bucket_size - ++ bcache_flash_devs_sectors_dirty(c); + uint64_t cache_dirty_target = + div_u64(cache_sectors * dc->writeback_percent, 100); + +@@ -190,7 +191,7 @@ static void write_dirty(struct closure *cl) + + closure_bio_submit(&io->bio, cl); + +- continue_at(cl, write_dirty_finish, system_wq); ++ continue_at(cl, write_dirty_finish, io->dc->writeback_write_wq); + } + + static void read_dirty_endio(struct bio *bio) +@@ -210,7 +211,7 @@ static void read_dirty_submit(struct closure *cl) + + closure_bio_submit(&io->bio, cl); + +- continue_at(cl, write_dirty, system_wq); ++ continue_at(cl, write_dirty, io->dc->writeback_write_wq); + } + + static void read_dirty(struct cached_dev *dc) +@@ -488,17 +489,17 @@ static int sectors_dirty_init_fn(struct btree_op *_op, struct btree *b, + return MAP_CONTINUE; + } + +-void bch_sectors_dirty_init(struct cached_dev *dc) ++void bch_sectors_dirty_init(struct bcache_device *d) + { + struct sectors_dirty_init op; + + bch_btree_op_init(&op.op, -1); +- op.inode = dc->disk.id; ++ op.inode = d->id; + +- bch_btree_map_keys(&op.op, dc->disk.c, &KEY(op.inode, 0, 0), ++ bch_btree_map_keys(&op.op, d->c, &KEY(op.inode, 0, 0), + sectors_dirty_init_fn, 0); + +- dc->disk.sectors_dirty_last = bcache_dev_sectors_dirty(&dc->disk); ++ d->sectors_dirty_last = bcache_dev_sectors_dirty(d); + } + + void bch_cached_dev_writeback_init(struct cached_dev *dc) +@@ -522,6 +523,11 @@ void bch_cached_dev_writeback_init(struct cached_dev *dc) + + int bch_cached_dev_writeback_start(struct cached_dev *dc) + { ++ dc->writeback_write_wq = alloc_workqueue("bcache_writeback_wq", ++ WQ_MEM_RECLAIM, 0); ++ if (!dc->writeback_write_wq) ++ return -ENOMEM; ++ + dc->writeback_thread = kthread_create(bch_writeback_thread, dc, + "bcache_writeback"); + if (IS_ERR(dc->writeback_thread)) +diff --git a/drivers/md/bcache/writeback.h b/drivers/md/bcache/writeback.h +index 073a042aed24..daec4fd782ea 100644 +--- a/drivers/md/bcache/writeback.h ++++ b/drivers/md/bcache/writeback.h +@@ -14,6 +14,25 @@ static inline uint64_t bcache_dev_sectors_dirty(struct bcache_device *d) + return ret; + } + ++static inline uint64_t bcache_flash_devs_sectors_dirty(struct cache_set *c) ++{ ++ uint64_t i, ret = 0; ++ ++ mutex_lock(&bch_register_lock); ++ ++ for (i = 0; i < c->nr_uuids; i++) { ++ struct bcache_device *d = c->devices[i]; ++ ++ if (!d || !UUID_FLASH_ONLY(&c->uuids[i])) ++ continue; ++ ret += bcache_dev_sectors_dirty(d); ++ } ++ ++ mutex_unlock(&bch_register_lock); ++ ++ return ret; ++} ++ + static inline unsigned offset_to_stripe(struct bcache_device *d, + uint64_t offset) + { +@@ -85,7 +104,7 @@ static inline void bch_writeback_add(struct cached_dev *dc) + + void bcache_dev_sectors_dirty_add(struct cache_set *, unsigned, uint64_t, int); + +-void bch_sectors_dirty_init(struct cached_dev *dc); ++void bch_sectors_dirty_init(struct bcache_device *); + void bch_cached_dev_writeback_init(struct cached_dev *); + int bch_cached_dev_writeback_start(struct cached_dev *); + +diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c +index 4f22e919787a..7a50728b9389 100644 +--- a/drivers/md/bitmap.c ++++ b/drivers/md/bitmap.c +@@ -1960,6 +1960,11 @@ int bitmap_resize(struct bitmap *bitmap, sector_t blocks, + long pages; + struct bitmap_page *new_bp; + ++ if (bitmap->storage.file && !init) { ++ pr_info("md: cannot resize file-based bitmap\n"); ++ return -EINVAL; ++ } ++ + if (chunksize == 0) { + /* If there is enough space, leave the chunk size unchanged, + * else increase by factor of two until there is enough space. +diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c +index 8f60520c8392..5eac08ffc697 100644 +--- a/drivers/md/raid5.c ++++ b/drivers/md/raid5.c +@@ -5822,6 +5822,8 @@ static void raid5_do_work(struct work_struct *work) + + spin_unlock_irq(&conf->device_lock); + ++ r5l_flush_stripe_to_raid(conf->log); ++ + async_tx_issue_pending_all(); + blk_finish_plug(&plug); + +diff --git a/drivers/media/usb/uvc/uvc_ctrl.c b/drivers/media/usb/uvc/uvc_ctrl.c +index 3e59b288b8a8..618e4e2b4207 100644 +--- a/drivers/media/usb/uvc/uvc_ctrl.c ++++ b/drivers/media/usb/uvc/uvc_ctrl.c +@@ -2001,6 +2001,13 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, + goto done; + } + ++ /* Validate the user-provided bit-size and offset */ ++ if (mapping->size > 32 || ++ mapping->offset + mapping->size > ctrl->info.size * 8) { ++ ret = -EINVAL; ++ goto done; ++ } ++ + list_for_each_entry(map, &ctrl->info.mappings, list) { + if (mapping->id == map->id) { + uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " +diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +index 109f687d1cbd..4379b949bb93 100644 +--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c ++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c +@@ -773,7 +773,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u + copy_to_user(&up->u, &kp->u, sizeof(kp->u)) || + put_user(kp->pending, &up->pending) || + put_user(kp->sequence, &up->sequence) || +- compat_put_timespec(&kp->timestamp, &up->timestamp) || ++ put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || ++ put_user(kp->timestamp.tv_nsec, &up->timestamp.tv_nsec) || + put_user(kp->id, &up->id) || + copy_to_user(up->reserved, kp->reserved, 8 * sizeof(__u32))) + return -EFAULT; +diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c +index 4cd2a7d0124f..7923bfdc9b30 100644 +--- a/drivers/net/ethernet/freescale/gianfar.c ++++ b/drivers/net/ethernet/freescale/gianfar.c +@@ -3676,7 +3676,7 @@ static noinline void gfar_update_link_state(struct gfar_private *priv) + u32 tempval1 = gfar_read(®s->maccfg1); + u32 tempval = gfar_read(®s->maccfg2); + u32 ecntrl = gfar_read(®s->ecntrl); +- u32 tx_flow_oldval = (tempval & MACCFG1_TX_FLOW); ++ u32 tx_flow_oldval = (tempval1 & MACCFG1_TX_FLOW); + + if (phydev->duplex != priv->oldduplex) { + if (!(phydev->duplex)) +diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +index 829be21f97b2..be258d90de9e 100644 +--- a/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c ++++ b/drivers/net/ethernet/qlogic/qlge/qlge_dbg.c +@@ -724,7 +724,7 @@ static void ql_build_coredump_seg_header( + seg_hdr->cookie = MPI_COREDUMP_COOKIE; + seg_hdr->segNum = seg_number; + seg_hdr->segSize = seg_size; +- memcpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1); ++ strncpy(seg_hdr->description, desc, (sizeof(seg_hdr->description)) - 1); + } + + /* +diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +index 49d9f0a789fe..7d0690433ee0 100644 +--- a/drivers/net/phy/phy.c ++++ b/drivers/net/phy/phy.c +@@ -541,9 +541,6 @@ void phy_stop_machine(struct phy_device *phydev) + if (phydev->state > PHY_UP && phydev->state != PHY_HALTED) + phydev->state = PHY_UP; + mutex_unlock(&phydev->lock); +- +- /* Now we can run the state machine synchronously */ +- phy_state_machine(&phydev->state_queue.work); + } + + /** +diff --git a/drivers/pci/hotplug/shpchp_hpc.c b/drivers/pci/hotplug/shpchp_hpc.c +index 7d223e9080ef..77dddee2753a 100644 +--- a/drivers/pci/hotplug/shpchp_hpc.c ++++ b/drivers/pci/hotplug/shpchp_hpc.c +@@ -1062,6 +1062,8 @@ int shpc_init(struct controller *ctrl, struct pci_dev *pdev) + if (rc) { + ctrl_info(ctrl, "Can't get msi for the hotplug controller\n"); + ctrl_info(ctrl, "Use INTx for the hotplug controller\n"); ++ } else { ++ pci_set_master(pdev); + } + + rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED, +diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c +index d5bf36ec8a75..34367d172961 100644 +--- a/drivers/s390/scsi/zfcp_dbf.c ++++ b/drivers/s390/scsi/zfcp_dbf.c +@@ -3,7 +3,7 @@ + * + * Debug traces for zfcp. + * +- * Copyright IBM Corp. 2002, 2016 ++ * Copyright IBM Corp. 2002, 2017 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -447,6 +447,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, + struct fc_ct_hdr *reqh = sg_virt(ct_els->req); + struct fc_ns_gid_ft *reqn = (struct fc_ns_gid_ft *)(reqh + 1); + struct scatterlist *resp_entry = ct_els->resp; ++ struct fc_ct_hdr *resph; + struct fc_gpn_ft_resp *acc; + int max_entries, x, last = 0; + +@@ -473,6 +474,13 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag, + return len; /* not GPN_FT response so do not cap */ + + acc = sg_virt(resp_entry); ++ ++ /* cap all but accept CT responses to at least the CT header */ ++ resph = (struct fc_ct_hdr *)acc; ++ if ((ct_els->status) || ++ (resph->ct_cmd != cpu_to_be16(FC_FS_ACC))) ++ return max(FC_CT_HDR_LEN, ZFCP_DBF_SAN_MAX_PAYLOAD); ++ + max_entries = (reqh->ct_mr_size * 4 / sizeof(struct fc_gpn_ft_resp)) + + 1 /* zfcp_fc_scan_ports: bytes correct, entries off-by-one + * to account for header as 1st pseudo "entry" */; +@@ -555,8 +563,8 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, + rec->scsi_retries = sc->retries; + rec->scsi_allowed = sc->allowed; + rec->scsi_id = sc->device->id; +- /* struct zfcp_dbf_scsi needs to be updated to handle 64bit LUNs */ + rec->scsi_lun = (u32)sc->device->lun; ++ rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32); + rec->host_scribble = (unsigned long)sc->host_scribble; + + memcpy(rec->scsi_opcode, sc->cmnd, +@@ -564,19 +572,32 @@ void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc, + + if (fsf) { + rec->fsf_req_id = fsf->req_id; ++ rec->pl_len = FCP_RESP_WITH_EXT; + fcp_rsp = (struct fcp_resp_with_ext *) + &(fsf->qtcb->bottom.io.fcp_rsp); ++ /* mandatory parts of FCP_RSP IU in this SCSI record */ + memcpy(&rec->fcp_rsp, fcp_rsp, FCP_RESP_WITH_EXT); + if (fcp_rsp->resp.fr_flags & FCP_RSP_LEN_VAL) { + fcp_rsp_info = (struct fcp_resp_rsp_info *) &fcp_rsp[1]; + rec->fcp_rsp_info = fcp_rsp_info->rsp_code; ++ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_rsp_len); + } + if (fcp_rsp->resp.fr_flags & FCP_SNS_LEN_VAL) { +- rec->pl_len = min((u16)SCSI_SENSE_BUFFERSIZE, +- (u16)ZFCP_DBF_PAY_MAX_REC); +- zfcp_dbf_pl_write(dbf, sc->sense_buffer, rec->pl_len, +- "fcp_sns", fsf->req_id); ++ rec->pl_len += be32_to_cpu(fcp_rsp->ext.fr_sns_len); + } ++ /* complete FCP_RSP IU in associated PAYload record ++ * but only if there are optional parts ++ */ ++ if (fcp_rsp->resp.fr_flags != 0) ++ zfcp_dbf_pl_write( ++ dbf, fcp_rsp, ++ /* at least one full PAY record ++ * but not beyond hardware response field ++ */ ++ min_t(u16, max_t(u16, rec->pl_len, ++ ZFCP_DBF_PAY_MAX_REC), ++ FSF_FCP_RSP_SIZE), ++ "fcp_riu", fsf->req_id); + } + + debug_event(dbf->scsi, level, rec, sizeof(*rec)); +diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h +index db186d44cfaf..b60667c145fd 100644 +--- a/drivers/s390/scsi/zfcp_dbf.h ++++ b/drivers/s390/scsi/zfcp_dbf.h +@@ -2,7 +2,7 @@ + * zfcp device driver + * debug feature declarations + * +- * Copyright IBM Corp. 2008, 2016 ++ * Copyright IBM Corp. 2008, 2017 + */ + + #ifndef ZFCP_DBF_H +@@ -204,7 +204,7 @@ enum zfcp_dbf_scsi_id { + * @id: unique number of recovery record type + * @tag: identifier string specifying the location of initiation + * @scsi_id: scsi device id +- * @scsi_lun: scsi device logical unit number ++ * @scsi_lun: scsi device logical unit number, low part of 64 bit, old 32 bit + * @scsi_result: scsi result + * @scsi_retries: current retry number of scsi request + * @scsi_allowed: allowed retries +@@ -214,6 +214,7 @@ enum zfcp_dbf_scsi_id { + * @host_scribble: LLD specific data attached to SCSI request + * @pl_len: length of paload stored as zfcp_dbf_pay + * @fsf_rsp: response for fsf request ++ * @scsi_lun_64_hi: scsi device logical unit number, high part of 64 bit + */ + struct zfcp_dbf_scsi { + u8 id; +@@ -230,6 +231,7 @@ struct zfcp_dbf_scsi { + u64 host_scribble; + u16 pl_len; + struct fcp_resp_with_ext fcp_rsp; ++ u32 scsi_lun_64_hi; + } __packed; + + /** +@@ -323,7 +325,11 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req) + { + struct fsf_qtcb *qtcb = req->qtcb; + +- if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && ++ if (unlikely(req->status & (ZFCP_STATUS_FSFREQ_DISMISSED | ++ ZFCP_STATUS_FSFREQ_ERROR))) { ++ zfcp_dbf_hba_fsf_resp("fs_rerr", 3, req); ++ ++ } else if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) && + (qtcb->prefix.prot_status != FSF_PROT_FSF_STATUS_PRESENTED)) { + zfcp_dbf_hba_fsf_resp("fs_perr", 1, req); + +@@ -401,7 +407,8 @@ void zfcp_dbf_scsi_abort(char *tag, struct scsi_cmnd *scmd, + * @flag: indicates type of reset (Target Reset, Logical Unit Reset) + */ + static inline +-void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) ++void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag, ++ struct zfcp_fsf_req *fsf_req) + { + char tmp_tag[ZFCP_DBF_TAG_LEN]; + +@@ -411,7 +418,7 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag) + memcpy(tmp_tag, "lr_", 3); + + memcpy(&tmp_tag[3], tag, 4); +- _zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL); ++ _zfcp_dbf_scsi(tmp_tag, 1, scmnd, fsf_req); + } + + /** +diff --git a/drivers/s390/scsi/zfcp_fc.h b/drivers/s390/scsi/zfcp_fc.h +index df2b541c8287..a2275825186f 100644 +--- a/drivers/s390/scsi/zfcp_fc.h ++++ b/drivers/s390/scsi/zfcp_fc.h +@@ -4,7 +4,7 @@ + * Fibre Channel related definitions and inline functions for the zfcp + * device driver + * +- * Copyright IBM Corp. 2009 ++ * Copyright IBM Corp. 2009, 2017 + */ + + #ifndef ZFCP_FC_H +@@ -279,6 +279,10 @@ void zfcp_fc_eval_fcp_rsp(struct fcp_resp_with_ext *fcp_rsp, + !(rsp_flags & FCP_SNS_LEN_VAL) && + fcp_rsp->resp.fr_status == SAM_STAT_GOOD) + set_host_byte(scsi, DID_ERROR); ++ } else if (unlikely(rsp_flags & FCP_RESID_OVER)) { ++ /* FCP_DL was not sufficient for SCSI data length */ ++ if (fcp_rsp->resp.fr_status == SAM_STAT_GOOD) ++ set_host_byte(scsi, DID_ERROR); + } + } + +diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c +index 27ff38f839fc..1964391db904 100644 +--- a/drivers/s390/scsi/zfcp_fsf.c ++++ b/drivers/s390/scsi/zfcp_fsf.c +@@ -928,8 +928,8 @@ static void zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *req) + + switch (header->fsf_status) { + case FSF_GOOD: +- zfcp_dbf_san_res("fsscth2", req); + ct->status = 0; ++ zfcp_dbf_san_res("fsscth2", req); + break; + case FSF_SERVICE_CLASS_NOT_SUPPORTED: + zfcp_fsf_class_not_supp(req); +@@ -1109,8 +1109,8 @@ static void zfcp_fsf_send_els_handler(struct zfcp_fsf_req *req) + + switch (header->fsf_status) { + case FSF_GOOD: +- zfcp_dbf_san_res("fsselh1", req); + send_els->status = 0; ++ zfcp_dbf_san_res("fsselh1", req); + break; + case FSF_SERVICE_CLASS_NOT_SUPPORTED: + zfcp_fsf_class_not_supp(req); +@@ -2258,7 +2258,8 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) + fcp_cmnd = (struct fcp_cmnd *) &req->qtcb->bottom.io.fcp_cmnd; + zfcp_fc_scsi_to_fcp(fcp_cmnd, scsi_cmnd, 0); + +- if (scsi_prot_sg_count(scsi_cmnd)) { ++ if ((scsi_get_prot_op(scsi_cmnd) != SCSI_PROT_NORMAL) && ++ scsi_prot_sg_count(scsi_cmnd)) { + zfcp_qdio_set_data_div(qdio, &req->qdio_req, + scsi_prot_sg_count(scsi_cmnd)); + retval = zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, +diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c +index 07ffdbb5107f..9bd9b9a29dfc 100644 +--- a/drivers/s390/scsi/zfcp_scsi.c ++++ b/drivers/s390/scsi/zfcp_scsi.c +@@ -3,7 +3,7 @@ + * + * Interface to Linux SCSI midlayer. + * +- * Copyright IBM Corp. 2002, 2016 ++ * Copyright IBM Corp. 2002, 2017 + */ + + #define KMSG_COMPONENT "zfcp" +@@ -273,25 +273,29 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags) + + zfcp_erp_wait(adapter); + ret = fc_block_scsi_eh(scpnt); +- if (ret) ++ if (ret) { ++ zfcp_dbf_scsi_devreset("fiof", scpnt, tm_flags, NULL); + return ret; ++ } + + if (!(atomic_read(&adapter->status) & + ZFCP_STATUS_COMMON_RUNNING)) { +- zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("nres", scpnt, tm_flags, NULL); + return SUCCESS; + } + } +- if (!fsf_req) ++ if (!fsf_req) { ++ zfcp_dbf_scsi_devreset("reqf", scpnt, tm_flags, NULL); + return FAILED; ++ } + + wait_for_completion(&fsf_req->completion); + + if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) { +- zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags, fsf_req); + retval = FAILED; + } else { +- zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags); ++ zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags, fsf_req); + zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags); + } + +diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c +index 17c440b9d086..6835bae33ec4 100644 +--- a/drivers/scsi/megaraid/megaraid_sas_base.c ++++ b/drivers/scsi/megaraid/megaraid_sas_base.c +@@ -1824,9 +1824,12 @@ static void megasas_complete_outstanding_ioctls(struct megasas_instance *instanc + if (cmd_fusion->sync_cmd_idx != (u32)ULONG_MAX) { + cmd_mfi = instance->cmd_list[cmd_fusion->sync_cmd_idx]; + if (cmd_mfi->sync_cmd && +- cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) ++ (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) { ++ cmd_mfi->frame->hdr.cmd_status = ++ MFI_STAT_WRONG_STATE; + megasas_complete_cmd(instance, + cmd_mfi, DID_OK); ++ } + } + } + } else { +@@ -5094,6 +5097,14 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num, + prev_aen.word = + le32_to_cpu(instance->aen_cmd->frame->dcmd.mbox.w[1]); + ++ if ((curr_aen.members.class < MFI_EVT_CLASS_DEBUG) || ++ (curr_aen.members.class > MFI_EVT_CLASS_DEAD)) { ++ dev_info(&instance->pdev->dev, ++ "%s %d out of range class %d send by application\n", ++ __func__, __LINE__, curr_aen.members.class); ++ return 0; ++ } ++ + /* + * A class whose enum value is smaller is inclusive of all + * higher values. If a PROGRESS (= -1) was previously +diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c +index 1ed85dfc008d..ac12ee844bfc 100644 +--- a/drivers/scsi/qla2xxx/qla_attr.c ++++ b/drivers/scsi/qla2xxx/qla_attr.c +@@ -404,6 +404,8 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + return -EINVAL; + if (start > ha->optrom_size) + return -EINVAL; ++ if (size > ha->optrom_size - start) ++ size = ha->optrom_size - start; + + mutex_lock(&ha->optrom_mutex); + switch (val) { +@@ -429,8 +431,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + } + + ha->optrom_region_start = start; +- ha->optrom_region_size = start + size > ha->optrom_size ? +- ha->optrom_size - start : size; ++ ha->optrom_region_size = start + size; + + ha->optrom_state = QLA_SREADING; + ha->optrom_buffer = vmalloc(ha->optrom_region_size); +@@ -503,8 +504,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj, + } + + ha->optrom_region_start = start; +- ha->optrom_region_size = start + size > ha->optrom_size ? +- ha->optrom_size - start : size; ++ ha->optrom_region_size = start + size; + + ha->optrom_state = QLA_SWRITING; + ha->optrom_buffer = vmalloc(ha->optrom_region_size); +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 71325972e503..39e8b5dc23fa 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -133,7 +133,7 @@ struct sg_device; /* forward declarations */ + struct sg_fd; + + typedef struct sg_request { /* SG_MAX_QUEUE requests outstanding per file */ +- struct sg_request *nextrp; /* NULL -> tail request (slist) */ ++ struct list_head entry; /* list entry */ + struct sg_fd *parentfp; /* NULL -> not in use */ + Sg_scatter_hold data; /* hold buffer, perhaps scatter list */ + sg_io_hdr_t header; /* scsi command+info, see <scsi/sg.h> */ +@@ -157,8 +157,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */ + int timeout; /* defaults to SG_DEFAULT_TIMEOUT */ + int timeout_user; /* defaults to SG_DEFAULT_TIMEOUT_USER */ + Sg_scatter_hold reserve; /* buffer held for this file descriptor */ +- unsigned save_scat_len; /* original length of trunc. scat. element */ +- Sg_request *headrp; /* head of request slist, NULL->empty */ ++ struct list_head rq_list; /* head of request list */ + struct fasync_struct *async_qp; /* used by asynchronous notification */ + Sg_request req_arr[SG_MAX_QUEUE]; /* used as singly-linked list */ + char low_dma; /* as in parent but possibly overridden to 1 */ +@@ -840,6 +839,39 @@ static int max_sectors_bytes(struct request_queue *q) + return max_sectors << 9; + } + ++static void ++sg_fill_request_table(Sg_fd *sfp, sg_req_info_t *rinfo) ++{ ++ Sg_request *srp; ++ int val; ++ unsigned int ms; ++ ++ val = 0; ++ list_for_each_entry(srp, &sfp->rq_list, entry) { ++ if (val > SG_MAX_QUEUE) ++ break; ++ rinfo[val].req_state = srp->done + 1; ++ rinfo[val].problem = ++ srp->header.masked_status & ++ srp->header.host_status & ++ srp->header.driver_status; ++ if (srp->done) ++ rinfo[val].duration = ++ srp->header.duration; ++ else { ++ ms = jiffies_to_msecs(jiffies); ++ rinfo[val].duration = ++ (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; ++ } ++ rinfo[val].orphan = srp->orphan; ++ rinfo[val].sg_io_owned = srp->sg_io_owned; ++ rinfo[val].pack_id = srp->header.pack_id; ++ rinfo[val].usr_ptr = srp->header.usr_ptr; ++ val++; ++ } ++} ++ + static long + sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + { +@@ -951,7 +983,7 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + if (!access_ok(VERIFY_WRITE, ip, sizeof (int))) + return -EFAULT; + read_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (srp = sfp->headrp; srp; srp = srp->nextrp) { ++ list_for_each_entry(srp, &sfp->rq_list, entry) { + if ((1 == srp->done) && (!srp->sg_io_owned)) { + read_unlock_irqrestore(&sfp->rq_list_lock, + iflags); +@@ -964,7 +996,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + return 0; + case SG_GET_NUM_WAITING: + read_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (val = 0, srp = sfp->headrp; srp; srp = srp->nextrp) { ++ val = 0; ++ list_for_each_entry(srp, &sfp->rq_list, entry) { + if ((1 == srp->done) && (!srp->sg_io_owned)) + ++val; + } +@@ -1032,42 +1065,15 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg) + return -EFAULT; + else { + sg_req_info_t *rinfo; +- unsigned int ms; + +- rinfo = kmalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, +- GFP_KERNEL); ++ rinfo = kzalloc(SZ_SG_REQ_INFO * SG_MAX_QUEUE, ++ GFP_KERNEL); + if (!rinfo) + return -ENOMEM; + read_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (srp = sfp->headrp, val = 0; val < SG_MAX_QUEUE; +- ++val, srp = srp ? srp->nextrp : srp) { +- memset(&rinfo[val], 0, SZ_SG_REQ_INFO); +- if (srp) { +- rinfo[val].req_state = srp->done + 1; +- rinfo[val].problem = +- srp->header.masked_status & +- srp->header.host_status & +- srp->header.driver_status; +- if (srp->done) +- rinfo[val].duration = +- srp->header.duration; +- else { +- ms = jiffies_to_msecs(jiffies); +- rinfo[val].duration = +- (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; +- } +- rinfo[val].orphan = srp->orphan; +- rinfo[val].sg_io_owned = +- srp->sg_io_owned; +- rinfo[val].pack_id = +- srp->header.pack_id; +- rinfo[val].usr_ptr = +- srp->header.usr_ptr; +- } +- } ++ sg_fill_request_table(sfp, rinfo); + read_unlock_irqrestore(&sfp->rq_list_lock, iflags); +- result = __copy_to_user(p, rinfo, ++ result = __copy_to_user(p, rinfo, + SZ_SG_REQ_INFO * SG_MAX_QUEUE); + result = result ? -EFAULT : 0; + kfree(rinfo); +@@ -1173,7 +1179,7 @@ sg_poll(struct file *filp, poll_table * wait) + return POLLERR; + poll_wait(filp, &sfp->read_wait, wait); + read_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (srp = sfp->headrp; srp; srp = srp->nextrp) { ++ list_for_each_entry(srp, &sfp->rq_list, entry) { + /* if any read waiting, flag it */ + if ((0 == res) && (1 == srp->done) && (!srp->sg_io_owned)) + res = POLLIN | POLLRDNORM; +@@ -2059,7 +2065,6 @@ sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp) + req_schp->pages = NULL; + req_schp->page_order = 0; + req_schp->sglist_len = 0; +- sfp->save_scat_len = 0; + srp->res_used = 0; + /* Called without mutex lock to avoid deadlock */ + sfp->res_in_use = 0; +@@ -2072,7 +2077,7 @@ sg_get_rq_mark(Sg_fd * sfp, int pack_id) + unsigned long iflags; + + write_lock_irqsave(&sfp->rq_list_lock, iflags); +- for (resp = sfp->headrp; resp; resp = resp->nextrp) { ++ list_for_each_entry(resp, &sfp->rq_list, entry) { + /* look for requests that are ready + not SG_IO owned */ + if ((1 == resp->done) && (!resp->sg_io_owned) && + ((-1 == pack_id) || (resp->header.pack_id == pack_id))) { +@@ -2090,70 +2095,45 @@ sg_add_request(Sg_fd * sfp) + { + int k; + unsigned long iflags; +- Sg_request *resp; + Sg_request *rp = sfp->req_arr; + + write_lock_irqsave(&sfp->rq_list_lock, iflags); +- resp = sfp->headrp; +- if (!resp) { +- memset(rp, 0, sizeof (Sg_request)); +- rp->parentfp = sfp; +- resp = rp; +- sfp->headrp = resp; +- } else { +- if (0 == sfp->cmd_q) +- resp = NULL; /* command queuing disallowed */ +- else { +- for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) { +- if (!rp->parentfp) +- break; +- } +- if (k < SG_MAX_QUEUE) { +- memset(rp, 0, sizeof (Sg_request)); +- rp->parentfp = sfp; +- while (resp->nextrp) +- resp = resp->nextrp; +- resp->nextrp = rp; +- resp = rp; +- } else +- resp = NULL; ++ if (!list_empty(&sfp->rq_list)) { ++ if (!sfp->cmd_q) ++ goto out_unlock; ++ ++ for (k = 0; k < SG_MAX_QUEUE; ++k, ++rp) { ++ if (!rp->parentfp) ++ break; + } ++ if (k >= SG_MAX_QUEUE) ++ goto out_unlock; + } +- if (resp) { +- resp->nextrp = NULL; +- resp->header.duration = jiffies_to_msecs(jiffies); +- } ++ memset(rp, 0, sizeof (Sg_request)); ++ rp->parentfp = sfp; ++ rp->header.duration = jiffies_to_msecs(jiffies); ++ list_add_tail(&rp->entry, &sfp->rq_list); + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); +- return resp; ++ return rp; ++out_unlock: ++ write_unlock_irqrestore(&sfp->rq_list_lock, iflags); ++ return NULL; + } + + /* Return of 1 for found; 0 for not found */ + static int + sg_remove_request(Sg_fd * sfp, Sg_request * srp) + { +- Sg_request *prev_rp; +- Sg_request *rp; + unsigned long iflags; + int res = 0; + +- if ((!sfp) || (!srp) || (!sfp->headrp)) ++ if (!sfp || !srp || list_empty(&sfp->rq_list)) + return res; + write_lock_irqsave(&sfp->rq_list_lock, iflags); +- prev_rp = sfp->headrp; +- if (srp == prev_rp) { +- sfp->headrp = prev_rp->nextrp; +- prev_rp->parentfp = NULL; ++ if (!list_empty(&srp->entry)) { ++ list_del(&srp->entry); ++ srp->parentfp = NULL; + res = 1; +- } else { +- while ((rp = prev_rp->nextrp)) { +- if (srp == rp) { +- prev_rp->nextrp = rp->nextrp; +- rp->parentfp = NULL; +- res = 1; +- break; +- } +- prev_rp = rp; +- } + } + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + return res; +@@ -2172,7 +2152,7 @@ sg_add_sfp(Sg_device * sdp) + + init_waitqueue_head(&sfp->read_wait); + rwlock_init(&sfp->rq_list_lock); +- ++ INIT_LIST_HEAD(&sfp->rq_list); + kref_init(&sfp->f_ref); + mutex_init(&sfp->f_mutex); + sfp->timeout = SG_DEFAULT_TIMEOUT; +@@ -2213,10 +2193,13 @@ sg_remove_sfp_usercontext(struct work_struct *work) + { + struct sg_fd *sfp = container_of(work, struct sg_fd, ew.work); + struct sg_device *sdp = sfp->parentdp; ++ Sg_request *srp; + + /* Cleanup any responses which were never read(). */ +- while (sfp->headrp) +- sg_finish_rem_req(sfp->headrp); ++ while (!list_empty(&sfp->rq_list)) { ++ srp = list_first_entry(&sfp->rq_list, Sg_request, entry); ++ sg_finish_rem_req(srp); ++ } + + if (sfp->reserve.bufflen > 0) { + SCSI_LOG_TIMEOUT(6, sg_printk(KERN_INFO, sdp, +@@ -2619,7 +2602,7 @@ static int sg_proc_seq_show_devstrs(struct seq_file *s, void *v) + /* must be called while holding sg_index_lock */ + static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + { +- int k, m, new_interface, blen, usg; ++ int k, new_interface, blen, usg; + Sg_request *srp; + Sg_fd *fp; + const sg_io_hdr_t *hp; +@@ -2639,13 +2622,11 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " cmd_q=%d f_packid=%d k_orphan=%d closed=0\n", + (int) fp->cmd_q, (int) fp->force_packid, + (int) fp->keep_orphan); +- for (m = 0, srp = fp->headrp; +- srp != NULL; +- ++m, srp = srp->nextrp) { ++ list_for_each_entry(srp, &fp->rq_list, entry) { + hp = &srp->header; + new_interface = (hp->interface_id == '\0') ? 0 : 1; + if (srp->res_used) { +- if (new_interface && ++ if (new_interface && + (SG_FLAG_MMAP_IO & hp->flags)) + cp = " mmap>> "; + else +@@ -2676,7 +2657,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); + } +- if (0 == m) ++ if (list_empty(&fp->rq_list)) + seq_puts(s, " No requests active\n"); + read_unlock(&fp->rq_list_lock); + } +diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c +index cd5c1c060481..6df2841cb7f9 100644 +--- a/drivers/scsi/storvsc_drv.c ++++ b/drivers/scsi/storvsc_drv.c +@@ -1511,6 +1511,8 @@ static int storvsc_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scmnd) + ret = storvsc_do_io(dev, cmd_request); + + if (ret == -EAGAIN) { ++ if (payload_sz > sizeof(cmd_request->mpb)) ++ kfree(payload); + /* no more space */ + return SCSI_MLQUEUE_DEVICE_BUSY; + } +diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c +index fb31eecb708d..8f3566cde3eb 100644 +--- a/drivers/tty/tty_buffer.c ++++ b/drivers/tty/tty_buffer.c +@@ -361,6 +361,32 @@ int tty_insert_flip_string_flags(struct tty_port *port, + } + EXPORT_SYMBOL(tty_insert_flip_string_flags); + ++/** ++ * __tty_insert_flip_char - Add one character to the tty buffer ++ * @port: tty port ++ * @ch: character ++ * @flag: flag byte ++ * ++ * Queue a single byte to the tty buffering, with an optional flag. ++ * This is the slow path of tty_insert_flip_char. ++ */ ++int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag) ++{ ++ struct tty_buffer *tb; ++ int flags = (flag == TTY_NORMAL) ? TTYB_NORMAL : 0; ++ ++ if (!__tty_buffer_request_room(port, 1, flags)) ++ return 0; ++ ++ tb = port->buf.tail; ++ if (~tb->flags & TTYB_NORMAL) ++ *flag_buf_ptr(tb, tb->used) = flag; ++ *char_buf_ptr(tb, tb->used++) = ch; ++ ++ return 1; ++} ++EXPORT_SYMBOL(__tty_insert_flip_char); ++ + /** + * tty_schedule_flip - push characters to ldisc + * @port: tty port to push from +diff --git a/fs/ext4/super.c b/fs/ext4/super.c +index 68345a9e59b8..32941cd6d34b 100644 +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -2205,6 +2205,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, + unsigned int s_flags = sb->s_flags; + int nr_orphans = 0, nr_truncates = 0; + #ifdef CONFIG_QUOTA ++ int quota_update = 0; + int i; + #endif + if (!es->s_last_orphan) { +@@ -2243,14 +2244,32 @@ static void ext4_orphan_cleanup(struct super_block *sb, + #ifdef CONFIG_QUOTA + /* Needed for iput() to work correctly and not trash data */ + sb->s_flags |= MS_ACTIVE; +- /* Turn on quotas so that they are updated correctly */ ++ ++ /* ++ * Turn on quotas which were not enabled for read-only mounts if ++ * filesystem has quota feature, so that they are updated correctly. ++ */ ++ if (ext4_has_feature_quota(sb) && (s_flags & MS_RDONLY)) { ++ int ret = ext4_enable_quotas(sb); ++ ++ if (!ret) ++ quota_update = 1; ++ else ++ ext4_msg(sb, KERN_ERR, ++ "Cannot turn on quotas: error %d", ret); ++ } ++ ++ /* Turn on journaled quotas used for old sytle */ + for (i = 0; i < EXT4_MAXQUOTAS; i++) { + if (EXT4_SB(sb)->s_qf_names[i]) { + int ret = ext4_quota_on_mount(sb, i); +- if (ret < 0) ++ ++ if (!ret) ++ quota_update = 1; ++ else + ext4_msg(sb, KERN_ERR, + "Cannot turn on journaled " +- "quota: error %d", ret); ++ "quota: type %d: error %d", i, ret); + } + } + #endif +@@ -2309,10 +2328,12 @@ static void ext4_orphan_cleanup(struct super_block *sb, + ext4_msg(sb, KERN_INFO, "%d truncate%s cleaned up", + PLURAL(nr_truncates)); + #ifdef CONFIG_QUOTA +- /* Turn quotas off */ +- for (i = 0; i < EXT4_MAXQUOTAS; i++) { +- if (sb_dqopt(sb)->files[i]) +- dquot_quota_off(sb, i); ++ /* Turn off quotas if they were enabled for orphan cleanup */ ++ if (quota_update) { ++ for (i = 0; i < EXT4_MAXQUOTAS; i++) { ++ if (sb_dqopt(sb)->files[i]) ++ dquot_quota_off(sb, i); ++ } + } + #endif + sb->s_flags = s_flags; /* Restore MS_RDONLY status */ +@@ -5120,6 +5141,9 @@ static int ext4_enable_quotas(struct super_block *sb) + err = ext4_quota_enable(sb, type, QFMT_VFS_V1, + DQUOT_USAGE_ENABLED); + if (err) { ++ for (type--; type >= 0; type--) ++ dquot_quota_off(sb, type); ++ + ext4_warning(sb, + "Failed to enable quota tracking " + "(type=%d, err=%d). Please run " +diff --git a/fs/f2fs/recovery.c b/fs/f2fs/recovery.c +index cbf74f47cce8..e32f349f341b 100644 +--- a/fs/f2fs/recovery.c ++++ b/fs/f2fs/recovery.c +@@ -276,7 +276,7 @@ static int check_index_in_prev_nodes(struct f2fs_sb_info *sbi, + return 0; + + /* Get the previous summary */ +- for (i = CURSEG_WARM_DATA; i <= CURSEG_COLD_DATA; i++) { ++ for (i = CURSEG_HOT_DATA; i <= CURSEG_COLD_DATA; i++) { + struct curseg_info *curseg = CURSEG_I(sbi, i); + if (curseg->segno == segno) { + sum = curseg->sum_blk->entries[blkoff]; +diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c +index c7f1ce41442a..9e5a6842346e 100644 +--- a/fs/nfsd/nfs4state.c ++++ b/fs/nfsd/nfs4state.c +@@ -1145,9 +1145,7 @@ static void put_ol_stateid_locked(struct nfs4_ol_stateid *stp, + + static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp) + { +- struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); +- +- lockdep_assert_held(&oo->oo_owner.so_client->cl_lock); ++ lockdep_assert_held(&stp->st_stid.sc_client->cl_lock); + + list_del_init(&stp->st_locks); + nfs4_unhash_stid(&stp->st_stid); +@@ -1156,12 +1154,12 @@ static bool unhash_lock_stateid(struct nfs4_ol_stateid *stp) + + static void release_lock_stateid(struct nfs4_ol_stateid *stp) + { +- struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner); ++ struct nfs4_client *clp = stp->st_stid.sc_client; + bool unhashed; + +- spin_lock(&oo->oo_owner.so_client->cl_lock); ++ spin_lock(&clp->cl_lock); + unhashed = unhash_lock_stateid(stp); +- spin_unlock(&oo->oo_owner.so_client->cl_lock); ++ spin_unlock(&clp->cl_lock); + if (unhashed) + nfs4_put_stid(&stp->st_stid); + } +diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h +index c28dd523f96e..d43837f2ce3a 100644 +--- a/include/linux/tty_flip.h ++++ b/include/linux/tty_flip.h +@@ -12,6 +12,7 @@ extern int tty_prepare_flip_string(struct tty_port *port, + unsigned char **chars, size_t size); + extern void tty_flip_buffer_push(struct tty_port *port); + void tty_schedule_flip(struct tty_port *port); ++int __tty_insert_flip_char(struct tty_port *port, unsigned char ch, char flag); + + static inline int tty_insert_flip_char(struct tty_port *port, + unsigned char ch, char flag) +@@ -26,7 +27,7 @@ static inline int tty_insert_flip_char(struct tty_port *port, + *char_buf_ptr(tb, tb->used++) = ch; + return 1; + } +- return tty_insert_flip_string_flags(port, &ch, &flag, 1); ++ return __tty_insert_flip_char(port, ch, flag); + } + + static inline int tty_insert_flip_string(struct tty_port *port, +diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h +index ac42bbb37b2d..c26a6e4dc306 100644 +--- a/include/net/inet_frag.h ++++ b/include/net/inet_frag.h +@@ -1,14 +1,9 @@ + #ifndef __NET_FRAG_H__ + #define __NET_FRAG_H__ + +-#include <linux/percpu_counter.h> +- + struct netns_frags { +- /* The percpu_counter "mem" need to be cacheline aligned. +- * mem.count must not share cacheline with other writers +- */ +- struct percpu_counter mem ____cacheline_aligned_in_smp; +- ++ /* Keep atomic mem on separate cachelines in structs that include it */ ++ atomic_t mem ____cacheline_aligned_in_smp; + /* sysctls */ + int timeout; + int high_thresh; +@@ -108,15 +103,10 @@ struct inet_frags { + int inet_frags_init(struct inet_frags *); + void inet_frags_fini(struct inet_frags *); + +-static inline int inet_frags_init_net(struct netns_frags *nf) +-{ +- return percpu_counter_init(&nf->mem, 0, GFP_KERNEL); +-} +-static inline void inet_frags_uninit_net(struct netns_frags *nf) ++static inline void inet_frags_init_net(struct netns_frags *nf) + { +- percpu_counter_destroy(&nf->mem); ++ atomic_set(&nf->mem, 0); + } +- + void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f); + + void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f); +@@ -140,37 +130,24 @@ static inline bool inet_frag_evicting(struct inet_frag_queue *q) + + /* Memory Tracking Functions. */ + +-/* The default percpu_counter batch size is not big enough to scale to +- * fragmentation mem acct sizes. +- * The mem size of a 64K fragment is approx: +- * (44 fragments * 2944 truesize) + frag_queue struct(200) = 129736 bytes +- */ +-static unsigned int frag_percpu_counter_batch = 130000; +- + static inline int frag_mem_limit(struct netns_frags *nf) + { +- return percpu_counter_read(&nf->mem); ++ return atomic_read(&nf->mem); + } + + static inline void sub_frag_mem_limit(struct netns_frags *nf, int i) + { +- __percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch); ++ atomic_sub(i, &nf->mem); + } + + static inline void add_frag_mem_limit(struct netns_frags *nf, int i) + { +- __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch); ++ atomic_add(i, &nf->mem); + } + +-static inline unsigned int sum_frag_mem_limit(struct netns_frags *nf) ++static inline int sum_frag_mem_limit(struct netns_frags *nf) + { +- unsigned int res; +- +- local_bh_disable(); +- res = percpu_counter_sum_positive(&nf->mem); +- local_bh_enable(); +- +- return res; ++ return atomic_read(&nf->mem); + } + + /* RFC 3168 support : +diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h +index fb961a576abe..fa5e703a14ed 100644 +--- a/include/net/ip6_fib.h ++++ b/include/net/ip6_fib.h +@@ -68,6 +68,7 @@ struct fib6_node { + __u16 fn_flags; + int fn_sernum; + struct rt6_info *rr_ptr; ++ struct rcu_head rcu; + }; + + #ifndef CONFIG_IPV6_SUBTREES +@@ -102,7 +103,7 @@ struct rt6_info { + * the same cache line. + */ + struct fib6_table *rt6i_table; +- struct fib6_node *rt6i_node; ++ struct fib6_node __rcu *rt6i_node; + + struct in6_addr rt6i_gateway; + +@@ -165,13 +166,40 @@ static inline void rt6_update_expires(struct rt6_info *rt0, int timeout) + rt0->rt6i_flags |= RTF_EXPIRES; + } + ++/* Function to safely get fn->sernum for passed in rt ++ * and store result in passed in cookie. ++ * Return true if we can get cookie safely ++ * Return false if not ++ */ ++static inline bool rt6_get_cookie_safe(const struct rt6_info *rt, ++ u32 *cookie) ++{ ++ struct fib6_node *fn; ++ bool status = false; ++ ++ rcu_read_lock(); ++ fn = rcu_dereference(rt->rt6i_node); ++ ++ if (fn) { ++ *cookie = fn->fn_sernum; ++ status = true; ++ } ++ ++ rcu_read_unlock(); ++ return status; ++} ++ + static inline u32 rt6_get_cookie(const struct rt6_info *rt) + { ++ u32 cookie = 0; ++ + if (rt->rt6i_flags & RTF_PCPU || + (unlikely(rt->dst.flags & DST_NOCACHE) && rt->dst.from)) + rt = (struct rt6_info *)(rt->dst.from); + +- return rt->rt6i_node ? rt->rt6i_node->fn_sernum : 0; ++ rt6_get_cookie_safe(rt, &cookie); ++ ++ return cookie; + } + + static inline void ip6_rt_put(struct rt6_info *rt) +diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c +index eba904bae48c..38d73a6e2857 100644 +--- a/kernel/trace/ftrace.c ++++ b/kernel/trace/ftrace.c +@@ -2667,13 +2667,14 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) + + if (!command || !ftrace_enabled) { + /* +- * If these are control ops, they still need their +- * per_cpu field freed. Since, function tracing is ++ * If these are dynamic or control ops, they still ++ * need their data freed. Since, function tracing is + * not currently active, we can just free them + * without synchronizing all CPUs. + */ +- if (ops->flags & FTRACE_OPS_FL_CONTROL) +- control_ops_free(ops); ++ if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) ++ goto free_ops; ++ + return 0; + } + +@@ -2728,6 +2729,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command) + if (ops->flags & (FTRACE_OPS_FL_DYNAMIC | FTRACE_OPS_FL_CONTROL)) { + schedule_on_each_cpu(ftrace_sync); + ++ free_ops: + arch_ftrace_trampoline_free(ops); + + if (ops->flags & FTRACE_OPS_FL_CONTROL) +diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c +index d59ebd9d21df..4743066010c4 100644 +--- a/kernel/trace/trace.c ++++ b/kernel/trace/trace.c +@@ -5237,7 +5237,7 @@ static int tracing_set_clock(struct trace_array *tr, const char *clockstr) + tracing_reset_online_cpus(&tr->trace_buffer); + + #ifdef CONFIG_TRACER_MAX_TRACE +- if (tr->flags & TRACE_ARRAY_FL_GLOBAL && tr->max_buffer.buffer) ++ if (tr->max_buffer.buffer) + ring_buffer_set_clock(tr->max_buffer.buffer, trace_clocks[i].func); + tracing_reset_online_cpus(&tr->max_buffer); + #endif +diff --git a/kernel/trace/trace_selftest.c b/kernel/trace/trace_selftest.c +index b0f86ea77881..ca70d11b8aa7 100644 +--- a/kernel/trace/trace_selftest.c ++++ b/kernel/trace/trace_selftest.c +@@ -272,7 +272,7 @@ static int trace_selftest_ops(struct trace_array *tr, int cnt) + goto out_free; + if (cnt > 1) { + if (trace_selftest_test_global_cnt == 0) +- goto out; ++ goto out_free; + } + if (trace_selftest_test_dyn_cnt == 0) + goto out_free; +diff --git a/mm/page_alloc.c b/mm/page_alloc.c +index 53286b2f5b1c..6b5421ae86c6 100644 +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -1748,13 +1748,25 @@ static void unreserve_highatomic_pageblock(const struct alloc_context *ac) + struct page, lru); + + /* +- * It should never happen but changes to locking could +- * inadvertently allow a per-cpu drain to add pages +- * to MIGRATE_HIGHATOMIC while unreserving so be safe +- * and watch for underflows. ++ * In page freeing path, migratetype change is racy so ++ * we can counter several free pages in a pageblock ++ * in this loop althoug we changed the pageblock type ++ * from highatomic to ac->migratetype. So we should ++ * adjust the count once. + */ +- zone->nr_reserved_highatomic -= min(pageblock_nr_pages, +- zone->nr_reserved_highatomic); ++ if (get_pageblock_migratetype(page) == ++ MIGRATE_HIGHATOMIC) { ++ /* ++ * It should never happen but changes to ++ * locking could inadvertently allow a per-cpu ++ * drain to add pages to MIGRATE_HIGHATOMIC ++ * while unreserving so be safe and watch for ++ * underflows. ++ */ ++ zone->nr_reserved_highatomic -= min( ++ pageblock_nr_pages, ++ zone->nr_reserved_highatomic); ++ } + + /* + * Convert to ac->migratetype and avoid the normal +diff --git a/net/ieee802154/6lowpan/reassembly.c b/net/ieee802154/6lowpan/reassembly.c +index 6b437e8760d3..12e8cf4bda9f 100644 +--- a/net/ieee802154/6lowpan/reassembly.c ++++ b/net/ieee802154/6lowpan/reassembly.c +@@ -580,19 +580,14 @@ static int __net_init lowpan_frags_init_net(struct net *net) + { + struct netns_ieee802154_lowpan *ieee802154_lowpan = + net_ieee802154_lowpan(net); +- int res; + + ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH; + ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH; + ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT; + +- res = inet_frags_init_net(&ieee802154_lowpan->frags); +- if (res) +- return res; +- res = lowpan_frags_ns_sysctl_register(net); +- if (res) +- inet_frags_uninit_net(&ieee802154_lowpan->frags); +- return res; ++ inet_frags_init_net(&ieee802154_lowpan->frags); ++ ++ return lowpan_frags_ns_sysctl_register(net); + } + + static void __net_exit lowpan_frags_exit_net(struct net *net) +diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c +index fe144dae7372..c5fb2f694ed0 100644 +--- a/net/ipv4/inet_fragment.c ++++ b/net/ipv4/inet_fragment.c +@@ -234,10 +234,8 @@ evict_again: + cond_resched(); + + if (read_seqretry(&f->rnd_seqlock, seq) || +- percpu_counter_sum(&nf->mem)) ++ sum_frag_mem_limit(nf)) + goto evict_again; +- +- percpu_counter_destroy(&nf->mem); + } + EXPORT_SYMBOL(inet_frags_exit_net); + +diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c +index b8a0607dab96..e2e162432aa3 100644 +--- a/net/ipv4/ip_fragment.c ++++ b/net/ipv4/ip_fragment.c +@@ -840,8 +840,6 @@ static void __init ip4_frags_ctl_register(void) + + static int __net_init ipv4_frags_init_net(struct net *net) + { +- int res; +- + /* Fragment cache limits. + * + * The fragment memory accounting code, (tries to) account for +@@ -865,13 +863,9 @@ static int __net_init ipv4_frags_init_net(struct net *net) + */ + net->ipv4.frags.timeout = IP_FRAG_TIME; + +- res = inet_frags_init_net(&net->ipv4.frags); +- if (res) +- return res; +- res = ip4_frags_ns_ctl_register(net); +- if (res) +- inet_frags_uninit_net(&net->ipv4.frags); +- return res; ++ inet_frags_init_net(&net->ipv4.frags); ++ ++ return ip4_frags_ns_ctl_register(net); + } + + static void __net_exit ipv4_frags_exit_net(struct net *net) +diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c +index 0870a86e9d96..5597120c8ffd 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2260,6 +2260,10 @@ int tcp_disconnect(struct sock *sk, int flags) + tcp_set_ca_state(sk, TCP_CA_Open); + tcp_clear_retrans(tp); + inet_csk_delack_init(sk); ++ /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0 ++ * issue in __tcp_select_window() ++ */ ++ icsk->icsk_ack.rcv_mss = TCP_MIN_MSS; + tcp_init_send_head(sk); + memset(&tp->rx_opt, 0, sizeof(tp->rx_opt)); + __sk_dst_reset(sk); +diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c +index 735b22b1b4ea..92174881844d 100644 +--- a/net/ipv6/addrconf.c ++++ b/net/ipv6/addrconf.c +@@ -5152,7 +5152,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) + * our DAD process, so we don't need + * to do it again + */ +- if (!(ifp->rt->rt6i_node)) ++ if (!rcu_access_pointer(ifp->rt->rt6i_node)) + ip6_ins_rt(ifp->rt); + if (ifp->idev->cnf.forwarding) + addrconf_join_anycast(ifp); +diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c +index aad8cdf15472..c23e02a7ccb0 100644 +--- a/net/ipv6/ip6_fib.c ++++ b/net/ipv6/ip6_fib.c +@@ -150,11 +150,23 @@ static struct fib6_node *node_alloc(void) + return fn; + } + +-static void node_free(struct fib6_node *fn) ++static void node_free_immediate(struct fib6_node *fn) ++{ ++ kmem_cache_free(fib6_node_kmem, fn); ++} ++ ++static void node_free_rcu(struct rcu_head *head) + { ++ struct fib6_node *fn = container_of(head, struct fib6_node, rcu); ++ + kmem_cache_free(fib6_node_kmem, fn); + } + ++static void node_free(struct fib6_node *fn) ++{ ++ call_rcu(&fn->rcu, node_free_rcu); ++} ++ + static void rt6_rcu_free(struct rt6_info *rt) + { + call_rcu(&rt->dst.rcu_head, dst_rcu_free); +@@ -191,6 +203,12 @@ static void rt6_release(struct rt6_info *rt) + } + } + ++static void fib6_free_table(struct fib6_table *table) ++{ ++ inetpeer_invalidate_tree(&table->tb6_peers); ++ kfree(table); ++} ++ + static void fib6_link_table(struct net *net, struct fib6_table *tb) + { + unsigned int h; +@@ -588,9 +606,9 @@ insert_above: + + if (!in || !ln) { + if (in) +- node_free(in); ++ node_free_immediate(in); + if (ln) +- node_free(ln); ++ node_free_immediate(ln); + return ERR_PTR(-ENOMEM); + } + +@@ -857,7 +875,7 @@ add: + + rt->dst.rt6_next = iter; + *ins = rt; +- rt->rt6i_node = fn; ++ rcu_assign_pointer(rt->rt6i_node, fn); + atomic_inc(&rt->rt6i_ref); + inet6_rt_notify(RTM_NEWROUTE, rt, info, 0); + info->nl_net->ipv6.rt6_stats->fib_rt_entries++; +@@ -882,7 +900,7 @@ add: + return err; + + *ins = rt; +- rt->rt6i_node = fn; ++ rcu_assign_pointer(rt->rt6i_node, fn); + rt->dst.rt6_next = iter->dst.rt6_next; + atomic_inc(&rt->rt6i_ref); + inet6_rt_notify(RTM_NEWROUTE, rt, info, NLM_F_REPLACE); +@@ -1015,7 +1033,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, + root, and then (in failure) stale node + in main tree. + */ +- node_free(sfn); ++ node_free_immediate(sfn); + err = PTR_ERR(sn); + goto failure; + } +@@ -1442,8 +1460,9 @@ static void fib6_del_route(struct fib6_node *fn, struct rt6_info **rtp, + + int fib6_del(struct rt6_info *rt, struct nl_info *info) + { ++ struct fib6_node *fn = rcu_dereference_protected(rt->rt6i_node, ++ lockdep_is_held(&rt->rt6i_table->tb6_lock)); + struct net *net = info->nl_net; +- struct fib6_node *fn = rt->rt6i_node; + struct rt6_info **rtp; + + #if RT6_DEBUG >= 2 +@@ -1632,7 +1651,9 @@ static int fib6_clean_node(struct fib6_walker *w) + if (res) { + #if RT6_DEBUG >= 2 + pr_debug("%s: del failed: rt=%p@%p err=%d\n", +- __func__, rt, rt->rt6i_node, res); ++ __func__, rt, ++ rcu_access_pointer(rt->rt6i_node), ++ res); + #endif + continue; + } +@@ -1870,15 +1891,22 @@ out_timer: + + static void fib6_net_exit(struct net *net) + { ++ unsigned int i; ++ + rt6_ifdown(net, NULL); + del_timer_sync(&net->ipv6.ip6_fib_timer); + +-#ifdef CONFIG_IPV6_MULTIPLE_TABLES +- inetpeer_invalidate_tree(&net->ipv6.fib6_local_tbl->tb6_peers); +- kfree(net->ipv6.fib6_local_tbl); +-#endif +- inetpeer_invalidate_tree(&net->ipv6.fib6_main_tbl->tb6_peers); +- kfree(net->ipv6.fib6_main_tbl); ++ for (i = 0; i < FIB6_TABLE_HASHSZ; i++) { ++ struct hlist_head *head = &net->ipv6.fib_table_hash[i]; ++ struct hlist_node *tmp; ++ struct fib6_table *tb; ++ ++ hlist_for_each_entry_safe(tb, tmp, head, tb6_hlist) { ++ hlist_del(&tb->tb6_hlist); ++ fib6_free_table(tb); ++ } ++ } ++ + kfree(net->ipv6.fib_table_hash); + kfree(net->ipv6.rt6_stats); + } +diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c +index bab4441ed4e4..eb2dc39f7066 100644 +--- a/net/ipv6/netfilter/nf_conntrack_reasm.c ++++ b/net/ipv6/netfilter/nf_conntrack_reasm.c +@@ -649,18 +649,12 @@ EXPORT_SYMBOL_GPL(nf_ct_frag6_consume_orig); + + static int nf_ct_net_init(struct net *net) + { +- int res; +- + net->nf_frag.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; + net->nf_frag.frags.low_thresh = IPV6_FRAG_LOW_THRESH; + net->nf_frag.frags.timeout = IPV6_FRAG_TIMEOUT; +- res = inet_frags_init_net(&net->nf_frag.frags); +- if (res) +- return res; +- res = nf_ct_frag6_sysctl_register(net); +- if (res) +- inet_frags_uninit_net(&net->nf_frag.frags); +- return res; ++ inet_frags_init_net(&net->nf_frag.frags); ++ ++ return nf_ct_frag6_sysctl_register(net); + } + + static void nf_ct_net_exit(struct net *net) +diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c +index f9f02581c4ca..f99a04674419 100644 +--- a/net/ipv6/output_core.c ++++ b/net/ipv6/output_core.c +@@ -86,7 +86,6 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) + + while (offset <= packet_len) { + struct ipv6_opt_hdr *exthdr; +- unsigned int len; + + switch (**nexthdr) { + +@@ -112,10 +111,9 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) + + exthdr = (struct ipv6_opt_hdr *)(skb_network_header(skb) + + offset); +- len = ipv6_optlen(exthdr); +- if (len + offset >= IPV6_MAXPLEN) ++ offset += ipv6_optlen(exthdr); ++ if (offset > IPV6_MAXPLEN) + return -EINVAL; +- offset += len; + *nexthdr = &exthdr->nexthdr; + } + +diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c +index a234552a7e3d..58f2139ebb5e 100644 +--- a/net/ipv6/reassembly.c ++++ b/net/ipv6/reassembly.c +@@ -708,19 +708,13 @@ static void ip6_frags_sysctl_unregister(void) + + static int __net_init ipv6_frags_init_net(struct net *net) + { +- int res; +- + net->ipv6.frags.high_thresh = IPV6_FRAG_HIGH_THRESH; + net->ipv6.frags.low_thresh = IPV6_FRAG_LOW_THRESH; + net->ipv6.frags.timeout = IPV6_FRAG_TIMEOUT; + +- res = inet_frags_init_net(&net->ipv6.frags); +- if (res) +- return res; +- res = ip6_frags_ns_sysctl_register(net); +- if (res) +- inet_frags_uninit_net(&net->ipv6.frags); +- return res; ++ inet_frags_init_net(&net->ipv6.frags); ++ ++ return ip6_frags_ns_sysctl_register(net); + } + + static void __net_exit ipv6_frags_exit_net(struct net *net) +diff --git a/net/ipv6/route.c b/net/ipv6/route.c +index ef335070e98a..48917437550e 100644 +--- a/net/ipv6/route.c ++++ b/net/ipv6/route.c +@@ -1248,7 +1248,9 @@ static void rt6_dst_from_metrics_check(struct rt6_info *rt) + + static struct dst_entry *rt6_check(struct rt6_info *rt, u32 cookie) + { +- if (!rt->rt6i_node || (rt->rt6i_node->fn_sernum != cookie)) ++ u32 rt_cookie; ++ ++ if (!rt6_get_cookie_safe(rt, &rt_cookie) || rt_cookie != cookie) + return NULL; + + if (rt6_check_expired(rt)) +@@ -1316,8 +1318,14 @@ static void ip6_link_failure(struct sk_buff *skb) + if (rt->rt6i_flags & RTF_CACHE) { + dst_hold(&rt->dst); + ip6_del_rt(rt); +- } else if (rt->rt6i_node && (rt->rt6i_flags & RTF_DEFAULT)) { +- rt->rt6i_node->fn_sernum = -1; ++ } else { ++ struct fib6_node *fn; ++ ++ rcu_read_lock(); ++ fn = rcu_dereference(rt->rt6i_node); ++ if (fn && (rt->rt6i_flags & RTF_DEFAULT)) ++ fn->fn_sernum = -1; ++ rcu_read_unlock(); + } + } + } +@@ -1334,7 +1342,8 @@ static void rt6_do_update_pmtu(struct rt6_info *rt, u32 mtu) + static bool rt6_cache_allowed_for_pmtu(const struct rt6_info *rt) + { + return !(rt->rt6i_flags & RTF_CACHE) && +- (rt->rt6i_flags & RTF_PCPU || rt->rt6i_node); ++ (rt->rt6i_flags & RTF_PCPU || ++ rcu_access_pointer(rt->rt6i_node)); + } + + static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, |