public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-08-22 15:06 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-08-22 15:06 UTC (permalink / raw
  To: gentoo-commits

commit:     3588a4790a924cb888ff5717434c6db1b034cfa3
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Aug 22 15:06:29 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Aug 22 15:06:29 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=3588a479

Gentoo Linux support config settings and defaults. Patch to add support for namespace user.pax.* on tmpfs. Patch to enable link security restrictions by default.
Patch to ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs. Patch to enable control of the unaligned access control policy from sysctl

 0000_README                                        |  24 ++
 1500_XATTR_USER_PREFIX.patch                       |  69 ++++
 ...ble-link-security-restrictions-by-default.patch |  22 ++
 2900_dev-root-proc-mount-fix.patch                 |  38 ++
 4400_alpha-sysctl-uac.patch                        | 142 +++++++
 ...-additional-cpu-optimizations-for-gcc-4.9.patch | 426 +++++++++++++++++++++
 6 files changed, 721 insertions(+)

diff --git a/0000_README b/0000_README
index 9018993..777f7c8 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,30 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1500_XATTR_USER_PREFIX.patch
+From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
+Desc:   Support for namespace user.pax.* on tmpfs.
+
+Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
+From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
+Desc:   Enable link security restrictions by default.
+
+Patch:  2900_dev-root-proc-mount-fix.patch
+From:   https://bugs.gentoo.org/show_bug.cgi?id=438380
+Desc:   Ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs.
+
+Patch:  4400_alpha-sysctl-uac.patch
+From:   Tobias Klausmann (klausman@gentoo.org) and http://bugs.gentoo.org/show_bug.cgi?id=217323 
+Desc:   Enable control of the unaligned access control policy from sysctl
+
 Patch:  4567_distro-Gentoo-Kconfig.patch
 From:   Tom Wijsman <TomWij@gentoo.org>
 Desc:   Add Gentoo Linux support config settings and defaults.
+
+Patch:  5000_enable-additional-cpu-optimizations-for-gcc.patch
+From:   https://github.com/graysky2/kernel_gcc_patch/
+Desc:   Kernel patch enables gcc < v4.9 optimizations for additional CPUs.
+
+Patch:  5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
+From:   https://github.com/graysky2/kernel_gcc_patch/
+Desc:   Kernel patch enables gcc >= v4.9 optimizations for additional CPUs.

diff --git a/1500_XATTR_USER_PREFIX.patch b/1500_XATTR_USER_PREFIX.patch
new file mode 100644
index 0000000..bacd032
--- /dev/null
+++ b/1500_XATTR_USER_PREFIX.patch
@@ -0,0 +1,69 @@
+From: Anthony G. Basile <blueness@gentoo.org>
+
+This patch adds support for a restricted user-controlled namespace on
+tmpfs filesystem used to house PaX flags.  The namespace must be of the
+form user.pax.* and its value cannot exceed a size of 8 bytes.
+
+This is needed even on all Gentoo systems so that XATTR_PAX flags
+are preserved for users who might build packages using portage on
+a tmpfs system with a non-hardened kernel and then switch to a
+hardened kernel with XATTR_PAX enabled.
+
+The namespace is added to any user with Extended Attribute support
+enabled for tmpfs.  Users who do not enable xattrs will not have
+the XATTR_PAX flags preserved.
+
+diff --git a/include/uapi/linux/xattr.h b/include/uapi/linux/xattr.h
+index 1590c49..5eab462 100644
+--- a/include/uapi/linux/xattr.h
++++ b/include/uapi/linux/xattr.h
+@@ -73,5 +73,9 @@
+ #define XATTR_POSIX_ACL_DEFAULT  "posix_acl_default"
+ #define XATTR_NAME_POSIX_ACL_DEFAULT XATTR_SYSTEM_PREFIX XATTR_POSIX_ACL_DEFAULT
+ 
++/* User namespace */
++#define XATTR_PAX_PREFIX XATTR_USER_PREFIX "pax."
++#define XATTR_PAX_FLAGS_SUFFIX "flags"
++#define XATTR_NAME_PAX_FLAGS XATTR_PAX_PREFIX XATTR_PAX_FLAGS_SUFFIX
+ 
+ #endif /* _UAPI_LINUX_XATTR_H */
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 440e2a7..c377172 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -2667,6 +2667,14 @@ static int shmem_xattr_handler_set(const struct xattr_handler *handler,
+ 	struct shmem_inode_info *info = SHMEM_I(d_inode(dentry));
+ 
+ 	name = xattr_full_name(handler, name);
++
++	if (!strncmp(name, XATTR_USER_PREFIX, XATTR_USER_PREFIX_LEN)) {
++		if (strcmp(name, XATTR_NAME_PAX_FLAGS))
++			return -EOPNOTSUPP;
++		if (size > 8)
++			return -EINVAL;
++	}
++
+ 	return simple_xattr_set(&info->xattrs, name, value, size, flags);
+ }
+ 
+@@ -2682,6 +2690,12 @@ static const struct xattr_handler shmem_trusted_xattr_handler = {
+ 	.set = shmem_xattr_handler_set,
+ };
+ 
++static const struct xattr_handler shmem_user_xattr_handler = {
++	.prefix = XATTR_USER_PREFIX,
++	.get = shmem_xattr_handler_get,
++	.set = shmem_xattr_handler_set,
++};
++
+ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ #ifdef CONFIG_TMPFS_POSIX_ACL
+ 	&posix_acl_access_xattr_handler,
+@@ -2689,6 +2703,7 @@ static const struct xattr_handler *shmem_xattr_handlers[] = {
+ #endif
+ 	&shmem_security_xattr_handler,
+ 	&shmem_trusted_xattr_handler,
++	&shmem_user_xattr_handler,
+ 	NULL
+ };
+ 

diff --git a/1510_fs-enable-link-security-restrictions-by-default.patch b/1510_fs-enable-link-security-restrictions-by-default.patch
new file mode 100644
index 0000000..639fb3c
--- /dev/null
+++ b/1510_fs-enable-link-security-restrictions-by-default.patch
@@ -0,0 +1,22 @@
+From: Ben Hutchings <ben@decadent.org.uk>
+Subject: fs: Enable link security restrictions by default
+Date: Fri, 02 Nov 2012 05:32:06 +0000
+Bug-Debian: https://bugs.debian.org/609455
+Forwarded: not-needed
+
+This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415
+('VFS: don't do protected {sym,hard}links by default').
+
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -651,8 +651,8 @@ static inline void put_link(struct namei
+ 	path_put(link);
+ }
+ 
+-int sysctl_protected_symlinks __read_mostly = 0;
+-int sysctl_protected_hardlinks __read_mostly = 0;
++int sysctl_protected_symlinks __read_mostly = 1;
++int sysctl_protected_hardlinks __read_mostly = 1;
+ 
+ /**
+  * may_follow_link - Check symlink following for unsafe situations

diff --git a/2900_dev-root-proc-mount-fix.patch b/2900_dev-root-proc-mount-fix.patch
new file mode 100644
index 0000000..60af1eb
--- /dev/null
+++ b/2900_dev-root-proc-mount-fix.patch
@@ -0,0 +1,38 @@
+--- a/init/do_mounts.c	2015-08-19 10:27:16.753852576 -0400
++++ b/init/do_mounts.c	2015-08-19 10:34:25.473850353 -0400
+@@ -490,7 +490,11 @@ void __init change_floppy(char *fmt, ...
+ 	va_start(args, fmt);
+ 	vsprintf(buf, fmt, args);
+ 	va_end(args);
+-	fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
++	if (saved_root_name[0])
++		fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0);
++	else
++		fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
++
+ 	if (fd >= 0) {
+ 		sys_ioctl(fd, FDEJECT, 0);
+ 		sys_close(fd);
+@@ -534,11 +538,17 @@ void __init mount_root(void)
+ #endif
+ #ifdef CONFIG_BLOCK
+ 	{
+-		int err = create_dev("/dev/root", ROOT_DEV);
+-
+-		if (err < 0)
+-			pr_emerg("Failed to create /dev/root: %d\n", err);
+-		mount_block_root("/dev/root", root_mountflags);
++		if (saved_root_name[0] == '/') {
++	       	int err = create_dev(saved_root_name, ROOT_DEV);
++			if (err < 0)
++				pr_emerg("Failed to create %s: %d\n", saved_root_name, err);
++			mount_block_root(saved_root_name, root_mountflags);
++		} else {
++			int err = create_dev("/dev/root", ROOT_DEV);
++			if (err < 0)
++				pr_emerg("Failed to create /dev/root: %d\n", err);
++			mount_block_root("/dev/root", root_mountflags);
++		}
+ 	}
+ #endif
+ }

diff --git a/4400_alpha-sysctl-uac.patch b/4400_alpha-sysctl-uac.patch
new file mode 100644
index 0000000..d42b4ed
--- /dev/null
+++ b/4400_alpha-sysctl-uac.patch
@@ -0,0 +1,142 @@
+diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
+index 7f312d8..1eb686b 100644
+--- a/arch/alpha/Kconfig
++++ b/arch/alpha/Kconfig
+@@ -697,6 +697,33 @@ config HZ
+ 	default 1200 if HZ_1200
+ 	default 1024
+
++config ALPHA_UAC_SYSCTL
++       bool "Configure UAC policy via sysctl"
++       depends on SYSCTL
++       default y
++       ---help---
++         Configuring the UAC (unaligned access control) policy on a Linux
++         system usually involves setting a compile time define. If you say
++         Y here, you will be able to modify the UAC policy at runtime using
++         the /proc interface.
++
++         The UAC policy defines the action Linux should take when an
++         unaligned memory access occurs. The action can include printing a
++         warning message (NOPRINT), sending a signal to the offending
++         program to help developers debug their applications (SIGBUS), or
++         disabling the transparent fixing (NOFIX).
++
++         The sysctls will be initialized to the compile-time defined UAC
++         policy. You can change these manually, or with the sysctl(8)
++         userspace utility.
++
++         To disable the warning messages at runtime, you would use
++
++           echo 1 > /proc/sys/kernel/uac/noprint
++
++         This is pretty harmless. Say Y if you're not sure.
++
++
+ source "drivers/pci/Kconfig"
+ source "drivers/eisa/Kconfig"
+
+diff --git a/arch/alpha/kernel/traps.c b/arch/alpha/kernel/traps.c
+index 74aceea..cb35d80 100644
+--- a/arch/alpha/kernel/traps.c
++++ b/arch/alpha/kernel/traps.c
+@@ -103,6 +103,49 @@ static char * ireg_name[] = {"v0", "t0", "t1", "t2", "t3", "t4", "t5", "t6",
+ 			   "t10", "t11", "ra", "pv", "at", "gp", "sp", "zero"};
+ #endif
+
++#ifdef CONFIG_ALPHA_UAC_SYSCTL
++
++#include <linux/sysctl.h>
++
++static int enabled_noprint = 0;
++static int enabled_sigbus = 0;
++static int enabled_nofix = 0;
++
++struct ctl_table uac_table[] = {
++       {
++               .procname       = "noprint",
++               .data           = &enabled_noprint,
++               .maxlen         = sizeof (int),
++               .mode           = 0644,
++               .proc_handler = &proc_dointvec,
++       },
++       {
++               .procname       = "sigbus",
++               .data           = &enabled_sigbus,
++               .maxlen         = sizeof (int),
++               .mode           = 0644,
++               .proc_handler = &proc_dointvec,
++       },
++       {
++               .procname       = "nofix",
++               .data           = &enabled_nofix,
++               .maxlen         = sizeof (int),
++               .mode           = 0644,
++               .proc_handler = &proc_dointvec,
++       },
++       { }
++};
++
++static int __init init_uac_sysctl(void)
++{
++   /* Initialize sysctls with the #defined UAC policy */
++   enabled_noprint = (test_thread_flag (TS_UAC_NOPRINT)) ? 1 : 0;
++   enabled_sigbus = (test_thread_flag (TS_UAC_SIGBUS)) ? 1 : 0;
++   enabled_nofix = (test_thread_flag (TS_UAC_NOFIX)) ? 1 : 0;
++   return 0;
++}
++#endif
++
+ static void
+ dik_show_code(unsigned int *pc)
+ {
+@@ -785,7 +828,12 @@ do_entUnaUser(void __user * va, unsigned long opcode,
+ 	/* Check the UAC bits to decide what the user wants us to do
+ 	   with the unaliged access.  */
+
++#ifndef CONFIG_ALPHA_UAC_SYSCTL
+ 	if (!(current_thread_info()->status & TS_UAC_NOPRINT)) {
++#else  /* CONFIG_ALPHA_UAC_SYSCTL */
++	if (!(current_thread_info()->status & TS_UAC_NOPRINT) &&
++	    !(enabled_noprint)) {
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
+ 		if (__ratelimit(&ratelimit)) {
+ 			printk("%s(%d): unaligned trap at %016lx: %p %lx %ld\n",
+ 			       current->comm, task_pid_nr(current),
+@@ -1090,3 +1138,6 @@ trap_init(void)
+ 	wrent(entSys, 5);
+ 	wrent(entDbg, 6);
+ }
++#ifdef CONFIG_ALPHA_UAC_SYSCTL
++       __initcall(init_uac_sysctl);
++#endif
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 87b2fc3..55021a8 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -152,6 +152,11 @@ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
+ #ifdef CONFIG_INOTIFY_USER
+ #include <linux/inotify.h>
+ #endif
++
++#ifdef CONFIG_ALPHA_UAC_SYSCTL
++extern struct ctl_table uac_table[];
++#endif
++
+ #ifdef CONFIG_SPARC
+ #endif
+
+@@ -1844,6 +1849,13 @@ static struct ctl_table debug_table[] = {
+ 		.extra2		= &one,
+ 	},
+ #endif
++#ifdef CONFIG_ALPHA_UAC_SYSCTL
++	{
++	        .procname   = "uac",
++		.mode       = 0555,
++	        .child      = uac_table,
++	 },
++#endif /* CONFIG_ALPHA_UAC_SYSCTL */
+ 	{ }
+ };
+

diff --git a/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch b/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
new file mode 100644
index 0000000..d9729b2
--- /dev/null
+++ b/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
@@ -0,0 +1,426 @@
+WARNING - this version of the patch works with version 4.9+ of gcc and with
+kernel version 3.15.x+ and should NOT be applied when compiling on older
+versions due to name changes of the flags with the 4.9 release of gcc.
+Use the older version of this patch hosted on the same github for older
+versions of gcc. For example:
+
+corei7 --> nehalem
+corei7-avx --> sandybridge
+core-avx-i --> ivybridge
+core-avx2 --> haswell
+
+For more, see: https://gcc.gnu.org/gcc-4.9/changes.html
+
+It also changes 'atom' to 'bonnell' in accordance with the gcc v4.9 changes.
+Note that upstream is using the deprecated 'match=atom' flags when I believe it
+should use the newer 'march=bonnell' flag for atom processors.
+
+I have made that change to this patch set as well.  See the following kernel
+bug report to see if I'm right: https://bugzilla.kernel.org/show_bug.cgi?id=77461
+
+This patch will expand the number of microarchitectures to include newer
+processors including: AMD K10-family, AMD Family 10h (Barcelona), AMD Family
+14h (Bobcat), AMD Family 15h (Bulldozer), AMD Family 15h (Piledriver), AMD
+Family 15h (Steamroller), Family 16h (Jaguar), Intel 1st Gen Core i3/i5/i7
+(Nehalem), Intel 1.5 Gen Core i3/i5/i7 (Westmere), Intel 2nd Gen Core i3/i5/i7
+(Sandybridge), Intel 3rd Gen Core i3/i5/i7 (Ivybridge), Intel 4th Gen Core
+i3/i5/i7 (Haswell), Intel 5th Gen Core i3/i5/i7 (Broadwell), and the low power
+Silvermont series of Atom processors (Silvermont). It also offers the compiler
+the 'native' flag.
+
+Small but real speed increases are measurable using a make endpoint comparing
+a generic kernel to one built with one of the respective microarchs.
+
+See the following experimental evidence supporting this statement:
+https://github.com/graysky2/kernel_gcc_patch
+
+REQUIREMENTS
+linux version >=3.15
+gcc version >=4.9
+
+--- a/arch/x86/include/asm/module.h	2015-08-30 14:34:09.000000000 -0400
++++ b/arch/x86/include/asm/module.h	2015-11-06 14:18:24.234941036 -0500
+@@ -15,6 +15,24 @@
+ #define MODULE_PROC_FAMILY "586MMX "
+ #elif defined CONFIG_MCORE2
+ #define MODULE_PROC_FAMILY "CORE2 "
++#elif defined CONFIG_MNATIVE
++#define MODULE_PROC_FAMILY "NATIVE "
++#elif defined CONFIG_MNEHALEM
++#define MODULE_PROC_FAMILY "NEHALEM "
++#elif defined CONFIG_MWESTMERE
++#define MODULE_PROC_FAMILY "WESTMERE "
++#elif defined CONFIG_MSILVERMONT
++#define MODULE_PROC_FAMILY "SILVERMONT "
++#elif defined CONFIG_MSANDYBRIDGE
++#define MODULE_PROC_FAMILY "SANDYBRIDGE "
++#elif defined CONFIG_MIVYBRIDGE
++#define MODULE_PROC_FAMILY "IVYBRIDGE "
++#elif defined CONFIG_MHASWELL
++#define MODULE_PROC_FAMILY "HASWELL "
++#elif defined CONFIG_MBROADWELL
++#define MODULE_PROC_FAMILY "BROADWELL "
++#elif defined CONFIG_MSKYLAKE
++#define MODULE_PROC_FAMILY "SKYLAKE "
+ #elif defined CONFIG_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
+ #elif defined CONFIG_M686
+@@ -33,6 +51,22 @@
+ #define MODULE_PROC_FAMILY "K7 "
+ #elif defined CONFIG_MK8
+ #define MODULE_PROC_FAMILY "K8 "
++#elif defined CONFIG_MK8SSE3
++#define MODULE_PROC_FAMILY "K8SSE3 "
++#elif defined CONFIG_MK10
++#define MODULE_PROC_FAMILY "K10 "
++#elif defined CONFIG_MBARCELONA
++#define MODULE_PROC_FAMILY "BARCELONA "
++#elif defined CONFIG_MBOBCAT
++#define MODULE_PROC_FAMILY "BOBCAT "
++#elif defined CONFIG_MBULLDOZER
++#define MODULE_PROC_FAMILY "BULLDOZER "
++#elif defined CONFIG_MPILEDRIVER
++#define MODULE_PROC_FAMILY "STEAMROLLER "
++#elif defined CONFIG_MSTEAMROLLER
++#define MODULE_PROC_FAMILY "PILEDRIVER "
++#elif defined CONFIG_MJAGUAR
++#define MODULE_PROC_FAMILY "JAGUAR "
+ #elif defined CONFIG_MELAN
+ #define MODULE_PROC_FAMILY "ELAN "
+ #elif defined CONFIG_MCRUSOE
+--- a/arch/x86/Kconfig.cpu	2015-08-30 14:34:09.000000000 -0400
++++ b/arch/x86/Kconfig.cpu	2015-11-06 14:20:14.948369244 -0500
+@@ -137,9 +137,8 @@ config MPENTIUM4
+ 		-Paxville
+ 		-Dempsey
+ 
+-
+ config MK6
+-	bool "K6/K6-II/K6-III"
++	bool "AMD K6/K6-II/K6-III"
+ 	depends on X86_32
+ 	---help---
+ 	  Select this for an AMD K6-family processor.  Enables use of
+@@ -147,7 +146,7 @@ config MK6
+ 	  flags to GCC.
+ 
+ config MK7
+-	bool "Athlon/Duron/K7"
++	bool "AMD Athlon/Duron/K7"
+ 	depends on X86_32
+ 	---help---
+ 	  Select this for an AMD Athlon K7-family processor.  Enables use of
+@@ -155,12 +154,69 @@ config MK7
+ 	  flags to GCC.
+ 
+ config MK8
+-	bool "Opteron/Athlon64/Hammer/K8"
++	bool "AMD Opteron/Athlon64/Hammer/K8"
+ 	---help---
+ 	  Select this for an AMD Opteron or Athlon64 Hammer-family processor.
+ 	  Enables use of some extended instructions, and passes appropriate
+ 	  optimization flags to GCC.
+ 
++config MK8SSE3
++	bool "AMD Opteron/Athlon64/Hammer/K8 with SSE3"
++	---help---
++	  Select this for improved AMD Opteron or Athlon64 Hammer-family processors.
++	  Enables use of some extended instructions, and passes appropriate
++	  optimization flags to GCC.
++
++config MK10
++	bool "AMD 61xx/7x50/PhenomX3/X4/II/K10"
++	---help---
++	  Select this for an AMD 61xx Eight-Core Magny-Cours, Athlon X2 7x50,
++		Phenom X3/X4/II, Athlon II X2/X3/X4, or Turion II-family processor.
++	  Enables use of some extended instructions, and passes appropriate
++	  optimization flags to GCC.
++
++config MBARCELONA
++	bool "AMD Barcelona"
++	---help---
++	  Select this for AMD Barcelona and newer processors.
++
++	  Enables -march=barcelona
++
++config MBOBCAT
++	bool "AMD Bobcat"
++	---help---
++	  Select this for AMD Bobcat processors.
++
++	  Enables -march=btver1
++
++config MBULLDOZER
++	bool "AMD Bulldozer"
++	---help---
++	  Select this for AMD Bulldozer processors.
++
++	  Enables -march=bdver1
++
++config MPILEDRIVER
++	bool "AMD Piledriver"
++	---help---
++	  Select this for AMD Piledriver processors.
++
++	  Enables -march=bdver2
++
++config MSTEAMROLLER
++	bool "AMD Steamroller"
++	---help---
++	  Select this for AMD Steamroller processors.
++
++	  Enables -march=bdver3
++
++config MJAGUAR
++	bool "AMD Jaguar"
++	---help---
++	  Select this for AMD Jaguar processors.
++
++	  Enables -march=btver2
++
+ config MCRUSOE
+ 	bool "Crusoe"
+ 	depends on X86_32
+@@ -251,8 +307,17 @@ config MPSC
+ 	  using the cpu family field
+ 	  in /proc/cpuinfo. Family 15 is an older Xeon, Family 6 a newer one.
+ 
++config MATOM
++	bool "Intel Atom"
++	---help---
++
++	  Select this for the Intel Atom platform. Intel Atom CPUs have an
++	  in-order pipelining architecture and thus can benefit from
++	  accordingly optimized code. Use a recent GCC with specific Atom
++	  support in order to fully benefit from selecting this option.
++
+ config MCORE2
+-	bool "Core 2/newer Xeon"
++	bool "Intel Core 2"
+ 	---help---
+ 
+ 	  Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
+@@ -260,14 +325,71 @@ config MCORE2
+ 	  family in /proc/cpuinfo. Newer ones have 6 and older ones 15
+ 	  (not a typo)
+ 
+-config MATOM
+-	bool "Intel Atom"
++	  Enables -march=core2
++
++config MNEHALEM
++	bool "Intel Nehalem"
+ 	---help---
+ 
+-	  Select this for the Intel Atom platform. Intel Atom CPUs have an
+-	  in-order pipelining architecture and thus can benefit from
+-	  accordingly optimized code. Use a recent GCC with specific Atom
+-	  support in order to fully benefit from selecting this option.
++	  Select this for 1st Gen Core processors in the Nehalem family.
++
++	  Enables -march=nehalem
++
++config MWESTMERE
++	bool "Intel Westmere"
++	---help---
++
++	  Select this for the Intel Westmere formerly Nehalem-C family.
++
++	  Enables -march=westmere
++
++config MSILVERMONT
++	bool "Intel Silvermont"
++	---help---
++
++	  Select this for the Intel Silvermont platform.
++
++	  Enables -march=silvermont
++
++config MSANDYBRIDGE
++	bool "Intel Sandy Bridge"
++	---help---
++
++	  Select this for 2nd Gen Core processors in the Sandy Bridge family.
++
++	  Enables -march=sandybridge
++
++config MIVYBRIDGE
++	bool "Intel Ivy Bridge"
++	---help---
++
++	  Select this for 3rd Gen Core processors in the Ivy Bridge family.
++
++	  Enables -march=ivybridge
++
++config MHASWELL
++	bool "Intel Haswell"
++	---help---
++
++	  Select this for 4th Gen Core processors in the Haswell family.
++
++	  Enables -march=haswell
++
++config MBROADWELL
++	bool "Intel Broadwell"
++	---help---
++
++	  Select this for 5th Gen Core processors in the Broadwell family.
++
++	  Enables -march=broadwell
++
++config MSKYLAKE
++	bool "Intel Skylake"
++	---help---
++
++	  Select this for 6th Gen Core processors in the Skylake family.
++
++	  Enables -march=skylake
+ 
+ config GENERIC_CPU
+ 	bool "Generic-x86-64"
+@@ -276,6 +398,19 @@ config GENERIC_CPU
+ 	  Generic x86-64 CPU.
+ 	  Run equally well on all x86-64 CPUs.
+ 
++config MNATIVE
++ bool "Native optimizations autodetected by GCC"
++ ---help---
++
++   GCC 4.2 and above support -march=native, which automatically detects
++   the optimum settings to use based on your processor. -march=native 
++   also detects and applies additional settings beyond -march specific
++   to your CPU, (eg. -msse4). Unless you have a specific reason not to
++   (e.g. distcc cross-compiling), you should probably be using
++   -march=native rather than anything listed below.
++
++   Enables -march=native
++
+ endchoice
+ 
+ config X86_GENERIC
+@@ -300,7 +435,7 @@ config X86_INTERNODE_CACHE_SHIFT
+ config X86_L1_CACHE_SHIFT
+ 	int
+ 	default "7" if MPENTIUM4 || MPSC
+-	default "6" if MK7 || MK8 || MPENTIUMM || MCORE2 || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
++	default "6" if MK7 || MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE || MATOM || MVIAC7 || X86_GENERIC || GENERIC_CPU
+ 	default "4" if MELAN || M486 || MGEODEGX1
+ 	default "5" if MWINCHIP3D || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE_LX
+ 
+@@ -331,11 +466,11 @@ config X86_ALIGNMENT_16
+ 
+ config X86_INTEL_USERCOPY
+ 	def_bool y
+-	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK7 || MEFFICEON || MCORE2
++	depends on MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M586MMX || X86_GENERIC || MK8 || MK8SSE3 || MK7 || MEFFICEON || MCORE2 || MK10 || MBARCELONA || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE
+ 
+ config X86_USE_PPRO_CHECKSUM
+ 	def_bool y
+-	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MATOM
++	depends on MWINCHIP3D || MWINCHIPC6 || MCYRIXIII || MK7 || MK6 || MK10 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MATOM || MNATIVE
+ 
+ config X86_USE_3DNOW
+ 	def_bool y
+@@ -359,17 +494,17 @@ config X86_P6_NOP
+ 
+ config X86_TSC
+ 	def_bool y
+-	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) || X86_64
++	depends on (MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MK8SSE3 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MNATIVE || MATOM) || X86_64
+ 
+ config X86_CMPXCHG64
+ 	def_bool y
+-	depends on X86_PAE || X86_64 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM
++	depends on X86_PAE || X86_64 || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM || MNATIVE
+ 
+ # this should be set for all -march=.. options where the compiler
+ # generates cmov.
+ config X86_CMOV
+ 	def_bool y
+-	depends on (MK8 || MK7 || MCORE2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MATOM || MGEODE_LX)
++	depends on (MK8 || MK8SSE3 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MSTEAMROLLER || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MSKYLAKE || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || MATOM || MGEODE_LX)
+ 
+ config X86_MINIMUM_CPU_FAMILY
+ 	int
+--- a/arch/x86/Makefile	2015-08-30 14:34:09.000000000 -0400
++++ b/arch/x86/Makefile	2015-11-06 14:21:05.708983344 -0500
+@@ -94,13 +94,38 @@ else
+ 	KBUILD_CFLAGS += $(call cc-option,-mskip-rax-setup)
+ 
+         # FIXME - should be integrated in Makefile.cpu (Makefile_32.cpu)
++        cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native)
+         cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
++        cflags-$(CONFIG_MK8SSE3) += $(call cc-option,-march=k8-sse3,-mtune=k8)
++        cflags-$(CONFIG_MK10) += $(call cc-option,-march=amdfam10)
++        cflags-$(CONFIG_MBARCELONA) += $(call cc-option,-march=barcelona)
++        cflags-$(CONFIG_MBOBCAT) += $(call cc-option,-march=btver1)
++        cflags-$(CONFIG_MBULLDOZER) += $(call cc-option,-march=bdver1)
++        cflags-$(CONFIG_MPILEDRIVER) += $(call cc-option,-march=bdver2)
++        cflags-$(CONFIG_MSTEAMROLLER) += $(call cc-option,-march=bdver3)
++        cflags-$(CONFIG_MJAGUAR) += $(call cc-option,-march=btver2)
+         cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
+ 
+         cflags-$(CONFIG_MCORE2) += \
+-                $(call cc-option,-march=core2,$(call cc-option,-mtune=generic))
+-	cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
+-		$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
++                $(call cc-option,-march=core2,$(call cc-option,-mtune=core2))
++        cflags-$(CONFIG_MNEHALEM) += \
++                $(call cc-option,-march=nehalem,$(call cc-option,-mtune=nehalem))
++        cflags-$(CONFIG_MWESTMERE) += \
++                $(call cc-option,-march=westmere,$(call cc-option,-mtune=westmere))
++        cflags-$(CONFIG_MSILVERMONT) += \
++                $(call cc-option,-march=silvermont,$(call cc-option,-mtune=silvermont))
++        cflags-$(CONFIG_MSANDYBRIDGE) += \
++                $(call cc-option,-march=sandybridge,$(call cc-option,-mtune=sandybridge))
++        cflags-$(CONFIG_MIVYBRIDGE) += \
++                $(call cc-option,-march=ivybridge,$(call cc-option,-mtune=ivybridge))
++        cflags-$(CONFIG_MHASWELL) += \
++                $(call cc-option,-march=haswell,$(call cc-option,-mtune=haswell))
++        cflags-$(CONFIG_MBROADWELL) += \
++                $(call cc-option,-march=broadwell,$(call cc-option,-mtune=broadwell))
++        cflags-$(CONFIG_MSKYLAKE) += \
++                $(call cc-option,-march=skylake,$(call cc-option,-mtune=skylake))
++        cflags-$(CONFIG_MATOM) += $(call cc-option,-march=bonnell) \
++                $(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic))
+         cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
+         KBUILD_CFLAGS += $(cflags-y)
+ 
+--- a/arch/x86/Makefile_32.cpu	2015-08-30 14:34:09.000000000 -0400
++++ b/arch/x86/Makefile_32.cpu	2015-11-06 14:21:43.604429077 -0500
+@@ -23,7 +23,16 @@ cflags-$(CONFIG_MK6)		+= -march=k6
+ # Please note, that patches that add -march=athlon-xp and friends are pointless.
+ # They make zero difference whatsosever to performance at this time.
+ cflags-$(CONFIG_MK7)		+= -march=athlon
++cflags-$(CONFIG_MNATIVE) += $(call cc-option,-march=native)
+ cflags-$(CONFIG_MK8)		+= $(call cc-option,-march=k8,-march=athlon)
++cflags-$(CONFIG_MK8SSE3)		+= $(call cc-option,-march=k8-sse3,-march=athlon)
++cflags-$(CONFIG_MK10)	+= $(call cc-option,-march=amdfam10,-march=athlon)
++cflags-$(CONFIG_MBARCELONA)	+= $(call cc-option,-march=barcelona,-march=athlon)
++cflags-$(CONFIG_MBOBCAT)	+= $(call cc-option,-march=btver1,-march=athlon)
++cflags-$(CONFIG_MBULLDOZER)	+= $(call cc-option,-march=bdver1,-march=athlon)
++cflags-$(CONFIG_MPILEDRIVER)	+= $(call cc-option,-march=bdver2,-march=athlon)
++cflags-$(CONFIG_MSTEAMROLLER)	+= $(call cc-option,-march=bdver3,-march=athlon)
++cflags-$(CONFIG_MJAGUAR)	+= $(call cc-option,-march=btver2,-march=athlon)
+ cflags-$(CONFIG_MCRUSOE)	+= -march=i686 $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+ cflags-$(CONFIG_MEFFICEON)	+= -march=i686 $(call tune,pentium3) $(align)-functions=0 $(align)-jumps=0 $(align)-loops=0
+ cflags-$(CONFIG_MWINCHIPC6)	+= $(call cc-option,-march=winchip-c6,-march=i586)
+@@ -32,8 +41,16 @@ cflags-$(CONFIG_MCYRIXIII)	+= $(call cc-
+ cflags-$(CONFIG_MVIAC3_2)	+= $(call cc-option,-march=c3-2,-march=i686)
+ cflags-$(CONFIG_MVIAC7)		+= -march=i686
+ cflags-$(CONFIG_MCORE2)		+= -march=i686 $(call tune,core2)
+-cflags-$(CONFIG_MATOM)		+= $(call cc-option,-march=atom,$(call cc-option,-march=core2,-march=i686)) \
+-	$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
++cflags-$(CONFIG_MNEHALEM)	+= -march=i686 $(call tune,nehalem)
++cflags-$(CONFIG_MWESTMERE)	+= -march=i686 $(call tune,westmere)
++cflags-$(CONFIG_MSILVERMONT)	+= -march=i686 $(call tune,silvermont)
++cflags-$(CONFIG_MSANDYBRIDGE)	+= -march=i686 $(call tune,sandybridge)
++cflags-$(CONFIG_MIVYBRIDGE)	+= -march=i686 $(call tune,ivybridge)
++cflags-$(CONFIG_MHASWELL)	+= -march=i686 $(call tune,haswell)
++cflags-$(CONFIG_MBROADWELL)	+= -march=i686 $(call tune,broadwell)
++cflags-$(CONFIG_MSKYLAKE)	+= -march=i686 $(call tune,skylake)
++cflags-$(CONFIG_MATOM)		+= $(call cc-option,-march=bonnell,$(call cc-option,-march=core2,-march=i686)) \
++	$(call cc-option,-mtune=bonnell,$(call cc-option,-mtune=generic))
+ 
+ # AMD Elan support
+ cflags-$(CONFIG_MELAN)		+= -march=i486


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-09-26 10:35 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-09-26 10:35 UTC (permalink / raw
  To: gentoo-commits

commit:     b60690c2015d9946308c9442b50d8343983f1bfd
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 26 10:35:24 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Sep 26 10:35:24 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b60690c2

Update gentoo kconfig patch to remove DEVPTS_MULTIPLE_INSTANCES. See kernel upstream commit: eedf265aa003b4781de24cfed40a655a664457e6.

 4567_distro-Gentoo-Kconfig.patch | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)

diff --git a/4567_distro-Gentoo-Kconfig.patch b/4567_distro-Gentoo-Kconfig.patch
index 499b21f..cf5a20c 100644
--- a/4567_distro-Gentoo-Kconfig.patch
+++ b/4567_distro-Gentoo-Kconfig.patch
@@ -1,15 +1,14 @@
---- a/Kconfig	2016-07-01 19:22:17.117439707 -0400
-+++ b/Kconfig	2016-07-01 19:21:54.371440596 -0400
-@@ -8,4 +8,6 @@ config SRCARCH
- 	string
+--- a/Kconfig	2016-08-30 14:30:48.508361013 -0400
++++ b/Kconfig	2016-08-30 14:31:40.718683061 -0400
+@@ -9,3 +9,5 @@ config SRCARCH
  	option env="SRCARCH"
  
-+source "distro/Kconfig"
-+
  source "arch/$SRCARCH/Kconfig"
---- /dev/null	2016-07-01 11:23:26.087932647 -0400
-+++ b/distro/Kconfig	2016-07-01 19:32:35.581415519 -0400
-@@ -0,0 +1,134 @@
++
++source "distro/Kconfig"
+--- /dev/null	2016-08-30 01:47:09.760073185 -0400
++++ b/distro/Kconfig	2016-08-30 14:32:21.378933599 -0400
+@@ -0,0 +1,133 @@
 +menu "Gentoo Linux"
 +
 +config GENTOO_LINUX
@@ -112,7 +111,6 @@
 +	select AUTOFS4_FS
 +	select BLK_DEV_BSG
 +	select CGROUPS
-+	select DEVPTS_MULTIPLE_INSTANCES
 +	select EPOLL
 +	select FANOTIFY
 +	select FHANDLE


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-09-26 10:37 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-09-26 10:37 UTC (permalink / raw
  To: gentoo-commits

commit:     37185eb0b6d421615685085052f14f7cd937cb2d
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Sep 26 10:36:56 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Sep 26 10:36:56 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=37185eb0

Rename gcc optimization patch for more clarity.

 0000_README                                                             | 2 +-
 ...-4.9.patch => 5010_enable-additional-cpu-optimizations-for-gcc.patch | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/0000_README b/0000_README
index 777f7c8..db75eae 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,6 @@ Patch:  5000_enable-additional-cpu-optimizations-for-gcc.patch
 From:   https://github.com/graysky2/kernel_gcc_patch/
 Desc:   Kernel patch enables gcc < v4.9 optimizations for additional CPUs.
 
-Patch:  5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
+Patch:  5010_enable-additional-cpu-optimizations-for-gcc.patch
 From:   https://github.com/graysky2/kernel_gcc_patch/
 Desc:   Kernel patch enables gcc >= v4.9 optimizations for additional CPUs.

diff --git a/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch b/5010_enable-additional-cpu-optimizations-for-gcc.patch
similarity index 100%
rename from 5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
rename to 5010_enable-additional-cpu-optimizations-for-gcc.patch


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-08 19:50 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-08 19:50 UTC (permalink / raw
  To: gentoo-commits

commit:     2a460f07ad824ea67abac1d6d7626046a89d8322
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct  8 19:50:27 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct  8 19:50:27 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=2a460f07

Linux patch 4.8.1

 0000_README            |   4 +
 1000_linux-4.8.1.patch | 252 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 256 insertions(+)

diff --git a/0000_README b/0000_README
index db75eae..55d306f 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,10 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1000_linux-4.8.1.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.1
+
 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/1000_linux-4.8.1.patch b/1000_linux-4.8.1.patch
new file mode 100644
index 0000000..870f17f
--- /dev/null
+++ b/1000_linux-4.8.1.patch
@@ -0,0 +1,252 @@
+diff --git a/Makefile b/Makefile
+index 80b8671d5c46..75db9f3988f3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 0
++SUBLEVEL = 1
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
+index 91fff48d0f57..2751ff9c0934 100644
+--- a/arch/arm64/kernel/debug-monitors.c
++++ b/arch/arm64/kernel/debug-monitors.c
+@@ -435,8 +435,10 @@ NOKPROBE_SYMBOL(kernel_active_single_step);
+ /* ptrace API */
+ void user_enable_single_step(struct task_struct *task)
+ {
+-	set_ti_thread_flag(task_thread_info(task), TIF_SINGLESTEP);
+-	set_regs_spsr_ss(task_pt_regs(task));
++	struct thread_info *ti = task_thread_info(task);
++
++	if (!test_and_set_ti_thread_flag(ti, TIF_SINGLESTEP))
++		set_regs_spsr_ss(task_pt_regs(task));
+ }
+ NOKPROBE_SYMBOL(user_enable_single_step);
+ 
+diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
+index 0c1a77cafe14..4c281df16816 100644
+--- a/drivers/staging/fbtft/fbtft-core.c
++++ b/drivers/staging/fbtft/fbtft-core.c
+@@ -391,11 +391,11 @@ static void fbtft_update_display(struct fbtft_par *par, unsigned start_line,
+ 
+ 	if (unlikely(timeit)) {
+ 		ts_end = ktime_get();
+-		if (ktime_to_ns(par->update_time))
++		if (!ktime_to_ns(par->update_time))
+ 			par->update_time = ts_start;
+ 
+-		par->update_time = ts_start;
+ 		fps = ktime_us_delta(ts_start, par->update_time);
++		par->update_time = ts_start;
+ 		fps = fps ? 1000000 / fps : 0;
+ 
+ 		throughput = ktime_us_delta(ts_end, ts_start);
+diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
+index 917a55c4480d..ffe9f8875311 100644
+--- a/drivers/usb/class/usbtmc.c
++++ b/drivers/usb/class/usbtmc.c
+@@ -141,6 +141,7 @@ static void usbtmc_delete(struct kref *kref)
+ 	struct usbtmc_device_data *data = to_usbtmc_data(kref);
+ 
+ 	usb_put_dev(data->usb_dev);
++	kfree(data);
+ }
+ 
+ static int usbtmc_open(struct inode *inode, struct file *filp)
+@@ -1379,7 +1380,7 @@ static int usbtmc_probe(struct usb_interface *intf,
+ 
+ 	dev_dbg(&intf->dev, "%s called\n", __func__);
+ 
+-	data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL);
++	data = kmalloc(sizeof(*data), GFP_KERNEL);
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c
+index 7771be3ac178..4dd531ac5a7f 100644
+--- a/drivers/usb/misc/legousbtower.c
++++ b/drivers/usb/misc/legousbtower.c
+@@ -898,24 +898,6 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
+ 	dev->interrupt_in_interval = interrupt_in_interval ? interrupt_in_interval : dev->interrupt_in_endpoint->bInterval;
+ 	dev->interrupt_out_interval = interrupt_out_interval ? interrupt_out_interval : dev->interrupt_out_endpoint->bInterval;
+ 
+-	/* we can register the device now, as it is ready */
+-	usb_set_intfdata (interface, dev);
+-
+-	retval = usb_register_dev (interface, &tower_class);
+-
+-	if (retval) {
+-		/* something prevented us from registering this driver */
+-		dev_err(idev, "Not able to get a minor for this device.\n");
+-		usb_set_intfdata (interface, NULL);
+-		goto error;
+-	}
+-	dev->minor = interface->minor;
+-
+-	/* let the user know what node this device is now attached to */
+-	dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major "
+-		 "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE),
+-		 USB_MAJOR, dev->minor);
+-
+ 	/* get the firmware version and log it */
+ 	result = usb_control_msg (udev,
+ 				  usb_rcvctrlpipe(udev, 0),
+@@ -936,6 +918,23 @@ static int tower_probe (struct usb_interface *interface, const struct usb_device
+ 		 get_version_reply.minor,
+ 		 le16_to_cpu(get_version_reply.build_no));
+ 
++	/* we can register the device now, as it is ready */
++	usb_set_intfdata (interface, dev);
++
++	retval = usb_register_dev (interface, &tower_class);
++
++	if (retval) {
++		/* something prevented us from registering this driver */
++		dev_err(idev, "Not able to get a minor for this device.\n");
++		usb_set_intfdata (interface, NULL);
++		goto error;
++	}
++	dev->minor = interface->minor;
++
++	/* let the user know what node this device is now attached to */
++	dev_info(&interface->dev, "LEGO USB Tower #%d now attached to major "
++		 "%d minor %d\n", (dev->minor - LEGO_USB_TOWER_MINOR_BASE),
++		 USB_MAJOR, dev->minor);
+ 
+ exit:
+ 	return retval;
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 4d6a5c672a3d..54a4de0efdba 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -118,6 +118,7 @@ static const struct usb_device_id id_table[] = {
+ 	{ USB_DEVICE(0x10C4, 0x8411) }, /* Kyocera GPS Module */
+ 	{ USB_DEVICE(0x10C4, 0x8418) }, /* IRZ Automation Teleport SG-10 GSM/GPRS Modem */
+ 	{ USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */
++	{ USB_DEVICE(0x10C4, 0x8470) }, /* Juniper Networks BX Series System Console */
+ 	{ USB_DEVICE(0x10C4, 0x8477) }, /* Balluff RFID */
+ 	{ USB_DEVICE(0x10C4, 0x84B6) }, /* Starizona Hyperion */
+ 	{ USB_DEVICE(0x10C4, 0x85EA) }, /* AC-Services IBUS-IF */
+diff --git a/drivers/usb/usbip/vudc_rx.c b/drivers/usb/usbip/vudc_rx.c
+index 344bd9473475..e429b59f6f8a 100644
+--- a/drivers/usb/usbip/vudc_rx.c
++++ b/drivers/usb/usbip/vudc_rx.c
+@@ -142,7 +142,7 @@ static int v_recv_cmd_submit(struct vudc *udc,
+ 	urb_p->urb->status = -EINPROGRESS;
+ 
+ 	/* FIXME: more pipe setup to please usbip_common */
+-	urb_p->urb->pipe &= ~(11 << 30);
++	urb_p->urb->pipe &= ~(3 << 30);
+ 	switch (urb_p->ep->type) {
+ 	case USB_ENDPOINT_XFER_BULK:
+ 		urb_p->urb->pipe |= (PIPE_BULK << 30);
+diff --git a/include/linux/swap.h b/include/linux/swap.h
+index 4a529c984a3f..e1d761463243 100644
+--- a/include/linux/swap.h
++++ b/include/linux/swap.h
+@@ -257,7 +257,7 @@ static inline void workingset_node_pages_inc(struct radix_tree_node *node)
+ 
+ static inline void workingset_node_pages_dec(struct radix_tree_node *node)
+ {
+-	VM_BUG_ON(!workingset_node_pages(node));
++	VM_WARN_ON_ONCE(!workingset_node_pages(node));
+ 	node->count--;
+ }
+ 
+@@ -273,7 +273,7 @@ static inline void workingset_node_shadows_inc(struct radix_tree_node *node)
+ 
+ static inline void workingset_node_shadows_dec(struct radix_tree_node *node)
+ {
+-	VM_BUG_ON(!workingset_node_shadows(node));
++	VM_WARN_ON_ONCE(!workingset_node_shadows(node));
+ 	node->count -= 1U << RADIX_TREE_COUNT_SHIFT;
+ }
+ 
+diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
+index 56fefbd85782..ed62748a6d55 100644
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -261,6 +261,7 @@ enum {
+ 	CXT_FIXUP_HP_530,
+ 	CXT_FIXUP_CAP_MIX_AMP_5047,
+ 	CXT_FIXUP_MUTE_LED_EAPD,
++	CXT_FIXUP_HP_SPECTRE,
+ };
+ 
+ /* for hda_fixup_thinkpad_acpi() */
+@@ -765,6 +766,14 @@ static const struct hda_fixup cxt_fixups[] = {
+ 		.type = HDA_FIXUP_FUNC,
+ 		.v.func = cxt_fixup_mute_led_eapd,
+ 	},
++	[CXT_FIXUP_HP_SPECTRE] = {
++		.type = HDA_FIXUP_PINS,
++		.v.pins = (const struct hda_pintbl[]) {
++			/* enable NID 0x1d for the speaker on top */
++			{ 0x1d, 0x91170111 },
++			{ }
++		}
++	},
+ };
+ 
+ static const struct snd_pci_quirk cxt5045_fixups[] = {
+@@ -814,6 +823,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
+ 	SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
+ 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
+ 	SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
++	SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
+ 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
+ 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
+ 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 575cefd8cc4a..bd481ac23faf 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5806,6 +5806,13 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ 	{0x14, 0x90170110}, \
+ 	{0x15, 0x0221401f}
+ 
++#define ALC295_STANDARD_PINS \
++	{0x12, 0xb7a60130}, \
++	{0x14, 0x90170110}, \
++	{0x17, 0x21014020}, \
++	{0x18, 0x21a19030}, \
++	{0x21, 0x04211020}
++
+ #define ALC298_STANDARD_PINS \
+ 	{0x12, 0x90a60130}, \
+ 	{0x21, 0x03211020}
+@@ -5846,6 +5853,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x14, 0x90170120},
+ 		{0x21, 0x02211030}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x14, 0x90170110},
++		{0x1b, 0x02011020},
++		{0x21, 0x0221101f}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x14, 0x90170130},
+ 		{0x1b, 0x01014020},
+ 		{0x21, 0x0221103f}),
+@@ -5911,6 +5922,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x14, 0x90170120},
+ 		{0x21, 0x02211030}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x12, 0xb7a60130},
++		{0x14, 0x90170110},
++		{0x21, 0x02211020}),
++	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC256_STANDARD_PINS),
+ 	SND_HDA_PIN_QUIRK(0x10ec0280, 0x103c, "HP", ALC280_FIXUP_HP_GPIO4,
+ 		{0x12, 0x90a60130},
+@@ -6021,6 +6036,8 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 	SND_HDA_PIN_QUIRK(0x10ec0293, 0x1028, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC292_STANDARD_PINS,
+ 		{0x13, 0x90a60140}),
++	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
++		ALC295_STANDARD_PINS),
+ 	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC298_STANDARD_PINS,
+ 		{0x17, 0x90170110}),


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-11  0:07 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-11  0:07 UTC (permalink / raw
  To: gentoo-commits

commit:     87cd8ce6b13f62532e383db6302117fd51ed9f62
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 11 00:07:31 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Oct 11 00:07:31 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=87cd8ce6

Bootsplash ported by Uladzimir Bely. (Bug #596126)

 0000_README           |    4 +
 4200_fbcondecor.patch | 2095 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2099 insertions(+)

diff --git a/0000_README b/0000_README
index 55d306f..4af14fd 100644
--- a/0000_README
+++ b/0000_README
@@ -59,6 +59,10 @@ Patch:  2900_dev-root-proc-mount-fix.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=438380
 Desc:   Ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs.
 
+Patch:  4200_fbcondecor.patch
+From:   http://www.mepiscommunity.org/fbcondecor
+Desc:   Bootsplash ported by Uladzimir Bely. (Bug #596126)
+
 Patch:  4400_alpha-sysctl-uac.patch
 From:   Tobias Klausmann (klausman@gentoo.org) and http://bugs.gentoo.org/show_bug.cgi?id=217323 
 Desc:   Enable control of the unaligned access control policy from sysctl

diff --git a/4200_fbcondecor.patch b/4200_fbcondecor.patch
new file mode 100644
index 0000000..f7d9879
--- /dev/null
+++ b/4200_fbcondecor.patch
@@ -0,0 +1,2095 @@
+diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
+index fe85e7c..2230930 100644
+--- a/Documentation/fb/00-INDEX
++++ b/Documentation/fb/00-INDEX
+@@ -23,6 +23,8 @@ ep93xx-fb.txt
+ 	- info on the driver for EP93xx LCD controller.
+ fbcon.txt
+ 	- intro to and usage guide for the framebuffer console (fbcon).
++fbcondecor.txt
++	- info on the Framebuffer Console Decoration
+ framebuffer.txt
+ 	- introduction to frame buffer devices.
+ gxfb.txt
+diff --git a/Documentation/fb/fbcondecor.txt b/Documentation/fb/fbcondecor.txt
+new file mode 100644
+index 0000000..637209e
+--- /dev/null
++++ b/Documentation/fb/fbcondecor.txt
+@@ -0,0 +1,207 @@
++What is it?
++-----------
++
++The framebuffer decorations are a kernel feature which allows displaying a
++background picture on selected consoles.
++
++What do I need to get it to work?
++---------------------------------
++
++To get fbcondecor up-and-running you will have to:
++ 1) get a copy of splashutils [1] or a similar program
++ 2) get some fbcondecor themes
++ 3) build the kernel helper program
++ 4) build your kernel with the FB_CON_DECOR option enabled.
++
++To get fbcondecor operational right after fbcon initialization is finished, you
++will have to include a theme and the kernel helper into your initramfs image.
++Please refer to splashutils documentation for instructions on how to do that.
++
++[1] The splashutils package can be downloaded from:
++    http://github.com/alanhaggai/fbsplash
++
++The userspace helper
++--------------------
++
++The userspace fbcondecor helper (by default: /sbin/fbcondecor_helper) is called by the
++kernel whenever an important event occurs and the kernel needs some kind of
++job to be carried out. Important events include console switches and video
++mode switches (the kernel requests background images and configuration
++parameters for the current console). The fbcondecor helper must be accessible at
++all times. If it's not, fbcondecor will be switched off automatically.
++
++It's possible to set path to the fbcondecor helper by writing it to
++/proc/sys/kernel/fbcondecor.
++
++*****************************************************************************
++
++The information below is mostly technical stuff. There's probably no need to
++read it unless you plan to develop a userspace helper.
++
++The fbcondecor protocol
++-----------------------
++
++The fbcondecor protocol defines a communication interface between the kernel and
++the userspace fbcondecor helper.
++
++The kernel side is responsible for:
++
++ * rendering console text, using an image as a background (instead of a
++   standard solid color fbcon uses),
++ * accepting commands from the user via ioctls on the fbcondecor device,
++ * calling the userspace helper to set things up as soon as the fb subsystem
++   is initialized.
++
++The userspace helper is responsible for everything else, including parsing
++configuration files, decompressing the image files whenever the kernel needs
++it, and communicating with the kernel if necessary.
++
++The fbcondecor protocol specifies how communication is done in both ways:
++kernel->userspace and userspace->helper.
++
++Kernel -> Userspace
++-------------------
++
++The kernel communicates with the userspace helper by calling it and specifying
++the task to be done in a series of arguments.
++
++The arguments follow the pattern:
++<fbcondecor protocol version> <command> <parameters>
++
++All commands defined in fbcondecor protocol v2 have the following parameters:
++ virtual console
++ framebuffer number
++ theme
++
++Fbcondecor protocol v1 specified an additional 'fbcondecor mode' after the
++framebuffer number. Fbcondecor protocol v1 is deprecated and should not be used.
++
++Fbcondecor protocol v2 specifies the following commands:
++
++getpic
++------
++ The kernel issues this command to request image data. It's up to the
++ userspace  helper to find a background image appropriate for the specified
++ theme and the current resolution. The userspace helper should respond by
++ issuing the FBIOCONDECOR_SETPIC ioctl.
++
++init
++----
++ The kernel issues this command after the fbcondecor device is created and
++ the fbcondecor interface is initialized. Upon receiving 'init', the userspace
++ helper should parse the kernel command line (/proc/cmdline) or otherwise
++ decide whether fbcondecor is to be activated.
++
++ To activate fbcondecor on the first console the helper should issue the
++ FBIOCONDECOR_SETCFG, FBIOCONDECOR_SETPIC and FBIOCONDECOR_SETSTATE commands,
++ in the above-mentioned order.
++
++ When the userspace helper is called in an early phase of the boot process
++ (right after the initialization of fbcon), no filesystems will be mounted.
++ The helper program should mount sysfs and then create the appropriate
++ framebuffer, fbcondecor and tty0 devices (if they don't already exist) to get
++ current display settings and to be able to communicate with the kernel side.
++ It should probably also mount the procfs to be able to parse the kernel
++ command line parameters.
++
++ Note that the console sem is not held when the kernel calls fbcondecor_helper
++ with the 'init' command. The fbcondecor helper should perform all ioctls with
++ origin set to FBCON_DECOR_IO_ORIG_USER.
++
++modechange
++----------
++ The kernel issues this command on a mode change. The helper's response should
++ be similar to the response to the 'init' command. Note that this time the
++ console sem is held and all ioctls must be performed with origin set to
++ FBCON_DECOR_IO_ORIG_KERNEL.
++
++
++Userspace -> Kernel
++-------------------
++
++Userspace programs can communicate with fbcondecor via ioctls on the
++fbcondecor device. These ioctls are to be used by both the userspace helper
++(called only by the kernel) and userspace configuration tools (run by the users).
++
++The fbcondecor helper should set the origin field to FBCON_DECOR_IO_ORIG_KERNEL
++when doing the appropriate ioctls. All userspace configuration tools should
++use FBCON_DECOR_IO_ORIG_USER. Failure to set the appropriate value in the origin
++field when performing ioctls from the kernel helper will most likely result
++in a console deadlock.
++
++FBCON_DECOR_IO_ORIG_KERNEL instructs fbcondecor not to try to acquire the console
++semaphore. Not surprisingly, FBCON_DECOR_IO_ORIG_USER instructs it to acquire
++the console sem.
++
++The framebuffer console decoration provides the following ioctls (all defined in
++linux/fb.h):
++
++FBIOCONDECOR_SETPIC
++description: loads a background picture for a virtual console
++argument: struct fbcon_decor_iowrapper*; data: struct fb_image*
++notes:
++If called for consoles other than the current foreground one, the picture data
++will be ignored.
++
++If the current virtual console is running in a 8-bpp mode, the cmap substruct
++of fb_image has to be filled appropriately: start should be set to 16 (first
++16 colors are reserved for fbcon), len to a value <= 240 and red, green and
++blue should point to valid cmap data. The transp field is ingored. The fields
++dx, dy, bg_color, fg_color in fb_image are ignored as well.
++
++FBIOCONDECOR_SETCFG
++description: sets the fbcondecor config for a virtual console
++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
++notes: The structure has to be filled with valid data.
++
++FBIOCONDECOR_GETCFG
++description: gets the fbcondecor config for a virtual console
++argument: struct fbcon_decor_iowrapper*; data: struct vc_decor*
++
++FBIOCONDECOR_SETSTATE
++description: sets the fbcondecor state for a virtual console
++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
++          values: 0 = disabled, 1 = enabled.
++
++FBIOCONDECOR_GETSTATE
++description: gets the fbcondecor state for a virtual console
++argument: struct fbcon_decor_iowrapper*; data: unsigned int*
++          values: as in FBIOCONDECOR_SETSTATE
++
++Info on used structures:
++
++Definition of struct vc_decor can be found in linux/console_decor.h. It's
++heavily commented. Note that the 'theme' field should point to a string
++no longer than FBCON_DECOR_THEME_LEN. When FBIOCONDECOR_GETCFG call is
++performed, the theme field should point to a char buffer of length
++FBCON_DECOR_THEME_LEN.
++
++Definition of struct fbcon_decor_iowrapper can be found in linux/fb.h.
++The fields in this struct have the following meaning:
++
++vc:
++Virtual console number.
++
++origin:
++Specifies if the ioctl is performed as a response to a kernel request. The
++fbcondecor helper should set this field to FBCON_DECOR_IO_ORIG_KERNEL, userspace
++programs should set it to FBCON_DECOR_IO_ORIG_USER. This field is necessary to
++avoid console semaphore deadlocks.
++
++data:
++Pointer to a data structure appropriate for the performed ioctl. Type of
++the data struct is specified in the ioctls description.
++
++*****************************************************************************
++
++Credit
++------
++
++Original 'bootsplash' project & implementation by:
++  Volker Poplawski <volker@poplawski.de>, Stefan Reinauer <stepan@suse.de>,
++  Steffen Winterfeldt <snwint@suse.de>, Michael Schroeder <mls@suse.de>,
++  Ken Wimer <wimer@suse.de>.
++
++Fbcondecor, fbcondecor protocol design, current implementation & docs by:
++  Michal Januszewski <michalj+fbcondecor@gmail.com>
++
+diff --git a/drivers/Makefile b/drivers/Makefile
+index 53abb4a..1721aee 100644
+--- a/drivers/Makefile
++++ b/drivers/Makefile
+@@ -17,6 +17,10 @@ obj-y				+= pwm/
+ obj-$(CONFIG_PCI)		+= pci/
+ obj-$(CONFIG_PARISC)		+= parisc/
+ obj-$(CONFIG_RAPIDIO)		+= rapidio/
++# tty/ comes before char/ so that the VT console is the boot-time
++# default.
++obj-y				+= tty/
++obj-y				+= char/
+ obj-y				+= video/
+ obj-y				+= idle/
+ 
+@@ -45,11 +49,6 @@ obj-$(CONFIG_REGULATOR)		+= regulator/
+ # reset controllers early, since gpu drivers might rely on them to initialize
+ obj-$(CONFIG_RESET_CONTROLLER)	+= reset/
+ 
+-# tty/ comes before char/ so that the VT console is the boot-time
+-# default.
+-obj-y				+= tty/
+-obj-y				+= char/
+-
+ # iommu/ comes before gpu as gpu are using iommu controllers
+ obj-$(CONFIG_IOMMU_SUPPORT)	+= iommu/
+ 
+diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig
+index 38da6e2..fe58152 100644
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -130,6 +130,19 @@ config FRAMEBUFFER_CONSOLE_ROTATION
+          such that other users of the framebuffer will remain normally
+          oriented.
+ 
++config FB_CON_DECOR
++	bool "Support for the Framebuffer Console Decorations"
++	depends on FRAMEBUFFER_CONSOLE=y && !FB_TILEBLITTING
++	default n
++	---help---
++	  This option enables support for framebuffer console decorations which
++	  makes it possible to display images in the background of the system
++	  consoles.  Note that userspace utilities are necessary in order to take
++	  advantage of these features. Refer to Documentation/fb/fbcondecor.txt
++	  for more information.
++
++	  If unsure, say N.
++
+ config STI_CONSOLE
+         bool "STI text console"
+         depends on PARISC
+diff --git a/drivers/video/console/Makefile b/drivers/video/console/Makefile
+index 43bfa48..cc104b6 100644
+--- a/drivers/video/console/Makefile
++++ b/drivers/video/console/Makefile
+@@ -16,4 +16,5 @@ obj-$(CONFIG_FRAMEBUFFER_CONSOLE)     += fbcon_rotate.o fbcon_cw.o fbcon_ud.o \
+                                          fbcon_ccw.o
+ endif
+ 
++obj-$(CONFIG_FB_CON_DECOR)     	  += fbcondecor.o cfbcondecor.o
+ obj-$(CONFIG_FB_STI)              += sticore.o
+diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c
+index dbfe4ee..14da307 100644
+--- a/drivers/video/console/bitblit.c
++++ b/drivers/video/console/bitblit.c
+@@ -18,6 +18,7 @@
+ #include <linux/console.h>
+ #include <asm/types.h>
+ #include "fbcon.h"
++#include "fbcondecor.h"
+ 
+ /*
+  * Accelerated handlers.
+@@ -55,6 +56,13 @@ static void bit_bmove(struct vc_data *vc, struct fb_info *info, int sy,
+ 	area.height = height * vc->vc_font.height;
+ 	area.width = width * vc->vc_font.width;
+ 
++	if (fbcon_decor_active(info, vc)) {
++		area.sx += vc->vc_decor.tx;
++		area.sy += vc->vc_decor.ty;
++		area.dx += vc->vc_decor.tx;
++		area.dy += vc->vc_decor.ty;
++	}
++
+ 	info->fbops->fb_copyarea(info, &area);
+ }
+ 
+@@ -379,11 +387,15 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, int mode,
+ 	cursor.image.depth = 1;
+ 	cursor.rop = ROP_XOR;
+ 
+-	if (info->fbops->fb_cursor)
+-		err = info->fbops->fb_cursor(info, &cursor);
++	if (fbcon_decor_active(info, vc)) {
++		fbcon_decor_cursor(info, &cursor);
++	} else {
++		if (info->fbops->fb_cursor)
++			err = info->fbops->fb_cursor(info, &cursor);
+ 
+-	if (err)
+-		soft_cursor(info, &cursor);
++		if (err)
++			soft_cursor(info, &cursor);
++	}
+ 
+ 	ops->cursor_reset = 0;
+ }
+diff --git a/drivers/video/console/cfbcondecor.c b/drivers/video/console/cfbcondecor.c
+new file mode 100644
+index 0000000..c262540
+--- /dev/null
++++ b/drivers/video/console/cfbcondecor.c
+@@ -0,0 +1,473 @@
++/*
++ *  linux/drivers/video/cfbcon_decor.c -- Framebuffer decor render functions
++ *
++ *  Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
++ *
++ *  Code based upon "Bootdecor" (C) 2001-2003
++ *       Volker Poplawski <volker@poplawski.de>,
++ *       Stefan Reinauer <stepan@suse.de>,
++ *       Steffen Winterfeldt <snwint@suse.de>,
++ *       Michael Schroeder <mls@suse.de>,
++ *       Ken Wimer <wimer@suse.de>.
++ *
++ *  This file is subject to the terms and conditions of the GNU General Public
++ *  License.  See the file COPYING in the main directory of this archive for
++ *  more details.
++ */
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/fb.h>
++#include <linux/selection.h>
++#include <linux/slab.h>
++#include <linux/vt_kern.h>
++#include <asm/irq.h>
++
++#include "fbcon.h"
++#include "fbcondecor.h"
++
++#define parse_pixel(shift, bpp, type)						\
++	do {									\
++		if (d & (0x80 >> (shift)))					\
++			dd2[(shift)] = fgx;					\
++		else								\
++			dd2[(shift)] = transparent ? *(type *)decor_src : bgx;	\
++		decor_src += (bpp);						\
++	} while (0)								\
++
++extern int get_color(struct vc_data *vc, struct fb_info *info,
++		     u16 c, int is_fg);
++
++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc)
++{
++	int i, j, k;
++	int minlen = min(min(info->var.red.length, info->var.green.length),
++			     info->var.blue.length);
++	u32 col;
++
++	for (j = i = 0; i < 16; i++) {
++		k = color_table[i];
++
++		col = ((vc->vc_palette[j++]  >> (8-minlen))
++			<< info->var.red.offset);
++		col |= ((vc->vc_palette[j++] >> (8-minlen))
++			<< info->var.green.offset);
++		col |= ((vc->vc_palette[j++] >> (8-minlen))
++			<< info->var.blue.offset);
++			((u32 *)info->pseudo_palette)[k] = col;
++	}
++}
++
++void fbcon_decor_renderc(struct fb_info *info, int ypos, int xpos, int height,
++		      int width, u8 *src, u32 fgx, u32 bgx, u8 transparent)
++{
++	unsigned int x, y;
++	u32 dd;
++	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
++	unsigned int d = ypos * info->fix.line_length + xpos * bytespp;
++	unsigned int ds = (ypos * info->var.xres + xpos) * bytespp;
++	u16 dd2[4];
++
++	u8 *decor_src = (u8 *)(info->bgdecor.data + ds);
++	u8 *dst = (u8 *)(info->screen_base + d);
++
++	if ((ypos + height) > info->var.yres || (xpos + width) > info->var.xres)
++		return;
++
++	for (y = 0; y < height; y++) {
++		switch (info->var.bits_per_pixel) {
++
++		case 32:
++			for (x = 0; x < width; x++) {
++
++				if ((x & 7) == 0)
++					d = *src++;
++				if (d & 0x80)
++					dd = fgx;
++				else
++					dd = transparent ?
++					     *(u32 *)decor_src : bgx;
++
++				d <<= 1;
++				decor_src += 4;
++				fb_writel(dd, dst);
++				dst += 4;
++			}
++			break;
++		case 24:
++			for (x = 0; x < width; x++) {
++
++				if ((x & 7) == 0)
++					d = *src++;
++				if (d & 0x80)
++					dd = fgx;
++				else
++					dd = transparent ?
++					     (*(u32 *)decor_src & 0xffffff) : bgx;
++
++				d <<= 1;
++				decor_src += 3;
++#ifdef __LITTLE_ENDIAN
++				fb_writew(dd & 0xffff, dst);
++				dst += 2;
++				fb_writeb((dd >> 16), dst);
++#else
++				fb_writew(dd >> 8, dst);
++				dst += 2;
++				fb_writeb(dd & 0xff, dst);
++#endif
++				dst++;
++			}
++			break;
++		case 16:
++			for (x = 0; x < width; x += 2) {
++				if ((x & 7) == 0)
++					d = *src++;
++
++				parse_pixel(0, 2, u16);
++				parse_pixel(1, 2, u16);
++#ifdef __LITTLE_ENDIAN
++				dd = dd2[0] | (dd2[1] << 16);
++#else
++				dd = dd2[1] | (dd2[0] << 16);
++#endif
++				d <<= 2;
++				fb_writel(dd, dst);
++				dst += 4;
++			}
++			break;
++
++		case 8:
++			for (x = 0; x < width; x += 4) {
++				if ((x & 7) == 0)
++					d = *src++;
++
++				parse_pixel(0, 1, u8);
++				parse_pixel(1, 1, u8);
++				parse_pixel(2, 1, u8);
++				parse_pixel(3, 1, u8);
++
++#ifdef __LITTLE_ENDIAN
++				dd = dd2[0] | (dd2[1] << 8) | (dd2[2] << 16) | (dd2[3] << 24);
++#else
++				dd = dd2[3] | (dd2[2] << 8) | (dd2[1] << 16) | (dd2[0] << 24);
++#endif
++				d <<= 4;
++				fb_writel(dd, dst);
++				dst += 4;
++			}
++		}
++
++		dst += info->fix.line_length - width * bytespp;
++		decor_src += (info->var.xres - width) * bytespp;
++	}
++}
++
++#define cc2cx(a)						\
++	((info->fix.visual == FB_VISUAL_TRUECOLOR ||		\
++		info->fix.visual == FB_VISUAL_DIRECTCOLOR) ?	\
++			((u32 *)info->pseudo_palette)[a] : a)
++
++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info,
++		   const unsigned short *s, int count, int yy, int xx)
++{
++	unsigned short charmask = vc->vc_hi_font_mask ? 0x1ff : 0xff;
++	struct fbcon_ops *ops = info->fbcon_par;
++	int fg_color, bg_color, transparent;
++	u8 *src;
++	u32 bgx, fgx;
++	u16 c = scr_readw(s);
++
++	fg_color = get_color(vc, info, c, 1);
++	bg_color = get_color(vc, info, c, 0);
++
++	/* Don't paint the background image if console is blanked */
++	transparent = ops->blank_state ? 0 :
++		(vc->vc_decor.bg_color == bg_color);
++
++	xx = xx * vc->vc_font.width + vc->vc_decor.tx;
++	yy = yy * vc->vc_font.height + vc->vc_decor.ty;
++
++	fgx = cc2cx(fg_color);
++	bgx = cc2cx(bg_color);
++
++	while (count--) {
++		c = scr_readw(s++);
++		src = vc->vc_font.data + (c & charmask) * vc->vc_font.height *
++		      ((vc->vc_font.width + 7) >> 3);
++
++		fbcon_decor_renderc(info, yy, xx, vc->vc_font.height,
++			       vc->vc_font.width, src, fgx, bgx, transparent);
++		xx += vc->vc_font.width;
++	}
++}
++
++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor)
++{
++	int i;
++	unsigned int dsize, s_pitch;
++	struct fbcon_ops *ops = info->fbcon_par;
++	struct vc_data *vc;
++	u8 *src;
++
++	/* we really don't need any cursors while the console is blanked */
++	if (info->state != FBINFO_STATE_RUNNING || ops->blank_state)
++		return;
++
++	vc = vc_cons[ops->currcon].d;
++
++	src = kmalloc(64 + sizeof(struct fb_image), GFP_ATOMIC);
++	if (!src)
++		return;
++
++	s_pitch = (cursor->image.width + 7) >> 3;
++	dsize = s_pitch * cursor->image.height;
++	if (cursor->enable) {
++		switch (cursor->rop) {
++		case ROP_XOR:
++			for (i = 0; i < dsize; i++)
++				src[i] = cursor->image.data[i] ^ cursor->mask[i];
++			break;
++		case ROP_COPY:
++		default:
++			for (i = 0; i < dsize; i++)
++				src[i] = cursor->image.data[i] & cursor->mask[i];
++			break;
++		}
++	} else
++		memcpy(src, cursor->image.data, dsize);
++
++	fbcon_decor_renderc(info,
++			cursor->image.dy + vc->vc_decor.ty,
++			cursor->image.dx + vc->vc_decor.tx,
++			cursor->image.height,
++			cursor->image.width,
++			(u8 *)src,
++			cc2cx(cursor->image.fg_color),
++			cc2cx(cursor->image.bg_color),
++			cursor->image.bg_color == vc->vc_decor.bg_color);
++
++	kfree(src);
++}
++
++static void decorset(u8 *dst, int height, int width, int dstbytes,
++				u32 bgx, int bpp)
++{
++	int i;
++
++	if (bpp == 8)
++		bgx |= bgx << 8;
++	if (bpp == 16 || bpp == 8)
++		bgx |= bgx << 16;
++
++	while (height-- > 0) {
++		u8 *p = dst;
++
++		switch (bpp) {
++
++		case 32:
++			for (i = 0; i < width; i++) {
++				fb_writel(bgx, p); p += 4;
++			}
++			break;
++		case 24:
++			for (i = 0; i < width; i++) {
++#ifdef __LITTLE_ENDIAN
++				fb_writew((bgx & 0xffff), (u16 *)p); p += 2;
++				fb_writeb((bgx >> 16), p++);
++#else
++				fb_writew((bgx >> 8), (u16 *)p); p += 2;
++				fb_writeb((bgx & 0xff), p++);
++#endif
++			}
++			break;
++		case 16:
++			for (i = 0; i < width/4; i++) {
++				fb_writel(bgx, p); p += 4;
++				fb_writel(bgx, p); p += 4;
++			}
++			if (width & 2) {
++				fb_writel(bgx, p); p += 4;
++			}
++			if (width & 1)
++				fb_writew(bgx, (u16 *)p);
++			break;
++		case 8:
++			for (i = 0; i < width/4; i++) {
++				fb_writel(bgx, p); p += 4;
++			}
++
++			if (width & 2) {
++				fb_writew(bgx, p); p += 2;
++			}
++			if (width & 1)
++				fb_writeb(bgx, (u8 *)p);
++			break;
++
++		}
++		dst += dstbytes;
++	}
++}
++
++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes,
++		   int srclinebytes, int bpp)
++{
++	int i;
++
++	while (height-- > 0) {
++		u32 *p = (u32 *)dst;
++		u32 *q = (u32 *)src;
++
++		switch (bpp) {
++
++		case 32:
++			for (i = 0; i < width; i++)
++				fb_writel(*q++, p++);
++			break;
++		case 24:
++			for (i = 0; i < (width * 3 / 4); i++)
++				fb_writel(*q++, p++);
++			if ((width * 3) % 4) {
++				if (width & 2) {
++					fb_writeb(*(u8 *)q, (u8 *)p);
++				} else if (width & 1) {
++					fb_writew(*(u16 *)q, (u16 *)p);
++					fb_writeb(*(u8 *)((u16 *)q + 1),
++							(u8 *)((u16 *)p + 2));
++				}
++			}
++			break;
++		case 16:
++			for (i = 0; i < width/4; i++) {
++				fb_writel(*q++, p++);
++				fb_writel(*q++, p++);
++			}
++			if (width & 2)
++				fb_writel(*q++, p++);
++			if (width & 1)
++				fb_writew(*(u16 *)q, (u16 *)p);
++			break;
++		case 8:
++			for (i = 0; i < width/4; i++)
++				fb_writel(*q++, p++);
++
++			if (width & 2) {
++				fb_writew(*(u16 *)q, (u16 *)p);
++				q = (u32 *) ((u16 *)q + 1);
++				p = (u32 *) ((u16 *)p + 1);
++			}
++			if (width & 1)
++				fb_writeb(*(u8 *)q, (u8 *)p);
++			break;
++		}
++
++		dst += linebytes;
++		src += srclinebytes;
++	}
++}
++
++static void decorfill(struct fb_info *info, int sy, int sx, int height,
++		       int width)
++{
++	int bytespp = ((info->var.bits_per_pixel + 7) >> 3);
++	int d  = sy * info->fix.line_length + sx * bytespp;
++	int ds = (sy * info->var.xres + sx) * bytespp;
++
++	fbcon_decor_copy((u8 *)(info->screen_base + d), (u8 *)(info->bgdecor.data + ds),
++		    height, width, info->fix.line_length, info->var.xres * bytespp,
++		    info->var.bits_per_pixel);
++}
++
++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx,
++		    int height, int width)
++{
++	int bgshift = (vc->vc_hi_font_mask) ? 13 : 12;
++	struct fbcon_ops *ops = info->fbcon_par;
++	u8 *dst;
++	int transparent, bg_color = attr_bgcol_ec(bgshift, vc, info);
++
++	transparent = (vc->vc_decor.bg_color == bg_color);
++	sy = sy * vc->vc_font.height + vc->vc_decor.ty;
++	sx = sx * vc->vc_font.width + vc->vc_decor.tx;
++	height *= vc->vc_font.height;
++	width *= vc->vc_font.width;
++
++	/* Don't paint the background image if console is blanked */
++	if (transparent && !ops->blank_state) {
++		decorfill(info, sy, sx, height, width);
++	} else {
++		dst = (u8 *)(info->screen_base + sy * info->fix.line_length +
++			     sx * ((info->var.bits_per_pixel + 7) >> 3));
++		decorset(dst, height, width, info->fix.line_length, cc2cx(bg_color),
++			  info->var.bits_per_pixel);
++	}
++}
++
++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info,
++			    int bottom_only)
++{
++	unsigned int tw = vc->vc_cols*vc->vc_font.width;
++	unsigned int th = vc->vc_rows*vc->vc_font.height;
++
++	if (!bottom_only) {
++		/* top margin */
++		decorfill(info, 0, 0, vc->vc_decor.ty, info->var.xres);
++		/* left margin */
++		decorfill(info, vc->vc_decor.ty, 0, th, vc->vc_decor.tx);
++		/* right margin */
++		decorfill(info, vc->vc_decor.ty, vc->vc_decor.tx + tw, th,
++			   info->var.xres - vc->vc_decor.tx - tw);
++	}
++	decorfill(info, vc->vc_decor.ty + th, 0,
++		   info->var.yres - vc->vc_decor.ty - th, info->var.xres);
++}
++
++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y,
++			   int sx, int dx, int width)
++{
++	u16 *d = (u16 *) (vc->vc_origin + vc->vc_size_row * y + dx * 2);
++	u16 *s = d + (dx - sx);
++	u16 *start = d;
++	u16 *ls = d;
++	u16 *le = d + width;
++	u16 c;
++	int x = dx;
++	u16 attr = 1;
++
++	do {
++		c = scr_readw(d);
++		if (attr != (c & 0xff00)) {
++			attr = c & 0xff00;
++			if (d > start) {
++				fbcon_decor_putcs(vc, info, start, d - start, y, x);
++				x += d - start;
++				start = d;
++			}
++		}
++		if (s >= ls && s < le && c == scr_readw(s)) {
++			if (d > start) {
++				fbcon_decor_putcs(vc, info, start, d - start, y, x);
++				x += d - start + 1;
++				start = d + 1;
++			} else {
++				x++;
++				start++;
++			}
++		}
++		s++;
++		d++;
++	} while (d < le);
++	if (d > start)
++		fbcon_decor_putcs(vc, info, start, d - start, y, x);
++}
++
++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank)
++{
++	if (blank) {
++		decorset((u8 *)info->screen_base, info->var.yres, info->var.xres,
++			  info->fix.line_length, 0, info->var.bits_per_pixel);
++	} else {
++		update_screen(vc);
++		fbcon_decor_clear_margins(vc, info, 0);
++	}
++}
++
+diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
+index b87f5cf..ce44538 100644
+--- a/drivers/video/console/fbcon.c
++++ b/drivers/video/console/fbcon.c
+@@ -79,6 +79,7 @@
+ #include <asm/irq.h>
+ 
+ #include "fbcon.h"
++#include "../console/fbcondecor.h"
+ 
+ #ifdef FBCONDEBUG
+ #  define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__ , ## args)
+@@ -94,7 +95,7 @@ enum {
+ 
+ static struct display fb_display[MAX_NR_CONSOLES];
+ 
+-static signed char con2fb_map[MAX_NR_CONSOLES];
++signed char con2fb_map[MAX_NR_CONSOLES];
+ static signed char con2fb_map_boot[MAX_NR_CONSOLES];
+ 
+ static int logo_lines;
+@@ -282,7 +283,7 @@ static inline int fbcon_is_inactive(struct vc_data *vc, struct fb_info *info)
+ 		!vt_force_oops_output(vc);
+ }
+ 
+-static int get_color(struct vc_data *vc, struct fb_info *info,
++int get_color(struct vc_data *vc, struct fb_info *info,
+ 	      u16 c, int is_fg)
+ {
+ 	int depth = fb_get_color_depth(&info->var, &info->fix);
+@@ -546,6 +547,9 @@ static int do_fbcon_takeover(int show_logo)
+ 		info_idx = -1;
+ 	} else {
+ 		fbcon_has_console_bind = 1;
++#ifdef CONFIG_FB_CON_DECOR
++		fbcon_decor_init();
++#endif
+ 	}
+ 
+ 	return err;
+@@ -1005,6 +1009,12 @@ static const char *fbcon_startup(void)
+ 	rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ 	cols /= vc->vc_font.width;
+ 	rows /= vc->vc_font.height;
++
++	if (fbcon_decor_active(info, vc)) {
++		cols = vc->vc_decor.twidth / vc->vc_font.width;
++		rows = vc->vc_decor.theight / vc->vc_font.height;
++	}
++
+ 	vc_resize(vc, cols, rows);
+ 
+ 	DPRINTK("mode:   %s\n", info->fix.id);
+@@ -1034,7 +1044,7 @@ static void fbcon_init(struct vc_data *vc, int init)
+ 	cap = info->flags;
+ 
+ 	if (vc != svc || logo_shown == FBCON_LOGO_DONTSHOW ||
+-	    (info->fix.type == FB_TYPE_TEXT))
++	    (info->fix.type == FB_TYPE_TEXT) || fbcon_decor_active(info, vc))
+ 		logo = 0;
+ 
+ 	if (var_to_display(p, &info->var, info))
+@@ -1259,6 +1269,11 @@ static void fbcon_clear(struct vc_data *vc, int sy, int sx, int height,
+ 		fbcon_clear_margins(vc, 0);
+ 	}
+ 
++	if (fbcon_decor_active(info, vc)) {
++		fbcon_decor_clear(vc, info, sy, sx, height, width);
++		return;
++	}
++
+ 	/* Split blits that cross physical y_wrap boundary */
+ 
+ 	y_break = p->vrows - p->yscroll;
+@@ -1278,10 +1293,15 @@ static void fbcon_putcs(struct vc_data *vc, const unsigned short *s,
+ 	struct display *p = &fb_display[vc->vc_num];
+ 	struct fbcon_ops *ops = info->fbcon_par;
+ 
+-	if (!fbcon_is_inactive(vc, info))
+-		ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
+-			   get_color(vc, info, scr_readw(s), 1),
+-			   get_color(vc, info, scr_readw(s), 0));
++	if (!fbcon_is_inactive(vc, info)) {
++
++		if (fbcon_decor_active(info, vc))
++			fbcon_decor_putcs(vc, info, s, count, ypos, xpos);
++		else
++			ops->putcs(vc, info, s, count, real_y(p, ypos), xpos,
++				   get_color(vc, info, scr_readw(s), 1),
++				   get_color(vc, info, scr_readw(s), 0));
++	}
+ }
+ 
+ static void fbcon_putc(struct vc_data *vc, int c, int ypos, int xpos)
+@@ -1297,8 +1317,12 @@ static void fbcon_clear_margins(struct vc_data *vc, int bottom_only)
+ 	struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
+ 	struct fbcon_ops *ops = info->fbcon_par;
+ 
+-	if (!fbcon_is_inactive(vc, info))
+-		ops->clear_margins(vc, info, bottom_only);
++	if (!fbcon_is_inactive(vc, info)) {
++		if (fbcon_decor_active(info, vc))
++			fbcon_decor_clear_margins(vc, info, bottom_only);
++		else
++			ops->clear_margins(vc, info, bottom_only);
++	}
+ }
+ 
+ static void fbcon_cursor(struct vc_data *vc, int mode)
+@@ -1819,7 +1843,7 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 			count = vc->vc_rows;
+ 		if (softback_top)
+ 			fbcon_softback_note(vc, t, count);
+-		if (logo_shown >= 0)
++		if (logo_shown >= 0 || fbcon_decor_active(info, vc))
+ 			goto redraw_up;
+ 		switch (p->scrollmode) {
+ 		case SCROLL_MOVE:
+@@ -1912,6 +1936,8 @@ static int fbcon_scroll(struct vc_data *vc, int t, int b, int dir,
+ 			count = vc->vc_rows;
+ 		if (logo_shown >= 0)
+ 			goto redraw_down;
++		if (fbcon_decor_active(info, vc))
++			goto redraw_down;
+ 		switch (p->scrollmode) {
+ 		case SCROLL_MOVE:
+ 			fbcon_redraw_blit(vc, info, p, b - 1, b - t - count,
+@@ -2060,6 +2086,13 @@ static void fbcon_bmove_rec(struct vc_data *vc, struct display *p, int sy, int s
+ 		}
+ 		return;
+ 	}
++
++	if (fbcon_decor_active(info, vc) && sy == dy && height == 1) {
++		/* must use slower redraw bmove to keep background pic intact */
++		fbcon_decor_bmove_redraw(vc, info, sy, sx, dx, width);
++		return;
++	}
++
+ 	ops->bmove(vc, info, real_y(p, sy), sx, real_y(p, dy), dx,
+ 		   height, width);
+ }
+@@ -2130,8 +2163,8 @@ static int fbcon_resize(struct vc_data *vc, unsigned int width,
+ 	var.yres = virt_h * virt_fh;
+ 	x_diff = info->var.xres - var.xres;
+ 	y_diff = info->var.yres - var.yres;
+-	if (x_diff < 0 || x_diff > virt_fw ||
+-	    y_diff < 0 || y_diff > virt_fh) {
++	if ((x_diff < 0 || x_diff > virt_fw ||
++		y_diff < 0 || y_diff > virt_fh) && !vc->vc_decor.state) {
+ 		const struct fb_videomode *mode;
+ 
+ 		DPRINTK("attempting resize %ix%i\n", var.xres, var.yres);
+@@ -2167,6 +2200,22 @@ static int fbcon_switch(struct vc_data *vc)
+ 
+ 	info = registered_fb[con2fb_map[vc->vc_num]];
+ 	ops = info->fbcon_par;
++	prev_console = ops->currcon;
++	if (prev_console != -1)
++		old_info = registered_fb[con2fb_map[prev_console]];
++
++#ifdef CONFIG_FB_CON_DECOR
++	if (!fbcon_decor_active_vc(vc) && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
++		struct vc_data *vc_curr = vc_cons[prev_console].d;
++
++		if (vc_curr && fbcon_decor_active_vc(vc_curr)) {
++			// Clear the screen to avoid displaying funky colors
++			// during palette updates.
++			memset((u8 *)info->screen_base + info->fix.line_length * info->var.yoffset,
++			       0, info->var.yres * info->fix.line_length);
++		}
++	}
++#endif
+ 
+ 	if (softback_top) {
+ 		if (softback_lines)
+@@ -2185,9 +2234,6 @@ static int fbcon_switch(struct vc_data *vc)
+ 		logo_shown = FBCON_LOGO_CANSHOW;
+ 	}
+ 
+-	prev_console = ops->currcon;
+-	if (prev_console != -1)
+-		old_info = registered_fb[con2fb_map[prev_console]];
+ 	/*
+ 	 * FIXME: If we have multiple fbdev's loaded, we need to
+ 	 * update all info->currcon.  Perhaps, we can place this
+@@ -2231,6 +2277,18 @@ static int fbcon_switch(struct vc_data *vc)
+ 			fbcon_del_cursor_timer(old_info);
+ 	}
+ 
++	if (fbcon_decor_active_vc(vc)) {
++		struct vc_data *vc_curr = vc_cons[prev_console].d;
++
++		if (!vc_curr->vc_decor.theme ||
++			strcmp(vc->vc_decor.theme, vc_curr->vc_decor.theme) ||
++			(fbcon_decor_active_nores(info, vc_curr) &&
++			 !fbcon_decor_active(info, vc_curr))) {
++			fbcon_decor_disable(vc, 0);
++			fbcon_decor_call_helper("modechange", vc->vc_num);
++		}
++	}
++
+ 	if (fbcon_is_inactive(vc, info) ||
+ 	    ops->blank_state != FB_BLANK_UNBLANK)
+ 		fbcon_del_cursor_timer(info);
+@@ -2339,15 +2397,20 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
+ 		}
+ 	}
+ 
+- 	if (!fbcon_is_inactive(vc, info)) {
++	if (!fbcon_is_inactive(vc, info)) {
+ 		if (ops->blank_state != blank) {
+ 			ops->blank_state = blank;
+ 			fbcon_cursor(vc, blank ? CM_ERASE : CM_DRAW);
+ 			ops->cursor_flash = (!blank);
+ 
+-			if (!(info->flags & FBINFO_MISC_USEREVENT))
+-				if (fb_blank(info, blank))
+-					fbcon_generic_blank(vc, info, blank);
++			if (!(info->flags & FBINFO_MISC_USEREVENT)) {
++				if (fb_blank(info, blank)) {
++					if (fbcon_decor_active(info, vc))
++						fbcon_decor_blank(vc, info, blank);
++					else
++						fbcon_generic_blank(vc, info, blank);
++				}
++			}
+ 		}
+ 
+ 		if (!blank)
+@@ -2522,13 +2585,22 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h,
+ 	}
+ 
+ 	if (resize) {
++		/* reset wrap/pan */
+ 		int cols, rows;
+ 
+ 		cols = FBCON_SWAP(ops->rotate, info->var.xres, info->var.yres);
+ 		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
++
++		if (fbcon_decor_active(info, vc)) {
++			info->var.xoffset = info->var.yoffset = p->yscroll = 0;
++			cols = vc->vc_decor.twidth;
++			rows = vc->vc_decor.theight;
++		}
+ 		cols /= w;
+ 		rows /= h;
++
+ 		vc_resize(vc, cols, rows);
++
+ 		if (con_is_visible(vc) && softback_buf)
+ 			fbcon_update_softback(vc);
+ 	} else if (con_is_visible(vc)
+@@ -2657,7 +2729,11 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
+ 	int i, j, k, depth;
+ 	u8 val;
+ 
+-	if (fbcon_is_inactive(vc, info))
++	if (fbcon_is_inactive(vc, info)
++#ifdef CONFIG_FB_CON_DECOR
++			|| vc->vc_num != fg_console
++#endif
++		)
+ 		return;
+ 
+ 	if (!con_is_visible(vc))
+@@ -2683,7 +2759,47 @@ static void fbcon_set_palette(struct vc_data *vc, const unsigned char *table)
+ 	} else
+ 		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
+ 
+-	fb_set_cmap(&palette_cmap, info);
++	if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
++	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
++
++		u16 *red, *green, *blue;
++		int minlen = min(min(info->var.red.length, info->var.green.length),
++				     info->var.blue.length);
++
++		struct fb_cmap cmap = {
++			.start = 0,
++			.len = (1 << minlen),
++			.red = NULL,
++			.green = NULL,
++			.blue = NULL,
++			.transp = NULL
++		};
++
++		red = kmalloc(256 * sizeof(u16) * 3, GFP_KERNEL);
++
++		if (!red)
++			goto out;
++
++		green = red + 256;
++		blue = green + 256;
++		cmap.red = red;
++		cmap.green = green;
++		cmap.blue = blue;
++
++		for (i = 0; i < cmap.len; i++)
++			red[i] = green[i] = blue[i] = (0xffff * i)/(cmap.len-1);
++
++		fb_set_cmap(&cmap, info);
++		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
++		kfree(red);
++
++		return;
++
++	} else if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
++		   info->var.bits_per_pixel == 8 && info->bgdecor.cmap.red != NULL)
++		fb_set_cmap(&info->bgdecor.cmap, info);
++
++out:	fb_set_cmap(&palette_cmap, info);
+ }
+ 
+ static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
+@@ -2908,7 +3024,14 @@ static void fbcon_modechanged(struct fb_info *info)
+ 		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ 		cols /= vc->vc_font.width;
+ 		rows /= vc->vc_font.height;
+-		vc_resize(vc, cols, rows);
++
++		if (!fbcon_decor_active_nores(info, vc)) {
++			vc_resize(vc, cols, rows);
++		} else {
++			fbcon_decor_disable(vc, 0);
++			fbcon_decor_call_helper("modechange", vc->vc_num);
++		}
++
+ 		updatescrollmode(p, info, vc);
+ 		scrollback_max = 0;
+ 		scrollback_current = 0;
+@@ -2953,7 +3076,8 @@ static void fbcon_set_all_vcs(struct fb_info *info)
+ 		rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
+ 		cols /= vc->vc_font.width;
+ 		rows /= vc->vc_font.height;
+-		vc_resize(vc, cols, rows);
++		if (!fbcon_decor_active_nores(info, vc))
++			vc_resize(vc, cols, rows);
+ 	}
+ 
+ 	if (fg != -1)
+@@ -3594,6 +3718,7 @@ static void fbcon_exit(void)
+ 		}
+ 	}
+ 
++	fbcon_decor_exit();
+ 	fbcon_has_exited = 1;
+ }
+ 
+diff --git a/drivers/video/console/fbcondecor.c b/drivers/video/console/fbcondecor.c
+new file mode 100644
+index 0000000..65cc0d3
+--- /dev/null
++++ b/drivers/video/console/fbcondecor.c
+@@ -0,0 +1,549 @@
++/*
++ *  linux/drivers/video/console/fbcondecor.c -- Framebuffer console decorations
++ *
++ *  Copyright (C) 2004-2009 Michal Januszewski <michalj+fbcondecor@gmail.com>
++ *
++ *  Code based upon "Bootsplash" (C) 2001-2003
++ *       Volker Poplawski <volker@poplawski.de>,
++ *       Stefan Reinauer <stepan@suse.de>,
++ *       Steffen Winterfeldt <snwint@suse.de>,
++ *       Michael Schroeder <mls@suse.de>,
++ *       Ken Wimer <wimer@suse.de>.
++ *
++ *  Compat ioctl support by Thorsten Klein <TK@Thorsten-Klein.de>.
++ *
++ *  This file is subject to the terms and conditions of the GNU General Public
++ *  License.  See the file COPYING in the main directory of this archive for
++ *  more details.
++ *
++ */
++#include <linux/module.h>
++#include <linux/kernel.h>
++#include <linux/string.h>
++#include <linux/types.h>
++#include <linux/fb.h>
++#include <linux/vt_kern.h>
++#include <linux/vmalloc.h>
++#include <linux/unistd.h>
++#include <linux/syscalls.h>
++#include <linux/init.h>
++#include <linux/proc_fs.h>
++#include <linux/workqueue.h>
++#include <linux/kmod.h>
++#include <linux/miscdevice.h>
++#include <linux/device.h>
++#include <linux/fs.h>
++#include <linux/compat.h>
++#include <linux/console.h>
++
++#include <linux/uaccess.h>
++#include <asm/irq.h>
++
++#include "fbcon.h"
++#include "fbcondecor.h"
++
++extern signed char con2fb_map[];
++static int fbcon_decor_enable(struct vc_data *vc);
++
++static int initialized;
++
++char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
++EXPORT_SYMBOL(fbcon_decor_path);
++
++int fbcon_decor_call_helper(char *cmd, unsigned short vc)
++{
++	char *envp[] = {
++		"HOME=/",
++		"PATH=/sbin:/bin",
++		NULL
++	};
++
++	char tfb[5];
++	char tcons[5];
++	unsigned char fb = (int) con2fb_map[vc];
++
++	char *argv[] = {
++		fbcon_decor_path,
++		"2",
++		cmd,
++		tcons,
++		tfb,
++		vc_cons[vc].d->vc_decor.theme,
++		NULL
++	};
++
++	snprintf(tfb, 5, "%d", fb);
++	snprintf(tcons, 5, "%d", vc);
++
++	return call_usermodehelper(fbcon_decor_path, argv, envp, UMH_WAIT_EXEC);
++}
++
++/* Disables fbcondecor on a virtual console; called with console sem held. */
++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw)
++{
++	struct fb_info *info;
++
++	if (!vc->vc_decor.state)
++		return -EINVAL;
++
++	info = registered_fb[(int) con2fb_map[vc->vc_num]];
++
++	if (info == NULL)
++		return -EINVAL;
++
++	vc->vc_decor.state = 0;
++	vc_resize(vc, info->var.xres / vc->vc_font.width,
++		  info->var.yres / vc->vc_font.height);
++
++	if (fg_console == vc->vc_num && redraw) {
++		redraw_screen(vc, 0);
++		update_region(vc, vc->vc_origin +
++			      vc->vc_size_row * vc->vc_top,
++			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
++	}
++
++	printk(KERN_INFO "fbcondecor: switched decor state to 'off' on console %d\n",
++			 vc->vc_num);
++
++	return 0;
++}
++
++/* Enables fbcondecor on a virtual console; called with console sem held. */
++static int fbcon_decor_enable(struct vc_data *vc)
++{
++	struct fb_info *info;
++
++	info = registered_fb[(int) con2fb_map[vc->vc_num]];
++
++	if (vc->vc_decor.twidth == 0 || vc->vc_decor.theight == 0 ||
++	    info == NULL || vc->vc_decor.state || (!info->bgdecor.data &&
++	    vc->vc_num == fg_console))
++		return -EINVAL;
++
++	vc->vc_decor.state = 1;
++	vc_resize(vc, vc->vc_decor.twidth / vc->vc_font.width,
++		  vc->vc_decor.theight / vc->vc_font.height);
++
++	if (fg_console == vc->vc_num) {
++		redraw_screen(vc, 0);
++		update_region(vc, vc->vc_origin +
++			      vc->vc_size_row * vc->vc_top,
++			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
++		fbcon_decor_clear_margins(vc, info, 0);
++	}
++
++	printk(KERN_INFO "fbcondecor: switched decor state to 'on' on console %d\n",
++			 vc->vc_num);
++
++	return 0;
++}
++
++static inline int fbcon_decor_ioctl_dosetstate(struct vc_data *vc, unsigned int state, unsigned char origin)
++{
++	int ret;
++
++	console_lock();
++	if (!state)
++		ret = fbcon_decor_disable(vc, 1);
++	else
++		ret = fbcon_decor_enable(vc);
++	console_unlock();
++
++	return ret;
++}
++
++static inline void fbcon_decor_ioctl_dogetstate(struct vc_data *vc, unsigned int *state)
++{
++	*state = vc->vc_decor.state;
++}
++
++static int fbcon_decor_ioctl_dosetcfg(struct vc_data *vc, struct vc_decor *cfg, unsigned char origin)
++{
++	struct fb_info *info;
++	int len;
++	char *tmp;
++
++	info = registered_fb[(int) con2fb_map[vc->vc_num]];
++
++	if (info == NULL || !cfg->twidth || !cfg->theight ||
++	    cfg->tx + cfg->twidth  > info->var.xres ||
++	    cfg->ty + cfg->theight > info->var.yres)
++		return -EINVAL;
++
++	len = strlen_user(cfg->theme);
++	if (!len || len > FBCON_DECOR_THEME_LEN)
++		return -EINVAL;
++	tmp = kmalloc(len, GFP_KERNEL);
++	if (!tmp)
++		return -ENOMEM;
++	if (copy_from_user(tmp, (void __user *)cfg->theme, len))
++		return -EFAULT;
++	cfg->theme = tmp;
++	cfg->state = 0;
++
++	console_lock();
++	if (vc->vc_decor.state)
++		fbcon_decor_disable(vc, 1);
++	kfree(vc->vc_decor.theme);
++	vc->vc_decor = *cfg;
++	console_unlock();
++
++	printk(KERN_INFO "fbcondecor: console %d using theme '%s'\n",
++			 vc->vc_num, vc->vc_decor.theme);
++	return 0;
++}
++
++static int fbcon_decor_ioctl_dogetcfg(struct vc_data *vc,
++					struct vc_decor *decor)
++{
++	char __user *tmp;
++
++	tmp = decor->theme;
++	*decor = vc->vc_decor;
++	decor->theme = tmp;
++
++	if (vc->vc_decor.theme) {
++		if (copy_to_user(tmp, vc->vc_decor.theme,
++					strlen(vc->vc_decor.theme) + 1))
++			return -EFAULT;
++	} else
++		if (put_user(0, tmp))
++			return -EFAULT;
++
++	return 0;
++}
++
++static int fbcon_decor_ioctl_dosetpic(struct vc_data *vc, struct fb_image *img,
++						unsigned char origin)
++{
++	struct fb_info *info;
++	int len;
++	u8 *tmp;
++
++	if (vc->vc_num != fg_console)
++		return -EINVAL;
++
++	info = registered_fb[(int) con2fb_map[vc->vc_num]];
++
++	if (info == NULL)
++		return -EINVAL;
++
++	if (img->width != info->var.xres || img->height != info->var.yres) {
++		printk(KERN_ERR "fbcondecor: picture dimensions mismatch\n");
++		printk(KERN_ERR "%dx%d vs %dx%d\n", img->width, img->height,
++				info->var.xres, info->var.yres);
++		return -EINVAL;
++	}
++
++	if (img->depth != info->var.bits_per_pixel) {
++		printk(KERN_ERR "fbcondecor: picture depth mismatch\n");
++		return -EINVAL;
++	}
++
++	if (img->depth == 8) {
++		if (!img->cmap.len || !img->cmap.red || !img->cmap.green ||
++		    !img->cmap.blue)
++			return -EINVAL;
++
++		tmp = vmalloc(img->cmap.len * 3 * 2);
++		if (!tmp)
++			return -ENOMEM;
++
++		if (copy_from_user(tmp,
++				(void __user *)img->cmap.red,
++						(img->cmap.len << 1)) ||
++			copy_from_user(tmp + (img->cmap.len << 1),
++				(void __user *)img->cmap.green,
++						(img->cmap.len << 1)) ||
++			copy_from_user(tmp + (img->cmap.len << 2),
++				(void __user *)img->cmap.blue,
++						(img->cmap.len << 1))) {
++			vfree(tmp);
++			return -EFAULT;
++		}
++
++		img->cmap.transp = NULL;
++		img->cmap.red = (u16 *)tmp;
++		img->cmap.green = img->cmap.red + img->cmap.len;
++		img->cmap.blue = img->cmap.green + img->cmap.len;
++	} else {
++		img->cmap.red = NULL;
++	}
++
++	len = ((img->depth + 7) >> 3) * img->width * img->height;
++
++	/*
++	 * Allocate an additional byte so that we never go outside of the
++	 * buffer boundaries in the rendering functions in a 24 bpp mode.
++	 */
++	tmp = vmalloc(len + 1);
++
++	if (!tmp)
++		goto out;
++
++	if (copy_from_user(tmp, (void __user *)img->data, len))
++		goto out;
++
++	img->data = tmp;
++
++	console_lock();
++
++	if (info->bgdecor.data)
++		vfree((u8 *)info->bgdecor.data);
++	if (info->bgdecor.cmap.red)
++		vfree(info->bgdecor.cmap.red);
++
++	info->bgdecor = *img;
++
++	if (fbcon_decor_active_vc(vc) && fg_console == vc->vc_num) {
++		redraw_screen(vc, 0);
++		update_region(vc, vc->vc_origin +
++			      vc->vc_size_row * vc->vc_top,
++			      vc->vc_size_row * (vc->vc_bottom - vc->vc_top) / 2);
++		fbcon_decor_clear_margins(vc, info, 0);
++	}
++
++	console_unlock();
++
++	return 0;
++
++out:
++	if (img->cmap.red)
++		vfree(img->cmap.red);
++
++	if (tmp)
++		vfree(tmp);
++	return -ENOMEM;
++}
++
++static long fbcon_decor_ioctl(struct file *filp, u_int cmd, u_long arg)
++{
++	struct fbcon_decor_iowrapper __user *wrapper = (void __user *) arg;
++	struct vc_data *vc = NULL;
++	unsigned short vc_num = 0;
++	unsigned char origin = 0;
++	void __user *data = NULL;
++
++	if (!access_ok(VERIFY_READ, wrapper,
++			sizeof(struct fbcon_decor_iowrapper)))
++		return -EFAULT;
++
++	__get_user(vc_num, &wrapper->vc);
++	__get_user(origin, &wrapper->origin);
++	__get_user(data, &wrapper->data);
++
++	if (!vc_cons_allocated(vc_num))
++		return -EINVAL;
++
++	vc = vc_cons[vc_num].d;
++
++	switch (cmd) {
++	case FBIOCONDECOR_SETPIC:
++	{
++		struct fb_image img;
++
++		if (copy_from_user(&img, (struct fb_image __user *)data, sizeof(struct fb_image)))
++			return -EFAULT;
++
++		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
++	}
++	case FBIOCONDECOR_SETCFG:
++	{
++		struct vc_decor cfg;
++
++		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
++			return -EFAULT;
++
++		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
++	}
++	case FBIOCONDECOR_GETCFG:
++	{
++		int rval;
++		struct vc_decor cfg;
++
++		if (copy_from_user(&cfg, (struct vc_decor __user *)data, sizeof(struct vc_decor)))
++			return -EFAULT;
++
++		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
++
++		if (copy_to_user(data, &cfg, sizeof(struct vc_decor)))
++			return -EFAULT;
++		return rval;
++	}
++	case FBIOCONDECOR_SETSTATE:
++	{
++		unsigned int state = 0;
++
++		if (get_user(state, (unsigned int __user *)data))
++			return -EFAULT;
++		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
++	}
++	case FBIOCONDECOR_GETSTATE:
++	{
++		unsigned int state = 0;
++
++		fbcon_decor_ioctl_dogetstate(vc, &state);
++		return put_user(state, (unsigned int __user *)data);
++	}
++
++	default:
++		return -ENOIOCTLCMD;
++	}
++}
++
++#ifdef CONFIG_COMPAT
++
++static long fbcon_decor_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
++{
++	struct fbcon_decor_iowrapper32 __user *wrapper = (void __user *)arg;
++	struct vc_data *vc = NULL;
++	unsigned short vc_num = 0;
++	unsigned char origin = 0;
++	compat_uptr_t data_compat = 0;
++	void __user *data = NULL;
++
++	if (!access_ok(VERIFY_READ, wrapper,
++			sizeof(struct fbcon_decor_iowrapper32)))
++		return -EFAULT;
++
++	__get_user(vc_num, &wrapper->vc);
++	__get_user(origin, &wrapper->origin);
++	__get_user(data_compat, &wrapper->data);
++	data = compat_ptr(data_compat);
++
++	if (!vc_cons_allocated(vc_num))
++		return -EINVAL;
++
++	vc = vc_cons[vc_num].d;
++
++	switch (cmd) {
++	case FBIOCONDECOR_SETPIC32:
++	{
++		struct fb_image32 img_compat;
++		struct fb_image img;
++
++		if (copy_from_user(&img_compat, (struct fb_image32 __user *)data, sizeof(struct fb_image32)))
++			return -EFAULT;
++
++		fb_image_from_compat(img, img_compat);
++
++		return fbcon_decor_ioctl_dosetpic(vc, &img, origin);
++	}
++
++	case FBIOCONDECOR_SETCFG32:
++	{
++		struct vc_decor32 cfg_compat;
++		struct vc_decor cfg;
++
++		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
++			return -EFAULT;
++
++		vc_decor_from_compat(cfg, cfg_compat);
++
++		return fbcon_decor_ioctl_dosetcfg(vc, &cfg, origin);
++	}
++
++	case FBIOCONDECOR_GETCFG32:
++	{
++		int rval;
++		struct vc_decor32 cfg_compat;
++		struct vc_decor cfg;
++
++		if (copy_from_user(&cfg_compat, (struct vc_decor32 __user *)data, sizeof(struct vc_decor32)))
++			return -EFAULT;
++		cfg.theme = compat_ptr(cfg_compat.theme);
++
++		rval = fbcon_decor_ioctl_dogetcfg(vc, &cfg);
++
++		vc_decor_to_compat(cfg_compat, cfg);
++
++		if (copy_to_user((struct vc_decor32 __user *)data, &cfg_compat, sizeof(struct vc_decor32)))
++			return -EFAULT;
++		return rval;
++	}
++
++	case FBIOCONDECOR_SETSTATE32:
++	{
++		compat_uint_t state_compat = 0;
++		unsigned int state = 0;
++
++		if (get_user(state_compat, (compat_uint_t __user *)data))
++			return -EFAULT;
++
++		state = (unsigned int)state_compat;
++
++		return fbcon_decor_ioctl_dosetstate(vc, state, origin);
++	}
++
++	case FBIOCONDECOR_GETSTATE32:
++	{
++		compat_uint_t state_compat = 0;
++		unsigned int state = 0;
++
++		fbcon_decor_ioctl_dogetstate(vc, &state);
++		state_compat = (compat_uint_t)state;
++
++		return put_user(state_compat, (compat_uint_t __user *)data);
++	}
++
++	default:
++		return -ENOIOCTLCMD;
++	}
++}
++#else
++  #define fbcon_decor_compat_ioctl NULL
++#endif
++
++static struct file_operations fbcon_decor_ops = {
++	.owner = THIS_MODULE,
++	.unlocked_ioctl = fbcon_decor_ioctl,
++	.compat_ioctl = fbcon_decor_compat_ioctl
++};
++
++static struct miscdevice fbcon_decor_dev = {
++	.minor = MISC_DYNAMIC_MINOR,
++	.name = "fbcondecor",
++	.fops = &fbcon_decor_ops
++};
++
++void fbcon_decor_reset(void)
++{
++	int i;
++
++	for (i = 0; i < num_registered_fb; i++) {
++		registered_fb[i]->bgdecor.data = NULL;
++		registered_fb[i]->bgdecor.cmap.red = NULL;
++	}
++
++	for (i = 0; i < MAX_NR_CONSOLES && vc_cons[i].d; i++) {
++		vc_cons[i].d->vc_decor.state = vc_cons[i].d->vc_decor.twidth =
++						vc_cons[i].d->vc_decor.theight = 0;
++		vc_cons[i].d->vc_decor.theme = NULL;
++	}
++}
++
++int fbcon_decor_init(void)
++{
++	int i;
++
++	fbcon_decor_reset();
++
++	if (initialized)
++		return 0;
++
++	i = misc_register(&fbcon_decor_dev);
++	if (i) {
++		printk(KERN_ERR "fbcondecor: failed to register device\n");
++		return i;
++	}
++
++	fbcon_decor_call_helper("init", 0);
++	initialized = 1;
++	return 0;
++}
++
++int fbcon_decor_exit(void)
++{
++	fbcon_decor_reset();
++	return 0;
++}
+diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
+new file mode 100644
+index 0000000..c49386c
+--- /dev/null
++++ b/drivers/video/console/fbcondecor.h
+@@ -0,0 +1,77 @@
++/*
++ *  linux/drivers/video/console/fbcondecor.h -- Framebuffer Console Decoration headers
++ *
++ *  Copyright (C) 2004 Michal Januszewski <michalj+fbcondecor@gmail.com>
++ *
++ */
++
++#ifndef __FBCON_DECOR_H
++#define __FBCON_DECOR_H
++
++#ifndef _LINUX_FB_H
++#include <linux/fb.h>
++#endif
++
++/* This is needed for vc_cons in fbcmap.c */
++#include <linux/vt_kern.h>
++
++struct fb_cursor;
++struct fb_info;
++struct vc_data;
++
++#ifdef CONFIG_FB_CON_DECOR
++/* fbcondecor.c */
++int fbcon_decor_init(void);
++int fbcon_decor_exit(void);
++int fbcon_decor_call_helper(char *cmd, unsigned short cons);
++int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw);
++
++/* cfbcondecor.c */
++void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx);
++void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor);
++void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width);
++void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only);
++void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank);
++void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width);
++void fbcon_decor_copy(u8 *dst, u8 *src, int height, int width, int linebytes, int srclinesbytes, int bpp);
++void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc);
++
++/* vt.c */
++void acquire_console_sem(void);
++void release_console_sem(void);
++void do_unblank_screen(int entering_gfx);
++
++/* struct vc_data *y */
++#define fbcon_decor_active_vc(y) (y->vc_decor.state && y->vc_decor.theme)
++
++/* struct fb_info *x, struct vc_data *y */
++#define fbcon_decor_active_nores(x, y) (x->bgdecor.data && fbcon_decor_active_vc(y))
++
++/* struct fb_info *x, struct vc_data *y */
++#define fbcon_decor_active(x, y) (fbcon_decor_active_nores(x, y) &&	\
++				x->bgdecor.width == x->var.xres &&	\
++				x->bgdecor.height == x->var.yres &&	\
++				x->bgdecor.depth == x->var.bits_per_pixel)
++
++#else /* CONFIG_FB_CON_DECOR */
++
++static inline void fbcon_decor_putcs(struct vc_data *vc, struct fb_info *info, const unsigned short *s, int count, int yy, int xx) {}
++static inline void fbcon_decor_putc(struct vc_data *vc, struct fb_info *info, int c, int ypos, int xpos) {}
++static inline void fbcon_decor_cursor(struct fb_info *info, struct fb_cursor *cursor) {}
++static inline void fbcon_decor_clear(struct vc_data *vc, struct fb_info *info, int sy, int sx, int height, int width) {}
++static inline void fbcon_decor_clear_margins(struct vc_data *vc, struct fb_info *info, int bottom_only) {}
++static inline void fbcon_decor_blank(struct vc_data *vc, struct fb_info *info, int blank) {}
++static inline void fbcon_decor_bmove_redraw(struct vc_data *vc, struct fb_info *info, int y, int sx, int dx, int width) {}
++static inline void fbcon_decor_fix_pseudo_pal(struct fb_info *info, struct vc_data *vc) {}
++static inline int fbcon_decor_call_helper(char *cmd, unsigned short cons) { return 0; }
++static inline int fbcon_decor_init(void) { return 0; }
++static inline int fbcon_decor_exit(void) { return 0; }
++static inline int fbcon_decor_disable(struct vc_data *vc, unsigned char redraw) { return 0; }
++
++#define fbcon_decor_active_vc(y) (0)
++#define fbcon_decor_active_nores(x, y) (0)
++#define fbcon_decor_active(x, y) (0)
++
++#endif /* CONFIG_FB_CON_DECOR */
++
++#endif /* __FBCON_DECOR_H */
+diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
+index 88b008f..c84113d 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -1216,7 +1216,6 @@ config FB_MATROX
+ 	select FB_CFB_FILLRECT
+ 	select FB_CFB_COPYAREA
+ 	select FB_CFB_IMAGEBLIT
+-	select FB_TILEBLITTING
+ 	select FB_MACMODES if PPC_PMAC
+ 	---help---
+ 	  Say Y here if you have a Matrox Millennium, Matrox Millennium II,
+diff --git a/drivers/video/fbdev/core/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
+index f89245b..c2c12ce 100644
+--- a/drivers/video/fbdev/core/fbcmap.c
++++ b/drivers/video/fbdev/core/fbcmap.c
+@@ -17,6 +17,8 @@
+ #include <linux/slab.h>
+ #include <linux/uaccess.h>
+ 
++#include "../../console/fbcondecor.h"
++
+ static u16 red2[] __read_mostly = {
+     0x0000, 0xaaaa
+ };
+@@ -254,9 +256,12 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
+ 				break;
+ 		}
+ 	}
+-	if (rc == 0)
++	if (rc == 0) {
+ 		fb_copy_cmap(cmap, &info->cmap);
+-
++		if (fbcon_decor_active(info, vc_cons[fg_console].d) &&
++		    info->fix.visual == FB_VISUAL_DIRECTCOLOR)
++			fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
++	}
+ 	return rc;
+ }
+ 
+diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
+index 76c1ad9..fafc0af 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1251,15 +1251,6 @@ struct fb_fix_screeninfo32 {
+ 	u16			reserved[3];
+ };
+ 
+-struct fb_cmap32 {
+-	u32			start;
+-	u32			len;
+-	compat_caddr_t	red;
+-	compat_caddr_t	green;
+-	compat_caddr_t	blue;
+-	compat_caddr_t	transp;
+-};
+-
+ static int fb_getput_cmap(struct fb_info *info, unsigned int cmd,
+ 			  unsigned long arg)
+ {
+diff --git a/include/linux/console_decor.h b/include/linux/console_decor.h
+new file mode 100644
+index 0000000..1514355
+--- /dev/null
++++ b/include/linux/console_decor.h
+@@ -0,0 +1,46 @@
++#ifndef _LINUX_CONSOLE_DECOR_H_
++#define _LINUX_CONSOLE_DECOR_H_ 1
++
++/* A structure used by the framebuffer console decorations (drivers/video/console/fbcondecor.c) */
++struct vc_decor {
++	__u8 bg_color;				/* The color that is to be treated as transparent */
++	__u8 state;				/* Current decor state: 0 = off, 1 = on */
++	__u16 tx, ty;				/* Top left corner coordinates of the text field */
++	__u16 twidth, theight;			/* Width and height of the text field */
++	char *theme;
++};
++
++#ifdef __KERNEL__
++#ifdef CONFIG_COMPAT
++#include <linux/compat.h>
++
++struct vc_decor32 {
++	__u8 bg_color;				/* The color that is to be treated as transparent */
++	__u8 state;				/* Current decor state: 0 = off, 1 = on */
++	__u16 tx, ty;				/* Top left corner coordinates of the text field */
++	__u16 twidth, theight;			/* Width and height of the text field */
++	compat_uptr_t theme;
++};
++
++#define vc_decor_from_compat(to, from) \
++	(to).bg_color = (from).bg_color; \
++	(to).state    = (from).state; \
++	(to).tx       = (from).tx; \
++	(to).ty       = (from).ty; \
++	(to).twidth   = (from).twidth; \
++	(to).theight  = (from).theight; \
++	(to).theme    = compat_ptr((from).theme)
++
++#define vc_decor_to_compat(to, from) \
++	(to).bg_color = (from).bg_color; \
++	(to).state    = (from).state; \
++	(to).tx       = (from).tx; \
++	(to).ty       = (from).ty; \
++	(to).twidth   = (from).twidth; \
++	(to).theight  = (from).theight; \
++	(to).theme    = ptr_to_compat((from).theme)
++
++#endif /* CONFIG_COMPAT */
++#endif /* __KERNEL__ */
++
++#endif
+diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
+index 6fd3c90..c649555 100644
+--- a/include/linux/console_struct.h
++++ b/include/linux/console_struct.h
+@@ -20,6 +20,7 @@ struct vt_struct;
+ struct uni_pagedir;
+ 
+ #define NPAR 16
++#include <linux/console_decor.h>
+ 
+ /*
+  * Example: vc_data of a console that was scrolled 3 lines down.
+@@ -140,6 +141,8 @@ struct vc_data {
+ 	struct uni_pagedir *vc_uni_pagedir;
+ 	struct uni_pagedir **vc_uni_pagedir_loc; /* [!] Location of uni_pagedir variable for this console */
+ 	bool vc_panic_force_write; /* when oops/panic this VC can accept forced output/blanking */
++
++	struct vc_decor vc_decor;
+ 	/* additional information is in vt_kern.h */
+ };
+ 
+diff --git a/include/linux/fb.h b/include/linux/fb.h
+index a964d07..672cc64 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -238,6 +238,34 @@ struct fb_deferred_io {
+ };
+ #endif
+ 
++#ifdef __KERNEL__
++#ifdef CONFIG_COMPAT
++struct fb_image32 {
++	__u32 dx;			/* Where to place image */
++	__u32 dy;
++	__u32 width;			/* Size of image */
++	__u32 height;
++	__u32 fg_color;			/* Only used when a mono bitmap */
++	__u32 bg_color;
++	__u8  depth;			/* Depth of the image */
++	const compat_uptr_t data;	/* Pointer to image data */
++	struct fb_cmap32 cmap;		/* color map info */
++};
++
++#define fb_image_from_compat(to, from) \
++	(to).dx       = (from).dx; \
++	(to).dy       = (from).dy; \
++	(to).width    = (from).width; \
++	(to).height   = (from).height; \
++	(to).fg_color = (from).fg_color; \
++	(to).bg_color = (from).bg_color; \
++	(to).depth    = (from).depth; \
++	(to).data     = compat_ptr((from).data); \
++	fb_cmap_from_compat((to).cmap, (from).cmap)
++
++#endif /* CONFIG_COMPAT */
++#endif /* __KERNEL__ */
++
+ /*
+  * Frame buffer operations
+  *
+@@ -508,6 +536,9 @@ struct fb_info {
+ #define FBINFO_STATE_SUSPENDED	1
+ 	u32 state;			/* Hardware state i.e suspend */
+ 	void *fbcon_par;                /* fbcon use-only private area */
++
++	struct fb_image bgdecor;
++
+ 	/* From here on everything is device dependent */
+ 	void *par;
+ 	/* we need the PCI or similar aperture base/size not
+diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h
+index fb795c3..4b57c67 100644
+--- a/include/uapi/linux/fb.h
++++ b/include/uapi/linux/fb.h
+@@ -8,6 +8,23 @@
+ 
+ #define FB_MAX			32	/* sufficient for now */
+ 
++struct fbcon_decor_iowrapper {
++	unsigned short vc;		/* Virtual console */
++	unsigned char origin;		/* Point of origin of the request */
++	void *data;
++};
++
++#ifdef __KERNEL__
++#ifdef CONFIG_COMPAT
++#include <linux/compat.h>
++struct fbcon_decor_iowrapper32 {
++	unsigned short vc;		/* Virtual console */
++	unsigned char origin;		/* Point of origin of the request */
++	compat_uptr_t data;
++};
++#endif /* CONFIG_COMPAT */
++#endif /* __KERNEL__ */
++
+ /* ioctls
+    0x46 is 'F'								*/
+ #define FBIOGET_VSCREENINFO	0x4600
+@@ -35,6 +52,25 @@
+ #define FBIOGET_DISPINFO        0x4618
+ #define FBIO_WAITFORVSYNC	_IOW('F', 0x20, __u32)
+ 
++#define FBIOCONDECOR_SETCFG	_IOWR('F', 0x19, struct fbcon_decor_iowrapper)
++#define FBIOCONDECOR_GETCFG	_IOR('F', 0x1A, struct fbcon_decor_iowrapper)
++#define FBIOCONDECOR_SETSTATE	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
++#define FBIOCONDECOR_GETSTATE	_IOR('F', 0x1C, struct fbcon_decor_iowrapper)
++#define FBIOCONDECOR_SETPIC	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
++#ifdef __KERNEL__
++#ifdef CONFIG_COMPAT
++#define FBIOCONDECOR_SETCFG32	_IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
++#define FBIOCONDECOR_GETCFG32	_IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
++#define FBIOCONDECOR_SETSTATE32	_IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
++#define FBIOCONDECOR_GETSTATE32	_IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
++#define FBIOCONDECOR_SETPIC32	_IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
++#endif /* CONFIG_COMPAT */
++#endif /* __KERNEL__ */
++
++#define FBCON_DECOR_THEME_LEN		128	/* Maximum length of a theme name */
++#define FBCON_DECOR_IO_ORIG_KERNEL	0	/* Kernel ioctl origin */
++#define FBCON_DECOR_IO_ORIG_USER	1	/* User ioctl origin */
++
+ #define FB_TYPE_PACKED_PIXELS		0	/* Packed Pixels	*/
+ #define FB_TYPE_PLANES			1	/* Non interleaved planes */
+ #define FB_TYPE_INTERLEAVED_PLANES	2	/* Interleaved planes	*/
+@@ -277,6 +313,29 @@ struct fb_var_screeninfo {
+ 	__u32 reserved[4];		/* Reserved for future compatibility */
+ };
+ 
++#ifdef __KERNEL__
++#ifdef CONFIG_COMPAT
++struct fb_cmap32 {
++	__u32 start;
++	__u32 len;			/* Number of entries */
++	compat_uptr_t red;		/* Red values	*/
++	compat_uptr_t green;
++	compat_uptr_t blue;
++	compat_uptr_t transp;		/* transparency, can be NULL */
++};
++
++#define fb_cmap_from_compat(to, from) \
++	(to).start  = (from).start; \
++	(to).len    = (from).len; \
++	(to).red    = compat_ptr((from).red); \
++	(to).green  = compat_ptr((from).green); \
++	(to).blue   = compat_ptr((from).blue); \
++	(to).transp = compat_ptr((from).transp)
++
++#endif /* CONFIG_COMPAT */
++#endif /* __KERNEL__ */
++
++
+ struct fb_cmap {
+ 	__u32 start;			/* First entry	*/
+ 	__u32 len;			/* Number of entries */
+diff --git a/kernel/sysctl.c b/kernel/sysctl.c
+index 6ee416e..d2c2425 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -149,6 +149,10 @@ static const int cap_last_cap = CAP_LAST_CAP;
+ static unsigned long hung_task_timeout_max = (LONG_MAX/HZ);
+ #endif
+ 
++#ifdef CONFIG_FB_CON_DECOR
++extern char fbcon_decor_path[];
++#endif
++
+ #ifdef CONFIG_INOTIFY_USER
+ #include <linux/inotify.h>
+ #endif
+@@ -266,6 +270,15 @@ static struct ctl_table sysctl_base_table[] = {
+ 		.mode		= 0555,
+ 		.child		= dev_table,
+ 	},
++#ifdef CONFIG_FB_CON_DECOR
++	{
++		.procname	= "fbcondecor",
++		.data		= &fbcon_decor_path,
++		.maxlen		= KMOD_PATH_LEN,
++		.mode		= 0644,
++		.proc_handler	= &proc_dostring,
++	},
++#endif
+ 	{ }
+ };
+ 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-16 19:21 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-16 19:21 UTC (permalink / raw
  To: gentoo-commits

commit:     29a5a3247fd5e7a469a377914052a120ef0e4d05
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 16 19:21:08 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Oct 16 19:21:08 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=29a5a324

Linux patch 4.8.2

 0000_README            |    4 +
 1001_linux-4.8.2.patch | 1841 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1845 insertions(+)

diff --git a/0000_README b/0000_README
index 4af14fd..07a39ba 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch:  1000_linux-4.8.1.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.1
 
+Patch:  1001_linux-4.8.2.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.2
+
 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/1001_linux-4.8.2.patch b/1001_linux-4.8.2.patch
new file mode 100644
index 0000000..353b6a8
--- /dev/null
+++ b/1001_linux-4.8.2.patch
@@ -0,0 +1,1841 @@
+diff --git a/Documentation/virtual/kvm/devices/vcpu.txt b/Documentation/virtual/kvm/devices/vcpu.txt
+index c04165868faf..02f50686c418 100644
+--- a/Documentation/virtual/kvm/devices/vcpu.txt
++++ b/Documentation/virtual/kvm/devices/vcpu.txt
+@@ -30,4 +30,6 @@ Returns: -ENODEV: PMUv3 not supported
+                  attribute
+          -EBUSY: PMUv3 already initialized
+ 
+-Request the initialization of the PMUv3.
++Request the initialization of the PMUv3.  This must be done after creating the
++in-kernel irqchip.  Creating a PMU with a userspace irqchip is currently not
++supported.
+diff --git a/Makefile b/Makefile
+index 75db9f3988f3..bf6e44a421df 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/boot/dts/armada-390.dtsi b/arch/arm/boot/dts/armada-390.dtsi
+index 094e39c66039..6cd18d8aaac7 100644
+--- a/arch/arm/boot/dts/armada-390.dtsi
++++ b/arch/arm/boot/dts/armada-390.dtsi
+@@ -47,6 +47,8 @@
+ #include "armada-39x.dtsi"
+ 
+ / {
++	compatible = "marvell,armada390";
++
+ 	soc {
+ 		internal-regs {
+ 			pinctrl@18000 {
+@@ -54,4 +56,5 @@
+ 				reg = <0x18000 0x20>;
+ 			};
+ 		};
++	};
+ };
+diff --git a/arch/arm/boot/dts/qcom-apq8064.dtsi b/arch/arm/boot/dts/qcom-apq8064.dtsi
+index 74a9b6c394f5..9dc83b09d987 100644
+--- a/arch/arm/boot/dts/qcom-apq8064.dtsi
++++ b/arch/arm/boot/dts/qcom-apq8064.dtsi
+@@ -5,6 +5,7 @@
+ #include <dt-bindings/reset/qcom,gcc-msm8960.h>
+ #include <dt-bindings/clock/qcom,mmcc-msm8960.h>
+ #include <dt-bindings/soc/qcom,gsbi.h>
++#include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ / {
+ 	model = "Qualcomm APQ8064";
+@@ -559,22 +560,50 @@
+ 					compatible = "qcom,pm8921-gpio",
+ 						     "qcom,ssbi-gpio";
+ 					reg = <0x150>;
+-					interrupts = <192 1>, <193 1>, <194 1>,
+-						     <195 1>, <196 1>, <197 1>,
+-						     <198 1>, <199 1>, <200 1>,
+-						     <201 1>, <202 1>, <203 1>,
+-						     <204 1>, <205 1>, <206 1>,
+-						     <207 1>, <208 1>, <209 1>,
+-						     <210 1>, <211 1>, <212 1>,
+-						     <213 1>, <214 1>, <215 1>,
+-						     <216 1>, <217 1>, <218 1>,
+-						     <219 1>, <220 1>, <221 1>,
+-						     <222 1>, <223 1>, <224 1>,
+-						     <225 1>, <226 1>, <227 1>,
+-						     <228 1>, <229 1>, <230 1>,
+-						     <231 1>, <232 1>, <233 1>,
+-						     <234 1>, <235 1>;
+-
++					interrupts = <192 IRQ_TYPE_NONE>,
++						     <193 IRQ_TYPE_NONE>,
++						     <194 IRQ_TYPE_NONE>,
++						     <195 IRQ_TYPE_NONE>,
++						     <196 IRQ_TYPE_NONE>,
++						     <197 IRQ_TYPE_NONE>,
++						     <198 IRQ_TYPE_NONE>,
++						     <199 IRQ_TYPE_NONE>,
++						     <200 IRQ_TYPE_NONE>,
++						     <201 IRQ_TYPE_NONE>,
++						     <202 IRQ_TYPE_NONE>,
++						     <203 IRQ_TYPE_NONE>,
++						     <204 IRQ_TYPE_NONE>,
++						     <205 IRQ_TYPE_NONE>,
++						     <206 IRQ_TYPE_NONE>,
++						     <207 IRQ_TYPE_NONE>,
++						     <208 IRQ_TYPE_NONE>,
++						     <209 IRQ_TYPE_NONE>,
++						     <210 IRQ_TYPE_NONE>,
++						     <211 IRQ_TYPE_NONE>,
++						     <212 IRQ_TYPE_NONE>,
++						     <213 IRQ_TYPE_NONE>,
++						     <214 IRQ_TYPE_NONE>,
++						     <215 IRQ_TYPE_NONE>,
++						     <216 IRQ_TYPE_NONE>,
++						     <217 IRQ_TYPE_NONE>,
++						     <218 IRQ_TYPE_NONE>,
++						     <219 IRQ_TYPE_NONE>,
++						     <220 IRQ_TYPE_NONE>,
++						     <221 IRQ_TYPE_NONE>,
++						     <222 IRQ_TYPE_NONE>,
++						     <223 IRQ_TYPE_NONE>,
++						     <224 IRQ_TYPE_NONE>,
++						     <225 IRQ_TYPE_NONE>,
++						     <226 IRQ_TYPE_NONE>,
++						     <227 IRQ_TYPE_NONE>,
++						     <228 IRQ_TYPE_NONE>,
++						     <229 IRQ_TYPE_NONE>,
++						     <230 IRQ_TYPE_NONE>,
++						     <231 IRQ_TYPE_NONE>,
++						     <232 IRQ_TYPE_NONE>,
++						     <233 IRQ_TYPE_NONE>,
++						     <234 IRQ_TYPE_NONE>,
++						     <235 IRQ_TYPE_NONE>;
+ 					gpio-controller;
+ 					#gpio-cells = <2>;
+ 
+@@ -587,9 +616,18 @@
+ 					gpio-controller;
+ 					#gpio-cells = <2>;
+ 					interrupts =
+-					<128 1>, <129 1>, <130 1>, <131 1>,
+-					<132 1>, <133 1>, <134 1>, <135 1>,
+-					<136 1>, <137 1>, <138 1>, <139 1>;
++					<128 IRQ_TYPE_NONE>,
++					<129 IRQ_TYPE_NONE>,
++					<130 IRQ_TYPE_NONE>,
++					<131 IRQ_TYPE_NONE>,
++					<132 IRQ_TYPE_NONE>,
++					<133 IRQ_TYPE_NONE>,
++					<134 IRQ_TYPE_NONE>,
++					<135 IRQ_TYPE_NONE>,
++					<136 IRQ_TYPE_NONE>,
++					<137 IRQ_TYPE_NONE>,
++					<138 IRQ_TYPE_NONE>,
++					<139 IRQ_TYPE_NONE>;
+ 				};
+ 
+ 				rtc@11d {
+diff --git a/arch/arm/boot/dts/qcom-msm8660.dtsi b/arch/arm/boot/dts/qcom-msm8660.dtsi
+index acbe71febe13..8c65e0d82559 100644
+--- a/arch/arm/boot/dts/qcom-msm8660.dtsi
++++ b/arch/arm/boot/dts/qcom-msm8660.dtsi
+@@ -2,6 +2,7 @@
+ 
+ /include/ "skeleton.dtsi"
+ 
++#include <dt-bindings/interrupt-controller/irq.h>
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/clock/qcom,gcc-msm8660.h>
+ #include <dt-bindings/soc/qcom,gsbi.h>
+@@ -159,21 +160,50 @@
+ 						     "qcom,ssbi-gpio";
+ 					reg = <0x150>;
+ 					interrupt-parent = <&pmicintc>;
+-					interrupts = <192 1>, <193 1>, <194 1>,
+-						     <195 1>, <196 1>, <197 1>,
+-						     <198 1>, <199 1>, <200 1>,
+-						     <201 1>, <202 1>, <203 1>,
+-						     <204 1>, <205 1>, <206 1>,
+-						     <207 1>, <208 1>, <209 1>,
+-						     <210 1>, <211 1>, <212 1>,
+-						     <213 1>, <214 1>, <215 1>,
+-						     <216 1>, <217 1>, <218 1>,
+-						     <219 1>, <220 1>, <221 1>,
+-						     <222 1>, <223 1>, <224 1>,
+-						     <225 1>, <226 1>, <227 1>,
+-						     <228 1>, <229 1>, <230 1>,
+-						     <231 1>, <232 1>, <233 1>,
+-						     <234 1>, <235 1>;
++					interrupts = <192 IRQ_TYPE_NONE>,
++						     <193 IRQ_TYPE_NONE>,
++						     <194 IRQ_TYPE_NONE>,
++						     <195 IRQ_TYPE_NONE>,
++						     <196 IRQ_TYPE_NONE>,
++						     <197 IRQ_TYPE_NONE>,
++						     <198 IRQ_TYPE_NONE>,
++						     <199 IRQ_TYPE_NONE>,
++						     <200 IRQ_TYPE_NONE>,
++						     <201 IRQ_TYPE_NONE>,
++						     <202 IRQ_TYPE_NONE>,
++						     <203 IRQ_TYPE_NONE>,
++						     <204 IRQ_TYPE_NONE>,
++						     <205 IRQ_TYPE_NONE>,
++						     <206 IRQ_TYPE_NONE>,
++						     <207 IRQ_TYPE_NONE>,
++						     <208 IRQ_TYPE_NONE>,
++						     <209 IRQ_TYPE_NONE>,
++						     <210 IRQ_TYPE_NONE>,
++						     <211 IRQ_TYPE_NONE>,
++						     <212 IRQ_TYPE_NONE>,
++						     <213 IRQ_TYPE_NONE>,
++						     <214 IRQ_TYPE_NONE>,
++						     <215 IRQ_TYPE_NONE>,
++						     <216 IRQ_TYPE_NONE>,
++						     <217 IRQ_TYPE_NONE>,
++						     <218 IRQ_TYPE_NONE>,
++						     <219 IRQ_TYPE_NONE>,
++						     <220 IRQ_TYPE_NONE>,
++						     <221 IRQ_TYPE_NONE>,
++						     <222 IRQ_TYPE_NONE>,
++						     <223 IRQ_TYPE_NONE>,
++						     <224 IRQ_TYPE_NONE>,
++						     <225 IRQ_TYPE_NONE>,
++						     <226 IRQ_TYPE_NONE>,
++						     <227 IRQ_TYPE_NONE>,
++						     <228 IRQ_TYPE_NONE>,
++						     <229 IRQ_TYPE_NONE>,
++						     <230 IRQ_TYPE_NONE>,
++						     <231 IRQ_TYPE_NONE>,
++						     <232 IRQ_TYPE_NONE>,
++						     <233 IRQ_TYPE_NONE>,
++						     <234 IRQ_TYPE_NONE>,
++						     <235 IRQ_TYPE_NONE>;
+ 					gpio-controller;
+ 					#gpio-cells = <2>;
+ 
+@@ -187,9 +217,18 @@
+ 					#gpio-cells = <2>;
+ 					interrupt-parent = <&pmicintc>;
+ 					interrupts =
+-					<128 1>, <129 1>, <130 1>, <131 1>,
+-					<132 1>, <133 1>, <134 1>, <135 1>,
+-					<136 1>, <137 1>, <138 1>, <139 1>;
++					<128 IRQ_TYPE_NONE>,
++					<129 IRQ_TYPE_NONE>,
++					<130 IRQ_TYPE_NONE>,
++					<131 IRQ_TYPE_NONE>,
++					<132 IRQ_TYPE_NONE>,
++					<133 IRQ_TYPE_NONE>,
++					<134 IRQ_TYPE_NONE>,
++					<135 IRQ_TYPE_NONE>,
++					<136 IRQ_TYPE_NONE>,
++					<137 IRQ_TYPE_NONE>,
++					<138 IRQ_TYPE_NONE>,
++					<139 IRQ_TYPE_NONE>;
+ 				};
+ 
+ 				pwrkey@1c {
+diff --git a/arch/arm/include/asm/delay.h b/arch/arm/include/asm/delay.h
+index b7a428154355..b1ce037e4380 100644
+--- a/arch/arm/include/asm/delay.h
++++ b/arch/arm/include/asm/delay.h
+@@ -10,7 +10,7 @@
+ #include <asm/param.h>	/* HZ */
+ 
+ #define MAX_UDELAY_MS	2
+-#define UDELAY_MULT	UL(2047 * HZ + 483648 * HZ / 1000000)
++#define UDELAY_MULT	UL(2147 * HZ + 483648 * HZ / 1000000)
+ #define UDELAY_SHIFT	31
+ 
+ #ifndef __ASSEMBLY__
+diff --git a/arch/arm64/kernel/stacktrace.c b/arch/arm64/kernel/stacktrace.c
+index d9751a4769e7..d34fd72172b6 100644
+--- a/arch/arm64/kernel/stacktrace.c
++++ b/arch/arm64/kernel/stacktrace.c
+@@ -43,6 +43,9 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+ 	unsigned long fp = frame->fp;
+ 	unsigned long irq_stack_ptr;
+ 
++	if (!tsk)
++		tsk = current;
++
+ 	/*
+ 	 * Switching between stacks is valid when tracing current and in
+ 	 * non-preemptible context.
+@@ -67,7 +70,7 @@ int notrace unwind_frame(struct task_struct *tsk, struct stackframe *frame)
+ 	frame->pc = READ_ONCE_NOCHECK(*(unsigned long *)(fp + 8));
+ 
+ #ifdef CONFIG_FUNCTION_GRAPH_TRACER
+-	if (tsk && tsk->ret_stack &&
++	if (tsk->ret_stack &&
+ 			(frame->pc == (unsigned long)return_to_handler)) {
+ 		/*
+ 		 * This is a case where function graph tracer has
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index e04f83873af7..df06750846de 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -142,6 +142,11 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+ 	unsigned long irq_stack_ptr;
+ 	int skip;
+ 
++	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
++
++	if (!tsk)
++		tsk = current;
++
+ 	/*
+ 	 * Switching between stacks is valid when tracing current and in
+ 	 * non-preemptible context.
+@@ -151,11 +156,6 @@ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+ 	else
+ 		irq_stack_ptr = 0;
+ 
+-	pr_debug("%s(regs = %p tsk = %p)\n", __func__, regs, tsk);
+-
+-	if (!tsk)
+-		tsk = current;
+-
+ 	if (tsk == current) {
+ 		frame.fp = (unsigned long)__builtin_frame_address(0);
+ 		frame.sp = current_stack_pointer;
+diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
+index e788515f766b..43853ec6e160 100644
+--- a/arch/mips/kvm/emulate.c
++++ b/arch/mips/kvm/emulate.c
+@@ -846,6 +846,47 @@ enum emulation_result kvm_mips_emul_tlbr(struct kvm_vcpu *vcpu)
+ 	return EMULATE_FAIL;
+ }
+ 
++/**
++ * kvm_mips_invalidate_guest_tlb() - Indicates a change in guest MMU map.
++ * @vcpu:	VCPU with changed mappings.
++ * @tlb:	TLB entry being removed.
++ *
++ * This is called to indicate a single change in guest MMU mappings, so that we
++ * can arrange TLB flushes on this and other CPUs.
++ */
++static void kvm_mips_invalidate_guest_tlb(struct kvm_vcpu *vcpu,
++					  struct kvm_mips_tlb *tlb)
++{
++	int cpu, i;
++	bool user;
++
++	/* No need to flush for entries which are already invalid */
++	if (!((tlb->tlb_lo[0] | tlb->tlb_lo[1]) & ENTRYLO_V))
++		return;
++	/* User address space doesn't need flushing for KSeg2/3 changes */
++	user = tlb->tlb_hi < KVM_GUEST_KSEG0;
++
++	preempt_disable();
++
++	/*
++	 * Probe the shadow host TLB for the entry being overwritten, if one
++	 * matches, invalidate it
++	 */
++	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++
++	/* Invalidate the whole ASID on other CPUs */
++	cpu = smp_processor_id();
++	for_each_possible_cpu(i) {
++		if (i == cpu)
++			continue;
++		if (user)
++			vcpu->arch.guest_user_asid[i] = 0;
++		vcpu->arch.guest_kernel_asid[i] = 0;
++	}
++
++	preempt_enable();
++}
++
+ /* Write Guest TLB Entry @ Index */
+ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
+ {
+@@ -865,11 +906,8 @@ enum emulation_result kvm_mips_emul_tlbwi(struct kvm_vcpu *vcpu)
+ 	}
+ 
+ 	tlb = &vcpu->arch.guest_tlb[index];
+-	/*
+-	 * Probe the shadow host TLB for the entry being overwritten, if one
+-	 * matches, invalidate it
+-	 */
+-	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++
++	kvm_mips_invalidate_guest_tlb(vcpu, tlb);
+ 
+ 	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
+ 	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
+@@ -898,11 +936,7 @@ enum emulation_result kvm_mips_emul_tlbwr(struct kvm_vcpu *vcpu)
+ 
+ 	tlb = &vcpu->arch.guest_tlb[index];
+ 
+-	/*
+-	 * Probe the shadow host TLB for the entry being overwritten, if one
+-	 * matches, invalidate it
+-	 */
+-	kvm_mips_host_tlb_inv(vcpu, tlb->tlb_hi);
++	kvm_mips_invalidate_guest_tlb(vcpu, tlb);
+ 
+ 	tlb->tlb_mask = kvm_read_c0_guest_pagemask(cop0);
+ 	tlb->tlb_hi = kvm_read_c0_guest_entryhi(cop0);
+@@ -1026,6 +1060,7 @@ enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
+ 	enum emulation_result er = EMULATE_DONE;
+ 	u32 rt, rd, sel;
+ 	unsigned long curr_pc;
++	int cpu, i;
+ 
+ 	/*
+ 	 * Update PC and hold onto current PC in case there is
+@@ -1135,8 +1170,16 @@ enum emulation_result kvm_mips_emulate_CP0(union mips_instruction inst,
+ 							& KVM_ENTRYHI_ASID,
+ 						nasid);
+ 
++					preempt_disable();
+ 					/* Blow away the shadow host TLBs */
+ 					kvm_mips_flush_host_tlb(1);
++					cpu = smp_processor_id();
++					for_each_possible_cpu(i)
++						if (i != cpu) {
++							vcpu->arch.guest_user_asid[i] = 0;
++							vcpu->arch.guest_kernel_asid[i] = 0;
++						}
++					preempt_enable();
+ 				}
+ 				kvm_write_c0_guest_entryhi(cop0,
+ 							   vcpu->arch.gprs[rt]);
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index f69f40f1519a..978dada662ae 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -737,6 +737,7 @@
+ #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
+ #define SPRN_MMCR1	798
+ #define SPRN_MMCR2	785
++#define SPRN_UMMCR2	769
+ #define SPRN_MMCRA	0x312
+ #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
+ #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
+diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
+index 2afdb9c0937d..729f8faa95c5 100644
+--- a/arch/powerpc/kvm/book3s_emulate.c
++++ b/arch/powerpc/kvm/book3s_emulate.c
+@@ -498,6 +498,7 @@ int kvmppc_core_emulate_mtspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong spr_val)
+ 	case SPRN_MMCR0:
+ 	case SPRN_MMCR1:
+ 	case SPRN_MMCR2:
++	case SPRN_UMMCR2:
+ #endif
+ 		break;
+ unprivileged:
+@@ -640,6 +641,7 @@ int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu, int sprn, ulong *spr_val
+ 	case SPRN_MMCR0:
+ 	case SPRN_MMCR1:
+ 	case SPRN_MMCR2:
++	case SPRN_UMMCR2:
+ 	case SPRN_TIR:
+ #endif
+ 		*spr_val = 0;
+diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c
+index 02b4672f7347..df3f2706d3e5 100644
+--- a/arch/powerpc/kvm/booke.c
++++ b/arch/powerpc/kvm/booke.c
+@@ -2038,7 +2038,7 @@ int kvm_arch_vcpu_ioctl_set_guest_debug(struct kvm_vcpu *vcpu,
+ 		if (type == KVMPPC_DEBUG_NONE)
+ 			continue;
+ 
+-		if (type & !(KVMPPC_DEBUG_WATCH_READ |
++		if (type & ~(KVMPPC_DEBUG_WATCH_READ |
+ 			     KVMPPC_DEBUG_WATCH_WRITE |
+ 			     KVMPPC_DEBUG_BREAKPOINT))
+ 			return -EINVAL;
+diff --git a/arch/x86/include/asm/fpu/xstate.h b/arch/x86/include/asm/fpu/xstate.h
+index ae55a43e09c0..19f30a814f54 100644
+--- a/arch/x86/include/asm/fpu/xstate.h
++++ b/arch/x86/include/asm/fpu/xstate.h
+@@ -27,11 +27,12 @@
+ 				 XFEATURE_MASK_YMM | \
+ 				 XFEATURE_MASK_OPMASK | \
+ 				 XFEATURE_MASK_ZMM_Hi256 | \
+-				 XFEATURE_MASK_Hi16_ZMM	 | \
+-				 XFEATURE_MASK_PKRU)
++				 XFEATURE_MASK_Hi16_ZMM)
+ 
+ /* Supported features which require eager state saving */
+-#define XFEATURE_MASK_EAGER	(XFEATURE_MASK_BNDREGS | XFEATURE_MASK_BNDCSR)
++#define XFEATURE_MASK_EAGER	(XFEATURE_MASK_BNDREGS | \
++				 XFEATURE_MASK_BNDCSR | \
++				 XFEATURE_MASK_PKRU)
+ 
+ /* All currently supported features */
+ #define XCNTXT_MASK	(XFEATURE_MASK_LAZY | XFEATURE_MASK_EAGER)
+diff --git a/arch/x86/include/asm/intel-family.h b/arch/x86/include/asm/intel-family.h
+index 627719475457..9ae5ab80a497 100644
+--- a/arch/x86/include/asm/intel-family.h
++++ b/arch/x86/include/asm/intel-family.h
+@@ -56,8 +56,8 @@
+ #define INTEL_FAM6_ATOM_SILVERMONT1	0x37 /* BayTrail/BYT / Valleyview */
+ #define INTEL_FAM6_ATOM_SILVERMONT2	0x4D /* Avaton/Rangely */
+ #define INTEL_FAM6_ATOM_AIRMONT		0x4C /* CherryTrail / Braswell */
+-#define INTEL_FAM6_ATOM_MERRIFIELD1	0x4A /* Tangier */
+-#define INTEL_FAM6_ATOM_MERRIFIELD2	0x5A /* Annidale */
++#define INTEL_FAM6_ATOM_MERRIFIELD	0x4A /* Tangier */
++#define INTEL_FAM6_ATOM_MOOREFIELD	0x5A /* Annidale */
+ #define INTEL_FAM6_ATOM_GOLDMONT	0x5C
+ #define INTEL_FAM6_ATOM_DENVERTON	0x5F /* Goldmont Microserver */
+ 
+diff --git a/arch/x86/include/asm/mpspec.h b/arch/x86/include/asm/mpspec.h
+index b07233b64578..c2f94dcc92ce 100644
+--- a/arch/x86/include/asm/mpspec.h
++++ b/arch/x86/include/asm/mpspec.h
+@@ -6,7 +6,6 @@
+ #include <asm/x86_init.h>
+ #include <asm/apicdef.h>
+ 
+-extern int apic_version[];
+ extern int pic_mode;
+ 
+ #ifdef CONFIG_X86_32
+@@ -40,6 +39,7 @@ extern int mp_bus_id_to_type[MAX_MP_BUSSES];
+ extern DECLARE_BITMAP(mp_bus_not_pci, MAX_MP_BUSSES);
+ 
+ extern unsigned int boot_cpu_physical_apicid;
++extern u8 boot_cpu_apic_version;
+ extern unsigned long mp_lapic_addr;
+ 
+ #ifdef CONFIG_X86_LOCAL_APIC
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index 90d84c3eee53..fbd19444403f 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -182,7 +182,7 @@ static int acpi_register_lapic(int id, u32 acpiid, u8 enabled)
+ 	}
+ 
+ 	if (boot_cpu_physical_apicid != -1U)
+-		ver = apic_version[boot_cpu_physical_apicid];
++		ver = boot_cpu_apic_version;
+ 
+ 	cpu = generic_processor_info(id, ver);
+ 	if (cpu >= 0)
+diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
+index f3e9b2df4b16..076c315cdf18 100644
+--- a/arch/x86/kernel/apic/apic.c
++++ b/arch/x86/kernel/apic/apic.c
+@@ -64,6 +64,8 @@ unsigned disabled_cpus;
+ unsigned int boot_cpu_physical_apicid = -1U;
+ EXPORT_SYMBOL_GPL(boot_cpu_physical_apicid);
+ 
++u8 boot_cpu_apic_version;
++
+ /*
+  * The highest APIC ID seen during enumeration.
+  */
+@@ -1816,8 +1818,7 @@ void __init init_apic_mappings(void)
+ 		 * since smp_sanity_check is prepared for such a case
+ 		 * and disable smp mode
+ 		 */
+-		apic_version[new_apicid] =
+-			 GET_APIC_VERSION(apic_read(APIC_LVR));
++		boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR));
+ 	}
+ }
+ 
+@@ -1832,13 +1833,10 @@ void __init register_lapic_address(unsigned long address)
+ 	}
+ 	if (boot_cpu_physical_apicid == -1U) {
+ 		boot_cpu_physical_apicid  = read_apic_id();
+-		apic_version[boot_cpu_physical_apicid] =
+-			 GET_APIC_VERSION(apic_read(APIC_LVR));
++		boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR));
+ 	}
+ }
+ 
+-int apic_version[MAX_LOCAL_APIC];
+-
+ /*
+  * Local APIC interrupts
+  */
+@@ -2130,11 +2128,10 @@ int generic_processor_info(int apicid, int version)
+ 			   cpu, apicid);
+ 		version = 0x10;
+ 	}
+-	apic_version[apicid] = version;
+ 
+-	if (version != apic_version[boot_cpu_physical_apicid]) {
++	if (version != boot_cpu_apic_version) {
+ 		pr_warning("BIOS bug: APIC version mismatch, boot CPU: %x, CPU %d: version %x\n",
+-			apic_version[boot_cpu_physical_apicid], cpu, version);
++			boot_cpu_apic_version, cpu, version);
+ 	}
+ 
+ 	physid_set(apicid, phys_cpu_present_map);
+@@ -2277,7 +2274,7 @@ int __init APIC_init_uniprocessor(void)
+ 	 * Complain if the BIOS pretends there is one.
+ 	 */
+ 	if (!boot_cpu_has(X86_FEATURE_APIC) &&
+-	    APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
++	    APIC_INTEGRATED(boot_cpu_apic_version)) {
+ 		pr_err("BIOS bug, local APIC 0x%x not detected!...\n",
+ 			boot_cpu_physical_apicid);
+ 		return -1;
+diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
+index 7491f417a8e4..48e6d84f173e 100644
+--- a/arch/x86/kernel/apic/io_apic.c
++++ b/arch/x86/kernel/apic/io_apic.c
+@@ -1593,7 +1593,7 @@ void __init setup_ioapic_ids_from_mpc(void)
+ 	 * no meaning without the serial APIC bus.
+ 	 */
+ 	if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL)
+-		|| APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
++		|| APIC_XAPIC(boot_cpu_apic_version))
+ 		return;
+ 	setup_ioapic_ids_from_mpc_nocheck();
+ }
+@@ -2423,7 +2423,7 @@ static int io_apic_get_unique_id(int ioapic, int apic_id)
+ static u8 io_apic_unique_id(int idx, u8 id)
+ {
+ 	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
+-	    !APIC_XAPIC(apic_version[boot_cpu_physical_apicid]))
++	    !APIC_XAPIC(boot_cpu_apic_version))
+ 		return io_apic_get_unique_id(idx, id);
+ 	else
+ 		return id;
+diff --git a/arch/x86/kernel/apic/probe_32.c b/arch/x86/kernel/apic/probe_32.c
+index 7c43e716c158..563096267ca2 100644
+--- a/arch/x86/kernel/apic/probe_32.c
++++ b/arch/x86/kernel/apic/probe_32.c
+@@ -152,7 +152,7 @@ early_param("apic", parse_apic);
+ 
+ void __init default_setup_apic_routing(void)
+ {
+-	int version = apic_version[boot_cpu_physical_apicid];
++	int version = boot_cpu_apic_version;
+ 
+ 	if (num_possible_cpus() > 8) {
+ 		switch (boot_cpu_data.x86_vendor) {
+diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
+index 6066d945c40e..5d30c5e42bb1 100644
+--- a/arch/x86/kernel/apic/vector.c
++++ b/arch/x86/kernel/apic/vector.c
+@@ -661,11 +661,28 @@ void irq_complete_move(struct irq_cfg *cfg)
+  */
+ void irq_force_complete_move(struct irq_desc *desc)
+ {
+-	struct irq_data *irqdata = irq_desc_get_irq_data(desc);
+-	struct apic_chip_data *data = apic_chip_data(irqdata);
+-	struct irq_cfg *cfg = data ? &data->cfg : NULL;
++	struct irq_data *irqdata;
++	struct apic_chip_data *data;
++	struct irq_cfg *cfg;
+ 	unsigned int cpu;
+ 
++	/*
++	 * The function is called for all descriptors regardless of which
++	 * irqdomain they belong to. For example if an IRQ is provided by
++	 * an irq_chip as part of a GPIO driver, the chip data for that
++	 * descriptor is specific to the irq_chip in question.
++	 *
++	 * Check first that the chip_data is what we expect
++	 * (apic_chip_data) before touching it any further.
++	 */
++	irqdata = irq_domain_get_irq_data(x86_vector_domain,
++					  irq_desc_get_irq(desc));
++	if (!irqdata)
++		return;
++
++	data = apic_chip_data(irqdata);
++	cfg = data ? &data->cfg : NULL;
++
+ 	if (!cfg)
+ 		return;
+ 
+diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
+index 621b501f8935..8a90f1517837 100644
+--- a/arch/x86/kernel/e820.c
++++ b/arch/x86/kernel/e820.c
+@@ -348,7 +348,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+ 		 * continue building up new bios map based on this
+ 		 * information
+ 		 */
+-		if (current_type != last_type || current_type == E820_PRAM) {
++		if (current_type != last_type) {
+ 			if (last_type != 0)	 {
+ 				new_bios[new_bios_entry].size =
+ 					change_point[chgidx]->addr - last_addr;
+@@ -754,7 +754,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
+ /*
+  * Find the highest page frame number we have available
+  */
+-static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
++static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
+ {
+ 	int i;
+ 	unsigned long last_pfn = 0;
+@@ -765,11 +765,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
+ 		unsigned long start_pfn;
+ 		unsigned long end_pfn;
+ 
+-		/*
+-		 * Persistent memory is accounted as ram for purposes of
+-		 * establishing max_pfn and mem_map.
+-		 */
+-		if (ei->type != E820_RAM && ei->type != E820_PRAM)
++		if (ei->type != type)
+ 			continue;
+ 
+ 		start_pfn = ei->addr >> PAGE_SHIFT;
+@@ -794,12 +790,12 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn)
+ }
+ unsigned long __init e820_end_of_ram_pfn(void)
+ {
+-	return e820_end_pfn(MAX_ARCH_PFN);
++	return e820_end_pfn(MAX_ARCH_PFN, E820_RAM);
+ }
+ 
+ unsigned long __init e820_end_of_low_ram_pfn(void)
+ {
+-	return e820_end_pfn(1UL << (32-PAGE_SHIFT));
++	return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_RAM);
+ }
+ 
+ static void early_panic(char *msg)
+diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
+index 63236d8f84bf..a21068e49dac 100644
+--- a/arch/x86/kernel/process_64.c
++++ b/arch/x86/kernel/process_64.c
+@@ -110,12 +110,13 @@ void __show_regs(struct pt_regs *regs, int all)
+ 	get_debugreg(d7, 7);
+ 
+ 	/* Only print out debug registers if they are in their non-default state. */
+-	if ((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
+-	    (d6 == DR6_RESERVED) && (d7 == 0x400))
+-		return;
+-
+-	printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n", d0, d1, d2);
+-	printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n", d3, d6, d7);
++	if (!((d0 == 0) && (d1 == 0) && (d2 == 0) && (d3 == 0) &&
++	    (d6 == DR6_RESERVED) && (d7 == 0x400))) {
++		printk(KERN_DEFAULT "DR0: %016lx DR1: %016lx DR2: %016lx\n",
++		       d0, d1, d2);
++		printk(KERN_DEFAULT "DR3: %016lx DR6: %016lx DR7: %016lx\n",
++		       d3, d6, d7);
++	}
+ 
+ 	if (boot_cpu_has(X86_FEATURE_OSPKE))
+ 		printk(KERN_DEFAULT "PKRU: %08x\n", read_pkru());
+diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
+index f79576a541ff..a1606eadd9ce 100644
+--- a/arch/x86/kernel/ptrace.c
++++ b/arch/x86/kernel/ptrace.c
+@@ -173,8 +173,8 @@ unsigned long kernel_stack_pointer(struct pt_regs *regs)
+ 		return sp;
+ 
+ 	prev_esp = (u32 *)(context);
+-	if (prev_esp)
+-		return (unsigned long)prev_esp;
++	if (*prev_esp)
++		return (unsigned long)*prev_esp;
+ 
+ 	return (unsigned long)regs;
+ }
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index 4296beb8fdd3..82b17373b66a 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -690,7 +690,7 @@ wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip)
+ 	 * Give the other CPU some time to accept the IPI.
+ 	 */
+ 	udelay(200);
+-	if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
++	if (APIC_INTEGRATED(boot_cpu_apic_version)) {
+ 		maxlvt = lapic_get_maxlvt();
+ 		if (maxlvt > 3)			/* Due to the Pentium erratum 3AP.  */
+ 			apic_write(APIC_ESR, 0);
+@@ -717,7 +717,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
+ 	/*
+ 	 * Be paranoid about clearing APIC errors.
+ 	 */
+-	if (APIC_INTEGRATED(apic_version[phys_apicid])) {
++	if (APIC_INTEGRATED(boot_cpu_apic_version)) {
+ 		if (maxlvt > 3)		/* Due to the Pentium erratum 3AP.  */
+ 			apic_write(APIC_ESR, 0);
+ 		apic_read(APIC_ESR);
+@@ -756,7 +756,7 @@ wakeup_secondary_cpu_via_init(int phys_apicid, unsigned long start_eip)
+ 	 * Determine this based on the APIC version.
+ 	 * If we don't have an integrated APIC, don't send the STARTUP IPIs.
+ 	 */
+-	if (APIC_INTEGRATED(apic_version[phys_apicid]))
++	if (APIC_INTEGRATED(boot_cpu_apic_version))
+ 		num_starts = 2;
+ 	else
+ 		num_starts = 0;
+@@ -994,7 +994,7 @@ static int do_boot_cpu(int apicid, int cpu, struct task_struct *idle)
+ 		/*
+ 		 * Be paranoid about clearing APIC errors.
+ 		*/
+-		if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid])) {
++		if (APIC_INTEGRATED(boot_cpu_apic_version)) {
+ 			apic_write(APIC_ESR, 0);
+ 			apic_read(APIC_ESR);
+ 		}
+@@ -1249,7 +1249,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
+ 	/*
+ 	 * If we couldn't find a local APIC, then get out of here now!
+ 	 */
+-	if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) &&
++	if (APIC_INTEGRATED(boot_cpu_apic_version) &&
+ 	    !boot_cpu_has(X86_FEATURE_APIC)) {
+ 		if (!disable_apic) {
+ 			pr_err("BIOS bug, local APIC #%d not detected!...\n",
+@@ -1406,9 +1406,21 @@ __init void prefill_possible_map(void)
+ {
+ 	int i, possible;
+ 
+-	/* no processor from mptable or madt */
+-	if (!num_processors)
+-		num_processors = 1;
++	/* No boot processor was found in mptable or ACPI MADT */
++	if (!num_processors) {
++		int apicid = boot_cpu_physical_apicid;
++		int cpu = hard_smp_processor_id();
++
++		pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu);
++
++		/* Make sure boot cpu is enumerated */
++		if (apic->cpu_present_to_apicid(0) == BAD_APICID &&
++		    apic->apic_id_valid(apicid))
++			generic_processor_info(apicid, boot_cpu_apic_version);
++
++		if (!num_processors)
++			num_processors = 1;
++	}
+ 
+ 	i = setup_max_cpus ?: 1;
+ 	if (setup_possible_cpus == -1) {
+diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c
+index 8ff7b9355416..d49d3be81953 100644
+--- a/arch/x86/platform/atom/punit_atom_debug.c
++++ b/arch/x86/platform/atom/punit_atom_debug.c
+@@ -155,7 +155,7 @@ static void punit_dbgfs_unregister(void)
+ 
+ static const struct x86_cpu_id intel_punit_cpu_ids[] = {
+ 	ICPU(INTEL_FAM6_ATOM_SILVERMONT1, punit_device_byt),
+-	ICPU(INTEL_FAM6_ATOM_MERRIFIELD1, punit_device_tng),
++	ICPU(INTEL_FAM6_ATOM_MERRIFIELD,  punit_device_tng),
+ 	ICPU(INTEL_FAM6_ATOM_AIRMONT,	  punit_device_cht),
+ 	{}
+ };
+diff --git a/arch/x86/platform/intel-mid/pwr.c b/arch/x86/platform/intel-mid/pwr.c
+index c901a3423772..6eca0f6fe57d 100644
+--- a/arch/x86/platform/intel-mid/pwr.c
++++ b/arch/x86/platform/intel-mid/pwr.c
+@@ -354,7 +354,7 @@ static int mid_pwr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	return 0;
+ }
+ 
+-static int mid_set_initial_state(struct mid_pwr *pwr)
++static int mid_set_initial_state(struct mid_pwr *pwr, const u32 *states)
+ {
+ 	unsigned int i, j;
+ 	int ret;
+@@ -379,10 +379,10 @@ static int mid_set_initial_state(struct mid_pwr *pwr)
+ 	 * NOTE: The actual device mapping is provided by a platform at run
+ 	 * time using vendor capability of PCI configuration space.
+ 	 */
+-	mid_pwr_set_state(pwr, 0, 0xffffffff);
+-	mid_pwr_set_state(pwr, 1, 0xffffffff);
+-	mid_pwr_set_state(pwr, 2, 0xffffffff);
+-	mid_pwr_set_state(pwr, 3, 0xffffffff);
++	mid_pwr_set_state(pwr, 0, states[0]);
++	mid_pwr_set_state(pwr, 1, states[1]);
++	mid_pwr_set_state(pwr, 2, states[2]);
++	mid_pwr_set_state(pwr, 3, states[3]);
+ 
+ 	/* Send command to SCU */
+ 	ret = mid_pwr_wait_for_cmd(pwr, CMD_SET_CFG);
+@@ -397,13 +397,41 @@ static int mid_set_initial_state(struct mid_pwr *pwr)
+ 	return 0;
+ }
+ 
+-static const struct mid_pwr_device_info mid_info = {
+-	.set_initial_state = mid_set_initial_state,
++static int pnw_set_initial_state(struct mid_pwr *pwr)
++{
++	/* On Penwell SRAM must stay powered on */
++	const u32 states[] = {
++		0xf00fffff,		/* PM_SSC(0) */
++		0xffffffff,		/* PM_SSC(1) */
++		0xffffffff,		/* PM_SSC(2) */
++		0xffffffff,		/* PM_SSC(3) */
++	};
++	return mid_set_initial_state(pwr, states);
++}
++
++static int tng_set_initial_state(struct mid_pwr *pwr)
++{
++	const u32 states[] = {
++		0xffffffff,		/* PM_SSC(0) */
++		0xffffffff,		/* PM_SSC(1) */
++		0xffffffff,		/* PM_SSC(2) */
++		0xffffffff,		/* PM_SSC(3) */
++	};
++	return mid_set_initial_state(pwr, states);
++}
++
++static const struct mid_pwr_device_info pnw_info = {
++	.set_initial_state = pnw_set_initial_state,
++};
++
++static const struct mid_pwr_device_info tng_info = {
++	.set_initial_state = tng_set_initial_state,
+ };
+ 
++/* This table should be in sync with the one in drivers/pci/pci-mid.c */
+ static const struct pci_device_id mid_pwr_pci_ids[] = {
+-	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PENWELL), (kernel_ulong_t)&mid_info },
+-	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_TANGIER), (kernel_ulong_t)&mid_info },
++	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_PENWELL), (kernel_ulong_t)&pnw_info },
++	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_TANGIER), (kernel_ulong_t)&tng_info },
+ 	{}
+ };
+ 
+diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
+index 0b4d04c8ab4d..62284035be84 100644
+--- a/arch/x86/xen/smp.c
++++ b/arch/x86/xen/smp.c
+@@ -87,6 +87,12 @@ static void cpu_bringup(void)
+ 	cpu_data(cpu).x86_max_cores = 1;
+ 	set_cpu_sibling_map(cpu);
+ 
++	/*
++	 * identify_cpu() may have set logical_pkg_id to -1 due
++	 * to incorrect phys_proc_id. Let's re-comupte it.
++	 */
++	topology_update_package_map(apic->cpu_present_to_apicid(cpu), cpu);
++
+ 	xen_setup_cpu_clockevents();
+ 
+ 	notify_cpu_starting(cpu);
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
+index 811f9b97e360..d4d55f60cd81 100644
+--- a/drivers/bluetooth/btusb.c
++++ b/drivers/bluetooth/btusb.c
+@@ -251,6 +251,7 @@ static const struct usb_device_id blacklist_table[] = {
+ 	{ USB_DEVICE(0x0cf3, 0xe300), .driver_info = BTUSB_QCA_ROME },
+ 	{ USB_DEVICE(0x0cf3, 0xe360), .driver_info = BTUSB_QCA_ROME },
+ 	{ USB_DEVICE(0x0489, 0xe092), .driver_info = BTUSB_QCA_ROME },
++	{ USB_DEVICE(0x04ca, 0x3011), .driver_info = BTUSB_QCA_ROME },
+ 
+ 	/* Broadcom BCM2035 */
+ 	{ USB_DEVICE(0x0a5c, 0x2009), .driver_info = BTUSB_BCM92035 },
+diff --git a/drivers/char/tpm/tpm-dev.c b/drivers/char/tpm/tpm-dev.c
+index f5d452151c6b..912ad30be585 100644
+--- a/drivers/char/tpm/tpm-dev.c
++++ b/drivers/char/tpm/tpm-dev.c
+@@ -145,7 +145,7 @@ static ssize_t tpm_write(struct file *file, const char __user *buf,
+ 		return -EPIPE;
+ 	}
+ 	out_size = tpm_transmit(priv->chip, priv->data_buffer,
+-				sizeof(priv->data_buffer));
++				sizeof(priv->data_buffer), 0);
+ 
+ 	tpm_put_ops(priv->chip);
+ 	if (out_size < 0) {
+diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
+index 1abe2d7a2610..aef20ee2331a 100644
+--- a/drivers/char/tpm/tpm-interface.c
++++ b/drivers/char/tpm/tpm-interface.c
+@@ -330,8 +330,8 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
+ /*
+  * Internal kernel interface to transmit TPM commands
+  */
+-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+-		     size_t bufsiz)
++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
++		     unsigned int flags)
+ {
+ 	ssize_t rc;
+ 	u32 count, ordinal;
+@@ -350,7 +350,8 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+ 		return -E2BIG;
+ 	}
+ 
+-	mutex_lock(&chip->tpm_mutex);
++	if (!(flags & TPM_TRANSMIT_UNLOCKED))
++		mutex_lock(&chip->tpm_mutex);
+ 
+ 	rc = chip->ops->send(chip, (u8 *) buf, count);
+ 	if (rc < 0) {
+@@ -393,20 +394,21 @@ out_recv:
+ 		dev_err(&chip->dev,
+ 			"tpm_transmit: tpm_recv: error %zd\n", rc);
+ out:
+-	mutex_unlock(&chip->tpm_mutex);
++	if (!(flags & TPM_TRANSMIT_UNLOCKED))
++		mutex_unlock(&chip->tpm_mutex);
+ 	return rc;
+ }
+ 
+ #define TPM_DIGEST_SIZE 20
+ #define TPM_RET_CODE_IDX 6
+ 
+-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd,
+-			 int len, const char *desc)
++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd,
++			 int len, unsigned int flags, const char *desc)
+ {
+-	struct tpm_output_header *header;
++	const struct tpm_output_header *header;
+ 	int err;
+ 
+-	len = tpm_transmit(chip, (u8 *) cmd, len);
++	len = tpm_transmit(chip, (const u8 *)cmd, len, flags);
+ 	if (len <  0)
+ 		return len;
+ 	else if (len < TPM_HEADER_SIZE)
+@@ -453,7 +455,8 @@ ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
+ 		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 		tpm_cmd.params.getcap_in.subcap = subcap_id;
+ 	}
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, desc);
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
++			      desc);
+ 	if (!rc)
+ 		*cap = tpm_cmd.params.getcap_out.cap;
+ 	return rc;
+@@ -469,7 +472,7 @@ void tpm_gen_interrupt(struct tpm_chip *chip)
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+ 
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 			      "attempting to determine the timeouts");
+ }
+ EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+@@ -490,7 +493,7 @@ static int tpm_startup(struct tpm_chip *chip, __be16 startup_type)
+ 	start_cmd.header.in = tpm_startup_header;
+ 
+ 	start_cmd.params.startup_in.startup_type = startup_type;
+-	return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE,
++	return tpm_transmit_cmd(chip, &start_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 				"attempting to start the TPM");
+ }
+ 
+@@ -521,7 +524,8 @@ int tpm_get_timeouts(struct tpm_chip *chip)
+ 	tpm_cmd.params.getcap_in.cap = TPM_CAP_PROP;
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, NULL);
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
++			      NULL);
+ 
+ 	if (rc == TPM_ERR_INVALID_POSTINIT) {
+ 		/* The TPM is not started, we are the first to talk to it.
+@@ -535,7 +539,7 @@ int tpm_get_timeouts(struct tpm_chip *chip)
+ 		tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 		tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_TIMEOUT;
+ 		rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
+-				  NULL);
++				      0, NULL);
+ 	}
+ 	if (rc) {
+ 		dev_err(&chip->dev,
+@@ -596,7 +600,7 @@ duration:
+ 	tpm_cmd.params.getcap_in.subcap_size = cpu_to_be32(4);
+ 	tpm_cmd.params.getcap_in.subcap = TPM_CAP_PROP_TIS_DURATION;
+ 
+-	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &tpm_cmd, TPM_INTERNAL_RESULT_SIZE, 0,
+ 			      "attempting to determine the durations");
+ 	if (rc)
+ 		return rc;
+@@ -652,7 +656,7 @@ static int tpm_continue_selftest(struct tpm_chip *chip)
+ 	struct tpm_cmd_t cmd;
+ 
+ 	cmd.header.in = continue_selftest_header;
+-	rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, CONTINUE_SELFTEST_RESULT_SIZE, 0,
+ 			      "continue selftest");
+ 	return rc;
+ }
+@@ -672,7 +676,7 @@ int tpm_pcr_read_dev(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+ 
+ 	cmd.header.in = pcrread_header;
+ 	cmd.params.pcrread_in.pcr_idx = cpu_to_be32(pcr_idx);
+-	rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, READ_PCR_RESULT_SIZE, 0,
+ 			      "attempting to read a pcr value");
+ 
+ 	if (rc == 0)
+@@ -770,7 +774,7 @@ int tpm_pcr_extend(u32 chip_num, int pcr_idx, const u8 *hash)
+ 	cmd.header.in = pcrextend_header;
+ 	cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(pcr_idx);
+ 	memcpy(cmd.params.pcrextend_in.hash, hash, TPM_DIGEST_SIZE);
+-	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
+ 			      "attempting extend a PCR value");
+ 
+ 	tpm_put_ops(chip);
+@@ -809,7 +813,7 @@ int tpm_do_selftest(struct tpm_chip *chip)
+ 		/* Attempt to read a PCR value */
+ 		cmd.header.in = pcrread_header;
+ 		cmd.params.pcrread_in.pcr_idx = cpu_to_be32(0);
+-		rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE);
++		rc = tpm_transmit(chip, (u8 *) &cmd, READ_PCR_RESULT_SIZE, 0);
+ 		/* Some buggy TPMs will not respond to tpm_tis_ready() for
+ 		 * around 300ms while the self test is ongoing, keep trying
+ 		 * until the self test duration expires. */
+@@ -879,7 +883,7 @@ int tpm_send(u32 chip_num, void *cmd, size_t buflen)
+ 	if (chip == NULL)
+ 		return -ENODEV;
+ 
+-	rc = tpm_transmit_cmd(chip, cmd, buflen, "attempting tpm_cmd");
++	rc = tpm_transmit_cmd(chip, cmd, buflen, 0, "attempting tpm_cmd");
+ 
+ 	tpm_put_ops(chip);
+ 	return rc;
+@@ -981,14 +985,15 @@ int tpm_pm_suspend(struct device *dev)
+ 		cmd.params.pcrextend_in.pcr_idx = cpu_to_be32(tpm_suspend_pcr);
+ 		memcpy(cmd.params.pcrextend_in.hash, dummy_hash,
+ 		       TPM_DIGEST_SIZE);
+-		rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE,
++		rc = tpm_transmit_cmd(chip, &cmd, EXTEND_PCR_RESULT_SIZE, 0,
+ 				      "extending dummy pcr before suspend");
+ 	}
+ 
+ 	/* now do the actual savestate */
+ 	for (try = 0; try < TPM_RETRY; try++) {
+ 		cmd.header.in = savestate_header;
+-		rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, NULL);
++		rc = tpm_transmit_cmd(chip, &cmd, SAVESTATE_RESULT_SIZE, 0,
++				      NULL);
+ 
+ 		/*
+ 		 * If the TPM indicates that it is too busy to respond to
+@@ -1072,8 +1077,8 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max)
+ 		tpm_cmd.params.getrandom_in.num_bytes = cpu_to_be32(num_bytes);
+ 
+ 		err = tpm_transmit_cmd(chip, &tpm_cmd,
+-				   TPM_GETRANDOM_RESULT_SIZE + num_bytes,
+-				   "attempting get random");
++				       TPM_GETRANDOM_RESULT_SIZE + num_bytes,
++				       0, "attempting get random");
+ 		if (err)
+ 			break;
+ 
+diff --git a/drivers/char/tpm/tpm-sysfs.c b/drivers/char/tpm/tpm-sysfs.c
+index b46cf70c8b16..e1f7236c115c 100644
+--- a/drivers/char/tpm/tpm-sysfs.c
++++ b/drivers/char/tpm/tpm-sysfs.c
+@@ -39,7 +39,7 @@ static ssize_t pubek_show(struct device *dev, struct device_attribute *attr,
+ 	struct tpm_chip *chip = to_tpm_chip(dev);
+ 
+ 	tpm_cmd.header.in = tpm_readpubek_header;
+-	err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE,
++	err = tpm_transmit_cmd(chip, &tpm_cmd, READ_PUBEK_RESULT_SIZE, 0,
+ 			       "attempting to read the PUBEK");
+ 	if (err)
+ 		goto out;
+diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
+index 3e32d5bd2dc6..b0585e99da49 100644
+--- a/drivers/char/tpm/tpm.h
++++ b/drivers/char/tpm/tpm.h
+@@ -476,12 +476,16 @@ extern dev_t tpm_devt;
+ extern const struct file_operations tpm_fops;
+ extern struct idr dev_nums_idr;
+ 
++enum tpm_transmit_flags {
++	TPM_TRANSMIT_UNLOCKED	= BIT(0),
++};
++
++ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz,
++		     unsigned int flags);
++ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *cmd, int len,
++			 unsigned int flags, const char *desc);
+ ssize_t tpm_getcap(struct tpm_chip *chip, __be32 subcap_id, cap_t *cap,
+ 		   const char *desc);
+-ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
+-		     size_t bufsiz);
+-ssize_t tpm_transmit_cmd(struct tpm_chip *chip, void *cmd, int len,
+-			 const char *desc);
+ extern int tpm_get_timeouts(struct tpm_chip *);
+ extern void tpm_gen_interrupt(struct tpm_chip *);
+ int tpm1_auto_startup(struct tpm_chip *chip);
+diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
+index 0c75c3f1689f..ef5a58b986f6 100644
+--- a/drivers/char/tpm/tpm2-cmd.c
++++ b/drivers/char/tpm/tpm2-cmd.c
+@@ -282,7 +282,7 @@ int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
+ 	       sizeof(cmd.params.pcrread_in.pcr_select));
+ 	cmd.params.pcrread_in.pcr_select[pcr_idx >> 3] = 1 << (pcr_idx & 0x7);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 			      "attempting to read a pcr value");
+ 	if (rc == 0) {
+ 		buf = cmd.params.pcrread_out.digest;
+@@ -330,7 +330,7 @@ int tpm2_pcr_extend(struct tpm_chip *chip, int pcr_idx, const u8 *hash)
+ 	cmd.params.pcrextend_in.hash_alg = cpu_to_be16(TPM2_ALG_SHA1);
+ 	memcpy(cmd.params.pcrextend_in.digest, hash, TPM_DIGEST_SIZE);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 			      "attempting extend a PCR value");
+ 
+ 	return rc;
+@@ -376,7 +376,7 @@ int tpm2_get_random(struct tpm_chip *chip, u8 *out, size_t max)
+ 		cmd.header.in = tpm2_getrandom_header;
+ 		cmd.params.getrandom_in.size = cpu_to_be16(num_bytes);
+ 
+-		err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++		err = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 				       "attempting get random");
+ 		if (err)
+ 			break;
+@@ -434,12 +434,12 @@ static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
+ }
+ 
+ /**
+- * tpm2_seal_trusted() - seal a trusted key
+- * @chip_num: A specific chip number for the request or TPM_ANY_NUM
+- * @options: authentication values and other options
++ * tpm2_seal_trusted() - seal the payload of a trusted key
++ * @chip_num: TPM chip to use
+  * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
+  *
+- * Returns < 0 on error and 0 on success.
++ * Return: < 0 on error and 0 on success.
+  */
+ int tpm2_seal_trusted(struct tpm_chip *chip,
+ 		      struct trusted_key_payload *payload,
+@@ -512,7 +512,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
+ 		goto out;
+ 	}
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "sealing data");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, 0, "sealing data");
+ 	if (rc)
+ 		goto out;
+ 
+@@ -538,10 +538,18 @@ out:
+ 	return rc;
+ }
+ 
+-static int tpm2_load(struct tpm_chip *chip,
+-		     struct trusted_key_payload *payload,
+-		     struct trusted_key_options *options,
+-		     u32 *blob_handle)
++/**
++ * tpm2_load_cmd() - execute a TPM2_Load command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static int tpm2_load_cmd(struct tpm_chip *chip,
++			 struct trusted_key_payload *payload,
++			 struct trusted_key_options *options,
++			 u32 *blob_handle, unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	unsigned int private_len;
+@@ -576,7 +584,7 @@ static int tpm2_load(struct tpm_chip *chip,
+ 		goto out;
+ 	}
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "loading blob");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "loading blob");
+ 	if (!rc)
+ 		*blob_handle = be32_to_cpup(
+ 			(__be32 *) &buf.data[TPM_HEADER_SIZE]);
+@@ -590,7 +598,16 @@ out:
+ 	return rc;
+ }
+ 
+-static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
++/**
++ * tpm2_flush_context_cmd() - execute a TPM2_FlushContext command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
++				   unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	int rc;
+@@ -604,7 +621,8 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
+ 
+ 	tpm_buf_append_u32(&buf, handle);
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "flushing context");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags,
++			      "flushing context");
+ 	if (rc)
+ 		dev_warn(&chip->dev, "0x%08x was not flushed, rc=%d\n", handle,
+ 			 rc);
+@@ -612,10 +630,18 @@ static void tpm2_flush_context(struct tpm_chip *chip, u32 handle)
+ 	tpm_buf_destroy(&buf);
+ }
+ 
+-static int tpm2_unseal(struct tpm_chip *chip,
+-		       struct trusted_key_payload *payload,
+-		       struct trusted_key_options *options,
+-		       u32 blob_handle)
++/**
++ * tpm2_unseal_cmd() - execute a TPM2_Unload command
++ * @chip_num: TPM chip to use
++ * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
++ *
++ * Return: same as with tpm_transmit_cmd
++ */
++static int tpm2_unseal_cmd(struct tpm_chip *chip,
++			   struct trusted_key_payload *payload,
++			   struct trusted_key_options *options,
++			   u32 blob_handle, unsigned int flags)
+ {
+ 	struct tpm_buf buf;
+ 	u16 data_len;
+@@ -635,7 +661,7 @@ static int tpm2_unseal(struct tpm_chip *chip,
+ 			     options->blobauth /* hmac */,
+ 			     TPM_DIGEST_SIZE);
+ 
+-	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, "unsealing");
++	rc = tpm_transmit_cmd(chip, buf.data, PAGE_SIZE, flags, "unsealing");
+ 	if (rc > 0)
+ 		rc = -EPERM;
+ 
+@@ -654,12 +680,12 @@ static int tpm2_unseal(struct tpm_chip *chip,
+ }
+ 
+ /**
+- * tpm_unseal_trusted() - unseal a trusted key
+- * @chip_num: A specific chip number for the request or TPM_ANY_NUM
+- * @options: authentication values and other options
++ * tpm_unseal_trusted() - unseal the payload of a trusted key
++ * @chip_num: TPM chip to use
+  * @payload: the key data in clear and encrypted form
++ * @options: authentication values and other options
+  *
+- * Returns < 0 on error and 0 on success.
++ * Return: < 0 on error and 0 on success.
+  */
+ int tpm2_unseal_trusted(struct tpm_chip *chip,
+ 			struct trusted_key_payload *payload,
+@@ -668,14 +694,17 @@ int tpm2_unseal_trusted(struct tpm_chip *chip,
+ 	u32 blob_handle;
+ 	int rc;
+ 
+-	rc = tpm2_load(chip, payload, options, &blob_handle);
++	mutex_lock(&chip->tpm_mutex);
++	rc = tpm2_load_cmd(chip, payload, options, &blob_handle,
++			   TPM_TRANSMIT_UNLOCKED);
+ 	if (rc)
+-		return rc;
+-
+-	rc = tpm2_unseal(chip, payload, options, blob_handle);
+-
+-	tpm2_flush_context(chip, blob_handle);
++		goto out;
+ 
++	rc = tpm2_unseal_cmd(chip, payload, options, blob_handle,
++			     TPM_TRANSMIT_UNLOCKED);
++	tpm2_flush_context_cmd(chip, blob_handle, TPM_TRANSMIT_UNLOCKED);
++out:
++	mutex_unlock(&chip->tpm_mutex);
+ 	return rc;
+ }
+ 
+@@ -701,7 +730,7 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 property_id,  u32 *value,
+ 	cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(property_id);
+ 	cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), desc);
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, desc);
+ 	if (!rc)
+ 		*value = be32_to_cpu(cmd.params.get_tpm_pt_out.value);
+ 
+@@ -735,7 +764,7 @@ static int tpm2_startup(struct tpm_chip *chip, u16 startup_type)
+ 	cmd.header.in = tpm2_startup_header;
+ 
+ 	cmd.params.startup_in.startup_type = cpu_to_be16(startup_type);
+-	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd),
++	return tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
+ 				"attempting to start the TPM");
+ }
+ 
+@@ -763,7 +792,7 @@ void tpm2_shutdown(struct tpm_chip *chip, u16 shutdown_type)
+ 	cmd.header.in = tpm2_shutdown_header;
+ 	cmd.params.startup_in.startup_type = cpu_to_be16(shutdown_type);
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), "stopping the TPM");
++	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, "stopping the TPM");
+ 
+ 	/* In places where shutdown command is sent there's no much we can do
+ 	 * except print the error code on a system failure.
+@@ -828,7 +857,7 @@ static int tpm2_start_selftest(struct tpm_chip *chip, bool full)
+ 	cmd.header.in = tpm2_selftest_header;
+ 	cmd.params.selftest_in.full_test = full;
+ 
+-	rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE,
++	rc = tpm_transmit_cmd(chip, &cmd, TPM2_SELF_TEST_IN_SIZE, 0,
+ 			      "continue selftest");
+ 
+ 	/* At least some prototype chips seem to give RC_TESTING error
+@@ -880,7 +909,7 @@ static int tpm2_do_selftest(struct tpm_chip *chip)
+ 		cmd.params.pcrread_in.pcr_select[1] = 0x00;
+ 		cmd.params.pcrread_in.pcr_select[2] = 0x00;
+ 
+-		rc = tpm_transmit_cmd(chip, (u8 *) &cmd, sizeof(cmd), NULL);
++		rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0, NULL);
+ 		if (rc < 0)
+ 			break;
+ 
+@@ -928,7 +957,7 @@ int tpm2_probe(struct tpm_chip *chip)
+ 	cmd.params.get_tpm_pt_in.property_id = cpu_to_be32(0x100);
+ 	cmd.params.get_tpm_pt_in.property_cnt = cpu_to_be32(1);
+ 
+-	rc = tpm_transmit(chip, (const char *) &cmd, sizeof(cmd));
++	rc = tpm_transmit(chip, (const u8 *)&cmd, sizeof(cmd), 0);
+ 	if (rc <  0)
+ 		return rc;
+ 	else if (rc < TPM_HEADER_SIZE)
+diff --git a/drivers/char/tpm/tpm_crb.c b/drivers/char/tpm/tpm_crb.c
+index 018c382554ba..1801f382377e 100644
+--- a/drivers/char/tpm/tpm_crb.c
++++ b/drivers/char/tpm/tpm_crb.c
+@@ -142,6 +142,11 @@ static int crb_send(struct tpm_chip *chip, u8 *buf, size_t len)
+ 	struct crb_priv *priv = dev_get_drvdata(&chip->dev);
+ 	int rc = 0;
+ 
++	/* Zero the cancel register so that the next command will not get
++	 * canceled.
++	 */
++	iowrite32(0, &priv->cca->cancel);
++
+ 	if (len > ioread32(&priv->cca->cmd_size)) {
+ 		dev_err(&chip->dev,
+ 			"invalid command count value %x %zx\n",
+@@ -175,8 +180,6 @@ static void crb_cancel(struct tpm_chip *chip)
+ 
+ 	if ((priv->flags & CRB_FL_ACPI_START) && crb_do_acpi_start(chip))
+ 		dev_err(&chip->dev, "ACPI Start failed\n");
+-
+-	iowrite32(0, &priv->cca->cancel);
+ }
+ 
+ static bool crb_req_canceled(struct tpm_chip *chip, u8 status)
+diff --git a/drivers/cpuidle/cpuidle-arm.c b/drivers/cpuidle/cpuidle-arm.c
+index 4ba3d3fe142f..f440d385ed34 100644
+--- a/drivers/cpuidle/cpuidle-arm.c
++++ b/drivers/cpuidle/cpuidle-arm.c
+@@ -121,6 +121,7 @@ static int __init arm_idle_init(void)
+ 		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ 		if (!dev) {
+ 			pr_err("Failed to allocate cpuidle device\n");
++			ret = -ENOMEM;
+ 			goto out_fail;
+ 		}
+ 		dev->cpu = cpu;
+diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
+index 2d1fb6420592..580f4f280d6b 100644
+--- a/drivers/mfd/Kconfig
++++ b/drivers/mfd/Kconfig
+@@ -1549,6 +1549,7 @@ config MFD_WM8350
+ config MFD_WM8350_I2C
+ 	bool "Wolfson Microelectronics WM8350 with I2C"
+ 	select MFD_WM8350
++	select REGMAP_I2C
+ 	depends on I2C=y
+ 	help
+ 	  The WM8350 is an integrated audio and power management
+diff --git a/drivers/mfd/atmel-hlcdc.c b/drivers/mfd/atmel-hlcdc.c
+index eca7ea69b81c..4b15b0840f16 100644
+--- a/drivers/mfd/atmel-hlcdc.c
++++ b/drivers/mfd/atmel-hlcdc.c
+@@ -50,8 +50,9 @@ static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg,
+ 	if (reg <= ATMEL_HLCDC_DIS) {
+ 		u32 status;
+ 
+-		readl_poll_timeout(hregmap->regs + ATMEL_HLCDC_SR, status,
+-				   !(status & ATMEL_HLCDC_SIP), 1, 100);
++		readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR,
++					  status, !(status & ATMEL_HLCDC_SIP),
++					  1, 100);
+ 	}
+ 
+ 	writel(val, hregmap->regs + reg);
+diff --git a/drivers/mfd/rtsx_usb.c b/drivers/mfd/rtsx_usb.c
+index dbd907d7170e..691dab791f7a 100644
+--- a/drivers/mfd/rtsx_usb.c
++++ b/drivers/mfd/rtsx_usb.c
+@@ -46,9 +46,6 @@ static void rtsx_usb_sg_timed_out(unsigned long data)
+ 
+ 	dev_dbg(&ucr->pusb_intf->dev, "%s: sg transfer timed out", __func__);
+ 	usb_sg_cancel(&ucr->current_sg);
+-
+-	/* we know the cancellation is caused by time-out */
+-	ucr->current_sg.status = -ETIMEDOUT;
+ }
+ 
+ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+@@ -67,12 +64,15 @@ static int rtsx_usb_bulk_transfer_sglist(struct rtsx_ucr *ucr,
+ 	ucr->sg_timer.expires = jiffies + msecs_to_jiffies(timeout);
+ 	add_timer(&ucr->sg_timer);
+ 	usb_sg_wait(&ucr->current_sg);
+-	del_timer_sync(&ucr->sg_timer);
++	if (!del_timer_sync(&ucr->sg_timer))
++		ret = -ETIMEDOUT;
++	else
++		ret = ucr->current_sg.status;
+ 
+ 	if (act_len)
+ 		*act_len = ucr->current_sg.bytes;
+ 
+-	return ucr->current_sg.status;
++	return ret;
+ }
+ 
+ int rtsx_usb_transfer_data(struct rtsx_ucr *ucr, unsigned int pipe,
+diff --git a/drivers/pci/pci-mid.c b/drivers/pci/pci-mid.c
+index c878aa71173b..55f453de562e 100644
+--- a/drivers/pci/pci-mid.c
++++ b/drivers/pci/pci-mid.c
+@@ -60,8 +60,13 @@ static struct pci_platform_pm_ops mid_pci_platform_pm = {
+ 
+ #define ICPU(model)	{ X86_VENDOR_INTEL, 6, model, X86_FEATURE_ANY, }
+ 
++/*
++ * This table should be in sync with the one in
++ * arch/x86/platform/intel-mid/pwr.c.
++ */
+ static const struct x86_cpu_id lpss_cpu_ids[] = {
+-	ICPU(INTEL_FAM6_ATOM_MERRIFIELD1),
++	ICPU(INTEL_FAM6_ATOM_PENWELL),
++	ICPU(INTEL_FAM6_ATOM_MERRIFIELD),
+ 	{}
+ };
+ 
+diff --git a/drivers/phy/phy-sun4i-usb.c b/drivers/phy/phy-sun4i-usb.c
+index 8c7eb335622e..4d74ca9186c7 100644
+--- a/drivers/phy/phy-sun4i-usb.c
++++ b/drivers/phy/phy-sun4i-usb.c
+@@ -40,6 +40,7 @@
+ #include <linux/power_supply.h>
+ #include <linux/regulator/consumer.h>
+ #include <linux/reset.h>
++#include <linux/spinlock.h>
+ #include <linux/usb/of.h>
+ #include <linux/workqueue.h>
+ 
+@@ -112,7 +113,7 @@ struct sun4i_usb_phy_data {
+ 	void __iomem *base;
+ 	const struct sun4i_usb_phy_cfg *cfg;
+ 	enum usb_dr_mode dr_mode;
+-	struct mutex mutex;
++	spinlock_t reg_lock; /* guard access to phyctl reg */
+ 	struct sun4i_usb_phy {
+ 		struct phy *phy;
+ 		void __iomem *pmu;
+@@ -179,9 +180,10 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
+ 	struct sun4i_usb_phy_data *phy_data = to_sun4i_usb_phy_data(phy);
+ 	u32 temp, usbc_bit = BIT(phy->index * 2);
+ 	void __iomem *phyctl = phy_data->base + phy_data->cfg->phyctl_offset;
++	unsigned long flags;
+ 	int i;
+ 
+-	mutex_lock(&phy_data->mutex);
++	spin_lock_irqsave(&phy_data->reg_lock, flags);
+ 
+ 	if (phy_data->cfg->type == sun8i_a33_phy) {
+ 		/* A33 needs us to set phyctl to 0 explicitly */
+@@ -218,7 +220,8 @@ static void sun4i_usb_phy_write(struct sun4i_usb_phy *phy, u32 addr, u32 data,
+ 
+ 		data >>= 1;
+ 	}
+-	mutex_unlock(&phy_data->mutex);
++
++	spin_unlock_irqrestore(&phy_data->reg_lock, flags);
+ }
+ 
+ static void sun4i_usb_phy_passby(struct sun4i_usb_phy *phy, int enable)
+@@ -577,7 +580,7 @@ static int sun4i_usb_phy_probe(struct platform_device *pdev)
+ 	if (!data)
+ 		return -ENOMEM;
+ 
+-	mutex_init(&data->mutex);
++	spin_lock_init(&data->reg_lock);
+ 	INIT_DELAYED_WORK(&data->detect, sun4i_usb_phy0_id_vbus_det_scan);
+ 	dev_set_drvdata(dev, data);
+ 	data->cfg = of_device_get_match_data(dev);
+diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c
+index fbab29dfa793..243b233ff31b 100644
+--- a/drivers/powercap/intel_rapl.c
++++ b/drivers/powercap/intel_rapl.c
+@@ -1154,8 +1154,8 @@ static const struct x86_cpu_id rapl_ids[] __initconst = {
+ 
+ 	RAPL_CPU(INTEL_FAM6_ATOM_SILVERMONT1,	rapl_defaults_byt),
+ 	RAPL_CPU(INTEL_FAM6_ATOM_AIRMONT,	rapl_defaults_cht),
+-	RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD1,	rapl_defaults_tng),
+-	RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD2,	rapl_defaults_ann),
++	RAPL_CPU(INTEL_FAM6_ATOM_MERRIFIELD,	rapl_defaults_tng),
++	RAPL_CPU(INTEL_FAM6_ATOM_MOOREFIELD,	rapl_defaults_ann),
+ 	RAPL_CPU(INTEL_FAM6_ATOM_GOLDMONT,	rapl_defaults_core),
+ 	RAPL_CPU(INTEL_FAM6_ATOM_DENVERTON,	rapl_defaults_core),
+ 
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 122e64df2f4d..68544618982e 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -348,7 +348,8 @@ static int dwc3_send_clear_stall_ep_cmd(struct dwc3_ep *dep)
+ 	 * IN transfers due to a mishandled error condition. Synopsys
+ 	 * STAR 9000614252.
+ 	 */
+-	if (dep->direction && (dwc->revision >= DWC3_REVISION_260A))
++	if (dep->direction && (dwc->revision >= DWC3_REVISION_260A) &&
++	    (dwc->gadget.speed >= USB_SPEED_SUPER))
+ 		cmd |= DWC3_DEPCMD_CLEARPENDIN;
+ 
+ 	memset(&params, 0, sizeof(params));
+diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
+index ef2d8cde6ef7..8c5f0115166a 100644
+--- a/drivers/usb/storage/usb.c
++++ b/drivers/usb/storage/usb.c
+@@ -1070,17 +1070,17 @@ int usb_stor_probe2(struct us_data *us)
+ 	result = usb_stor_acquire_resources(us);
+ 	if (result)
+ 		goto BadDevice;
++	usb_autopm_get_interface_no_resume(us->pusb_intf);
+ 	snprintf(us->scsi_name, sizeof(us->scsi_name), "usb-storage %s",
+ 					dev_name(&us->pusb_intf->dev));
+ 	result = scsi_add_host(us_to_host(us), dev);
+ 	if (result) {
+ 		dev_warn(dev,
+ 				"Unable to add the scsi host\n");
+-		goto BadDevice;
++		goto HostAddErr;
+ 	}
+ 
+ 	/* Submit the delayed_work for SCSI-device scanning */
+-	usb_autopm_get_interface_no_resume(us->pusb_intf);
+ 	set_bit(US_FLIDX_SCAN_PENDING, &us->dflags);
+ 
+ 	if (delay_use > 0)
+@@ -1090,6 +1090,8 @@ int usb_stor_probe2(struct us_data *us)
+ 	return 0;
+ 
+ 	/* We come here if there are any problems */
++HostAddErr:
++	usb_autopm_put_interface_no_suspend(us->pusb_intf);
+ BadDevice:
+ 	usb_stor_dbg(us, "storage_probe() failed\n");
+ 	release_everything(us);
+diff --git a/include/linux/mfd/88pm80x.h b/include/linux/mfd/88pm80x.h
+index d409ceb2231e..c118a7ec94d6 100644
+--- a/include/linux/mfd/88pm80x.h
++++ b/include/linux/mfd/88pm80x.h
+@@ -350,7 +350,7 @@ static inline int pm80x_dev_suspend(struct device *dev)
+ 	int irq = platform_get_irq(pdev, 0);
+ 
+ 	if (device_may_wakeup(dev))
+-		set_bit((1 << irq), &chip->wu_flag);
++		set_bit(irq, &chip->wu_flag);
+ 
+ 	return 0;
+ }
+@@ -362,7 +362,7 @@ static inline int pm80x_dev_resume(struct device *dev)
+ 	int irq = platform_get_irq(pdev, 0);
+ 
+ 	if (device_may_wakeup(dev))
+-		clear_bit((1 << irq), &chip->wu_flag);
++		clear_bit(irq, &chip->wu_flag);
+ 
+ 	return 0;
+ }
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index e07fb093f819..37dec7e3db43 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -403,8 +403,11 @@ static __always_inline u64 __ktime_get_fast_ns(struct tk_fast *tkf)
+ 		tkr = tkf->base + (seq & 0x01);
+ 		now = ktime_to_ns(tkr->base);
+ 
+-		now += clocksource_delta(tkr->read(tkr->clock),
+-					 tkr->cycle_last, tkr->mask);
++		now += timekeeping_delta_to_ns(tkr,
++				clocksource_delta(
++					tkr->read(tkr->clock),
++					tkr->cycle_last,
++					tkr->mask));
+ 	} while (read_seqcount_retry(&tkf->seq, seq));
+ 
+ 	return now;
+diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c
+index 4b9b4a4e1b89..ef1e4e701780 100644
+--- a/security/integrity/ima/ima_appraise.c
++++ b/security/integrity/ima/ima_appraise.c
+@@ -190,7 +190,7 @@ int ima_appraise_measurement(enum ima_hooks func,
+ {
+ 	static const char op[] = "appraise_data";
+ 	char *cause = "unknown";
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file_dentry(file);
+ 	struct inode *inode = d_backing_inode(dentry);
+ 	enum integrity_status status = INTEGRITY_UNKNOWN;
+ 	int rc = xattr_len, hash_start = 0;
+@@ -295,7 +295,7 @@ out:
+  */
+ void ima_update_xattr(struct integrity_iint_cache *iint, struct file *file)
+ {
+-	struct dentry *dentry = file->f_path.dentry;
++	struct dentry *dentry = file_dentry(file);
+ 	int rc = 0;
+ 
+ 	/* do not collect and update hash for digital signatures */
+diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
+index 596ef616ac21..423d111b3b94 100644
+--- a/security/integrity/ima/ima_main.c
++++ b/security/integrity/ima/ima_main.c
+@@ -228,7 +228,7 @@ static int process_measurement(struct file *file, char *buf, loff_t size,
+ 	if ((action & IMA_APPRAISE_SUBMASK) ||
+ 		    strcmp(template_desc->name, IMA_TEMPLATE_IMA_NAME) != 0)
+ 		/* read 'security.ima' */
+-		xattr_len = ima_read_xattr(file->f_path.dentry, &xattr_value);
++		xattr_len = ima_read_xattr(file_dentry(file), &xattr_value);
+ 
+ 	hash_algo = ima_get_hash_algo(xattr_value, xattr_len);
+ 
+diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c
+index 36470af7eda7..92b819e4f729 100644
+--- a/sound/pci/ali5451/ali5451.c
++++ b/sound/pci/ali5451/ali5451.c
+@@ -1408,6 +1408,7 @@ snd_ali_playback_pointer(struct snd_pcm_substream *substream)
+ 	spin_unlock(&codec->reg_lock);
+ 	dev_dbg(codec->card->dev, "playback pointer returned cso=%xh.\n", cso);
+ 
++	cso %= runtime->buffer_size;
+ 	return cso;
+ }
+ 
+@@ -1428,6 +1429,7 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream)
+ 	cso = inw(ALI_REG(codec, ALI_CSO_ALPHA_FMS + 2));
+ 	spin_unlock(&codec->reg_lock);
+ 
++	cso %= runtime->buffer_size;
+ 	return cso;
+ }
+ 
+diff --git a/sound/usb/line6/driver.c b/sound/usb/line6/driver.c
+index 81b7da8e56d3..183311cb849e 100644
+--- a/sound/usb/line6/driver.c
++++ b/sound/usb/line6/driver.c
+@@ -29,7 +29,7 @@
+ /*
+ 	This is Line 6's MIDI manufacturer ID.
+ */
+-const unsigned char line6_midi_id[] = {
++const unsigned char line6_midi_id[3] = {
+ 	0x00, 0x01, 0x0c
+ };
+ EXPORT_SYMBOL_GPL(line6_midi_id);
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c
+index f6c3bf79af9a..04991b009132 100644
+--- a/sound/usb/mixer_quirks.c
++++ b/sound/usb/mixer_quirks.c
+@@ -1831,6 +1831,7 @@ void snd_usb_mixer_rc_memory_change(struct usb_mixer_interface *mixer,
+ }
+ 
+ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
++					 struct usb_mixer_elem_info *cval,
+ 					 struct snd_kcontrol *kctl)
+ {
+ 	/* Approximation using 10 ranges based on output measurement on hw v1.2.
+@@ -1848,10 +1849,19 @@ static void snd_dragonfly_quirk_db_scale(struct usb_mixer_interface *mixer,
+ 		41, 50, TLV_DB_MINMAX_ITEM(-441, 0),
+ 	);
+ 
+-	usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk\n");
+-	kctl->tlv.p = scale;
+-	kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
+-	kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++	if (cval->min == 0 && cval->max == 50) {
++		usb_audio_info(mixer->chip, "applying DragonFly dB scale quirk (0-50 variant)\n");
++		kctl->tlv.p = scale;
++		kctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ;
++		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++
++	} else if (cval->min == 0 && cval->max <= 1000) {
++		/* Some other clearly broken DragonFly variant.
++		 * At least a 0..53 variant (hw v1.0) exists.
++		 */
++		usb_audio_info(mixer->chip, "ignoring too narrow dB range on a DragonFly device");
++		kctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK;
++	}
+ }
+ 
+ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+@@ -1860,8 +1870,8 @@ void snd_usb_mixer_fu_apply_quirk(struct usb_mixer_interface *mixer,
+ {
+ 	switch (mixer->chip->usb_id) {
+ 	case USB_ID(0x21b4, 0x0081): /* AudioQuest DragonFly */
+-		if (unitid == 7 && cval->min == 0 && cval->max == 50)
+-			snd_dragonfly_quirk_db_scale(mixer, kctl);
++		if (unitid == 7 && cval->control == UAC_FU_VOLUME)
++			snd_dragonfly_quirk_db_scale(mixer, cval, kctl);
+ 		break;
+ 	}
+ }
+diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
+index a027569facfa..6e9c40eea208 100644
+--- a/virt/kvm/arm/pmu.c
++++ b/virt/kvm/arm/pmu.c
+@@ -423,6 +423,14 @@ static int kvm_arm_pmu_v3_init(struct kvm_vcpu *vcpu)
+ 	if (!kvm_arm_support_pmu_v3())
+ 		return -ENODEV;
+ 
++	/*
++	 * We currently require an in-kernel VGIC to use the PMU emulation,
++	 * because we do not support forwarding PMU overflow interrupts to
++	 * userspace yet.
++	 */
++	if (!irqchip_in_kernel(vcpu->kvm) || !vgic_initialized(vcpu->kvm))
++		return -ENODEV;
++
+ 	if (!test_bit(KVM_ARM_VCPU_PMU_V3, vcpu->arch.features) ||
+ 	    !kvm_arm_pmu_irq_initialized(vcpu))
+ 		return -ENXIO;
+diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
+index e83b7fe4baae..b465ac6d5d48 100644
+--- a/virt/kvm/arm/vgic/vgic.c
++++ b/virt/kvm/arm/vgic/vgic.c
+@@ -645,6 +645,9 @@ next:
+ /* Sync back the hardware VGIC state into our emulation after a guest's run. */
+ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
+ {
++	if (unlikely(!vgic_initialized(vcpu->kvm)))
++		return;
++
+ 	vgic_process_maintenance_interrupt(vcpu);
+ 	vgic_fold_lr_state(vcpu);
+ 	vgic_prune_ap_list(vcpu);
+@@ -653,6 +656,9 @@ void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu)
+ /* Flush our emulation state into the GIC hardware before entering the guest. */
+ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
+ {
++	if (unlikely(!vgic_initialized(vcpu->kvm)))
++		return;
++
+ 	spin_lock(&vcpu->arch.vgic_cpu.ap_list_lock);
+ 	vgic_flush_lr_state(vcpu);
+ 	spin_unlock(&vcpu->arch.vgic_cpu.ap_list_lock);


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-21 11:11 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-21 11:11 UTC (permalink / raw
  To: gentoo-commits

commit:     b2af285eb4601a6aa04bd1b1d14c211a1408e39e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 21 11:11:37 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Oct 21 11:11:37 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b2af285e

Linux patch 4.8.3

 0000_README            |   4 ++
 1002_linux-4.8.3.patch | 125 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 129 insertions(+)

diff --git a/0000_README b/0000_README
index 07a39ba..f814c9e 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch:  1001_linux-4.8.2.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.2
 
+Patch:  1002_linux-4.8.3.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.3
+
 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/1002_linux-4.8.3.patch b/1002_linux-4.8.3.patch
new file mode 100644
index 0000000..36a0827
--- /dev/null
+++ b/1002_linux-4.8.3.patch
@@ -0,0 +1,125 @@
+diff --git a/Makefile b/Makefile
+index bf6e44a421df..42eb45c86a42 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
+index ec6381e57eb7..258a3f9a2519 100644
+--- a/drivers/scsi/hosts.c
++++ b/drivers/scsi/hosts.c
+@@ -246,10 +246,6 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+ 
+ 	shost->dma_dev = dma_dev;
+ 
+-	error = device_add(&shost->shost_gendev);
+-	if (error)
+-		goto out_destroy_freelist;
+-
+ 	/*
+ 	 * Increase usage count temporarily here so that calling
+ 	 * scsi_autopm_put_host() will trigger runtime idle if there is
+@@ -260,6 +256,10 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+ 	pm_runtime_enable(&shost->shost_gendev);
+ 	device_enable_async_suspend(&shost->shost_gendev);
+ 
++	error = device_add(&shost->shost_gendev);
++	if (error)
++		goto out_destroy_freelist;
++
+ 	scsi_host_set_state(shost, SHOST_RUNNING);
+ 	get_device(shost->shost_gendev.parent);
+ 
+@@ -309,6 +309,10 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev,
+  out_del_gendev:
+ 	device_del(&shost->shost_gendev);
+  out_destroy_freelist:
++	device_disable_async_suspend(&shost->shost_gendev);
++	pm_runtime_disable(&shost->shost_gendev);
++	pm_runtime_set_suspended(&shost->shost_gendev);
++	pm_runtime_put_noidle(&shost->shost_gendev);
+ 	scsi_destroy_command_freelist(shost);
+  out_destroy_tags:
+ 	if (shost_use_blk_mq(shost))
+diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
+index ea62245fee26..62900938f26d 100644
+--- a/fs/xfs/xfs_xattr.c
++++ b/fs/xfs/xfs_xattr.c
+@@ -147,6 +147,7 @@ __xfs_xattr_put_listent(
+ 	arraytop = context->count + prefix_len + namelen + 1;
+ 	if (arraytop > context->firstu) {
+ 		context->count = -1;	/* insufficient space */
++		context->seen_enough = 1;
+ 		return 0;
+ 	}
+ 	offset = (char *)context->alist + context->count;
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index ef815b9cd426..277cd39a6399 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -2234,6 +2234,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
+ #define FOLL_TRIED	0x800	/* a retry, previous pass started an IO */
+ #define FOLL_MLOCK	0x1000	/* lock present pages */
+ #define FOLL_REMOTE	0x2000	/* we are working on non-current tsk/mm */
++#define FOLL_COW	0x4000	/* internal GUP flag */
+ 
+ typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
+ 			void *data);
+diff --git a/include/media/rcar-fcp.h b/include/media/rcar-fcp.h
+index 4c7fc77eaf29..8723f05c6321 100644
+--- a/include/media/rcar-fcp.h
++++ b/include/media/rcar-fcp.h
+@@ -29,7 +29,7 @@ static inline struct rcar_fcp_device *rcar_fcp_get(const struct device_node *np)
+ static inline void rcar_fcp_put(struct rcar_fcp_device *fcp) { }
+ static inline int rcar_fcp_enable(struct rcar_fcp_device *fcp)
+ {
+-	return -ENOSYS;
++	return 0;
+ }
+ static inline void rcar_fcp_disable(struct rcar_fcp_device *fcp) { }
+ #endif
+diff --git a/mm/gup.c b/mm/gup.c
+index 96b2b2fd0fbd..22cc22e7432f 100644
+--- a/mm/gup.c
++++ b/mm/gup.c
+@@ -60,6 +60,16 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address,
+ 	return -EEXIST;
+ }
+ 
++/*
++ * FOLL_FORCE can write to even unwritable pte's, but only
++ * after we've gone through a COW cycle and they are dirty.
++ */
++static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
++{
++	return pte_write(pte) ||
++		((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
++}
++
+ static struct page *follow_page_pte(struct vm_area_struct *vma,
+ 		unsigned long address, pmd_t *pmd, unsigned int flags)
+ {
+@@ -95,7 +105,7 @@ retry:
+ 	}
+ 	if ((flags & FOLL_NUMA) && pte_protnone(pte))
+ 		goto no_page;
+-	if ((flags & FOLL_WRITE) && !pte_write(pte)) {
++	if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
+ 		pte_unmap_unlock(ptep, ptl);
+ 		return NULL;
+ 	}
+@@ -412,7 +422,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
+ 	 * reCOWed by userspace write).
+ 	 */
+ 	if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
+-		*flags &= ~FOLL_WRITE;
++	        *flags |= FOLL_COW;
+ 	return 0;
+ }
+ 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-22 13:08 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-22 13:08 UTC (permalink / raw
  To: gentoo-commits

commit:     586e8ad56c51f3844347707c9b20aa666796fbdf
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 22 13:08:18 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Oct 22 13:08:18 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=586e8ad5

Linux patch 4.8.4

 0000_README            |    4 +
 1003_linux-4.8.4.patch | 2264 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2268 insertions(+)

diff --git a/0000_README b/0000_README
index f814c9e..5a8b43e 100644
--- a/0000_README
+++ b/0000_README
@@ -55,6 +55,10 @@ Patch:  1002_linux-4.8.3.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.3
 
+Patch:  1003_linux-4.8.4.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.4
+
 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/1003_linux-4.8.4.patch b/1003_linux-4.8.4.patch
new file mode 100644
index 0000000..bb2930c
--- /dev/null
+++ b/1003_linux-4.8.4.patch
@@ -0,0 +1,2264 @@
+diff --git a/MAINTAINERS b/MAINTAINERS
+index f593300e310b..babaf8261941 100644
+--- a/MAINTAINERS
++++ b/MAINTAINERS
+@@ -12951,11 +12951,10 @@ F:	arch/x86/xen/*swiotlb*
+ F:	drivers/xen/*swiotlb*
+ 
+ XFS FILESYSTEM
+-P:	Silicon Graphics Inc
+ M:	Dave Chinner <david@fromorbit.com>
+-M:	xfs@oss.sgi.com
+-L:	xfs@oss.sgi.com
+-W:	http://oss.sgi.com/projects/xfs
++M:	linux-xfs@vger.kernel.org
++L:	linux-xfs@vger.kernel.org
++W:	http://xfs.org/
+ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/dgc/linux-xfs.git
+ S:	Supported
+ F:	Documentation/filesystems/xfs.txt
+diff --git a/Makefile b/Makefile
+index 42eb45c86a42..82a36ab540a4 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arc/include/asm/irqflags-arcv2.h b/arch/arc/include/asm/irqflags-arcv2.h
+index d1ec7f6b31e0..e880dfa3fcd3 100644
+--- a/arch/arc/include/asm/irqflags-arcv2.h
++++ b/arch/arc/include/asm/irqflags-arcv2.h
+@@ -112,7 +112,7 @@ static inline long arch_local_save_flags(void)
+ 	 */
+ 	temp = (1 << 5) |
+ 		((!!(temp & STATUS_IE_MASK)) << CLRI_STATUS_IE_BIT) |
+-		(temp & CLRI_STATUS_E_MASK);
++		((temp >> 1) & CLRI_STATUS_E_MASK);
+ 	return temp;
+ }
+ 
+diff --git a/arch/arc/kernel/intc-arcv2.c b/arch/arc/kernel/intc-arcv2.c
+index 6c24faf48b16..62b59409a5d9 100644
+--- a/arch/arc/kernel/intc-arcv2.c
++++ b/arch/arc/kernel/intc-arcv2.c
+@@ -74,7 +74,7 @@ void arc_init_IRQ(void)
+ 	tmp = read_aux_reg(0xa);
+ 	tmp |= STATUS_AD_MASK | (irq_prio << 1);
+ 	tmp &= ~STATUS_IE_MASK;
+-	asm volatile("flag %0	\n"::"r"(tmp));
++	asm volatile("kflag %0	\n"::"r"(tmp));
+ }
+ 
+ static void arcv2_irq_mask(struct irq_data *data)
+diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c
+index cc2f6dbd4303..5e24d880306c 100644
+--- a/block/cfq-iosched.c
++++ b/block/cfq-iosched.c
+@@ -3042,7 +3042,6 @@ static struct request *cfq_check_fifo(struct cfq_queue *cfqq)
+ 	if (ktime_get_ns() < rq->fifo_time)
+ 		rq = NULL;
+ 
+-	cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
+ 	return rq;
+ }
+ 
+@@ -3420,6 +3419,9 @@ static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+ {
+ 	unsigned int max_dispatch;
+ 
++	if (cfq_cfqq_must_dispatch(cfqq))
++		return true;
++
+ 	/*
+ 	 * Drain async requests before we start sync IO
+ 	 */
+@@ -3511,15 +3513,20 @@ static bool cfq_dispatch_request(struct cfq_data *cfqd, struct cfq_queue *cfqq)
+ 
+ 	BUG_ON(RB_EMPTY_ROOT(&cfqq->sort_list));
+ 
++	rq = cfq_check_fifo(cfqq);
++	if (rq)
++		cfq_mark_cfqq_must_dispatch(cfqq);
++
+ 	if (!cfq_may_dispatch(cfqd, cfqq))
+ 		return false;
+ 
+ 	/*
+ 	 * follow expired path, else get first next available
+ 	 */
+-	rq = cfq_check_fifo(cfqq);
+ 	if (!rq)
+ 		rq = cfqq->next_rq;
++	else
++		cfq_log_cfqq(cfqq->cfqd, cfqq, "fifo=%p", rq);
+ 
+ 	/*
+ 	 * insert request into driver dispatch list
+@@ -3989,7 +3996,7 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq,
+ 	 * if the new request is sync, but the currently running queue is
+ 	 * not, let the sync request have priority.
+ 	 */
+-	if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq))
++	if (rq_is_sync(rq) && !cfq_cfqq_sync(cfqq) && !cfq_cfqq_must_dispatch(cfqq))
+ 		return true;
+ 
+ 	/*
+diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c
+index 08b3ac68952b..f83de99d7d71 100644
+--- a/crypto/async_tx/async_pq.c
++++ b/crypto/async_tx/async_pq.c
+@@ -368,8 +368,6 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
+ 
+ 		dma_set_unmap(tx, unmap);
+ 		async_tx_submit(chan, tx, submit);
+-
+-		return tx;
+ 	} else {
+ 		struct page *p_src = P(blocks, disks);
+ 		struct page *q_src = Q(blocks, disks);
+@@ -424,9 +422,11 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks,
+ 		submit->cb_param = cb_param_orig;
+ 		submit->flags = flags_orig;
+ 		async_tx_sync_epilog(submit);
+-
+-		return NULL;
++		tx = NULL;
+ 	}
++	dmaengine_unmap_put(unmap);
++
++	return tx;
+ }
+ EXPORT_SYMBOL_GPL(async_syndrome_val);
+ 
+diff --git a/crypto/ghash-generic.c b/crypto/ghash-generic.c
+index bac70995e064..12ad3e3a84e3 100644
+--- a/crypto/ghash-generic.c
++++ b/crypto/ghash-generic.c
+@@ -14,24 +14,13 @@
+ 
+ #include <crypto/algapi.h>
+ #include <crypto/gf128mul.h>
++#include <crypto/ghash.h>
+ #include <crypto/internal/hash.h>
+ #include <linux/crypto.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/module.h>
+ 
+-#define GHASH_BLOCK_SIZE	16
+-#define GHASH_DIGEST_SIZE	16
+-
+-struct ghash_ctx {
+-	struct gf128mul_4k *gf128;
+-};
+-
+-struct ghash_desc_ctx {
+-	u8 buffer[GHASH_BLOCK_SIZE];
+-	u32 bytes;
+-};
+-
+ static int ghash_init(struct shash_desc *desc)
+ {
+ 	struct ghash_desc_ctx *dctx = shash_desc_ctx(desc);
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index e1d5ea6d5e40..2accf784534e 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -2689,6 +2689,9 @@ static void acpi_nfit_notify(struct acpi_device *adev, u32 event)
+ 
+ 	dev_dbg(dev, "%s: event: %d\n", __func__, event);
+ 
++	if (event != NFIT_NOTIFY_UPDATE)
++		return;
++
+ 	device_lock(dev);
+ 	if (!dev->driver) {
+ 		/* dev->driver may be null if we're being removed */
+diff --git a/drivers/acpi/nfit/nfit.h b/drivers/acpi/nfit/nfit.h
+index e894ded24d99..51d23f130d86 100644
+--- a/drivers/acpi/nfit/nfit.h
++++ b/drivers/acpi/nfit/nfit.h
+@@ -78,6 +78,10 @@ enum {
+ 	NFIT_ARS_TIMEOUT = 90,
+ };
+ 
++enum nfit_root_notifiers {
++	NFIT_NOTIFY_UPDATE = 0x80,
++};
++
+ struct nfit_spa {
+ 	struct list_head list;
+ 	struct nd_region *nd_region;
+diff --git a/drivers/base/dma-mapping.c b/drivers/base/dma-mapping.c
+index d799662f19eb..261420ddfe66 100644
+--- a/drivers/base/dma-mapping.c
++++ b/drivers/base/dma-mapping.c
+@@ -334,7 +334,7 @@ void dma_common_free_remap(void *cpu_addr, size_t size, unsigned long vm_flags)
+ 		return;
+ 	}
+ 
+-	unmap_kernel_range((unsigned long)cpu_addr, size);
++	unmap_kernel_range((unsigned long)cpu_addr, PAGE_ALIGN(size));
+ 	vunmap(cpu_addr);
+ }
+ #endif
+diff --git a/drivers/clk/mvebu/cp110-system-controller.c b/drivers/clk/mvebu/cp110-system-controller.c
+index 7fa42d6b2b92..f2303da7fda7 100644
+--- a/drivers/clk/mvebu/cp110-system-controller.c
++++ b/drivers/clk/mvebu/cp110-system-controller.c
+@@ -81,13 +81,6 @@ enum {
+ #define CP110_GATE_EIP150		25
+ #define CP110_GATE_EIP197		26
+ 
+-static struct clk *cp110_clks[CP110_CLK_NUM];
+-
+-static struct clk_onecell_data cp110_clk_data = {
+-	.clks = cp110_clks,
+-	.clk_num = CP110_CLK_NUM,
+-};
+-
+ struct cp110_gate_clk {
+ 	struct clk_hw hw;
+ 	struct regmap *regmap;
+@@ -142,6 +135,8 @@ static struct clk *cp110_register_gate(const char *name,
+ 	if (!gate)
+ 		return ERR_PTR(-ENOMEM);
+ 
++	memset(&init, 0, sizeof(init));
++
+ 	init.name = name;
+ 	init.ops = &cp110_gate_ops;
+ 	init.parent_names = &parent_name;
+@@ -194,7 +189,8 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
+ 	struct regmap *regmap;
+ 	struct device_node *np = pdev->dev.of_node;
+ 	const char *ppv2_name, *apll_name, *core_name, *eip_name, *nand_name;
+-	struct clk *clk;
++	struct clk_onecell_data *cp110_clk_data;
++	struct clk *clk, **cp110_clks;
+ 	u32 nand_clk_ctrl;
+ 	int i, ret;
+ 
+@@ -207,6 +203,20 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
+ 	if (ret)
+ 		return ret;
+ 
++	cp110_clks = devm_kcalloc(&pdev->dev, sizeof(struct clk *),
++				  CP110_CLK_NUM, GFP_KERNEL);
++	if (!cp110_clks)
++		return -ENOMEM;
++
++	cp110_clk_data = devm_kzalloc(&pdev->dev,
++				      sizeof(*cp110_clk_data),
++				      GFP_KERNEL);
++	if (!cp110_clk_data)
++		return -ENOMEM;
++
++	cp110_clk_data->clks = cp110_clks;
++	cp110_clk_data->clk_num = CP110_CLK_NUM;
++
+ 	/* Register the APLL which is the root of the clk tree */
+ 	of_property_read_string_index(np, "core-clock-output-names",
+ 				      CP110_CORE_APLL, &apll_name);
+@@ -334,10 +344,12 @@ static int cp110_syscon_clk_probe(struct platform_device *pdev)
+ 		cp110_clks[CP110_MAX_CORE_CLOCKS + i] = clk;
+ 	}
+ 
+-	ret = of_clk_add_provider(np, cp110_of_clk_get, &cp110_clk_data);
++	ret = of_clk_add_provider(np, cp110_of_clk_get, cp110_clk_data);
+ 	if (ret)
+ 		goto fail_clk_add;
+ 
++	platform_set_drvdata(pdev, cp110_clks);
++
+ 	return 0;
+ 
+ fail_clk_add:
+@@ -364,6 +376,7 @@ fail0:
+ 
+ static int cp110_syscon_clk_remove(struct platform_device *pdev)
+ {
++	struct clk **cp110_clks = platform_get_drvdata(pdev);
+ 	int i;
+ 
+ 	of_clk_del_provider(pdev->dev.of_node);
+diff --git a/drivers/crypto/vmx/ghash.c b/drivers/crypto/vmx/ghash.c
+index 6c999cb01b80..27a94a119009 100644
+--- a/drivers/crypto/vmx/ghash.c
++++ b/drivers/crypto/vmx/ghash.c
+@@ -26,16 +26,13 @@
+ #include <linux/hardirq.h>
+ #include <asm/switch_to.h>
+ #include <crypto/aes.h>
++#include <crypto/ghash.h>
+ #include <crypto/scatterwalk.h>
+ #include <crypto/internal/hash.h>
+ #include <crypto/b128ops.h>
+ 
+ #define IN_INTERRUPT in_interrupt()
+ 
+-#define GHASH_BLOCK_SIZE (16)
+-#define GHASH_DIGEST_SIZE (16)
+-#define GHASH_KEY_LEN (16)
+-
+ void gcm_init_p8(u128 htable[16], const u64 Xi[2]);
+ void gcm_gmult_p8(u64 Xi[2], const u128 htable[16]);
+ void gcm_ghash_p8(u64 Xi[2], const u128 htable[16],
+@@ -55,16 +52,11 @@ struct p8_ghash_desc_ctx {
+ 
+ static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
+ {
+-	const char *alg;
++	const char *alg = "ghash-generic";
+ 	struct crypto_shash *fallback;
+ 	struct crypto_shash *shash_tfm = __crypto_shash_cast(tfm);
+ 	struct p8_ghash_ctx *ctx = crypto_tfm_ctx(tfm);
+ 
+-	if (!(alg = crypto_tfm_alg_name(tfm))) {
+-		printk(KERN_ERR "Failed to get algorithm name.\n");
+-		return -ENOENT;
+-	}
+-
+ 	fallback = crypto_alloc_shash(alg, 0, CRYPTO_ALG_NEED_FALLBACK);
+ 	if (IS_ERR(fallback)) {
+ 		printk(KERN_ERR
+@@ -78,10 +70,18 @@ static int p8_ghash_init_tfm(struct crypto_tfm *tfm)
+ 	crypto_shash_set_flags(fallback,
+ 			       crypto_shash_get_flags((struct crypto_shash
+ 						       *) tfm));
+-	ctx->fallback = fallback;
+ 
+-	shash_tfm->descsize = sizeof(struct p8_ghash_desc_ctx)
+-	    + crypto_shash_descsize(fallback);
++	/* Check if the descsize defined in the algorithm is still enough. */
++	if (shash_tfm->descsize < sizeof(struct p8_ghash_desc_ctx)
++	    + crypto_shash_descsize(fallback)) {
++		printk(KERN_ERR
++		       "Desc size of the fallback implementation (%s) does not match the expected value: %lu vs %u\n",
++		       alg,
++		       shash_tfm->descsize - sizeof(struct p8_ghash_desc_ctx),
++		       crypto_shash_descsize(fallback));
++		return -EINVAL;
++	}
++	ctx->fallback = fallback;
+ 
+ 	return 0;
+ }
+@@ -113,7 +113,7 @@ static int p8_ghash_setkey(struct crypto_shash *tfm, const u8 *key,
+ {
+ 	struct p8_ghash_ctx *ctx = crypto_tfm_ctx(crypto_shash_tfm(tfm));
+ 
+-	if (keylen != GHASH_KEY_LEN)
++	if (keylen != GHASH_BLOCK_SIZE)
+ 		return -EINVAL;
+ 
+ 	preempt_disable();
+@@ -211,7 +211,8 @@ struct shash_alg p8_ghash_alg = {
+ 	.update = p8_ghash_update,
+ 	.final = p8_ghash_final,
+ 	.setkey = p8_ghash_setkey,
+-	.descsize = sizeof(struct p8_ghash_desc_ctx),
++	.descsize = sizeof(struct p8_ghash_desc_ctx)
++		+ sizeof(struct ghash_desc_ctx),
+ 	.base = {
+ 		 .cra_name = "ghash",
+ 		 .cra_driver_name = "p8_ghash",
+diff --git a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
+index 7f0e93f87a55..88a39165edd5 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
++++ b/drivers/gpu/drm/virtio/virtgpu_drm_bus.c
+@@ -27,6 +27,16 @@
+ 
+ #include "virtgpu_drv.h"
+ 
++int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master)
++{
++	struct pci_dev *pdev = dev->pdev;
++
++	if (pdev) {
++		return drm_pci_set_busid(dev, master);
++	}
++	return 0;
++}
++
+ static void virtio_pci_kick_out_firmware_fb(struct pci_dev *pci_dev)
+ {
+ 	struct apertures_struct *ap;
+diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
+index c13f70cfc461..5820b7020ae5 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
++++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
+@@ -117,6 +117,7 @@ static const struct file_operations virtio_gpu_driver_fops = {
+ 
+ static struct drm_driver driver = {
+ 	.driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_PRIME | DRIVER_RENDER | DRIVER_ATOMIC,
++	.set_busid = drm_virtio_set_busid,
+ 	.load = virtio_gpu_driver_load,
+ 	.unload = virtio_gpu_driver_unload,
+ 	.open = virtio_gpu_driver_open,
+diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
+index b18ef3111f0c..acf556a35cb2 100644
+--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
++++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
+@@ -49,6 +49,7 @@
+ #define DRIVER_PATCHLEVEL 1
+ 
+ /* virtgpu_drm_bus.c */
++int drm_virtio_set_busid(struct drm_device *dev, struct drm_master *master);
+ int drm_virtio_init(struct drm_driver *driver, struct virtio_device *vdev);
+ 
+ struct virtio_gpu_object {
+diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
+index 5da190e6011b..bcf76c33726b 100644
+--- a/drivers/infiniband/hw/hfi1/rc.c
++++ b/drivers/infiniband/hw/hfi1/rc.c
+@@ -932,8 +932,10 @@ void hfi1_send_rc_ack(struct hfi1_ctxtdata *rcd, struct rvt_qp *qp,
+ 	return;
+ 
+ queue_ack:
+-	this_cpu_inc(*ibp->rvp.rc_qacks);
+ 	spin_lock_irqsave(&qp->s_lock, flags);
++	if (!(ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK))
++		goto unlock;
++	this_cpu_inc(*ibp->rvp.rc_qacks);
+ 	qp->s_flags |= RVT_S_ACK_PENDING | RVT_S_RESP_PENDING;
+ 	qp->s_nak_state = qp->r_nak_state;
+ 	qp->s_ack_psn = qp->r_ack_psn;
+@@ -942,6 +944,7 @@ queue_ack:
+ 
+ 	/* Schedule the send tasklet. */
+ 	hfi1_schedule_send(qp);
++unlock:
+ 	spin_unlock_irqrestore(&qp->s_lock, flags);
+ }
+ 
+diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
+index a039a5df6f21..fd9271bc1a11 100644
+--- a/drivers/misc/mei/amthif.c
++++ b/drivers/misc/mei/amthif.c
+@@ -67,8 +67,12 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
+ 	struct mei_cl *cl = &dev->iamthif_cl;
+ 	int ret;
+ 
+-	if (mei_cl_is_connected(cl))
+-		return 0;
++	mutex_lock(&dev->device_lock);
++
++	if (mei_cl_is_connected(cl)) {
++		ret = 0;
++		goto out;
++	}
+ 
+ 	dev->iamthif_state = MEI_IAMTHIF_IDLE;
+ 
+@@ -77,11 +81,13 @@ int mei_amthif_host_init(struct mei_device *dev, struct mei_me_client *me_cl)
+ 	ret = mei_cl_link(cl);
+ 	if (ret < 0) {
+ 		dev_err(dev->dev, "amthif: failed cl_link %d\n", ret);
+-		return ret;
++		goto out;
+ 	}
+ 
+ 	ret = mei_cl_connect(cl, me_cl, NULL);
+ 
++out:
++	mutex_unlock(&dev->device_lock);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
+index 1f33fea9299f..e094df3cf2d5 100644
+--- a/drivers/misc/mei/bus.c
++++ b/drivers/misc/mei/bus.c
+@@ -983,12 +983,10 @@ void mei_cl_bus_rescan_work(struct work_struct *work)
+ 		container_of(work, struct mei_device, bus_rescan_work);
+ 	struct mei_me_client *me_cl;
+ 
+-	mutex_lock(&bus->device_lock);
+ 	me_cl = mei_me_cl_by_uuid(bus, &mei_amthif_guid);
+ 	if (me_cl)
+ 		mei_amthif_host_init(bus, me_cl);
+ 	mei_me_cl_put(me_cl);
+-	mutex_unlock(&bus->device_lock);
+ 
+ 	mei_cl_bus_rescan(bus);
+ }
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index d0b3a1bb82ca..dad15b6c66dd 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -11360,6 +11360,12 @@ static pci_ers_result_t i40e_pci_error_detected(struct pci_dev *pdev,
+ 
+ 	dev_info(&pdev->dev, "%s: error %d\n", __func__, error);
+ 
++	if (!pf) {
++		dev_info(&pdev->dev,
++			 "Cannot recover - error happened during device probe\n");
++		return PCI_ERS_RESULT_DISCONNECT;
++	}
++
+ 	/* shutdown all operations */
+ 	if (!test_bit(__I40E_SUSPENDED, &pf->state)) {
+ 		rtnl_lock();
+diff --git a/drivers/net/wireless/ath/carl9170/debug.c b/drivers/net/wireless/ath/carl9170/debug.c
+index 6808db433283..ec3a64e5d2bb 100644
+--- a/drivers/net/wireless/ath/carl9170/debug.c
++++ b/drivers/net/wireless/ath/carl9170/debug.c
+@@ -75,7 +75,8 @@ static ssize_t carl9170_debugfs_read(struct file *file, char __user *userbuf,
+ 
+ 	if (!ar)
+ 		return -ENODEV;
+-	dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct carl9170_debugfs_fops, fops);
+ 
+ 	if (!dfops->read)
+ 		return -ENOSYS;
+@@ -127,7 +128,8 @@ static ssize_t carl9170_debugfs_write(struct file *file,
+ 
+ 	if (!ar)
+ 		return -ENODEV;
+-	dfops = container_of(file->f_op, struct carl9170_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct carl9170_debugfs_fops, fops);
+ 
+ 	if (!dfops->write)
+ 		return -ENOSYS;
+diff --git a/drivers/net/wireless/broadcom/b43/debugfs.c b/drivers/net/wireless/broadcom/b43/debugfs.c
+index b4bcd94aff6c..77046384dd80 100644
+--- a/drivers/net/wireless/broadcom/b43/debugfs.c
++++ b/drivers/net/wireless/broadcom/b43/debugfs.c
+@@ -524,7 +524,8 @@ static ssize_t b43_debugfs_read(struct file *file, char __user *userbuf,
+ 		goto out_unlock;
+ 	}
+ 
+-	dfops = container_of(file->f_op, struct b43_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct b43_debugfs_fops, fops);
+ 	if (!dfops->read) {
+ 		err = -ENOSYS;
+ 		goto out_unlock;
+@@ -585,7 +586,8 @@ static ssize_t b43_debugfs_write(struct file *file,
+ 		goto out_unlock;
+ 	}
+ 
+-	dfops = container_of(file->f_op, struct b43_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct b43_debugfs_fops, fops);
+ 	if (!dfops->write) {
+ 		err = -ENOSYS;
+ 		goto out_unlock;
+diff --git a/drivers/net/wireless/broadcom/b43legacy/debugfs.c b/drivers/net/wireless/broadcom/b43legacy/debugfs.c
+index 090910ea259e..82ef56ed7ca1 100644
+--- a/drivers/net/wireless/broadcom/b43legacy/debugfs.c
++++ b/drivers/net/wireless/broadcom/b43legacy/debugfs.c
+@@ -221,7 +221,8 @@ static ssize_t b43legacy_debugfs_read(struct file *file, char __user *userbuf,
+ 		goto out_unlock;
+ 	}
+ 
+-	dfops = container_of(file->f_op, struct b43legacy_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct b43legacy_debugfs_fops, fops);
+ 	if (!dfops->read) {
+ 		err = -ENOSYS;
+ 		goto out_unlock;
+@@ -287,7 +288,8 @@ static ssize_t b43legacy_debugfs_write(struct file *file,
+ 		goto out_unlock;
+ 	}
+ 
+-	dfops = container_of(file->f_op, struct b43legacy_debugfs_fops, fops);
++	dfops = container_of(debugfs_real_fops(file),
++			     struct b43legacy_debugfs_fops, fops);
+ 	if (!dfops->write) {
+ 		err = -ENOSYS;
+ 		goto out_unlock;
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+index b8aec5e5ef93..abaf003a5b39 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -2533,7 +2533,7 @@ static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
+ 				     WL_BSS_INFO_MAX);
+ 	if (err) {
+ 		brcmf_err("Failed to get bss info (%d)\n", err);
+-		return;
++		goto out_kfree;
+ 	}
+ 	si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
+ 	si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
+@@ -2545,6 +2545,9 @@ static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
+ 		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
+ 	if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ 		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
++
++out_kfree:
++	kfree(buf);
+ }
+ 
+ static s32
+@@ -3884,11 +3887,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
+ 	if (!check_vif_up(ifp->vif))
+ 		return -EIO;
+ 
+-	brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
++	brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
+ 
+ 	npmk = le32_to_cpu(cfg->pmk_list.npmk);
+ 	for (i = 0; i < npmk; i++)
+-		if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
++		if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
+ 			break;
+ 
+ 	if ((npmk > 0) && (i < npmk)) {
+diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+index 7e269f9aa607..63664442e687 100644
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct brcmf_flowring *flow, u16 flowid,
+ 
+ void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid)
+ {
++	struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
+ 	struct brcmf_flowring_ring *ring;
++	struct brcmf_if *ifp;
+ 	u16 hash_idx;
++	u8 ifidx;
+ 	struct sk_buff *skb;
+ 
+ 	ring = flow->rings[flowid];
+ 	if (!ring)
+ 		return;
++
++	ifidx = brcmf_flowring_ifidx_get(flow, flowid);
++	ifp = brcmf_get_ifp(bus_if->drvr, ifidx);
++
+ 	brcmf_flowring_block(flow, flowid, false);
+ 	hash_idx = ring->hash_id;
+ 	flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
+@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid)
+ 
+ 	skb = skb_dequeue(&ring->skblist);
+ 	while (skb) {
+-		brcmu_pkt_buf_free_skb(skb);
++		brcmf_txfinalize(ifp, skb, false);
+ 		skb = skb_dequeue(&ring->skblist);
+ 	}
+ 
+diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
+index 7640498964a5..3d53d636b17b 100644
+--- a/drivers/scsi/arcmsr/arcmsr_hba.c
++++ b/drivers/scsi/arcmsr/arcmsr_hba.c
+@@ -2388,15 +2388,23 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb,
+ 	}
+ 	case ARCMSR_MESSAGE_WRITE_WQBUFFER: {
+ 		unsigned char *ver_addr;
+-		int32_t user_len, cnt2end;
++		uint32_t user_len;
++		int32_t cnt2end;
+ 		uint8_t *pQbuffer, *ptmpuserbuffer;
++
++		user_len = pcmdmessagefld->cmdmessage.Length;
++		if (user_len > ARCMSR_API_DATA_BUFLEN) {
++			retvalue = ARCMSR_MESSAGE_FAIL;
++			goto message_out;
++		}
++
+ 		ver_addr = kmalloc(ARCMSR_API_DATA_BUFLEN, GFP_ATOMIC);
+ 		if (!ver_addr) {
+ 			retvalue = ARCMSR_MESSAGE_FAIL;
+ 			goto message_out;
+ 		}
+ 		ptmpuserbuffer = ver_addr;
+-		user_len = pcmdmessagefld->cmdmessage.Length;
++
+ 		memcpy(ptmpuserbuffer,
+ 			pcmdmessagefld->messagedatabuffer, user_len);
+ 		spin_lock_irqsave(&acb->wqbuffer_lock, flags);
+diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
+index ab67ec4b6bd6..79c9860a165f 100644
+--- a/drivers/scsi/ibmvscsi/ibmvfc.c
++++ b/drivers/scsi/ibmvscsi/ibmvfc.c
+@@ -717,7 +717,6 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost)
+ 	spin_lock_irqsave(vhost->host->host_lock, flags);
+ 	vhost->state = IBMVFC_NO_CRQ;
+ 	vhost->logged_in = 0;
+-	ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
+ 
+ 	/* Clean out the queue */
+ 	memset(crq->msgs, 0, PAGE_SIZE);
+diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
+index e19969614203..b022f5a01e63 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -462,7 +462,7 @@ static int dw8250_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	data->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
+-	if (IS_ERR(data->clk) && PTR_ERR(data->clk) == -EPROBE_DEFER) {
++	if (IS_ERR(data->pclk) && PTR_ERR(data->pclk) == -EPROBE_DEFER) {
+ 		err = -EPROBE_DEFER;
+ 		goto err_clk;
+ 	}
+diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
+index bdfa659b9606..858a54633664 100644
+--- a/drivers/tty/serial/8250/8250_port.c
++++ b/drivers/tty/serial/8250/8250_port.c
+@@ -1414,12 +1414,8 @@ static void __do_stop_tx_rs485(struct uart_8250_port *p)
+ 	if (!(p->port.rs485.flags & SER_RS485_RX_DURING_TX)) {
+ 		serial8250_clear_fifos(p);
+ 
+-		serial8250_rpm_get(p);
+-
+ 		p->ier |= UART_IER_RLSI | UART_IER_RDI;
+ 		serial_port_out(&p->port, UART_IER, p->ier);
+-
+-		serial8250_rpm_put(p);
+ 	}
+ }
+ 
+@@ -1429,6 +1425,7 @@ static void serial8250_em485_handle_stop_tx(unsigned long arg)
+ 	struct uart_8250_em485 *em485 = p->em485;
+ 	unsigned long flags;
+ 
++	serial8250_rpm_get(p);
+ 	spin_lock_irqsave(&p->port.lock, flags);
+ 	if (em485 &&
+ 	    em485->active_timer == &em485->stop_tx_timer) {
+@@ -1436,6 +1433,7 @@ static void serial8250_em485_handle_stop_tx(unsigned long arg)
+ 		em485->active_timer = NULL;
+ 	}
+ 	spin_unlock_irqrestore(&p->port.lock, flags);
++	serial8250_rpm_put(p);
+ }
+ 
+ static void __stop_tx_rs485(struct uart_8250_port *p)
+@@ -1475,7 +1473,7 @@ static inline void __stop_tx(struct uart_8250_port *p)
+ 		unsigned char lsr = serial_in(p, UART_LSR);
+ 		/*
+ 		 * To provide required timeing and allow FIFO transfer,
+-		 * __stop_tx_rs485 must be called only when both FIFO and
++		 * __stop_tx_rs485() must be called only when both FIFO and
+ 		 * shift register are empty. It is for device driver to enable
+ 		 * interrupt on TEMT.
+ 		 */
+@@ -1484,9 +1482,10 @@ static inline void __stop_tx(struct uart_8250_port *p)
+ 
+ 		del_timer(&em485->start_tx_timer);
+ 		em485->active_timer = NULL;
++
++		__stop_tx_rs485(p);
+ 	}
+ 	__do_stop_tx(p);
+-	__stop_tx_rs485(p);
+ }
+ 
+ static void serial8250_stop_tx(struct uart_port *port)
+diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
+index 2eaa18ddef61..8bbde52db376 100644
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -1929,6 +1929,9 @@ static void atmel_shutdown(struct uart_port *port)
+ {
+ 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ 
++	/* Disable modem control lines interrupts */
++	atmel_disable_ms(port);
++
+ 	/* Disable interrupts at device level */
+ 	atmel_uart_writel(port, ATMEL_US_IDR, -1);
+ 
+@@ -1979,8 +1982,6 @@ static void atmel_shutdown(struct uart_port *port)
+ 	 */
+ 	free_irq(port->irq, port);
+ 
+-	atmel_port->ms_irq_enabled = false;
+-
+ 	atmel_flush_buffer(port);
+ }
+ 
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c
+index 0df2b1c091ae..615c0279a1a6 100644
+--- a/drivers/tty/serial/imx.c
++++ b/drivers/tty/serial/imx.c
+@@ -740,12 +740,13 @@ static unsigned int imx_get_hwmctrl(struct imx_port *sport)
+ {
+ 	unsigned int tmp = TIOCM_DSR;
+ 	unsigned usr1 = readl(sport->port.membase + USR1);
++	unsigned usr2 = readl(sport->port.membase + USR2);
+ 
+ 	if (usr1 & USR1_RTSS)
+ 		tmp |= TIOCM_CTS;
+ 
+ 	/* in DCE mode DCDIN is always 0 */
+-	if (!(usr1 & USR2_DCDIN))
++	if (!(usr2 & USR2_DCDIN))
+ 		tmp |= TIOCM_CAR;
+ 
+ 	if (sport->dte_mode)
+diff --git a/fs/attr.c b/fs/attr.c
+index 42bb42bb3c72..3c42cab06b5d 100644
+--- a/fs/attr.c
++++ b/fs/attr.c
+@@ -202,6 +202,21 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
+ 			return -EPERM;
+ 	}
+ 
++	/*
++	 * If utimes(2) and friends are called with times == NULL (or both
++	 * times are UTIME_NOW), then we need to check for write permission
++	 */
++	if (ia_valid & ATTR_TOUCH) {
++		if (IS_IMMUTABLE(inode))
++			return -EPERM;
++
++		if (!inode_owner_or_capable(inode)) {
++			error = inode_permission(inode, MAY_WRITE);
++			if (error)
++				return error;
++		}
++	}
++
+ 	if ((ia_valid & ATTR_MODE)) {
+ 		umode_t amode = attr->ia_mode;
+ 		/* Flag setting protected by i_mutex */
+diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c
+index 431fd7ee3488..e44271dfceb6 100644
+--- a/fs/autofs4/waitq.c
++++ b/fs/autofs4/waitq.c
+@@ -431,8 +431,8 @@ int autofs4_wait(struct autofs_sb_info *sbi,
+ 		memcpy(&wq->name, &qstr, sizeof(struct qstr));
+ 		wq->dev = autofs4_get_dev(sbi);
+ 		wq->ino = autofs4_get_ino(sbi);
+-		wq->uid = current_uid();
+-		wq->gid = current_gid();
++		wq->uid = current_real_cred()->uid;
++		wq->gid = current_real_cred()->gid;
+ 		wq->pid = pid;
+ 		wq->tgid = tgid;
+ 		wq->status = -EINTR; /* Status return if interrupted */
+diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
+index 029db6e1105c..60a850ee8c78 100644
+--- a/fs/btrfs/compression.c
++++ b/fs/btrfs/compression.c
+@@ -698,7 +698,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
+ 
+ 			ret = btrfs_map_bio(root, comp_bio, mirror_num, 0);
+ 			if (ret) {
+-				bio->bi_error = ret;
++				comp_bio->bi_error = ret;
+ 				bio_endio(comp_bio);
+ 			}
+ 
+@@ -728,7 +728,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
+ 
+ 	ret = btrfs_map_bio(root, comp_bio, mirror_num, 0);
+ 	if (ret) {
+-		bio->bi_error = ret;
++		comp_bio->bi_error = ret;
+ 		bio_endio(comp_bio);
+ 	}
+ 
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 33fe03551105..791e47ce9d27 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -251,7 +251,8 @@ struct btrfs_super_block {
+ #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR		0ULL
+ 
+ #define BTRFS_FEATURE_COMPAT_RO_SUPP			\
+-	(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE)
++	(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE |	\
++	 BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID)
+ 
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET	0ULL
+ #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR	0ULL
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 54bc8c7c6bcd..3dede6d53bad 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2566,6 +2566,7 @@ int open_ctree(struct super_block *sb,
+ 	int num_backups_tried = 0;
+ 	int backup_index = 0;
+ 	int max_active;
++	int clear_free_space_tree = 0;
+ 
+ 	tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+ 	chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
+@@ -3129,6 +3130,26 @@ retry_root_backup:
+ 	if (sb->s_flags & MS_RDONLY)
+ 		return 0;
+ 
++	if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
++	    btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
++		clear_free_space_tree = 1;
++	} else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
++		   !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
++		btrfs_warn(fs_info, "free space tree is invalid");
++		clear_free_space_tree = 1;
++	}
++
++	if (clear_free_space_tree) {
++		btrfs_info(fs_info, "clearing free space tree");
++		ret = btrfs_clear_free_space_tree(fs_info);
++		if (ret) {
++			btrfs_warn(fs_info,
++				   "failed to clear free space tree: %d", ret);
++			close_ctree(tree_root);
++			return ret;
++		}
++	}
++
+ 	if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) &&
+ 	    !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
+ 		btrfs_info(fs_info, "creating free space tree");
+@@ -3166,18 +3187,6 @@ retry_root_backup:
+ 
+ 	btrfs_qgroup_rescan_resume(fs_info);
+ 
+-	if (btrfs_test_opt(tree_root->fs_info, CLEAR_CACHE) &&
+-	    btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
+-		btrfs_info(fs_info, "clearing free space tree");
+-		ret = btrfs_clear_free_space_tree(fs_info);
+-		if (ret) {
+-			btrfs_warn(fs_info,
+-				"failed to clear free space tree: %d", ret);
+-			close_ctree(tree_root);
+-			return ret;
+-		}
+-	}
+-
+ 	if (!fs_info->uuid_root) {
+ 		btrfs_info(fs_info, "creating UUID tree");
+ 		ret = btrfs_create_uuid_tree(fs_info);
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index 44fe66b53c8b..c3ec30dea9a5 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -5524,17 +5524,45 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
+ 	}
+ }
+ 
+-/*
+- * The extent buffer bitmap operations are done with byte granularity because
+- * bitmap items are not guaranteed to be aligned to a word and therefore a
+- * single word in a bitmap may straddle two pages in the extent buffer.
+- */
+-#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
+-#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)
+-#define BITMAP_FIRST_BYTE_MASK(start) \
+-	((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)
+-#define BITMAP_LAST_BYTE_MASK(nbits) \
+-	(BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))
++void le_bitmap_set(u8 *map, unsigned int start, int len)
++{
++	u8 *p = map + BIT_BYTE(start);
++	const unsigned int size = start + len;
++	int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
++	u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
++
++	while (len - bits_to_set >= 0) {
++		*p |= mask_to_set;
++		len -= bits_to_set;
++		bits_to_set = BITS_PER_BYTE;
++		mask_to_set = ~(u8)0;
++		p++;
++	}
++	if (len) {
++		mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
++		*p |= mask_to_set;
++	}
++}
++
++void le_bitmap_clear(u8 *map, unsigned int start, int len)
++{
++	u8 *p = map + BIT_BYTE(start);
++	const unsigned int size = start + len;
++	int bits_to_clear = BITS_PER_BYTE - (start % BITS_PER_BYTE);
++	u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(start);
++
++	while (len - bits_to_clear >= 0) {
++		*p &= ~mask_to_clear;
++		len -= bits_to_clear;
++		bits_to_clear = BITS_PER_BYTE;
++		mask_to_clear = ~(u8)0;
++		p++;
++	}
++	if (len) {
++		mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);
++		*p &= ~mask_to_clear;
++	}
++}
+ 
+ /*
+  * eb_bitmap_offset() - calculate the page and offset of the byte containing the
+@@ -5578,7 +5606,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
+ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
+ 			   unsigned long nr)
+ {
+-	char *kaddr;
++	u8 *kaddr;
+ 	struct page *page;
+ 	unsigned long i;
+ 	size_t offset;
+@@ -5600,13 +5628,13 @@ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
+ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+ 			      unsigned long pos, unsigned long len)
+ {
+-	char *kaddr;
++	u8 *kaddr;
+ 	struct page *page;
+ 	unsigned long i;
+ 	size_t offset;
+ 	const unsigned int size = pos + len;
+ 	int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+-	unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
++	u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
+ 
+ 	eb_bitmap_offset(eb, start, pos, &i, &offset);
+ 	page = eb->pages[i];
+@@ -5617,7 +5645,7 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+ 		kaddr[offset] |= mask_to_set;
+ 		len -= bits_to_set;
+ 		bits_to_set = BITS_PER_BYTE;
+-		mask_to_set = ~0U;
++		mask_to_set = ~(u8)0;
+ 		if (++offset >= PAGE_SIZE && len > 0) {
+ 			offset = 0;
+ 			page = eb->pages[++i];
+@@ -5642,13 +5670,13 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
+ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
+ 				unsigned long pos, unsigned long len)
+ {
+-	char *kaddr;
++	u8 *kaddr;
+ 	struct page *page;
+ 	unsigned long i;
+ 	size_t offset;
+ 	const unsigned int size = pos + len;
+ 	int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
+-	unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);
++	u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);
+ 
+ 	eb_bitmap_offset(eb, start, pos, &i, &offset);
+ 	page = eb->pages[i];
+@@ -5659,7 +5687,7 @@ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
+ 		kaddr[offset] &= ~mask_to_clear;
+ 		len -= bits_to_clear;
+ 		bits_to_clear = BITS_PER_BYTE;
+-		mask_to_clear = ~0U;
++		mask_to_clear = ~(u8)0;
+ 		if (++offset >= PAGE_SIZE && len > 0) {
+ 			offset = 0;
+ 			page = eb->pages[++i];
+diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
+index 28cd88fccc7e..1cf4e4226fc8 100644
+--- a/fs/btrfs/extent_io.h
++++ b/fs/btrfs/extent_io.h
+@@ -59,6 +59,28 @@
+  */
+ #define EXTENT_PAGE_PRIVATE 1
+ 
++/*
++ * The extent buffer bitmap operations are done with byte granularity instead of
++ * word granularity for two reasons:
++ * 1. The bitmaps must be little-endian on disk.
++ * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a
++ *    single word in a bitmap may straddle two pages in the extent buffer.
++ */
++#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
++#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)
++#define BITMAP_FIRST_BYTE_MASK(start) \
++	((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)
++#define BITMAP_LAST_BYTE_MASK(nbits) \
++	(BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))
++
++static inline int le_test_bit(int nr, const u8 *addr)
++{
++	return 1U & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE-1)));
++}
++
++extern void le_bitmap_set(u8 *map, unsigned int start, int len);
++extern void le_bitmap_clear(u8 *map, unsigned int start, int len);
++
+ struct extent_state;
+ struct btrfs_root;
+ struct btrfs_io_bio;
+diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
+index 87e7e3d3e676..ea605ffd0e03 100644
+--- a/fs/btrfs/free-space-tree.c
++++ b/fs/btrfs/free-space-tree.c
+@@ -151,7 +151,7 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize)
+ 	return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE);
+ }
+ 
+-static unsigned long *alloc_bitmap(u32 bitmap_size)
++static u8 *alloc_bitmap(u32 bitmap_size)
+ {
+ 	void *mem;
+ 
+@@ -180,8 +180,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
+ 	struct btrfs_free_space_info *info;
+ 	struct btrfs_key key, found_key;
+ 	struct extent_buffer *leaf;
+-	unsigned long *bitmap;
+-	char *bitmap_cursor;
++	u8 *bitmap, *bitmap_cursor;
+ 	u64 start, end;
+ 	u64 bitmap_range, i;
+ 	u32 bitmap_size, flags, expected_extent_count;
+@@ -231,7 +230,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
+ 						block_group->sectorsize);
+ 				last = div_u64(found_key.objectid + found_key.offset - start,
+ 					       block_group->sectorsize);
+-				bitmap_set(bitmap, first, last - first);
++				le_bitmap_set(bitmap, first, last - first);
+ 
+ 				extent_count++;
+ 				nr++;
+@@ -269,7 +268,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
+ 		goto out;
+ 	}
+ 
+-	bitmap_cursor = (char *)bitmap;
++	bitmap_cursor = bitmap;
+ 	bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
+ 	i = start;
+ 	while (i < end) {
+@@ -318,7 +317,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
+ 	struct btrfs_free_space_info *info;
+ 	struct btrfs_key key, found_key;
+ 	struct extent_buffer *leaf;
+-	unsigned long *bitmap;
++	u8 *bitmap;
+ 	u64 start, end;
+ 	/* Initialize to silence GCC. */
+ 	u64 extent_start = 0;
+@@ -362,7 +361,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
+ 				break;
+ 			} else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
+ 				unsigned long ptr;
+-				char *bitmap_cursor;
++				u8 *bitmap_cursor;
+ 				u32 bitmap_pos, data_size;
+ 
+ 				ASSERT(found_key.objectid >= start);
+@@ -372,7 +371,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
+ 				bitmap_pos = div_u64(found_key.objectid - start,
+ 						     block_group->sectorsize *
+ 						     BITS_PER_BYTE);
+-				bitmap_cursor = ((char *)bitmap) + bitmap_pos;
++				bitmap_cursor = bitmap + bitmap_pos;
+ 				data_size = free_space_bitmap_size(found_key.offset,
+ 								   block_group->sectorsize);
+ 
+@@ -409,7 +408,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
+ 	offset = start;
+ 	bitnr = 0;
+ 	while (offset < end) {
+-		bit = !!test_bit(bitnr, bitmap);
++		bit = !!le_test_bit(bitnr, bitmap);
+ 		if (prev_bit == 0 && bit == 1) {
+ 			extent_start = offset;
+ 		} else if (prev_bit == 1 && bit == 0) {
+@@ -1183,6 +1182,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
+ 	}
+ 
+ 	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
++	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
+ 	fs_info->creating_free_space_tree = 0;
+ 
+ 	ret = btrfs_commit_transaction(trans, tree_root);
+@@ -1251,6 +1251,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
+ 		return PTR_ERR(trans);
+ 
+ 	btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);
++	btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
+ 	fs_info->free_space_root = NULL;
+ 
+ 	ret = clear_free_space_tree(trans, free_space_root);
+diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c
+index ce5f345d70f5..e7f16a77a22a 100644
+--- a/fs/cachefiles/interface.c
++++ b/fs/cachefiles/interface.c
+@@ -253,6 +253,8 @@ static void cachefiles_drop_object(struct fscache_object *_object)
+ 	struct cachefiles_object *object;
+ 	struct cachefiles_cache *cache;
+ 	const struct cred *saved_cred;
++	struct inode *inode;
++	blkcnt_t i_blocks = 0;
+ 
+ 	ASSERT(_object);
+ 
+@@ -279,6 +281,10 @@ static void cachefiles_drop_object(struct fscache_object *_object)
+ 		    _object != cache->cache.fsdef
+ 		    ) {
+ 			_debug("- retire object OBJ%x", object->fscache.debug_id);
++			inode = d_backing_inode(object->dentry);
++			if (inode)
++				i_blocks = inode->i_blocks;
++
+ 			cachefiles_begin_secure(cache, &saved_cred);
+ 			cachefiles_delete_object(cache, object);
+ 			cachefiles_end_secure(cache, saved_cred);
+@@ -292,7 +298,7 @@ static void cachefiles_drop_object(struct fscache_object *_object)
+ 
+ 	/* note that the object is now inactive */
+ 	if (test_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags))
+-		cachefiles_mark_object_inactive(cache, object);
++		cachefiles_mark_object_inactive(cache, object, i_blocks);
+ 
+ 	dput(object->dentry);
+ 	object->dentry = NULL;
+diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h
+index 2fcde1a34b7c..cd1effee8a49 100644
+--- a/fs/cachefiles/internal.h
++++ b/fs/cachefiles/internal.h
+@@ -160,7 +160,8 @@ extern char *cachefiles_cook_key(const u8 *raw, int keylen, uint8_t type);
+  * namei.c
+  */
+ extern void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
+-					    struct cachefiles_object *object);
++					    struct cachefiles_object *object,
++					    blkcnt_t i_blocks);
+ extern int cachefiles_delete_object(struct cachefiles_cache *cache,
+ 				    struct cachefiles_object *object);
+ extern int cachefiles_walk_to_object(struct cachefiles_object *parent,
+diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
+index 3f7c2cd41f8f..c6ee4b5fb7e6 100644
+--- a/fs/cachefiles/namei.c
++++ b/fs/cachefiles/namei.c
+@@ -261,10 +261,9 @@ requeue:
+  * Mark an object as being inactive.
+  */
+ void cachefiles_mark_object_inactive(struct cachefiles_cache *cache,
+-				     struct cachefiles_object *object)
++				     struct cachefiles_object *object,
++				     blkcnt_t i_blocks)
+ {
+-	blkcnt_t i_blocks = d_backing_inode(object->dentry)->i_blocks;
+-
+ 	write_lock(&cache->active_lock);
+ 	rb_erase(&object->active_node, &cache->active_nodes);
+ 	clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags);
+@@ -707,7 +706,8 @@ mark_active_timed_out:
+ 
+ check_error:
+ 	_debug("check error %d", ret);
+-	cachefiles_mark_object_inactive(cache, object);
++	cachefiles_mark_object_inactive(
++		cache, object, d_backing_inode(object->dentry)->i_blocks);
+ release_dentry:
+ 	dput(object->dentry);
+ 	object->dentry = NULL;
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
+index 592059f88e04..309f4e9b2419 100644
+--- a/fs/debugfs/file.c
++++ b/fs/debugfs/file.c
+@@ -97,9 +97,6 @@ EXPORT_SYMBOL_GPL(debugfs_use_file_finish);
+ 
+ #define F_DENTRY(filp) ((filp)->f_path.dentry)
+ 
+-#define REAL_FOPS_DEREF(dentry)					\
+-	((const struct file_operations *)(dentry)->d_fsdata)
+-
+ static int open_proxy_open(struct inode *inode, struct file *filp)
+ {
+ 	const struct dentry *dentry = F_DENTRY(filp);
+@@ -112,7 +109,7 @@ static int open_proxy_open(struct inode *inode, struct file *filp)
+ 		goto out;
+ 	}
+ 
+-	real_fops = REAL_FOPS_DEREF(dentry);
++	real_fops = debugfs_real_fops(filp);
+ 	real_fops = fops_get(real_fops);
+ 	if (!real_fops) {
+ 		/* Huh? Module did not clean up after itself at exit? */
+@@ -143,7 +140,7 @@ static ret_type full_proxy_ ## name(proto)				\
+ {									\
+ 	const struct dentry *dentry = F_DENTRY(filp);			\
+ 	const struct file_operations *real_fops =			\
+-		REAL_FOPS_DEREF(dentry);				\
++		debugfs_real_fops(filp);				\
+ 	int srcu_idx;							\
+ 	ret_type r;							\
+ 									\
+@@ -176,7 +173,7 @@ static unsigned int full_proxy_poll(struct file *filp,
+ 				struct poll_table_struct *wait)
+ {
+ 	const struct dentry *dentry = F_DENTRY(filp);
+-	const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry);
++	const struct file_operations *real_fops = debugfs_real_fops(filp);
+ 	int srcu_idx;
+ 	unsigned int r = 0;
+ 
+@@ -193,7 +190,7 @@ static unsigned int full_proxy_poll(struct file *filp,
+ static int full_proxy_release(struct inode *inode, struct file *filp)
+ {
+ 	const struct dentry *dentry = F_DENTRY(filp);
+-	const struct file_operations *real_fops = REAL_FOPS_DEREF(dentry);
++	const struct file_operations *real_fops = debugfs_real_fops(filp);
+ 	const struct file_operations *proxy_fops = filp->f_op;
+ 	int r = 0;
+ 
+@@ -241,7 +238,7 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
+ 		goto out;
+ 	}
+ 
+-	real_fops = REAL_FOPS_DEREF(dentry);
++	real_fops = debugfs_real_fops(filp);
+ 	real_fops = fops_get(real_fops);
+ 	if (!real_fops) {
+ 		/* Huh? Module did not cleanup after itself at exit? */
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c
+index 963016c8f3d1..609998de533e 100644
+--- a/fs/dlm/lowcomms.c
++++ b/fs/dlm/lowcomms.c
+@@ -1656,16 +1656,12 @@ void dlm_lowcomms_stop(void)
+ 	mutex_lock(&connections_lock);
+ 	dlm_allow_conn = 0;
+ 	foreach_conn(stop_conn);
++	clean_writequeues();
++	foreach_conn(free_conn);
+ 	mutex_unlock(&connections_lock);
+ 
+ 	work_stop();
+ 
+-	mutex_lock(&connections_lock);
+-	clean_writequeues();
+-
+-	foreach_conn(free_conn);
+-
+-	mutex_unlock(&connections_lock);
+ 	kmem_cache_destroy(con_cache);
+ }
+ 
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index d7ccb7f51dfc..7f69347bd5a5 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -5734,6 +5734,9 @@ int ext4_insert_range(struct inode *inode, loff_t offset, loff_t len)
+ 			up_write(&EXT4_I(inode)->i_data_sem);
+ 			goto out_stop;
+ 		}
++	} else {
++		ext4_ext_drop_refs(path);
++		kfree(path);
+ 	}
+ 
+ 	ret = ext4_es_remove_extent(inode, offset_lblk,
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index c6ea25a190f8..f4cdc647ecfc 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -647,11 +647,19 @@ found:
+ 		/*
+ 		 * We have to zeroout blocks before inserting them into extent
+ 		 * status tree. Otherwise someone could look them up there and
+-		 * use them before they are really zeroed.
++		 * use them before they are really zeroed. We also have to
++		 * unmap metadata before zeroing as otherwise writeback can
++		 * overwrite zeros with stale data from block device.
+ 		 */
+ 		if (flags & EXT4_GET_BLOCKS_ZERO &&
+ 		    map->m_flags & EXT4_MAP_MAPPED &&
+ 		    map->m_flags & EXT4_MAP_NEW) {
++			ext4_lblk_t i;
++
++			for (i = 0; i < map->m_len; i++) {
++				unmap_underlying_metadata(inode->i_sb->s_bdev,
++							  map->m_pblk + i);
++			}
+ 			ret = ext4_issue_zeroout(inode, map->m_lblk,
+ 						 map->m_pblk, map->m_len);
+ 			if (ret) {
+@@ -1649,6 +1657,8 @@ static void mpage_release_unused_pages(struct mpage_da_data *mpd,
+ 			BUG_ON(!PageLocked(page));
+ 			BUG_ON(PageWriteback(page));
+ 			if (invalidate) {
++				if (page_mapped(page))
++					clear_page_dirty_for_io(page);
+ 				block_invalidatepage(page, 0, PAGE_SIZE);
+ 				ClearPageUptodate(page);
+ 			}
+@@ -3890,7 +3900,7 @@ int ext4_update_disksize_before_punch(struct inode *inode, loff_t offset,
+ }
+ 
+ /*
+- * ext4_punch_hole: punches a hole in a file by releaseing the blocks
++ * ext4_punch_hole: punches a hole in a file by releasing the blocks
+  * associated with the given offset and length
+  *
+  * @inode:  File inode
+@@ -3919,7 +3929,7 @@ int ext4_punch_hole(struct inode *inode, loff_t offset, loff_t length)
+ 	 * Write out all dirty pages to avoid race conditions
+ 	 * Then release them.
+ 	 */
+-	if (mapping->nrpages && mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
++	if (mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) {
+ 		ret = filemap_write_and_wait_range(mapping, offset,
+ 						   offset + length - 1);
+ 		if (ret)
+@@ -4814,14 +4824,14 @@ static int ext4_do_update_inode(handle_t *handle,
+  * Fix up interoperability with old kernels. Otherwise, old inodes get
+  * re-used with the upper 16 bits of the uid/gid intact
+  */
+-		if (!ei->i_dtime) {
++		if (ei->i_dtime && list_empty(&ei->i_orphan)) {
++			raw_inode->i_uid_high = 0;
++			raw_inode->i_gid_high = 0;
++		} else {
+ 			raw_inode->i_uid_high =
+ 				cpu_to_le16(high_16_bits(i_uid));
+ 			raw_inode->i_gid_high =
+ 				cpu_to_le16(high_16_bits(i_gid));
+-		} else {
+-			raw_inode->i_uid_high = 0;
+-			raw_inode->i_gid_high = 0;
+ 		}
+ 	} else {
+ 		raw_inode->i_uid_low = cpu_to_le16(fs_high2lowuid(i_uid));
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index a920c5d29fac..6fc14def0c70 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -598,6 +598,13 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
+ 		return -EOPNOTSUPP;
+ 	}
+ 
++	if (ext4_encrypted_inode(orig_inode) ||
++	    ext4_encrypted_inode(donor_inode)) {
++		ext4_msg(orig_inode->i_sb, KERN_ERR,
++			 "Online defrag not supported for encrypted files");
++		return -EOPNOTSUPP;
++	}
++
+ 	/* Protect orig and donor inodes against a truncate */
+ 	lock_two_nondirectories(orig_inode, donor_inode);
+ 
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 34c0142caf6a..7e2f8c3c11ce 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2044,33 +2044,31 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,
+ 	frame->entries = entries;
+ 	frame->at = entries;
+ 	frame->bh = bh;
+-	bh = bh2;
+ 
+ 	retval = ext4_handle_dirty_dx_node(handle, dir, frame->bh);
+ 	if (retval)
+ 		goto out_frames;	
+-	retval = ext4_handle_dirty_dirent_node(handle, dir, bh);
++	retval = ext4_handle_dirty_dirent_node(handle, dir, bh2);
+ 	if (retval)
+ 		goto out_frames;	
+ 
+-	de = do_split(handle,dir, &bh, frame, &fname->hinfo);
++	de = do_split(handle,dir, &bh2, frame, &fname->hinfo);
+ 	if (IS_ERR(de)) {
+ 		retval = PTR_ERR(de);
+ 		goto out_frames;
+ 	}
+-	dx_release(frames);
+ 
+-	retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh);
+-	brelse(bh);
+-	return retval;
++	retval = add_dirent_to_buf(handle, fname, dir, inode, de, bh2);
+ out_frames:
+ 	/*
+ 	 * Even if the block split failed, we have to properly write
+ 	 * out all the changes we did so far. Otherwise we can end up
+ 	 * with corrupted filesystem.
+ 	 */
+-	ext4_mark_inode_dirty(handle, dir);
++	if (retval)
++		ext4_mark_inode_dirty(handle, dir);
+ 	dx_release(frames);
++	brelse(bh2);
+ 	return retval;
+ }
+ 
+diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
+index 4d83d9e05f2e..04a7850a0d45 100644
+--- a/fs/ext4/symlink.c
++++ b/fs/ext4/symlink.c
+@@ -65,13 +65,12 @@ static const char *ext4_encrypted_get_link(struct dentry *dentry,
+ 	res = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
+ 	if (res)
+ 		goto errout;
++	paddr = pstr.name;
+ 
+ 	res = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr);
+ 	if (res < 0)
+ 		goto errout;
+ 
+-	paddr = pstr.name;
+-
+ 	/* Null-terminate the name */
+ 	if (res <= pstr.len)
+ 		paddr[res] = '\0';
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index c47b7780ce37..4ff9251e9d3a 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -1702,14 +1702,46 @@ error:
+ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+ {
+ 	struct inode *inode = d_inode(entry);
++	struct file *file = (attr->ia_valid & ATTR_FILE) ? attr->ia_file : NULL;
++	int ret;
+ 
+ 	if (!fuse_allow_current_process(get_fuse_conn(inode)))
+ 		return -EACCES;
+ 
+-	if (attr->ia_valid & ATTR_FILE)
+-		return fuse_do_setattr(inode, attr, attr->ia_file);
+-	else
+-		return fuse_do_setattr(inode, attr, NULL);
++	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
++		int kill;
++
++		attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
++				    ATTR_MODE);
++		/*
++		 * ia_mode calculation may have used stale i_mode.  Refresh and
++		 * recalculate.
++		 */
++		ret = fuse_do_getattr(inode, NULL, file);
++		if (ret)
++			return ret;
++
++		attr->ia_mode = inode->i_mode;
++		kill = should_remove_suid(entry);
++		if (kill & ATTR_KILL_SUID) {
++			attr->ia_valid |= ATTR_MODE;
++			attr->ia_mode &= ~S_ISUID;
++		}
++		if (kill & ATTR_KILL_SGID) {
++			attr->ia_valid |= ATTR_MODE;
++			attr->ia_mode &= ~S_ISGID;
++		}
++	}
++	if (!attr->ia_valid)
++		return 0;
++
++	ret = fuse_do_setattr(inode, attr, file);
++	if (!ret) {
++		/* Directory mode changed, may need to revalidate access */
++		if (d_is_dir(entry) && (attr->ia_valid & ATTR_MODE))
++			fuse_invalidate_entry_cache(entry);
++	}
++	return ret;
+ }
+ 
+ static int fuse_getattr(struct vfsmount *mnt, struct dentry *entry,
+@@ -1801,6 +1833,23 @@ static ssize_t fuse_getxattr(struct dentry *entry, struct inode *inode,
+ 	return ret;
+ }
+ 
++static int fuse_verify_xattr_list(char *list, size_t size)
++{
++	size_t origsize = size;
++
++	while (size) {
++		size_t thislen = strnlen(list, size);
++
++		if (!thislen || thislen == size)
++			return -EIO;
++
++		size -= thislen + 1;
++		list += thislen + 1;
++	}
++
++	return origsize;
++}
++
+ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
+ {
+ 	struct inode *inode = d_inode(entry);
+@@ -1836,6 +1885,8 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
+ 	ret = fuse_simple_request(fc, &args);
+ 	if (!ret && !size)
+ 		ret = outarg.size;
++	if (ret > 0 && size)
++		ret = fuse_verify_xattr_list(list, ret);
+ 	if (ret == -ENOSYS) {
+ 		fc->no_listxattr = 1;
+ 		ret = -EOPNOTSUPP;
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index b5bc3e249163..3d8246a9faa4 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -159,6 +159,7 @@ static void wait_transaction_locked(journal_t *journal)
+ 	read_unlock(&journal->j_state_lock);
+ 	if (need_to_start)
+ 		jbd2_log_start_commit(journal, tid);
++	jbd2_might_wait_for_commit(journal);
+ 	schedule();
+ 	finish_wait(&journal->j_wait_transaction_locked, &wait);
+ }
+@@ -182,8 +183,6 @@ static int add_transaction_credits(journal_t *journal, int blocks,
+ 	int needed;
+ 	int total = blocks + rsv_blocks;
+ 
+-	jbd2_might_wait_for_commit(journal);
+-
+ 	/*
+ 	 * If the current transaction is locked down for commit, wait
+ 	 * for the lock to be released.
+@@ -214,6 +213,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
+ 		if (atomic_read(&journal->j_reserved_credits) + total >
+ 		    journal->j_max_transaction_buffers) {
+ 			read_unlock(&journal->j_state_lock);
++			jbd2_might_wait_for_commit(journal);
+ 			wait_event(journal->j_wait_reserved,
+ 				   atomic_read(&journal->j_reserved_credits) + total <=
+ 				   journal->j_max_transaction_buffers);
+@@ -238,6 +238,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
+ 	if (jbd2_log_space_left(journal) < jbd2_space_needed(journal)) {
+ 		atomic_sub(total, &t->t_outstanding_credits);
+ 		read_unlock(&journal->j_state_lock);
++		jbd2_might_wait_for_commit(journal);
+ 		write_lock(&journal->j_state_lock);
+ 		if (jbd2_log_space_left(journal) < jbd2_space_needed(journal))
+ 			__jbd2_log_wait_for_space(journal);
+@@ -255,6 +256,7 @@ static int add_transaction_credits(journal_t *journal, int blocks,
+ 		sub_reserved_credits(journal, rsv_blocks);
+ 		atomic_sub(total, &t->t_outstanding_credits);
+ 		read_unlock(&journal->j_state_lock);
++		jbd2_might_wait_for_commit(journal);
+ 		wait_event(journal->j_wait_reserved,
+ 			 atomic_read(&journal->j_reserved_credits) + rsv_blocks
+ 			 <= journal->j_max_transaction_buffers / 2);
+diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
+index 7a4a85a6821e..74d5ddd26296 100644
+--- a/fs/reiserfs/super.c
++++ b/fs/reiserfs/super.c
+@@ -190,7 +190,15 @@ static int remove_save_link_only(struct super_block *s,
+ static int reiserfs_quota_on_mount(struct super_block *, int);
+ #endif
+ 
+-/* look for uncompleted unlinks and truncates and complete them */
++/*
++ * Look for uncompleted unlinks and truncates and complete them
++ *
++ * Called with superblock write locked.  If quotas are enabled, we have to
++ * release/retake lest we call dquot_quota_on_mount(), proceed to
++ * schedule_on_each_cpu() in invalidate_bdev() and deadlock waiting for the per
++ * cpu worklets to complete flush_async_commits() that in turn wait for the
++ * superblock write lock.
++ */
+ static int finish_unfinished(struct super_block *s)
+ {
+ 	INITIALIZE_PATH(path);
+@@ -237,7 +245,9 @@ static int finish_unfinished(struct super_block *s)
+ 				quota_enabled[i] = 0;
+ 				continue;
+ 			}
++			reiserfs_write_unlock(s);
+ 			ret = reiserfs_quota_on_mount(s, i);
++			reiserfs_write_lock(s);
+ 			if (ret < 0)
+ 				reiserfs_warning(s, "reiserfs-2500",
+ 						 "cannot turn on journaled "
+diff --git a/fs/utimes.c b/fs/utimes.c
+index 794f5f5b1fb5..ba54b9e648c9 100644
+--- a/fs/utimes.c
++++ b/fs/utimes.c
+@@ -87,21 +87,7 @@ static int utimes_common(struct path *path, struct timespec *times)
+ 		 */
+ 		newattrs.ia_valid |= ATTR_TIMES_SET;
+ 	} else {
+-		/*
+-		 * If times is NULL (or both times are UTIME_NOW),
+-		 * then we need to check permissions, because
+-		 * inode_change_ok() won't do it.
+-		 */
+-		error = -EPERM;
+-                if (IS_IMMUTABLE(inode))
+-			goto mnt_drop_write_and_out;
+-
+-		error = -EACCES;
+-		if (!inode_owner_or_capable(inode)) {
+-			error = inode_permission(inode, MAY_WRITE);
+-			if (error)
+-				goto mnt_drop_write_and_out;
+-		}
++		newattrs.ia_valid |= ATTR_TOUCH;
+ 	}
+ retry_deleg:
+ 	inode_lock(inode);
+@@ -113,7 +99,6 @@ retry_deleg:
+ 			goto retry_deleg;
+ 	}
+ 
+-mnt_drop_write_and_out:
+ 	mnt_drop_write(path->mnt);
+ out:
+ 	return error;
+diff --git a/include/crypto/ghash.h b/include/crypto/ghash.h
+new file mode 100644
+index 000000000000..2a61c9bbab8f
+--- /dev/null
++++ b/include/crypto/ghash.h
+@@ -0,0 +1,23 @@
++/*
++ * Common values for GHASH algorithms
++ */
++
++#ifndef __CRYPTO_GHASH_H__
++#define __CRYPTO_GHASH_H__
++
++#include <linux/types.h>
++#include <crypto/gf128mul.h>
++
++#define GHASH_BLOCK_SIZE	16
++#define GHASH_DIGEST_SIZE	16
++
++struct ghash_ctx {
++	struct gf128mul_4k *gf128;
++};
++
++struct ghash_desc_ctx {
++	u8 buffer[GHASH_BLOCK_SIZE];
++	u32 bytes;
++};
++
++#endif
+diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
+index 1438e2322d5c..4d3f0d1aec73 100644
+--- a/include/linux/debugfs.h
++++ b/include/linux/debugfs.h
+@@ -45,6 +45,23 @@ extern struct dentry *arch_debugfs_dir;
+ 
+ extern struct srcu_struct debugfs_srcu;
+ 
++/**
++ * debugfs_real_fops - getter for the real file operation
++ * @filp: a pointer to a struct file
++ *
++ * Must only be called under the protection established by
++ * debugfs_use_file_start().
++ */
++static inline const struct file_operations *debugfs_real_fops(struct file *filp)
++	__must_hold(&debugfs_srcu)
++{
++	/*
++	 * Neither the pointer to the struct file_operations, nor its
++	 * contents ever change -- srcu_dereference() is not needed here.
++	 */
++	return filp->f_path.dentry->d_fsdata;
++}
++
+ #if defined(CONFIG_DEBUG_FS)
+ 
+ struct dentry *debugfs_create_file(const char *name, umode_t mode,
+diff --git a/include/linux/fs.h b/include/linux/fs.h
+index 901e25d495cc..7c391366fb43 100644
+--- a/include/linux/fs.h
++++ b/include/linux/fs.h
+@@ -224,6 +224,7 @@ typedef int (dio_iodone_t)(struct kiocb *iocb, loff_t offset,
+ #define ATTR_KILL_PRIV	(1 << 14)
+ #define ATTR_OPEN	(1 << 15) /* Truncating from open(O_TRUNC) */
+ #define ATTR_TIMES_SET	(1 << 16)
++#define ATTR_TOUCH	(1 << 17)
+ 
+ /*
+  * Whiteout is represented by a char device.  The following constants define the
+diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
+index 4c45105dece3..52b97db93830 100644
+--- a/include/linux/radix-tree.h
++++ b/include/linux/radix-tree.h
+@@ -280,9 +280,9 @@ bool __radix_tree_delete_node(struct radix_tree_root *root,
+ 			      struct radix_tree_node *node);
+ void *radix_tree_delete_item(struct radix_tree_root *, unsigned long, void *);
+ void *radix_tree_delete(struct radix_tree_root *, unsigned long);
+-struct radix_tree_node *radix_tree_replace_clear_tags(
+-				struct radix_tree_root *root,
+-				unsigned long index, void *entry);
++void radix_tree_clear_tags(struct radix_tree_root *root,
++			   struct radix_tree_node *node,
++			   void **slot);
+ unsigned int radix_tree_gang_lookup(struct radix_tree_root *root,
+ 			void **results, unsigned long first_index,
+ 			unsigned int max_items);
+diff --git a/include/linux/sem.h b/include/linux/sem.h
+index 976ce3a19f1b..d0efd6e6c20a 100644
+--- a/include/linux/sem.h
++++ b/include/linux/sem.h
+@@ -21,6 +21,7 @@ struct sem_array {
+ 	struct list_head	list_id;	/* undo requests on this array */
+ 	int			sem_nsems;	/* no. of semaphores in array */
+ 	int			complex_count;	/* pending complex operations */
++	bool			complex_mode;	/* no parallel simple ops */
+ };
+ 
+ #ifdef CONFIG_SYSVIPC
+diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
+index ac5eacd3055b..db4c253f8011 100644
+--- a/include/uapi/linux/btrfs.h
++++ b/include/uapi/linux/btrfs.h
+@@ -239,7 +239,17 @@ struct btrfs_ioctl_fs_info_args {
+  * Used by:
+  * struct btrfs_ioctl_feature_flags
+  */
+-#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE	(1ULL << 0)
++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE		(1ULL << 0)
++/*
++ * Older kernels (< 4.9) on big-endian systems produced broken free space tree
++ * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions
++ * < 4.7.3).  If this bit is clear, then the free space tree cannot be trusted.
++ * btrfs-progs can also intentionally clear this bit to ask the kernel to
++ * rebuild the free space tree, however this might not work on older kernels
++ * that do not know about this bit. If not sure, clear the cache manually on
++ * first mount when booting older kernel versions.
++ */
++#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID	(1ULL << 1)
+ 
+ #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF	(1ULL << 0)
+ #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL	(1ULL << 1)
+diff --git a/ipc/sem.c b/ipc/sem.c
+index 7c9d4f7683c0..5e318c5f749d 100644
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -162,14 +162,21 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
+ 
+ /*
+  * Locking:
++ * a) global sem_lock() for read/write
+  *	sem_undo.id_next,
+  *	sem_array.complex_count,
+- *	sem_array.pending{_alter,_cont},
+- *	sem_array.sem_undo: global sem_lock() for read/write
+- *	sem_undo.proc_next: only "current" is allowed to read/write that field.
++ *	sem_array.complex_mode
++ *	sem_array.pending{_alter,_const},
++ *	sem_array.sem_undo
+  *
++ * b) global or semaphore sem_lock() for read/write:
+  *	sem_array.sem_base[i].pending_{const,alter}:
+- *		global or semaphore sem_lock() for read/write
++ *	sem_array.complex_mode (for read)
++ *
++ * c) special:
++ *	sem_undo_list.list_proc:
++ *	* undo_list->lock for write
++ *	* rcu for read
+  */
+ 
+ #define sc_semmsl	sem_ctls[0]
+@@ -260,30 +267,61 @@ static void sem_rcu_free(struct rcu_head *head)
+ }
+ 
+ /*
+- * Wait until all currently ongoing simple ops have completed.
++ * Enter the mode suitable for non-simple operations:
+  * Caller must own sem_perm.lock.
+- * New simple ops cannot start, because simple ops first check
+- * that sem_perm.lock is free.
+- * that a) sem_perm.lock is free and b) complex_count is 0.
+  */
+-static void sem_wait_array(struct sem_array *sma)
++static void complexmode_enter(struct sem_array *sma)
+ {
+ 	int i;
+ 	struct sem *sem;
+ 
+-	if (sma->complex_count)  {
+-		/* The thread that increased sma->complex_count waited on
+-		 * all sem->lock locks. Thus we don't need to wait again.
+-		 */
++	if (sma->complex_mode)  {
++		/* We are already in complex_mode. Nothing to do */
+ 		return;
+ 	}
+ 
++	/* We need a full barrier after seting complex_mode:
++	 * The write to complex_mode must be visible
++	 * before we read the first sem->lock spinlock state.
++	 */
++	smp_store_mb(sma->complex_mode, true);
++
+ 	for (i = 0; i < sma->sem_nsems; i++) {
+ 		sem = sma->sem_base + i;
+ 		spin_unlock_wait(&sem->lock);
+ 	}
++	/*
++	 * spin_unlock_wait() is not a memory barriers, it is only a
++	 * control barrier. The code must pair with spin_unlock(&sem->lock),
++	 * thus just the control barrier is insufficient.
++	 *
++	 * smp_rmb() is sufficient, as writes cannot pass the control barrier.
++	 */
++	smp_rmb();
++}
++
++/*
++ * Try to leave the mode that disallows simple operations:
++ * Caller must own sem_perm.lock.
++ */
++static void complexmode_tryleave(struct sem_array *sma)
++{
++	if (sma->complex_count)  {
++		/* Complex ops are sleeping.
++		 * We must stay in complex mode
++		 */
++		return;
++	}
++	/*
++	 * Immediately after setting complex_mode to false,
++	 * a simple op can start. Thus: all memory writes
++	 * performed by the current operation must be visible
++	 * before we set complex_mode to false.
++	 */
++	smp_store_release(&sma->complex_mode, false);
+ }
+ 
++#define SEM_GLOBAL_LOCK	(-1)
+ /*
+  * If the request contains only one semaphore operation, and there are
+  * no complex transactions pending, lock only the semaphore involved.
+@@ -300,56 +338,42 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
+ 		/* Complex operation - acquire a full lock */
+ 		ipc_lock_object(&sma->sem_perm);
+ 
+-		/* And wait until all simple ops that are processed
+-		 * right now have dropped their locks.
+-		 */
+-		sem_wait_array(sma);
+-		return -1;
++		/* Prevent parallel simple ops */
++		complexmode_enter(sma);
++		return SEM_GLOBAL_LOCK;
+ 	}
+ 
+ 	/*
+ 	 * Only one semaphore affected - try to optimize locking.
+-	 * The rules are:
+-	 * - optimized locking is possible if no complex operation
+-	 *   is either enqueued or processed right now.
+-	 * - The test for enqueued complex ops is simple:
+-	 *      sma->complex_count != 0
+-	 * - Testing for complex ops that are processed right now is
+-	 *   a bit more difficult. Complex ops acquire the full lock
+-	 *   and first wait that the running simple ops have completed.
+-	 *   (see above)
+-	 *   Thus: If we own a simple lock and the global lock is free
+-	 *	and complex_count is now 0, then it will stay 0 and
+-	 *	thus just locking sem->lock is sufficient.
++	 * Optimized locking is possible if no complex operation
++	 * is either enqueued or processed right now.
++	 *
++	 * Both facts are tracked by complex_mode.
+ 	 */
+ 	sem = sma->sem_base + sops->sem_num;
+ 
+-	if (sma->complex_count == 0) {
++	/*
++	 * Initial check for complex_mode. Just an optimization,
++	 * no locking, no memory barrier.
++	 */
++	if (!sma->complex_mode) {
+ 		/*
+ 		 * It appears that no complex operation is around.
+ 		 * Acquire the per-semaphore lock.
+ 		 */
+ 		spin_lock(&sem->lock);
+ 
+-		/* Then check that the global lock is free */
+-		if (!spin_is_locked(&sma->sem_perm.lock)) {
+-			/*
+-			 * We need a memory barrier with acquire semantics,
+-			 * otherwise we can race with another thread that does:
+-			 *	complex_count++;
+-			 *	spin_unlock(sem_perm.lock);
+-			 */
+-			smp_acquire__after_ctrl_dep();
++		/*
++		 * See 51d7d5205d33
++		 * ("powerpc: Add smp_mb() to arch_spin_is_locked()"):
++		 * A full barrier is required: the write of sem->lock
++		 * must be visible before the read is executed
++		 */
++		smp_mb();
+ 
+-			/*
+-			 * Now repeat the test of complex_count:
+-			 * It can't change anymore until we drop sem->lock.
+-			 * Thus: if is now 0, then it will stay 0.
+-			 */
+-			if (sma->complex_count == 0) {
+-				/* fast path successful! */
+-				return sops->sem_num;
+-			}
++		if (!smp_load_acquire(&sma->complex_mode)) {
++			/* fast path successful! */
++			return sops->sem_num;
+ 		}
+ 		spin_unlock(&sem->lock);
+ 	}
+@@ -369,15 +393,16 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
+ 		/* Not a false alarm, thus complete the sequence for a
+ 		 * full lock.
+ 		 */
+-		sem_wait_array(sma);
+-		return -1;
++		complexmode_enter(sma);
++		return SEM_GLOBAL_LOCK;
+ 	}
+ }
+ 
+ static inline void sem_unlock(struct sem_array *sma, int locknum)
+ {
+-	if (locknum == -1) {
++	if (locknum == SEM_GLOBAL_LOCK) {
+ 		unmerge_queues(sma);
++		complexmode_tryleave(sma);
+ 		ipc_unlock_object(&sma->sem_perm);
+ 	} else {
+ 		struct sem *sem = sma->sem_base + locknum;
+@@ -529,6 +554,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
+ 	}
+ 
+ 	sma->complex_count = 0;
++	sma->complex_mode = true; /* dropped by sem_unlock below */
+ 	INIT_LIST_HEAD(&sma->pending_alter);
+ 	INIT_LIST_HEAD(&sma->pending_const);
+ 	INIT_LIST_HEAD(&sma->list_id);
+@@ -2184,10 +2210,10 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
+ 	/*
+ 	 * The proc interface isn't aware of sem_lock(), it calls
+ 	 * ipc_lock_object() directly (in sysvipc_find_ipc).
+-	 * In order to stay compatible with sem_lock(), we must wait until
+-	 * all simple semop() calls have left their critical regions.
++	 * In order to stay compatible with sem_lock(), we must
++	 * enter / leave complex_mode.
+ 	 */
+-	sem_wait_array(sma);
++	complexmode_enter(sma);
+ 
+ 	sem_otime = get_semotime(sma);
+ 
+@@ -2204,6 +2230,8 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
+ 		   sem_otime,
+ 		   sma->sem_ctime);
+ 
++	complexmode_tryleave(sma);
++
+ 	return 0;
+ }
+ #endif
+diff --git a/lib/radix-tree.c b/lib/radix-tree.c
+index 91f0727e3cad..8e6d552c40dd 100644
+--- a/lib/radix-tree.c
++++ b/lib/radix-tree.c
+@@ -1583,15 +1583,10 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
+ }
+ EXPORT_SYMBOL(radix_tree_delete);
+ 
+-struct radix_tree_node *radix_tree_replace_clear_tags(
+-			struct radix_tree_root *root,
+-			unsigned long index, void *entry)
++void radix_tree_clear_tags(struct radix_tree_root *root,
++			   struct radix_tree_node *node,
++			   void **slot)
+ {
+-	struct radix_tree_node *node;
+-	void **slot;
+-
+-	__radix_tree_lookup(root, index, &node, &slot);
+-
+ 	if (node) {
+ 		unsigned int tag, offset = get_slot_offset(node, slot);
+ 		for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++)
+@@ -1600,9 +1595,6 @@ struct radix_tree_node *radix_tree_replace_clear_tags(
+ 		/* Clear root node tags */
+ 		root->gfp_mask &= __GFP_BITS_MASK;
+ 	}
+-
+-	radix_tree_replace_slot(slot, entry);
+-	return node;
+ }
+ 
+ /**
+diff --git a/mm/filemap.c b/mm/filemap.c
+index 2d0986a64f1f..ced9ef6c06b0 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -169,33 +169,35 @@ static int page_cache_tree_insert(struct address_space *mapping,
+ static void page_cache_tree_delete(struct address_space *mapping,
+ 				   struct page *page, void *shadow)
+ {
+-	struct radix_tree_node *node;
+ 	int i, nr = PageHuge(page) ? 1 : hpage_nr_pages(page);
+ 
+ 	VM_BUG_ON_PAGE(!PageLocked(page), page);
+ 	VM_BUG_ON_PAGE(PageTail(page), page);
+ 	VM_BUG_ON_PAGE(nr != 1 && shadow, page);
+ 
+-	if (shadow) {
+-		mapping->nrexceptional += nr;
+-		/*
+-		 * Make sure the nrexceptional update is committed before
+-		 * the nrpages update so that final truncate racing
+-		 * with reclaim does not see both counters 0 at the
+-		 * same time and miss a shadow entry.
+-		 */
+-		smp_wmb();
+-	}
+-	mapping->nrpages -= nr;
+-
+ 	for (i = 0; i < nr; i++) {
+-		node = radix_tree_replace_clear_tags(&mapping->page_tree,
+-				page->index + i, shadow);
++		struct radix_tree_node *node;
++		void **slot;
++
++		__radix_tree_lookup(&mapping->page_tree, page->index + i,
++				    &node, &slot);
++
++		radix_tree_clear_tags(&mapping->page_tree, node, slot);
++
+ 		if (!node) {
+ 			VM_BUG_ON_PAGE(nr != 1, page);
+-			return;
++			/*
++			 * We need a node to properly account shadow
++			 * entries. Don't plant any without. XXX
++			 */
++			shadow = NULL;
+ 		}
+ 
++		radix_tree_replace_slot(slot, shadow);
++
++		if (!node)
++			break;
++
+ 		workingset_node_pages_dec(node);
+ 		if (shadow)
+ 			workingset_node_shadows_inc(node);
+@@ -219,6 +221,18 @@ static void page_cache_tree_delete(struct address_space *mapping,
+ 					&node->private_list);
+ 		}
+ 	}
++
++	if (shadow) {
++		mapping->nrexceptional += nr;
++		/*
++		 * Make sure the nrexceptional update is committed before
++		 * the nrpages update so that final truncate racing
++		 * with reclaim does not see both counters 0 at the
++		 * same time and miss a shadow entry.
++		 */
++		smp_wmb();
++	}
++	mapping->nrpages -= nr;
+ }
+ 
+ /*
+@@ -619,7 +633,6 @@ int replace_page_cache_page(struct page *old, struct page *new, gfp_t gfp_mask)
+ 		__delete_from_page_cache(old, NULL);
+ 		error = page_cache_tree_insert(mapping, new, NULL);
+ 		BUG_ON(error);
+-		mapping->nrpages++;
+ 
+ 		/*
+ 		 * hugetlb pages do not participate in page cache accounting.
+@@ -1674,6 +1687,10 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos,
+ 	unsigned int prev_offset;
+ 	int error = 0;
+ 
++	if (unlikely(*ppos >= inode->i_sb->s_maxbytes))
++		return -EINVAL;
++	iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
++
+ 	index = *ppos >> PAGE_SHIFT;
+ 	prev_index = ra->prev_pos >> PAGE_SHIFT;
+ 	prev_offset = ra->prev_pos & (PAGE_SIZE-1);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 87e11d8ad536..603bdd01ec2c 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1443,13 +1443,14 @@ static void dissolve_free_huge_page(struct page *page)
+ {
+ 	spin_lock(&hugetlb_lock);
+ 	if (PageHuge(page) && !page_count(page)) {
+-		struct hstate *h = page_hstate(page);
+-		int nid = page_to_nid(page);
+-		list_del(&page->lru);
++		struct page *head = compound_head(page);
++		struct hstate *h = page_hstate(head);
++		int nid = page_to_nid(head);
++		list_del(&head->lru);
+ 		h->free_huge_pages--;
+ 		h->free_huge_pages_node[nid]--;
+ 		h->max_huge_pages--;
+-		update_and_free_page(h, page);
++		update_and_free_page(h, head);
+ 	}
+ 	spin_unlock(&hugetlb_lock);
+ }
+@@ -1457,7 +1458,8 @@ static void dissolve_free_huge_page(struct page *page)
+ /*
+  * Dissolve free hugepages in a given pfn range. Used by memory hotplug to
+  * make specified memory blocks removable from the system.
+- * Note that start_pfn should aligned with (minimum) hugepage size.
++ * Note that this will dissolve a free gigantic hugepage completely, if any
++ * part of it lies within the given range.
+  */
+ void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
+ {
+@@ -1466,7 +1468,6 @@ void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
+ 	if (!hugepages_supported())
+ 		return;
+ 
+-	VM_BUG_ON(!IS_ALIGNED(start_pfn, 1 << minimum_order));
+ 	for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order)
+ 		dissolve_free_huge_page(pfn_to_page(pfn));
+ }
+diff --git a/sound/soc/codecs/nau8825.c b/sound/soc/codecs/nau8825.c
+index 2e59a85e360b..ff566376da40 100644
+--- a/sound/soc/codecs/nau8825.c
++++ b/sound/soc/codecs/nau8825.c
+@@ -1907,7 +1907,7 @@ static int nau8825_calc_fll_param(unsigned int fll_in, unsigned int fs,
+ 	/* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional
+ 	 * input based on FDCO, FREF and FLL ratio.
+ 	 */
+-	fvco = div_u64(fvco << 16, fref * fll_param->ratio);
++	fvco = div_u64(fvco_max << 16, fref * fll_param->ratio);
+ 	fll_param->fll_int = (fvco >> 16) & 0x3FF;
+ 	fll_param->fll_frac = fvco & 0xFFFF;
+ 	return 0;
+diff --git a/sound/soc/intel/atom/sst/sst_pvt.c b/sound/soc/intel/atom/sst/sst_pvt.c
+index adb32fefd693..b1e6b8f34a6a 100644
+--- a/sound/soc/intel/atom/sst/sst_pvt.c
++++ b/sound/soc/intel/atom/sst/sst_pvt.c
+@@ -279,17 +279,15 @@ int sst_prepare_and_post_msg(struct intel_sst_drv *sst,
+ 
+ 	if (response) {
+ 		ret = sst_wait_timeout(sst, block);
+-		if (ret < 0) {
++		if (ret < 0)
+ 			goto out;
+-		} else if(block->data) {
+-			if (!data)
+-				goto out;
+-			*data = kzalloc(block->size, GFP_KERNEL);
+-			if (!(*data)) {
++
++		if (data && block->data) {
++			*data = kmemdup(block->data, block->size, GFP_KERNEL);
++			if (!*data) {
+ 				ret = -ENOMEM;
+ 				goto out;
+-			} else
+-				memcpy(data, (void *) block->data, block->size);
++			}
+ 		}
+ 	}
+ out:


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-23 13:59 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-10-23 13:59 UTC (permalink / raw
  To: gentoo-commits

commit:     5f366798d7e0ab4865e24b35e1f3af8b438d9d4b
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 23 13:59:25 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sun Oct 23 13:59:25 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5f366798

BFQ patchset for 4.8 v7r11.

 0000_README                                        |   16 +
 ...oups-kconfig-build-bits-for-BFQ-v7r11-4.8.patch |  103 +
 ...ntroduce-the-BFQ-v7r11-I-O-sched-for-4.8.patch1 | 7110 +++++++++++++++++++
 ...arly-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch | 1101 +++
 ...-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1 | 7392 ++++++++++++++++++++
 5 files changed, 15722 insertions(+)

diff --git a/0000_README b/0000_README
index 5a8b43e..c65f1ed 100644
--- a/0000_README
+++ b/0000_README
@@ -87,6 +87,22 @@ Patch:  5000_enable-additional-cpu-optimizations-for-gcc.patch
 From:   https://github.com/graysky2/kernel_gcc_patch/
 Desc:   Kernel patch enables gcc < v4.9 optimizations for additional CPUs.
 
+Patch:  5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.patch
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 1 for 4.8: Build, cgroups and kconfig bits
+
+Patch:  5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.8.patch1
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 2 for 4.8: BFQ Scheduler
+
+Patch:  5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 3 for 4.8: Early Queue Merge (EQM)
+
+Patch:  5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v8r3 patch 4 for 4.8: Early Queue Merge (EQM)
+
 Patch:  5010_enable-additional-cpu-optimizations-for-gcc.patch
 From:   https://github.com/graysky2/kernel_gcc_patch/
 Desc:   Kernel patch enables gcc >= v4.9 optimizations for additional CPUs.

diff --git a/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.patch b/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.patch
new file mode 100644
index 0000000..35cd1ce
--- /dev/null
+++ b/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.8.patch
@@ -0,0 +1,103 @@
+From f2ebe596e7d72e96e0fb2be87be90f0b96e6f1b3 Mon Sep 17 00:00:00 2001
+From: Paolo Valente <paolo.valente@unimore.it>
+Date: Tue, 7 Apr 2015 13:39:12 +0200
+Subject: [PATCH 1/4] block: cgroups, kconfig, build bits for BFQ-v7r11-4.8.0
+
+Update Kconfig.iosched and do the related Makefile changes to include
+kernel configuration options for BFQ. Also increase the number of
+policies supported by the blkio controller so that BFQ can add its
+own.
+
+Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
+Signed-off-by: Arianna Avanzini <avanzini@google.com>
+---
+ block/Kconfig.iosched  | 32 ++++++++++++++++++++++++++++++++
+ block/Makefile         |  1 +
+ include/linux/blkdev.h |  2 +-
+ 3 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
+index 421bef9..0ee5f0f 100644
+--- a/block/Kconfig.iosched
++++ b/block/Kconfig.iosched
+@@ -39,6 +39,27 @@ config CFQ_GROUP_IOSCHED
+ 	---help---
+ 	  Enable group IO scheduling in CFQ.
+ 
++config IOSCHED_BFQ
++	tristate "BFQ I/O scheduler"
++	default n
++	---help---
++	  The BFQ I/O scheduler tries to distribute bandwidth among
++	  all processes according to their weights.
++	  It aims at distributing the bandwidth as desired, independently of
++	  the disk parameters and with any workload. It also tries to
++	  guarantee low latency to interactive and soft real-time
++	  applications. If compiled built-in (saying Y here), BFQ can
++	  be configured to support hierarchical scheduling.
++
++config CGROUP_BFQIO
++	bool "BFQ hierarchical scheduling support"
++	depends on CGROUPS && IOSCHED_BFQ=y
++	default n
++	---help---
++	  Enable hierarchical scheduling in BFQ, using the cgroups
++	  filesystem interface.  The name of the subsystem will be
++	  bfqio.
++
+ choice
+ 	prompt "Default I/O scheduler"
+ 	default DEFAULT_CFQ
+@@ -52,6 +73,16 @@ choice
+ 	config DEFAULT_CFQ
+ 		bool "CFQ" if IOSCHED_CFQ=y
+ 
++	config DEFAULT_BFQ
++		bool "BFQ" if IOSCHED_BFQ=y
++		help
++		  Selects BFQ as the default I/O scheduler which will be
++		  used by default for all block devices.
++		  The BFQ I/O scheduler aims at distributing the bandwidth
++		  as desired, independently of the disk parameters and with
++		  any workload. It also tries to guarantee low latency to
++		  interactive and soft real-time applications.
++
+ 	config DEFAULT_NOOP
+ 		bool "No-op"
+ 
+@@ -61,6 +92,7 @@ config DEFAULT_IOSCHED
+ 	string
+ 	default "deadline" if DEFAULT_DEADLINE
+ 	default "cfq" if DEFAULT_CFQ
++	default "bfq" if DEFAULT_BFQ
+ 	default "noop" if DEFAULT_NOOP
+ 
+ endmenu
+diff --git a/block/Makefile b/block/Makefile
+index 9eda232..4a36683 100644
+--- a/block/Makefile
++++ b/block/Makefile
+@@ -18,6 +18,7 @@ obj-$(CONFIG_BLK_DEV_THROTTLING)	+= blk-throttle.o
+ obj-$(CONFIG_IOSCHED_NOOP)	+= noop-iosched.o
+ obj-$(CONFIG_IOSCHED_DEADLINE)	+= deadline-iosched.o
+ obj-$(CONFIG_IOSCHED_CFQ)	+= cfq-iosched.o
++obj-$(CONFIG_IOSCHED_BFQ)	+= bfq-iosched.o
+ 
+ obj-$(CONFIG_BLOCK_COMPAT)	+= compat_ioctl.o
+ obj-$(CONFIG_BLK_CMDLINE_PARSER)	+= cmdline-parser.o
+diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
+index e79055c..931ff1e 100644
+--- a/include/linux/blkdev.h
++++ b/include/linux/blkdev.h
+@@ -45,7 +45,7 @@ struct pr_ops;
+  * Maximum number of blkcg policies allowed to be registered concurrently.
+  * Defined here to simplify include dependency.
+  */
+-#define BLKCG_MAX_POLS		2
++#define BLKCG_MAX_POLS		3
+ 
+ typedef void (rq_end_io_fn)(struct request *, int);
+ 
+-- 
+2.7.4 (Apple Git-66)
+

diff --git a/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.8.patch1 b/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.8.patch1
new file mode 100644
index 0000000..7cc8ce1
--- /dev/null
+++ b/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.8.patch1
@@ -0,0 +1,7110 @@
+From d9af6fcc4167cbb8433b10bbf3663c8297487f52 Mon Sep 17 00:00:00 2001
+From: Paolo Valente <paolo.valente@unimore.it>
+Date: Thu, 9 May 2013 19:10:02 +0200
+Subject: [PATCH 2/4] block: introduce the BFQ-v7r11 I/O sched, to be ported to
+ 4.8.0
+
+The general structure is borrowed from CFQ, as much of the code for
+handling I/O contexts. Over time, several useful features have been
+ported from CFQ as well (details in the changelog in README.BFQ). A
+(bfq_)queue is associated to each task doing I/O on a device, and each
+time a scheduling decision has to be made a queue is selected and served
+until it expires.
+
+    - Slices are given in the service domain: tasks are assigned
+      budgets, measured in number of sectors. Once got the disk, a task
+      must however consume its assigned budget within a configurable
+      maximum time (by default, the maximum possible value of the
+      budgets is automatically computed to comply with this timeout).
+      This allows the desired latency vs "throughput boosting" tradeoff
+      to be set.
+
+    - Budgets are scheduled according to a variant of WF2Q+, implemented
+      using an augmented rb-tree to take eligibility into account while
+      preserving an O(log N) overall complexity.
+
+    - A low-latency tunable is provided; if enabled, both interactive
+      and soft real-time applications are guaranteed a very low latency.
+
+    - Latency guarantees are preserved also in the presence of NCQ.
+
+    - Also with flash-based devices, a high throughput is achieved
+      while still preserving latency guarantees.
+
+    - BFQ features Early Queue Merge (EQM), a sort of fusion of the
+      cooperating-queue-merging and the preemption mechanisms present
+      in CFQ. EQM is in fact a unified mechanism that tries to get a
+      sequential read pattern, and hence a high throughput, with any
+      set of processes performing interleaved I/O over a contiguous
+      sequence of sectors.
+
+    - BFQ supports full hierarchical scheduling, exporting a cgroups
+      interface.  Since each node has a full scheduler, each group can
+      be assigned its own weight.
+
+    - If the cgroups interface is not used, only I/O priorities can be
+      assigned to processes, with ioprio values mapped to weights
+      with the relation weight = IOPRIO_BE_NR - ioprio.
+
+    - ioprio classes are served in strict priority order, i.e., lower
+      priority queues are not served as long as there are higher
+      priority queues.  Among queues in the same class the bandwidth is
+      distributed in proportion to the weight of each queue. A very
+      thin extra bandwidth is however guaranteed to the Idle class, to
+      prevent it from starving.
+
+Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
+Signed-off-by: Arianna Avanzini <avanzini@google.com>
+---
+ block/Kconfig.iosched |    6 +-
+ block/bfq-cgroup.c    | 1186 ++++++++++++++++
+ block/bfq-ioc.c       |   36 +
+ block/bfq-iosched.c   | 3763 +++++++++++++++++++++++++++++++++++++++++++++++++
+ block/bfq-sched.c     | 1199 ++++++++++++++++
+ block/bfq.h           |  801 +++++++++++
+ 6 files changed, 6987 insertions(+), 4 deletions(-)
+ create mode 100644 block/bfq-cgroup.c
+ create mode 100644 block/bfq-ioc.c
+ create mode 100644 block/bfq-iosched.c
+ create mode 100644 block/bfq-sched.c
+ create mode 100644 block/bfq.h
+
+diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
+index 0ee5f0f..f78cd1a 100644
+--- a/block/Kconfig.iosched
++++ b/block/Kconfig.iosched
+@@ -51,14 +51,12 @@ config IOSCHED_BFQ
+ 	  applications. If compiled built-in (saying Y here), BFQ can
+ 	  be configured to support hierarchical scheduling.
+ 
+-config CGROUP_BFQIO
++config BFQ_GROUP_IOSCHED
+ 	bool "BFQ hierarchical scheduling support"
+ 	depends on CGROUPS && IOSCHED_BFQ=y
+ 	default n
+ 	---help---
+-	  Enable hierarchical scheduling in BFQ, using the cgroups
+-	  filesystem interface.  The name of the subsystem will be
+-	  bfqio.
++	  Enable hierarchical scheduling in BFQ, using the blkio controller.
+ 
+ choice
+ 	prompt "Default I/O scheduler"
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+new file mode 100644
+index 0000000..8b08a57
+--- /dev/null
++++ b/block/bfq-cgroup.c
+@@ -0,0 +1,1186 @@
++/*
++ * BFQ: CGROUPS support.
++ *
++ * Based on ideas and code from CFQ:
++ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
++ *
++ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
++ *		      Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
++ * file.
++ */
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++
++/* bfqg stats flags */
++enum bfqg_stats_flags {
++	BFQG_stats_waiting = 0,
++	BFQG_stats_idling,
++	BFQG_stats_empty,
++};
++
++#define BFQG_FLAG_FNS(name)						\
++static void bfqg_stats_mark_##name(struct bfqg_stats *stats)	\
++{									\
++	stats->flags |= (1 << BFQG_stats_##name);			\
++}									\
++static void bfqg_stats_clear_##name(struct bfqg_stats *stats)	\
++{									\
++	stats->flags &= ~(1 << BFQG_stats_##name);			\
++}									\
++static int bfqg_stats_##name(struct bfqg_stats *stats)		\
++{									\
++	return (stats->flags & (1 << BFQG_stats_##name)) != 0;		\
++}									\
++
++BFQG_FLAG_FNS(waiting)
++BFQG_FLAG_FNS(idling)
++BFQG_FLAG_FNS(empty)
++#undef BFQG_FLAG_FNS
++
++/* This should be called with the queue_lock held. */
++static void bfqg_stats_update_group_wait_time(struct bfqg_stats *stats)
++{
++	unsigned long long now;
++
++	if (!bfqg_stats_waiting(stats))
++		return;
++
++	now = sched_clock();
++	if (time_after64(now, stats->start_group_wait_time))
++		blkg_stat_add(&stats->group_wait_time,
++			      now - stats->start_group_wait_time);
++	bfqg_stats_clear_waiting(stats);
++}
++
++/* This should be called with the queue_lock held. */
++static void bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg,
++						 struct bfq_group *curr_bfqg)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++
++	if (bfqg_stats_waiting(stats))
++		return;
++	if (bfqg == curr_bfqg)
++		return;
++	stats->start_group_wait_time = sched_clock();
++	bfqg_stats_mark_waiting(stats);
++}
++
++/* This should be called with the queue_lock held. */
++static void bfqg_stats_end_empty_time(struct bfqg_stats *stats)
++{
++	unsigned long long now;
++
++	if (!bfqg_stats_empty(stats))
++		return;
++
++	now = sched_clock();
++	if (time_after64(now, stats->start_empty_time))
++		blkg_stat_add(&stats->empty_time,
++			      now - stats->start_empty_time);
++	bfqg_stats_clear_empty(stats);
++}
++
++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg)
++{
++	blkg_stat_add(&bfqg->stats.dequeue, 1);
++}
++
++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++
++	if (blkg_rwstat_total(&stats->queued))
++		return;
++
++	/*
++	 * group is already marked empty. This can happen if bfqq got new
++	 * request in parent group and moved to this group while being added
++	 * to service tree. Just ignore the event and move on.
++	 */
++	if (bfqg_stats_empty(stats))
++		return;
++
++	stats->start_empty_time = sched_clock();
++	bfqg_stats_mark_empty(stats);
++}
++
++static void bfqg_stats_update_idle_time(struct bfq_group *bfqg)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++
++	if (bfqg_stats_idling(stats)) {
++		unsigned long long now = sched_clock();
++
++		if (time_after64(now, stats->start_idle_time))
++			blkg_stat_add(&stats->idle_time,
++				      now - stats->start_idle_time);
++		bfqg_stats_clear_idling(stats);
++	}
++}
++
++static void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++
++	stats->start_idle_time = sched_clock();
++	bfqg_stats_mark_idling(stats);
++}
++
++static void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++
++	blkg_stat_add(&stats->avg_queue_size_sum,
++		      blkg_rwstat_total(&stats->queued));
++	blkg_stat_add(&stats->avg_queue_size_samples, 1);
++	bfqg_stats_update_group_wait_time(stats);
++}
++
++static struct blkcg_policy blkcg_policy_bfq;
++
++/*
++ * blk-cgroup policy-related handlers
++ * The following functions help in converting between blk-cgroup
++ * internal structures and BFQ-specific structures.
++ */
++
++static struct bfq_group *pd_to_bfqg(struct blkg_policy_data *pd)
++{
++	return pd ? container_of(pd, struct bfq_group, pd) : NULL;
++}
++
++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg)
++{
++	return pd_to_blkg(&bfqg->pd);
++}
++
++static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg)
++{
++	struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq);
++
++	BUG_ON(!pd);
++
++	return pd_to_bfqg(pd);
++}
++
++/*
++ * bfq_group handlers
++ * The following functions help in navigating the bfq_group hierarchy
++ * by allowing to find the parent of a bfq_group or the bfq_group
++ * associated to a bfq_queue.
++ */
++
++static struct bfq_group *bfqg_parent(struct bfq_group *bfqg)
++{
++	struct blkcg_gq *pblkg = bfqg_to_blkg(bfqg)->parent;
++
++	return pblkg ? blkg_to_bfqg(pblkg) : NULL;
++}
++
++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
++{
++	struct bfq_entity *group_entity = bfqq->entity.parent;
++
++	return group_entity ? container_of(group_entity, struct bfq_group,
++					   entity) :
++			      bfqq->bfqd->root_group;
++}
++
++/*
++ * The following two functions handle get and put of a bfq_group by
++ * wrapping the related blk-cgroup hooks.
++ */
++
++static void bfqg_get(struct bfq_group *bfqg)
++{
++	return blkg_get(bfqg_to_blkg(bfqg));
++}
++
++static void bfqg_put(struct bfq_group *bfqg)
++{
++	return blkg_put(bfqg_to_blkg(bfqg));
++}
++
++static void bfqg_stats_update_io_add(struct bfq_group *bfqg,
++				     struct bfq_queue *bfqq,
++				     int rw)
++{
++	blkg_rwstat_add(&bfqg->stats.queued, rw, 1);
++	bfqg_stats_end_empty_time(&bfqg->stats);
++	if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue))
++		bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq));
++}
++
++static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int rw)
++{
++	blkg_rwstat_add(&bfqg->stats.queued, rw, -1);
++}
++
++static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw)
++{
++	blkg_rwstat_add(&bfqg->stats.merged, rw, 1);
++}
++
++static void bfqg_stats_update_dispatch(struct bfq_group *bfqg,
++					      uint64_t bytes, int rw)
++{
++	blkg_stat_add(&bfqg->stats.sectors, bytes >> 9);
++	blkg_rwstat_add(&bfqg->stats.serviced, rw, 1);
++	blkg_rwstat_add(&bfqg->stats.service_bytes, rw, bytes);
++}
++
++static void bfqg_stats_update_completion(struct bfq_group *bfqg,
++			uint64_t start_time, uint64_t io_start_time, int rw)
++{
++	struct bfqg_stats *stats = &bfqg->stats;
++	unsigned long long now = sched_clock();
++
++	if (time_after64(now, io_start_time))
++		blkg_rwstat_add(&stats->service_time, rw, now - io_start_time);
++	if (time_after64(io_start_time, start_time))
++		blkg_rwstat_add(&stats->wait_time, rw,
++				io_start_time - start_time);
++}
++
++/* @stats = 0 */
++static void bfqg_stats_reset(struct bfqg_stats *stats)
++{
++	if (!stats)
++		return;
++
++	/* queued stats shouldn't be cleared */
++	blkg_rwstat_reset(&stats->service_bytes);
++	blkg_rwstat_reset(&stats->serviced);
++	blkg_rwstat_reset(&stats->merged);
++	blkg_rwstat_reset(&stats->service_time);
++	blkg_rwstat_reset(&stats->wait_time);
++	blkg_stat_reset(&stats->time);
++	blkg_stat_reset(&stats->unaccounted_time);
++	blkg_stat_reset(&stats->avg_queue_size_sum);
++	blkg_stat_reset(&stats->avg_queue_size_samples);
++	blkg_stat_reset(&stats->dequeue);
++	blkg_stat_reset(&stats->group_wait_time);
++	blkg_stat_reset(&stats->idle_time);
++	blkg_stat_reset(&stats->empty_time);
++}
++
++/* @to += @from */
++static void bfqg_stats_merge(struct bfqg_stats *to, struct bfqg_stats *from)
++{
++	if (!to || !from)
++		return;
++
++	/* queued stats shouldn't be cleared */
++	blkg_rwstat_add_aux(&to->service_bytes, &from->service_bytes);
++	blkg_rwstat_add_aux(&to->serviced, &from->serviced);
++	blkg_rwstat_add_aux(&to->merged, &from->merged);
++	blkg_rwstat_add_aux(&to->service_time, &from->service_time);
++	blkg_rwstat_add_aux(&to->wait_time, &from->wait_time);
++	blkg_stat_add_aux(&from->time, &from->time);
++	blkg_stat_add_aux(&to->unaccounted_time, &from->unaccounted_time);
++	blkg_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum);
++	blkg_stat_add_aux(&to->avg_queue_size_samples,
++			  &from->avg_queue_size_samples);
++	blkg_stat_add_aux(&to->dequeue, &from->dequeue);
++	blkg_stat_add_aux(&to->group_wait_time, &from->group_wait_time);
++	blkg_stat_add_aux(&to->idle_time, &from->idle_time);
++	blkg_stat_add_aux(&to->empty_time, &from->empty_time);
++}
++
++/*
++ * Transfer @bfqg's stats to its parent's dead_stats so that the ancestors'
++ * recursive stats can still account for the amount used by this bfqg after
++ * it's gone.
++ */
++static void bfqg_stats_xfer_dead(struct bfq_group *bfqg)
++{
++	struct bfq_group *parent;
++
++	if (!bfqg) /* root_group */
++		return;
++
++	parent = bfqg_parent(bfqg);
++
++	lockdep_assert_held(bfqg_to_blkg(bfqg)->q->queue_lock);
++
++	if (unlikely(!parent))
++		return;
++
++	bfqg_stats_merge(&parent->dead_stats, &bfqg->stats);
++	bfqg_stats_merge(&parent->dead_stats, &bfqg->dead_stats);
++	bfqg_stats_reset(&bfqg->stats);
++	bfqg_stats_reset(&bfqg->dead_stats);
++}
++
++static void bfq_init_entity(struct bfq_entity *entity,
++			    struct bfq_group *bfqg)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++	entity->weight = entity->new_weight;
++	entity->orig_weight = entity->new_weight;
++	if (bfqq) {
++		bfqq->ioprio = bfqq->new_ioprio;
++		bfqq->ioprio_class = bfqq->new_ioprio_class;
++		bfqg_get(bfqg);
++	}
++	entity->parent = bfqg->my_entity;
++	entity->sched_data = &bfqg->sched_data;
++}
++
++static void bfqg_stats_exit(struct bfqg_stats *stats)
++{
++	blkg_rwstat_exit(&stats->service_bytes);
++	blkg_rwstat_exit(&stats->serviced);
++	blkg_rwstat_exit(&stats->merged);
++	blkg_rwstat_exit(&stats->service_time);
++	blkg_rwstat_exit(&stats->wait_time);
++	blkg_rwstat_exit(&stats->queued);
++	blkg_stat_exit(&stats->sectors);
++	blkg_stat_exit(&stats->time);
++	blkg_stat_exit(&stats->unaccounted_time);
++	blkg_stat_exit(&stats->avg_queue_size_sum);
++	blkg_stat_exit(&stats->avg_queue_size_samples);
++	blkg_stat_exit(&stats->dequeue);
++	blkg_stat_exit(&stats->group_wait_time);
++	blkg_stat_exit(&stats->idle_time);
++	blkg_stat_exit(&stats->empty_time);
++}
++
++static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
++{
++	if (blkg_rwstat_init(&stats->service_bytes, gfp) ||
++	    blkg_rwstat_init(&stats->serviced, gfp) ||
++	    blkg_rwstat_init(&stats->merged, gfp) ||
++	    blkg_rwstat_init(&stats->service_time, gfp) ||
++	    blkg_rwstat_init(&stats->wait_time, gfp) ||
++	    blkg_rwstat_init(&stats->queued, gfp) ||
++	    blkg_stat_init(&stats->sectors, gfp) ||
++	    blkg_stat_init(&stats->time, gfp) ||
++	    blkg_stat_init(&stats->unaccounted_time, gfp) ||
++	    blkg_stat_init(&stats->avg_queue_size_sum, gfp) ||
++	    blkg_stat_init(&stats->avg_queue_size_samples, gfp) ||
++	    blkg_stat_init(&stats->dequeue, gfp) ||
++	    blkg_stat_init(&stats->group_wait_time, gfp) ||
++	    blkg_stat_init(&stats->idle_time, gfp) ||
++	    blkg_stat_init(&stats->empty_time, gfp)) {
++		bfqg_stats_exit(stats);
++		return -ENOMEM;
++	}
++
++	return 0;
++}
++
++static struct bfq_group_data *cpd_to_bfqgd(struct blkcg_policy_data *cpd)
++{
++	return cpd ? container_of(cpd, struct bfq_group_data, pd) : NULL;
++}
++
++static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg)
++{
++	return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq));
++}
++
++static void bfq_cpd_init(struct blkcg_policy_data *cpd)
++{
++	struct bfq_group_data *d = cpd_to_bfqgd(cpd);
++
++	d->weight = BFQ_DEFAULT_GRP_WEIGHT;
++}
++
++static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node)
++{
++	struct bfq_group *bfqg;
++
++	bfqg = kzalloc_node(sizeof(*bfqg), gfp, node);
++	if (!bfqg)
++		return NULL;
++
++	if (bfqg_stats_init(&bfqg->stats, gfp) ||
++	    bfqg_stats_init(&bfqg->dead_stats, gfp)) {
++		kfree(bfqg);
++		return NULL;
++	}
++
++	return &bfqg->pd;
++}
++
++static void bfq_group_set_parent(struct bfq_group *bfqg,
++					struct bfq_group *parent)
++{
++	struct bfq_entity *entity;
++
++	BUG_ON(!parent);
++	BUG_ON(!bfqg);
++	BUG_ON(bfqg == parent);
++
++	entity = &bfqg->entity;
++	entity->parent = parent->my_entity;
++	entity->sched_data = &parent->sched_data;
++}
++
++static void bfq_pd_init(struct blkg_policy_data *pd)
++{
++	struct blkcg_gq *blkg = pd_to_blkg(pd);
++	struct bfq_group *bfqg = blkg_to_bfqg(blkg);
++	struct bfq_data *bfqd = blkg->q->elevator->elevator_data;
++	struct bfq_entity *entity = &bfqg->entity;
++	struct bfq_group_data *d = blkcg_to_bfqgd(blkg->blkcg);
++
++	entity->orig_weight = entity->weight = entity->new_weight = d->weight;
++	entity->my_sched_data = &bfqg->sched_data;
++	bfqg->my_entity = entity; /*
++				   * the root_group's will be set to NULL
++				   * in bfq_init_queue()
++				   */
++	bfqg->bfqd = bfqd;
++	bfqg->active_entities = 0;
++}
++
++static void bfq_pd_free(struct blkg_policy_data *pd)
++{
++	struct bfq_group *bfqg = pd_to_bfqg(pd);
++
++	bfqg_stats_exit(&bfqg->stats);
++	bfqg_stats_exit(&bfqg->dead_stats);
++
++	return kfree(bfqg);
++}
++
++/* offset delta from bfqg->stats to bfqg->dead_stats */
++static const int dead_stats_off_delta = offsetof(struct bfq_group, dead_stats) -
++					offsetof(struct bfq_group, stats);
++
++/* to be used by recursive prfill, sums live and dead stats recursively */
++static u64 bfqg_stat_pd_recursive_sum(struct blkg_policy_data *pd, int off)
++{
++	u64 sum = 0;
++
++	sum += blkg_stat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, off);
++	sum += blkg_stat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq,
++				       off + dead_stats_off_delta);
++	return sum;
++}
++
++/* to be used by recursive prfill, sums live and dead rwstats recursively */
++static struct blkg_rwstat
++bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, int off)
++{
++	struct blkg_rwstat a, b;
++
++	a = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, off);
++	b = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq,
++				      off + dead_stats_off_delta);
++	blkg_rwstat_add_aux(&a, &b);
++	return a;
++}
++
++static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
++{
++	struct bfq_group *bfqg = pd_to_bfqg(pd);
++
++	bfqg_stats_reset(&bfqg->stats);
++	bfqg_stats_reset(&bfqg->dead_stats);
++}
++
++static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
++					      struct blkcg *blkcg)
++{
++	struct request_queue *q = bfqd->queue;
++	struct bfq_group *bfqg = NULL, *parent;
++	struct bfq_entity *entity = NULL;
++
++	assert_spin_locked(bfqd->queue->queue_lock);
++
++	/* avoid lookup for the common case where there's no blkcg */
++	if (blkcg == &blkcg_root) {
++		bfqg = bfqd->root_group;
++	} else {
++		struct blkcg_gq *blkg;
++
++		blkg = blkg_lookup_create(blkcg, q);
++		if (!IS_ERR(blkg))
++			bfqg = blkg_to_bfqg(blkg);
++		else /* fallback to root_group */
++			bfqg = bfqd->root_group;
++	}
++
++	BUG_ON(!bfqg);
++
++	/*
++	 * Update chain of bfq_groups as we might be handling a leaf group
++	 * which, along with some of its relatives, has not been hooked yet
++	 * to the private hierarchy of BFQ.
++	 */
++	entity = &bfqg->entity;
++	for_each_entity(entity) {
++		bfqg = container_of(entity, struct bfq_group, entity);
++		BUG_ON(!bfqg);
++		if (bfqg != bfqd->root_group) {
++			parent = bfqg_parent(bfqg);
++			if (!parent)
++				parent = bfqd->root_group;
++			BUG_ON(!parent);
++			bfq_group_set_parent(bfqg, parent);
++		}
++	}
++
++	return bfqg;
++}
++
++/**
++ * bfq_bfqq_move - migrate @bfqq to @bfqg.
++ * @bfqd: queue descriptor.
++ * @bfqq: the queue to move.
++ * @entity: @bfqq's entity.
++ * @bfqg: the group to move to.
++ *
++ * Move @bfqq to @bfqg, deactivating it from its old group and reactivating
++ * it on the new one.  Avoid putting the entity on the old group idle tree.
++ *
++ * Must be called under the queue lock; the cgroup owning @bfqg must
++ * not disappear (by now this just means that we are called under
++ * rcu_read_lock()).
++ */
++static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++			  struct bfq_entity *entity, struct bfq_group *bfqg)
++{
++	int busy, resume;
++
++	busy = bfq_bfqq_busy(bfqq);
++	resume = !RB_EMPTY_ROOT(&bfqq->sort_list);
++
++	BUG_ON(resume && !entity->on_st);
++	BUG_ON(busy && !resume && entity->on_st &&
++	       bfqq != bfqd->in_service_queue);
++
++	if (busy) {
++		BUG_ON(atomic_read(&bfqq->ref) < 2);
++
++		if (!resume)
++			bfq_del_bfqq_busy(bfqd, bfqq, 0);
++		else
++			bfq_deactivate_bfqq(bfqd, bfqq, 0);
++	} else if (entity->on_st)
++		bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
++	bfqg_put(bfqq_group(bfqq));
++
++	/*
++	 * Here we use a reference to bfqg.  We don't need a refcounter
++	 * as the cgroup reference will not be dropped, so that its
++	 * destroy() callback will not be invoked.
++	 */
++	entity->parent = bfqg->my_entity;
++	entity->sched_data = &bfqg->sched_data;
++	bfqg_get(bfqg);
++
++	if (busy) {
++		if (resume)
++			bfq_activate_bfqq(bfqd, bfqq);
++	}
++
++	if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
++		bfq_schedule_dispatch(bfqd);
++}
++
++/**
++ * __bfq_bic_change_cgroup - move @bic to @cgroup.
++ * @bfqd: the queue descriptor.
++ * @bic: the bic to move.
++ * @blkcg: the blk-cgroup to move to.
++ *
++ * Move bic to blkcg, assuming that bfqd->queue is locked; the caller
++ * has to make sure that the reference to cgroup is valid across the call.
++ *
++ * NOTE: an alternative approach might have been to store the current
++ * cgroup in bfqq and getting a reference to it, reducing the lookup
++ * time here, at the price of slightly more complex code.
++ */
++static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
++						struct bfq_io_cq *bic,
++						struct blkcg *blkcg)
++{
++	struct bfq_queue *async_bfqq = bic_to_bfqq(bic, 0);
++	struct bfq_queue *sync_bfqq = bic_to_bfqq(bic, 1);
++	struct bfq_group *bfqg;
++	struct bfq_entity *entity;
++
++	lockdep_assert_held(bfqd->queue->queue_lock);
++
++	bfqg = bfq_find_alloc_group(bfqd, blkcg);
++	if (async_bfqq) {
++		entity = &async_bfqq->entity;
++
++		if (entity->sched_data != &bfqg->sched_data) {
++			bic_set_bfqq(bic, NULL, 0);
++			bfq_log_bfqq(bfqd, async_bfqq,
++				     "bic_change_group: %p %d",
++				     async_bfqq, atomic_read(&async_bfqq->ref));
++			bfq_put_queue(async_bfqq);
++		}
++	}
++
++	if (sync_bfqq) {
++		entity = &sync_bfqq->entity;
++		if (entity->sched_data != &bfqg->sched_data)
++			bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg);
++	}
++
++	return bfqg;
++}
++
++static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
++{
++	struct bfq_data *bfqd = bic_to_bfqd(bic);
++	struct blkcg *blkcg;
++	struct bfq_group *bfqg = NULL;
++	uint64_t id;
++
++	rcu_read_lock();
++	blkcg = bio_blkcg(bio);
++	id = blkcg->css.serial_nr;
++	rcu_read_unlock();
++
++	/*
++	 * Check whether blkcg has changed.  The condition may trigger
++	 * spuriously on a newly created cic but there's no harm.
++	 */
++	if (unlikely(!bfqd) || likely(bic->blkcg_id == id))
++		return;
++
++	bfqg = __bfq_bic_change_cgroup(bfqd, bic, blkcg);
++	BUG_ON(!bfqg);
++	bic->blkcg_id = id;
++}
++
++/**
++ * bfq_flush_idle_tree - deactivate any entity on the idle tree of @st.
++ * @st: the service tree being flushed.
++ */
++static void bfq_flush_idle_tree(struct bfq_service_tree *st)
++{
++	struct bfq_entity *entity = st->first_idle;
++
++	for (; entity ; entity = st->first_idle)
++		__bfq_deactivate_entity(entity, 0);
++}
++
++/**
++ * bfq_reparent_leaf_entity - move leaf entity to the root_group.
++ * @bfqd: the device data structure with the root group.
++ * @entity: the entity to move.
++ */
++static void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
++				     struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++	BUG_ON(!bfqq);
++	bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group);
++}
++
++/**
++ * bfq_reparent_active_entities - move to the root group all active
++ *                                entities.
++ * @bfqd: the device data structure with the root group.
++ * @bfqg: the group to move from.
++ * @st: the service tree with the entities.
++ *
++ * Needs queue_lock to be taken and reference to be valid over the call.
++ */
++static void bfq_reparent_active_entities(struct bfq_data *bfqd,
++					 struct bfq_group *bfqg,
++					 struct bfq_service_tree *st)
++{
++	struct rb_root *active = &st->active;
++	struct bfq_entity *entity = NULL;
++
++	if (!RB_EMPTY_ROOT(&st->active))
++		entity = bfq_entity_of(rb_first(active));
++
++	for (; entity ; entity = bfq_entity_of(rb_first(active)))
++		bfq_reparent_leaf_entity(bfqd, entity);
++
++	if (bfqg->sched_data.in_service_entity)
++		bfq_reparent_leaf_entity(bfqd,
++			bfqg->sched_data.in_service_entity);
++}
++
++/**
++ * bfq_destroy_group - destroy @bfqg.
++ * @bfqg: the group being destroyed.
++ *
++ * Destroy @bfqg, making sure that it is not referenced from its parent.
++ * blkio already grabs the queue_lock for us, so no need to use RCU-based magic
++ */
++static void bfq_pd_offline(struct blkg_policy_data *pd)
++{
++	struct bfq_service_tree *st;
++	struct bfq_group *bfqg;
++	struct bfq_data *bfqd;
++	struct bfq_entity *entity;
++	int i;
++
++	BUG_ON(!pd);
++	bfqg = pd_to_bfqg(pd);
++	BUG_ON(!bfqg);
++	bfqd = bfqg->bfqd;
++	BUG_ON(bfqd && !bfqd->root_group);
++
++	entity = bfqg->my_entity;
++
++	if (!entity) /* root group */
++		return;
++
++	/*
++	 * Empty all service_trees belonging to this group before
++	 * deactivating the group itself.
++	 */
++	for (i = 0; i < BFQ_IOPRIO_CLASSES; i++) {
++		BUG_ON(!bfqg->sched_data.service_tree);
++		st = bfqg->sched_data.service_tree + i;
++		/*
++		 * The idle tree may still contain bfq_queues belonging
++		 * to exited task because they never migrated to a different
++		 * cgroup from the one being destroyed now.  No one else
++		 * can access them so it's safe to act without any lock.
++		 */
++		bfq_flush_idle_tree(st);
++
++		/*
++		 * It may happen that some queues are still active
++		 * (busy) upon group destruction (if the corresponding
++		 * processes have been forced to terminate). We move
++		 * all the leaf entities corresponding to these queues
++		 * to the root_group.
++		 * Also, it may happen that the group has an entity
++		 * in service, which is disconnected from the active
++		 * tree: it must be moved, too.
++		 * There is no need to put the sync queues, as the
++		 * scheduler has taken no reference.
++		 */
++		bfq_reparent_active_entities(bfqd, bfqg, st);
++		BUG_ON(!RB_EMPTY_ROOT(&st->active));
++		BUG_ON(!RB_EMPTY_ROOT(&st->idle));
++	}
++	BUG_ON(bfqg->sched_data.next_in_service);
++	BUG_ON(bfqg->sched_data.in_service_entity);
++
++	__bfq_deactivate_entity(entity, 0);
++	bfq_put_async_queues(bfqd, bfqg);
++	BUG_ON(entity->tree);
++
++	bfqg_stats_xfer_dead(bfqg);
++}
++
++static void bfq_end_wr_async(struct bfq_data *bfqd)
++{
++	struct blkcg_gq *blkg;
++
++	list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) {
++		struct bfq_group *bfqg = blkg_to_bfqg(blkg);
++
++		bfq_end_wr_async_queues(bfqd, bfqg);
++	}
++	bfq_end_wr_async_queues(bfqd, bfqd->root_group);
++}
++
++static u64 bfqio_cgroup_weight_read(struct cgroup_subsys_state *css,
++				       struct cftype *cftype)
++{
++	struct blkcg *blkcg = css_to_blkcg(css);
++	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
++	int ret = -EINVAL;
++
++	spin_lock_irq(&blkcg->lock);
++	ret = bfqgd->weight;
++	spin_unlock_irq(&blkcg->lock);
++
++	return ret;
++}
++
++static int bfqio_cgroup_weight_read_dfl(struct seq_file *sf, void *v)
++{
++	struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
++	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
++
++	spin_lock_irq(&blkcg->lock);
++	seq_printf(sf, "%u\n", bfqgd->weight);
++	spin_unlock_irq(&blkcg->lock);
++
++	return 0;
++}
++
++static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css,
++					struct cftype *cftype,
++					u64 val)
++{
++	struct blkcg *blkcg = css_to_blkcg(css);
++	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
++	struct blkcg_gq *blkg;
++	int ret = -EINVAL;
++
++	if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT)
++		return ret;
++
++	ret = 0;
++	spin_lock_irq(&blkcg->lock);
++	bfqgd->weight = (unsigned short)val;
++	hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node) {
++		struct bfq_group *bfqg = blkg_to_bfqg(blkg);
++
++		if (!bfqg)
++			continue;
++		/*
++		 * Setting the prio_changed flag of the entity
++		 * to 1 with new_weight == weight would re-set
++		 * the value of the weight to its ioprio mapping.
++		 * Set the flag only if necessary.
++		 */
++		if ((unsigned short)val != bfqg->entity.new_weight) {
++			bfqg->entity.new_weight = (unsigned short)val;
++			/*
++			 * Make sure that the above new value has been
++			 * stored in bfqg->entity.new_weight before
++			 * setting the prio_changed flag. In fact,
++			 * this flag may be read asynchronously (in
++			 * critical sections protected by a different
++			 * lock than that held here), and finding this
++			 * flag set may cause the execution of the code
++			 * for updating parameters whose value may
++			 * depend also on bfqg->entity.new_weight (in
++			 * __bfq_entity_update_weight_prio).
++			 * This barrier makes sure that the new value
++			 * of bfqg->entity.new_weight is correctly
++			 * seen in that code.
++			 */
++			smp_wmb();
++			bfqg->entity.prio_changed = 1;
++		}
++	}
++	spin_unlock_irq(&blkcg->lock);
++
++	return ret;
++}
++
++static ssize_t bfqio_cgroup_weight_write_dfl(struct kernfs_open_file *of,
++					     char *buf, size_t nbytes,
++					     loff_t off)
++{
++	/* First unsigned long found in the file is used */
++	return bfqio_cgroup_weight_write(of_css(of), NULL,
++					 simple_strtoull(strim(buf), NULL, 0));
++}
++
++static int bfqg_print_stat(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_stat,
++			  &blkcg_policy_bfq, seq_cft(sf)->private, false);
++	return 0;
++}
++
++static int bfqg_print_rwstat(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)), blkg_prfill_rwstat,
++			  &blkcg_policy_bfq, seq_cft(sf)->private, true);
++	return 0;
++}
++
++static u64 bfqg_prfill_stat_recursive(struct seq_file *sf,
++				      struct blkg_policy_data *pd, int off)
++{
++	u64 sum = bfqg_stat_pd_recursive_sum(pd, off);
++
++	return __blkg_prfill_u64(sf, pd, sum);
++}
++
++static u64 bfqg_prfill_rwstat_recursive(struct seq_file *sf,
++					struct blkg_policy_data *pd, int off)
++{
++	struct blkg_rwstat sum = bfqg_rwstat_pd_recursive_sum(pd, off);
++
++	return __blkg_prfill_rwstat(sf, pd, &sum);
++}
++
++static int bfqg_print_stat_recursive(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
++			  bfqg_prfill_stat_recursive, &blkcg_policy_bfq,
++			  seq_cft(sf)->private, false);
++	return 0;
++}
++
++static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
++			  bfqg_prfill_rwstat_recursive, &blkcg_policy_bfq,
++			  seq_cft(sf)->private, true);
++	return 0;
++}
++
++static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf,
++				      struct blkg_policy_data *pd, int off)
++{
++	struct bfq_group *bfqg = pd_to_bfqg(pd);
++	u64 samples = blkg_stat_read(&bfqg->stats.avg_queue_size_samples);
++	u64 v = 0;
++
++	if (samples) {
++		v = blkg_stat_read(&bfqg->stats.avg_queue_size_sum);
++		v = div64_u64(v, samples);
++	}
++	__blkg_prfill_u64(sf, pd, v);
++	return 0;
++}
++
++/* print avg_queue_size */
++static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
++			  bfqg_prfill_avg_queue_size, &blkcg_policy_bfq,
++			  0, false);
++	return 0;
++}
++
++static struct bfq_group *
++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
++{
++	int ret;
++
++	ret = blkcg_activate_policy(bfqd->queue, &blkcg_policy_bfq);
++	if (ret)
++		return NULL;
++
++	return blkg_to_bfqg(bfqd->queue->root_blkg);
++}
++
++static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp)
++{
++	struct bfq_group_data *bgd;
++
++	bgd = kzalloc(sizeof(*bgd), GFP_KERNEL);
++	if (!bgd)
++		return NULL;
++	return &bgd->pd;
++}
++
++static void bfq_cpd_free(struct blkcg_policy_data *cpd)
++{
++	kfree(cpd_to_bfqgd(cpd));
++}
++
++static struct cftype bfqio_files_dfl[] = {
++	{
++		.name = "weight",
++		.flags = CFTYPE_NOT_ON_ROOT,
++		.seq_show = bfqio_cgroup_weight_read_dfl,
++		.write = bfqio_cgroup_weight_write_dfl,
++	},
++	{} /* terminate */
++};
++
++static struct cftype bfqio_files[] = {
++	{
++		.name = "bfq.weight",
++		.read_u64 = bfqio_cgroup_weight_read,
++		.write_u64 = bfqio_cgroup_weight_write,
++	},
++	/* statistics, cover only the tasks in the bfqg */
++	{
++		.name = "bfq.time",
++		.private = offsetof(struct bfq_group, stats.time),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.sectors",
++		.private = offsetof(struct bfq_group, stats.sectors),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.io_service_bytes",
++		.private = offsetof(struct bfq_group, stats.service_bytes),
++		.seq_show = bfqg_print_rwstat,
++	},
++	{
++		.name = "bfq.io_serviced",
++		.private = offsetof(struct bfq_group, stats.serviced),
++		.seq_show = bfqg_print_rwstat,
++	},
++	{
++		.name = "bfq.io_service_time",
++		.private = offsetof(struct bfq_group, stats.service_time),
++		.seq_show = bfqg_print_rwstat,
++	},
++	{
++		.name = "bfq.io_wait_time",
++		.private = offsetof(struct bfq_group, stats.wait_time),
++		.seq_show = bfqg_print_rwstat,
++	},
++	{
++		.name = "bfq.io_merged",
++		.private = offsetof(struct bfq_group, stats.merged),
++		.seq_show = bfqg_print_rwstat,
++	},
++	{
++		.name = "bfq.io_queued",
++		.private = offsetof(struct bfq_group, stats.queued),
++		.seq_show = bfqg_print_rwstat,
++	},
++
++	/* the same statictics which cover the bfqg and its descendants */
++	{
++		.name = "bfq.time_recursive",
++		.private = offsetof(struct bfq_group, stats.time),
++		.seq_show = bfqg_print_stat_recursive,
++	},
++	{
++		.name = "bfq.sectors_recursive",
++		.private = offsetof(struct bfq_group, stats.sectors),
++		.seq_show = bfqg_print_stat_recursive,
++	},
++	{
++		.name = "bfq.io_service_bytes_recursive",
++		.private = offsetof(struct bfq_group, stats.service_bytes),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.io_serviced_recursive",
++		.private = offsetof(struct bfq_group, stats.serviced),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.io_service_time_recursive",
++		.private = offsetof(struct bfq_group, stats.service_time),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.io_wait_time_recursive",
++		.private = offsetof(struct bfq_group, stats.wait_time),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.io_merged_recursive",
++		.private = offsetof(struct bfq_group, stats.merged),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.io_queued_recursive",
++		.private = offsetof(struct bfq_group, stats.queued),
++		.seq_show = bfqg_print_rwstat_recursive,
++	},
++	{
++		.name = "bfq.avg_queue_size",
++		.seq_show = bfqg_print_avg_queue_size,
++	},
++	{
++		.name = "bfq.group_wait_time",
++		.private = offsetof(struct bfq_group, stats.group_wait_time),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.idle_time",
++		.private = offsetof(struct bfq_group, stats.idle_time),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.empty_time",
++		.private = offsetof(struct bfq_group, stats.empty_time),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.dequeue",
++		.private = offsetof(struct bfq_group, stats.dequeue),
++		.seq_show = bfqg_print_stat,
++	},
++	{
++		.name = "bfq.unaccounted_time",
++		.private = offsetof(struct bfq_group, stats.unaccounted_time),
++		.seq_show = bfqg_print_stat,
++	},
++	{ }	/* terminate */
++};
++
++static struct blkcg_policy blkcg_policy_bfq = {
++	.dfl_cftypes            = bfqio_files_dfl,
++	.legacy_cftypes		= bfqio_files,
++
++	.pd_alloc_fn		= bfq_pd_alloc,
++	.pd_init_fn		= bfq_pd_init,
++	.pd_offline_fn		= bfq_pd_offline,
++	.pd_free_fn		= bfq_pd_free,
++	.pd_reset_stats_fn	= bfq_pd_reset_stats,
++
++	.cpd_alloc_fn		= bfq_cpd_alloc,
++	.cpd_init_fn		= bfq_cpd_init,
++	.cpd_bind_fn		= bfq_cpd_init,
++	.cpd_free_fn		= bfq_cpd_free,
++};
++
++#else
++
++static void bfq_init_entity(struct bfq_entity *entity,
++			    struct bfq_group *bfqg)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++	entity->weight = entity->new_weight;
++	entity->orig_weight = entity->new_weight;
++	if (bfqq) {
++		bfqq->ioprio = bfqq->new_ioprio;
++		bfqq->ioprio_class = bfqq->new_ioprio_class;
++	}
++	entity->sched_data = &bfqg->sched_data;
++}
++
++static struct bfq_group *
++bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
++{
++	struct bfq_data *bfqd = bic_to_bfqd(bic);
++
++	return bfqd->root_group;
++}
++
++static void bfq_bfqq_move(struct bfq_data *bfqd,
++			  struct bfq_queue *bfqq,
++			  struct bfq_entity *entity,
++			  struct bfq_group *bfqg)
++{
++}
++
++static void bfq_end_wr_async(struct bfq_data *bfqd)
++{
++	bfq_end_wr_async_queues(bfqd, bfqd->root_group);
++}
++
++static void bfq_disconnect_groups(struct bfq_data *bfqd)
++{
++	bfq_put_async_queues(bfqd, bfqd->root_group);
++}
++
++static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
++					      struct blkcg *blkcg)
++{
++	return bfqd->root_group;
++}
++
++static struct bfq_group *
++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
++{
++	struct bfq_group *bfqg;
++	int i;
++
++	bfqg = kmalloc_node(sizeof(*bfqg), GFP_KERNEL | __GFP_ZERO, node);
++	if (!bfqg)
++		return NULL;
++
++	for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
++		bfqg->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
++
++	return bfqg;
++}
++#endif
+diff --git a/block/bfq-ioc.c b/block/bfq-ioc.c
+new file mode 100644
+index 0000000..fb7bb8f
+--- /dev/null
++++ b/block/bfq-ioc.c
+@@ -0,0 +1,36 @@
++/*
++ * BFQ: I/O context handling.
++ *
++ * Based on ideas and code from CFQ:
++ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
++ *
++ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
++ *		      Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ */
++
++/**
++ * icq_to_bic - convert iocontext queue structure to bfq_io_cq.
++ * @icq: the iocontext queue.
++ */
++static struct bfq_io_cq *icq_to_bic(struct io_cq *icq)
++{
++	/* bic->icq is the first member, %NULL will convert to %NULL */
++	return container_of(icq, struct bfq_io_cq, icq);
++}
++
++/**
++ * bfq_bic_lookup - search into @ioc a bic associated to @bfqd.
++ * @bfqd: the lookup key.
++ * @ioc: the io_context of the process doing I/O.
++ *
++ * Queue lock must be held.
++ */
++static struct bfq_io_cq *bfq_bic_lookup(struct bfq_data *bfqd,
++					struct io_context *ioc)
++{
++	if (ioc)
++		return icq_to_bic(ioc_lookup_icq(ioc, bfqd->queue));
++	return NULL;
++}
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+new file mode 100644
+index 0000000..85e2169
+--- /dev/null
++++ b/block/bfq-iosched.c
+@@ -0,0 +1,3763 @@
++/*
++ * Budget Fair Queueing (BFQ) disk scheduler.
++ *
++ * Based on ideas and code from CFQ:
++ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
++ *
++ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
++ *		      Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
++ * file.
++ *
++ * BFQ is a proportional-share storage-I/O scheduling algorithm based on
++ * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets,
++ * measured in number of sectors, to processes instead of time slices. The
++ * device is not granted to the in-service process for a given time slice,
++ * but until it has exhausted its assigned budget. This change from the time
++ * to the service domain allows BFQ to distribute the device throughput
++ * among processes as desired, without any distortion due to ZBR, workload
++ * fluctuations or other factors. BFQ uses an ad hoc internal scheduler,
++ * called B-WF2Q+, to schedule processes according to their budgets. More
++ * precisely, BFQ schedules queues associated to processes. Thanks to the
++ * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to
++ * I/O-bound processes issuing sequential requests (to boost the
++ * throughput), and yet guarantee a low latency to interactive and soft
++ * real-time applications.
++ *
++ * BFQ is described in [1], where also a reference to the initial, more
++ * theoretical paper on BFQ can be found. The interested reader can find
++ * in the latter paper full details on the main algorithm, as well as
++ * formulas of the guarantees and formal proofs of all the properties.
++ * With respect to the version of BFQ presented in these papers, this
++ * implementation adds a few more heuristics, such as the one that
++ * guarantees a low latency to soft real-time applications, and a
++ * hierarchical extension based on H-WF2Q+.
++ *
++ * B-WF2Q+ is based on WF2Q+, that is described in [2], together with
++ * H-WF2Q+, while the augmented tree used to implement B-WF2Q+ with O(log N)
++ * complexity derives from the one introduced with EEVDF in [3].
++ *
++ * [1] P. Valente and M. Andreolini, ``Improving Application Responsiveness
++ *     with the BFQ Disk I/O Scheduler'',
++ *     Proceedings of the 5th Annual International Systems and Storage
++ *     Conference (SYSTOR '12), June 2012.
++ *
++ * http://algogroup.unimo.it/people/paolo/disk_sched/bf1-v1-suite-results.pdf
++ *
++ * [2] Jon C.R. Bennett and H. Zhang, ``Hierarchical Packet Fair Queueing
++ *     Algorithms,'' IEEE/ACM Transactions on Networking, 5(5):675-689,
++ *     Oct 1997.
++ *
++ * http://www.cs.cmu.edu/~hzhang/papers/TON-97-Oct.ps.gz
++ *
++ * [3] I. Stoica and H. Abdel-Wahab, ``Earliest Eligible Virtual Deadline
++ *     First: A Flexible and Accurate Mechanism for Proportional Share
++ *     Resource Allocation,'' technical report.
++ *
++ * http://www.cs.berkeley.edu/~istoica/papers/eevdf-tr-95.pdf
++ */
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/blkdev.h>
++#include <linux/cgroup.h>
++#include <linux/elevator.h>
++#include <linux/jiffies.h>
++#include <linux/rbtree.h>
++#include <linux/ioprio.h>
++#include "bfq.h"
++#include "blk.h"
++
++/* Expiration time of sync (0) and async (1) requests, in jiffies. */
++static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
++
++/* Maximum backwards seek, in KiB. */
++static const int bfq_back_max = 16 * 1024;
++
++/* Penalty of a backwards seek, in number of sectors. */
++static const int bfq_back_penalty = 2;
++
++/* Idling period duration, in jiffies. */
++static int bfq_slice_idle = HZ / 125;
++
++/* Minimum number of assigned budgets for which stats are safe to compute. */
++static const int bfq_stats_min_budgets = 194;
++
++/* Default maximum budget values, in sectors and number of requests. */
++static const int bfq_default_max_budget = 16 * 1024;
++static const int bfq_max_budget_async_rq = 4;
++
++/*
++ * Async to sync throughput distribution is controlled as follows:
++ * when an async request is served, the entity is charged the number
++ * of sectors of the request, multiplied by the factor below
++ */
++static const int bfq_async_charge_factor = 10;
++
++/* Default timeout values, in jiffies, approximating CFQ defaults. */
++static const int bfq_timeout_sync = HZ / 8;
++static int bfq_timeout_async = HZ / 25;
++
++struct kmem_cache *bfq_pool;
++
++/* Below this threshold (in ms), we consider thinktime immediate. */
++#define BFQ_MIN_TT		2
++
++/* hw_tag detection: parallel requests threshold and min samples needed. */
++#define BFQ_HW_QUEUE_THRESHOLD	4
++#define BFQ_HW_QUEUE_SAMPLES	32
++
++#define BFQQ_SEEK_THR	 (sector_t)(8 * 1024)
++#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR)
++
++/* Min samples used for peak rate estimation (for autotuning). */
++#define BFQ_PEAK_RATE_SAMPLES	32
++
++/* Shift used for peak rate fixed precision calculations. */
++#define BFQ_RATE_SHIFT		16
++
++/*
++ * By default, BFQ computes the duration of the weight raising for
++ * interactive applications automatically, using the following formula:
++ * duration = (R / r) * T, where r is the peak rate of the device, and
++ * R and T are two reference parameters.
++ * In particular, R is the peak rate of the reference device (see below),
++ * and T is a reference time: given the systems that are likely to be
++ * installed on the reference device according to its speed class, T is
++ * about the maximum time needed, under BFQ and while reading two files in
++ * parallel, to load typical large applications on these systems.
++ * In practice, the slower/faster the device at hand is, the more/less it
++ * takes to load applications with respect to the reference device.
++ * Accordingly, the longer/shorter BFQ grants weight raising to interactive
++ * applications.
++ *
++ * BFQ uses four different reference pairs (R, T), depending on:
++ * . whether the device is rotational or non-rotational;
++ * . whether the device is slow, such as old or portable HDDs, as well as
++ *   SD cards, or fast, such as newer HDDs and SSDs.
++ *
++ * The device's speed class is dynamically (re)detected in
++ * bfq_update_peak_rate() every time the estimated peak rate is updated.
++ *
++ * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0]
++ * are the reference values for a slow/fast rotational device, whereas
++ * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for
++ * a slow/fast non-rotational device. Finally, device_speed_thresh are the
++ * thresholds used to switch between speed classes.
++ * Both the reference peak rates and the thresholds are measured in
++ * sectors/usec, left-shifted by BFQ_RATE_SHIFT.
++ */
++static int R_slow[2] = {1536, 10752};
++static int R_fast[2] = {17415, 34791};
++/*
++ * To improve readability, a conversion function is used to initialize the
++ * following arrays, which entails that they can be initialized only in a
++ * function.
++ */
++static int T_slow[2];
++static int T_fast[2];
++static int device_speed_thresh[2];
++
++#define BFQ_SERVICE_TREE_INIT	((struct bfq_service_tree)		\
++				{ RB_ROOT, RB_ROOT, NULL, NULL, 0, 0 })
++
++#define RQ_BIC(rq)		((struct bfq_io_cq *) (rq)->elv.priv[0])
++#define RQ_BFQQ(rq)		((rq)->elv.priv[1])
++
++static void bfq_schedule_dispatch(struct bfq_data *bfqd);
++
++#include "bfq-ioc.c"
++#include "bfq-sched.c"
++#include "bfq-cgroup.c"
++
++#define bfq_class_idle(bfqq)	((bfqq)->ioprio_class == IOPRIO_CLASS_IDLE)
++#define bfq_class_rt(bfqq)	((bfqq)->ioprio_class == IOPRIO_CLASS_RT)
++
++#define bfq_sample_valid(samples)	((samples) > 80)
++
++/*
++ * We regard a request as SYNC, if either it's a read or has the SYNC bit
++ * set (in which case it could also be a direct WRITE).
++ */
++static int bfq_bio_sync(struct bio *bio)
++{
++	if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC))
++		return 1;
++
++	return 0;
++}
++
++/*
++ * Scheduler run of queue, if there are requests pending and no one in the
++ * driver that will restart queueing.
++ */
++static void bfq_schedule_dispatch(struct bfq_data *bfqd)
++{
++	if (bfqd->queued != 0) {
++		bfq_log(bfqd, "schedule dispatch");
++		kblockd_schedule_work(&bfqd->unplug_work);
++	}
++}
++
++/*
++ * Lifted from AS - choose which of rq1 and rq2 that is best served now.
++ * We choose the request that is closesr to the head right now.  Distance
++ * behind the head is penalized and only allowed to a certain extent.
++ */
++static struct request *bfq_choose_req(struct bfq_data *bfqd,
++				      struct request *rq1,
++				      struct request *rq2,
++				      sector_t last)
++{
++	sector_t s1, s2, d1 = 0, d2 = 0;
++	unsigned long back_max;
++#define BFQ_RQ1_WRAP	0x01 /* request 1 wraps */
++#define BFQ_RQ2_WRAP	0x02 /* request 2 wraps */
++	unsigned int wrap = 0; /* bit mask: requests behind the disk head? */
++
++	if (!rq1 || rq1 == rq2)
++		return rq2;
++	if (!rq2)
++		return rq1;
++
++	if (rq_is_sync(rq1) && !rq_is_sync(rq2))
++		return rq1;
++	else if (rq_is_sync(rq2) && !rq_is_sync(rq1))
++		return rq2;
++	if ((rq1->cmd_flags & REQ_META) && !(rq2->cmd_flags & REQ_META))
++		return rq1;
++	else if ((rq2->cmd_flags & REQ_META) && !(rq1->cmd_flags & REQ_META))
++		return rq2;
++
++	s1 = blk_rq_pos(rq1);
++	s2 = blk_rq_pos(rq2);
++
++	/*
++	 * By definition, 1KiB is 2 sectors.
++	 */
++	back_max = bfqd->bfq_back_max * 2;
++
++	/*
++	 * Strict one way elevator _except_ in the case where we allow
++	 * short backward seeks which are biased as twice the cost of a
++	 * similar forward seek.
++	 */
++	if (s1 >= last)
++		d1 = s1 - last;
++	else if (s1 + back_max >= last)
++		d1 = (last - s1) * bfqd->bfq_back_penalty;
++	else
++		wrap |= BFQ_RQ1_WRAP;
++
++	if (s2 >= last)
++		d2 = s2 - last;
++	else if (s2 + back_max >= last)
++		d2 = (last - s2) * bfqd->bfq_back_penalty;
++	else
++		wrap |= BFQ_RQ2_WRAP;
++
++	/* Found required data */
++
++	/*
++	 * By doing switch() on the bit mask "wrap" we avoid having to
++	 * check two variables for all permutations: --> faster!
++	 */
++	switch (wrap) {
++	case 0: /* common case for CFQ: rq1 and rq2 not wrapped */
++		if (d1 < d2)
++			return rq1;
++		else if (d2 < d1)
++			return rq2;
++
++		if (s1 >= s2)
++			return rq1;
++		else
++			return rq2;
++
++	case BFQ_RQ2_WRAP:
++		return rq1;
++	case BFQ_RQ1_WRAP:
++		return rq2;
++	case (BFQ_RQ1_WRAP|BFQ_RQ2_WRAP): /* both rqs wrapped */
++	default:
++		/*
++		 * Since both rqs are wrapped,
++		 * start with the one that's further behind head
++		 * (--> only *one* back seek required),
++		 * since back seek takes more time than forward.
++		 */
++		if (s1 <= s2)
++			return rq1;
++		else
++			return rq2;
++	}
++}
++
++/*
++ * Tell whether there are active queues or groups with differentiated weights.
++ */
++static bool bfq_differentiated_weights(struct bfq_data *bfqd)
++{
++	/*
++	 * For weights to differ, at least one of the trees must contain
++	 * at least two nodes.
++	 */
++	return (!RB_EMPTY_ROOT(&bfqd->queue_weights_tree) &&
++		(bfqd->queue_weights_tree.rb_node->rb_left ||
++		 bfqd->queue_weights_tree.rb_node->rb_right)
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	       ) ||
++	       (!RB_EMPTY_ROOT(&bfqd->group_weights_tree) &&
++		(bfqd->group_weights_tree.rb_node->rb_left ||
++		 bfqd->group_weights_tree.rb_node->rb_right)
++#endif
++	       );
++}
++
++/*
++ * The following function returns true if every queue must receive the
++ * same share of the throughput (this condition is used when deciding
++ * whether idling may be disabled, see the comments in the function
++ * bfq_bfqq_may_idle()).
++ *
++ * Such a scenario occurs when:
++ * 1) all active queues have the same weight,
++ * 2) all active groups at the same level in the groups tree have the same
++ *    weight,
++ * 3) all active groups at the same level in the groups tree have the same
++ *    number of children.
++ *
++ * Unfortunately, keeping the necessary state for evaluating exactly the
++ * above symmetry conditions would be quite complex and time-consuming.
++ * Therefore this function evaluates, instead, the following stronger
++ * sub-conditions, for which it is much easier to maintain the needed
++ * state:
++ * 1) all active queues have the same weight,
++ * 2) all active groups have the same weight,
++ * 3) all active groups have at most one active child each.
++ * In particular, the last two conditions are always true if hierarchical
++ * support and the cgroups interface are not enabled, thus no state needs
++ * to be maintained in this case.
++ */
++static bool bfq_symmetric_scenario(struct bfq_data *bfqd)
++{
++	return
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		!bfqd->active_numerous_groups &&
++#endif
++		!bfq_differentiated_weights(bfqd);
++}
++
++/*
++ * If the weight-counter tree passed as input contains no counter for
++ * the weight of the input entity, then add that counter; otherwise just
++ * increment the existing counter.
++ *
++ * Note that weight-counter trees contain few nodes in mostly symmetric
++ * scenarios. For example, if all queues have the same weight, then the
++ * weight-counter tree for the queues may contain at most one node.
++ * This holds even if low_latency is on, because weight-raised queues
++ * are not inserted in the tree.
++ * In most scenarios, the rate at which nodes are created/destroyed
++ * should be low too.
++ */
++static void bfq_weights_tree_add(struct bfq_data *bfqd,
++				 struct bfq_entity *entity,
++				 struct rb_root *root)
++{
++	struct rb_node **new = &(root->rb_node), *parent = NULL;
++
++	/*
++	 * Do not insert if the entity is already associated with a
++	 * counter, which happens if:
++	 *   1) the entity is associated with a queue,
++	 *   2) a request arrival has caused the queue to become both
++	 *      non-weight-raised, and hence change its weight, and
++	 *      backlogged; in this respect, each of the two events
++	 *      causes an invocation of this function,
++	 *   3) this is the invocation of this function caused by the
++	 *      second event. This second invocation is actually useless,
++	 *      and we handle this fact by exiting immediately. More
++	 *      efficient or clearer solutions might possibly be adopted.
++	 */
++	if (entity->weight_counter)
++		return;
++
++	while (*new) {
++		struct bfq_weight_counter *__counter = container_of(*new,
++						struct bfq_weight_counter,
++						weights_node);
++		parent = *new;
++
++		if (entity->weight == __counter->weight) {
++			entity->weight_counter = __counter;
++			goto inc_counter;
++		}
++		if (entity->weight < __counter->weight)
++			new = &((*new)->rb_left);
++		else
++			new = &((*new)->rb_right);
++	}
++
++	entity->weight_counter = kzalloc(sizeof(struct bfq_weight_counter),
++					 GFP_ATOMIC);
++	entity->weight_counter->weight = entity->weight;
++	rb_link_node(&entity->weight_counter->weights_node, parent, new);
++	rb_insert_color(&entity->weight_counter->weights_node, root);
++
++inc_counter:
++	entity->weight_counter->num_active++;
++}
++
++/*
++ * Decrement the weight counter associated with the entity, and, if the
++ * counter reaches 0, remove the counter from the tree.
++ * See the comments to the function bfq_weights_tree_add() for considerations
++ * about overhead.
++ */
++static void bfq_weights_tree_remove(struct bfq_data *bfqd,
++				    struct bfq_entity *entity,
++				    struct rb_root *root)
++{
++	if (!entity->weight_counter)
++		return;
++
++	BUG_ON(RB_EMPTY_ROOT(root));
++	BUG_ON(entity->weight_counter->weight != entity->weight);
++
++	BUG_ON(!entity->weight_counter->num_active);
++	entity->weight_counter->num_active--;
++	if (entity->weight_counter->num_active > 0)
++		goto reset_entity_pointer;
++
++	rb_erase(&entity->weight_counter->weights_node, root);
++	kfree(entity->weight_counter);
++
++reset_entity_pointer:
++	entity->weight_counter = NULL;
++}
++
++static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
++					struct bfq_queue *bfqq,
++					struct request *last)
++{
++	struct rb_node *rbnext = rb_next(&last->rb_node);
++	struct rb_node *rbprev = rb_prev(&last->rb_node);
++	struct request *next = NULL, *prev = NULL;
++
++	BUG_ON(RB_EMPTY_NODE(&last->rb_node));
++
++	if (rbprev)
++		prev = rb_entry_rq(rbprev);
++
++	if (rbnext)
++		next = rb_entry_rq(rbnext);
++	else {
++		rbnext = rb_first(&bfqq->sort_list);
++		if (rbnext && rbnext != &last->rb_node)
++			next = rb_entry_rq(rbnext);
++	}
++
++	return bfq_choose_req(bfqd, next, prev, blk_rq_pos(last));
++}
++
++/* see the definition of bfq_async_charge_factor for details */
++static unsigned long bfq_serv_to_charge(struct request *rq,
++					struct bfq_queue *bfqq)
++{
++	return blk_rq_sectors(rq) *
++		(1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) *
++		bfq_async_charge_factor));
++}
++
++/**
++ * bfq_updated_next_req - update the queue after a new next_rq selection.
++ * @bfqd: the device data the queue belongs to.
++ * @bfqq: the queue to update.
++ *
++ * If the first request of a queue changes we make sure that the queue
++ * has enough budget to serve at least its first request (if the
++ * request has grown).  We do this because if the queue has not enough
++ * budget for its first request, it has to go through two dispatch
++ * rounds to actually get it dispatched.
++ */
++static void bfq_updated_next_req(struct bfq_data *bfqd,
++				 struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
++	struct request *next_rq = bfqq->next_rq;
++	unsigned long new_budget;
++
++	if (!next_rq)
++		return;
++
++	if (bfqq == bfqd->in_service_queue)
++		/*
++		 * In order not to break guarantees, budgets cannot be
++		 * changed after an entity has been selected.
++		 */
++		return;
++
++	BUG_ON(entity->tree != &st->active);
++	BUG_ON(entity == entity->sched_data->in_service_entity);
++
++	new_budget = max_t(unsigned long, bfqq->max_budget,
++			   bfq_serv_to_charge(next_rq, bfqq));
++	if (entity->budget != new_budget) {
++		entity->budget = new_budget;
++		bfq_log_bfqq(bfqd, bfqq, "updated next rq: new budget %lu",
++					 new_budget);
++		bfq_activate_bfqq(bfqd, bfqq);
++	}
++}
++
++static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
++{
++	u64 dur;
++
++	if (bfqd->bfq_wr_max_time > 0)
++		return bfqd->bfq_wr_max_time;
++
++	dur = bfqd->RT_prod;
++	do_div(dur, bfqd->peak_rate);
++
++	return dur;
++}
++
++/* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */
++static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	struct bfq_queue *item;
++	struct hlist_node *n;
++
++	hlist_for_each_entry_safe(item, n, &bfqd->burst_list, burst_list_node)
++		hlist_del_init(&item->burst_list_node);
++	hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list);
++	bfqd->burst_size = 1;
++}
++
++/* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */
++static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	/* Increment burst size to take into account also bfqq */
++	bfqd->burst_size++;
++
++	if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) {
++		struct bfq_queue *pos, *bfqq_item;
++		struct hlist_node *n;
++
++		/*
++		 * Enough queues have been activated shortly after each
++		 * other to consider this burst as large.
++		 */
++		bfqd->large_burst = true;
++
++		/*
++		 * We can now mark all queues in the burst list as
++		 * belonging to a large burst.
++		 */
++		hlist_for_each_entry(bfqq_item, &bfqd->burst_list,
++				     burst_list_node)
++			bfq_mark_bfqq_in_large_burst(bfqq_item);
++		bfq_mark_bfqq_in_large_burst(bfqq);
++
++		/*
++		 * From now on, and until the current burst finishes, any
++		 * new queue being activated shortly after the last queue
++		 * was inserted in the burst can be immediately marked as
++		 * belonging to a large burst. So the burst list is not
++		 * needed any more. Remove it.
++		 */
++		hlist_for_each_entry_safe(pos, n, &bfqd->burst_list,
++					  burst_list_node)
++			hlist_del_init(&pos->burst_list_node);
++	} else /* burst not yet large: add bfqq to the burst list */
++		hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list);
++}
++
++/*
++ * If many queues happen to become active shortly after each other, then,
++ * to help the processes associated to these queues get their job done as
++ * soon as possible, it is usually better to not grant either weight-raising
++ * or device idling to these queues. In this comment we describe, firstly,
++ * the reasons why this fact holds, and, secondly, the next function, which
++ * implements the main steps needed to properly mark these queues so that
++ * they can then be treated in a different way.
++ *
++ * As for the terminology, we say that a queue becomes active, i.e.,
++ * switches from idle to backlogged, either when it is created (as a
++ * consequence of the arrival of an I/O request), or, if already existing,
++ * when a new request for the queue arrives while the queue is idle.
++ * Bursts of activations, i.e., activations of different queues occurring
++ * shortly after each other, are typically caused by services or applications
++ * that spawn or reactivate many parallel threads/processes. Examples are
++ * systemd during boot or git grep.
++ *
++ * These services or applications benefit mostly from a high throughput:
++ * the quicker the requests of the activated queues are cumulatively served,
++ * the sooner the target job of these queues gets completed. As a consequence,
++ * weight-raising any of these queues, which also implies idling the device
++ * for it, is almost always counterproductive: in most cases it just lowers
++ * throughput.
++ *
++ * On the other hand, a burst of activations may be also caused by the start
++ * of an application that does not consist in a lot of parallel I/O-bound
++ * threads. In fact, with a complex application, the burst may be just a
++ * consequence of the fact that several processes need to be executed to
++ * start-up the application. To start an application as quickly as possible,
++ * the best thing to do is to privilege the I/O related to the application
++ * with respect to all other I/O. Therefore, the best strategy to start as
++ * quickly as possible an application that causes a burst of activations is
++ * to weight-raise all the queues activated during the burst. This is the
++ * exact opposite of the best strategy for the other type of bursts.
++ *
++ * In the end, to take the best action for each of the two cases, the two
++ * types of bursts need to be distinguished. Fortunately, this seems
++ * relatively easy to do, by looking at the sizes of the bursts. In
++ * particular, we found a threshold such that bursts with a larger size
++ * than that threshold are apparently caused only by services or commands
++ * such as systemd or git grep. For brevity, hereafter we call just 'large'
++ * these bursts. BFQ *does not* weight-raise queues whose activations occur
++ * in a large burst. In addition, for each of these queues BFQ performs or
++ * does not perform idling depending on which choice boosts the throughput
++ * most. The exact choice depends on the device and request pattern at
++ * hand.
++ *
++ * Turning back to the next function, it implements all the steps needed
++ * to detect the occurrence of a large burst and to properly mark all the
++ * queues belonging to it (so that they can then be treated in a different
++ * way). This goal is achieved by maintaining a special "burst list" that
++ * holds, temporarily, the queues that belong to the burst in progress. The
++ * list is then used to mark these queues as belonging to a large burst if
++ * the burst does become large. The main steps are the following.
++ *
++ * . when the very first queue is activated, the queue is inserted into the
++ *   list (as it could be the first queue in a possible burst)
++ *
++ * . if the current burst has not yet become large, and a queue Q that does
++ *   not yet belong to the burst is activated shortly after the last time
++ *   at which a new queue entered the burst list, then the function appends
++ *   Q to the burst list
++ *
++ * . if, as a consequence of the previous step, the burst size reaches
++ *   the large-burst threshold, then
++ *
++ *     . all the queues in the burst list are marked as belonging to a
++ *       large burst
++ *
++ *     . the burst list is deleted; in fact, the burst list already served
++ *       its purpose (keeping temporarily track of the queues in a burst,
++ *       so as to be able to mark them as belonging to a large burst in the
++ *       previous sub-step), and now is not needed any more
++ *
++ *     . the device enters a large-burst mode
++ *
++ * . if a queue Q that does not belong to the burst is activated while
++ *   the device is in large-burst mode and shortly after the last time
++ *   at which a queue either entered the burst list or was marked as
++ *   belonging to the current large burst, then Q is immediately marked
++ *   as belonging to a large burst.
++ *
++ * . if a queue Q that does not belong to the burst is activated a while
++ *   later, i.e., not shortly after, than the last time at which a queue
++ *   either entered the burst list or was marked as belonging to the
++ *   current large burst, then the current burst is deemed as finished and:
++ *
++ *        . the large-burst mode is reset if set
++ *
++ *        . the burst list is emptied
++ *
++ *        . Q is inserted in the burst list, as Q may be the first queue
++ *          in a possible new burst (then the burst list contains just Q
++ *          after this step).
++ */
++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++			     bool idle_for_long_time)
++{
++	/*
++	 * If bfqq happened to be activated in a burst, but has been idle
++	 * for at least as long as an interactive queue, then we assume
++	 * that, in the overall I/O initiated in the burst, the I/O
++	 * associated to bfqq is finished. So bfqq does not need to be
++	 * treated as a queue belonging to a burst anymore. Accordingly,
++	 * we reset bfqq's in_large_burst flag if set, and remove bfqq
++	 * from the burst list if it's there. We do not decrement instead
++	 * burst_size, because the fact that bfqq does not need to belong
++	 * to the burst list any more does not invalidate the fact that
++	 * bfqq may have been activated during the current burst.
++	 */
++	if (idle_for_long_time) {
++		hlist_del_init(&bfqq->burst_list_node);
++		bfq_clear_bfqq_in_large_burst(bfqq);
++	}
++
++	/*
++	 * If bfqq is already in the burst list or is part of a large
++	 * burst, then there is nothing else to do.
++	 */
++	if (!hlist_unhashed(&bfqq->burst_list_node) ||
++	    bfq_bfqq_in_large_burst(bfqq))
++		return;
++
++	/*
++	 * If bfqq's activation happens late enough, then the current
++	 * burst is finished, and related data structures must be reset.
++	 *
++	 * In this respect, consider the special case where bfqq is the very
++	 * first queue being activated. In this case, last_ins_in_burst is
++	 * not yet significant when we get here. But it is easy to verify
++	 * that, whether or not the following condition is true, bfqq will
++	 * end up being inserted into the burst list. In particular the
++	 * list will happen to contain only bfqq. And this is exactly what
++	 * has to happen, as bfqq may be the first queue in a possible
++	 * burst.
++	 */
++	if (time_is_before_jiffies(bfqd->last_ins_in_burst +
++	    bfqd->bfq_burst_interval)) {
++		bfqd->large_burst = false;
++		bfq_reset_burst_list(bfqd, bfqq);
++		return;
++	}
++
++	/*
++	 * If we get here, then bfqq is being activated shortly after the
++	 * last queue. So, if the current burst is also large, we can mark
++	 * bfqq as belonging to this large burst immediately.
++	 */
++	if (bfqd->large_burst) {
++		bfq_mark_bfqq_in_large_burst(bfqq);
++		return;
++	}
++
++	/*
++	 * If we get here, then a large-burst state has not yet been
++	 * reached, but bfqq is being activated shortly after the last
++	 * queue. Then we add bfqq to the burst.
++	 */
++	bfq_add_to_burst(bfqd, bfqq);
++}
++
++static void bfq_add_request(struct request *rq)
++{
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++	struct bfq_entity *entity = &bfqq->entity;
++	struct bfq_data *bfqd = bfqq->bfqd;
++	struct request *next_rq, *prev;
++	unsigned long old_wr_coeff = bfqq->wr_coeff;
++	bool interactive = false;
++
++	bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
++	bfqq->queued[rq_is_sync(rq)]++;
++	bfqd->queued++;
++
++	elv_rb_add(&bfqq->sort_list, rq);
++
++	/*
++	 * Check if this request is a better next-serve candidate.
++	 */
++	prev = bfqq->next_rq;
++	next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position);
++	BUG_ON(!next_rq);
++	bfqq->next_rq = next_rq;
++
++	if (!bfq_bfqq_busy(bfqq)) {
++		bool soft_rt, in_burst,
++		     idle_for_long_time = time_is_before_jiffies(
++						bfqq->budget_timeout +
++						bfqd->bfq_wr_min_idle_time);
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq,
++					 rq->cmd_flags);
++#endif
++		if (bfq_bfqq_sync(bfqq)) {
++			bool already_in_burst =
++			   !hlist_unhashed(&bfqq->burst_list_node) ||
++			   bfq_bfqq_in_large_burst(bfqq);
++			bfq_handle_burst(bfqd, bfqq, idle_for_long_time);
++			/*
++			 * If bfqq was not already in the current burst,
++			 * then, at this point, bfqq either has been
++			 * added to the current burst or has caused the
++			 * current burst to terminate. In particular, in
++			 * the second case, bfqq has become the first
++			 * queue in a possible new burst.
++			 * In both cases last_ins_in_burst needs to be
++			 * moved forward.
++			 */
++			if (!already_in_burst)
++				bfqd->last_ins_in_burst = jiffies;
++		}
++
++		in_burst = bfq_bfqq_in_large_burst(bfqq);
++		soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
++			!in_burst &&
++			time_is_before_jiffies(bfqq->soft_rt_next_start);
++		interactive = !in_burst && idle_for_long_time;
++		entity->budget = max_t(unsigned long, bfqq->max_budget,
++				       bfq_serv_to_charge(next_rq, bfqq));
++
++		if (!bfq_bfqq_IO_bound(bfqq)) {
++			if (time_before(jiffies,
++					RQ_BIC(rq)->ttime.last_end_request +
++					bfqd->bfq_slice_idle)) {
++				bfqq->requests_within_timer++;
++				if (bfqq->requests_within_timer >=
++				    bfqd->bfq_requests_within_timer)
++					bfq_mark_bfqq_IO_bound(bfqq);
++			} else
++				bfqq->requests_within_timer = 0;
++		}
++
++		if (!bfqd->low_latency)
++			goto add_bfqq_busy;
++
++		/*
++		 * If the queue:
++		 * - is not being boosted,
++		 * - has been idle for enough time,
++		 * - is not a sync queue or is linked to a bfq_io_cq (it is
++		 *   shared "for its nature" or it is not shared and its
++		 *   requests have not been redirected to a shared queue)
++		 * start a weight-raising period.
++		 */
++		if (old_wr_coeff == 1 && (interactive || soft_rt) &&
++		    (!bfq_bfqq_sync(bfqq) || bfqq->bic)) {
++			bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++			if (interactive)
++				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++			else
++				bfqq->wr_cur_max_time =
++					bfqd->bfq_wr_rt_max_time;
++			bfq_log_bfqq(bfqd, bfqq,
++				     "wrais starting at %lu, rais_max_time %u",
++				     jiffies,
++				     jiffies_to_msecs(bfqq->wr_cur_max_time));
++		} else if (old_wr_coeff > 1) {
++			if (interactive)
++				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++			else if (in_burst ||
++				 (bfqq->wr_cur_max_time ==
++				  bfqd->bfq_wr_rt_max_time &&
++				  !soft_rt)) {
++				bfqq->wr_coeff = 1;
++				bfq_log_bfqq(bfqd, bfqq,
++					"wrais ending at %lu, rais_max_time %u",
++					jiffies,
++					jiffies_to_msecs(bfqq->
++						wr_cur_max_time));
++			} else if (time_before(
++					bfqq->last_wr_start_finish +
++					bfqq->wr_cur_max_time,
++					jiffies +
++					bfqd->bfq_wr_rt_max_time) &&
++				   soft_rt) {
++				/*
++				 *
++				 * The remaining weight-raising time is lower
++				 * than bfqd->bfq_wr_rt_max_time, which means
++				 * that the application is enjoying weight
++				 * raising either because deemed soft-rt in
++				 * the near past, or because deemed interactive
++				 * a long ago.
++				 * In both cases, resetting now the current
++				 * remaining weight-raising time for the
++				 * application to the weight-raising duration
++				 * for soft rt applications would not cause any
++				 * latency increase for the application (as the
++				 * new duration would be higher than the
++				 * remaining time).
++				 *
++				 * In addition, the application is now meeting
++				 * the requirements for being deemed soft rt.
++				 * In the end we can correctly and safely
++				 * (re)charge the weight-raising duration for
++				 * the application with the weight-raising
++				 * duration for soft rt applications.
++				 *
++				 * In particular, doing this recharge now, i.e.,
++				 * before the weight-raising period for the
++				 * application finishes, reduces the probability
++				 * of the following negative scenario:
++				 * 1) the weight of a soft rt application is
++				 *    raised at startup (as for any newly
++				 *    created application),
++				 * 2) since the application is not interactive,
++				 *    at a certain time weight-raising is
++				 *    stopped for the application,
++				 * 3) at that time the application happens to
++				 *    still have pending requests, and hence
++				 *    is destined to not have a chance to be
++				 *    deemed soft rt before these requests are
++				 *    completed (see the comments to the
++				 *    function bfq_bfqq_softrt_next_start()
++				 *    for details on soft rt detection),
++				 * 4) these pending requests experience a high
++				 *    latency because the application is not
++				 *    weight-raised while they are pending.
++				 */
++				bfqq->last_wr_start_finish = jiffies;
++				bfqq->wr_cur_max_time =
++					bfqd->bfq_wr_rt_max_time;
++			}
++		}
++		if (old_wr_coeff != bfqq->wr_coeff)
++			entity->prio_changed = 1;
++add_bfqq_busy:
++		bfqq->last_idle_bklogged = jiffies;
++		bfqq->service_from_backlogged = 0;
++		bfq_clear_bfqq_softrt_update(bfqq);
++		bfq_add_bfqq_busy(bfqd, bfqq);
++	} else {
++		if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) &&
++		    time_is_before_jiffies(
++				bfqq->last_wr_start_finish +
++				bfqd->bfq_wr_min_inter_arr_async)) {
++			bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++			bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++
++			bfqd->wr_busy_queues++;
++			entity->prio_changed = 1;
++			bfq_log_bfqq(bfqd, bfqq,
++			    "non-idle wrais starting at %lu, rais_max_time %u",
++			    jiffies,
++			    jiffies_to_msecs(bfqq->wr_cur_max_time));
++		}
++		if (prev != bfqq->next_rq)
++			bfq_updated_next_req(bfqd, bfqq);
++	}
++
++	if (bfqd->low_latency &&
++		(old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive))
++		bfqq->last_wr_start_finish = jiffies;
++}
++
++static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd,
++					  struct bio *bio)
++{
++	struct task_struct *tsk = current;
++	struct bfq_io_cq *bic;
++	struct bfq_queue *bfqq;
++
++	bic = bfq_bic_lookup(bfqd, tsk->io_context);
++	if (!bic)
++		return NULL;
++
++	bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
++	if (bfqq)
++		return elv_rb_find(&bfqq->sort_list, bio_end_sector(bio));
++
++	return NULL;
++}
++
++static void bfq_activate_request(struct request_queue *q, struct request *rq)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++
++	bfqd->rq_in_driver++;
++	bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
++	bfq_log(bfqd, "activate_request: new bfqd->last_position %llu",
++		(unsigned long long) bfqd->last_position);
++}
++
++static void bfq_deactivate_request(struct request_queue *q, struct request *rq)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++
++	BUG_ON(bfqd->rq_in_driver == 0);
++	bfqd->rq_in_driver--;
++}
++
++static void bfq_remove_request(struct request *rq)
++{
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++	struct bfq_data *bfqd = bfqq->bfqd;
++	const int sync = rq_is_sync(rq);
++
++	if (bfqq->next_rq == rq) {
++		bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq);
++		bfq_updated_next_req(bfqd, bfqq);
++	}
++
++	if (rq->queuelist.prev != &rq->queuelist)
++		list_del_init(&rq->queuelist);
++	BUG_ON(bfqq->queued[sync] == 0);
++	bfqq->queued[sync]--;
++	bfqd->queued--;
++	elv_rb_del(&bfqq->sort_list, rq);
++
++	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
++		if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue)
++			bfq_del_bfqq_busy(bfqd, bfqq, 1);
++		/*
++		 * Remove queue from request-position tree as it is empty.
++		 */
++		if (bfqq->pos_root) {
++			rb_erase(&bfqq->pos_node, bfqq->pos_root);
++			bfqq->pos_root = NULL;
++		}
++	}
++
++	if (rq->cmd_flags & REQ_META) {
++		BUG_ON(bfqq->meta_pending == 0);
++		bfqq->meta_pending--;
++	}
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_update_io_remove(bfqq_group(bfqq), rq->cmd_flags);
++#endif
++}
++
++static int bfq_merge(struct request_queue *q, struct request **req,
++		     struct bio *bio)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct request *__rq;
++
++	__rq = bfq_find_rq_fmerge(bfqd, bio);
++	if (__rq && elv_rq_merge_ok(__rq, bio)) {
++		*req = __rq;
++		return ELEVATOR_FRONT_MERGE;
++	}
++
++	return ELEVATOR_NO_MERGE;
++}
++
++static void bfq_merged_request(struct request_queue *q, struct request *req,
++			       int type)
++{
++	if (type == ELEVATOR_FRONT_MERGE &&
++	    rb_prev(&req->rb_node) &&
++	    blk_rq_pos(req) <
++	    blk_rq_pos(container_of(rb_prev(&req->rb_node),
++				    struct request, rb_node))) {
++		struct bfq_queue *bfqq = RQ_BFQQ(req);
++		struct bfq_data *bfqd = bfqq->bfqd;
++		struct request *prev, *next_rq;
++
++		/* Reposition request in its sort_list */
++		elv_rb_del(&bfqq->sort_list, req);
++		elv_rb_add(&bfqq->sort_list, req);
++		/* Choose next request to be served for bfqq */
++		prev = bfqq->next_rq;
++		next_rq = bfq_choose_req(bfqd, bfqq->next_rq, req,
++					 bfqd->last_position);
++		BUG_ON(!next_rq);
++		bfqq->next_rq = next_rq;
++	}
++}
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++static void bfq_bio_merged(struct request_queue *q, struct request *req,
++			   struct bio *bio)
++{
++	bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio->bi_rw);
++}
++#endif
++
++static void bfq_merged_requests(struct request_queue *q, struct request *rq,
++				struct request *next)
++{
++	struct bfq_queue *bfqq = RQ_BFQQ(rq), *next_bfqq = RQ_BFQQ(next);
++
++	/*
++	 * If next and rq belong to the same bfq_queue and next is older
++	 * than rq, then reposition rq in the fifo (by substituting next
++	 * with rq). Otherwise, if next and rq belong to different
++	 * bfq_queues, never reposition rq: in fact, we would have to
++	 * reposition it with respect to next's position in its own fifo,
++	 * which would most certainly be too expensive with respect to
++	 * the benefits.
++	 */
++	if (bfqq == next_bfqq &&
++	    !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
++	    time_before(next->fifo_time, rq->fifo_time)) {
++		list_del_init(&rq->queuelist);
++		list_replace_init(&next->queuelist, &rq->queuelist);
++		rq->fifo_time = next->fifo_time;
++	}
++
++	if (bfqq->next_rq == next)
++		bfqq->next_rq = rq;
++
++	bfq_remove_request(next);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_update_io_merged(bfqq_group(bfqq), next->cmd_flags);
++#endif
++}
++
++/* Must be called with bfqq != NULL */
++static void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
++{
++	BUG_ON(!bfqq);
++	if (bfq_bfqq_busy(bfqq))
++		bfqq->bfqd->wr_busy_queues--;
++	bfqq->wr_coeff = 1;
++	bfqq->wr_cur_max_time = 0;
++	/* Trigger a weight change on the next activation of the queue */
++	bfqq->entity.prio_changed = 1;
++}
++
++static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
++				    struct bfq_group *bfqg)
++{
++	int i, j;
++
++	for (i = 0; i < 2; i++)
++		for (j = 0; j < IOPRIO_BE_NR; j++)
++			if (bfqg->async_bfqq[i][j])
++				bfq_bfqq_end_wr(bfqg->async_bfqq[i][j]);
++	if (bfqg->async_idle_bfqq)
++		bfq_bfqq_end_wr(bfqg->async_idle_bfqq);
++}
++
++static void bfq_end_wr(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq;
++
++	spin_lock_irq(bfqd->queue->queue_lock);
++
++	list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list)
++		bfq_bfqq_end_wr(bfqq);
++	list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list)
++		bfq_bfqq_end_wr(bfqq);
++	bfq_end_wr_async(bfqd);
++
++	spin_unlock_irq(bfqd->queue->queue_lock);
++}
++
++static int bfq_allow_merge(struct request_queue *q, struct request *rq,
++			   struct bio *bio)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct bfq_io_cq *bic;
++
++	/*
++	 * Disallow merge of a sync bio into an async request.
++	 */
++	if (bfq_bio_sync(bio) && !rq_is_sync(rq))
++		return 0;
++
++	/*
++	 * Lookup the bfqq that this bio will be queued with. Allow
++	 * merge only if rq is queued there.
++	 * Queue lock is held here.
++	 */
++	bic = bfq_bic_lookup(bfqd, current->io_context);
++	if (!bic)
++		return 0;
++
++	return bic_to_bfqq(bic, bfq_bio_sync(bio)) == RQ_BFQQ(rq);
++}
++
++static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
++				       struct bfq_queue *bfqq)
++{
++	if (bfqq) {
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		bfqg_stats_update_avg_queue_size(bfqq_group(bfqq));
++#endif
++		bfq_mark_bfqq_must_alloc(bfqq);
++		bfq_mark_bfqq_budget_new(bfqq);
++		bfq_clear_bfqq_fifo_expire(bfqq);
++
++		bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8;
++
++		bfq_log_bfqq(bfqd, bfqq,
++			     "set_in_service_queue, cur-budget = %d",
++			     bfqq->entity.budget);
++	}
++
++	bfqd->in_service_queue = bfqq;
++}
++
++/*
++ * Get and set a new queue for service.
++ */
++static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq = bfq_get_next_queue(bfqd);
++
++	__bfq_set_in_service_queue(bfqd, bfqq);
++	return bfqq;
++}
++
++/*
++ * If enough samples have been computed, return the current max budget
++ * stored in bfqd, which is dynamically updated according to the
++ * estimated disk peak rate; otherwise return the default max budget
++ */
++static int bfq_max_budget(struct bfq_data *bfqd)
++{
++	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
++		return bfq_default_max_budget;
++	else
++		return bfqd->bfq_max_budget;
++}
++
++/*
++ * Return min budget, which is a fraction of the current or default
++ * max budget (trying with 1/32)
++ */
++static int bfq_min_budget(struct bfq_data *bfqd)
++{
++	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
++		return bfq_default_max_budget / 32;
++	else
++		return bfqd->bfq_max_budget / 32;
++}
++
++static void bfq_arm_slice_timer(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq = bfqd->in_service_queue;
++	struct bfq_io_cq *bic;
++	unsigned long sl;
++
++	BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
++
++	/* Processes have exited, don't wait. */
++	bic = bfqd->in_service_bic;
++	if (!bic || atomic_read(&bic->icq.ioc->active_ref) == 0)
++		return;
++
++	bfq_mark_bfqq_wait_request(bfqq);
++
++	/*
++	 * We don't want to idle for seeks, but we do want to allow
++	 * fair distribution of slice time for a process doing back-to-back
++	 * seeks. So allow a little bit of time for him to submit a new rq.
++	 *
++	 * To prevent processes with (partly) seeky workloads from
++	 * being too ill-treated, grant them a small fraction of the
++	 * assigned budget before reducing the waiting time to
++	 * BFQ_MIN_TT. This happened to help reduce latency.
++	 */
++	sl = bfqd->bfq_slice_idle;
++	/*
++	 * Unless the queue is being weight-raised or the scenario is
++	 * asymmetric, grant only minimum idle time if the queue either
++	 * has been seeky for long enough or has already proved to be
++	 * constantly seeky.
++	 */
++	if (bfq_sample_valid(bfqq->seek_samples) &&
++	    ((BFQQ_SEEKY(bfqq) && bfqq->entity.service >
++				  bfq_max_budget(bfqq->bfqd) / 8) ||
++	      bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 &&
++	    bfq_symmetric_scenario(bfqd))
++		sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
++	else if (bfqq->wr_coeff > 1)
++		sl = sl * 3;
++	bfqd->last_idling_start = ktime_get();
++	mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_set_start_idle_time(bfqq_group(bfqq));
++#endif
++	bfq_log(bfqd, "arm idle: %u/%u ms",
++		jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
++}
++
++/*
++ * Set the maximum time for the in-service queue to consume its
++ * budget. This prevents seeky processes from lowering the disk
++ * throughput (always guaranteed with a time slice scheme as in CFQ).
++ */
++static void bfq_set_budget_timeout(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq = bfqd->in_service_queue;
++	unsigned int timeout_coeff;
++
++	if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
++		timeout_coeff = 1;
++	else
++		timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
++
++	bfqd->last_budget_start = ktime_get();
++
++	bfq_clear_bfqq_budget_new(bfqq);
++	bfqq->budget_timeout = jiffies +
++		bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff;
++
++	bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
++		jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
++		timeout_coeff));
++}
++
++/*
++ * Move request from internal lists to the request queue dispatch list.
++ */
++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++
++	/*
++	 * For consistency, the next instruction should have been executed
++	 * after removing the request from the queue and dispatching it.
++	 * We execute instead this instruction before bfq_remove_request()
++	 * (and hence introduce a temporary inconsistency), for efficiency.
++	 * In fact, in a forced_dispatch, this prevents two counters related
++	 * to bfqq->dispatched to risk to be uselessly decremented if bfqq
++	 * is not in service, and then to be incremented again after
++	 * incrementing bfqq->dispatched.
++	 */
++	bfqq->dispatched++;
++	bfq_remove_request(rq);
++	elv_dispatch_sort(q, rq);
++
++	if (bfq_bfqq_sync(bfqq))
++		bfqd->sync_flight++;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_update_dispatch(bfqq_group(bfqq), blk_rq_bytes(rq),
++				   rq->cmd_flags);
++#endif
++}
++
++/*
++ * Return expired entry, or NULL to just start from scratch in rbtree.
++ */
++static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
++{
++	struct request *rq = NULL;
++
++	if (bfq_bfqq_fifo_expire(bfqq))
++		return NULL;
++
++	bfq_mark_bfqq_fifo_expire(bfqq);
++
++	if (list_empty(&bfqq->fifo))
++		return NULL;
++
++	rq = rq_entry_fifo(bfqq->fifo.next);
++
++	if (time_before(jiffies, rq->fifo_time))
++		return NULL;
++
++	return rq;
++}
++
++static int bfq_bfqq_budget_left(struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	return entity->budget - entity->service;
++}
++
++static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	BUG_ON(bfqq != bfqd->in_service_queue);
++
++	__bfq_bfqd_reset_in_service(bfqd);
++
++	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
++		/*
++		 * Overloading budget_timeout field to store the time
++		 * at which the queue remains with no backlog; used by
++		 * the weight-raising mechanism.
++		 */
++		bfqq->budget_timeout = jiffies;
++		bfq_del_bfqq_busy(bfqd, bfqq, 1);
++	} else
++		bfq_activate_bfqq(bfqd, bfqq);
++}
++
++/**
++ * __bfq_bfqq_recalc_budget - try to adapt the budget to the @bfqq behavior.
++ * @bfqd: device data.
++ * @bfqq: queue to update.
++ * @reason: reason for expiration.
++ *
++ * Handle the feedback on @bfqq budget at queue expiration.
++ * See the body for detailed comments.
++ */
++static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
++				     struct bfq_queue *bfqq,
++				     enum bfqq_expiration reason)
++{
++	struct request *next_rq;
++	int budget, min_budget;
++
++	budget = bfqq->max_budget;
++	min_budget = bfq_min_budget(bfqd);
++
++	BUG_ON(bfqq != bfqd->in_service_queue);
++
++	bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %d, budg left %d",
++		bfqq->entity.budget, bfq_bfqq_budget_left(bfqq));
++	bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last max_budg %d, min budg %d",
++		budget, bfq_min_budget(bfqd));
++	bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d",
++		bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue));
++
++	if (bfq_bfqq_sync(bfqq)) {
++		switch (reason) {
++		/*
++		 * Caveat: in all the following cases we trade latency
++		 * for throughput.
++		 */
++		case BFQ_BFQQ_TOO_IDLE:
++			/*
++			 * This is the only case where we may reduce
++			 * the budget: if there is no request of the
++			 * process still waiting for completion, then
++			 * we assume (tentatively) that the timer has
++			 * expired because the batch of requests of
++			 * the process could have been served with a
++			 * smaller budget.  Hence, betting that
++			 * process will behave in the same way when it
++			 * becomes backlogged again, we reduce its
++			 * next budget.  As long as we guess right,
++			 * this budget cut reduces the latency
++			 * experienced by the process.
++			 *
++			 * However, if there are still outstanding
++			 * requests, then the process may have not yet
++			 * issued its next request just because it is
++			 * still waiting for the completion of some of
++			 * the still outstanding ones.  So in this
++			 * subcase we do not reduce its budget, on the
++			 * contrary we increase it to possibly boost
++			 * the throughput, as discussed in the
++			 * comments to the BUDGET_TIMEOUT case.
++			 */
++			if (bfqq->dispatched > 0) /* still outstanding reqs */
++				budget = min(budget * 2, bfqd->bfq_max_budget);
++			else {
++				if (budget > 5 * min_budget)
++					budget -= 4 * min_budget;
++				else
++					budget = min_budget;
++			}
++			break;
++		case BFQ_BFQQ_BUDGET_TIMEOUT:
++			/*
++			 * We double the budget here because: 1) it
++			 * gives the chance to boost the throughput if
++			 * this is not a seeky process (which may have
++			 * bumped into this timeout because of, e.g.,
++			 * ZBR), 2) together with charge_full_budget
++			 * it helps give seeky processes higher
++			 * timestamps, and hence be served less
++			 * frequently.
++			 */
++			budget = min(budget * 2, bfqd->bfq_max_budget);
++			break;
++		case BFQ_BFQQ_BUDGET_EXHAUSTED:
++			/*
++			 * The process still has backlog, and did not
++			 * let either the budget timeout or the disk
++			 * idling timeout expire. Hence it is not
++			 * seeky, has a short thinktime and may be
++			 * happy with a higher budget too. So
++			 * definitely increase the budget of this good
++			 * candidate to boost the disk throughput.
++			 */
++			budget = min(budget * 4, bfqd->bfq_max_budget);
++			break;
++		case BFQ_BFQQ_NO_MORE_REQUESTS:
++		       /*
++			* Leave the budget unchanged.
++			*/
++		default:
++			return;
++		}
++	} else
++		/*
++		 * Async queues get always the maximum possible budget
++		 * (their ability to dispatch is limited by
++		 * @bfqd->bfq_max_budget_async_rq).
++		 */
++		budget = bfqd->bfq_max_budget;
++
++	bfqq->max_budget = budget;
++
++	if (bfqd->budgets_assigned >= bfq_stats_min_budgets &&
++	    !bfqd->bfq_user_max_budget)
++		bfqq->max_budget = min(bfqq->max_budget, bfqd->bfq_max_budget);
++
++	/*
++	 * Make sure that we have enough budget for the next request.
++	 * Since the finish time of the bfqq must be kept in sync with
++	 * the budget, be sure to call __bfq_bfqq_expire() after the
++	 * update.
++	 */
++	next_rq = bfqq->next_rq;
++	if (next_rq)
++		bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget,
++					    bfq_serv_to_charge(next_rq, bfqq));
++	else
++		bfqq->entity.budget = bfqq->max_budget;
++
++	bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %d",
++			next_rq ? blk_rq_sectors(next_rq) : 0,
++			bfqq->entity.budget);
++}
++
++static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout)
++{
++	unsigned long max_budget;
++
++	/*
++	 * The max_budget calculated when autotuning is equal to the
++	 * amount of sectors transfered in timeout_sync at the
++	 * estimated peak rate.
++	 */
++	max_budget = (unsigned long)(peak_rate * 1000 *
++				     timeout >> BFQ_RATE_SHIFT);
++
++	return max_budget;
++}
++
++/*
++ * In addition to updating the peak rate, checks whether the process
++ * is "slow", and returns 1 if so. This slow flag is used, in addition
++ * to the budget timeout, to reduce the amount of service provided to
++ * seeky processes, and hence reduce their chances to lower the
++ * throughput. See the code for more details.
++ */
++static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++				 bool compensate, enum bfqq_expiration reason)
++{
++	u64 bw, usecs, expected, timeout;
++	ktime_t delta;
++	int update = 0;
++
++	if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq))
++		return false;
++
++	if (compensate)
++		delta = bfqd->last_idling_start;
++	else
++		delta = ktime_get();
++	delta = ktime_sub(delta, bfqd->last_budget_start);
++	usecs = ktime_to_us(delta);
++
++	/* Don't trust short/unrealistic values. */
++	if (usecs < 100 || usecs >= LONG_MAX)
++		return false;
++
++	/*
++	 * Calculate the bandwidth for the last slice.  We use a 64 bit
++	 * value to store the peak rate, in sectors per usec in fixed
++	 * point math.  We do so to have enough precision in the estimate
++	 * and to avoid overflows.
++	 */
++	bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT;
++	do_div(bw, (unsigned long)usecs);
++
++	timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
++
++	/*
++	 * Use only long (> 20ms) intervals to filter out spikes for
++	 * the peak rate estimation.
++	 */
++	if (usecs > 20000) {
++		if (bw > bfqd->peak_rate ||
++		   (!BFQQ_SEEKY(bfqq) &&
++		    reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
++			bfq_log(bfqd, "measured bw =%llu", bw);
++			/*
++			 * To smooth oscillations use a low-pass filter with
++			 * alpha=7/8, i.e.,
++			 * new_rate = (7/8) * old_rate + (1/8) * bw
++			 */
++			do_div(bw, 8);
++			if (bw == 0)
++				return 0;
++			bfqd->peak_rate *= 7;
++			do_div(bfqd->peak_rate, 8);
++			bfqd->peak_rate += bw;
++			update = 1;
++			bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
++		}
++
++		update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
++
++		if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES)
++			bfqd->peak_rate_samples++;
++
++		if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES &&
++		    update) {
++			int dev_type = blk_queue_nonrot(bfqd->queue);
++
++			if (bfqd->bfq_user_max_budget == 0) {
++				bfqd->bfq_max_budget =
++					bfq_calc_max_budget(bfqd->peak_rate,
++							    timeout);
++				bfq_log(bfqd, "new max_budget=%d",
++					bfqd->bfq_max_budget);
++			}
++			if (bfqd->device_speed == BFQ_BFQD_FAST &&
++			    bfqd->peak_rate < device_speed_thresh[dev_type]) {
++				bfqd->device_speed = BFQ_BFQD_SLOW;
++				bfqd->RT_prod = R_slow[dev_type] *
++						T_slow[dev_type];
++			} else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
++			    bfqd->peak_rate > device_speed_thresh[dev_type]) {
++				bfqd->device_speed = BFQ_BFQD_FAST;
++				bfqd->RT_prod = R_fast[dev_type] *
++						T_fast[dev_type];
++			}
++		}
++	}
++
++	/*
++	 * If the process has been served for a too short time
++	 * interval to let its possible sequential accesses prevail on
++	 * the initial seek time needed to move the disk head on the
++	 * first sector it requested, then give the process a chance
++	 * and for the moment return false.
++	 */
++	if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8)
++		return false;
++
++	/*
++	 * A process is considered ``slow'' (i.e., seeky, so that we
++	 * cannot treat it fairly in the service domain, as it would
++	 * slow down too much the other processes) if, when a slice
++	 * ends for whatever reason, it has received service at a
++	 * rate that would not be high enough to complete the budget
++	 * before the budget timeout expiration.
++	 */
++	expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT;
++
++	/*
++	 * Caveat: processes doing IO in the slower disk zones will
++	 * tend to be slow(er) even if not seeky. And the estimated
++	 * peak rate will actually be an average over the disk
++	 * surface. Hence, to not be too harsh with unlucky processes,
++	 * we keep a budget/3 margin of safety before declaring a
++	 * process slow.
++	 */
++	return expected > (4 * bfqq->entity.budget) / 3;
++}
++
++/*
++ * To be deemed as soft real-time, an application must meet two
++ * requirements. First, the application must not require an average
++ * bandwidth higher than the approximate bandwidth required to playback or
++ * record a compressed high-definition video.
++ * The next function is invoked on the completion of the last request of a
++ * batch, to compute the next-start time instant, soft_rt_next_start, such
++ * that, if the next request of the application does not arrive before
++ * soft_rt_next_start, then the above requirement on the bandwidth is met.
++ *
++ * The second requirement is that the request pattern of the application is
++ * isochronous, i.e., that, after issuing a request or a batch of requests,
++ * the application stops issuing new requests until all its pending requests
++ * have been completed. After that, the application may issue a new batch,
++ * and so on.
++ * For this reason the next function is invoked to compute
++ * soft_rt_next_start only for applications that meet this requirement,
++ * whereas soft_rt_next_start is set to infinity for applications that do
++ * not.
++ *
++ * Unfortunately, even a greedy application may happen to behave in an
++ * isochronous way if the CPU load is high. In fact, the application may
++ * stop issuing requests while the CPUs are busy serving other processes,
++ * then restart, then stop again for a while, and so on. In addition, if
++ * the disk achieves a low enough throughput with the request pattern
++ * issued by the application (e.g., because the request pattern is random
++ * and/or the device is slow), then the application may meet the above
++ * bandwidth requirement too. To prevent such a greedy application to be
++ * deemed as soft real-time, a further rule is used in the computation of
++ * soft_rt_next_start: soft_rt_next_start must be higher than the current
++ * time plus the maximum time for which the arrival of a request is waited
++ * for when a sync queue becomes idle, namely bfqd->bfq_slice_idle.
++ * This filters out greedy applications, as the latter issue instead their
++ * next request as soon as possible after the last one has been completed
++ * (in contrast, when a batch of requests is completed, a soft real-time
++ * application spends some time processing data).
++ *
++ * Unfortunately, the last filter may easily generate false positives if
++ * only bfqd->bfq_slice_idle is used as a reference time interval and one
++ * or both the following cases occur:
++ * 1) HZ is so low that the duration of a jiffy is comparable to or higher
++ *    than bfqd->bfq_slice_idle. This happens, e.g., on slow devices with
++ *    HZ=100.
++ * 2) jiffies, instead of increasing at a constant rate, may stop increasing
++ *    for a while, then suddenly 'jump' by several units to recover the lost
++ *    increments. This seems to happen, e.g., inside virtual machines.
++ * To address this issue, we do not use as a reference time interval just
++ * bfqd->bfq_slice_idle, but bfqd->bfq_slice_idle plus a few jiffies. In
++ * particular we add the minimum number of jiffies for which the filter
++ * seems to be quite precise also in embedded systems and KVM/QEMU virtual
++ * machines.
++ */
++static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
++						struct bfq_queue *bfqq)
++{
++	return max(bfqq->last_idle_bklogged +
++		   HZ * bfqq->service_from_backlogged /
++		   bfqd->bfq_wr_max_softrt_rate,
++		   jiffies + bfqq->bfqd->bfq_slice_idle + 4);
++}
++
++/*
++ * Return the largest-possible time instant such that, for as long as possible,
++ * the current time will be lower than this time instant according to the macro
++ * time_is_before_jiffies().
++ */
++static unsigned long bfq_infinity_from_now(unsigned long now)
++{
++	return now + ULONG_MAX / 2;
++}
++
++/**
++ * bfq_bfqq_expire - expire a queue.
++ * @bfqd: device owning the queue.
++ * @bfqq: the queue to expire.
++ * @compensate: if true, compensate for the time spent idling.
++ * @reason: the reason causing the expiration.
++ *
++ *
++ * If the process associated to the queue is slow (i.e., seeky), or in
++ * case of budget timeout, or, finally, if it is async, we
++ * artificially charge it an entire budget (independently of the
++ * actual service it received). As a consequence, the queue will get
++ * higher timestamps than the correct ones upon reactivation, and
++ * hence it will be rescheduled as if it had received more service
++ * than what it actually received. In the end, this class of processes
++ * will receive less service in proportion to how slowly they consume
++ * their budgets (and hence how seriously they tend to lower the
++ * throughput).
++ *
++ * In contrast, when a queue expires because it has been idling for
++ * too much or because it exhausted its budget, we do not touch the
++ * amount of service it has received. Hence when the queue will be
++ * reactivated and its timestamps updated, the latter will be in sync
++ * with the actual service received by the queue until expiration.
++ *
++ * Charging a full budget to the first type of queues and the exact
++ * service to the others has the effect of using the WF2Q+ policy to
++ * schedule the former on a timeslice basis, without violating the
++ * service domain guarantees of the latter.
++ */
++static void bfq_bfqq_expire(struct bfq_data *bfqd,
++			    struct bfq_queue *bfqq,
++			    bool compensate,
++			    enum bfqq_expiration reason)
++{
++	bool slow;
++
++	BUG_ON(bfqq != bfqd->in_service_queue);
++
++	/*
++	 * Update disk peak rate for autotuning and check whether the
++	 * process is slow (see bfq_update_peak_rate).
++	 */
++	slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason);
++
++	/*
++	 * As above explained, 'punish' slow (i.e., seeky), timed-out
++	 * and async queues, to favor sequential sync workloads.
++	 *
++	 * Processes doing I/O in the slower disk zones will tend to be
++	 * slow(er) even if not seeky. Hence, since the estimated peak
++	 * rate is actually an average over the disk surface, these
++	 * processes may timeout just for bad luck. To avoid punishing
++	 * them we do not charge a full budget to a process that
++	 * succeeded in consuming at least 2/3 of its budget.
++	 */
++	if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
++		     bfq_bfqq_budget_left(bfqq) >=  bfqq->entity.budget / 3))
++		bfq_bfqq_charge_full_budget(bfqq);
++
++	bfqq->service_from_backlogged += bfqq->entity.service;
++
++	if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
++	    !bfq_bfqq_constantly_seeky(bfqq)) {
++		bfq_mark_bfqq_constantly_seeky(bfqq);
++		if (!blk_queue_nonrot(bfqd->queue))
++			bfqd->const_seeky_busy_in_flight_queues++;
++	}
++
++	if (reason == BFQ_BFQQ_TOO_IDLE &&
++	    bfqq->entity.service <= 2 * bfqq->entity.budget / 10)
++		bfq_clear_bfqq_IO_bound(bfqq);
++
++	if (bfqd->low_latency && bfqq->wr_coeff == 1)
++		bfqq->last_wr_start_finish = jiffies;
++
++	if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 &&
++	    RB_EMPTY_ROOT(&bfqq->sort_list)) {
++		/*
++		 * If we get here, and there are no outstanding requests,
++		 * then the request pattern is isochronous (see the comments
++		 * to the function bfq_bfqq_softrt_next_start()). Hence we
++		 * can compute soft_rt_next_start. If, instead, the queue
++		 * still has outstanding requests, then we have to wait
++		 * for the completion of all the outstanding requests to
++		 * discover whether the request pattern is actually
++		 * isochronous.
++		 */
++		if (bfqq->dispatched == 0)
++			bfqq->soft_rt_next_start =
++				bfq_bfqq_softrt_next_start(bfqd, bfqq);
++		else {
++			/*
++			 * The application is still waiting for the
++			 * completion of one or more requests:
++			 * prevent it from possibly being incorrectly
++			 * deemed as soft real-time by setting its
++			 * soft_rt_next_start to infinity. In fact,
++			 * without this assignment, the application
++			 * would be incorrectly deemed as soft
++			 * real-time if:
++			 * 1) it issued a new request before the
++			 *    completion of all its in-flight
++			 *    requests, and
++			 * 2) at that time, its soft_rt_next_start
++			 *    happened to be in the past.
++			 */
++			bfqq->soft_rt_next_start =
++				bfq_infinity_from_now(jiffies);
++			/*
++			 * Schedule an update of soft_rt_next_start to when
++			 * the task may be discovered to be isochronous.
++			 */
++			bfq_mark_bfqq_softrt_update(bfqq);
++		}
++	}
++
++	bfq_log_bfqq(bfqd, bfqq,
++		"expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
++		slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
++
++	/*
++	 * Increase, decrease or leave budget unchanged according to
++	 * reason.
++	 */
++	__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
++	__bfq_bfqq_expire(bfqd, bfqq);
++}
++
++/*
++ * Budget timeout is not implemented through a dedicated timer, but
++ * just checked on request arrivals and completions, as well as on
++ * idle timer expirations.
++ */
++static bool bfq_bfqq_budget_timeout(struct bfq_queue *bfqq)
++{
++	if (bfq_bfqq_budget_new(bfqq) ||
++	    time_before(jiffies, bfqq->budget_timeout))
++		return false;
++	return true;
++}
++
++/*
++ * If we expire a queue that is waiting for the arrival of a new
++ * request, we may prevent the fictitious timestamp back-shifting that
++ * allows the guarantees of the queue to be preserved (see [1] for
++ * this tricky aspect). Hence we return true only if this condition
++ * does not hold, or if the queue is slow enough to deserve only to be
++ * kicked off for preserving a high throughput.
++*/
++static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
++{
++	bfq_log_bfqq(bfqq->bfqd, bfqq,
++		"may_budget_timeout: wait_request %d left %d timeout %d",
++		bfq_bfqq_wait_request(bfqq),
++			bfq_bfqq_budget_left(bfqq) >=  bfqq->entity.budget / 3,
++		bfq_bfqq_budget_timeout(bfqq));
++
++	return (!bfq_bfqq_wait_request(bfqq) ||
++		bfq_bfqq_budget_left(bfqq) >=  bfqq->entity.budget / 3)
++		&&
++		bfq_bfqq_budget_timeout(bfqq);
++}
++
++/*
++ * For a queue that becomes empty, device idling is allowed only if
++ * this function returns true for that queue. As a consequence, since
++ * device idling plays a critical role for both throughput boosting
++ * and service guarantees, the return value of this function plays a
++ * critical role as well.
++ *
++ * In a nutshell, this function returns true only if idling is
++ * beneficial for throughput or, even if detrimental for throughput,
++ * idling is however necessary to preserve service guarantees (low
++ * latency, desired throughput distribution, ...). In particular, on
++ * NCQ-capable devices, this function tries to return false, so as to
++ * help keep the drives' internal queues full, whenever this helps the
++ * device boost the throughput without causing any service-guarantee
++ * issue.
++ *
++ * In more detail, the return value of this function is obtained by,
++ * first, computing a number of boolean variables that take into
++ * account throughput and service-guarantee issues, and, then,
++ * combining these variables in a logical expression. Most of the
++ * issues taken into account are not trivial. We discuss these issues
++ * while introducing the variables.
++ */
++static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
++{
++	struct bfq_data *bfqd = bfqq->bfqd;
++	bool idling_boosts_thr, idling_boosts_thr_without_issues,
++		all_queues_seeky, on_hdd_and_not_all_queues_seeky,
++		idling_needed_for_service_guarantees,
++		asymmetric_scenario;
++
++	/*
++	 * The next variable takes into account the cases where idling
++	 * boosts the throughput.
++	 *
++	 * The value of the variable is computed considering, first, that
++	 * idling is virtually always beneficial for the throughput if:
++	 * (a) the device is not NCQ-capable, or
++	 * (b) regardless of the presence of NCQ, the device is rotational
++	 *     and the request pattern for bfqq is I/O-bound and sequential.
++	 *
++	 * Secondly, and in contrast to the above item (b), idling an
++	 * NCQ-capable flash-based device would not boost the
++	 * throughput even with sequential I/O; rather it would lower
++	 * the throughput in proportion to how fast the device
++	 * is. Accordingly, the next variable is true if any of the
++	 * above conditions (a) and (b) is true, and, in particular,
++	 * happens to be false if bfqd is an NCQ-capable flash-based
++	 * device.
++	 */
++	idling_boosts_thr = !bfqd->hw_tag ||
++		(!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) &&
++		 bfq_bfqq_idle_window(bfqq));
++
++	/*
++	 * The value of the next variable,
++	 * idling_boosts_thr_without_issues, is equal to that of
++	 * idling_boosts_thr, unless a special case holds. In this
++	 * special case, described below, idling may cause problems to
++	 * weight-raised queues.
++	 *
++	 * When the request pool is saturated (e.g., in the presence
++	 * of write hogs), if the processes associated with
++	 * non-weight-raised queues ask for requests at a lower rate,
++	 * then processes associated with weight-raised queues have a
++	 * higher probability to get a request from the pool
++	 * immediately (or at least soon) when they need one. Thus
++	 * they have a higher probability to actually get a fraction
++	 * of the device throughput proportional to their high
++	 * weight. This is especially true with NCQ-capable drives,
++	 * which enqueue several requests in advance, and further
++	 * reorder internally-queued requests.
++	 *
++	 * For this reason, we force to false the value of
++	 * idling_boosts_thr_without_issues if there are weight-raised
++	 * busy queues. In this case, and if bfqq is not weight-raised,
++	 * this guarantees that the device is not idled for bfqq (if,
++	 * instead, bfqq is weight-raised, then idling will be
++	 * guaranteed by another variable, see below). Combined with
++	 * the timestamping rules of BFQ (see [1] for details), this
++	 * behavior causes bfqq, and hence any sync non-weight-raised
++	 * queue, to get a lower number of requests served, and thus
++	 * to ask for a lower number of requests from the request
++	 * pool, before the busy weight-raised queues get served
++	 * again. This often mitigates starvation problems in the
++	 * presence of heavy write workloads and NCQ, thereby
++	 * guaranteeing a higher application and system responsiveness
++	 * in these hostile scenarios.
++	 */
++	idling_boosts_thr_without_issues = idling_boosts_thr &&
++		bfqd->wr_busy_queues == 0;
++
++	/*
++	 * There are then two cases where idling must be performed not
++	 * for throughput concerns, but to preserve service
++	 * guarantees. In the description of these cases, we say, for
++	 * short, that a queue is sequential/random if the process
++	 * associated to the queue issues sequential/random requests
++	 * (in the second case the queue may be tagged as seeky or
++	 * even constantly_seeky).
++	 *
++	 * To introduce the first case, we note that, since
++	 * bfq_bfqq_idle_window(bfqq) is false if the device is
++	 * NCQ-capable and bfqq is random (see
++	 * bfq_update_idle_window()), then, from the above two
++	 * assignments it follows that
++	 * idling_boosts_thr_without_issues is false if the device is
++	 * NCQ-capable and bfqq is random. Therefore, for this case,
++	 * device idling would never be allowed if we used just
++	 * idling_boosts_thr_without_issues to decide whether to allow
++	 * it. And, beneficially, this would imply that throughput
++	 * would always be boosted also with random I/O on NCQ-capable
++	 * HDDs.
++	 *
++	 * But we must be careful on this point, to avoid an unfair
++	 * treatment for bfqq. In fact, because of the same above
++	 * assignments, idling_boosts_thr_without_issues is, on the
++	 * other hand, true if 1) the device is an HDD and bfqq is
++	 * sequential, and 2) there are no busy weight-raised
++	 * queues. As a consequence, if we used just
++	 * idling_boosts_thr_without_issues to decide whether to idle
++	 * the device, then with an HDD we might easily bump into a
++	 * scenario where queues that are sequential and I/O-bound
++	 * would enjoy idling, whereas random queues would not. The
++	 * latter might then get a low share of the device throughput,
++	 * simply because the former would get many requests served
++	 * after being set as in service, while the latter would not.
++	 *
++	 * To address this issue, we start by setting to true a
++	 * sentinel variable, on_hdd_and_not_all_queues_seeky, if the
++	 * device is rotational and not all queues with pending or
++	 * in-flight requests are constantly seeky (i.e., there are
++	 * active sequential queues, and bfqq might then be mistreated
++	 * if it does not enjoy idling because it is random).
++	 */
++	all_queues_seeky = bfq_bfqq_constantly_seeky(bfqq) &&
++			   bfqd->busy_in_flight_queues ==
++			   bfqd->const_seeky_busy_in_flight_queues;
++
++	on_hdd_and_not_all_queues_seeky =
++		!blk_queue_nonrot(bfqd->queue) && !all_queues_seeky;
++
++	/*
++	 * To introduce the second case where idling needs to be
++	 * performed to preserve service guarantees, we can note that
++	 * allowing the drive to enqueue more than one request at a
++	 * time, and hence delegating de facto final scheduling
++	 * decisions to the drive's internal scheduler, causes loss of
++	 * control on the actual request service order. In particular,
++	 * the critical situation is when requests from different
++	 * processes happens to be present, at the same time, in the
++	 * internal queue(s) of the drive. In such a situation, the
++	 * drive, by deciding the service order of the
++	 * internally-queued requests, does determine also the actual
++	 * throughput distribution among these processes. But the
++	 * drive typically has no notion or concern about per-process
++	 * throughput distribution, and makes its decisions only on a
++	 * per-request basis. Therefore, the service distribution
++	 * enforced by the drive's internal scheduler is likely to
++	 * coincide with the desired device-throughput distribution
++	 * only in a completely symmetric scenario where:
++	 * (i)  each of these processes must get the same throughput as
++	 *      the others;
++	 * (ii) all these processes have the same I/O pattern
++	 *      (either sequential or random).
++	 * In fact, in such a scenario, the drive will tend to treat
++	 * the requests of each of these processes in about the same
++	 * way as the requests of the others, and thus to provide
++	 * each of these processes with about the same throughput
++	 * (which is exactly the desired throughput distribution). In
++	 * contrast, in any asymmetric scenario, device idling is
++	 * certainly needed to guarantee that bfqq receives its
++	 * assigned fraction of the device throughput (see [1] for
++	 * details).
++	 *
++	 * We address this issue by controlling, actually, only the
++	 * symmetry sub-condition (i), i.e., provided that
++	 * sub-condition (i) holds, idling is not performed,
++	 * regardless of whether sub-condition (ii) holds. In other
++	 * words, only if sub-condition (i) holds, then idling is
++	 * allowed, and the device tends to be prevented from queueing
++	 * many requests, possibly of several processes. The reason
++	 * for not controlling also sub-condition (ii) is that, first,
++	 * in the case of an HDD, the asymmetry in terms of types of
++	 * I/O patterns is already taken in to account in the above
++	 * sentinel variable
++	 * on_hdd_and_not_all_queues_seeky. Secondly, in the case of a
++	 * flash-based device, we prefer however to privilege
++	 * throughput (and idling lowers throughput for this type of
++	 * devices), for the following reasons:
++	 * 1) differently from HDDs, the service time of random
++	 *    requests is not orders of magnitudes lower than the service
++	 *    time of sequential requests; thus, even if processes doing
++	 *    sequential I/O get a preferential treatment with respect to
++	 *    others doing random I/O, the consequences are not as
++	 *    dramatic as with HDDs;
++	 * 2) if a process doing random I/O does need strong
++	 *    throughput guarantees, it is hopefully already being
++	 *    weight-raised, or the user is likely to have assigned it a
++	 *    higher weight than the other processes (and thus
++	 *    sub-condition (i) is likely to be false, which triggers
++	 *    idling).
++	 *
++	 * According to the above considerations, the next variable is
++	 * true (only) if sub-condition (i) holds. To compute the
++	 * value of this variable, we not only use the return value of
++	 * the function bfq_symmetric_scenario(), but also check
++	 * whether bfqq is being weight-raised, because
++	 * bfq_symmetric_scenario() does not take into account also
++	 * weight-raised queues (see comments to
++	 * bfq_weights_tree_add()).
++	 *
++	 * As a side note, it is worth considering that the above
++	 * device-idling countermeasures may however fail in the
++	 * following unlucky scenario: if idling is (correctly)
++	 * disabled in a time period during which all symmetry
++	 * sub-conditions hold, and hence the device is allowed to
++	 * enqueue many requests, but at some later point in time some
++	 * sub-condition stops to hold, then it may become impossible
++	 * to let requests be served in the desired order until all
++	 * the requests already queued in the device have been served.
++	 */
++	asymmetric_scenario = bfqq->wr_coeff > 1 ||
++		!bfq_symmetric_scenario(bfqd);
++
++	/*
++	 * Finally, there is a case where maximizing throughput is the
++	 * best choice even if it may cause unfairness toward
++	 * bfqq. Such a case is when bfqq became active in a burst of
++	 * queue activations. Queues that became active during a large
++	 * burst benefit only from throughput, as discussed in the
++	 * comments to bfq_handle_burst. Thus, if bfqq became active
++	 * in a burst and not idling the device maximizes throughput,
++	 * then the device must no be idled, because not idling the
++	 * device provides bfqq and all other queues in the burst with
++	 * maximum benefit. Combining this and the two cases above, we
++	 * can now establish when idling is actually needed to
++	 * preserve service guarantees.
++	 */
++	idling_needed_for_service_guarantees =
++		(on_hdd_and_not_all_queues_seeky || asymmetric_scenario) &&
++		!bfq_bfqq_in_large_burst(bfqq);
++
++	/*
++	 * We have now all the components we need to compute the return
++	 * value of the function, which is true only if both the following
++	 * conditions hold:
++	 * 1) bfqq is sync, because idling make sense only for sync queues;
++	 * 2) idling either boosts the throughput (without issues), or
++	 *    is necessary to preserve service guarantees.
++	 */
++	return bfq_bfqq_sync(bfqq) &&
++		(idling_boosts_thr_without_issues ||
++		 idling_needed_for_service_guarantees);
++}
++
++/*
++ * If the in-service queue is empty but the function bfq_bfqq_may_idle
++ * returns true, then:
++ * 1) the queue must remain in service and cannot be expired, and
++ * 2) the device must be idled to wait for the possible arrival of a new
++ *    request for the queue.
++ * See the comments to the function bfq_bfqq_may_idle for the reasons
++ * why performing device idling is the best choice to boost the throughput
++ * and preserve service guarantees when bfq_bfqq_may_idle itself
++ * returns true.
++ */
++static bool bfq_bfqq_must_idle(struct bfq_queue *bfqq)
++{
++	struct bfq_data *bfqd = bfqq->bfqd;
++
++	return RB_EMPTY_ROOT(&bfqq->sort_list) && bfqd->bfq_slice_idle != 0 &&
++	       bfq_bfqq_may_idle(bfqq);
++}
++
++/*
++ * Select a queue for service.  If we have a current queue in service,
++ * check whether to continue servicing it, or retrieve and set a new one.
++ */
++static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq;
++	struct request *next_rq;
++	enum bfqq_expiration reason = BFQ_BFQQ_BUDGET_TIMEOUT;
++
++	bfqq = bfqd->in_service_queue;
++	if (!bfqq)
++		goto new_queue;
++
++	bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue");
++
++	if (bfq_may_expire_for_budg_timeout(bfqq) &&
++	    !timer_pending(&bfqd->idle_slice_timer) &&
++	    !bfq_bfqq_must_idle(bfqq))
++		goto expire;
++
++	next_rq = bfqq->next_rq;
++	/*
++	 * If bfqq has requests queued and it has enough budget left to
++	 * serve them, keep the queue, otherwise expire it.
++	 */
++	if (next_rq) {
++		if (bfq_serv_to_charge(next_rq, bfqq) >
++			bfq_bfqq_budget_left(bfqq)) {
++			reason = BFQ_BFQQ_BUDGET_EXHAUSTED;
++			goto expire;
++		} else {
++			/*
++			 * The idle timer may be pending because we may
++			 * not disable disk idling even when a new request
++			 * arrives.
++			 */
++			if (timer_pending(&bfqd->idle_slice_timer)) {
++				/*
++				 * If we get here: 1) at least a new request
++				 * has arrived but we have not disabled the
++				 * timer because the request was too small,
++				 * 2) then the block layer has unplugged
++				 * the device, causing the dispatch to be
++				 * invoked.
++				 *
++				 * Since the device is unplugged, now the
++				 * requests are probably large enough to
++				 * provide a reasonable throughput.
++				 * So we disable idling.
++				 */
++				bfq_clear_bfqq_wait_request(bfqq);
++				del_timer(&bfqd->idle_slice_timer);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++				bfqg_stats_update_idle_time(bfqq_group(bfqq));
++#endif
++			}
++			goto keep_queue;
++		}
++	}
++
++	/*
++	 * No requests pending. However, if the in-service queue is idling
++	 * for a new request, or has requests waiting for a completion and
++	 * may idle after their completion, then keep it anyway.
++	 */
++	if (timer_pending(&bfqd->idle_slice_timer) ||
++	    (bfqq->dispatched != 0 && bfq_bfqq_may_idle(bfqq))) {
++		bfqq = NULL;
++		goto keep_queue;
++	}
++
++	reason = BFQ_BFQQ_NO_MORE_REQUESTS;
++expire:
++	bfq_bfqq_expire(bfqd, bfqq, false, reason);
++new_queue:
++	bfqq = bfq_set_in_service_queue(bfqd);
++	bfq_log(bfqd, "select_queue: new queue %d returned",
++		bfqq ? bfqq->pid : 0);
++keep_queue:
++	return bfqq;
++}
++
++static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */
++		bfq_log_bfqq(bfqd, bfqq,
++			"raising period dur %u/%u msec, old coeff %u, w %d(%d)",
++			jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
++			jiffies_to_msecs(bfqq->wr_cur_max_time),
++			bfqq->wr_coeff,
++			bfqq->entity.weight, bfqq->entity.orig_weight);
++
++		BUG_ON(bfqq != bfqd->in_service_queue && entity->weight !=
++		       entity->orig_weight * bfqq->wr_coeff);
++		if (entity->prio_changed)
++			bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change");
++
++		/*
++		 * If the queue was activated in a burst, or
++		 * too much time has elapsed from the beginning
++		 * of this weight-raising period, then end weight
++		 * raising.
++		 */
++		if (bfq_bfqq_in_large_burst(bfqq) ||
++		    time_is_before_jiffies(bfqq->last_wr_start_finish +
++					   bfqq->wr_cur_max_time)) {
++			bfqq->last_wr_start_finish = jiffies;
++			bfq_log_bfqq(bfqd, bfqq,
++				     "wrais ending at %lu, rais_max_time %u",
++				     bfqq->last_wr_start_finish,
++				     jiffies_to_msecs(bfqq->wr_cur_max_time));
++			bfq_bfqq_end_wr(bfqq);
++		}
++	}
++	/* Update weight both if it must be raised and if it must be lowered */
++	if ((entity->weight > entity->orig_weight) != (bfqq->wr_coeff > 1))
++		__bfq_entity_update_weight_prio(
++			bfq_entity_service_tree(entity),
++			entity);
++}
++
++/*
++ * Dispatch one request from bfqq, moving it to the request queue
++ * dispatch list.
++ */
++static int bfq_dispatch_request(struct bfq_data *bfqd,
++				struct bfq_queue *bfqq)
++{
++	int dispatched = 0;
++	struct request *rq;
++	unsigned long service_to_charge;
++
++	BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
++
++	/* Follow expired path, else get first next available. */
++	rq = bfq_check_fifo(bfqq);
++	if (!rq)
++		rq = bfqq->next_rq;
++	service_to_charge = bfq_serv_to_charge(rq, bfqq);
++
++	if (service_to_charge > bfq_bfqq_budget_left(bfqq)) {
++		/*
++		 * This may happen if the next rq is chosen in fifo order
++		 * instead of sector order. The budget is properly
++		 * dimensioned to be always sufficient to serve the next
++		 * request only if it is chosen in sector order. The reason
++		 * is that it would be quite inefficient and little useful
++		 * to always make sure that the budget is large enough to
++		 * serve even the possible next rq in fifo order.
++		 * In fact, requests are seldom served in fifo order.
++		 *
++		 * Expire the queue for budget exhaustion, and make sure
++		 * that the next act_budget is enough to serve the next
++		 * request, even if it comes from the fifo expired path.
++		 */
++		bfqq->next_rq = rq;
++		/*
++		 * Since this dispatch is failed, make sure that
++		 * a new one will be performed
++		 */
++		if (!bfqd->rq_in_driver)
++			bfq_schedule_dispatch(bfqd);
++		goto expire;
++	}
++
++	/* Finally, insert request into driver dispatch list. */
++	bfq_bfqq_served(bfqq, service_to_charge);
++	bfq_dispatch_insert(bfqd->queue, rq);
++
++	bfq_update_wr_data(bfqd, bfqq);
++
++	bfq_log_bfqq(bfqd, bfqq,
++			"dispatched %u sec req (%llu), budg left %d",
++			blk_rq_sectors(rq),
++			(unsigned long long) blk_rq_pos(rq),
++			bfq_bfqq_budget_left(bfqq));
++
++	dispatched++;
++
++	if (!bfqd->in_service_bic) {
++		atomic_long_inc(&RQ_BIC(rq)->icq.ioc->refcount);
++		bfqd->in_service_bic = RQ_BIC(rq);
++	}
++
++	if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) &&
++	    dispatched >= bfqd->bfq_max_budget_async_rq) ||
++	    bfq_class_idle(bfqq)))
++		goto expire;
++
++	return dispatched;
++
++expire:
++	bfq_bfqq_expire(bfqd, bfqq, false, BFQ_BFQQ_BUDGET_EXHAUSTED);
++	return dispatched;
++}
++
++static int __bfq_forced_dispatch_bfqq(struct bfq_queue *bfqq)
++{
++	int dispatched = 0;
++
++	while (bfqq->next_rq) {
++		bfq_dispatch_insert(bfqq->bfqd->queue, bfqq->next_rq);
++		dispatched++;
++	}
++
++	BUG_ON(!list_empty(&bfqq->fifo));
++	return dispatched;
++}
++
++/*
++ * Drain our current requests.
++ * Used for barriers and when switching io schedulers on-the-fly.
++ */
++static int bfq_forced_dispatch(struct bfq_data *bfqd)
++{
++	struct bfq_queue *bfqq, *n;
++	struct bfq_service_tree *st;
++	int dispatched = 0;
++
++	bfqq = bfqd->in_service_queue;
++	if (bfqq)
++		__bfq_bfqq_expire(bfqd, bfqq);
++
++	/*
++	 * Loop through classes, and be careful to leave the scheduler
++	 * in a consistent state, as feedback mechanisms and vtime
++	 * updates cannot be disabled during the process.
++	 */
++	list_for_each_entry_safe(bfqq, n, &bfqd->active_list, bfqq_list) {
++		st = bfq_entity_service_tree(&bfqq->entity);
++
++		dispatched += __bfq_forced_dispatch_bfqq(bfqq);
++		bfqq->max_budget = bfq_max_budget(bfqd);
++
++		bfq_forget_idle(st);
++	}
++
++	BUG_ON(bfqd->busy_queues != 0);
++
++	return dispatched;
++}
++
++static int bfq_dispatch_requests(struct request_queue *q, int force)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct bfq_queue *bfqq;
++	int max_dispatch;
++
++	bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues);
++	if (bfqd->busy_queues == 0)
++		return 0;
++
++	if (unlikely(force))
++		return bfq_forced_dispatch(bfqd);
++
++	bfqq = bfq_select_queue(bfqd);
++	if (!bfqq)
++		return 0;
++
++	if (bfq_class_idle(bfqq))
++		max_dispatch = 1;
++
++	if (!bfq_bfqq_sync(bfqq))
++		max_dispatch = bfqd->bfq_max_budget_async_rq;
++
++	if (!bfq_bfqq_sync(bfqq) && bfqq->dispatched >= max_dispatch) {
++		if (bfqd->busy_queues > 1)
++			return 0;
++		if (bfqq->dispatched >= 4 * max_dispatch)
++			return 0;
++	}
++
++	if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq))
++		return 0;
++
++	bfq_clear_bfqq_wait_request(bfqq);
++	BUG_ON(timer_pending(&bfqd->idle_slice_timer));
++
++	if (!bfq_dispatch_request(bfqd, bfqq))
++		return 0;
++
++	bfq_log_bfqq(bfqd, bfqq, "dispatched %s request",
++			bfq_bfqq_sync(bfqq) ? "sync" : "async");
++
++	return 1;
++}
++
++/*
++ * Task holds one reference to the queue, dropped when task exits.  Each rq
++ * in-flight on this queue also holds a reference, dropped when rq is freed.
++ *
++ * Queue lock must be held here.
++ */
++static void bfq_put_queue(struct bfq_queue *bfqq)
++{
++	struct bfq_data *bfqd = bfqq->bfqd;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	struct bfq_group *bfqg = bfqq_group(bfqq);
++#endif
++
++	BUG_ON(atomic_read(&bfqq->ref) <= 0);
++
++	bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq,
++		     atomic_read(&bfqq->ref));
++	if (!atomic_dec_and_test(&bfqq->ref))
++		return;
++
++	BUG_ON(rb_first(&bfqq->sort_list));
++	BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0);
++	BUG_ON(bfqq->entity.tree);
++	BUG_ON(bfq_bfqq_busy(bfqq));
++	BUG_ON(bfqd->in_service_queue == bfqq);
++
++	if (bfq_bfqq_sync(bfqq))
++		/*
++		 * The fact that this queue is being destroyed does not
++		 * invalidate the fact that this queue may have been
++		 * activated during the current burst. As a consequence,
++		 * although the queue does not exist anymore, and hence
++		 * needs to be removed from the burst list if there,
++		 * the burst size has not to be decremented.
++		 */
++		hlist_del_init(&bfqq->burst_list_node);
++
++	bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq);
++
++	kmem_cache_free(bfq_pool, bfqq);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_put(bfqg);
++#endif
++}
++
++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	if (bfqq == bfqd->in_service_queue) {
++		__bfq_bfqq_expire(bfqd, bfqq);
++		bfq_schedule_dispatch(bfqd);
++	}
++
++	bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
++		     atomic_read(&bfqq->ref));
++
++	bfq_put_queue(bfqq);
++}
++
++static void bfq_init_icq(struct io_cq *icq)
++{
++	struct bfq_io_cq *bic = icq_to_bic(icq);
++
++	bic->ttime.last_end_request = jiffies;
++}
++
++static void bfq_exit_icq(struct io_cq *icq)
++{
++	struct bfq_io_cq *bic = icq_to_bic(icq);
++	struct bfq_data *bfqd = bic_to_bfqd(bic);
++
++	if (bic->bfqq[BLK_RW_ASYNC]) {
++		bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]);
++		bic->bfqq[BLK_RW_ASYNC] = NULL;
++	}
++
++	if (bic->bfqq[BLK_RW_SYNC]) {
++		bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
++		bic->bfqq[BLK_RW_SYNC] = NULL;
++	}
++}
++
++/*
++ * Update the entity prio values; note that the new values will not
++ * be used until the next (re)activation.
++ */
++static void
++bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
++{
++	struct task_struct *tsk = current;
++	int ioprio_class;
++
++	ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
++	switch (ioprio_class) {
++	default:
++		dev_err(bfqq->bfqd->queue->backing_dev_info.dev,
++			"bfq: bad prio class %d\n", ioprio_class);
++	case IOPRIO_CLASS_NONE:
++		/*
++		 * No prio set, inherit CPU scheduling settings.
++		 */
++		bfqq->new_ioprio = task_nice_ioprio(tsk);
++		bfqq->new_ioprio_class = task_nice_ioclass(tsk);
++		break;
++	case IOPRIO_CLASS_RT:
++		bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
++		bfqq->new_ioprio_class = IOPRIO_CLASS_RT;
++		break;
++	case IOPRIO_CLASS_BE:
++		bfqq->new_ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
++		bfqq->new_ioprio_class = IOPRIO_CLASS_BE;
++		break;
++	case IOPRIO_CLASS_IDLE:
++		bfqq->new_ioprio_class = IOPRIO_CLASS_IDLE;
++		bfqq->new_ioprio = 7;
++		bfq_clear_bfqq_idle_window(bfqq);
++		break;
++	}
++
++	if (bfqq->new_ioprio < 0 || bfqq->new_ioprio >= IOPRIO_BE_NR) {
++		pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n",
++			bfqq->new_ioprio);
++		BUG();
++	}
++
++	bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio);
++	bfqq->entity.prio_changed = 1;
++}
++
++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
++{
++	struct bfq_data *bfqd;
++	struct bfq_queue *bfqq, *new_bfqq;
++	unsigned long uninitialized_var(flags);
++	int ioprio = bic->icq.ioc->ioprio;
++
++	bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
++				   &flags);
++	/*
++	 * This condition may trigger on a newly created bic, be sure to
++	 * drop the lock before returning.
++	 */
++	if (unlikely(!bfqd) || likely(bic->ioprio == ioprio))
++		goto out;
++
++	bic->ioprio = ioprio;
++
++	bfqq = bic->bfqq[BLK_RW_ASYNC];
++	if (bfqq) {
++		new_bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic,
++					 GFP_ATOMIC);
++		if (new_bfqq) {
++			bic->bfqq[BLK_RW_ASYNC] = new_bfqq;
++			bfq_log_bfqq(bfqd, bfqq,
++				     "check_ioprio_change: bfqq %p %d",
++				     bfqq, atomic_read(&bfqq->ref));
++			bfq_put_queue(bfqq);
++		}
++	}
++
++	bfqq = bic->bfqq[BLK_RW_SYNC];
++	if (bfqq)
++		bfq_set_next_ioprio_data(bfqq, bic);
++
++out:
++	bfq_put_bfqd_unlock(bfqd, &flags);
++}
++
++static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++			  struct bfq_io_cq *bic, pid_t pid, int is_sync)
++{
++	RB_CLEAR_NODE(&bfqq->entity.rb_node);
++	INIT_LIST_HEAD(&bfqq->fifo);
++	INIT_HLIST_NODE(&bfqq->burst_list_node);
++
++	atomic_set(&bfqq->ref, 0);
++	bfqq->bfqd = bfqd;
++
++	if (bic)
++		bfq_set_next_ioprio_data(bfqq, bic);
++
++	if (is_sync) {
++		if (!bfq_class_idle(bfqq))
++			bfq_mark_bfqq_idle_window(bfqq);
++		bfq_mark_bfqq_sync(bfqq);
++	} else
++		bfq_clear_bfqq_sync(bfqq);
++	bfq_mark_bfqq_IO_bound(bfqq);
++
++	/* Tentative initial value to trade off between thr and lat */
++	bfqq->max_budget = (2 * bfq_max_budget(bfqd)) / 3;
++	bfqq->pid = pid;
++
++	bfqq->wr_coeff = 1;
++	bfqq->last_wr_start_finish = 0;
++	/*
++	 * Set to the value for which bfqq will not be deemed as
++	 * soft rt when it becomes backlogged.
++	 */
++	bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies);
++}
++
++static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd,
++					      struct bio *bio, int is_sync,
++					      struct bfq_io_cq *bic,
++					      gfp_t gfp_mask)
++{
++	struct bfq_group *bfqg;
++	struct bfq_queue *bfqq, *new_bfqq = NULL;
++	struct blkcg *blkcg;
++
++retry:
++	rcu_read_lock();
++
++	blkcg = bio_blkcg(bio);
++	bfqg = bfq_find_alloc_group(bfqd, blkcg);
++	/* bic always exists here */
++	bfqq = bic_to_bfqq(bic, is_sync);
++
++	/*
++	 * Always try a new alloc if we fall back to the OOM bfqq
++	 * originally, since it should just be a temporary situation.
++	 */
++	if (!bfqq || bfqq == &bfqd->oom_bfqq) {
++		bfqq = NULL;
++		if (new_bfqq) {
++			bfqq = new_bfqq;
++			new_bfqq = NULL;
++		} else if (gfpflags_allow_blocking(gfp_mask)) {
++			rcu_read_unlock();
++			spin_unlock_irq(bfqd->queue->queue_lock);
++			new_bfqq = kmem_cache_alloc_node(bfq_pool,
++					gfp_mask | __GFP_ZERO,
++					bfqd->queue->node);
++			spin_lock_irq(bfqd->queue->queue_lock);
++			if (new_bfqq)
++				goto retry;
++		} else {
++			bfqq = kmem_cache_alloc_node(bfq_pool,
++					gfp_mask | __GFP_ZERO,
++					bfqd->queue->node);
++		}
++
++		if (bfqq) {
++			bfq_init_bfqq(bfqd, bfqq, bic, current->pid,
++				      is_sync);
++			bfq_init_entity(&bfqq->entity, bfqg);
++			bfq_log_bfqq(bfqd, bfqq, "allocated");
++		} else {
++			bfqq = &bfqd->oom_bfqq;
++			bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
++		}
++	}
++
++	if (new_bfqq)
++		kmem_cache_free(bfq_pool, new_bfqq);
++
++	rcu_read_unlock();
++
++	return bfqq;
++}
++
++static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
++					       struct bfq_group *bfqg,
++					       int ioprio_class, int ioprio)
++{
++	switch (ioprio_class) {
++	case IOPRIO_CLASS_RT:
++		return &bfqg->async_bfqq[0][ioprio];
++	case IOPRIO_CLASS_NONE:
++		ioprio = IOPRIO_NORM;
++		/* fall through */
++	case IOPRIO_CLASS_BE:
++		return &bfqg->async_bfqq[1][ioprio];
++	case IOPRIO_CLASS_IDLE:
++		return &bfqg->async_idle_bfqq;
++	default:
++		BUG();
++	}
++}
++
++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
++				       struct bio *bio, int is_sync,
++				       struct bfq_io_cq *bic, gfp_t gfp_mask)
++{
++	const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
++	const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
++	struct bfq_queue **async_bfqq = NULL;
++	struct bfq_queue *bfqq = NULL;
++
++	if (!is_sync) {
++		struct blkcg *blkcg;
++		struct bfq_group *bfqg;
++
++		rcu_read_lock();
++		blkcg = bio_blkcg(bio);
++		rcu_read_unlock();
++		bfqg = bfq_find_alloc_group(bfqd, blkcg);
++		async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
++						  ioprio);
++		bfqq = *async_bfqq;
++	}
++
++	if (!bfqq)
++		bfqq = bfq_find_alloc_queue(bfqd, bio, is_sync, bic, gfp_mask);
++
++	/*
++	 * Pin the queue now that it's allocated, scheduler exit will
++	 * prune it.
++	 */
++	if (!is_sync && !(*async_bfqq)) {
++		atomic_inc(&bfqq->ref);
++		bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
++			     bfqq, atomic_read(&bfqq->ref));
++		*async_bfqq = bfqq;
++	}
++
++	atomic_inc(&bfqq->ref);
++	bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq,
++		     atomic_read(&bfqq->ref));
++	return bfqq;
++}
++
++static void bfq_update_io_thinktime(struct bfq_data *bfqd,
++				    struct bfq_io_cq *bic)
++{
++	unsigned long elapsed = jiffies - bic->ttime.last_end_request;
++	unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle);
++
++	bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
++	bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8;
++	bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) /
++				bic->ttime.ttime_samples;
++}
++
++static void bfq_update_io_seektime(struct bfq_data *bfqd,
++				   struct bfq_queue *bfqq,
++				   struct request *rq)
++{
++	sector_t sdist;
++	u64 total;
++
++	if (bfqq->last_request_pos < blk_rq_pos(rq))
++		sdist = blk_rq_pos(rq) - bfqq->last_request_pos;
++	else
++		sdist = bfqq->last_request_pos - blk_rq_pos(rq);
++
++	/*
++	 * Don't allow the seek distance to get too large from the
++	 * odd fragment, pagein, etc.
++	 */
++	if (bfqq->seek_samples == 0) /* first request, not really a seek */
++		sdist = 0;
++	else if (bfqq->seek_samples <= 60) /* second & third seek */
++		sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024);
++	else
++		sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64);
++
++	bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8;
++	bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8;
++	total = bfqq->seek_total + (bfqq->seek_samples/2);
++	do_div(total, bfqq->seek_samples);
++	bfqq->seek_mean = (sector_t)total;
++
++	bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
++			(u64)bfqq->seek_mean);
++}
++
++/*
++ * Disable idle window if the process thinks too long or seeks so much that
++ * it doesn't matter.
++ */
++static void bfq_update_idle_window(struct bfq_data *bfqd,
++				   struct bfq_queue *bfqq,
++				   struct bfq_io_cq *bic)
++{
++	int enable_idle;
++
++	/* Don't idle for async or idle io prio class. */
++	if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
++		return;
++
++	enable_idle = bfq_bfqq_idle_window(bfqq);
++
++	if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
++	    bfqd->bfq_slice_idle == 0 ||
++		(bfqd->hw_tag && BFQQ_SEEKY(bfqq) &&
++			bfqq->wr_coeff == 1))
++		enable_idle = 0;
++	else if (bfq_sample_valid(bic->ttime.ttime_samples)) {
++		if (bic->ttime.ttime_mean > bfqd->bfq_slice_idle &&
++			bfqq->wr_coeff == 1)
++			enable_idle = 0;
++		else
++			enable_idle = 1;
++	}
++	bfq_log_bfqq(bfqd, bfqq, "update_idle_window: enable_idle %d",
++		enable_idle);
++
++	if (enable_idle)
++		bfq_mark_bfqq_idle_window(bfqq);
++	else
++		bfq_clear_bfqq_idle_window(bfqq);
++}
++
++/*
++ * Called when a new fs request (rq) is added to bfqq.  Check if there's
++ * something we should do about it.
++ */
++static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++			    struct request *rq)
++{
++	struct bfq_io_cq *bic = RQ_BIC(rq);
++
++	if (rq->cmd_flags & REQ_META)
++		bfqq->meta_pending++;
++
++	bfq_update_io_thinktime(bfqd, bic);
++	bfq_update_io_seektime(bfqd, bfqq, rq);
++	if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) {
++		bfq_clear_bfqq_constantly_seeky(bfqq);
++		if (!blk_queue_nonrot(bfqd->queue)) {
++			BUG_ON(!bfqd->const_seeky_busy_in_flight_queues);
++			bfqd->const_seeky_busy_in_flight_queues--;
++		}
++	}
++	if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
++	    !BFQQ_SEEKY(bfqq))
++		bfq_update_idle_window(bfqd, bfqq, bic);
++
++	bfq_log_bfqq(bfqd, bfqq,
++		     "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
++		     bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq),
++		     (unsigned long long) bfqq->seek_mean);
++
++	bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
++
++	if (bfqq == bfqd->in_service_queue && bfq_bfqq_wait_request(bfqq)) {
++		bool small_req = bfqq->queued[rq_is_sync(rq)] == 1 &&
++				 blk_rq_sectors(rq) < 32;
++		bool budget_timeout = bfq_bfqq_budget_timeout(bfqq);
++
++		/*
++		 * There is just this request queued: if the request
++		 * is small and the queue is not to be expired, then
++		 * just exit.
++		 *
++		 * In this way, if the disk is being idled to wait for
++		 * a new request from the in-service queue, we avoid
++		 * unplugging the device and committing the disk to serve
++		 * just a small request. On the contrary, we wait for
++		 * the block layer to decide when to unplug the device:
++		 * hopefully, new requests will be merged to this one
++		 * quickly, then the device will be unplugged and
++		 * larger requests will be dispatched.
++		 */
++		if (small_req && !budget_timeout)
++			return;
++
++		/*
++		 * A large enough request arrived, or the queue is to
++		 * be expired: in both cases disk idling is to be
++		 * stopped, so clear wait_request flag and reset
++		 * timer.
++		 */
++		bfq_clear_bfqq_wait_request(bfqq);
++		del_timer(&bfqd->idle_slice_timer);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		bfqg_stats_update_idle_time(bfqq_group(bfqq));
++#endif
++
++		/*
++		 * The queue is not empty, because a new request just
++		 * arrived. Hence we can safely expire the queue, in
++		 * case of budget timeout, without risking that the
++		 * timestamps of the queue are not updated correctly.
++		 * See [1] for more details.
++		 */
++		if (budget_timeout)
++			bfq_bfqq_expire(bfqd, bfqq, false,
++					BFQ_BFQQ_BUDGET_TIMEOUT);
++
++		/*
++		 * Let the request rip immediately, or let a new queue be
++		 * selected if bfqq has just been expired.
++		 */
++		__blk_run_queue(bfqd->queue);
++	}
++}
++
++static void bfq_insert_request(struct request_queue *q, struct request *rq)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++
++	assert_spin_locked(bfqd->queue->queue_lock);
++
++	bfq_add_request(rq);
++
++	rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)];
++	list_add_tail(&rq->queuelist, &bfqq->fifo);
++
++	bfq_rq_enqueued(bfqd, bfqq, rq);
++}
++
++static void bfq_update_hw_tag(struct bfq_data *bfqd)
++{
++	bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver,
++				     bfqd->rq_in_driver);
++
++	if (bfqd->hw_tag == 1)
++		return;
++
++	/*
++	 * This sample is valid if the number of outstanding requests
++	 * is large enough to allow a queueing behavior.  Note that the
++	 * sum is not exact, as it's not taking into account deactivated
++	 * requests.
++	 */
++	if (bfqd->rq_in_driver + bfqd->queued < BFQ_HW_QUEUE_THRESHOLD)
++		return;
++
++	if (bfqd->hw_tag_samples++ < BFQ_HW_QUEUE_SAMPLES)
++		return;
++
++	bfqd->hw_tag = bfqd->max_rq_in_driver > BFQ_HW_QUEUE_THRESHOLD;
++	bfqd->max_rq_in_driver = 0;
++	bfqd->hw_tag_samples = 0;
++}
++
++static void bfq_completed_request(struct request_queue *q, struct request *rq)
++{
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++	struct bfq_data *bfqd = bfqq->bfqd;
++	bool sync = bfq_bfqq_sync(bfqq);
++
++	bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
++		     blk_rq_sectors(rq), sync);
++
++	bfq_update_hw_tag(bfqd);
++
++	BUG_ON(!bfqd->rq_in_driver);
++	BUG_ON(!bfqq->dispatched);
++	bfqd->rq_in_driver--;
++	bfqq->dispatched--;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_update_completion(bfqq_group(bfqq),
++				     rq_start_time_ns(rq),
++				     rq_io_start_time_ns(rq), rq->cmd_flags);
++#endif
++
++	if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) {
++		bfq_weights_tree_remove(bfqd, &bfqq->entity,
++					&bfqd->queue_weights_tree);
++		if (!blk_queue_nonrot(bfqd->queue)) {
++			BUG_ON(!bfqd->busy_in_flight_queues);
++			bfqd->busy_in_flight_queues--;
++			if (bfq_bfqq_constantly_seeky(bfqq)) {
++				BUG_ON(!bfqd->
++					const_seeky_busy_in_flight_queues);
++				bfqd->const_seeky_busy_in_flight_queues--;
++			}
++		}
++	}
++
++	if (sync) {
++		bfqd->sync_flight--;
++		RQ_BIC(rq)->ttime.last_end_request = jiffies;
++	}
++
++	/*
++	 * If we are waiting to discover whether the request pattern of the
++	 * task associated with the queue is actually isochronous, and
++	 * both requisites for this condition to hold are satisfied, then
++	 * compute soft_rt_next_start (see the comments to the function
++	 * bfq_bfqq_softrt_next_start()).
++	 */
++	if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 &&
++	    RB_EMPTY_ROOT(&bfqq->sort_list))
++		bfqq->soft_rt_next_start =
++			bfq_bfqq_softrt_next_start(bfqd, bfqq);
++
++	/*
++	 * If this is the in-service queue, check if it needs to be expired,
++	 * or if we want to idle in case it has no pending requests.
++	 */
++	if (bfqd->in_service_queue == bfqq) {
++		if (bfq_bfqq_budget_new(bfqq))
++			bfq_set_budget_timeout(bfqd);
++
++		if (bfq_bfqq_must_idle(bfqq)) {
++			bfq_arm_slice_timer(bfqd);
++			goto out;
++		} else if (bfq_may_expire_for_budg_timeout(bfqq))
++			bfq_bfqq_expire(bfqd, bfqq, false,
++					BFQ_BFQQ_BUDGET_TIMEOUT);
++		else if (RB_EMPTY_ROOT(&bfqq->sort_list) &&
++			 (bfqq->dispatched == 0 ||
++			  !bfq_bfqq_may_idle(bfqq)))
++			bfq_bfqq_expire(bfqd, bfqq, false,
++					BFQ_BFQQ_NO_MORE_REQUESTS);
++	}
++
++	if (!bfqd->rq_in_driver)
++		bfq_schedule_dispatch(bfqd);
++
++out:
++	return;
++}
++
++static int __bfq_may_queue(struct bfq_queue *bfqq)
++{
++	if (bfq_bfqq_wait_request(bfqq) && bfq_bfqq_must_alloc(bfqq)) {
++		bfq_clear_bfqq_must_alloc(bfqq);
++		return ELV_MQUEUE_MUST;
++	}
++
++	return ELV_MQUEUE_MAY;
++}
++
++static int bfq_may_queue(struct request_queue *q, int rw)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct task_struct *tsk = current;
++	struct bfq_io_cq *bic;
++	struct bfq_queue *bfqq;
++
++	/*
++	 * Don't force setup of a queue from here, as a call to may_queue
++	 * does not necessarily imply that a request actually will be
++	 * queued. So just lookup a possibly existing queue, or return
++	 * 'may queue' if that fails.
++	 */
++	bic = bfq_bic_lookup(bfqd, tsk->io_context);
++	if (!bic)
++		return ELV_MQUEUE_MAY;
++
++	bfqq = bic_to_bfqq(bic, rw_is_sync(rw));
++	if (bfqq)
++		return __bfq_may_queue(bfqq);
++
++	return ELV_MQUEUE_MAY;
++}
++
++/*
++ * Queue lock held here.
++ */
++static void bfq_put_request(struct request *rq)
++{
++	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++
++	if (bfqq) {
++		const int rw = rq_data_dir(rq);
++
++		BUG_ON(!bfqq->allocated[rw]);
++		bfqq->allocated[rw]--;
++
++		rq->elv.priv[0] = NULL;
++		rq->elv.priv[1] = NULL;
++
++		bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d",
++			     bfqq, atomic_read(&bfqq->ref));
++		bfq_put_queue(bfqq);
++	}
++}
++
++/*
++ * Allocate bfq data structures associated with this request.
++ */
++static int bfq_set_request(struct request_queue *q, struct request *rq,
++			   struct bio *bio, gfp_t gfp_mask)
++{
++	struct bfq_data *bfqd = q->elevator->elevator_data;
++	struct bfq_io_cq *bic = icq_to_bic(rq->elv.icq);
++	const int rw = rq_data_dir(rq);
++	const int is_sync = rq_is_sync(rq);
++	struct bfq_queue *bfqq;
++	unsigned long flags;
++
++	might_sleep_if(gfpflags_allow_blocking(gfp_mask));
++
++	bfq_check_ioprio_change(bic, bio);
++
++	spin_lock_irqsave(q->queue_lock, flags);
++
++	if (!bic)
++		goto queue_fail;
++
++	bfq_bic_update_cgroup(bic, bio);
++
++	bfqq = bic_to_bfqq(bic, is_sync);
++	if (!bfqq || bfqq == &bfqd->oom_bfqq) {
++		bfqq = bfq_get_queue(bfqd, bio, is_sync, bic, gfp_mask);
++		bic_set_bfqq(bic, bfqq, is_sync);
++		if (is_sync) {
++			if (bfqd->large_burst)
++				bfq_mark_bfqq_in_large_burst(bfqq);
++			else
++				bfq_clear_bfqq_in_large_burst(bfqq);
++		}
++	}
++
++	bfqq->allocated[rw]++;
++	atomic_inc(&bfqq->ref);
++	bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq,
++		     atomic_read(&bfqq->ref));
++
++	rq->elv.priv[0] = bic;
++	rq->elv.priv[1] = bfqq;
++
++	spin_unlock_irqrestore(q->queue_lock, flags);
++
++	return 0;
++
++queue_fail:
++	bfq_schedule_dispatch(bfqd);
++	spin_unlock_irqrestore(q->queue_lock, flags);
++
++	return 1;
++}
++
++static void bfq_kick_queue(struct work_struct *work)
++{
++	struct bfq_data *bfqd =
++		container_of(work, struct bfq_data, unplug_work);
++	struct request_queue *q = bfqd->queue;
++
++	spin_lock_irq(q->queue_lock);
++	__blk_run_queue(q);
++	spin_unlock_irq(q->queue_lock);
++}
++
++/*
++ * Handler of the expiration of the timer running if the in-service queue
++ * is idling inside its time slice.
++ */
++static void bfq_idle_slice_timer(unsigned long data)
++{
++	struct bfq_data *bfqd = (struct bfq_data *)data;
++	struct bfq_queue *bfqq;
++	unsigned long flags;
++	enum bfqq_expiration reason;
++
++	spin_lock_irqsave(bfqd->queue->queue_lock, flags);
++
++	bfqq = bfqd->in_service_queue;
++	/*
++	 * Theoretical race here: the in-service queue can be NULL or
++	 * different from the queue that was idling if the timer handler
++	 * spins on the queue_lock and a new request arrives for the
++	 * current queue and there is a full dispatch cycle that changes
++	 * the in-service queue.  This can hardly happen, but in the worst
++	 * case we just expire a queue too early.
++	 */
++	if (bfqq) {
++		bfq_log_bfqq(bfqd, bfqq, "slice_timer expired");
++		if (bfq_bfqq_budget_timeout(bfqq))
++			/*
++			 * Also here the queue can be safely expired
++			 * for budget timeout without wasting
++			 * guarantees
++			 */
++			reason = BFQ_BFQQ_BUDGET_TIMEOUT;
++		else if (bfqq->queued[0] == 0 && bfqq->queued[1] == 0)
++			/*
++			 * The queue may not be empty upon timer expiration,
++			 * because we may not disable the timer when the
++			 * first request of the in-service queue arrives
++			 * during disk idling.
++			 */
++			reason = BFQ_BFQQ_TOO_IDLE;
++		else
++			goto schedule_dispatch;
++
++		bfq_bfqq_expire(bfqd, bfqq, true, reason);
++	}
++
++schedule_dispatch:
++	bfq_schedule_dispatch(bfqd);
++
++	spin_unlock_irqrestore(bfqd->queue->queue_lock, flags);
++}
++
++static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
++{
++	del_timer_sync(&bfqd->idle_slice_timer);
++	cancel_work_sync(&bfqd->unplug_work);
++}
++
++static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
++					struct bfq_queue **bfqq_ptr)
++{
++	struct bfq_group *root_group = bfqd->root_group;
++	struct bfq_queue *bfqq = *bfqq_ptr;
++
++	bfq_log(bfqd, "put_async_bfqq: %p", bfqq);
++	if (bfqq) {
++		bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group);
++		bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d",
++			     bfqq, atomic_read(&bfqq->ref));
++		bfq_put_queue(bfqq);
++		*bfqq_ptr = NULL;
++	}
++}
++
++/*
++ * Release all the bfqg references to its async queues.  If we are
++ * deallocating the group these queues may still contain requests, so
++ * we reparent them to the root cgroup (i.e., the only one that will
++ * exist for sure until all the requests on a device are gone).
++ */
++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
++{
++	int i, j;
++
++	for (i = 0; i < 2; i++)
++		for (j = 0; j < IOPRIO_BE_NR; j++)
++			__bfq_put_async_bfqq(bfqd, &bfqg->async_bfqq[i][j]);
++
++	__bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
++}
++
++static void bfq_exit_queue(struct elevator_queue *e)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++	struct request_queue *q = bfqd->queue;
++	struct bfq_queue *bfqq, *n;
++
++	bfq_shutdown_timer_wq(bfqd);
++
++	spin_lock_irq(q->queue_lock);
++
++	BUG_ON(bfqd->in_service_queue);
++	list_for_each_entry_safe(bfqq, n, &bfqd->idle_list, bfqq_list)
++		bfq_deactivate_bfqq(bfqd, bfqq, 0);
++
++	spin_unlock_irq(q->queue_lock);
++
++	bfq_shutdown_timer_wq(bfqd);
++
++	synchronize_rcu();
++
++	BUG_ON(timer_pending(&bfqd->idle_slice_timer));
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	blkcg_deactivate_policy(q, &blkcg_policy_bfq);
++#else
++	kfree(bfqd->root_group);
++#endif
++
++	kfree(bfqd);
++}
++
++static void bfq_init_root_group(struct bfq_group *root_group,
++				struct bfq_data *bfqd)
++{
++	int i;
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	root_group->entity.parent = NULL;
++	root_group->my_entity = NULL;
++	root_group->bfqd = bfqd;
++#endif
++	for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
++		root_group->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
++}
++
++static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
++{
++	struct bfq_data *bfqd;
++	struct elevator_queue *eq;
++
++	eq = elevator_alloc(q, e);
++	if (!eq)
++		return -ENOMEM;
++
++	bfqd = kzalloc_node(sizeof(*bfqd), GFP_KERNEL, q->node);
++	if (!bfqd) {
++		kobject_put(&eq->kobj);
++		return -ENOMEM;
++	}
++	eq->elevator_data = bfqd;
++
++	/*
++	 * Our fallback bfqq if bfq_find_alloc_queue() runs into OOM issues.
++	 * Grab a permanent reference to it, so that the normal code flow
++	 * will not attempt to free it.
++	 */
++	bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0);
++	atomic_inc(&bfqd->oom_bfqq.ref);
++	bfqd->oom_bfqq.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO;
++	bfqd->oom_bfqq.new_ioprio_class = IOPRIO_CLASS_BE;
++	bfqd->oom_bfqq.entity.new_weight =
++		bfq_ioprio_to_weight(bfqd->oom_bfqq.new_ioprio);
++	/*
++	 * Trigger weight initialization, according to ioprio, at the
++	 * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio
++	 * class won't be changed any more.
++	 */
++	bfqd->oom_bfqq.entity.prio_changed = 1;
++
++	bfqd->queue = q;
++
++	spin_lock_irq(q->queue_lock);
++	q->elevator = eq;
++	spin_unlock_irq(q->queue_lock);
++
++	bfqd->root_group = bfq_create_group_hierarchy(bfqd, q->node);
++	if (!bfqd->root_group)
++		goto out_free;
++	bfq_init_root_group(bfqd->root_group, bfqd);
++	bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqd->active_numerous_groups = 0;
++#endif
++
++	init_timer(&bfqd->idle_slice_timer);
++	bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
++	bfqd->idle_slice_timer.data = (unsigned long)bfqd;
++
++	bfqd->queue_weights_tree = RB_ROOT;
++	bfqd->group_weights_tree = RB_ROOT;
++
++	INIT_WORK(&bfqd->unplug_work, bfq_kick_queue);
++
++	INIT_LIST_HEAD(&bfqd->active_list);
++	INIT_LIST_HEAD(&bfqd->idle_list);
++	INIT_HLIST_HEAD(&bfqd->burst_list);
++
++	bfqd->hw_tag = -1;
++
++	bfqd->bfq_max_budget = bfq_default_max_budget;
++
++	bfqd->bfq_fifo_expire[0] = bfq_fifo_expire[0];
++	bfqd->bfq_fifo_expire[1] = bfq_fifo_expire[1];
++	bfqd->bfq_back_max = bfq_back_max;
++	bfqd->bfq_back_penalty = bfq_back_penalty;
++	bfqd->bfq_slice_idle = bfq_slice_idle;
++	bfqd->bfq_class_idle_last_service = 0;
++	bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq;
++	bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
++	bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
++
++	bfqd->bfq_requests_within_timer = 120;
++
++	bfqd->bfq_large_burst_thresh = 11;
++	bfqd->bfq_burst_interval = msecs_to_jiffies(500);
++
++	bfqd->low_latency = true;
++
++	bfqd->bfq_wr_coeff = 20;
++	bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300);
++	bfqd->bfq_wr_max_time = 0;
++	bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000);
++	bfqd->bfq_wr_min_inter_arr_async = msecs_to_jiffies(500);
++	bfqd->bfq_wr_max_softrt_rate = 7000; /*
++					      * Approximate rate required
++					      * to playback or record a
++					      * high-definition compressed
++					      * video.
++					      */
++	bfqd->wr_busy_queues = 0;
++	bfqd->busy_in_flight_queues = 0;
++	bfqd->const_seeky_busy_in_flight_queues = 0;
++
++	/*
++	 * Begin by assuming, optimistically, that the device peak rate is
++	 * equal to the highest reference rate.
++	 */
++	bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] *
++			T_fast[blk_queue_nonrot(bfqd->queue)];
++	bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)];
++	bfqd->device_speed = BFQ_BFQD_FAST;
++
++	return 0;
++
++out_free:
++	kfree(bfqd);
++	kobject_put(&eq->kobj);
++	return -ENOMEM;
++}
++
++static void bfq_slab_kill(void)
++{
++	kmem_cache_destroy(bfq_pool);
++}
++
++static int __init bfq_slab_setup(void)
++{
++	bfq_pool = KMEM_CACHE(bfq_queue, 0);
++	if (!bfq_pool)
++		return -ENOMEM;
++	return 0;
++}
++
++static ssize_t bfq_var_show(unsigned int var, char *page)
++{
++	return sprintf(page, "%d\n", var);
++}
++
++static ssize_t bfq_var_store(unsigned long *var, const char *page,
++			     size_t count)
++{
++	unsigned long new_val;
++	int ret = kstrtoul(page, 10, &new_val);
++
++	if (ret == 0)
++		*var = new_val;
++
++	return count;
++}
++
++static ssize_t bfq_wr_max_time_show(struct elevator_queue *e, char *page)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++
++	return sprintf(page, "%d\n", bfqd->bfq_wr_max_time > 0 ?
++		       jiffies_to_msecs(bfqd->bfq_wr_max_time) :
++		       jiffies_to_msecs(bfq_wr_duration(bfqd)));
++}
++
++static ssize_t bfq_weights_show(struct elevator_queue *e, char *page)
++{
++	struct bfq_queue *bfqq;
++	struct bfq_data *bfqd = e->elevator_data;
++	ssize_t num_char = 0;
++
++	num_char += sprintf(page + num_char, "Tot reqs queued %d\n\n",
++			    bfqd->queued);
++
++	spin_lock_irq(bfqd->queue->queue_lock);
++
++	num_char += sprintf(page + num_char, "Active:\n");
++	list_for_each_entry(bfqq, &bfqd->active_list, bfqq_list) {
++		num_char += sprintf(page + num_char,
++				    "pid%d: weight %hu, nr_queued %d %d, ",
++				    bfqq->pid,
++				    bfqq->entity.weight,
++				    bfqq->queued[0],
++				    bfqq->queued[1]);
++		num_char += sprintf(page + num_char,
++				    "dur %d/%u\n",
++				    jiffies_to_msecs(
++					    jiffies -
++					    bfqq->last_wr_start_finish),
++				    jiffies_to_msecs(bfqq->wr_cur_max_time));
++	}
++
++	num_char += sprintf(page + num_char, "Idle:\n");
++	list_for_each_entry(bfqq, &bfqd->idle_list, bfqq_list) {
++		num_char += sprintf(page + num_char,
++				    "pid%d: weight %hu, dur %d/%u\n",
++				    bfqq->pid,
++				    bfqq->entity.weight,
++				    jiffies_to_msecs(jiffies -
++						     bfqq->last_wr_start_finish),
++				    jiffies_to_msecs(bfqq->wr_cur_max_time));
++	}
++
++	spin_unlock_irq(bfqd->queue->queue_lock);
++
++	return num_char;
++}
++
++#define SHOW_FUNCTION(__FUNC, __VAR, __CONV)				\
++static ssize_t __FUNC(struct elevator_queue *e, char *page)		\
++{									\
++	struct bfq_data *bfqd = e->elevator_data;			\
++	unsigned int __data = __VAR;					\
++	if (__CONV)							\
++		__data = jiffies_to_msecs(__data);			\
++	return bfq_var_show(__data, (page));				\
++}
++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1);
++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1);
++SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0);
++SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0);
++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1);
++SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0);
++SHOW_FUNCTION(bfq_max_budget_async_rq_show,
++	      bfqd->bfq_max_budget_async_rq, 0);
++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1);
++SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1);
++SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0);
++SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0);
++SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1);
++SHOW_FUNCTION(bfq_wr_min_idle_time_show, bfqd->bfq_wr_min_idle_time, 1);
++SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async,
++	1);
++SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0);
++#undef SHOW_FUNCTION
++
++#define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
++static ssize_t								\
++__FUNC(struct elevator_queue *e, const char *page, size_t count)	\
++{									\
++	struct bfq_data *bfqd = e->elevator_data;			\
++	unsigned long uninitialized_var(__data);			\
++	int ret = bfq_var_store(&__data, (page), count);		\
++	if (__data < (MIN))						\
++		__data = (MIN);						\
++	else if (__data > (MAX))					\
++		__data = (MAX);						\
++	if (__CONV)							\
++		*(__PTR) = msecs_to_jiffies(__data);			\
++	else								\
++		*(__PTR) = __data;					\
++	return ret;							\
++}
++STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
++		INT_MAX, 1);
++STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1,
++		INT_MAX, 1);
++STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0);
++STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1,
++		INT_MAX, 0);
++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1);
++STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq,
++		1, INT_MAX, 0);
++STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0,
++		INT_MAX, 1);
++STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0);
++STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1);
++STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX,
++		1);
++STORE_FUNCTION(bfq_wr_min_idle_time_store, &bfqd->bfq_wr_min_idle_time, 0,
++		INT_MAX, 1);
++STORE_FUNCTION(bfq_wr_min_inter_arr_async_store,
++		&bfqd->bfq_wr_min_inter_arr_async, 0, INT_MAX, 1);
++STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0,
++		INT_MAX, 0);
++#undef STORE_FUNCTION
++
++/* do nothing for the moment */
++static ssize_t bfq_weights_store(struct elevator_queue *e,
++				    const char *page, size_t count)
++{
++	return count;
++}
++
++static unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd)
++{
++	u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
++
++	if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES)
++		return bfq_calc_max_budget(bfqd->peak_rate, timeout);
++	else
++		return bfq_default_max_budget;
++}
++
++static ssize_t bfq_max_budget_store(struct elevator_queue *e,
++				    const char *page, size_t count)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++	unsigned long uninitialized_var(__data);
++	int ret = bfq_var_store(&__data, (page), count);
++
++	if (__data == 0)
++		bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
++	else {
++		if (__data > INT_MAX)
++			__data = INT_MAX;
++		bfqd->bfq_max_budget = __data;
++	}
++
++	bfqd->bfq_user_max_budget = __data;
++
++	return ret;
++}
++
++static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
++				      const char *page, size_t count)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++	unsigned long uninitialized_var(__data);
++	int ret = bfq_var_store(&__data, (page), count);
++
++	if (__data < 1)
++		__data = 1;
++	else if (__data > INT_MAX)
++		__data = INT_MAX;
++
++	bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data);
++	if (bfqd->bfq_user_max_budget == 0)
++		bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
++
++	return ret;
++}
++
++static ssize_t bfq_low_latency_store(struct elevator_queue *e,
++				     const char *page, size_t count)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++	unsigned long uninitialized_var(__data);
++	int ret = bfq_var_store(&__data, (page), count);
++
++	if (__data > 1)
++		__data = 1;
++	if (__data == 0 && bfqd->low_latency != 0)
++		bfq_end_wr(bfqd);
++	bfqd->low_latency = __data;
++
++	return ret;
++}
++
++#define BFQ_ATTR(name) \
++	__ATTR(name, S_IRUGO|S_IWUSR, bfq_##name##_show, bfq_##name##_store)
++
++static struct elv_fs_entry bfq_attrs[] = {
++	BFQ_ATTR(fifo_expire_sync),
++	BFQ_ATTR(fifo_expire_async),
++	BFQ_ATTR(back_seek_max),
++	BFQ_ATTR(back_seek_penalty),
++	BFQ_ATTR(slice_idle),
++	BFQ_ATTR(max_budget),
++	BFQ_ATTR(max_budget_async_rq),
++	BFQ_ATTR(timeout_sync),
++	BFQ_ATTR(timeout_async),
++	BFQ_ATTR(low_latency),
++	BFQ_ATTR(wr_coeff),
++	BFQ_ATTR(wr_max_time),
++	BFQ_ATTR(wr_rt_max_time),
++	BFQ_ATTR(wr_min_idle_time),
++	BFQ_ATTR(wr_min_inter_arr_async),
++	BFQ_ATTR(wr_max_softrt_rate),
++	BFQ_ATTR(weights),
++	__ATTR_NULL
++};
++
++static struct elevator_type iosched_bfq = {
++	.ops = {
++		.elevator_merge_fn =		bfq_merge,
++		.elevator_merged_fn =		bfq_merged_request,
++		.elevator_merge_req_fn =	bfq_merged_requests,
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		.elevator_bio_merged_fn =	bfq_bio_merged,
++#endif
++		.elevator_allow_merge_fn =	bfq_allow_merge,
++		.elevator_dispatch_fn =		bfq_dispatch_requests,
++		.elevator_add_req_fn =		bfq_insert_request,
++		.elevator_activate_req_fn =	bfq_activate_request,
++		.elevator_deactivate_req_fn =	bfq_deactivate_request,
++		.elevator_completed_req_fn =	bfq_completed_request,
++		.elevator_former_req_fn =	elv_rb_former_request,
++		.elevator_latter_req_fn =	elv_rb_latter_request,
++		.elevator_init_icq_fn =		bfq_init_icq,
++		.elevator_exit_icq_fn =		bfq_exit_icq,
++		.elevator_set_req_fn =		bfq_set_request,
++		.elevator_put_req_fn =		bfq_put_request,
++		.elevator_may_queue_fn =	bfq_may_queue,
++		.elevator_init_fn =		bfq_init_queue,
++		.elevator_exit_fn =		bfq_exit_queue,
++	},
++	.icq_size =		sizeof(struct bfq_io_cq),
++	.icq_align =		__alignof__(struct bfq_io_cq),
++	.elevator_attrs =	bfq_attrs,
++	.elevator_name =	"bfq",
++	.elevator_owner =	THIS_MODULE,
++};
++
++static int __init bfq_init(void)
++{
++	int ret;
++
++	/*
++	 * Can be 0 on HZ < 1000 setups.
++	 */
++	if (bfq_slice_idle == 0)
++		bfq_slice_idle = 1;
++
++	if (bfq_timeout_async == 0)
++		bfq_timeout_async = 1;
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	ret = blkcg_policy_register(&blkcg_policy_bfq);
++	if (ret)
++		return ret;
++#endif
++
++	ret = -ENOMEM;
++	if (bfq_slab_setup())
++		goto err_pol_unreg;
++
++	/*
++	 * Times to load large popular applications for the typical systems
++	 * installed on the reference devices (see the comments before the
++	 * definitions of the two arrays).
++	 */
++	T_slow[0] = msecs_to_jiffies(2600);
++	T_slow[1] = msecs_to_jiffies(1000);
++	T_fast[0] = msecs_to_jiffies(5500);
++	T_fast[1] = msecs_to_jiffies(2000);
++
++	/*
++	 * Thresholds that determine the switch between speed classes (see
++	 * the comments before the definition of the array).
++	 */
++	device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2;
++	device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2;
++
++	ret = elv_register(&iosched_bfq);
++	if (ret)
++		goto err_pol_unreg;
++
++	pr_info("BFQ I/O-scheduler: v7r11");
++
++	return 0;
++
++err_pol_unreg:
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	blkcg_policy_unregister(&blkcg_policy_bfq);
++#endif
++	return ret;
++}
++
++static void __exit bfq_exit(void)
++{
++	elv_unregister(&iosched_bfq);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	blkcg_policy_unregister(&blkcg_policy_bfq);
++#endif
++	bfq_slab_kill();
++}
++
++module_init(bfq_init);
++module_exit(bfq_exit);
++
++MODULE_AUTHOR("Arianna Avanzini, Fabio Checconi, Paolo Valente");
++MODULE_LICENSE("GPL");
+diff --git a/block/bfq-sched.c b/block/bfq-sched.c
+new file mode 100644
+index 0000000..a5ed694
+--- /dev/null
++++ b/block/bfq-sched.c
+@@ -0,0 +1,1199 @@
++/*
++ * BFQ: Hierarchical B-WF2Q+ scheduler.
++ *
++ * Based on ideas and code from CFQ:
++ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
++ *
++ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
++ *		      Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ */
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++#define for_each_entity(entity)	\
++	for (; entity ; entity = entity->parent)
++
++#define for_each_entity_safe(entity, parent) \
++	for (; entity && ({ parent = entity->parent; 1; }); entity = parent)
++
++
++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
++						 int extract,
++						 struct bfq_data *bfqd);
++
++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
++
++static void bfq_update_budget(struct bfq_entity *next_in_service)
++{
++	struct bfq_entity *bfqg_entity;
++	struct bfq_group *bfqg;
++	struct bfq_sched_data *group_sd;
++
++	BUG_ON(!next_in_service);
++
++	group_sd = next_in_service->sched_data;
++
++	bfqg = container_of(group_sd, struct bfq_group, sched_data);
++	/*
++	 * bfq_group's my_entity field is not NULL only if the group
++	 * is not the root group. We must not touch the root entity
++	 * as it must never become an in-service entity.
++	 */
++	bfqg_entity = bfqg->my_entity;
++	if (bfqg_entity)
++		bfqg_entity->budget = next_in_service->budget;
++}
++
++static int bfq_update_next_in_service(struct bfq_sched_data *sd)
++{
++	struct bfq_entity *next_in_service;
++
++	if (sd->in_service_entity)
++		/* will update/requeue at the end of service */
++		return 0;
++
++	/*
++	 * NOTE: this can be improved in many ways, such as returning
++	 * 1 (and thus propagating upwards the update) only when the
++	 * budget changes, or caching the bfqq that will be scheduled
++	 * next from this subtree.  By now we worry more about
++	 * correctness than about performance...
++	 */
++	next_in_service = bfq_lookup_next_entity(sd, 0, NULL);
++	sd->next_in_service = next_in_service;
++
++	if (next_in_service)
++		bfq_update_budget(next_in_service);
++
++	return 1;
++}
++
++static void bfq_check_next_in_service(struct bfq_sched_data *sd,
++				      struct bfq_entity *entity)
++{
++	BUG_ON(sd->next_in_service != entity);
++}
++#else
++#define for_each_entity(entity)	\
++	for (; entity ; entity = NULL)
++
++#define for_each_entity_safe(entity, parent) \
++	for (parent = NULL; entity ; entity = parent)
++
++static int bfq_update_next_in_service(struct bfq_sched_data *sd)
++{
++	return 0;
++}
++
++static void bfq_check_next_in_service(struct bfq_sched_data *sd,
++				      struct bfq_entity *entity)
++{
++}
++
++static void bfq_update_budget(struct bfq_entity *next_in_service)
++{
++}
++#endif
++
++/*
++ * Shift for timestamp calculations.  This actually limits the maximum
++ * service allowed in one timestamp delta (small shift values increase it),
++ * the maximum total weight that can be used for the queues in the system
++ * (big shift values increase it), and the period of virtual time
++ * wraparounds.
++ */
++#define WFQ_SERVICE_SHIFT	22
++
++/**
++ * bfq_gt - compare two timestamps.
++ * @a: first ts.
++ * @b: second ts.
++ *
++ * Return @a > @b, dealing with wrapping correctly.
++ */
++static int bfq_gt(u64 a, u64 b)
++{
++	return (s64)(a - b) > 0;
++}
++
++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = NULL;
++
++	BUG_ON(!entity);
++
++	if (!entity->my_sched_data)
++		bfqq = container_of(entity, struct bfq_queue, entity);
++
++	return bfqq;
++}
++
++
++/**
++ * bfq_delta - map service into the virtual time domain.
++ * @service: amount of service.
++ * @weight: scale factor (weight of an entity or weight sum).
++ */
++static u64 bfq_delta(unsigned long service, unsigned long weight)
++{
++	u64 d = (u64)service << WFQ_SERVICE_SHIFT;
++
++	do_div(d, weight);
++	return d;
++}
++
++/**
++ * bfq_calc_finish - assign the finish time to an entity.
++ * @entity: the entity to act upon.
++ * @service: the service to be charged to the entity.
++ */
++static void bfq_calc_finish(struct bfq_entity *entity, unsigned long service)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++	BUG_ON(entity->weight == 0);
++
++	entity->finish = entity->start +
++		bfq_delta(service, entity->weight);
++
++	if (bfqq) {
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			"calc_finish: serv %lu, w %d",
++			service, entity->weight);
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			"calc_finish: start %llu, finish %llu, delta %llu",
++			entity->start, entity->finish,
++			bfq_delta(service, entity->weight));
++	}
++}
++
++/**
++ * bfq_entity_of - get an entity from a node.
++ * @node: the node field of the entity.
++ *
++ * Convert a node pointer to the relative entity.  This is used only
++ * to simplify the logic of some functions and not as the generic
++ * conversion mechanism because, e.g., in the tree walking functions,
++ * the check for a %NULL value would be redundant.
++ */
++static struct bfq_entity *bfq_entity_of(struct rb_node *node)
++{
++	struct bfq_entity *entity = NULL;
++
++	if (node)
++		entity = rb_entry(node, struct bfq_entity, rb_node);
++
++	return entity;
++}
++
++/**
++ * bfq_extract - remove an entity from a tree.
++ * @root: the tree root.
++ * @entity: the entity to remove.
++ */
++static void bfq_extract(struct rb_root *root, struct bfq_entity *entity)
++{
++	BUG_ON(entity->tree != root);
++
++	entity->tree = NULL;
++	rb_erase(&entity->rb_node, root);
++}
++
++/**
++ * bfq_idle_extract - extract an entity from the idle tree.
++ * @st: the service tree of the owning @entity.
++ * @entity: the entity being removed.
++ */
++static void bfq_idle_extract(struct bfq_service_tree *st,
++			     struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	struct rb_node *next;
++
++	BUG_ON(entity->tree != &st->idle);
++
++	if (entity == st->first_idle) {
++		next = rb_next(&entity->rb_node);
++		st->first_idle = bfq_entity_of(next);
++	}
++
++	if (entity == st->last_idle) {
++		next = rb_prev(&entity->rb_node);
++		st->last_idle = bfq_entity_of(next);
++	}
++
++	bfq_extract(&st->idle, entity);
++
++	if (bfqq)
++		list_del(&bfqq->bfqq_list);
++}
++
++/**
++ * bfq_insert - generic tree insertion.
++ * @root: tree root.
++ * @entity: entity to insert.
++ *
++ * This is used for the idle and the active tree, since they are both
++ * ordered by finish time.
++ */
++static void bfq_insert(struct rb_root *root, struct bfq_entity *entity)
++{
++	struct bfq_entity *entry;
++	struct rb_node **node = &root->rb_node;
++	struct rb_node *parent = NULL;
++
++	BUG_ON(entity->tree);
++
++	while (*node) {
++		parent = *node;
++		entry = rb_entry(parent, struct bfq_entity, rb_node);
++
++		if (bfq_gt(entry->finish, entity->finish))
++			node = &parent->rb_left;
++		else
++			node = &parent->rb_right;
++	}
++
++	rb_link_node(&entity->rb_node, parent, node);
++	rb_insert_color(&entity->rb_node, root);
++
++	entity->tree = root;
++}
++
++/**
++ * bfq_update_min - update the min_start field of a entity.
++ * @entity: the entity to update.
++ * @node: one of its children.
++ *
++ * This function is called when @entity may store an invalid value for
++ * min_start due to updates to the active tree.  The function  assumes
++ * that the subtree rooted at @node (which may be its left or its right
++ * child) has a valid min_start value.
++ */
++static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
++{
++	struct bfq_entity *child;
++
++	if (node) {
++		child = rb_entry(node, struct bfq_entity, rb_node);
++		if (bfq_gt(entity->min_start, child->min_start))
++			entity->min_start = child->min_start;
++	}
++}
++
++/**
++ * bfq_update_active_node - recalculate min_start.
++ * @node: the node to update.
++ *
++ * @node may have changed position or one of its children may have moved,
++ * this function updates its min_start value.  The left and right subtrees
++ * are assumed to hold a correct min_start value.
++ */
++static void bfq_update_active_node(struct rb_node *node)
++{
++	struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
++
++	entity->min_start = entity->start;
++	bfq_update_min(entity, node->rb_right);
++	bfq_update_min(entity, node->rb_left);
++}
++
++/**
++ * bfq_update_active_tree - update min_start for the whole active tree.
++ * @node: the starting node.
++ *
++ * @node must be the deepest modified node after an update.  This function
++ * updates its min_start using the values held by its children, assuming
++ * that they did not change, and then updates all the nodes that may have
++ * changed in the path to the root.  The only nodes that may have changed
++ * are the ones in the path or their siblings.
++ */
++static void bfq_update_active_tree(struct rb_node *node)
++{
++	struct rb_node *parent;
++
++up:
++	bfq_update_active_node(node);
++
++	parent = rb_parent(node);
++	if (!parent)
++		return;
++
++	if (node == parent->rb_left && parent->rb_right)
++		bfq_update_active_node(parent->rb_right);
++	else if (parent->rb_left)
++		bfq_update_active_node(parent->rb_left);
++
++	node = parent;
++	goto up;
++}
++
++static void bfq_weights_tree_add(struct bfq_data *bfqd,
++				 struct bfq_entity *entity,
++				 struct rb_root *root);
++
++static void bfq_weights_tree_remove(struct bfq_data *bfqd,
++				    struct bfq_entity *entity,
++				    struct rb_root *root);
++
++
++/**
++ * bfq_active_insert - insert an entity in the active tree of its
++ *                     group/device.
++ * @st: the service tree of the entity.
++ * @entity: the entity being inserted.
++ *
++ * The active tree is ordered by finish time, but an extra key is kept
++ * per each node, containing the minimum value for the start times of
++ * its children (and the node itself), so it's possible to search for
++ * the eligible node with the lowest finish time in logarithmic time.
++ */
++static void bfq_active_insert(struct bfq_service_tree *st,
++			      struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	struct rb_node *node = &entity->rb_node;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	struct bfq_sched_data *sd = NULL;
++	struct bfq_group *bfqg = NULL;
++	struct bfq_data *bfqd = NULL;
++#endif
++
++	bfq_insert(&st->active, entity);
++
++	if (node->rb_left)
++		node = node->rb_left;
++	else if (node->rb_right)
++		node = node->rb_right;
++
++	bfq_update_active_tree(node);
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	sd = entity->sched_data;
++	bfqg = container_of(sd, struct bfq_group, sched_data);
++	BUG_ON(!bfqg);
++	bfqd = (struct bfq_data *)bfqg->bfqd;
++#endif
++	if (bfqq)
++		list_add(&bfqq->bfqq_list, &bfqq->bfqd->active_list);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	else { /* bfq_group */
++		BUG_ON(!bfqd);
++		bfq_weights_tree_add(bfqd, entity, &bfqd->group_weights_tree);
++	}
++	if (bfqg != bfqd->root_group) {
++		BUG_ON(!bfqg);
++		BUG_ON(!bfqd);
++		bfqg->active_entities++;
++		if (bfqg->active_entities == 2)
++			bfqd->active_numerous_groups++;
++	}
++#endif
++}
++
++/**
++ * bfq_ioprio_to_weight - calc a weight from an ioprio.
++ * @ioprio: the ioprio value to convert.
++ */
++static unsigned short bfq_ioprio_to_weight(int ioprio)
++{
++	BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
++	return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - ioprio;
++}
++
++/**
++ * bfq_weight_to_ioprio - calc an ioprio from a weight.
++ * @weight: the weight value to convert.
++ *
++ * To preserve as much as possible the old only-ioprio user interface,
++ * 0 is used as an escape ioprio value for weights (numerically) equal or
++ * larger than IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF.
++ */
++static unsigned short bfq_weight_to_ioprio(int weight)
++{
++	BUG_ON(weight < BFQ_MIN_WEIGHT || weight > BFQ_MAX_WEIGHT);
++	return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight < 0 ?
++		0 : IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - weight;
++}
++
++static void bfq_get_entity(struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++	if (bfqq) {
++		atomic_inc(&bfqq->ref);
++		bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
++			     bfqq, atomic_read(&bfqq->ref));
++	}
++}
++
++/**
++ * bfq_find_deepest - find the deepest node that an extraction can modify.
++ * @node: the node being removed.
++ *
++ * Do the first step of an extraction in an rb tree, looking for the
++ * node that will replace @node, and returning the deepest node that
++ * the following modifications to the tree can touch.  If @node is the
++ * last node in the tree return %NULL.
++ */
++static struct rb_node *bfq_find_deepest(struct rb_node *node)
++{
++	struct rb_node *deepest;
++
++	if (!node->rb_right && !node->rb_left)
++		deepest = rb_parent(node);
++	else if (!node->rb_right)
++		deepest = node->rb_left;
++	else if (!node->rb_left)
++		deepest = node->rb_right;
++	else {
++		deepest = rb_next(node);
++		if (deepest->rb_right)
++			deepest = deepest->rb_right;
++		else if (rb_parent(deepest) != node)
++			deepest = rb_parent(deepest);
++	}
++
++	return deepest;
++}
++
++/**
++ * bfq_active_extract - remove an entity from the active tree.
++ * @st: the service_tree containing the tree.
++ * @entity: the entity being removed.
++ */
++static void bfq_active_extract(struct bfq_service_tree *st,
++			       struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	struct rb_node *node;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	struct bfq_sched_data *sd = NULL;
++	struct bfq_group *bfqg = NULL;
++	struct bfq_data *bfqd = NULL;
++#endif
++
++	node = bfq_find_deepest(&entity->rb_node);
++	bfq_extract(&st->active, entity);
++
++	if (node)
++		bfq_update_active_tree(node);
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	sd = entity->sched_data;
++	bfqg = container_of(sd, struct bfq_group, sched_data);
++	BUG_ON(!bfqg);
++	bfqd = (struct bfq_data *)bfqg->bfqd;
++#endif
++	if (bfqq)
++		list_del(&bfqq->bfqq_list);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	else { /* bfq_group */
++		BUG_ON(!bfqd);
++		bfq_weights_tree_remove(bfqd, entity,
++					&bfqd->group_weights_tree);
++	}
++	if (bfqg != bfqd->root_group) {
++		BUG_ON(!bfqg);
++		BUG_ON(!bfqd);
++		BUG_ON(!bfqg->active_entities);
++		bfqg->active_entities--;
++		if (bfqg->active_entities == 1) {
++			BUG_ON(!bfqd->active_numerous_groups);
++			bfqd->active_numerous_groups--;
++		}
++	}
++#endif
++}
++
++/**
++ * bfq_idle_insert - insert an entity into the idle tree.
++ * @st: the service tree containing the tree.
++ * @entity: the entity to insert.
++ */
++static void bfq_idle_insert(struct bfq_service_tree *st,
++			    struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	struct bfq_entity *first_idle = st->first_idle;
++	struct bfq_entity *last_idle = st->last_idle;
++
++	if (!first_idle || bfq_gt(first_idle->finish, entity->finish))
++		st->first_idle = entity;
++	if (!last_idle || bfq_gt(entity->finish, last_idle->finish))
++		st->last_idle = entity;
++
++	bfq_insert(&st->idle, entity);
++
++	if (bfqq)
++		list_add(&bfqq->bfqq_list, &bfqq->bfqd->idle_list);
++}
++
++/**
++ * bfq_forget_entity - remove an entity from the wfq trees.
++ * @st: the service tree.
++ * @entity: the entity being removed.
++ *
++ * Update the device status and forget everything about @entity, putting
++ * the device reference to it, if it is a queue.  Entities belonging to
++ * groups are not refcounted.
++ */
++static void bfq_forget_entity(struct bfq_service_tree *st,
++			      struct bfq_entity *entity)
++{
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	struct bfq_sched_data *sd;
++
++	BUG_ON(!entity->on_st);
++
++	entity->on_st = 0;
++	st->wsum -= entity->weight;
++	if (bfqq) {
++		sd = entity->sched_data;
++		bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
++			     bfqq, atomic_read(&bfqq->ref));
++		bfq_put_queue(bfqq);
++	}
++}
++
++/**
++ * bfq_put_idle_entity - release the idle tree ref of an entity.
++ * @st: service tree for the entity.
++ * @entity: the entity being released.
++ */
++static void bfq_put_idle_entity(struct bfq_service_tree *st,
++				struct bfq_entity *entity)
++{
++	bfq_idle_extract(st, entity);
++	bfq_forget_entity(st, entity);
++}
++
++/**
++ * bfq_forget_idle - update the idle tree if necessary.
++ * @st: the service tree to act upon.
++ *
++ * To preserve the global O(log N) complexity we only remove one entry here;
++ * as the idle tree will not grow indefinitely this can be done safely.
++ */
++static void bfq_forget_idle(struct bfq_service_tree *st)
++{
++	struct bfq_entity *first_idle = st->first_idle;
++	struct bfq_entity *last_idle = st->last_idle;
++
++	if (RB_EMPTY_ROOT(&st->active) && last_idle &&
++	    !bfq_gt(last_idle->finish, st->vtime)) {
++		/*
++		 * Forget the whole idle tree, increasing the vtime past
++		 * the last finish time of idle entities.
++		 */
++		st->vtime = last_idle->finish;
++	}
++
++	if (first_idle && !bfq_gt(first_idle->finish, st->vtime))
++		bfq_put_idle_entity(st, first_idle);
++}
++
++static struct bfq_service_tree *
++__bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
++			 struct bfq_entity *entity)
++{
++	struct bfq_service_tree *new_st = old_st;
++
++	if (entity->prio_changed) {
++		struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++		unsigned short prev_weight, new_weight;
++		struct bfq_data *bfqd = NULL;
++		struct rb_root *root;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		struct bfq_sched_data *sd;
++		struct bfq_group *bfqg;
++#endif
++
++		if (bfqq)
++			bfqd = bfqq->bfqd;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		else {
++			sd = entity->my_sched_data;
++			bfqg = container_of(sd, struct bfq_group, sched_data);
++			BUG_ON(!bfqg);
++			bfqd = (struct bfq_data *)bfqg->bfqd;
++			BUG_ON(!bfqd);
++		}
++#endif
++
++		BUG_ON(old_st->wsum < entity->weight);
++		old_st->wsum -= entity->weight;
++
++		if (entity->new_weight != entity->orig_weight) {
++			if (entity->new_weight < BFQ_MIN_WEIGHT ||
++			    entity->new_weight > BFQ_MAX_WEIGHT) {
++				pr_crit("update_weight_prio: new_weight %d\n",
++					entity->new_weight);
++				BUG();
++			}
++			entity->orig_weight = entity->new_weight;
++			if (bfqq)
++				bfqq->ioprio =
++				  bfq_weight_to_ioprio(entity->orig_weight);
++		}
++
++		if (bfqq)
++			bfqq->ioprio_class = bfqq->new_ioprio_class;
++		entity->prio_changed = 0;
++
++		/*
++		 * NOTE: here we may be changing the weight too early,
++		 * this will cause unfairness.  The correct approach
++		 * would have required additional complexity to defer
++		 * weight changes to the proper time instants (i.e.,
++		 * when entity->finish <= old_st->vtime).
++		 */
++		new_st = bfq_entity_service_tree(entity);
++
++		prev_weight = entity->weight;
++		new_weight = entity->orig_weight *
++			     (bfqq ? bfqq->wr_coeff : 1);
++		/*
++		 * If the weight of the entity changes, remove the entity
++		 * from its old weight counter (if there is a counter
++		 * associated with the entity), and add it to the counter
++		 * associated with its new weight.
++		 */
++		if (prev_weight != new_weight) {
++			root = bfqq ? &bfqd->queue_weights_tree :
++				      &bfqd->group_weights_tree;
++			bfq_weights_tree_remove(bfqd, entity, root);
++		}
++		entity->weight = new_weight;
++		/*
++		 * Add the entity to its weights tree only if it is
++		 * not associated with a weight-raised queue.
++		 */
++		if (prev_weight != new_weight &&
++		    (bfqq ? bfqq->wr_coeff == 1 : 1))
++			/* If we get here, root has been initialized. */
++			bfq_weights_tree_add(bfqd, entity, root);
++
++		new_st->wsum += entity->weight;
++
++		if (new_st != old_st)
++			entity->start = new_st->vtime;
++	}
++
++	return new_st;
++}
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++static void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg);
++#endif
++
++/**
++ * bfq_bfqq_served - update the scheduler status after selection for
++ *                   service.
++ * @bfqq: the queue being served.
++ * @served: bytes to transfer.
++ *
++ * NOTE: this can be optimized, as the timestamps of upper level entities
++ * are synchronized every time a new bfqq is selected for service.  By now,
++ * we keep it to better check consistency.
++ */
++static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++	struct bfq_service_tree *st;
++
++	for_each_entity(entity) {
++		st = bfq_entity_service_tree(entity);
++
++		entity->service += served;
++		BUG_ON(entity->service > entity->budget);
++		BUG_ON(st->wsum == 0);
++
++		st->vtime += bfq_delta(served, st->wsum);
++		bfq_forget_idle(st);
++	}
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_set_start_empty_time(bfqq_group(bfqq));
++#endif
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs", served);
++}
++
++/**
++ * bfq_bfqq_charge_full_budget - set the service to the entity budget.
++ * @bfqq: the queue that needs a service update.
++ *
++ * When it's not possible to be fair in the service domain, because
++ * a queue is not consuming its budget fast enough (the meaning of
++ * fast depends on the timeout parameter), we charge it a full
++ * budget.  In this way we should obtain a sort of time-domain
++ * fairness among all the seeky/slow queues.
++ */
++static void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
++
++	bfq_bfqq_served(bfqq, entity->budget - entity->service);
++}
++
++/**
++ * __bfq_activate_entity - activate an entity.
++ * @entity: the entity being activated.
++ *
++ * Called whenever an entity is activated, i.e., it is not active and one
++ * of its children receives a new request, or has to be reactivated due to
++ * budget exhaustion.  It uses the current budget of the entity (and the
++ * service received if @entity is active) of the queue to calculate its
++ * timestamps.
++ */
++static void __bfq_activate_entity(struct bfq_entity *entity)
++{
++	struct bfq_sched_data *sd = entity->sched_data;
++	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
++
++	if (entity == sd->in_service_entity) {
++		BUG_ON(entity->tree);
++		/*
++		 * If we are requeueing the current entity we have
++		 * to take care of not charging to it service it has
++		 * not received.
++		 */
++		bfq_calc_finish(entity, entity->service);
++		entity->start = entity->finish;
++		sd->in_service_entity = NULL;
++	} else if (entity->tree == &st->active) {
++		/*
++		 * Requeueing an entity due to a change of some
++		 * next_in_service entity below it.  We reuse the
++		 * old start time.
++		 */
++		bfq_active_extract(st, entity);
++	} else if (entity->tree == &st->idle) {
++		/*
++		 * Must be on the idle tree, bfq_idle_extract() will
++		 * check for that.
++		 */
++		bfq_idle_extract(st, entity);
++		entity->start = bfq_gt(st->vtime, entity->finish) ?
++				       st->vtime : entity->finish;
++	} else {
++		/*
++		 * The finish time of the entity may be invalid, and
++		 * it is in the past for sure, otherwise the queue
++		 * would have been on the idle tree.
++		 */
++		entity->start = st->vtime;
++		st->wsum += entity->weight;
++		bfq_get_entity(entity);
++
++		BUG_ON(entity->on_st);
++		entity->on_st = 1;
++	}
++
++	st = __bfq_entity_update_weight_prio(st, entity);
++	bfq_calc_finish(entity, entity->budget);
++	bfq_active_insert(st, entity);
++}
++
++/**
++ * bfq_activate_entity - activate an entity and its ancestors if necessary.
++ * @entity: the entity to activate.
++ *
++ * Activate @entity and all the entities on the path from it to the root.
++ */
++static void bfq_activate_entity(struct bfq_entity *entity)
++{
++	struct bfq_sched_data *sd;
++
++	for_each_entity(entity) {
++		__bfq_activate_entity(entity);
++
++		sd = entity->sched_data;
++		if (!bfq_update_next_in_service(sd))
++			/*
++			 * No need to propagate the activation to the
++			 * upper entities, as they will be updated when
++			 * the in-service entity is rescheduled.
++			 */
++			break;
++	}
++}
++
++/**
++ * __bfq_deactivate_entity - deactivate an entity from its service tree.
++ * @entity: the entity to deactivate.
++ * @requeue: if false, the entity will not be put into the idle tree.
++ *
++ * Deactivate an entity, independently from its previous state.  If the
++ * entity was not on a service tree just return, otherwise if it is on
++ * any scheduler tree, extract it from that tree, and if necessary
++ * and if the caller did not specify @requeue, put it on the idle tree.
++ *
++ * Return %1 if the caller should update the entity hierarchy, i.e.,
++ * if the entity was in service or if it was the next_in_service for
++ * its sched_data; return %0 otherwise.
++ */
++static int __bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
++{
++	struct bfq_sched_data *sd = entity->sched_data;
++	struct bfq_service_tree *st;
++	int was_in_service;
++	int ret = 0;
++
++	if (sd == NULL || !entity->on_st) /* never activated, or inactive */
++		return 0;
++
++	st = bfq_entity_service_tree(entity);
++	was_in_service = entity == sd->in_service_entity;
++
++	BUG_ON(was_in_service && entity->tree);
++
++	if (was_in_service) {
++		bfq_calc_finish(entity, entity->service);
++		sd->in_service_entity = NULL;
++	} else if (entity->tree == &st->active)
++		bfq_active_extract(st, entity);
++	else if (entity->tree == &st->idle)
++		bfq_idle_extract(st, entity);
++	else if (entity->tree)
++		BUG();
++
++	if (was_in_service || sd->next_in_service == entity)
++		ret = bfq_update_next_in_service(sd);
++
++	if (!requeue || !bfq_gt(entity->finish, st->vtime))
++		bfq_forget_entity(st, entity);
++	else
++		bfq_idle_insert(st, entity);
++
++	BUG_ON(sd->in_service_entity == entity);
++	BUG_ON(sd->next_in_service == entity);
++
++	return ret;
++}
++
++/**
++ * bfq_deactivate_entity - deactivate an entity.
++ * @entity: the entity to deactivate.
++ * @requeue: true if the entity can be put on the idle tree
++ */
++static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
++{
++	struct bfq_sched_data *sd;
++	struct bfq_entity *parent;
++
++	for_each_entity_safe(entity, parent) {
++		sd = entity->sched_data;
++
++		if (!__bfq_deactivate_entity(entity, requeue))
++			/*
++			 * The parent entity is still backlogged, and
++			 * we don't need to update it as it is still
++			 * in service.
++			 */
++			break;
++
++		if (sd->next_in_service)
++			/*
++			 * The parent entity is still backlogged and
++			 * the budgets on the path towards the root
++			 * need to be updated.
++			 */
++			goto update;
++
++		/*
++		 * If we reach there the parent is no more backlogged and
++		 * we want to propagate the dequeue upwards.
++		 */
++		requeue = 1;
++	}
++
++	return;
++
++update:
++	entity = parent;
++	for_each_entity(entity) {
++		__bfq_activate_entity(entity);
++
++		sd = entity->sched_data;
++		if (!bfq_update_next_in_service(sd))
++			break;
++	}
++}
++
++/**
++ * bfq_update_vtime - update vtime if necessary.
++ * @st: the service tree to act upon.
++ *
++ * If necessary update the service tree vtime to have at least one
++ * eligible entity, skipping to its start time.  Assumes that the
++ * active tree of the device is not empty.
++ *
++ * NOTE: this hierarchical implementation updates vtimes quite often,
++ * we may end up with reactivated processes getting timestamps after a
++ * vtime skip done because we needed a ->first_active entity on some
++ * intermediate node.
++ */
++static void bfq_update_vtime(struct bfq_service_tree *st)
++{
++	struct bfq_entity *entry;
++	struct rb_node *node = st->active.rb_node;
++
++	entry = rb_entry(node, struct bfq_entity, rb_node);
++	if (bfq_gt(entry->min_start, st->vtime)) {
++		st->vtime = entry->min_start;
++		bfq_forget_idle(st);
++	}
++}
++
++/**
++ * bfq_first_active_entity - find the eligible entity with
++ *                           the smallest finish time
++ * @st: the service tree to select from.
++ *
++ * This function searches the first schedulable entity, starting from the
++ * root of the tree and going on the left every time on this side there is
++ * a subtree with at least one eligible (start >= vtime) entity. The path on
++ * the right is followed only if a) the left subtree contains no eligible
++ * entities and b) no eligible entity has been found yet.
++ */
++static struct bfq_entity *bfq_first_active_entity(struct bfq_service_tree *st)
++{
++	struct bfq_entity *entry, *first = NULL;
++	struct rb_node *node = st->active.rb_node;
++
++	while (node) {
++		entry = rb_entry(node, struct bfq_entity, rb_node);
++left:
++		if (!bfq_gt(entry->start, st->vtime))
++			first = entry;
++
++		BUG_ON(bfq_gt(entry->min_start, st->vtime));
++
++		if (node->rb_left) {
++			entry = rb_entry(node->rb_left,
++					 struct bfq_entity, rb_node);
++			if (!bfq_gt(entry->min_start, st->vtime)) {
++				node = node->rb_left;
++				goto left;
++			}
++		}
++		if (first)
++			break;
++		node = node->rb_right;
++	}
++
++	BUG_ON(!first && !RB_EMPTY_ROOT(&st->active));
++	return first;
++}
++
++/**
++ * __bfq_lookup_next_entity - return the first eligible entity in @st.
++ * @st: the service tree.
++ *
++ * Update the virtual time in @st and return the first eligible entity
++ * it contains.
++ */
++static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
++						   bool force)
++{
++	struct bfq_entity *entity, *new_next_in_service = NULL;
++
++	if (RB_EMPTY_ROOT(&st->active))
++		return NULL;
++
++	bfq_update_vtime(st);
++	entity = bfq_first_active_entity(st);
++	BUG_ON(bfq_gt(entity->start, st->vtime));
++
++	/*
++	 * If the chosen entity does not match with the sched_data's
++	 * next_in_service and we are forcedly serving the IDLE priority
++	 * class tree, bubble up budget update.
++	 */
++	if (unlikely(force && entity != entity->sched_data->next_in_service)) {
++		new_next_in_service = entity;
++		for_each_entity(new_next_in_service)
++			bfq_update_budget(new_next_in_service);
++	}
++
++	return entity;
++}
++
++/**
++ * bfq_lookup_next_entity - return the first eligible entity in @sd.
++ * @sd: the sched_data.
++ * @extract: if true the returned entity will be also extracted from @sd.
++ *
++ * NOTE: since we cache the next_in_service entity at each level of the
++ * hierarchy, the complexity of the lookup can be decreased with
++ * absolutely no effort just returning the cached next_in_service value;
++ * we prefer to do full lookups to test the consistency of * the data
++ * structures.
++ */
++static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
++						 int extract,
++						 struct bfq_data *bfqd)
++{
++	struct bfq_service_tree *st = sd->service_tree;
++	struct bfq_entity *entity;
++	int i = 0;
++
++	BUG_ON(sd->in_service_entity);
++
++	if (bfqd &&
++	    jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) {
++		entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1,
++						  true);
++		if (entity) {
++			i = BFQ_IOPRIO_CLASSES - 1;
++			bfqd->bfq_class_idle_last_service = jiffies;
++			sd->next_in_service = entity;
++		}
++	}
++	for (; i < BFQ_IOPRIO_CLASSES; i++) {
++		entity = __bfq_lookup_next_entity(st + i, false);
++		if (entity) {
++			if (extract) {
++				bfq_check_next_in_service(sd, entity);
++				bfq_active_extract(st + i, entity);
++				sd->in_service_entity = entity;
++				sd->next_in_service = NULL;
++			}
++			break;
++		}
++	}
++
++	return entity;
++}
++
++/*
++ * Get next queue for service.
++ */
++static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
++{
++	struct bfq_entity *entity = NULL;
++	struct bfq_sched_data *sd;
++	struct bfq_queue *bfqq;
++
++	BUG_ON(bfqd->in_service_queue);
++
++	if (bfqd->busy_queues == 0)
++		return NULL;
++
++	sd = &bfqd->root_group->sched_data;
++	for (; sd ; sd = entity->my_sched_data) {
++		entity = bfq_lookup_next_entity(sd, 1, bfqd);
++		BUG_ON(!entity);
++		entity->service = 0;
++	}
++
++	bfqq = bfq_entity_to_bfqq(entity);
++	BUG_ON(!bfqq);
++
++	return bfqq;
++}
++
++static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
++{
++	if (bfqd->in_service_bic) {
++		put_io_context(bfqd->in_service_bic->icq.ioc);
++		bfqd->in_service_bic = NULL;
++	}
++
++	bfqd->in_service_queue = NULL;
++	del_timer(&bfqd->idle_slice_timer);
++}
++
++static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++				int requeue)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	if (bfqq == bfqd->in_service_queue)
++		__bfq_bfqd_reset_in_service(bfqd);
++
++	bfq_deactivate_entity(entity, requeue);
++}
++
++static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	bfq_activate_entity(entity);
++}
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++static void bfqg_stats_update_dequeue(struct bfq_group *bfqg);
++#endif
++
++/*
++ * Called when the bfqq no longer has requests pending, remove it from
++ * the service tree.
++ */
++static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++			      int requeue)
++{
++	BUG_ON(!bfq_bfqq_busy(bfqq));
++	BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
++
++	bfq_log_bfqq(bfqd, bfqq, "del from busy");
++
++	bfq_clear_bfqq_busy(bfqq);
++
++	BUG_ON(bfqd->busy_queues == 0);
++	bfqd->busy_queues--;
++
++	if (!bfqq->dispatched) {
++		bfq_weights_tree_remove(bfqd, &bfqq->entity,
++					&bfqd->queue_weights_tree);
++		if (!blk_queue_nonrot(bfqd->queue)) {
++			BUG_ON(!bfqd->busy_in_flight_queues);
++			bfqd->busy_in_flight_queues--;
++			if (bfq_bfqq_constantly_seeky(bfqq)) {
++				BUG_ON(!bfqd->
++					const_seeky_busy_in_flight_queues);
++				bfqd->const_seeky_busy_in_flight_queues--;
++			}
++		}
++	}
++	if (bfqq->wr_coeff > 1)
++		bfqd->wr_busy_queues--;
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	bfqg_stats_update_dequeue(bfqq_group(bfqq));
++#endif
++
++	bfq_deactivate_bfqq(bfqd, bfqq, requeue);
++}
++
++/*
++ * Called when an inactive queue receives a new request.
++ */
++static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	BUG_ON(bfq_bfqq_busy(bfqq));
++	BUG_ON(bfqq == bfqd->in_service_queue);
++
++	bfq_log_bfqq(bfqd, bfqq, "add to busy");
++
++	bfq_activate_bfqq(bfqd, bfqq);
++
++	bfq_mark_bfqq_busy(bfqq);
++	bfqd->busy_queues++;
++
++	if (!bfqq->dispatched) {
++		if (bfqq->wr_coeff == 1)
++			bfq_weights_tree_add(bfqd, &bfqq->entity,
++					     &bfqd->queue_weights_tree);
++		if (!blk_queue_nonrot(bfqd->queue)) {
++			bfqd->busy_in_flight_queues++;
++			if (bfq_bfqq_constantly_seeky(bfqq))
++				bfqd->const_seeky_busy_in_flight_queues++;
++		}
++	}
++	if (bfqq->wr_coeff > 1)
++		bfqd->wr_busy_queues++;
++}
+diff --git a/block/bfq.h b/block/bfq.h
+new file mode 100644
+index 0000000..2bf54ae
+--- /dev/null
++++ b/block/bfq.h
+@@ -0,0 +1,801 @@
++/*
++ * BFQ-v7r11 for 4.5.0: data structures and common functions prototypes.
++ *
++ * Based on ideas and code from CFQ:
++ * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
++ *
++ * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
++ *		      Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ */
++
++#ifndef _BFQ_H
++#define _BFQ_H
++
++#include <linux/blktrace_api.h>
++#include <linux/hrtimer.h>
++#include <linux/ioprio.h>
++#include <linux/rbtree.h>
++#include <linux/blk-cgroup.h>
++
++#define BFQ_IOPRIO_CLASSES	3
++#define BFQ_CL_IDLE_TIMEOUT	(HZ/5)
++
++#define BFQ_MIN_WEIGHT			1
++#define BFQ_MAX_WEIGHT			1000
++#define BFQ_WEIGHT_CONVERSION_COEFF	10
++
++#define BFQ_DEFAULT_QUEUE_IOPRIO	4
++
++#define BFQ_DEFAULT_GRP_WEIGHT	10
++#define BFQ_DEFAULT_GRP_IOPRIO	0
++#define BFQ_DEFAULT_GRP_CLASS	IOPRIO_CLASS_BE
++
++struct bfq_entity;
++
++/**
++ * struct bfq_service_tree - per ioprio_class service tree.
++ * @active: tree for active entities (i.e., those backlogged).
++ * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i).
++ * @first_idle: idle entity with minimum F_i.
++ * @last_idle: idle entity with maximum F_i.
++ * @vtime: scheduler virtual time.
++ * @wsum: scheduler weight sum; active and idle entities contribute to it.
++ *
++ * Each service tree represents a B-WF2Q+ scheduler on its own.  Each
++ * ioprio_class has its own independent scheduler, and so its own
++ * bfq_service_tree.  All the fields are protected by the queue lock
++ * of the containing bfqd.
++ */
++struct bfq_service_tree {
++	struct rb_root active;
++	struct rb_root idle;
++
++	struct bfq_entity *first_idle;
++	struct bfq_entity *last_idle;
++
++	u64 vtime;
++	unsigned long wsum;
++};
++
++/**
++ * struct bfq_sched_data - multi-class scheduler.
++ * @in_service_entity: entity in service.
++ * @next_in_service: head-of-the-line entity in the scheduler.
++ * @service_tree: array of service trees, one per ioprio_class.
++ *
++ * bfq_sched_data is the basic scheduler queue.  It supports three
++ * ioprio_classes, and can be used either as a toplevel queue or as
++ * an intermediate queue on a hierarchical setup.
++ * @next_in_service points to the active entity of the sched_data
++ * service trees that will be scheduled next.
++ *
++ * The supported ioprio_classes are the same as in CFQ, in descending
++ * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
++ * Requests from higher priority queues are served before all the
++ * requests from lower priority queues; among requests of the same
++ * queue requests are served according to B-WF2Q+.
++ * All the fields are protected by the queue lock of the containing bfqd.
++ */
++struct bfq_sched_data {
++	struct bfq_entity *in_service_entity;
++	struct bfq_entity *next_in_service;
++	struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
++};
++
++/**
++ * struct bfq_weight_counter - counter of the number of all active entities
++ *                             with a given weight.
++ * @weight: weight of the entities that this counter refers to.
++ * @num_active: number of active entities with this weight.
++ * @weights_node: weights tree member (see bfq_data's @queue_weights_tree
++ *                and @group_weights_tree).
++ */
++struct bfq_weight_counter {
++	short int weight;
++	unsigned int num_active;
++	struct rb_node weights_node;
++};
++
++/**
++ * struct bfq_entity - schedulable entity.
++ * @rb_node: service_tree member.
++ * @weight_counter: pointer to the weight counter associated with this entity.
++ * @on_st: flag, true if the entity is on a tree (either the active or
++ *         the idle one of its service_tree).
++ * @finish: B-WF2Q+ finish timestamp (aka F_i).
++ * @start: B-WF2Q+ start timestamp (aka S_i).
++ * @tree: tree the entity is enqueued into; %NULL if not on a tree.
++ * @min_start: minimum start time of the (active) subtree rooted at
++ *             this entity; used for O(log N) lookups into active trees.
++ * @service: service received during the last round of service.
++ * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight.
++ * @weight: weight of the queue
++ * @parent: parent entity, for hierarchical scheduling.
++ * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the
++ *                 associated scheduler queue, %NULL on leaf nodes.
++ * @sched_data: the scheduler queue this entity belongs to.
++ * @ioprio: the ioprio in use.
++ * @new_weight: when a weight change is requested, the new weight value.
++ * @orig_weight: original weight, used to implement weight boosting
++ * @prio_changed: flag, true when the user requested a weight, ioprio or
++ *		  ioprio_class change.
++ *
++ * A bfq_entity is used to represent either a bfq_queue (leaf node in the
++ * cgroup hierarchy) or a bfq_group into the upper level scheduler.  Each
++ * entity belongs to the sched_data of the parent group in the cgroup
++ * hierarchy.  Non-leaf entities have also their own sched_data, stored
++ * in @my_sched_data.
++ *
++ * Each entity stores independently its priority values; this would
++ * allow different weights on different devices, but this
++ * functionality is not exported to userspace by now.  Priorities and
++ * weights are updated lazily, first storing the new values into the
++ * new_* fields, then setting the @prio_changed flag.  As soon as
++ * there is a transition in the entity state that allows the priority
++ * update to take place the effective and the requested priority
++ * values are synchronized.
++ *
++ * Unless cgroups are used, the weight value is calculated from the
++ * ioprio to export the same interface as CFQ.  When dealing with
++ * ``well-behaved'' queues (i.e., queues that do not spend too much
++ * time to consume their budget and have true sequential behavior, and
++ * when there are no external factors breaking anticipation) the
++ * relative weights at each level of the cgroups hierarchy should be
++ * guaranteed.  All the fields are protected by the queue lock of the
++ * containing bfqd.
++ */
++struct bfq_entity {
++	struct rb_node rb_node;
++	struct bfq_weight_counter *weight_counter;
++
++	int on_st;
++
++	u64 finish;
++	u64 start;
++
++	struct rb_root *tree;
++
++	u64 min_start;
++
++	int service, budget;
++	unsigned short weight, new_weight;
++	unsigned short orig_weight;
++
++	struct bfq_entity *parent;
++
++	struct bfq_sched_data *my_sched_data;
++	struct bfq_sched_data *sched_data;
++
++	int prio_changed;
++};
++
++struct bfq_group;
++
++/**
++ * struct bfq_queue - leaf schedulable entity.
++ * @ref: reference counter.
++ * @bfqd: parent bfq_data.
++ * @new_ioprio: when an ioprio change is requested, the new ioprio value.
++ * @ioprio_class: the ioprio_class in use.
++ * @new_ioprio_class: when an ioprio_class change is requested, the new
++ *                    ioprio_class value.
++ * @new_bfqq: shared bfq_queue if queue is cooperating with
++ *           one or more other queues.
++ * @sort_list: sorted list of pending requests.
++ * @next_rq: if fifo isn't expired, next request to serve.
++ * @queued: nr of requests queued in @sort_list.
++ * @allocated: currently allocated requests.
++ * @meta_pending: pending metadata requests.
++ * @fifo: fifo list of requests in sort_list.
++ * @entity: entity representing this queue in the scheduler.
++ * @max_budget: maximum budget allowed from the feedback mechanism.
++ * @budget_timeout: budget expiration (in jiffies).
++ * @dispatched: number of requests on the dispatch list or inside driver.
++ * @flags: status flags.
++ * @bfqq_list: node for active/idle bfqq list inside our bfqd.
++ * @burst_list_node: node for the device's burst list.
++ * @seek_samples: number of seeks sampled
++ * @seek_total: sum of the distances of the seeks sampled
++ * @seek_mean: mean seek distance
++ * @last_request_pos: position of the last request enqueued
++ * @requests_within_timer: number of consecutive pairs of request completion
++ *                         and arrival, such that the queue becomes idle
++ *                         after the completion, but the next request arrives
++ *                         within an idle time slice; used only if the queue's
++ *                         IO_bound has been cleared.
++ * @pid: pid of the process owning the queue, used for logging purposes.
++ * @last_wr_start_finish: start time of the current weight-raising period if
++ *                        the @bfq-queue is being weight-raised, otherwise
++ *                        finish time of the last weight-raising period
++ * @wr_cur_max_time: current max raising time for this queue
++ * @soft_rt_next_start: minimum time instant such that, only if a new
++ *                      request is enqueued after this time instant in an
++ *                      idle @bfq_queue with no outstanding requests, then
++ *                      the task associated with the queue it is deemed as
++ *                      soft real-time (see the comments to the function
++ *                      bfq_bfqq_softrt_next_start())
++ * @last_idle_bklogged: time of the last transition of the @bfq_queue from
++ *                      idle to backlogged
++ * @service_from_backlogged: cumulative service received from the @bfq_queue
++ *                           since the last transition from idle to
++ *                           backlogged
++ * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the
++ *	 queue is shared
++ *
++ * A bfq_queue is a leaf request queue; it can be associated with an
++ * io_context or more, if it  is  async or shared  between  cooperating
++ * processes. @cgroup holds a reference to the cgroup, to be sure that it
++ * does not disappear while a bfqq still references it (mostly to avoid
++ * races between request issuing and task migration followed by cgroup
++ * destruction).
++ * All the fields are protected by the queue lock of the containing bfqd.
++ */
++struct bfq_queue {
++	atomic_t ref;
++	struct bfq_data *bfqd;
++
++	unsigned short ioprio, new_ioprio;
++	unsigned short ioprio_class, new_ioprio_class;
++
++	/* fields for cooperating queues handling */
++	struct bfq_queue *new_bfqq;
++	struct rb_node pos_node;
++	struct rb_root *pos_root;
++
++	struct rb_root sort_list;
++	struct request *next_rq;
++	int queued[2];
++	int allocated[2];
++	int meta_pending;
++	struct list_head fifo;
++
++	struct bfq_entity entity;
++
++	int max_budget;
++	unsigned long budget_timeout;
++
++	int dispatched;
++
++	unsigned int flags;
++
++	struct list_head bfqq_list;
++
++	struct hlist_node burst_list_node;
++
++	unsigned int seek_samples;
++	u64 seek_total;
++	sector_t seek_mean;
++	sector_t last_request_pos;
++
++	unsigned int requests_within_timer;
++
++	pid_t pid;
++	struct bfq_io_cq *bic;
++
++	/* weight-raising fields */
++	unsigned long wr_cur_max_time;
++	unsigned long soft_rt_next_start;
++	unsigned long last_wr_start_finish;
++	unsigned int wr_coeff;
++	unsigned long last_idle_bklogged;
++	unsigned long service_from_backlogged;
++};
++
++/**
++ * struct bfq_ttime - per process thinktime stats.
++ * @ttime_total: total process thinktime
++ * @ttime_samples: number of thinktime samples
++ * @ttime_mean: average process thinktime
++ */
++struct bfq_ttime {
++	unsigned long last_end_request;
++
++	unsigned long ttime_total;
++	unsigned long ttime_samples;
++	unsigned long ttime_mean;
++};
++
++/**
++ * struct bfq_io_cq - per (request_queue, io_context) structure.
++ * @icq: associated io_cq structure
++ * @bfqq: array of two process queues, the sync and the async
++ * @ttime: associated @bfq_ttime struct
++ * @ioprio: per (request_queue, blkcg) ioprio.
++ * @blkcg_id: id of the blkcg the related io_cq belongs to.
++ */
++struct bfq_io_cq {
++	struct io_cq icq; /* must be the first member */
++	struct bfq_queue *bfqq[2];
++	struct bfq_ttime ttime;
++	int ioprio;
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	uint64_t blkcg_id; /* the current blkcg ID */
++#endif
++};
++
++enum bfq_device_speed {
++	BFQ_BFQD_FAST,
++	BFQ_BFQD_SLOW,
++};
++
++/**
++ * struct bfq_data - per device data structure.
++ * @queue: request queue for the managed device.
++ * @root_group: root bfq_group for the device.
++ * @active_numerous_groups: number of bfq_groups containing more than one
++ *                          active @bfq_entity.
++ * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by
++ *                      weight. Used to keep track of whether all @bfq_queues
++ *                     have the same weight. The tree contains one counter
++ *                     for each distinct weight associated to some active
++ *                     and not weight-raised @bfq_queue (see the comments to
++ *                      the functions bfq_weights_tree_[add|remove] for
++ *                     further details).
++ * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted
++ *                      by weight. Used to keep track of whether all
++ *                     @bfq_groups have the same weight. The tree contains
++ *                     one counter for each distinct weight associated to
++ *                     some active @bfq_group (see the comments to the
++ *                     functions bfq_weights_tree_[add|remove] for further
++ *                     details).
++ * @busy_queues: number of bfq_queues containing requests (including the
++ *		 queue in service, even if it is idling).
++ * @busy_in_flight_queues: number of @bfq_queues containing pending or
++ *                         in-flight requests, plus the @bfq_queue in
++ *                         service, even if idle but waiting for the
++ *                         possible arrival of its next sync request. This
++ *                         field is updated only if the device is rotational,
++ *                         but used only if the device is also NCQ-capable.
++ *                         The reason why the field is updated also for non-
++ *                         NCQ-capable rotational devices is related to the
++ *                         fact that the value of @hw_tag may be set also
++ *                         later than when busy_in_flight_queues may need to
++ *                         be incremented for the first time(s). Taking also
++ *                         this possibility into account, to avoid unbalanced
++ *                         increments/decrements, would imply more overhead
++ *                         than just updating busy_in_flight_queues
++ *                         regardless of the value of @hw_tag.
++ * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues
++ *                                     (that is, seeky queues that expired
++ *                                     for budget timeout at least once)
++ *                                     containing pending or in-flight
++ *                                     requests, including the in-service
++ *                                     @bfq_queue if constantly seeky. This
++ *                                     field is updated only if the device
++ *                                     is rotational, but used only if the
++ *                                     device is also NCQ-capable (see the
++ *                                     comments to @busy_in_flight_queues).
++ * @wr_busy_queues: number of weight-raised busy @bfq_queues.
++ * @queued: number of queued requests.
++ * @rq_in_driver: number of requests dispatched and waiting for completion.
++ * @sync_flight: number of sync requests in the driver.
++ * @max_rq_in_driver: max number of reqs in driver in the last
++ *                    @hw_tag_samples completed requests.
++ * @hw_tag_samples: nr of samples used to calculate hw_tag.
++ * @hw_tag: flag set to one if the driver is showing a queueing behavior.
++ * @budgets_assigned: number of budgets assigned.
++ * @idle_slice_timer: timer set when idling for the next sequential request
++ *                    from the queue in service.
++ * @unplug_work: delayed work to restart dispatching on the request queue.
++ * @in_service_queue: bfq_queue in service.
++ * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue.
++ * @last_position: on-disk position of the last served request.
++ * @last_budget_start: beginning of the last budget.
++ * @last_idling_start: beginning of the last idle slice.
++ * @peak_rate: peak transfer rate observed for a budget.
++ * @peak_rate_samples: number of samples used to calculate @peak_rate.
++ * @bfq_max_budget: maximum budget allotted to a bfq_queue before
++ *                  rescheduling.
++ * @active_list: list of all the bfq_queues active on the device.
++ * @idle_list: list of all the bfq_queues idle on the device.
++ * @bfq_fifo_expire: timeout for async/sync requests; when it expires
++ *                   requests are served in fifo order.
++ * @bfq_back_penalty: weight of backward seeks wrt forward ones.
++ * @bfq_back_max: maximum allowed backward seek.
++ * @bfq_slice_idle: maximum idling time.
++ * @bfq_user_max_budget: user-configured max budget value
++ *                       (0 for auto-tuning).
++ * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to
++ *                           async queues.
++ * @bfq_timeout: timeout for bfq_queues to consume their budget; used to
++ *               to prevent seeky queues to impose long latencies to well
++ *               behaved ones (this also implies that seeky queues cannot
++ *               receive guarantees in the service domain; after a timeout
++ *               they are charged for the whole allocated budget, to try
++ *               to preserve a behavior reasonably fair among them, but
++ *               without service-domain guarantees).
++ * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is
++ *                   no more granted any weight-raising.
++ * @bfq_failed_cooperations: number of consecutive failed cooperation
++ *                           chances after which weight-raising is restored
++ *                           to a queue subject to more than bfq_coop_thresh
++ *                           queue merges.
++ * @bfq_requests_within_timer: number of consecutive requests that must be
++ *                             issued within the idle time slice to set
++ *                             again idling to a queue which was marked as
++ *                             non-I/O-bound (see the definition of the
++ *                             IO_bound flag for further details).
++ * @last_ins_in_burst: last time at which a queue entered the current
++ *                     burst of queues being activated shortly after
++ *                     each other; for more details about this and the
++ *                     following parameters related to a burst of
++ *                     activations, see the comments to the function
++ *                     @bfq_handle_burst.
++ * @bfq_burst_interval: reference time interval used to decide whether a
++ *                      queue has been activated shortly after
++ *                      @last_ins_in_burst.
++ * @burst_size: number of queues in the current burst of queue activations.
++ * @bfq_large_burst_thresh: maximum burst size above which the current
++ *			    queue-activation burst is deemed as 'large'.
++ * @large_burst: true if a large queue-activation burst is in progress.
++ * @burst_list: head of the burst list (as for the above fields, more details
++ *		in the comments to the function bfq_handle_burst).
++ * @low_latency: if set to true, low-latency heuristics are enabled.
++ * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised
++ *                queue is multiplied.
++ * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies).
++ * @bfq_wr_rt_max_time: maximum duration for soft real-time processes.
++ * @bfq_wr_min_idle_time: minimum idle period after which weight-raising
++ *			  may be reactivated for a queue (in jiffies).
++ * @bfq_wr_min_inter_arr_async: minimum period between request arrivals
++ *				after which weight-raising may be
++ *				reactivated for an already busy queue
++ *				(in jiffies).
++ * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue,
++ *			    sectors per seconds.
++ * @RT_prod: cached value of the product R*T used for computing the maximum
++ *	     duration of the weight raising automatically.
++ * @device_speed: device-speed class for the low-latency heuristic.
++ * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions.
++ *
++ * All the fields are protected by the @queue lock.
++ */
++struct bfq_data {
++	struct request_queue *queue;
++
++	struct bfq_group *root_group;
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	int active_numerous_groups;
++#endif
++
++	struct rb_root queue_weights_tree;
++	struct rb_root group_weights_tree;
++
++	int busy_queues;
++	int busy_in_flight_queues;
++	int const_seeky_busy_in_flight_queues;
++	int wr_busy_queues;
++	int queued;
++	int rq_in_driver;
++	int sync_flight;
++
++	int max_rq_in_driver;
++	int hw_tag_samples;
++	int hw_tag;
++
++	int budgets_assigned;
++
++	struct timer_list idle_slice_timer;
++	struct work_struct unplug_work;
++
++	struct bfq_queue *in_service_queue;
++	struct bfq_io_cq *in_service_bic;
++
++	sector_t last_position;
++
++	ktime_t last_budget_start;
++	ktime_t last_idling_start;
++	int peak_rate_samples;
++	u64 peak_rate;
++	int bfq_max_budget;
++
++	struct list_head active_list;
++	struct list_head idle_list;
++
++	unsigned int bfq_fifo_expire[2];
++	unsigned int bfq_back_penalty;
++	unsigned int bfq_back_max;
++	unsigned int bfq_slice_idle;
++	u64 bfq_class_idle_last_service;
++
++	int bfq_user_max_budget;
++	int bfq_max_budget_async_rq;
++	unsigned int bfq_timeout[2];
++
++	unsigned int bfq_coop_thresh;
++	unsigned int bfq_failed_cooperations;
++	unsigned int bfq_requests_within_timer;
++
++	unsigned long last_ins_in_burst;
++	unsigned long bfq_burst_interval;
++	int burst_size;
++	unsigned long bfq_large_burst_thresh;
++	bool large_burst;
++	struct hlist_head burst_list;
++
++	bool low_latency;
++
++	/* parameters of the low_latency heuristics */
++	unsigned int bfq_wr_coeff;
++	unsigned int bfq_wr_max_time;
++	unsigned int bfq_wr_rt_max_time;
++	unsigned int bfq_wr_min_idle_time;
++	unsigned long bfq_wr_min_inter_arr_async;
++	unsigned int bfq_wr_max_softrt_rate;
++	u64 RT_prod;
++	enum bfq_device_speed device_speed;
++
++	struct bfq_queue oom_bfqq;
++};
++
++enum bfqq_state_flags {
++	BFQ_BFQQ_FLAG_busy = 0,		/* has requests or is in service */
++	BFQ_BFQQ_FLAG_wait_request,	/* waiting for a request */
++	BFQ_BFQQ_FLAG_must_alloc,	/* must be allowed rq alloc */
++	BFQ_BFQQ_FLAG_fifo_expire,	/* FIFO checked in this slice */
++	BFQ_BFQQ_FLAG_idle_window,	/* slice idling enabled */
++	BFQ_BFQQ_FLAG_sync,		/* synchronous queue */
++	BFQ_BFQQ_FLAG_budget_new,	/* no completion with this budget */
++	BFQ_BFQQ_FLAG_IO_bound,		/*
++					 * bfqq has timed-out at least once
++					 * having consumed at most 2/10 of
++					 * its budget
++					 */
++	BFQ_BFQQ_FLAG_in_large_burst,	/*
++					 * bfqq activated in a large burst,
++					 * see comments to bfq_handle_burst.
++					 */
++	BFQ_BFQQ_FLAG_constantly_seeky,	/*
++					 * bfqq has proved to be slow and
++					 * seeky until budget timeout
++					 */
++	BFQ_BFQQ_FLAG_softrt_update,	/*
++					 * may need softrt-next-start
++					 * update
++					 */
++};
++
++#define BFQ_BFQQ_FNS(name)						\
++static void bfq_mark_bfqq_##name(struct bfq_queue *bfqq)		\
++{									\
++	(bfqq)->flags |= (1 << BFQ_BFQQ_FLAG_##name);			\
++}									\
++static void bfq_clear_bfqq_##name(struct bfq_queue *bfqq)		\
++{									\
++	(bfqq)->flags &= ~(1 << BFQ_BFQQ_FLAG_##name);			\
++}									\
++static int bfq_bfqq_##name(const struct bfq_queue *bfqq)		\
++{									\
++	return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0;	\
++}
++
++BFQ_BFQQ_FNS(busy);
++BFQ_BFQQ_FNS(wait_request);
++BFQ_BFQQ_FNS(must_alloc);
++BFQ_BFQQ_FNS(fifo_expire);
++BFQ_BFQQ_FNS(idle_window);
++BFQ_BFQQ_FNS(sync);
++BFQ_BFQQ_FNS(budget_new);
++BFQ_BFQQ_FNS(IO_bound);
++BFQ_BFQQ_FNS(in_large_burst);
++BFQ_BFQQ_FNS(constantly_seeky);
++BFQ_BFQQ_FNS(softrt_update);
++#undef BFQ_BFQQ_FNS
++
++/* Logging facilities. */
++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \
++	blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args)
++
++#define bfq_log(bfqd, fmt, args...) \
++	blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args)
++
++/* Expiration reasons. */
++enum bfqq_expiration {
++	BFQ_BFQQ_TOO_IDLE = 0,		/*
++					 * queue has been idling for
++					 * too long
++					 */
++	BFQ_BFQQ_BUDGET_TIMEOUT,	/* budget took too long to be used */
++	BFQ_BFQQ_BUDGET_EXHAUSTED,	/* budget consumed */
++	BFQ_BFQQ_NO_MORE_REQUESTS,	/* the queue has no more requests */
++};
++
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++
++struct bfqg_stats {
++	/* total bytes transferred */
++	struct blkg_rwstat		service_bytes;
++	/* total IOs serviced, post merge */
++	struct blkg_rwstat		serviced;
++	/* number of ios merged */
++	struct blkg_rwstat		merged;
++	/* total time spent on device in ns, may not be accurate w/ queueing */
++	struct blkg_rwstat		service_time;
++	/* total time spent waiting in scheduler queue in ns */
++	struct blkg_rwstat		wait_time;
++	/* number of IOs queued up */
++	struct blkg_rwstat		queued;
++	/* total sectors transferred */
++	struct blkg_stat		sectors;
++	/* total disk time and nr sectors dispatched by this group */
++	struct blkg_stat		time;
++	/* time not charged to this cgroup */
++	struct blkg_stat		unaccounted_time;
++	/* sum of number of ios queued across all samples */
++	struct blkg_stat		avg_queue_size_sum;
++	/* count of samples taken for average */
++	struct blkg_stat		avg_queue_size_samples;
++	/* how many times this group has been removed from service tree */
++	struct blkg_stat		dequeue;
++	/* total time spent waiting for it to be assigned a timeslice. */
++	struct blkg_stat		group_wait_time;
++	/* time spent idling for this blkcg_gq */
++	struct blkg_stat		idle_time;
++	/* total time with empty current active q with other requests queued */
++	struct blkg_stat		empty_time;
++	/* fields after this shouldn't be cleared on stat reset */
++	uint64_t			start_group_wait_time;
++	uint64_t			start_idle_time;
++	uint64_t			start_empty_time;
++	uint16_t			flags;
++};
++
++/*
++ * struct bfq_group_data - per-blkcg storage for the blkio subsystem.
++ *
++ * @ps: @blkcg_policy_storage that this structure inherits
++ * @weight: weight of the bfq_group
++ */
++struct bfq_group_data {
++	/* must be the first member */
++	struct blkcg_policy_data pd;
++
++	unsigned short weight;
++};
++
++/**
++ * struct bfq_group - per (device, cgroup) data structure.
++ * @entity: schedulable entity to insert into the parent group sched_data.
++ * @sched_data: own sched_data, to contain child entities (they may be
++ *              both bfq_queues and bfq_groups).
++ * @bfqd: the bfq_data for the device this group acts upon.
++ * @async_bfqq: array of async queues for all the tasks belonging to
++ *              the group, one queue per ioprio value per ioprio_class,
++ *              except for the idle class that has only one queue.
++ * @async_idle_bfqq: async queue for the idle class (ioprio is ignored).
++ * @my_entity: pointer to @entity, %NULL for the toplevel group; used
++ *             to avoid too many special cases during group creation/
++ *             migration.
++ * @active_entities: number of active entities belonging to the group;
++ *                   unused for the root group. Used to know whether there
++ *                   are groups with more than one active @bfq_entity
++ *                   (see the comments to the function
++ *                   bfq_bfqq_must_not_expire()).
++ *
++ * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup
++ * there is a set of bfq_groups, each one collecting the lower-level
++ * entities belonging to the group that are acting on the same device.
++ *
++ * Locking works as follows:
++ *    o @bfqd is protected by the queue lock, RCU is used to access it
++ *      from the readers.
++ *    o All the other fields are protected by the @bfqd queue lock.
++ */
++struct bfq_group {
++	/* must be the first member */
++	struct blkg_policy_data pd;
++
++	struct bfq_entity entity;
++	struct bfq_sched_data sched_data;
++
++	void *bfqd;
++
++	struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
++	struct bfq_queue *async_idle_bfqq;
++
++	struct bfq_entity *my_entity;
++
++	int active_entities;
++
++	struct bfqg_stats stats;
++	struct bfqg_stats dead_stats;	/* stats pushed from dead children */
++};
++
++#else
++struct bfq_group {
++	struct bfq_sched_data sched_data;
++
++	struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
++	struct bfq_queue *async_idle_bfqq;
++};
++#endif
++
++static struct bfq_queue *bfq_entity_to_bfqq(struct bfq_entity *entity);
++
++static struct bfq_service_tree *
++bfq_entity_service_tree(struct bfq_entity *entity)
++{
++	struct bfq_sched_data *sched_data = entity->sched_data;
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	unsigned int idx = bfqq ? bfqq->ioprio_class - 1 :
++				  BFQ_DEFAULT_GRP_CLASS;
++
++	BUG_ON(idx >= BFQ_IOPRIO_CLASSES);
++	BUG_ON(sched_data == NULL);
++
++	return sched_data->service_tree + idx;
++}
++
++static struct bfq_queue *bic_to_bfqq(struct bfq_io_cq *bic, bool is_sync)
++{
++	return bic->bfqq[is_sync];
++}
++
++static void bic_set_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq,
++			 bool is_sync)
++{
++	bic->bfqq[is_sync] = bfqq;
++}
++
++static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic)
++{
++	return bic->icq.q->elevator->elevator_data;
++}
++
++/**
++ * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer.
++ * @ptr: a pointer to a bfqd.
++ * @flags: storage for the flags to be saved.
++ *
++ * This function allows bfqg->bfqd to be protected by the
++ * queue lock of the bfqd they reference; the pointer is dereferenced
++ * under RCU, so the storage for bfqd is assured to be safe as long
++ * as the RCU read side critical section does not end.  After the
++ * bfqd->queue->queue_lock is taken the pointer is rechecked, to be
++ * sure that no other writer accessed it.  If we raced with a writer,
++ * the function returns NULL, with the queue unlocked, otherwise it
++ * returns the dereferenced pointer, with the queue locked.
++ */
++static struct bfq_data *bfq_get_bfqd_locked(void **ptr, unsigned long *flags)
++{
++	struct bfq_data *bfqd;
++
++	rcu_read_lock();
++	bfqd = rcu_dereference(*(struct bfq_data **)ptr);
++
++	if (bfqd != NULL) {
++		spin_lock_irqsave(bfqd->queue->queue_lock, *flags);
++		if (ptr == NULL)
++			printk(KERN_CRIT "get_bfqd_locked pointer NULL\n");
++		else if (*ptr == bfqd)
++			goto out;
++		spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
++	}
++
++	bfqd = NULL;
++out:
++	rcu_read_unlock();
++	return bfqd;
++}
++
++static void bfq_put_bfqd_unlock(struct bfq_data *bfqd, unsigned long *flags)
++{
++	spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
++}
++
++static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio);
++static void bfq_put_queue(struct bfq_queue *bfqq);
++static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
++static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
++				       struct bio *bio, int is_sync,
++				       struct bfq_io_cq *bic, gfp_t gfp_mask);
++static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
++				    struct bfq_group *bfqg);
++static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
++static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
++
++#endif /* _BFQ_H */
+-- 
+2.7.4 (Apple Git-66)
+

diff --git a/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch b/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch
new file mode 100644
index 0000000..2a53175
--- /dev/null
+++ b/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch
@@ -0,0 +1,1101 @@
+From 409e62551360d2802992b0175062237352793a2a Mon Sep 17 00:00:00 2001
+From: Mauro Andreolini <mauro.andreolini@unimore.it>
+Date: Sun, 6 Sep 2015 16:09:05 +0200
+Subject: [PATCH 3/4] block, bfq: add Early Queue Merge (EQM) to BFQ-v7r11, to
+ port to 4.8.0
+
+A set of processes may happen  to  perform interleaved reads, i.e.,requests
+whose union would give rise to a  sequential read  pattern.  There are two
+typical  cases: in the first  case,   processes  read  fixed-size chunks of
+data at a fixed distance from each other, while in the second case processes
+may read variable-size chunks at  variable distances. The latter case occurs
+for  example with  QEMU, which  splits the  I/O generated  by the  guest into
+multiple chunks,  and lets these chunks  be served by a  pool of cooperating
+processes,  iteratively  assigning  the  next  chunk of  I/O  to  the first
+available  process. CFQ  uses actual  queue merging  for the  first type of
+rocesses, whereas it  uses preemption to get a sequential  read pattern out
+of the read requests  performed by the second type of  processes. In the end
+it uses  two different  mechanisms to  achieve the  same goal: boosting the
+throughput with interleaved I/O.
+
+This patch introduces  Early Queue Merge (EQM), a unified mechanism to get a
+sequential  read pattern  with both  types of  processes. The  main idea is
+checking newly arrived requests against the next request of the active queue
+both in case of actual request insert and in case of request merge. By doing
+so, both the types of processes can be handled by just merging their queues.
+EQM is  then simpler and  more compact than the  pair of mechanisms used in
+CFQ.
+
+Finally, EQM  also preserves the  typical low-latency properties of BFQ, by
+properly restoring the weight-raising state of a queue when it gets back to
+a non-merged state.
+
+Signed-off-by: Mauro Andreolini <mauro.andreolini@unimore.it>
+Signed-off-by: Arianna Avanzini <avanzini@google.com>
+Signed-off-by: Paolo Valente <paolo.valente@unimore.it>
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+---
+ block/bfq-cgroup.c  |   5 +
+ block/bfq-iosched.c | 685 +++++++++++++++++++++++++++++++++++++++++++++++++++-
+ block/bfq.h         |  66 +++++
+ 3 files changed, 743 insertions(+), 13 deletions(-)
+
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 8b08a57..0367996 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -440,6 +440,7 @@ static void bfq_pd_init(struct blkg_policy_data *pd)
+ 				   */
+ 	bfqg->bfqd = bfqd;
+ 	bfqg->active_entities = 0;
++	bfqg->rq_pos_tree = RB_ROOT;
+ }
+ 
+ static void bfq_pd_free(struct blkg_policy_data *pd)
+@@ -533,6 +534,9 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
+ 	return bfqg;
+ }
+ 
++static void bfq_pos_tree_add_move(struct bfq_data *bfqd,
++				  struct bfq_queue *bfqq);
++
+ /**
+  * bfq_bfqq_move - migrate @bfqq to @bfqg.
+  * @bfqd: queue descriptor.
+@@ -580,6 +584,7 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	bfqg_get(bfqg);
+ 
+ 	if (busy) {
++		bfq_pos_tree_add_move(bfqd, bfqq);
+ 		if (resume)
+ 			bfq_activate_bfqq(bfqd, bfqq);
+ 	}
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index 85e2169..cf3e9b1 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -295,6 +295,72 @@ static struct request *bfq_choose_req(struct bfq_data *bfqd,
+ 	}
+ }
+ 
++static struct bfq_queue *
++bfq_rq_pos_tree_lookup(struct bfq_data *bfqd, struct rb_root *root,
++		     sector_t sector, struct rb_node **ret_parent,
++		     struct rb_node ***rb_link)
++{
++	struct rb_node **p, *parent;
++	struct bfq_queue *bfqq = NULL;
++
++	parent = NULL;
++	p = &root->rb_node;
++	while (*p) {
++		struct rb_node **n;
++
++		parent = *p;
++		bfqq = rb_entry(parent, struct bfq_queue, pos_node);
++
++		/*
++		 * Sort strictly based on sector. Smallest to the left,
++		 * largest to the right.
++		 */
++		if (sector > blk_rq_pos(bfqq->next_rq))
++			n = &(*p)->rb_right;
++		else if (sector < blk_rq_pos(bfqq->next_rq))
++			n = &(*p)->rb_left;
++		else
++			break;
++		p = n;
++		bfqq = NULL;
++	}
++
++	*ret_parent = parent;
++	if (rb_link)
++		*rb_link = p;
++
++	bfq_log(bfqd, "rq_pos_tree_lookup %llu: returning %d",
++		(unsigned long long) sector,
++		bfqq ? bfqq->pid : 0);
++
++	return bfqq;
++}
++
++static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
++{
++	struct rb_node **p, *parent;
++	struct bfq_queue *__bfqq;
++
++	if (bfqq->pos_root) {
++		rb_erase(&bfqq->pos_node, bfqq->pos_root);
++		bfqq->pos_root = NULL;
++	}
++
++	if (bfq_class_idle(bfqq))
++		return;
++	if (!bfqq->next_rq)
++		return;
++
++	bfqq->pos_root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree;
++	__bfqq = bfq_rq_pos_tree_lookup(bfqd, bfqq->pos_root,
++			blk_rq_pos(bfqq->next_rq), &parent, &p);
++	if (!__bfqq) {
++		rb_link_node(&bfqq->pos_node, parent, p);
++		rb_insert_color(&bfqq->pos_node, bfqq->pos_root);
++	} else
++		bfqq->pos_root = NULL;
++}
++
+ /*
+  * Tell whether there are active queues or groups with differentiated weights.
+  */
+@@ -527,6 +593,57 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
+ 	return dur;
+ }
+ 
++static unsigned int bfq_bfqq_cooperations(struct bfq_queue *bfqq)
++{
++	return bfqq->bic ? bfqq->bic->cooperations : 0;
++}
++
++static void
++bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
++{
++	if (bic->saved_idle_window)
++		bfq_mark_bfqq_idle_window(bfqq);
++	else
++		bfq_clear_bfqq_idle_window(bfqq);
++	if (bic->saved_IO_bound)
++		bfq_mark_bfqq_IO_bound(bfqq);
++	else
++		bfq_clear_bfqq_IO_bound(bfqq);
++	/* Assuming that the flag in_large_burst is already correctly set */
++	if (bic->wr_time_left && bfqq->bfqd->low_latency &&
++	    !bfq_bfqq_in_large_burst(bfqq) &&
++	    bic->cooperations < bfqq->bfqd->bfq_coop_thresh) {
++		/*
++		 * Start a weight raising period with the duration given by
++		 * the raising_time_left snapshot.
++		 */
++		if (bfq_bfqq_busy(bfqq))
++			bfqq->bfqd->wr_busy_queues++;
++		bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff;
++		bfqq->wr_cur_max_time = bic->wr_time_left;
++		bfqq->last_wr_start_finish = jiffies;
++		bfqq->entity.prio_changed = 1;
++	}
++	/*
++	 * Clear wr_time_left to prevent bfq_bfqq_save_state() from
++	 * getting confused about the queue's need of a weight-raising
++	 * period.
++	 */
++	bic->wr_time_left = 0;
++}
++
++static int bfqq_process_refs(struct bfq_queue *bfqq)
++{
++	int process_refs, io_refs;
++
++	lockdep_assert_held(bfqq->bfqd->queue->queue_lock);
++
++	io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE];
++	process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st;
++	BUG_ON(process_refs < 0);
++	return process_refs;
++}
++
+ /* Empty burst list and add just bfqq (see comments to bfq_handle_burst) */
+ static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ {
+@@ -763,8 +880,14 @@ static void bfq_add_request(struct request *rq)
+ 	BUG_ON(!next_rq);
+ 	bfqq->next_rq = next_rq;
+ 
++	/*
++	 * Adjust priority tree position, if next_rq changes.
++	 */
++	if (prev != bfqq->next_rq)
++		bfq_pos_tree_add_move(bfqd, bfqq);
++
+ 	if (!bfq_bfqq_busy(bfqq)) {
+-		bool soft_rt, in_burst,
++		bool soft_rt, coop_or_in_burst,
+ 		     idle_for_long_time = time_is_before_jiffies(
+ 						bfqq->budget_timeout +
+ 						bfqd->bfq_wr_min_idle_time);
+@@ -792,11 +915,12 @@ static void bfq_add_request(struct request *rq)
+ 				bfqd->last_ins_in_burst = jiffies;
+ 		}
+ 
+-		in_burst = bfq_bfqq_in_large_burst(bfqq);
++		coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) ||
++			bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh;
+ 		soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
+-			!in_burst &&
++			!coop_or_in_burst &&
+ 			time_is_before_jiffies(bfqq->soft_rt_next_start);
+-		interactive = !in_burst && idle_for_long_time;
++		interactive = !coop_or_in_burst && idle_for_long_time;
+ 		entity->budget = max_t(unsigned long, bfqq->max_budget,
+ 				       bfq_serv_to_charge(next_rq, bfqq));
+ 
+@@ -815,6 +939,9 @@ static void bfq_add_request(struct request *rq)
+ 		if (!bfqd->low_latency)
+ 			goto add_bfqq_busy;
+ 
++		if (bfq_bfqq_just_split(bfqq))
++			goto set_prio_changed;
++
+ 		/*
+ 		 * If the queue:
+ 		 * - is not being boosted,
+@@ -839,7 +966,7 @@ static void bfq_add_request(struct request *rq)
+ 		} else if (old_wr_coeff > 1) {
+ 			if (interactive)
+ 				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
+-			else if (in_burst ||
++			else if (coop_or_in_burst ||
+ 				 (bfqq->wr_cur_max_time ==
+ 				  bfqd->bfq_wr_rt_max_time &&
+ 				  !soft_rt)) {
+@@ -904,6 +1031,7 @@ static void bfq_add_request(struct request *rq)
+ 					bfqd->bfq_wr_rt_max_time;
+ 			}
+ 		}
++set_prio_changed:
+ 		if (old_wr_coeff != bfqq->wr_coeff)
+ 			entity->prio_changed = 1;
+ add_bfqq_busy:
+@@ -1046,6 +1174,15 @@ static void bfq_merged_request(struct request_queue *q, struct request *req,
+ 					 bfqd->last_position);
+ 		BUG_ON(!next_rq);
+ 		bfqq->next_rq = next_rq;
++		/*
++		 * If next_rq changes, update both the queue's budget to
++		 * fit the new request and the queue's position in its
++		 * rq_pos_tree.
++		 */
++		if (prev != bfqq->next_rq) {
++			bfq_updated_next_req(bfqd, bfqq);
++			bfq_pos_tree_add_move(bfqd, bfqq);
++		}
+ 	}
+ }
+ 
+@@ -1128,11 +1265,346 @@ static void bfq_end_wr(struct bfq_data *bfqd)
+ 	spin_unlock_irq(bfqd->queue->queue_lock);
+ }
+ 
++static sector_t bfq_io_struct_pos(void *io_struct, bool request)
++{
++	if (request)
++		return blk_rq_pos(io_struct);
++	else
++		return ((struct bio *)io_struct)->bi_iter.bi_sector;
++}
++
++static int bfq_rq_close_to_sector(void *io_struct, bool request,
++				  sector_t sector)
++{
++	return abs(bfq_io_struct_pos(io_struct, request) - sector) <=
++	       BFQQ_SEEK_THR;
++}
++
++static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd,
++					 struct bfq_queue *bfqq,
++					 sector_t sector)
++{
++	struct rb_root *root = &bfq_bfqq_to_bfqg(bfqq)->rq_pos_tree;
++	struct rb_node *parent, *node;
++	struct bfq_queue *__bfqq;
++
++	if (RB_EMPTY_ROOT(root))
++		return NULL;
++
++	/*
++	 * First, if we find a request starting at the end of the last
++	 * request, choose it.
++	 */
++	__bfqq = bfq_rq_pos_tree_lookup(bfqd, root, sector, &parent, NULL);
++	if (__bfqq)
++		return __bfqq;
++
++	/*
++	 * If the exact sector wasn't found, the parent of the NULL leaf
++	 * will contain the closest sector (rq_pos_tree sorted by
++	 * next_request position).
++	 */
++	__bfqq = rb_entry(parent, struct bfq_queue, pos_node);
++	if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
++		return __bfqq;
++
++	if (blk_rq_pos(__bfqq->next_rq) < sector)
++		node = rb_next(&__bfqq->pos_node);
++	else
++		node = rb_prev(&__bfqq->pos_node);
++	if (!node)
++		return NULL;
++
++	__bfqq = rb_entry(node, struct bfq_queue, pos_node);
++	if (bfq_rq_close_to_sector(__bfqq->next_rq, true, sector))
++		return __bfqq;
++
++	return NULL;
++}
++
++static struct bfq_queue *bfq_find_close_cooperator(struct bfq_data *bfqd,
++						   struct bfq_queue *cur_bfqq,
++						   sector_t sector)
++{
++	struct bfq_queue *bfqq;
++
++	/*
++	 * We shall notice if some of the queues are cooperating,
++	 * e.g., working closely on the same area of the device. In
++	 * that case, we can group them together and: 1) don't waste
++	 * time idling, and 2) serve the union of their requests in
++	 * the best possible order for throughput.
++	 */
++	bfqq = bfqq_find_close(bfqd, cur_bfqq, sector);
++	if (!bfqq || bfqq == cur_bfqq)
++		return NULL;
++
++	return bfqq;
++}
++
++static struct bfq_queue *
++bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
++{
++	int process_refs, new_process_refs;
++	struct bfq_queue *__bfqq;
++
++	/*
++	 * If there are no process references on the new_bfqq, then it is
++	 * unsafe to follow the ->new_bfqq chain as other bfqq's in the chain
++	 * may have dropped their last reference (not just their last process
++	 * reference).
++	 */
++	if (!bfqq_process_refs(new_bfqq))
++		return NULL;
++
++	/* Avoid a circular list and skip interim queue merges. */
++	while ((__bfqq = new_bfqq->new_bfqq)) {
++		if (__bfqq == bfqq)
++			return NULL;
++		new_bfqq = __bfqq;
++	}
++
++	process_refs = bfqq_process_refs(bfqq);
++	new_process_refs = bfqq_process_refs(new_bfqq);
++	/*
++	 * If the process for the bfqq has gone away, there is no
++	 * sense in merging the queues.
++	 */
++	if (process_refs == 0 || new_process_refs == 0)
++		return NULL;
++
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "scheduling merge with queue %d",
++		new_bfqq->pid);
++
++	/*
++	 * Merging is just a redirection: the requests of the process
++	 * owning one of the two queues are redirected to the other queue.
++	 * The latter queue, in its turn, is set as shared if this is the
++	 * first time that the requests of some process are redirected to
++	 * it.
++	 *
++	 * We redirect bfqq to new_bfqq and not the opposite, because we
++	 * are in the context of the process owning bfqq, hence we have
++	 * the io_cq of this process. So we can immediately configure this
++	 * io_cq to redirect the requests of the process to new_bfqq.
++	 *
++	 * NOTE, even if new_bfqq coincides with the in-service queue, the
++	 * io_cq of new_bfqq is not available, because, if the in-service
++	 * queue is shared, bfqd->in_service_bic may not point to the
++	 * io_cq of the in-service queue.
++	 * Redirecting the requests of the process owning bfqq to the
++	 * currently in-service queue is in any case the best option, as
++	 * we feed the in-service queue with new requests close to the
++	 * last request served and, by doing so, hopefully increase the
++	 * throughput.
++	 */
++	bfqq->new_bfqq = new_bfqq;
++	atomic_add(process_refs, &new_bfqq->ref);
++	return new_bfqq;
++}
++
++static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
++					struct bfq_queue *new_bfqq)
++{
++	if (bfq_class_idle(bfqq) || bfq_class_idle(new_bfqq) ||
++	    (bfqq->ioprio_class != new_bfqq->ioprio_class))
++		return false;
++
++	/*
++	 * If either of the queues has already been detected as seeky,
++	 * then merging it with the other queue is unlikely to lead to
++	 * sequential I/O.
++	 */
++	if (BFQQ_SEEKY(bfqq) || BFQQ_SEEKY(new_bfqq))
++		return false;
++
++	/*
++	 * Interleaved I/O is known to be done by (some) applications
++	 * only for reads, so it does not make sense to merge async
++	 * queues.
++	 */
++	if (!bfq_bfqq_sync(bfqq) || !bfq_bfqq_sync(new_bfqq))
++		return false;
++
++	return true;
++}
++
++/*
++ * Attempt to schedule a merge of bfqq with the currently in-service queue
++ * or with a close queue among the scheduled queues.
++ * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue
++ * structure otherwise.
++ *
++ * The OOM queue is not allowed to participate to cooperation: in fact, since
++ * the requests temporarily redirected to the OOM queue could be redirected
++ * again to dedicated queues at any time, the state needed to correctly
++ * handle merging with the OOM queue would be quite complex and expensive
++ * to maintain. Besides, in such a critical condition as an out of memory,
++ * the benefits of queue merging may be little relevant, or even negligible.
++ */
++static struct bfq_queue *
++bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++		     void *io_struct, bool request)
++{
++	struct bfq_queue *in_service_bfqq, *new_bfqq;
++
++	if (bfqq->new_bfqq)
++		return bfqq->new_bfqq;
++	if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq))
++		return NULL;
++	/* If device has only one backlogged bfq_queue, don't search. */
++	if (bfqd->busy_queues == 1)
++		return NULL;
++
++	in_service_bfqq = bfqd->in_service_queue;
++
++	if (!in_service_bfqq || in_service_bfqq == bfqq ||
++	    !bfqd->in_service_bic ||
++	    unlikely(in_service_bfqq == &bfqd->oom_bfqq))
++		goto check_scheduled;
++
++	if (bfq_rq_close_to_sector(io_struct, request, bfqd->last_position) &&
++	    bfqq->entity.parent == in_service_bfqq->entity.parent &&
++	    bfq_may_be_close_cooperator(bfqq, in_service_bfqq)) {
++		new_bfqq = bfq_setup_merge(bfqq, in_service_bfqq);
++		if (new_bfqq)
++			return new_bfqq;
++	}
++	/*
++	 * Check whether there is a cooperator among currently scheduled
++	 * queues. The only thing we need is that the bio/request is not
++	 * NULL, as we need it to establish whether a cooperator exists.
++	 */
++check_scheduled:
++	new_bfqq = bfq_find_close_cooperator(bfqd, bfqq,
++			bfq_io_struct_pos(io_struct, request));
++
++	BUG_ON(new_bfqq && bfqq->entity.parent != new_bfqq->entity.parent);
++
++	if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq) &&
++	    bfq_may_be_close_cooperator(bfqq, new_bfqq))
++		return bfq_setup_merge(bfqq, new_bfqq);
++
++	return NULL;
++}
++
++static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
++{
++	/*
++	 * If !bfqq->bic, the queue is already shared or its requests
++	 * have already been redirected to a shared queue; both idle window
++	 * and weight raising state have already been saved. Do nothing.
++	 */
++	if (!bfqq->bic)
++		return;
++	if (bfqq->bic->wr_time_left)
++		/*
++		 * This is the queue of a just-started process, and would
++		 * deserve weight raising: we set wr_time_left to the full
++		 * weight-raising duration to trigger weight-raising when
++		 * and if the queue is split and the first request of the
++		 * queue is enqueued.
++		 */
++		bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd);
++	else if (bfqq->wr_coeff > 1) {
++		unsigned long wr_duration =
++			jiffies - bfqq->last_wr_start_finish;
++		/*
++		 * It may happen that a queue's weight raising period lasts
++		 * longer than its wr_cur_max_time, as weight raising is
++		 * handled only when a request is enqueued or dispatched (it
++		 * does not use any timer). If the weight raising period is
++		 * about to end, don't save it.
++		 */
++		if (bfqq->wr_cur_max_time <= wr_duration)
++			bfqq->bic->wr_time_left = 0;
++		else
++			bfqq->bic->wr_time_left =
++				bfqq->wr_cur_max_time - wr_duration;
++		/*
++		 * The bfq_queue is becoming shared or the requests of the
++		 * process owning the queue are being redirected to a shared
++		 * queue. Stop the weight raising period of the queue, as in
++		 * both cases it should not be owned by an interactive or
++		 * soft real-time application.
++		 */
++		bfq_bfqq_end_wr(bfqq);
++	} else
++		bfqq->bic->wr_time_left = 0;
++	bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
++	bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
++	bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
++	bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
++	bfqq->bic->cooperations++;
++	bfqq->bic->failed_cooperations = 0;
++}
++
++static void bfq_get_bic_reference(struct bfq_queue *bfqq)
++{
++	/*
++	 * If bfqq->bic has a non-NULL value, the bic to which it belongs
++	 * is about to begin using a shared bfq_queue.
++	 */
++	if (bfqq->bic)
++		atomic_long_inc(&bfqq->bic->icq.ioc->refcount);
++}
++
++static void
++bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
++		struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
++{
++	bfq_log_bfqq(bfqd, bfqq, "merging with queue %lu",
++		     (unsigned long) new_bfqq->pid);
++	/* Save weight raising and idle window of the merged queues */
++	bfq_bfqq_save_state(bfqq);
++	bfq_bfqq_save_state(new_bfqq);
++	if (bfq_bfqq_IO_bound(bfqq))
++		bfq_mark_bfqq_IO_bound(new_bfqq);
++	bfq_clear_bfqq_IO_bound(bfqq);
++	/*
++	 * Grab a reference to the bic, to prevent it from being destroyed
++	 * before being possibly touched by a bfq_split_bfqq().
++	 */
++	bfq_get_bic_reference(bfqq);
++	bfq_get_bic_reference(new_bfqq);
++	/*
++	 * Merge queues (that is, let bic redirect its requests to new_bfqq)
++	 */
++	bic_set_bfqq(bic, new_bfqq, 1);
++	bfq_mark_bfqq_coop(new_bfqq);
++	/*
++	 * new_bfqq now belongs to at least two bics (it is a shared queue):
++	 * set new_bfqq->bic to NULL. bfqq either:
++	 * - does not belong to any bic any more, and hence bfqq->bic must
++	 *   be set to NULL, or
++	 * - is a queue whose owning bics have already been redirected to a
++	 *   different queue, hence the queue is destined to not belong to
++	 *   any bic soon and bfqq->bic is already NULL (therefore the next
++	 *   assignment causes no harm).
++	 */
++	new_bfqq->bic = NULL;
++	bfqq->bic = NULL;
++	bfq_put_queue(bfqq);
++}
++
++static void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq)
++{
++	struct bfq_io_cq *bic = bfqq->bic;
++	struct bfq_data *bfqd = bfqq->bfqd;
++
++	if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) {
++		bic->failed_cooperations++;
++		if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations)
++			bic->cooperations = 0;
++	}
++}
++
+ static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+ 			   struct bio *bio)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+ 	struct bfq_io_cq *bic;
++	struct bfq_queue *bfqq, *new_bfqq;
+ 
+ 	/*
+ 	 * Disallow merge of a sync bio into an async request.
+@@ -1149,7 +1621,26 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+ 	if (!bic)
+ 		return 0;
+ 
+-	return bic_to_bfqq(bic, bfq_bio_sync(bio)) == RQ_BFQQ(rq);
++	bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
++	/*
++	 * We take advantage of this function to perform an early merge
++	 * of the queues of possible cooperating processes.
++	 */
++	if (bfqq) {
++		new_bfqq = bfq_setup_cooperator(bfqd, bfqq, bio, false);
++		if (new_bfqq) {
++			bfq_merge_bfqqs(bfqd, bic, bfqq, new_bfqq);
++			/*
++			 * If we get here, the bio will be queued in the
++			 * shared queue, i.e., new_bfqq, so use new_bfqq
++			 * to decide whether bio and rq can be merged.
++			 */
++			bfqq = new_bfqq;
++		} else
++			bfq_bfqq_increase_failed_cooperations(bfqq);
++	}
++
++	return bfqq == RQ_BFQQ(rq);
+ }
+ 
+ static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
+@@ -1350,6 +1841,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 
+ 	__bfq_bfqd_reset_in_service(bfqd);
+ 
++	/*
++	 * If this bfqq is shared between multiple processes, check
++	 * to make sure that those processes are still issuing I/Os
++	 * within the mean seek distance. If not, it may be time to
++	 * break the queues apart again.
++	 */
++	if (bfq_bfqq_coop(bfqq) && BFQQ_SEEKY(bfqq))
++		bfq_mark_bfqq_split_coop(bfqq);
++
+ 	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
+ 		/*
+ 		 * Overloading budget_timeout field to store the time
+@@ -1358,8 +1858,13 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		 */
+ 		bfqq->budget_timeout = jiffies;
+ 		bfq_del_bfqq_busy(bfqd, bfqq, 1);
+-	} else
++	} else {
+ 		bfq_activate_bfqq(bfqd, bfqq);
++		/*
++		 * Resort priority tree of potential close cooperators.
++		 */
++		bfq_pos_tree_add_move(bfqd, bfqq);
++	}
+ }
+ 
+ /**
+@@ -2246,10 +2751,12 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		/*
+ 		 * If the queue was activated in a burst, or
+ 		 * too much time has elapsed from the beginning
+-		 * of this weight-raising period, then end weight
+-		 * raising.
++		 * of this weight-raising period, or the queue has
++		 * exceeded the acceptable number of cooperations,
++		 * then end weight raising.
+ 		 */
+ 		if (bfq_bfqq_in_large_burst(bfqq) ||
++		    bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh ||
+ 		    time_is_before_jiffies(bfqq->last_wr_start_finish +
+ 					   bfqq->wr_cur_max_time)) {
+ 			bfqq->last_wr_start_finish = jiffies;
+@@ -2478,6 +2985,25 @@ static void bfq_put_queue(struct bfq_queue *bfqq)
+ #endif
+ }
+ 
++static void bfq_put_cooperator(struct bfq_queue *bfqq)
++{
++	struct bfq_queue *__bfqq, *next;
++
++	/*
++	 * If this queue was scheduled to merge with another queue, be
++	 * sure to drop the reference taken on that queue (and others in
++	 * the merge chain). See bfq_setup_merge and bfq_merge_bfqqs.
++	 */
++	__bfqq = bfqq->new_bfqq;
++	while (__bfqq) {
++		if (__bfqq == bfqq)
++			break;
++		next = __bfqq->new_bfqq;
++		bfq_put_queue(__bfqq);
++		__bfqq = next;
++	}
++}
++
+ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ {
+ 	if (bfqq == bfqd->in_service_queue) {
+@@ -2488,6 +3014,8 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 	bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
+ 		     atomic_read(&bfqq->ref));
+ 
++	bfq_put_cooperator(bfqq);
++
+ 	bfq_put_queue(bfqq);
+ }
+ 
+@@ -2496,6 +3024,25 @@ static void bfq_init_icq(struct io_cq *icq)
+ 	struct bfq_io_cq *bic = icq_to_bic(icq);
+ 
+ 	bic->ttime.last_end_request = jiffies;
++	/*
++	 * A newly created bic indicates that the process has just
++	 * started doing I/O, and is probably mapping into memory its
++	 * executable and libraries: it definitely needs weight raising.
++	 * There is however the possibility that the process performs,
++	 * for a while, I/O close to some other process. EQM intercepts
++	 * this behavior and may merge the queue corresponding to the
++	 * process  with some other queue, BEFORE the weight of the queue
++	 * is raised. Merged queues are not weight-raised (they are assumed
++	 * to belong to processes that benefit only from high throughput).
++	 * If the merge is basically the consequence of an accident, then
++	 * the queue will be split soon and will get back its old weight.
++	 * It is then important to write down somewhere that this queue
++	 * does need weight raising, even if it did not make it to get its
++	 * weight raised before being merged. To this purpose, we overload
++	 * the field raising_time_left and assign 1 to it, to mark the queue
++	 * as needing weight raising.
++	 */
++	bic->wr_time_left = 1;
+ }
+ 
+ static void bfq_exit_icq(struct io_cq *icq)
+@@ -2509,6 +3056,13 @@ static void bfq_exit_icq(struct io_cq *icq)
+ 	}
+ 
+ 	if (bic->bfqq[BLK_RW_SYNC]) {
++		/*
++		 * If the bic is using a shared queue, put the reference
++		 * taken on the io_context when the bic started using a
++		 * shared bfq_queue.
++		 */
++		if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC]))
++			put_io_context(icq->ioc);
+ 		bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
+ 		bic->bfqq[BLK_RW_SYNC] = NULL;
+ 	}
+@@ -2814,6 +3368,10 @@ static void bfq_update_idle_window(struct bfq_data *bfqd,
+ 	if (!bfq_bfqq_sync(bfqq) || bfq_class_idle(bfqq))
+ 		return;
+ 
++	/* Idle window just restored, statistics are meaningless. */
++	if (bfq_bfqq_just_split(bfqq))
++		return;
++
+ 	enable_idle = bfq_bfqq_idle_window(bfqq);
+ 
+ 	if (atomic_read(&bic->icq.ioc->active_ref) == 0 ||
+@@ -2861,6 +3419,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
+ 	    !BFQQ_SEEKY(bfqq))
+ 		bfq_update_idle_window(bfqd, bfqq, bic);
++	bfq_clear_bfqq_just_split(bfqq);
+ 
+ 	bfq_log_bfqq(bfqd, bfqq,
+ 		     "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
+@@ -2925,12 +3484,47 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ static void bfq_insert_request(struct request_queue *q, struct request *rq)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+-	struct bfq_queue *bfqq = RQ_BFQQ(rq);
++	struct bfq_queue *bfqq = RQ_BFQQ(rq), *new_bfqq;
+ 
+ 	assert_spin_locked(bfqd->queue->queue_lock);
+ 
++	/*
++	 * An unplug may trigger a requeue of a request from the device
++	 * driver: make sure we are in process context while trying to
++	 * merge two bfq_queues.
++	 */
++	if (!in_interrupt()) {
++		new_bfqq = bfq_setup_cooperator(bfqd, bfqq, rq, true);
++		if (new_bfqq) {
++			if (bic_to_bfqq(RQ_BIC(rq), 1) != bfqq)
++				new_bfqq = bic_to_bfqq(RQ_BIC(rq), 1);
++			/*
++			 * Release the request's reference to the old bfqq
++			 * and make sure one is taken to the shared queue.
++			 */
++			new_bfqq->allocated[rq_data_dir(rq)]++;
++			bfqq->allocated[rq_data_dir(rq)]--;
++			atomic_inc(&new_bfqq->ref);
++			bfq_put_queue(bfqq);
++			if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
++				bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
++						bfqq, new_bfqq);
++			rq->elv.priv[1] = new_bfqq;
++			bfqq = new_bfqq;
++		} else
++			bfq_bfqq_increase_failed_cooperations(bfqq);
++	}
++
+ 	bfq_add_request(rq);
+ 
++	/*
++	 * Here a newly-created bfq_queue has already started a weight-raising
++	 * period: clear raising_time_left to prevent bfq_bfqq_save_state()
++	 * from assigning it a full weight-raising period. See the detailed
++	 * comments about this field in bfq_init_icq().
++	 */
++	if (bfqq->bic)
++		bfqq->bic->wr_time_left = 0;
+ 	rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)];
+ 	list_add_tail(&rq->queuelist, &bfqq->fifo);
+ 
+@@ -3099,6 +3693,32 @@ static void bfq_put_request(struct request *rq)
+ }
+ 
+ /*
++ * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
++ * was the last process referring to said bfqq.
++ */
++static struct bfq_queue *
++bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
++{
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "splitting queue");
++
++	put_io_context(bic->icq.ioc);
++
++	if (bfqq_process_refs(bfqq) == 1) {
++		bfqq->pid = current->pid;
++		bfq_clear_bfqq_coop(bfqq);
++		bfq_clear_bfqq_split_coop(bfqq);
++		return bfqq;
++	}
++
++	bic_set_bfqq(bic, NULL, 1);
++
++	bfq_put_cooperator(bfqq);
++
++	bfq_put_queue(bfqq);
++	return NULL;
++}
++
++/*
+  * Allocate bfq data structures associated with this request.
+  */
+ static int bfq_set_request(struct request_queue *q, struct request *rq,
+@@ -3110,6 +3730,7 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
+ 	const int is_sync = rq_is_sync(rq);
+ 	struct bfq_queue *bfqq;
+ 	unsigned long flags;
++	bool split = false;
+ 
+ 	might_sleep_if(gfpflags_allow_blocking(gfp_mask));
+ 
+@@ -3122,15 +3743,30 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
+ 
+ 	bfq_bic_update_cgroup(bic, bio);
+ 
++new_queue:
+ 	bfqq = bic_to_bfqq(bic, is_sync);
+ 	if (!bfqq || bfqq == &bfqd->oom_bfqq) {
+ 		bfqq = bfq_get_queue(bfqd, bio, is_sync, bic, gfp_mask);
+ 		bic_set_bfqq(bic, bfqq, is_sync);
+-		if (is_sync) {
+-			if (bfqd->large_burst)
++		if (split && is_sync) {
++			if ((bic->was_in_burst_list && bfqd->large_burst) ||
++			    bic->saved_in_large_burst)
+ 				bfq_mark_bfqq_in_large_burst(bfqq);
+-			else
++			else {
+ 				bfq_clear_bfqq_in_large_burst(bfqq);
++				if (bic->was_in_burst_list)
++					hlist_add_head(&bfqq->burst_list_node,
++						       &bfqd->burst_list);
++			}
++		}
++	} else {
++		/* If the queue was seeky for too long, break it apart. */
++		if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) {
++			bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq");
++			bfqq = bfq_split_bfqq(bic, bfqq);
++			split = true;
++			if (!bfqq)
++				goto new_queue;
+ 		}
+ 	}
+ 
+@@ -3142,6 +3778,26 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
+ 	rq->elv.priv[0] = bic;
+ 	rq->elv.priv[1] = bfqq;
+ 
++	/*
++	 * If a bfq_queue has only one process reference, it is owned
++	 * by only one bfq_io_cq: we can set the bic field of the
++	 * bfq_queue to the address of that structure. Also, if the
++	 * queue has just been split, mark a flag so that the
++	 * information is available to the other scheduler hooks.
++	 */
++	if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) {
++		bfqq->bic = bic;
++		if (split) {
++			bfq_mark_bfqq_just_split(bfqq);
++			/*
++			 * If the queue has just been split from a shared
++			 * queue, restore the idle window and the possible
++			 * weight raising period.
++			 */
++			bfq_bfqq_resume_state(bfqq, bic);
++		}
++	}
++
+ 	spin_unlock_irqrestore(q->queue_lock, flags);
+ 
+ 	return 0;
+@@ -3295,6 +3951,7 @@ static void bfq_init_root_group(struct bfq_group *root_group,
+ 	root_group->my_entity = NULL;
+ 	root_group->bfqd = bfqd;
+ #endif
++	root_group->rq_pos_tree = RB_ROOT;
+ 	for (i = 0; i < BFQ_IOPRIO_CLASSES; i++)
+ 		root_group->sched_data.service_tree[i] = BFQ_SERVICE_TREE_INIT;
+ }
+@@ -3375,6 +4032,8 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ 	bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
+ 	bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
+ 
++	bfqd->bfq_coop_thresh = 2;
++	bfqd->bfq_failed_cooperations = 7000;
+ 	bfqd->bfq_requests_within_timer = 120;
+ 
+ 	bfqd->bfq_large_burst_thresh = 11;
+diff --git a/block/bfq.h b/block/bfq.h
+index 2bf54ae..fcce855 100644
+--- a/block/bfq.h
++++ b/block/bfq.h
+@@ -183,6 +183,8 @@ struct bfq_group;
+  *                    ioprio_class value.
+  * @new_bfqq: shared bfq_queue if queue is cooperating with
+  *           one or more other queues.
++ * @pos_node: request-position tree member (see bfq_group's @rq_pos_tree).
++ * @pos_root: request-position tree root (see bfq_group's @rq_pos_tree).
+  * @sort_list: sorted list of pending requests.
+  * @next_rq: if fifo isn't expired, next request to serve.
+  * @queued: nr of requests queued in @sort_list.
+@@ -304,6 +306,26 @@ struct bfq_ttime {
+  * @ttime: associated @bfq_ttime struct
+  * @ioprio: per (request_queue, blkcg) ioprio.
+  * @blkcg_id: id of the blkcg the related io_cq belongs to.
++ * @wr_time_left: snapshot of the time left before weight raising ends
++ *                for the sync queue associated to this process; this
++ *		  snapshot is taken to remember this value while the weight
++ *		  raising is suspended because the queue is merged with a
++ *		  shared queue, and is used to set @raising_cur_max_time
++ *		  when the queue is split from the shared queue and its
++ *		  weight is raised again
++ * @saved_idle_window: same purpose as the previous field for the idle
++ *                     window
++ * @saved_IO_bound: same purpose as the previous two fields for the I/O
++ *                  bound classification of a queue
++ * @saved_in_large_burst: same purpose as the previous fields for the
++ *                        value of the field keeping the queue's belonging
++ *                        to a large burst
++ * @was_in_burst_list: true if the queue belonged to a burst list
++ *                     before its merge with another cooperating queue
++ * @cooperations: counter of consecutive successful queue merges underwent
++ *                by any of the process' @bfq_queues
++ * @failed_cooperations: counter of consecutive failed queue merges of any
++ *                       of the process' @bfq_queues
+  */
+ struct bfq_io_cq {
+ 	struct io_cq icq; /* must be the first member */
+@@ -314,6 +336,16 @@ struct bfq_io_cq {
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	uint64_t blkcg_id; /* the current blkcg ID */
+ #endif
++
++	unsigned int wr_time_left;
++	bool saved_idle_window;
++	bool saved_IO_bound;
++
++	bool saved_in_large_burst;
++	bool was_in_burst_list;
++
++	unsigned int cooperations;
++	unsigned int failed_cooperations;
+ };
+ 
+ enum bfq_device_speed {
+@@ -557,6 +589,9 @@ enum bfqq_state_flags {
+ 					 * may need softrt-next-start
+ 					 * update
+ 					 */
++	BFQ_BFQQ_FLAG_coop,		/* bfqq is shared */
++	BFQ_BFQQ_FLAG_split_coop,	/* shared bfqq will be split */
++	BFQ_BFQQ_FLAG_just_split,	/* queue has just been split */
+ };
+ 
+ #define BFQ_BFQQ_FNS(name)						\
+@@ -583,6 +618,9 @@ BFQ_BFQQ_FNS(budget_new);
+ BFQ_BFQQ_FNS(IO_bound);
+ BFQ_BFQQ_FNS(in_large_burst);
+ BFQ_BFQQ_FNS(constantly_seeky);
++BFQ_BFQQ_FNS(coop);
++BFQ_BFQQ_FNS(split_coop);
++BFQ_BFQQ_FNS(just_split);
+ BFQ_BFQQ_FNS(softrt_update);
+ #undef BFQ_BFQQ_FNS
+ 
+@@ -675,6 +713,9 @@ struct bfq_group_data {
+  *                   are groups with more than one active @bfq_entity
+  *                   (see the comments to the function
+  *                   bfq_bfqq_must_not_expire()).
++ * @rq_pos_tree: rbtree sorted by next_request position, used when
++ *               determining if two or more queues have interleaving
++ *               requests (see bfq_find_close_cooperator()).
+  *
+  * Each (device, cgroup) pair has its own bfq_group, i.e., for each cgroup
+  * there is a set of bfq_groups, each one collecting the lower-level
+@@ -701,6 +742,8 @@ struct bfq_group {
+ 
+ 	int active_entities;
+ 
++	struct rb_root rq_pos_tree;
++
+ 	struct bfqg_stats stats;
+ 	struct bfqg_stats dead_stats;	/* stats pushed from dead children */
+ };
+@@ -711,6 +754,8 @@ struct bfq_group {
+ 
+ 	struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
+ 	struct bfq_queue *async_idle_bfqq;
++
++	struct rb_root rq_pos_tree;
+ };
+ #endif
+ 
+@@ -787,6 +832,27 @@ static void bfq_put_bfqd_unlock(struct bfq_data *bfqd, unsigned long *flags)
+ 	spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
+ }
+ 
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++
++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq)
++{
++	struct bfq_entity *group_entity = bfqq->entity.parent;
++
++	if (!group_entity)
++		group_entity = &bfqq->bfqd->root_group->entity;
++
++	return container_of(group_entity, struct bfq_group, entity);
++}
++
++#else
++
++static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq)
++{
++	return bfqq->bfqd->root_group;
++}
++
++#endif
++
+ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio);
+ static void bfq_put_queue(struct bfq_queue *bfqq);
+ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
+-- 
+2.7.4 (Apple Git-66)
+

diff --git a/5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1 b/5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1
new file mode 100644
index 0000000..62cdd1a
--- /dev/null
+++ b/5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1
@@ -0,0 +1,7392 @@
+From ec8981e245dfe24bc6a80207e832ca9be18fd39d Mon Sep 17 00:00:00 2001
+From: Paolo Valente <paolo.valente@linaro.org>
+Date: Tue, 17 May 2016 08:28:04 +0200
+Subject: [PATCH 4/4] Turn BFQ-v7r11 into BFQ-v8r4 for 4.8.0
+
+Signed-off-by: Paolo Valente <paolo.valente@linaro.org>
+---
+ block/Kconfig.iosched |    2 +-
+ block/bfq-cgroup.c    |  495 ++++----
+ block/bfq-iosched.c   | 3230 +++++++++++++++++++++++++++++++------------------
+ block/bfq-sched.c     |  480 ++++++--
+ block/bfq.h           |  747 ++++++------
+ 5 files changed, 3073 insertions(+), 1881 deletions(-)
+
+diff --git a/block/Kconfig.iosched b/block/Kconfig.iosched
+index f78cd1a..6d92579 100644
+--- a/block/Kconfig.iosched
++++ b/block/Kconfig.iosched
+@@ -53,7 +53,7 @@ config IOSCHED_BFQ
+ 
+ config BFQ_GROUP_IOSCHED
+ 	bool "BFQ hierarchical scheduling support"
+-	depends on CGROUPS && IOSCHED_BFQ=y
++	depends on IOSCHED_BFQ && BLK_CGROUP
+ 	default n
+ 	---help---
+ 	  Enable hierarchical scheduling in BFQ, using the blkio controller.
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 0367996..b50ae8e 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -7,7 +7,9 @@
+  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+  *		      Paolo Valente <paolo.valente@unimore.it>
+  *
+- * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+  *
+  * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
+  * file.
+@@ -163,8 +165,6 @@ static struct bfq_group *blkg_to_bfqg(struct blkcg_gq *blkg)
+ {
+ 	struct blkg_policy_data *pd = blkg_to_pd(blkg, &blkcg_policy_bfq);
+ 
+-	BUG_ON(!pd);
+-
+ 	return pd_to_bfqg(pd);
+ }
+ 
+@@ -208,59 +208,49 @@ static void bfqg_put(struct bfq_group *bfqg)
+ 
+ static void bfqg_stats_update_io_add(struct bfq_group *bfqg,
+ 				     struct bfq_queue *bfqq,
+-				     int rw)
++				     int op, int op_flags)
+ {
+-	blkg_rwstat_add(&bfqg->stats.queued, rw, 1);
++	blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, 1);
+ 	bfqg_stats_end_empty_time(&bfqg->stats);
+ 	if (!(bfqq == ((struct bfq_data *)bfqg->bfqd)->in_service_queue))
+ 		bfqg_stats_set_start_group_wait_time(bfqg, bfqq_group(bfqq));
+ }
+ 
+-static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int rw)
+-{
+-	blkg_rwstat_add(&bfqg->stats.queued, rw, -1);
+-}
+-
+-static void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw)
++static void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op,
++					int op_flags)
+ {
+-	blkg_rwstat_add(&bfqg->stats.merged, rw, 1);
++	blkg_rwstat_add(&bfqg->stats.queued, op, op_flags, -1);
+ }
+ 
+-static void bfqg_stats_update_dispatch(struct bfq_group *bfqg,
+-					      uint64_t bytes, int rw)
++static void bfqg_stats_update_io_merged(struct bfq_group *bfqg,  int op,
++					int op_flags)
+ {
+-	blkg_stat_add(&bfqg->stats.sectors, bytes >> 9);
+-	blkg_rwstat_add(&bfqg->stats.serviced, rw, 1);
+-	blkg_rwstat_add(&bfqg->stats.service_bytes, rw, bytes);
++	blkg_rwstat_add(&bfqg->stats.merged, op, op_flags, 1);
+ }
+ 
+ static void bfqg_stats_update_completion(struct bfq_group *bfqg,
+-			uint64_t start_time, uint64_t io_start_time, int rw)
++			uint64_t start_time, uint64_t io_start_time, int op,
++			int op_flags)
+ {
+ 	struct bfqg_stats *stats = &bfqg->stats;
+ 	unsigned long long now = sched_clock();
+ 
+ 	if (time_after64(now, io_start_time))
+-		blkg_rwstat_add(&stats->service_time, rw, now - io_start_time);
++		blkg_rwstat_add(&stats->service_time, op, op_flags,
++				now - io_start_time);
+ 	if (time_after64(io_start_time, start_time))
+-		blkg_rwstat_add(&stats->wait_time, rw,
++		blkg_rwstat_add(&stats->wait_time, op, op_flags,
+ 				io_start_time - start_time);
+ }
+ 
+ /* @stats = 0 */
+ static void bfqg_stats_reset(struct bfqg_stats *stats)
+ {
+-	if (!stats)
+-		return;
+-
+ 	/* queued stats shouldn't be cleared */
+-	blkg_rwstat_reset(&stats->service_bytes);
+-	blkg_rwstat_reset(&stats->serviced);
+ 	blkg_rwstat_reset(&stats->merged);
+ 	blkg_rwstat_reset(&stats->service_time);
+ 	blkg_rwstat_reset(&stats->wait_time);
+ 	blkg_stat_reset(&stats->time);
+-	blkg_stat_reset(&stats->unaccounted_time);
+ 	blkg_stat_reset(&stats->avg_queue_size_sum);
+ 	blkg_stat_reset(&stats->avg_queue_size_samples);
+ 	blkg_stat_reset(&stats->dequeue);
+@@ -270,19 +260,16 @@ static void bfqg_stats_reset(struct bfqg_stats *stats)
+ }
+ 
+ /* @to += @from */
+-static void bfqg_stats_merge(struct bfqg_stats *to, struct bfqg_stats *from)
++static void bfqg_stats_add_aux(struct bfqg_stats *to, struct bfqg_stats *from)
+ {
+ 	if (!to || !from)
+ 		return;
+ 
+ 	/* queued stats shouldn't be cleared */
+-	blkg_rwstat_add_aux(&to->service_bytes, &from->service_bytes);
+-	blkg_rwstat_add_aux(&to->serviced, &from->serviced);
+ 	blkg_rwstat_add_aux(&to->merged, &from->merged);
+ 	blkg_rwstat_add_aux(&to->service_time, &from->service_time);
+ 	blkg_rwstat_add_aux(&to->wait_time, &from->wait_time);
+ 	blkg_stat_add_aux(&from->time, &from->time);
+-	blkg_stat_add_aux(&to->unaccounted_time, &from->unaccounted_time);
+ 	blkg_stat_add_aux(&to->avg_queue_size_sum, &from->avg_queue_size_sum);
+ 	blkg_stat_add_aux(&to->avg_queue_size_samples,
+ 			  &from->avg_queue_size_samples);
+@@ -311,10 +298,8 @@ static void bfqg_stats_xfer_dead(struct bfq_group *bfqg)
+ 	if (unlikely(!parent))
+ 		return;
+ 
+-	bfqg_stats_merge(&parent->dead_stats, &bfqg->stats);
+-	bfqg_stats_merge(&parent->dead_stats, &bfqg->dead_stats);
++	bfqg_stats_add_aux(&parent->stats, &bfqg->stats);
+ 	bfqg_stats_reset(&bfqg->stats);
+-	bfqg_stats_reset(&bfqg->dead_stats);
+ }
+ 
+ static void bfq_init_entity(struct bfq_entity *entity,
+@@ -335,15 +320,11 @@ static void bfq_init_entity(struct bfq_entity *entity,
+ 
+ static void bfqg_stats_exit(struct bfqg_stats *stats)
+ {
+-	blkg_rwstat_exit(&stats->service_bytes);
+-	blkg_rwstat_exit(&stats->serviced);
+ 	blkg_rwstat_exit(&stats->merged);
+ 	blkg_rwstat_exit(&stats->service_time);
+ 	blkg_rwstat_exit(&stats->wait_time);
+ 	blkg_rwstat_exit(&stats->queued);
+-	blkg_stat_exit(&stats->sectors);
+ 	blkg_stat_exit(&stats->time);
+-	blkg_stat_exit(&stats->unaccounted_time);
+ 	blkg_stat_exit(&stats->avg_queue_size_sum);
+ 	blkg_stat_exit(&stats->avg_queue_size_samples);
+ 	blkg_stat_exit(&stats->dequeue);
+@@ -354,15 +335,11 @@ static void bfqg_stats_exit(struct bfqg_stats *stats)
+ 
+ static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
+ {
+-	if (blkg_rwstat_init(&stats->service_bytes, gfp) ||
+-	    blkg_rwstat_init(&stats->serviced, gfp) ||
+-	    blkg_rwstat_init(&stats->merged, gfp) ||
++	if (blkg_rwstat_init(&stats->merged, gfp) ||
+ 	    blkg_rwstat_init(&stats->service_time, gfp) ||
+ 	    blkg_rwstat_init(&stats->wait_time, gfp) ||
+ 	    blkg_rwstat_init(&stats->queued, gfp) ||
+-	    blkg_stat_init(&stats->sectors, gfp) ||
+ 	    blkg_stat_init(&stats->time, gfp) ||
+-	    blkg_stat_init(&stats->unaccounted_time, gfp) ||
+ 	    blkg_stat_init(&stats->avg_queue_size_sum, gfp) ||
+ 	    blkg_stat_init(&stats->avg_queue_size_samples, gfp) ||
+ 	    blkg_stat_init(&stats->dequeue, gfp) ||
+@@ -386,11 +363,27 @@ static struct bfq_group_data *blkcg_to_bfqgd(struct blkcg *blkcg)
+ 	return cpd_to_bfqgd(blkcg_to_cpd(blkcg, &blkcg_policy_bfq));
+ }
+ 
++static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp)
++{
++	struct bfq_group_data *bgd;
++
++	bgd = kzalloc(sizeof(*bgd), GFP_KERNEL);
++	if (!bgd)
++		return NULL;
++	return &bgd->pd;
++}
++
+ static void bfq_cpd_init(struct blkcg_policy_data *cpd)
+ {
+ 	struct bfq_group_data *d = cpd_to_bfqgd(cpd);
+ 
+-	d->weight = BFQ_DEFAULT_GRP_WEIGHT;
++	d->weight = cgroup_subsys_on_dfl(io_cgrp_subsys) ?
++		CGROUP_WEIGHT_DFL : BFQ_WEIGHT_LEGACY_DFL;
++}
++
++static void bfq_cpd_free(struct blkcg_policy_data *cpd)
++{
++	kfree(cpd_to_bfqgd(cpd));
+ }
+ 
+ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node)
+@@ -401,8 +394,7 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node)
+ 	if (!bfqg)
+ 		return NULL;
+ 
+-	if (bfqg_stats_init(&bfqg->stats, gfp) ||
+-	    bfqg_stats_init(&bfqg->dead_stats, gfp)) {
++	if (bfqg_stats_init(&bfqg->stats, gfp)) {
+ 		kfree(bfqg);
+ 		return NULL;
+ 	}
+@@ -410,27 +402,20 @@ static struct blkg_policy_data *bfq_pd_alloc(gfp_t gfp, int node)
+ 	return &bfqg->pd;
+ }
+ 
+-static void bfq_group_set_parent(struct bfq_group *bfqg,
+-					struct bfq_group *parent)
++static void bfq_pd_init(struct blkg_policy_data *pd)
+ {
++	struct blkcg_gq *blkg;
++	struct bfq_group *bfqg;
++	struct bfq_data *bfqd;
+ 	struct bfq_entity *entity;
++	struct bfq_group_data *d;
+ 
+-	BUG_ON(!parent);
+-	BUG_ON(!bfqg);
+-	BUG_ON(bfqg == parent);
+-
++	blkg = pd_to_blkg(pd);
++	BUG_ON(!blkg);
++	bfqg = blkg_to_bfqg(blkg);
++	bfqd = blkg->q->elevator->elevator_data;
+ 	entity = &bfqg->entity;
+-	entity->parent = parent->my_entity;
+-	entity->sched_data = &parent->sched_data;
+-}
+-
+-static void bfq_pd_init(struct blkg_policy_data *pd)
+-{
+-	struct blkcg_gq *blkg = pd_to_blkg(pd);
+-	struct bfq_group *bfqg = blkg_to_bfqg(blkg);
+-	struct bfq_data *bfqd = blkg->q->elevator->elevator_data;
+-	struct bfq_entity *entity = &bfqg->entity;
+-	struct bfq_group_data *d = blkcg_to_bfqgd(blkg->blkcg);
++	d = blkcg_to_bfqgd(blkg->blkcg);
+ 
+ 	entity->orig_weight = entity->weight = entity->new_weight = d->weight;
+ 	entity->my_sched_data = &bfqg->sched_data;
+@@ -448,70 +433,53 @@ static void bfq_pd_free(struct blkg_policy_data *pd)
+ 	struct bfq_group *bfqg = pd_to_bfqg(pd);
+ 
+ 	bfqg_stats_exit(&bfqg->stats);
+-	bfqg_stats_exit(&bfqg->dead_stats);
+-
+ 	return kfree(bfqg);
+ }
+ 
+-/* offset delta from bfqg->stats to bfqg->dead_stats */
+-static const int dead_stats_off_delta = offsetof(struct bfq_group, dead_stats) -
+-					offsetof(struct bfq_group, stats);
+-
+-/* to be used by recursive prfill, sums live and dead stats recursively */
+-static u64 bfqg_stat_pd_recursive_sum(struct blkg_policy_data *pd, int off)
++static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
+ {
+-	u64 sum = 0;
++	struct bfq_group *bfqg = pd_to_bfqg(pd);
+ 
+-	sum += blkg_stat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, off);
+-	sum += blkg_stat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq,
+-				       off + dead_stats_off_delta);
+-	return sum;
++	bfqg_stats_reset(&bfqg->stats);
+ }
+ 
+-/* to be used by recursive prfill, sums live and dead rwstats recursively */
+-static struct blkg_rwstat
+-bfqg_rwstat_pd_recursive_sum(struct blkg_policy_data *pd, int off)
++static void bfq_group_set_parent(struct bfq_group *bfqg,
++					struct bfq_group *parent)
+ {
+-	struct blkg_rwstat a, b;
++	struct bfq_entity *entity;
+ 
+-	a = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq, off);
+-	b = blkg_rwstat_recursive_sum(pd_to_blkg(pd), &blkcg_policy_bfq,
+-				      off + dead_stats_off_delta);
+-	blkg_rwstat_add_aux(&a, &b);
+-	return a;
++	BUG_ON(!parent);
++	BUG_ON(!bfqg);
++	BUG_ON(bfqg == parent);
++
++	entity = &bfqg->entity;
++	entity->parent = parent->my_entity;
++	entity->sched_data = &parent->sched_data;
+ }
+ 
+-static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
++static struct bfq_group *bfq_lookup_bfqg(struct bfq_data *bfqd,
++					 struct blkcg *blkcg)
+ {
+-	struct bfq_group *bfqg = pd_to_bfqg(pd);
++	struct blkcg_gq *blkg;
+ 
+-	bfqg_stats_reset(&bfqg->stats);
+-	bfqg_stats_reset(&bfqg->dead_stats);
++	blkg = blkg_lookup(blkcg, bfqd->queue);
++	if (likely(blkg))
++		return blkg_to_bfqg(blkg);
++	return NULL;
+ }
+ 
+-static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
+-					      struct blkcg *blkcg)
++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
++					    struct blkcg *blkcg)
+ {
+-	struct request_queue *q = bfqd->queue;
+-	struct bfq_group *bfqg = NULL, *parent;
+-	struct bfq_entity *entity = NULL;
++	struct bfq_group *bfqg, *parent;
++	struct bfq_entity *entity;
+ 
+ 	assert_spin_locked(bfqd->queue->queue_lock);
+ 
+-	/* avoid lookup for the common case where there's no blkcg */
+-	if (blkcg == &blkcg_root) {
+-		bfqg = bfqd->root_group;
+-	} else {
+-		struct blkcg_gq *blkg;
+-
+-		blkg = blkg_lookup_create(blkcg, q);
+-		if (!IS_ERR(blkg))
+-			bfqg = blkg_to_bfqg(blkg);
+-		else /* fallback to root_group */
+-			bfqg = bfqd->root_group;
+-	}
++	bfqg = bfq_lookup_bfqg(bfqd, blkcg);
+ 
+-	BUG_ON(!bfqg);
++	if (unlikely(!bfqg))
++		return NULL;
+ 
+ 	/*
+ 	 * Update chain of bfq_groups as we might be handling a leaf group
+@@ -537,11 +505,15 @@ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
+ static void bfq_pos_tree_add_move(struct bfq_data *bfqd,
+ 				  struct bfq_queue *bfqq);
+ 
++static void bfq_bfqq_expire(struct bfq_data *bfqd,
++			    struct bfq_queue *bfqq,
++			    bool compensate,
++			    enum bfqq_expiration reason);
++
+ /**
+  * bfq_bfqq_move - migrate @bfqq to @bfqg.
+  * @bfqd: queue descriptor.
+  * @bfqq: the queue to move.
+- * @entity: @bfqq's entity.
+  * @bfqg: the group to move to.
+  *
+  * Move @bfqq to @bfqg, deactivating it from its old group and reactivating
+@@ -552,26 +524,40 @@ static void bfq_pos_tree_add_move(struct bfq_data *bfqd,
+  * rcu_read_lock()).
+  */
+ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+-			  struct bfq_entity *entity, struct bfq_group *bfqg)
++			  struct bfq_group *bfqg)
+ {
+-	int busy, resume;
+-
+-	busy = bfq_bfqq_busy(bfqq);
+-	resume = !RB_EMPTY_ROOT(&bfqq->sort_list);
++	struct bfq_entity *entity = &bfqq->entity;
+ 
+-	BUG_ON(resume && !entity->on_st);
+-	BUG_ON(busy && !resume && entity->on_st &&
++	BUG_ON(!bfq_bfqq_busy(bfqq) && !RB_EMPTY_ROOT(&bfqq->sort_list));
++	BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list) && !entity->on_st);
++	BUG_ON(bfq_bfqq_busy(bfqq) && RB_EMPTY_ROOT(&bfqq->sort_list)
++	       && entity->on_st &&
+ 	       bfqq != bfqd->in_service_queue);
++	BUG_ON(!bfq_bfqq_busy(bfqq) && bfqq == bfqd->in_service_queue);
+ 
+-	if (busy) {
+-		BUG_ON(atomic_read(&bfqq->ref) < 2);
++	/* If bfqq is empty, then bfq_bfqq_expire also invokes
++	 * bfq_del_bfqq_busy, thereby removing bfqq and its entity
++	 * from data structures related to current group. Otherwise we
++	 * need to remove bfqq explicitly with bfq_deactivate_bfqq, as
++	 * we do below.
++	 */
++	if (bfqq == bfqd->in_service_queue)
++		bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
++				false, BFQ_BFQQ_PREEMPTED);
++
++	BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq)
++	    && &bfq_entity_service_tree(entity)->idle !=
++	       entity->tree);
++
++	BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq));
+ 
+-		if (!resume)
+-			bfq_del_bfqq_busy(bfqd, bfqq, 0);
+-		else
+-			bfq_deactivate_bfqq(bfqd, bfqq, 0);
+-	} else if (entity->on_st)
++	if (bfq_bfqq_busy(bfqq))
++		bfq_deactivate_bfqq(bfqd, bfqq, 0);
++	else if (entity->on_st) {
++		BUG_ON(&bfq_entity_service_tree(entity)->idle !=
++		       entity->tree);
+ 		bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
++	}
+ 	bfqg_put(bfqq_group(bfqq));
+ 
+ 	/*
+@@ -583,14 +569,17 @@ static void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	entity->sched_data = &bfqg->sched_data;
+ 	bfqg_get(bfqg);
+ 
+-	if (busy) {
++	BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list) && bfq_bfqq_busy(bfqq));
++	if (bfq_bfqq_busy(bfqq)) {
+ 		bfq_pos_tree_add_move(bfqd, bfqq);
+-		if (resume)
+-			bfq_activate_bfqq(bfqd, bfqq);
++		bfq_activate_bfqq(bfqd, bfqq);
+ 	}
+ 
+ 	if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
+ 		bfq_schedule_dispatch(bfqd);
++	BUG_ON(entity->on_st && !bfq_bfqq_busy(bfqq)
++	       && &bfq_entity_service_tree(entity)->idle !=
++	       entity->tree);
+ }
+ 
+ /**
+@@ -617,7 +606,11 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
+ 
+ 	lockdep_assert_held(bfqd->queue->queue_lock);
+ 
+-	bfqg = bfq_find_alloc_group(bfqd, blkcg);
++	bfqg = bfq_find_set_group(bfqd, blkcg);
++
++	if (unlikely(!bfqg))
++		bfqg = bfqd->root_group;
++
+ 	if (async_bfqq) {
+ 		entity = &async_bfqq->entity;
+ 
+@@ -625,7 +618,8 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
+ 			bic_set_bfqq(bic, NULL, 0);
+ 			bfq_log_bfqq(bfqd, async_bfqq,
+ 				     "bic_change_group: %p %d",
+-				     async_bfqq, atomic_read(&async_bfqq->ref));
++				     async_bfqq,
++				     async_bfqq->ref);
+ 			bfq_put_queue(async_bfqq);
+ 		}
+ 	}
+@@ -633,7 +627,7 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
+ 	if (sync_bfqq) {
+ 		entity = &sync_bfqq->entity;
+ 		if (entity->sched_data != &bfqg->sched_data)
+-			bfq_bfqq_move(bfqd, sync_bfqq, entity, bfqg);
++			bfq_bfqq_move(bfqd, sync_bfqq, bfqg);
+ 	}
+ 
+ 	return bfqg;
+@@ -642,25 +636,23 @@ static struct bfq_group *__bfq_bic_change_cgroup(struct bfq_data *bfqd,
+ static void bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
+ {
+ 	struct bfq_data *bfqd = bic_to_bfqd(bic);
+-	struct blkcg *blkcg;
+ 	struct bfq_group *bfqg = NULL;
+-	uint64_t id;
++	uint64_t serial_nr;
+ 
+ 	rcu_read_lock();
+-	blkcg = bio_blkcg(bio);
+-	id = blkcg->css.serial_nr;
+-	rcu_read_unlock();
++	serial_nr = bio_blkcg(bio)->css.serial_nr;
+ 
+ 	/*
+ 	 * Check whether blkcg has changed.  The condition may trigger
+ 	 * spuriously on a newly created cic but there's no harm.
+ 	 */
+-	if (unlikely(!bfqd) || likely(bic->blkcg_id == id))
+-		return;
++	if (unlikely(!bfqd) || likely(bic->blkcg_serial_nr == serial_nr))
++		goto out;
+ 
+-	bfqg = __bfq_bic_change_cgroup(bfqd, bic, blkcg);
+-	BUG_ON(!bfqg);
+-	bic->blkcg_id = id;
++	bfqg = __bfq_bic_change_cgroup(bfqd, bic, bio_blkcg(bio));
++	bic->blkcg_serial_nr = serial_nr;
++out:
++	rcu_read_unlock();
+ }
+ 
+ /**
+@@ -686,7 +678,7 @@ static void bfq_reparent_leaf_entity(struct bfq_data *bfqd,
+ 	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
+ 
+ 	BUG_ON(!bfqq);
+-	bfq_bfqq_move(bfqd, bfqq, entity, bfqd->root_group);
++	bfq_bfqq_move(bfqd, bfqq, bfqd->root_group);
+ }
+ 
+ /**
+@@ -717,11 +709,12 @@ static void bfq_reparent_active_entities(struct bfq_data *bfqd,
+ }
+ 
+ /**
+- * bfq_destroy_group - destroy @bfqg.
+- * @bfqg: the group being destroyed.
++ * bfq_pd_offline - deactivate the entity associated with @pd,
++ *		    and reparent its children entities.
++ * @pd: descriptor of the policy going offline.
+  *
+- * Destroy @bfqg, making sure that it is not referenced from its parent.
+- * blkio already grabs the queue_lock for us, so no need to use RCU-based magic
++ * blkio already grabs the queue_lock for us, so no need to use
++ * RCU-based magic
+  */
+ static void bfq_pd_offline(struct blkg_policy_data *pd)
+ {
+@@ -780,6 +773,12 @@ static void bfq_pd_offline(struct blkg_policy_data *pd)
+ 	bfq_put_async_queues(bfqd, bfqg);
+ 	BUG_ON(entity->tree);
+ 
++	/*
++	 * @blkg is going offline and will be ignored by
++	 * blkg_[rw]stat_recursive_sum().  Transfer stats to the parent so
++	 * that they don't get lost.  If IOs complete after this point, the
++	 * stats for them will be lost.  Oh well...
++	 */
+ 	bfqg_stats_xfer_dead(bfqg);
+ }
+ 
+@@ -789,46 +788,35 @@ static void bfq_end_wr_async(struct bfq_data *bfqd)
+ 
+ 	list_for_each_entry(blkg, &bfqd->queue->blkg_list, q_node) {
+ 		struct bfq_group *bfqg = blkg_to_bfqg(blkg);
++		BUG_ON(!bfqg);
+ 
+ 		bfq_end_wr_async_queues(bfqd, bfqg);
+ 	}
+ 	bfq_end_wr_async_queues(bfqd, bfqd->root_group);
+ }
+ 
+-static u64 bfqio_cgroup_weight_read(struct cgroup_subsys_state *css,
+-				       struct cftype *cftype)
+-{
+-	struct blkcg *blkcg = css_to_blkcg(css);
+-	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
+-	int ret = -EINVAL;
+-
+-	spin_lock_irq(&blkcg->lock);
+-	ret = bfqgd->weight;
+-	spin_unlock_irq(&blkcg->lock);
+-
+-	return ret;
+-}
+-
+-static int bfqio_cgroup_weight_read_dfl(struct seq_file *sf, void *v)
++static int bfq_io_show_weight(struct seq_file *sf, void *v)
+ {
+ 	struct blkcg *blkcg = css_to_blkcg(seq_css(sf));
+ 	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
++	unsigned int val = 0;
+ 
+-	spin_lock_irq(&blkcg->lock);
+-	seq_printf(sf, "%u\n", bfqgd->weight);
+-	spin_unlock_irq(&blkcg->lock);
++	if (bfqgd)
++		val = bfqgd->weight;
++
++	seq_printf(sf, "%u\n", val);
+ 
+ 	return 0;
+ }
+ 
+-static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css,
+-					struct cftype *cftype,
+-					u64 val)
++static int bfq_io_set_weight_legacy(struct cgroup_subsys_state *css,
++				    struct cftype *cftype,
++				    u64 val)
+ {
+ 	struct blkcg *blkcg = css_to_blkcg(css);
+ 	struct bfq_group_data *bfqgd = blkcg_to_bfqgd(blkcg);
+ 	struct blkcg_gq *blkg;
+-	int ret = -EINVAL;
++	int ret = -ERANGE;
+ 
+ 	if (val < BFQ_MIN_WEIGHT || val > BFQ_MAX_WEIGHT)
+ 		return ret;
+@@ -873,13 +861,18 @@ static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css,
+ 	return ret;
+ }
+ 
+-static ssize_t bfqio_cgroup_weight_write_dfl(struct kernfs_open_file *of,
+-					     char *buf, size_t nbytes,
+-					     loff_t off)
++static ssize_t bfq_io_set_weight(struct kernfs_open_file *of,
++				 char *buf, size_t nbytes,
++				 loff_t off)
+ {
++	u64 weight;
+ 	/* First unsigned long found in the file is used */
+-	return bfqio_cgroup_weight_write(of_css(of), NULL,
+-					 simple_strtoull(strim(buf), NULL, 0));
++	int ret = kstrtoull(strim(buf), 0, &weight);
++
++	if (ret)
++		return ret;
++
++	return bfq_io_set_weight_legacy(of_css(of), NULL, weight);
+ }
+ 
+ static int bfqg_print_stat(struct seq_file *sf, void *v)
+@@ -899,16 +892,17 @@ static int bfqg_print_rwstat(struct seq_file *sf, void *v)
+ static u64 bfqg_prfill_stat_recursive(struct seq_file *sf,
+ 				      struct blkg_policy_data *pd, int off)
+ {
+-	u64 sum = bfqg_stat_pd_recursive_sum(pd, off);
+-
++	u64 sum = blkg_stat_recursive_sum(pd_to_blkg(pd),
++					  &blkcg_policy_bfq, off);
+ 	return __blkg_prfill_u64(sf, pd, sum);
+ }
+ 
+ static u64 bfqg_prfill_rwstat_recursive(struct seq_file *sf,
+ 					struct blkg_policy_data *pd, int off)
+ {
+-	struct blkg_rwstat sum = bfqg_rwstat_pd_recursive_sum(pd, off);
+-
++	struct blkg_rwstat sum = blkg_rwstat_recursive_sum(pd_to_blkg(pd),
++							   &blkcg_policy_bfq,
++							   off);
+ 	return __blkg_prfill_rwstat(sf, pd, &sum);
+ }
+ 
+@@ -928,6 +922,41 @@ static int bfqg_print_rwstat_recursive(struct seq_file *sf, void *v)
+ 	return 0;
+ }
+ 
++static u64 bfqg_prfill_sectors(struct seq_file *sf, struct blkg_policy_data *pd,
++			       int off)
++{
++	u64 sum = blkg_rwstat_total(&pd->blkg->stat_bytes);
++
++	return __blkg_prfill_u64(sf, pd, sum >> 9);
++}
++
++static int bfqg_print_stat_sectors(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
++			  bfqg_prfill_sectors, &blkcg_policy_bfq, 0, false);
++	return 0;
++}
++
++static u64 bfqg_prfill_sectors_recursive(struct seq_file *sf,
++					 struct blkg_policy_data *pd, int off)
++{
++	struct blkg_rwstat tmp = blkg_rwstat_recursive_sum(pd->blkg, NULL,
++					offsetof(struct blkcg_gq, stat_bytes));
++	u64 sum = atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_READ]) +
++		atomic64_read(&tmp.aux_cnt[BLKG_RWSTAT_WRITE]);
++
++	return __blkg_prfill_u64(sf, pd, sum >> 9);
++}
++
++static int bfqg_print_stat_sectors_recursive(struct seq_file *sf, void *v)
++{
++	blkcg_print_blkgs(sf, css_to_blkcg(seq_css(sf)),
++			  bfqg_prfill_sectors_recursive, &blkcg_policy_bfq, 0,
++			  false);
++	return 0;
++}
++
++
+ static u64 bfqg_prfill_avg_queue_size(struct seq_file *sf,
+ 				      struct blkg_policy_data *pd, int off)
+ {
+@@ -964,38 +993,15 @@ bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
+ 	return blkg_to_bfqg(bfqd->queue->root_blkg);
+ }
+ 
+-static struct blkcg_policy_data *bfq_cpd_alloc(gfp_t gfp)
+-{
+-	struct bfq_group_data *bgd;
+-
+-	bgd = kzalloc(sizeof(*bgd), GFP_KERNEL);
+-	if (!bgd)
+-		return NULL;
+-	return &bgd->pd;
+-}
+-
+-static void bfq_cpd_free(struct blkcg_policy_data *cpd)
+-{
+-	kfree(cpd_to_bfqgd(cpd));
+-}
+-
+-static struct cftype bfqio_files_dfl[] = {
++static struct cftype bfq_blkcg_legacy_files[] = {
+ 	{
+-		.name = "weight",
++		.name = "bfq.weight",
+ 		.flags = CFTYPE_NOT_ON_ROOT,
+-		.seq_show = bfqio_cgroup_weight_read_dfl,
+-		.write = bfqio_cgroup_weight_write_dfl,
++		.seq_show = bfq_io_show_weight,
++		.write_u64 = bfq_io_set_weight_legacy,
+ 	},
+-	{} /* terminate */
+-};
+ 
+-static struct cftype bfqio_files[] = {
+-	{
+-		.name = "bfq.weight",
+-		.read_u64 = bfqio_cgroup_weight_read,
+-		.write_u64 = bfqio_cgroup_weight_write,
+-	},
+-	/* statistics, cover only the tasks in the bfqg */
++	/* statistics, covers only the tasks in the bfqg */
+ 	{
+ 		.name = "bfq.time",
+ 		.private = offsetof(struct bfq_group, stats.time),
+@@ -1003,18 +1009,17 @@ static struct cftype bfqio_files[] = {
+ 	},
+ 	{
+ 		.name = "bfq.sectors",
+-		.private = offsetof(struct bfq_group, stats.sectors),
+-		.seq_show = bfqg_print_stat,
++		.seq_show = bfqg_print_stat_sectors,
+ 	},
+ 	{
+ 		.name = "bfq.io_service_bytes",
+-		.private = offsetof(struct bfq_group, stats.service_bytes),
+-		.seq_show = bfqg_print_rwstat,
++		.private = (unsigned long)&blkcg_policy_bfq,
++		.seq_show = blkg_print_stat_bytes,
+ 	},
+ 	{
+ 		.name = "bfq.io_serviced",
+-		.private = offsetof(struct bfq_group, stats.serviced),
+-		.seq_show = bfqg_print_rwstat,
++		.private = (unsigned long)&blkcg_policy_bfq,
++		.seq_show = blkg_print_stat_ios,
+ 	},
+ 	{
+ 		.name = "bfq.io_service_time",
+@@ -1045,18 +1050,17 @@ static struct cftype bfqio_files[] = {
+ 	},
+ 	{
+ 		.name = "bfq.sectors_recursive",
+-		.private = offsetof(struct bfq_group, stats.sectors),
+-		.seq_show = bfqg_print_stat_recursive,
++		.seq_show = bfqg_print_stat_sectors_recursive,
+ 	},
+ 	{
+ 		.name = "bfq.io_service_bytes_recursive",
+-		.private = offsetof(struct bfq_group, stats.service_bytes),
+-		.seq_show = bfqg_print_rwstat_recursive,
++		.private = (unsigned long)&blkcg_policy_bfq,
++		.seq_show = blkg_print_stat_bytes_recursive,
+ 	},
+ 	{
+ 		.name = "bfq.io_serviced_recursive",
+-		.private = offsetof(struct bfq_group, stats.serviced),
+-		.seq_show = bfqg_print_rwstat_recursive,
++		.private = (unsigned long)&blkcg_policy_bfq,
++		.seq_show = blkg_print_stat_ios_recursive,
+ 	},
+ 	{
+ 		.name = "bfq.io_service_time_recursive",
+@@ -1102,31 +1106,39 @@ static struct cftype bfqio_files[] = {
+ 		.private = offsetof(struct bfq_group, stats.dequeue),
+ 		.seq_show = bfqg_print_stat,
+ 	},
+-	{
+-		.name = "bfq.unaccounted_time",
+-		.private = offsetof(struct bfq_group, stats.unaccounted_time),
+-		.seq_show = bfqg_print_stat,
+-	},
+ 	{ }	/* terminate */
+ };
+ 
+-static struct blkcg_policy blkcg_policy_bfq = {
+-	.dfl_cftypes            = bfqio_files_dfl,
+-	.legacy_cftypes		= bfqio_files,
+-
+-	.pd_alloc_fn		= bfq_pd_alloc,
+-	.pd_init_fn		= bfq_pd_init,
+-	.pd_offline_fn		= bfq_pd_offline,
+-	.pd_free_fn		= bfq_pd_free,
+-	.pd_reset_stats_fn	= bfq_pd_reset_stats,
+-
+-	.cpd_alloc_fn		= bfq_cpd_alloc,
+-	.cpd_init_fn		= bfq_cpd_init,
+-	.cpd_bind_fn		= bfq_cpd_init,
+-	.cpd_free_fn		= bfq_cpd_free,
++static struct cftype bfq_blkg_files[] = {
++	{
++		.name = "bfq.weight",
++		.flags = CFTYPE_NOT_ON_ROOT,
++		.seq_show = bfq_io_show_weight,
++		.write = bfq_io_set_weight,
++	},
++	{} /* terminate */
+ };
+ 
+-#else
++#else /* CONFIG_BFQ_GROUP_IOSCHED */
++
++static inline void bfqg_stats_update_io_add(struct bfq_group *bfqg,
++			struct bfq_queue *bfqq, int op, int op_flags) { }
++static inline void
++bfqg_stats_update_io_remove(struct bfq_group *bfqg, int op, int op_flags) { }
++static inline void
++bfqg_stats_update_io_merged(struct bfq_group *bfqg, int op, int op_flags) { }
++static inline void bfqg_stats_update_completion(struct bfq_group *bfqg,
++			uint64_t start_time, uint64_t io_start_time, int op,
++			int op_flags) { }
++static inline void
++bfqg_stats_set_start_group_wait_time(struct bfq_group *bfqg,
++				     struct bfq_group *curr_bfqg) { }
++static inline void bfqg_stats_end_empty_time(struct bfqg_stats *stats) { }
++static inline void bfqg_stats_update_dequeue(struct bfq_group *bfqg) { }
++static inline void bfqg_stats_set_start_empty_time(struct bfq_group *bfqg) { }
++static inline void bfqg_stats_update_idle_time(struct bfq_group *bfqg) { }
++static inline void bfqg_stats_set_start_idle_time(struct bfq_group *bfqg) { }
++static inline void bfqg_stats_update_avg_queue_size(struct bfq_group *bfqg) { }
+ 
+ static void bfq_init_entity(struct bfq_entity *entity,
+ 			    struct bfq_group *bfqg)
+@@ -1150,27 +1162,20 @@ bfq_bic_update_cgroup(struct bfq_io_cq *bic, struct bio *bio)
+ 	return bfqd->root_group;
+ }
+ 
+-static void bfq_bfqq_move(struct bfq_data *bfqd,
+-			  struct bfq_queue *bfqq,
+-			  struct bfq_entity *entity,
+-			  struct bfq_group *bfqg)
+-{
+-}
+-
+ static void bfq_end_wr_async(struct bfq_data *bfqd)
+ {
+ 	bfq_end_wr_async_queues(bfqd, bfqd->root_group);
+ }
+ 
+-static void bfq_disconnect_groups(struct bfq_data *bfqd)
++static struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
++					    struct blkcg *blkcg)
+ {
+-	bfq_put_async_queues(bfqd, bfqd->root_group);
++	return bfqd->root_group;
+ }
+ 
+-static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
+-					      struct blkcg *blkcg)
++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
+ {
+-	return bfqd->root_group;
++	return bfqq->bfqd->root_group;
+ }
+ 
+ static struct bfq_group *
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index cf3e9b1..eef6ff4 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -7,25 +7,28 @@
+  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+  *		      Paolo Valente <paolo.valente@unimore.it>
+  *
+- * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+  *
+  * Licensed under the GPL-2 as detailed in the accompanying COPYING.BFQ
+  * file.
+  *
+- * BFQ is a proportional-share storage-I/O scheduling algorithm based on
+- * the slice-by-slice service scheme of CFQ. But BFQ assigns budgets,
+- * measured in number of sectors, to processes instead of time slices. The
+- * device is not granted to the in-service process for a given time slice,
+- * but until it has exhausted its assigned budget. This change from the time
+- * to the service domain allows BFQ to distribute the device throughput
+- * among processes as desired, without any distortion due to ZBR, workload
+- * fluctuations or other factors. BFQ uses an ad hoc internal scheduler,
+- * called B-WF2Q+, to schedule processes according to their budgets. More
+- * precisely, BFQ schedules queues associated to processes. Thanks to the
+- * accurate policy of B-WF2Q+, BFQ can afford to assign high budgets to
+- * I/O-bound processes issuing sequential requests (to boost the
+- * throughput), and yet guarantee a low latency to interactive and soft
+- * real-time applications.
++ * BFQ is a proportional-share storage-I/O scheduling algorithm based
++ * on the slice-by-slice service scheme of CFQ. But BFQ assigns
++ * budgets, measured in number of sectors, to processes instead of
++ * time slices. The device is not granted to the in-service process
++ * for a given time slice, but until it has exhausted its assigned
++ * budget. This change from the time to the service domain enables BFQ
++ * to distribute the device throughput among processes as desired,
++ * without any distortion due to throughput fluctuations, or to device
++ * internal queueing. BFQ uses an ad hoc internal scheduler, called
++ * B-WF2Q+, to schedule processes according to their budgets. More
++ * precisely, BFQ schedules queues associated with processes. Thanks to
++ * the accurate policy of B-WF2Q+, BFQ can afford to assign high
++ * budgets to I/O-bound processes issuing sequential requests (to
++ * boost the throughput), and yet guarantee a low latency to
++ * interactive and soft real-time applications.
+  *
+  * BFQ is described in [1], where also a reference to the initial, more
+  * theoretical paper on BFQ can be found. The interested reader can find
+@@ -70,8 +73,8 @@
+ #include "bfq.h"
+ #include "blk.h"
+ 
+-/* Expiration time of sync (0) and async (1) requests, in jiffies. */
+-static const int bfq_fifo_expire[2] = { HZ / 4, HZ / 8 };
++/* Expiration time of sync (0) and async (1) requests, in ns. */
++static const u64 bfq_fifo_expire[2] = { NSEC_PER_SEC / 4, NSEC_PER_SEC / 8 };
+ 
+ /* Maximum backwards seek, in KiB. */
+ static const int bfq_back_max = 16 * 1024;
+@@ -79,15 +82,14 @@ static const int bfq_back_max = 16 * 1024;
+ /* Penalty of a backwards seek, in number of sectors. */
+ static const int bfq_back_penalty = 2;
+ 
+-/* Idling period duration, in jiffies. */
+-static int bfq_slice_idle = HZ / 125;
++/* Idling period duration, in ns. */
++static u32 bfq_slice_idle = NSEC_PER_SEC / 125;
+ 
+ /* Minimum number of assigned budgets for which stats are safe to compute. */
+ static const int bfq_stats_min_budgets = 194;
+ 
+ /* Default maximum budget values, in sectors and number of requests. */
+ static const int bfq_default_max_budget = 16 * 1024;
+-static const int bfq_max_budget_async_rq = 4;
+ 
+ /*
+  * Async to sync throughput distribution is controlled as follows:
+@@ -97,23 +99,27 @@ static const int bfq_max_budget_async_rq = 4;
+ static const int bfq_async_charge_factor = 10;
+ 
+ /* Default timeout values, in jiffies, approximating CFQ defaults. */
+-static const int bfq_timeout_sync = HZ / 8;
+-static int bfq_timeout_async = HZ / 25;
++static const int bfq_timeout = HZ / 8;
+ 
+ struct kmem_cache *bfq_pool;
+ 
+-/* Below this threshold (in ms), we consider thinktime immediate. */
+-#define BFQ_MIN_TT		2
++/* Below this threshold (in ns), we consider thinktime immediate. */
++#define BFQ_MIN_TT		(2 * NSEC_PER_MSEC)
+ 
+ /* hw_tag detection: parallel requests threshold and min samples needed. */
+ #define BFQ_HW_QUEUE_THRESHOLD	4
+ #define BFQ_HW_QUEUE_SAMPLES	32
+ 
+-#define BFQQ_SEEK_THR	 (sector_t)(8 * 1024)
+-#define BFQQ_SEEKY(bfqq) ((bfqq)->seek_mean > BFQQ_SEEK_THR)
++#define BFQQ_SEEK_THR		(sector_t)(8 * 100)
++#define BFQQ_CLOSE_THR		(sector_t)(8 * 1024)
++#define BFQQ_SEEKY(bfqq)	(hweight32(bfqq->seek_history) > 32/8)
+ 
+-/* Min samples used for peak rate estimation (for autotuning). */
+-#define BFQ_PEAK_RATE_SAMPLES	32
++/* Min number of samples required to perform peak-rate update */
++#define BFQ_RATE_MIN_SAMPLES	32
++/* Min observation time interval required to perform a peak-rate update (ns) */
++#define BFQ_RATE_MIN_INTERVAL	300*NSEC_PER_MSEC
++/* Target observation time interval for a peak-rate update (ns) */
++#define BFQ_RATE_REF_INTERVAL	NSEC_PER_SEC
+ 
+ /* Shift used for peak rate fixed precision calculations. */
+ #define BFQ_RATE_SHIFT		16
+@@ -141,16 +147,24 @@ struct kmem_cache *bfq_pool;
+  * The device's speed class is dynamically (re)detected in
+  * bfq_update_peak_rate() every time the estimated peak rate is updated.
+  *
+- * In the following definitions, R_slow[0]/R_fast[0] and T_slow[0]/T_fast[0]
+- * are the reference values for a slow/fast rotational device, whereas
+- * R_slow[1]/R_fast[1] and T_slow[1]/T_fast[1] are the reference values for
+- * a slow/fast non-rotational device. Finally, device_speed_thresh are the
+- * thresholds used to switch between speed classes.
++ * In the following definitions, R_slow[0]/R_fast[0] and
++ * T_slow[0]/T_fast[0] are the reference values for a slow/fast
++ * rotational device, whereas R_slow[1]/R_fast[1] and
++ * T_slow[1]/T_fast[1] are the reference values for a slow/fast
++ * non-rotational device. Finally, device_speed_thresh are the
++ * thresholds used to switch between speed classes. The reference
++ * rates are not the actual peak rates of the devices used as a
++ * reference, but slightly lower values. The reason for using these
++ * slightly lower values is that the peak-rate estimator tends to
++ * yield slightly lower values than the actual peak rate (it can yield
++ * the actual peak rate only if there is only one process doing I/O,
++ * and the process does sequential I/O).
++ *
+  * Both the reference peak rates and the thresholds are measured in
+  * sectors/usec, left-shifted by BFQ_RATE_SHIFT.
+  */
+-static int R_slow[2] = {1536, 10752};
+-static int R_fast[2] = {17415, 34791};
++static int R_slow[2] = {1000, 10700};
++static int R_fast[2] = {14000, 33000};
+ /*
+  * To improve readability, a conversion function is used to initialize the
+  * following arrays, which entails that they can be initialized only in a
+@@ -183,10 +197,7 @@ static void bfq_schedule_dispatch(struct bfq_data *bfqd);
+  */
+ static int bfq_bio_sync(struct bio *bio)
+ {
+-	if (bio_data_dir(bio) == READ || (bio->bi_rw & REQ_SYNC))
+-		return 1;
+-
+-	return 0;
++	return bio_data_dir(bio) == READ || (bio->bi_opf & REQ_SYNC);
+ }
+ 
+ /*
+@@ -409,11 +420,7 @@ static bool bfq_differentiated_weights(struct bfq_data *bfqd)
+  */
+ static bool bfq_symmetric_scenario(struct bfq_data *bfqd)
+ {
+-	return
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-		!bfqd->active_numerous_groups &&
+-#endif
+-		!bfq_differentiated_weights(bfqd);
++	return !bfq_differentiated_weights(bfqd);
+ }
+ 
+ /*
+@@ -533,9 +540,19 @@ static struct request *bfq_find_next_rq(struct bfq_data *bfqd,
+ static unsigned long bfq_serv_to_charge(struct request *rq,
+ 					struct bfq_queue *bfqq)
+ {
+-	return blk_rq_sectors(rq) *
+-		(1 + ((!bfq_bfqq_sync(bfqq)) * (bfqq->wr_coeff == 1) *
+-		bfq_async_charge_factor));
++	if (bfq_bfqq_sync(bfqq) || bfqq->wr_coeff > 1)
++		return blk_rq_sectors(rq);
++
++	/*
++	 * If there are no weight-raised queues, then amplify service
++	 * by just the async charge factor; otherwise amplify service
++	 * by twice the async charge factor, to further reduce latency
++	 * for weight-raised queues.
++	 */
++	if (bfqq->bfqd->wr_busy_queues == 0)
++		return blk_rq_sectors(rq) * bfq_async_charge_factor;
++
++	return blk_rq_sectors(rq) * 2 * bfq_async_charge_factor;
+ }
+ 
+ /**
+@@ -590,12 +607,23 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
+ 	dur = bfqd->RT_prod;
+ 	do_div(dur, bfqd->peak_rate);
+ 
+-	return dur;
+-}
++	/*
++	 * Limit duration between 3 and 13 seconds. Tests show that
++	 * higher values than 13 seconds often yield the opposite of
++	 * the desired result, i.e., worsen responsiveness by letting
++	 * non-interactive and non-soft-real-time applications
++	 * preserve weight raising for a too long time interval.
++	 *
++	 * On the other end, lower values than 3 seconds make it
++	 * difficult for most interactive tasks to complete their jobs
++	 * before weight-raising finishes.
++	 */
++	if (dur > msecs_to_jiffies(13000))
++		dur = msecs_to_jiffies(13000);
++	else if (dur < msecs_to_jiffies(3000))
++		dur = msecs_to_jiffies(3000);
+ 
+-static unsigned int bfq_bfqq_cooperations(struct bfq_queue *bfqq)
+-{
+-	return bfqq->bic ? bfqq->bic->cooperations : 0;
++	return dur;
+ }
+ 
+ static void
+@@ -605,31 +633,28 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
+ 		bfq_mark_bfqq_idle_window(bfqq);
+ 	else
+ 		bfq_clear_bfqq_idle_window(bfqq);
++
+ 	if (bic->saved_IO_bound)
+ 		bfq_mark_bfqq_IO_bound(bfqq);
+ 	else
+ 		bfq_clear_bfqq_IO_bound(bfqq);
+-	/* Assuming that the flag in_large_burst is already correctly set */
+-	if (bic->wr_time_left && bfqq->bfqd->low_latency &&
+-	    !bfq_bfqq_in_large_burst(bfqq) &&
+-	    bic->cooperations < bfqq->bfqd->bfq_coop_thresh) {
+-		/*
+-		 * Start a weight raising period with the duration given by
+-		 * the raising_time_left snapshot.
+-		 */
+-		if (bfq_bfqq_busy(bfqq))
+-			bfqq->bfqd->wr_busy_queues++;
+-		bfqq->wr_coeff = bfqq->bfqd->bfq_wr_coeff;
+-		bfqq->wr_cur_max_time = bic->wr_time_left;
+-		bfqq->last_wr_start_finish = jiffies;
+-		bfqq->entity.prio_changed = 1;
++
++	bfqq->wr_coeff = bic->saved_wr_coeff;
++	bfqq->wr_start_at_switch_to_srt = bic->saved_wr_start_at_switch_to_srt;
++	BUG_ON(time_is_after_jiffies(bfqq->wr_start_at_switch_to_srt));
++	bfqq->last_wr_start_finish = bic->saved_last_wr_start_finish;
++	BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish));
++
++	if (bfqq->wr_coeff > 1 && (bfq_bfqq_in_large_burst(bfqq) ||
++	    time_is_before_jiffies(bfqq->last_wr_start_finish +
++				   bfqq->wr_cur_max_time))) {
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++		    "resume state: switching off wr");
++
++		bfqq->wr_coeff = 1;
+ 	}
+-	/*
+-	 * Clear wr_time_left to prevent bfq_bfqq_save_state() from
+-	 * getting confused about the queue's need of a weight-raising
+-	 * period.
+-	 */
+-	bic->wr_time_left = 0;
++	/* make sure weight will be updated, however we got here */
++	bfqq->entity.prio_changed = 1;
+ }
+ 
+ static int bfqq_process_refs(struct bfq_queue *bfqq)
+@@ -639,7 +664,7 @@ static int bfqq_process_refs(struct bfq_queue *bfqq)
+ 	lockdep_assert_held(bfqq->bfqd->queue->queue_lock);
+ 
+ 	io_refs = bfqq->allocated[READ] + bfqq->allocated[WRITE];
+-	process_refs = atomic_read(&bfqq->ref) - io_refs - bfqq->entity.on_st;
++	process_refs = bfqq->ref - io_refs - bfqq->entity.on_st;
+ 	BUG_ON(process_refs < 0);
+ 	return process_refs;
+ }
+@@ -654,6 +679,7 @@ static void bfq_reset_burst_list(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		hlist_del_init(&item->burst_list_node);
+ 	hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list);
+ 	bfqd->burst_size = 1;
++	bfqd->burst_parent_entity = bfqq->entity.parent;
+ }
+ 
+ /* Add bfqq to the list of queues in current burst (see bfq_handle_burst) */
+@@ -662,6 +688,10 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 	/* Increment burst size to take into account also bfqq */
+ 	bfqd->burst_size++;
+ 
++	bfq_log_bfqq(bfqd, bfqq, "add_to_burst %d", bfqd->burst_size);
++
++	BUG_ON(bfqd->burst_size > bfqd->bfq_large_burst_thresh);
++
+ 	if (bfqd->burst_size == bfqd->bfq_large_burst_thresh) {
+ 		struct bfq_queue *pos, *bfqq_item;
+ 		struct hlist_node *n;
+@@ -671,15 +701,19 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		 * other to consider this burst as large.
+ 		 */
+ 		bfqd->large_burst = true;
++		bfq_log_bfqq(bfqd, bfqq, "add_to_burst: large burst started");
+ 
+ 		/*
+ 		 * We can now mark all queues in the burst list as
+ 		 * belonging to a large burst.
+ 		 */
+ 		hlist_for_each_entry(bfqq_item, &bfqd->burst_list,
+-				     burst_list_node)
++				     burst_list_node) {
+ 			bfq_mark_bfqq_in_large_burst(bfqq_item);
++			bfq_log_bfqq(bfqd, bfqq_item, "marked in large burst");
++		}
+ 		bfq_mark_bfqq_in_large_burst(bfqq);
++		bfq_log_bfqq(bfqd, bfqq, "marked in large burst");
+ 
+ 		/*
+ 		 * From now on, and until the current burst finishes, any
+@@ -691,67 +725,79 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		hlist_for_each_entry_safe(pos, n, &bfqd->burst_list,
+ 					  burst_list_node)
+ 			hlist_del_init(&pos->burst_list_node);
+-	} else /* burst not yet large: add bfqq to the burst list */
++	} else /*
++		* Burst not yet large: add bfqq to the burst list. Do
++		* not increment the ref counter for bfqq, because bfqq
++		* is removed from the burst list before freeing bfqq
++		* in put_queue.
++		*/
+ 		hlist_add_head(&bfqq->burst_list_node, &bfqd->burst_list);
+ }
+ 
+ /*
+- * If many queues happen to become active shortly after each other, then,
+- * to help the processes associated to these queues get their job done as
+- * soon as possible, it is usually better to not grant either weight-raising
+- * or device idling to these queues. In this comment we describe, firstly,
+- * the reasons why this fact holds, and, secondly, the next function, which
+- * implements the main steps needed to properly mark these queues so that
+- * they can then be treated in a different way.
++ * If many queues belonging to the same group happen to be created
++ * shortly after each other, then the processes associated with these
++ * queues have typically a common goal. In particular, bursts of queue
++ * creations are usually caused by services or applications that spawn
++ * many parallel threads/processes. Examples are systemd during boot,
++ * or git grep. To help these processes get their job done as soon as
++ * possible, it is usually better to not grant either weight-raising
++ * or device idling to their queues.
+  *
+- * As for the terminology, we say that a queue becomes active, i.e.,
+- * switches from idle to backlogged, either when it is created (as a
+- * consequence of the arrival of an I/O request), or, if already existing,
+- * when a new request for the queue arrives while the queue is idle.
+- * Bursts of activations, i.e., activations of different queues occurring
+- * shortly after each other, are typically caused by services or applications
+- * that spawn or reactivate many parallel threads/processes. Examples are
+- * systemd during boot or git grep.
++ * In this comment we describe, firstly, the reasons why this fact
++ * holds, and, secondly, the next function, which implements the main
++ * steps needed to properly mark these queues so that they can then be
++ * treated in a different way.
+  *
+- * These services or applications benefit mostly from a high throughput:
+- * the quicker the requests of the activated queues are cumulatively served,
+- * the sooner the target job of these queues gets completed. As a consequence,
+- * weight-raising any of these queues, which also implies idling the device
+- * for it, is almost always counterproductive: in most cases it just lowers
+- * throughput.
++ * The above services or applications benefit mostly from a high
++ * throughput: the quicker the requests of the activated queues are
++ * cumulatively served, the sooner the target job of these queues gets
++ * completed. As a consequence, weight-raising any of these queues,
++ * which also implies idling the device for it, is almost always
++ * counterproductive. In most cases it just lowers throughput.
+  *
+- * On the other hand, a burst of activations may be also caused by the start
+- * of an application that does not consist in a lot of parallel I/O-bound
+- * threads. In fact, with a complex application, the burst may be just a
+- * consequence of the fact that several processes need to be executed to
+- * start-up the application. To start an application as quickly as possible,
+- * the best thing to do is to privilege the I/O related to the application
+- * with respect to all other I/O. Therefore, the best strategy to start as
+- * quickly as possible an application that causes a burst of activations is
+- * to weight-raise all the queues activated during the burst. This is the
++ * On the other hand, a burst of queue creations may be caused also by
++ * the start of an application that does not consist of a lot of
++ * parallel I/O-bound threads. In fact, with a complex application,
++ * several short processes may need to be executed to start-up the
++ * application. In this respect, to start an application as quickly as
++ * possible, the best thing to do is in any case to privilege the I/O
++ * related to the application with respect to all other
++ * I/O. Therefore, the best strategy to start as quickly as possible
++ * an application that causes a burst of queue creations is to
++ * weight-raise all the queues created during the burst. This is the
+  * exact opposite of the best strategy for the other type of bursts.
+  *
+- * In the end, to take the best action for each of the two cases, the two
+- * types of bursts need to be distinguished. Fortunately, this seems
+- * relatively easy to do, by looking at the sizes of the bursts. In
+- * particular, we found a threshold such that bursts with a larger size
+- * than that threshold are apparently caused only by services or commands
+- * such as systemd or git grep. For brevity, hereafter we call just 'large'
+- * these bursts. BFQ *does not* weight-raise queues whose activations occur
+- * in a large burst. In addition, for each of these queues BFQ performs or
+- * does not perform idling depending on which choice boosts the throughput
+- * most. The exact choice depends on the device and request pattern at
++ * In the end, to take the best action for each of the two cases, the
++ * two types of bursts need to be distinguished. Fortunately, this
++ * seems relatively easy, by looking at the sizes of the bursts. In
++ * particular, we found a threshold such that only bursts with a
++ * larger size than that threshold are apparently caused by
++ * services or commands such as systemd or git grep. For brevity,
++ * hereafter we call just 'large' these bursts. BFQ *does not*
++ * weight-raise queues whose creation occurs in a large burst. In
++ * addition, for each of these queues BFQ performs or does not perform
++ * idling depending on which choice boosts the throughput more. The
++ * exact choice depends on the device and request pattern at
+  * hand.
+  *
+- * Turning back to the next function, it implements all the steps needed
+- * to detect the occurrence of a large burst and to properly mark all the
+- * queues belonging to it (so that they can then be treated in a different
+- * way). This goal is achieved by maintaining a special "burst list" that
+- * holds, temporarily, the queues that belong to the burst in progress. The
+- * list is then used to mark these queues as belonging to a large burst if
+- * the burst does become large. The main steps are the following.
++ * Unfortunately, false positives may occur while an interactive task
++ * is starting (e.g., an application is being started). The
++ * consequence is that the queues associated with the task do not
++ * enjoy weight raising as expected. Fortunately these false positives
++ * are very rare. They typically occur if some service happens to
++ * start doing I/O exactly when the interactive task starts.
+  *
+- * . when the very first queue is activated, the queue is inserted into the
++ * Turning back to the next function, it implements all the steps
++ * needed to detect the occurrence of a large burst and to properly
++ * mark all the queues belonging to it (so that they can then be
++ * treated in a different way). This goal is achieved by maintaining a
++ * "burst list" that holds, temporarily, the queues that belong to the
++ * burst in progress. The list is then used to mark these queues as
++ * belonging to a large burst if the burst does become large. The main
++ * steps are the following.
++ *
++ * . when the very first queue is created, the queue is inserted into the
+  *   list (as it could be the first queue in a possible burst)
+  *
+  * . if the current burst has not yet become large, and a queue Q that does
+@@ -772,13 +818,13 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+  *
+  *     . the device enters a large-burst mode
+  *
+- * . if a queue Q that does not belong to the burst is activated while
++ * . if a queue Q that does not belong to the burst is created while
+  *   the device is in large-burst mode and shortly after the last time
+  *   at which a queue either entered the burst list or was marked as
+  *   belonging to the current large burst, then Q is immediately marked
+  *   as belonging to a large burst.
+  *
+- * . if a queue Q that does not belong to the burst is activated a while
++ * . if a queue Q that does not belong to the burst is created a while
+  *   later, i.e., not shortly after, than the last time at which a queue
+  *   either entered the burst list or was marked as belonging to the
+  *   current large burst, then the current burst is deemed as finished and:
+@@ -791,52 +837,44 @@ static void bfq_add_to_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+  *          in a possible new burst (then the burst list contains just Q
+  *          after this step).
+  */
+-static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+-			     bool idle_for_long_time)
++static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ {
+ 	/*
+-	 * If bfqq happened to be activated in a burst, but has been idle
+-	 * for at least as long as an interactive queue, then we assume
+-	 * that, in the overall I/O initiated in the burst, the I/O
+-	 * associated to bfqq is finished. So bfqq does not need to be
+-	 * treated as a queue belonging to a burst anymore. Accordingly,
+-	 * we reset bfqq's in_large_burst flag if set, and remove bfqq
+-	 * from the burst list if it's there. We do not decrement instead
+-	 * burst_size, because the fact that bfqq does not need to belong
+-	 * to the burst list any more does not invalidate the fact that
+-	 * bfqq may have been activated during the current burst.
+-	 */
+-	if (idle_for_long_time) {
+-		hlist_del_init(&bfqq->burst_list_node);
+-		bfq_clear_bfqq_in_large_burst(bfqq);
+-	}
+-
+-	/*
+ 	 * If bfqq is already in the burst list or is part of a large
+-	 * burst, then there is nothing else to do.
++	 * burst, or finally has just been split, then there is
++	 * nothing else to do.
+ 	 */
+ 	if (!hlist_unhashed(&bfqq->burst_list_node) ||
+-	    bfq_bfqq_in_large_burst(bfqq))
++	    bfq_bfqq_in_large_burst(bfqq) ||
++	    time_is_after_eq_jiffies(bfqq->split_time +
++				     msecs_to_jiffies(10)))
+ 		return;
+ 
+ 	/*
+-	 * If bfqq's activation happens late enough, then the current
+-	 * burst is finished, and related data structures must be reset.
++	 * If bfqq's creation happens late enough, or bfqq belongs to
++	 * a different group than the burst group, then the current
++	 * burst is finished, and related data structures must be
++	 * reset.
+ 	 *
+-	 * In this respect, consider the special case where bfqq is the very
+-	 * first queue being activated. In this case, last_ins_in_burst is
+-	 * not yet significant when we get here. But it is easy to verify
+-	 * that, whether or not the following condition is true, bfqq will
+-	 * end up being inserted into the burst list. In particular the
+-	 * list will happen to contain only bfqq. And this is exactly what
+-	 * has to happen, as bfqq may be the first queue in a possible
++	 * In this respect, consider the special case where bfqq is
++	 * the very first queue created after BFQ is selected for this
++	 * device. In this case, last_ins_in_burst and
++	 * burst_parent_entity are not yet significant when we get
++	 * here. But it is easy to verify that, whether or not the
++	 * following condition is true, bfqq will end up being
++	 * inserted into the burst list. In particular the list will
++	 * happen to contain only bfqq. And this is exactly what has
++	 * to happen, as bfqq may be the first queue of the first
+ 	 * burst.
+ 	 */
+ 	if (time_is_before_jiffies(bfqd->last_ins_in_burst +
+-	    bfqd->bfq_burst_interval)) {
++	    bfqd->bfq_burst_interval) ||
++	    bfqq->entity.parent != bfqd->burst_parent_entity) {
+ 		bfqd->large_burst = false;
+ 		bfq_reset_burst_list(bfqd, bfqq);
+-		return;
++		bfq_log_bfqq(bfqd, bfqq,
++			"handle_burst: late activation or different group");
++		goto end;
+ 	}
+ 
+ 	/*
+@@ -845,8 +883,9 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	 * bfqq as belonging to this large burst immediately.
+ 	 */
+ 	if (bfqd->large_burst) {
++		bfq_log_bfqq(bfqd, bfqq, "handle_burst: marked in burst");
+ 		bfq_mark_bfqq_in_large_burst(bfqq);
+-		return;
++		goto end;
+ 	}
+ 
+ 	/*
+@@ -855,25 +894,491 @@ static void bfq_handle_burst(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	 * queue. Then we add bfqq to the burst.
+ 	 */
+ 	bfq_add_to_burst(bfqd, bfqq);
++end:
++	/*
++	 * At this point, bfqq either has been added to the current
++	 * burst or has caused the current burst to terminate and a
++	 * possible new burst to start. In particular, in the second
++	 * case, bfqq has become the first queue in the possible new
++	 * burst.  In both cases last_ins_in_burst needs to be moved
++	 * forward.
++	 */
++	bfqd->last_ins_in_burst = jiffies;
++
++}
++
++static int bfq_bfqq_budget_left(struct bfq_queue *bfqq)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	return entity->budget - entity->service;
++}
++
++/*
++ * If enough samples have been computed, return the current max budget
++ * stored in bfqd, which is dynamically updated according to the
++ * estimated disk peak rate; otherwise return the default max budget
++ */
++static int bfq_max_budget(struct bfq_data *bfqd)
++{
++	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
++		return bfq_default_max_budget;
++	else
++		return bfqd->bfq_max_budget;
++}
++
++/*
++ * Return min budget, which is a fraction of the current or default
++ * max budget (trying with 1/32)
++ */
++static int bfq_min_budget(struct bfq_data *bfqd)
++{
++	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
++		return bfq_default_max_budget / 32;
++	else
++		return bfqd->bfq_max_budget / 32;
++}
++
++static void bfq_bfqq_expire(struct bfq_data *bfqd,
++			    struct bfq_queue *bfqq,
++			    bool compensate,
++			    enum bfqq_expiration reason);
++
++/*
++ * The next function, invoked after the input queue bfqq switches from
++ * idle to busy, updates the budget of bfqq. The function also tells
++ * whether the in-service queue should be expired, by returning
++ * true. The purpose of expiring the in-service queue is to give bfqq
++ * the chance to possibly preempt the in-service queue, and the reason
++ * for preempting the in-service queue is to achieve one of the two
++ * goals below.
++ *
++ * 1. Guarantee to bfqq its reserved bandwidth even if bfqq has
++ * expired because it has remained idle. In particular, bfqq may have
++ * expired for one of the following two reasons:
++ *
++ * - BFQ_BFQQ_NO_MORE_REQUEST bfqq did not enjoy any device idling and
++ *   did not make it to issue a new request before its last request
++ *   was served;
++ *
++ * - BFQ_BFQQ_TOO_IDLE bfqq did enjoy device idling, but did not issue
++ *   a new request before the expiration of the idling-time.
++ *
++ * Even if bfqq has expired for one of the above reasons, the process
++ * associated with the queue may be however issuing requests greedily,
++ * and thus be sensitive to the bandwidth it receives (bfqq may have
++ * remained idle for other reasons: CPU high load, bfqq not enjoying
++ * idling, I/O throttling somewhere in the path from the process to
++ * the I/O scheduler, ...). But if, after every expiration for one of
++ * the above two reasons, bfqq has to wait for the service of at least
++ * one full budget of another queue before being served again, then
++ * bfqq is likely to get a much lower bandwidth or resource time than
++ * its reserved ones. To address this issue, two countermeasures need
++ * to be taken.
++ *
++ * First, the budget and the timestamps of bfqq need to be updated in
++ * a special way on bfqq reactivation: they need to be updated as if
++ * bfqq did not remain idle and did not expire. In fact, if they are
++ * computed as if bfqq expired and remained idle until reactivation,
++ * then the process associated with bfqq is treated as if, instead of
++ * being greedy, it stopped issuing requests when bfqq remained idle,
++ * and restarts issuing requests only on this reactivation. In other
++ * words, the scheduler does not help the process recover the "service
++ * hole" between bfqq expiration and reactivation. As a consequence,
++ * the process receives a lower bandwidth than its reserved one. In
++ * contrast, to recover this hole, the budget must be updated as if
++ * bfqq was not expired at all before this reactivation, i.e., it must
++ * be set to the value of the remaining budget when bfqq was
++ * expired. Along the same line, timestamps need to be assigned the
++ * value they had the last time bfqq was selected for service, i.e.,
++ * before last expiration. Thus timestamps need to be back-shifted
++ * with respect to their normal computation (see [1] for more details
++ * on this tricky aspect).
++ *
++ * Secondly, to allow the process to recover the hole, the in-service
++ * queue must be expired too, to give bfqq the chance to preempt it
++ * immediately. In fact, if bfqq has to wait for a full budget of the
++ * in-service queue to be completed, then it may become impossible to
++ * let the process recover the hole, even if the back-shifted
++ * timestamps of bfqq are lower than those of the in-service queue. If
++ * this happens for most or all of the holes, then the process may not
++ * receive its reserved bandwidth. In this respect, it is worth noting
++ * that, being the service of outstanding requests unpreemptible, a
++ * little fraction of the holes may however be unrecoverable, thereby
++ * causing a little loss of bandwidth.
++ *
++ * The last important point is detecting whether bfqq does need this
++ * bandwidth recovery. In this respect, the next function deems the
++ * process associated with bfqq greedy, and thus allows it to recover
++ * the hole, if: 1) the process is waiting for the arrival of a new
++ * request (which implies that bfqq expired for one of the above two
++ * reasons), and 2) such a request has arrived soon. The first
++ * condition is controlled through the flag non_blocking_wait_rq,
++ * while the second through the flag arrived_in_time. If both
++ * conditions hold, then the function computes the budget in the
++ * above-described special way, and signals that the in-service queue
++ * should be expired. Timestamp back-shifting is done later in
++ * __bfq_activate_entity.
++ *
++ * 2. Reduce latency. Even if timestamps are not backshifted to let
++ * the process associated with bfqq recover a service hole, bfqq may
++ * however happen to have, after being (re)activated, a lower finish
++ * timestamp than the in-service queue.  That is, the next budget of
++ * bfqq may have to be completed before the one of the in-service
++ * queue. If this is the case, then preempting the in-service queue
++ * allows this goal to be achieved, apart from the unpreemptible,
++ * outstanding requests mentioned above.
++ *
++ * Unfortunately, regardless of which of the above two goals one wants
++ * to achieve, service trees need first to be updated to know whether
++ * the in-service queue must be preempted. To have service trees
++ * correctly updated, the in-service queue must be expired and
++ * rescheduled, and bfqq must be scheduled too. This is one of the
++ * most costly operations (in future versions, the scheduling
++ * mechanism may be re-designed in such a way to make it possible to
++ * know whether preemption is needed without needing to update service
++ * trees). In addition, queue preemptions almost always cause random
++ * I/O, and thus loss of throughput. Because of these facts, the next
++ * function adopts the following simple scheme to avoid both costly
++ * operations and too frequent preemptions: it requests the expiration
++ * of the in-service queue (unconditionally) only for queues that need
++ * to recover a hole, or that either are weight-raised or deserve to
++ * be weight-raised.
++ */
++static bool bfq_bfqq_update_budg_for_activation(struct bfq_data *bfqd,
++						struct bfq_queue *bfqq,
++						bool arrived_in_time,
++						bool wr_or_deserves_wr)
++{
++	struct bfq_entity *entity = &bfqq->entity;
++
++	if (bfq_bfqq_non_blocking_wait_rq(bfqq) && arrived_in_time) {
++		/*
++		 * We do not clear the flag non_blocking_wait_rq here, as
++		 * the latter is used in bfq_activate_bfqq to signal
++		 * that timestamps need to be back-shifted (and is
++		 * cleared right after).
++		 */
++
++		/*
++		 * In next assignment we rely on that either
++		 * entity->service or entity->budget are not updated
++		 * on expiration if bfqq is empty (see
++		 * __bfq_bfqq_recalc_budget). Thus both quantities
++		 * remain unchanged after such an expiration, and the
++		 * following statement therefore assigns to
++		 * entity->budget the remaining budget on such an
++		 * expiration. For clarity, entity->service is not
++		 * updated on expiration in any case, and, in normal
++		 * operation, is reset only when bfqq is selected for
++		 * service (see bfq_get_next_queue).
++		 */
++		BUG_ON(bfqq->max_budget < 0);
++		entity->budget = min_t(unsigned long,
++				       bfq_bfqq_budget_left(bfqq),
++				       bfqq->max_budget);
++
++		BUG_ON(entity->budget < 0);
++		return true;
++	}
++
++	BUG_ON(bfqq->max_budget < 0);
++	entity->budget = max_t(unsigned long, bfqq->max_budget,
++			       bfq_serv_to_charge(bfqq->next_rq, bfqq));
++	BUG_ON(entity->budget < 0);
++
++	bfq_clear_bfqq_non_blocking_wait_rq(bfqq);
++	return wr_or_deserves_wr;
++}
++
++static void bfq_update_bfqq_wr_on_rq_arrival(struct bfq_data *bfqd,
++					     struct bfq_queue *bfqq,
++					     unsigned int old_wr_coeff,
++					     bool wr_or_deserves_wr,
++					     bool interactive,
++					     bool in_burst,
++					     bool soft_rt)
++{
++	if (old_wr_coeff == 1 && wr_or_deserves_wr) {
++		/* start a weight-raising period */
++		if (interactive) {
++			bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++			bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++		} else {
++			bfqq->wr_start_at_switch_to_srt = jiffies;
++			bfqq->wr_coeff = bfqd->bfq_wr_coeff *
++				BFQ_SOFTRT_WEIGHT_FACTOR;
++			bfqq->wr_cur_max_time =
++				bfqd->bfq_wr_rt_max_time;
++		}
++		/*
++		 * If needed, further reduce budget to make sure it is
++		 * close to bfqq's backlog, so as to reduce the
++		 * scheduling-error component due to a too large
++		 * budget. Do not care about throughput consequences,
++		 * but only about latency. Finally, do not assign a
++		 * too small budget either, to avoid increasing
++		 * latency by causing too frequent expirations.
++		 */
++		bfqq->entity.budget = min_t(unsigned long,
++					    bfqq->entity.budget,
++					    2 * bfq_min_budget(bfqd));
++
++		bfq_log_bfqq(bfqd, bfqq,
++			     "wrais starting at %lu, rais_max_time %u",
++			     jiffies,
++			     jiffies_to_msecs(bfqq->wr_cur_max_time));
++	} else if (old_wr_coeff > 1) {
++		if (interactive) { /* update wr coeff and duration */
++			bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++			bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++		} else if (in_burst) {
++			bfqq->wr_coeff = 1;
++			bfq_log_bfqq(bfqd, bfqq,
++				     "wrais ending at %lu, rais_max_time %u",
++				     jiffies,
++				     jiffies_to_msecs(bfqq->
++						      wr_cur_max_time));
++		} else if (soft_rt) {
++			/*
++			 * The application is now or still meeting the
++			 * requirements for being deemed soft rt.  We
++			 * can then correctly and safely (re)charge
++			 * the weight-raising duration for the
++			 * application with the weight-raising
++			 * duration for soft rt applications.
++			 *
++			 * In particular, doing this recharge now, i.e.,
++			 * before the weight-raising period for the
++			 * application finishes, reduces the probability
++			 * of the following negative scenario:
++			 * 1) the weight of a soft rt application is
++			 *    raised at startup (as for any newly
++			 *    created application),
++			 * 2) since the application is not interactive,
++			 *    at a certain time weight-raising is
++			 *    stopped for the application,
++			 * 3) at that time the application happens to
++			 *    still have pending requests, and hence
++			 *    is destined to not have a chance to be
++			 *    deemed soft rt before these requests are
++			 *    completed (see the comments to the
++			 *    function bfq_bfqq_softrt_next_start()
++			 *    for details on soft rt detection),
++			 * 4) these pending requests experience a high
++			 *    latency because the application is not
++			 *    weight-raised while they are pending.
++			 */
++			if (bfqq->wr_cur_max_time !=
++				bfqd->bfq_wr_rt_max_time) {
++				bfqq->wr_start_at_switch_to_srt =
++					bfqq->last_wr_start_finish;
++                BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish));
++
++				bfqq->wr_cur_max_time =
++					bfqd->bfq_wr_rt_max_time;
++				bfqq->wr_coeff = bfqd->bfq_wr_coeff *
++					BFQ_SOFTRT_WEIGHT_FACTOR;
++				bfq_log_bfqq(bfqd, bfqq,
++					     "switching to soft_rt wr");
++			} else
++				bfq_log_bfqq(bfqd, bfqq,
++					"moving forward soft_rt wr duration");
++			bfqq->last_wr_start_finish = jiffies;
++		}
++	}
++}
++
++static bool bfq_bfqq_idle_for_long_time(struct bfq_data *bfqd,
++					struct bfq_queue *bfqq)
++{
++	return bfqq->dispatched == 0 &&
++		time_is_before_jiffies(
++			bfqq->budget_timeout +
++			bfqd->bfq_wr_min_idle_time);
++}
++
++static void bfq_bfqq_handle_idle_busy_switch(struct bfq_data *bfqd,
++					     struct bfq_queue *bfqq,
++					     int old_wr_coeff,
++					     struct request *rq,
++					     bool *interactive)
++{
++	bool soft_rt, in_burst,	wr_or_deserves_wr,
++		bfqq_wants_to_preempt,
++		idle_for_long_time = bfq_bfqq_idle_for_long_time(bfqd, bfqq),
++		/*
++		 * See the comments on
++		 * bfq_bfqq_update_budg_for_activation for
++		 * details on the usage of the next variable.
++		 */
++		arrived_in_time =  ktime_get_ns() <=
++			RQ_BIC(rq)->ttime.last_end_request +
++			bfqd->bfq_slice_idle * 3;
++
++	bfq_log_bfqq(bfqd, bfqq,
++		     "bfq_add_request non-busy: "
++		     "jiffies %lu, in_time %d, idle_long %d busyw %d "
++		     "wr_coeff %u",
++		     jiffies, arrived_in_time,
++		     idle_for_long_time,
++		     bfq_bfqq_non_blocking_wait_rq(bfqq),
++		     old_wr_coeff);
++
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
++
++	BUG_ON(bfqq == bfqd->in_service_queue);
++	bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq,
++				 req_op(rq), rq->cmd_flags);
++
++	/*
++	 * bfqq deserves to be weight-raised if:
++	 * - it is sync,
++	 * - it does not belong to a large burst,
++	 * - it has been idle for enough time or is soft real-time,
++	 * - is linked to a bfq_io_cq (it is not shared in any sense)
++	 */
++	in_burst = bfq_bfqq_in_large_burst(bfqq);
++	soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
++		!in_burst &&
++		time_is_before_jiffies(bfqq->soft_rt_next_start);
++	*interactive =
++		!in_burst &&
++		idle_for_long_time;
++	wr_or_deserves_wr = bfqd->low_latency &&
++		(bfqq->wr_coeff > 1 ||
++		 (bfq_bfqq_sync(bfqq) &&
++		  bfqq->bic && (*interactive || soft_rt)));
++
++	bfq_log_bfqq(bfqd, bfqq,
++		     "bfq_add_request: "
++		     "in_burst %d, "
++		     "soft_rt %d (next %lu), inter %d, bic %p",
++		     bfq_bfqq_in_large_burst(bfqq), soft_rt,
++		     bfqq->soft_rt_next_start,
++		     *interactive,
++		     bfqq->bic);
++
++	/*
++	 * Using the last flag, update budget and check whether bfqq
++	 * may want to preempt the in-service queue.
++	 */
++	bfqq_wants_to_preempt =
++		bfq_bfqq_update_budg_for_activation(bfqd, bfqq,
++						    arrived_in_time,
++						    wr_or_deserves_wr);
++
++	/*
++	 * If bfqq happened to be activated in a burst, but has been
++	 * idle for much more than an interactive queue, then we
++	 * assume that, in the overall I/O initiated in the burst, the
++	 * I/O associated with bfqq is finished. So bfqq does not need
++	 * to be treated as a queue belonging to a burst
++	 * anymore. Accordingly, we reset bfqq's in_large_burst flag
++	 * if set, and remove bfqq from the burst list if it's
++	 * there. We do not decrement burst_size, because the fact
++	 * that bfqq does not need to belong to the burst list any
++	 * more does not invalidate the fact that bfqq was created in
++	 * a burst.
++	 */
++	if (likely(!bfq_bfqq_just_created(bfqq)) &&
++	    idle_for_long_time &&
++	    time_is_before_jiffies(
++		    bfqq->budget_timeout +
++		    msecs_to_jiffies(10000))) {
++		hlist_del_init(&bfqq->burst_list_node);
++		bfq_clear_bfqq_in_large_burst(bfqq);
++	}
++
++	bfq_clear_bfqq_just_created(bfqq);
++
++	if (!bfq_bfqq_IO_bound(bfqq)) {
++		if (arrived_in_time) {
++			bfqq->requests_within_timer++;
++			if (bfqq->requests_within_timer >=
++			    bfqd->bfq_requests_within_timer)
++				bfq_mark_bfqq_IO_bound(bfqq);
++		} else
++			bfqq->requests_within_timer = 0;
++		bfq_log_bfqq(bfqd, bfqq, "requests in time %d",
++			     bfqq->requests_within_timer);
++	}
++
++	if (bfqd->low_latency) {
++		if (unlikely(time_is_after_jiffies(bfqq->split_time)))
++			/* wraparound */
++			bfqq->split_time =
++				jiffies - bfqd->bfq_wr_min_idle_time - 1;
++
++		if (time_is_before_jiffies(bfqq->split_time +
++					   bfqd->bfq_wr_min_idle_time)) {
++			bfq_update_bfqq_wr_on_rq_arrival(bfqd, bfqq,
++							 old_wr_coeff,
++							 wr_or_deserves_wr,
++							 *interactive,
++							 in_burst,
++							 soft_rt);
++
++			if (old_wr_coeff != bfqq->wr_coeff)
++				bfqq->entity.prio_changed = 1;
++		}
++	}
++
++	bfqq->last_idle_bklogged = jiffies;
++	bfqq->service_from_backlogged = 0;
++	bfq_clear_bfqq_softrt_update(bfqq);
++
++	bfq_add_bfqq_busy(bfqd, bfqq);
++
++	/*
++	 * Expire in-service queue only if preemption may be needed
++	 * for guarantees. In this respect, the function
++	 * next_queue_may_preempt just checks a simple, necessary
++	 * condition, and not a sufficient condition based on
++	 * timestamps. In fact, for the latter condition to be
++	 * evaluated, timestamps would need first to be updated, and
++	 * this operation is quite costly (see the comments on the
++	 * function bfq_bfqq_update_budg_for_activation).
++	 */
++	if (bfqd->in_service_queue && bfqq_wants_to_preempt &&
++	    bfqd->in_service_queue->wr_coeff < bfqq->wr_coeff &&
++	    next_queue_may_preempt(bfqd)) {
++		struct bfq_queue *in_serv =
++			bfqd->in_service_queue;
++		BUG_ON(in_serv == bfqq);
++
++		bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
++				false, BFQ_BFQQ_PREEMPTED);
++		BUG_ON(in_serv->entity.budget < 0);
++	}
+ }
+ 
+ static void bfq_add_request(struct request *rq)
+ {
+ 	struct bfq_queue *bfqq = RQ_BFQQ(rq);
+-	struct bfq_entity *entity = &bfqq->entity;
+ 	struct bfq_data *bfqd = bfqq->bfqd;
+ 	struct request *next_rq, *prev;
+-	unsigned long old_wr_coeff = bfqq->wr_coeff;
++	unsigned int old_wr_coeff = bfqq->wr_coeff;
+ 	bool interactive = false;
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "add_request %d", rq_is_sync(rq));
++	bfq_log_bfqq(bfqd, bfqq, "add_request: size %u %s",
++		     blk_rq_sectors(rq), rq_is_sync(rq) ? "S" : "A");
++
++	if (bfqq->wr_coeff > 1) /* queue is being weight-raised */
++		bfq_log_bfqq(bfqd, bfqq,
++			"raising period dur %u/%u msec, old coeff %u, w %d(%d)",
++			jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
++			jiffies_to_msecs(bfqq->wr_cur_max_time),
++			bfqq->wr_coeff,
++			bfqq->entity.weight, bfqq->entity.orig_weight);
++
+ 	bfqq->queued[rq_is_sync(rq)]++;
+ 	bfqd->queued++;
+ 
+ 	elv_rb_add(&bfqq->sort_list, rq);
+ 
+ 	/*
+-	 * Check if this request is a better next-serve candidate.
++	 * Check if this request is a better next-to-serve candidate.
+ 	 */
+ 	prev = bfqq->next_rq;
+ 	next_rq = bfq_choose_req(bfqd, bfqq->next_rq, rq, bfqd->last_position);
+@@ -886,160 +1391,10 @@ static void bfq_add_request(struct request *rq)
+ 	if (prev != bfqq->next_rq)
+ 		bfq_pos_tree_add_move(bfqd, bfqq);
+ 
+-	if (!bfq_bfqq_busy(bfqq)) {
+-		bool soft_rt, coop_or_in_burst,
+-		     idle_for_long_time = time_is_before_jiffies(
+-						bfqq->budget_timeout +
+-						bfqd->bfq_wr_min_idle_time);
+-
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-		bfqg_stats_update_io_add(bfqq_group(RQ_BFQQ(rq)), bfqq,
+-					 rq->cmd_flags);
+-#endif
+-		if (bfq_bfqq_sync(bfqq)) {
+-			bool already_in_burst =
+-			   !hlist_unhashed(&bfqq->burst_list_node) ||
+-			   bfq_bfqq_in_large_burst(bfqq);
+-			bfq_handle_burst(bfqd, bfqq, idle_for_long_time);
+-			/*
+-			 * If bfqq was not already in the current burst,
+-			 * then, at this point, bfqq either has been
+-			 * added to the current burst or has caused the
+-			 * current burst to terminate. In particular, in
+-			 * the second case, bfqq has become the first
+-			 * queue in a possible new burst.
+-			 * In both cases last_ins_in_burst needs to be
+-			 * moved forward.
+-			 */
+-			if (!already_in_burst)
+-				bfqd->last_ins_in_burst = jiffies;
+-		}
+-
+-		coop_or_in_burst = bfq_bfqq_in_large_burst(bfqq) ||
+-			bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh;
+-		soft_rt = bfqd->bfq_wr_max_softrt_rate > 0 &&
+-			!coop_or_in_burst &&
+-			time_is_before_jiffies(bfqq->soft_rt_next_start);
+-		interactive = !coop_or_in_burst && idle_for_long_time;
+-		entity->budget = max_t(unsigned long, bfqq->max_budget,
+-				       bfq_serv_to_charge(next_rq, bfqq));
+-
+-		if (!bfq_bfqq_IO_bound(bfqq)) {
+-			if (time_before(jiffies,
+-					RQ_BIC(rq)->ttime.last_end_request +
+-					bfqd->bfq_slice_idle)) {
+-				bfqq->requests_within_timer++;
+-				if (bfqq->requests_within_timer >=
+-				    bfqd->bfq_requests_within_timer)
+-					bfq_mark_bfqq_IO_bound(bfqq);
+-			} else
+-				bfqq->requests_within_timer = 0;
+-		}
+-
+-		if (!bfqd->low_latency)
+-			goto add_bfqq_busy;
+-
+-		if (bfq_bfqq_just_split(bfqq))
+-			goto set_prio_changed;
+-
+-		/*
+-		 * If the queue:
+-		 * - is not being boosted,
+-		 * - has been idle for enough time,
+-		 * - is not a sync queue or is linked to a bfq_io_cq (it is
+-		 *   shared "for its nature" or it is not shared and its
+-		 *   requests have not been redirected to a shared queue)
+-		 * start a weight-raising period.
+-		 */
+-		if (old_wr_coeff == 1 && (interactive || soft_rt) &&
+-		    (!bfq_bfqq_sync(bfqq) || bfqq->bic)) {
+-			bfqq->wr_coeff = bfqd->bfq_wr_coeff;
+-			if (interactive)
+-				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
+-			else
+-				bfqq->wr_cur_max_time =
+-					bfqd->bfq_wr_rt_max_time;
+-			bfq_log_bfqq(bfqd, bfqq,
+-				     "wrais starting at %lu, rais_max_time %u",
+-				     jiffies,
+-				     jiffies_to_msecs(bfqq->wr_cur_max_time));
+-		} else if (old_wr_coeff > 1) {
+-			if (interactive)
+-				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
+-			else if (coop_or_in_burst ||
+-				 (bfqq->wr_cur_max_time ==
+-				  bfqd->bfq_wr_rt_max_time &&
+-				  !soft_rt)) {
+-				bfqq->wr_coeff = 1;
+-				bfq_log_bfqq(bfqd, bfqq,
+-					"wrais ending at %lu, rais_max_time %u",
+-					jiffies,
+-					jiffies_to_msecs(bfqq->
+-						wr_cur_max_time));
+-			} else if (time_before(
+-					bfqq->last_wr_start_finish +
+-					bfqq->wr_cur_max_time,
+-					jiffies +
+-					bfqd->bfq_wr_rt_max_time) &&
+-				   soft_rt) {
+-				/*
+-				 *
+-				 * The remaining weight-raising time is lower
+-				 * than bfqd->bfq_wr_rt_max_time, which means
+-				 * that the application is enjoying weight
+-				 * raising either because deemed soft-rt in
+-				 * the near past, or because deemed interactive
+-				 * a long ago.
+-				 * In both cases, resetting now the current
+-				 * remaining weight-raising time for the
+-				 * application to the weight-raising duration
+-				 * for soft rt applications would not cause any
+-				 * latency increase for the application (as the
+-				 * new duration would be higher than the
+-				 * remaining time).
+-				 *
+-				 * In addition, the application is now meeting
+-				 * the requirements for being deemed soft rt.
+-				 * In the end we can correctly and safely
+-				 * (re)charge the weight-raising duration for
+-				 * the application with the weight-raising
+-				 * duration for soft rt applications.
+-				 *
+-				 * In particular, doing this recharge now, i.e.,
+-				 * before the weight-raising period for the
+-				 * application finishes, reduces the probability
+-				 * of the following negative scenario:
+-				 * 1) the weight of a soft rt application is
+-				 *    raised at startup (as for any newly
+-				 *    created application),
+-				 * 2) since the application is not interactive,
+-				 *    at a certain time weight-raising is
+-				 *    stopped for the application,
+-				 * 3) at that time the application happens to
+-				 *    still have pending requests, and hence
+-				 *    is destined to not have a chance to be
+-				 *    deemed soft rt before these requests are
+-				 *    completed (see the comments to the
+-				 *    function bfq_bfqq_softrt_next_start()
+-				 *    for details on soft rt detection),
+-				 * 4) these pending requests experience a high
+-				 *    latency because the application is not
+-				 *    weight-raised while they are pending.
+-				 */
+-				bfqq->last_wr_start_finish = jiffies;
+-				bfqq->wr_cur_max_time =
+-					bfqd->bfq_wr_rt_max_time;
+-			}
+-		}
+-set_prio_changed:
+-		if (old_wr_coeff != bfqq->wr_coeff)
+-			entity->prio_changed = 1;
+-add_bfqq_busy:
+-		bfqq->last_idle_bklogged = jiffies;
+-		bfqq->service_from_backlogged = 0;
+-		bfq_clear_bfqq_softrt_update(bfqq);
+-		bfq_add_bfqq_busy(bfqd, bfqq);
+-	} else {
++	if (!bfq_bfqq_busy(bfqq)) /* switching to busy ... */
++		bfq_bfqq_handle_idle_busy_switch(bfqd, bfqq, old_wr_coeff,
++						 rq, &interactive);
++	else {
+ 		if (bfqd->low_latency && old_wr_coeff == 1 && !rq_is_sync(rq) &&
+ 		    time_is_before_jiffies(
+ 				bfqq->last_wr_start_finish +
+@@ -1048,16 +1403,43 @@ add_bfqq_busy:
+ 			bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
+ 
+ 			bfqd->wr_busy_queues++;
+-			entity->prio_changed = 1;
++			bfqq->entity.prio_changed = 1;
+ 			bfq_log_bfqq(bfqd, bfqq,
+-			    "non-idle wrais starting at %lu, rais_max_time %u",
+-			    jiffies,
+-			    jiffies_to_msecs(bfqq->wr_cur_max_time));
++				     "non-idle wrais starting, "
++				     "wr_max_time %u wr_busy %d",
++				     jiffies_to_msecs(bfqq->wr_cur_max_time),
++				     bfqd->wr_busy_queues);
+ 		}
+ 		if (prev != bfqq->next_rq)
+ 			bfq_updated_next_req(bfqd, bfqq);
+ 	}
+ 
++	/*
++	 * Assign jiffies to last_wr_start_finish in the following
++	 * cases:
++	 *
++	 * . if bfqq is not going to be weight-raised, because, for
++	 *   non weight-raised queues, last_wr_start_finish stores the
++	 *   arrival time of the last request; as of now, this piece
++	 *   of information is used only for deciding whether to
++	 *   weight-raise async queues
++	 *
++	 * . if bfqq is not weight-raised, because, if bfqq is now
++	 *   switching to weight-raised, then last_wr_start_finish
++	 *   stores the time when weight-raising starts
++	 *
++	 * . if bfqq is interactive, because, regardless of whether
++	 *   bfqq is currently weight-raised, the weight-raising
++	 *   period must start or restart (this case is considered
++	 *   separately because it is not detected by the above
++	 *   conditions, if bfqq is already weight-raised)
++	 *
++	 * last_wr_start_finish has to be updated also if bfqq is soft
++	 * real-time, because the weight-raising period is constantly
++	 * restarted on idle-to-busy transitions for these queues, but
++	 * this is already done in bfq_bfqq_handle_idle_busy_switch if
++	 * needed.
++	 */
+ 	if (bfqd->low_latency &&
+ 		(old_wr_coeff == 1 || bfqq->wr_coeff == 1 || interactive))
+ 		bfqq->last_wr_start_finish = jiffies;
+@@ -1081,14 +1463,24 @@ static struct request *bfq_find_rq_fmerge(struct bfq_data *bfqd,
+ 	return NULL;
+ }
+ 
++static sector_t get_sdist(sector_t last_pos, struct request *rq)
++{
++	sector_t sdist = 0;
++
++	if (last_pos) {
++		if (last_pos < blk_rq_pos(rq))
++			sdist = blk_rq_pos(rq) - last_pos;
++		else
++			sdist = last_pos - blk_rq_pos(rq);
++	}
++
++	return sdist;
++}
++
+ static void bfq_activate_request(struct request_queue *q, struct request *rq)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+-
+ 	bfqd->rq_in_driver++;
+-	bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
+-	bfq_log(bfqd, "activate_request: new bfqd->last_position %llu",
+-		(unsigned long long) bfqd->last_position);
+ }
+ 
+ static void bfq_deactivate_request(struct request_queue *q, struct request *rq)
+@@ -1105,6 +1497,9 @@ static void bfq_remove_request(struct request *rq)
+ 	struct bfq_data *bfqd = bfqq->bfqd;
+ 	const int sync = rq_is_sync(rq);
+ 
++	BUG_ON(bfqq->entity.service > bfqq->entity.budget &&
++	       bfqq == bfqd->in_service_queue);
++
+ 	if (bfqq->next_rq == rq) {
+ 		bfqq->next_rq = bfq_find_next_rq(bfqd, bfqq, rq);
+ 		bfq_updated_next_req(bfqd, bfqq);
+@@ -1118,8 +1513,25 @@ static void bfq_remove_request(struct request *rq)
+ 	elv_rb_del(&bfqq->sort_list, rq);
+ 
+ 	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
+-		if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue)
++		BUG_ON(bfqq->entity.budget < 0);
++
++		if (bfq_bfqq_busy(bfqq) && bfqq != bfqd->in_service_queue) {
+ 			bfq_del_bfqq_busy(bfqd, bfqq, 1);
++
++			/* bfqq emptied. In normal operation, when
++			 * bfqq is empty, bfqq->entity.service and
++			 * bfqq->entity.budget must contain,
++			 * respectively, the service received and the
++			 * budget used last time bfqq emptied. These
++			 * facts do not hold in this case, as at least
++			 * this last removal occurred while bfqq is
++			 * not in service. To avoid inconsistencies,
++			 * reset both bfqq->entity.service and
++			 * bfqq->entity.budget.
++			 */
++			bfqq->entity.budget = bfqq->entity.service = 0;
++		}
++
+ 		/*
+ 		 * Remove queue from request-position tree as it is empty.
+ 		 */
+@@ -1133,9 +1545,8 @@ static void bfq_remove_request(struct request *rq)
+ 		BUG_ON(bfqq->meta_pending == 0);
+ 		bfqq->meta_pending--;
+ 	}
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	bfqg_stats_update_io_remove(bfqq_group(bfqq), rq->cmd_flags);
+-#endif
++	bfqg_stats_update_io_remove(bfqq_group(bfqq), req_op(rq),
++				    rq->cmd_flags);
+ }
+ 
+ static int bfq_merge(struct request_queue *q, struct request **req,
+@@ -1145,7 +1556,7 @@ static int bfq_merge(struct request_queue *q, struct request **req,
+ 	struct request *__rq;
+ 
+ 	__rq = bfq_find_rq_fmerge(bfqd, bio);
+-	if (__rq && elv_rq_merge_ok(__rq, bio)) {
++	if (__rq && elv_bio_merge_ok(__rq, bio)) {
+ 		*req = __rq;
+ 		return ELEVATOR_FRONT_MERGE;
+ 	}
+@@ -1190,7 +1601,8 @@ static void bfq_merged_request(struct request_queue *q, struct request *req,
+ static void bfq_bio_merged(struct request_queue *q, struct request *req,
+ 			   struct bio *bio)
+ {
+-	bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio->bi_rw);
++	bfqg_stats_update_io_merged(bfqq_group(RQ_BFQQ(req)), bio_op(bio),
++				    bio->bi_opf);
+ }
+ #endif
+ 
+@@ -1210,7 +1622,7 @@ static void bfq_merged_requests(struct request_queue *q, struct request *rq,
+ 	 */
+ 	if (bfqq == next_bfqq &&
+ 	    !list_empty(&rq->queuelist) && !list_empty(&next->queuelist) &&
+-	    time_before(next->fifo_time, rq->fifo_time)) {
++	    next->fifo_time < rq->fifo_time) {
+ 		list_del_init(&rq->queuelist);
+ 		list_replace_init(&next->queuelist, &rq->queuelist);
+ 		rq->fifo_time = next->fifo_time;
+@@ -1220,21 +1632,31 @@ static void bfq_merged_requests(struct request_queue *q, struct request *rq,
+ 		bfqq->next_rq = rq;
+ 
+ 	bfq_remove_request(next);
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	bfqg_stats_update_io_merged(bfqq_group(bfqq), next->cmd_flags);
+-#endif
++	bfqg_stats_update_io_merged(bfqq_group(bfqq), req_op(next),
++				    next->cmd_flags);
+ }
+ 
+ /* Must be called with bfqq != NULL */
+ static void bfq_bfqq_end_wr(struct bfq_queue *bfqq)
+ {
+ 	BUG_ON(!bfqq);
++
+ 	if (bfq_bfqq_busy(bfqq))
+ 		bfqq->bfqd->wr_busy_queues--;
+ 	bfqq->wr_coeff = 1;
+ 	bfqq->wr_cur_max_time = 0;
+-	/* Trigger a weight change on the next activation of the queue */
++	bfqq->last_wr_start_finish = jiffies;
++	/*
++	 * Trigger a weight change on the next invocation of
++	 * __bfq_entity_update_weight_prio.
++	 */
+ 	bfqq->entity.prio_changed = 1;
++	bfq_log_bfqq(bfqq->bfqd, bfqq,
++		     "end_wr: wrais ending at %lu, rais_max_time %u",
++		     bfqq->last_wr_start_finish,
++		     jiffies_to_msecs(bfqq->wr_cur_max_time));
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "end_wr: wr_busy %d",
++		     bfqq->bfqd->wr_busy_queues);
+ }
+ 
+ static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
+@@ -1277,7 +1699,7 @@ static int bfq_rq_close_to_sector(void *io_struct, bool request,
+ 				  sector_t sector)
+ {
+ 	return abs(bfq_io_struct_pos(io_struct, request) - sector) <=
+-	       BFQQ_SEEK_THR;
++	       BFQQ_CLOSE_THR;
+ }
+ 
+ static struct bfq_queue *bfqq_find_close(struct bfq_data *bfqd,
+@@ -1399,7 +1821,7 @@ bfq_setup_merge(struct bfq_queue *bfqq, struct bfq_queue *new_bfqq)
+ 	 * throughput.
+ 	 */
+ 	bfqq->new_bfqq = new_bfqq;
+-	atomic_add(process_refs, &new_bfqq->ref);
++	new_bfqq->ref += process_refs;
+ 	return new_bfqq;
+ }
+ 
+@@ -1430,9 +1852,23 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
+ }
+ 
+ /*
+- * Attempt to schedule a merge of bfqq with the currently in-service queue
+- * or with a close queue among the scheduled queues.
+- * Return NULL if no merge was scheduled, a pointer to the shared bfq_queue
++ * If this function returns true, then bfqq cannot be merged. The idea
++ * is that true cooperation happens very early after processes start
++ * to do I/O. Usually, late cooperations are just accidental false
++ * positives. In case bfqq is weight-raised, such false positives
++ * would evidently degrade latency guarantees for bfqq.
++ */
++bool wr_from_too_long(struct bfq_queue *bfqq)
++{
++	return bfqq->wr_coeff > 1 &&
++		time_is_before_jiffies(bfqq->last_wr_start_finish +
++				       msecs_to_jiffies(100));
++}
++
++/*
++ * Attempt to schedule a merge of bfqq with the currently in-service
++ * queue or with a close queue among the scheduled queues.  Return
++ * NULL if no merge was scheduled, a pointer to the shared bfq_queue
+  * structure otherwise.
+  *
+  * The OOM queue is not allowed to participate to cooperation: in fact, since
+@@ -1441,6 +1877,18 @@ static bool bfq_may_be_close_cooperator(struct bfq_queue *bfqq,
+  * handle merging with the OOM queue would be quite complex and expensive
+  * to maintain. Besides, in such a critical condition as an out of memory,
+  * the benefits of queue merging may be little relevant, or even negligible.
++ *
++ * Weight-raised queues can be merged only if their weight-raising
++ * period has just started. In fact cooperating processes are usually
++ * started together. Thus, with this filter we avoid false positives
++ * that would jeopardize low-latency guarantees.
++ *
++ * WARNING: queue merging may impair fairness among non-weight raised
++ * queues, for at least two reasons: 1) the original weight of a
++ * merged queue may change during the merged state, 2) even being the
++ * weight the same, a merged queue may be bloated with many more
++ * requests than the ones produced by its originally-associated
++ * process.
+  */
+ static struct bfq_queue *
+ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+@@ -1450,16 +1898,32 @@ bfq_setup_cooperator(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 
+ 	if (bfqq->new_bfqq)
+ 		return bfqq->new_bfqq;
+-	if (!io_struct || unlikely(bfqq == &bfqd->oom_bfqq))
++
++	if (io_struct && wr_from_too_long(bfqq) &&
++	    likely(bfqq != &bfqd->oom_bfqq))
++		bfq_log_bfqq(bfqd, bfqq,
++			     "would have looked for coop, but bfq%d wr",
++			bfqq->pid);
++
++	if (!io_struct ||
++	    wr_from_too_long(bfqq) ||
++	    unlikely(bfqq == &bfqd->oom_bfqq))
+ 		return NULL;
+-	/* If device has only one backlogged bfq_queue, don't search. */
++
++	/* If there is only one backlogged queue, don't search. */
+ 	if (bfqd->busy_queues == 1)
+ 		return NULL;
+ 
+ 	in_service_bfqq = bfqd->in_service_queue;
+ 
++	if (in_service_bfqq && in_service_bfqq != bfqq &&
++	    bfqd->in_service_bic && wr_from_too_long(in_service_bfqq)
++	    && likely(in_service_bfqq == &bfqd->oom_bfqq))
++		bfq_log_bfqq(bfqd, bfqq,
++		"would have tried merge with in-service-queue, but wr");
++
+ 	if (!in_service_bfqq || in_service_bfqq == bfqq ||
+-	    !bfqd->in_service_bic ||
++	    !bfqd->in_service_bic || wr_from_too_long(in_service_bfqq) ||
+ 	    unlikely(in_service_bfqq == &bfqd->oom_bfqq))
+ 		goto check_scheduled;
+ 
+@@ -1481,7 +1945,15 @@ check_scheduled:
+ 
+ 	BUG_ON(new_bfqq && bfqq->entity.parent != new_bfqq->entity.parent);
+ 
+-	if (new_bfqq && likely(new_bfqq != &bfqd->oom_bfqq) &&
++	if (new_bfqq && wr_from_too_long(new_bfqq) &&
++	    likely(new_bfqq != &bfqd->oom_bfqq) &&
++	    bfq_may_be_close_cooperator(bfqq, new_bfqq))
++		bfq_log_bfqq(bfqd, bfqq,
++			     "would have merged with bfq%d, but wr",
++			     new_bfqq->pid);
++
++	if (new_bfqq && !wr_from_too_long(new_bfqq) &&
++	    likely(new_bfqq != &bfqd->oom_bfqq) &&
+ 	    bfq_may_be_close_cooperator(bfqq, new_bfqq))
+ 		return bfq_setup_merge(bfqq, new_bfqq);
+ 
+@@ -1490,53 +1962,24 @@ check_scheduled:
+ 
+ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
+ {
++	struct bfq_io_cq *bic = bfqq->bic;
++
+ 	/*
+ 	 * If !bfqq->bic, the queue is already shared or its requests
+ 	 * have already been redirected to a shared queue; both idle window
+ 	 * and weight raising state have already been saved. Do nothing.
+ 	 */
+-	if (!bfqq->bic)
++	if (!bic)
+ 		return;
+-	if (bfqq->bic->wr_time_left)
+-		/*
+-		 * This is the queue of a just-started process, and would
+-		 * deserve weight raising: we set wr_time_left to the full
+-		 * weight-raising duration to trigger weight-raising when
+-		 * and if the queue is split and the first request of the
+-		 * queue is enqueued.
+-		 */
+-		bfqq->bic->wr_time_left = bfq_wr_duration(bfqq->bfqd);
+-	else if (bfqq->wr_coeff > 1) {
+-		unsigned long wr_duration =
+-			jiffies - bfqq->last_wr_start_finish;
+-		/*
+-		 * It may happen that a queue's weight raising period lasts
+-		 * longer than its wr_cur_max_time, as weight raising is
+-		 * handled only when a request is enqueued or dispatched (it
+-		 * does not use any timer). If the weight raising period is
+-		 * about to end, don't save it.
+-		 */
+-		if (bfqq->wr_cur_max_time <= wr_duration)
+-			bfqq->bic->wr_time_left = 0;
+-		else
+-			bfqq->bic->wr_time_left =
+-				bfqq->wr_cur_max_time - wr_duration;
+-		/*
+-		 * The bfq_queue is becoming shared or the requests of the
+-		 * process owning the queue are being redirected to a shared
+-		 * queue. Stop the weight raising period of the queue, as in
+-		 * both cases it should not be owned by an interactive or
+-		 * soft real-time application.
+-		 */
+-		bfq_bfqq_end_wr(bfqq);
+-	} else
+-		bfqq->bic->wr_time_left = 0;
+-	bfqq->bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
+-	bfqq->bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
+-	bfqq->bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
+-	bfqq->bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
+-	bfqq->bic->cooperations++;
+-	bfqq->bic->failed_cooperations = 0;
++
++	bic->saved_idle_window = bfq_bfqq_idle_window(bfqq);
++	bic->saved_IO_bound = bfq_bfqq_IO_bound(bfqq);
++	bic->saved_in_large_burst = bfq_bfqq_in_large_burst(bfqq);
++	bic->was_in_burst_list = !hlist_unhashed(&bfqq->burst_list_node);
++	bic->saved_wr_coeff = bfqq->wr_coeff;
++	bic->saved_wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt;
++	bic->saved_last_wr_start_finish = bfqq->last_wr_start_finish;
++	BUG_ON(time_is_after_jiffies(bfqq->last_wr_start_finish));
+ }
+ 
+ static void bfq_get_bic_reference(struct bfq_queue *bfqq)
+@@ -1561,6 +2004,40 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
+ 	if (bfq_bfqq_IO_bound(bfqq))
+ 		bfq_mark_bfqq_IO_bound(new_bfqq);
+ 	bfq_clear_bfqq_IO_bound(bfqq);
++
++	/*
++	 * If bfqq is weight-raised, then let new_bfqq inherit
++	 * weight-raising. To reduce false positives, neglect the case
++	 * where bfqq has just been created, but has not yet made it
++	 * to be weight-raised (which may happen because EQM may merge
++	 * bfqq even before bfq_add_request is executed for the first
++	 * time for bfqq). Handling this case would however be very
++	 * easy, thanks to the flag just_created.
++	 */
++	if (new_bfqq->wr_coeff == 1 && bfqq->wr_coeff > 1) {
++		new_bfqq->wr_coeff = bfqq->wr_coeff;
++		new_bfqq->wr_cur_max_time = bfqq->wr_cur_max_time;
++		new_bfqq->last_wr_start_finish = bfqq->last_wr_start_finish;
++		new_bfqq->wr_start_at_switch_to_srt = bfqq->wr_start_at_switch_to_srt;
++		if (bfq_bfqq_busy(new_bfqq))
++			bfqd->wr_busy_queues++;
++		new_bfqq->entity.prio_changed = 1;
++		bfq_log_bfqq(bfqd, new_bfqq,
++			     "wr start after merge with %d, rais_max_time %u",
++			     bfqq->pid,
++			     jiffies_to_msecs(bfqq->wr_cur_max_time));
++	}
++
++	if (bfqq->wr_coeff > 1) { /* bfqq has given its wr to new_bfqq */
++		bfqq->wr_coeff = 1;
++		bfqq->entity.prio_changed = 1;
++		if (bfq_bfqq_busy(bfqq))
++			bfqd->wr_busy_queues--;
++	}
++
++	bfq_log_bfqq(bfqd, new_bfqq, "merge_bfqqs: wr_busy %d",
++		     bfqd->wr_busy_queues);
++
+ 	/*
+ 	 * Grab a reference to the bic, to prevent it from being destroyed
+ 	 * before being possibly touched by a bfq_split_bfqq().
+@@ -1587,20 +2064,8 @@ bfq_merge_bfqqs(struct bfq_data *bfqd, struct bfq_io_cq *bic,
+ 	bfq_put_queue(bfqq);
+ }
+ 
+-static void bfq_bfqq_increase_failed_cooperations(struct bfq_queue *bfqq)
+-{
+-	struct bfq_io_cq *bic = bfqq->bic;
+-	struct bfq_data *bfqd = bfqq->bfqd;
+-
+-	if (bic && bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh) {
+-		bic->failed_cooperations++;
+-		if (bic->failed_cooperations >= bfqd->bfq_failed_cooperations)
+-			bic->cooperations = 0;
+-	}
+-}
+-
+-static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+-			   struct bio *bio)
++static int bfq_allow_bio_merge(struct request_queue *q, struct request *rq,
++			       struct bio *bio)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+ 	struct bfq_io_cq *bic;
+@@ -1610,7 +2075,7 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+ 	 * Disallow merge of a sync bio into an async request.
+ 	 */
+ 	if (bfq_bio_sync(bio) && !rq_is_sync(rq))
+-		return 0;
++		return false;
+ 
+ 	/*
+ 	 * Lookup the bfqq that this bio will be queued with. Allow
+@@ -1619,7 +2084,7 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+ 	 */
+ 	bic = bfq_bic_lookup(bfqd, current->io_context);
+ 	if (!bic)
+-		return 0;
++		return false;
+ 
+ 	bfqq = bic_to_bfqq(bic, bfq_bio_sync(bio));
+ 	/*
+@@ -1636,30 +2101,107 @@ static int bfq_allow_merge(struct request_queue *q, struct request *rq,
+ 			 * to decide whether bio and rq can be merged.
+ 			 */
+ 			bfqq = new_bfqq;
+-		} else
+-			bfq_bfqq_increase_failed_cooperations(bfqq);
++		}
+ 	}
+ 
+ 	return bfqq == RQ_BFQQ(rq);
+ }
+ 
++static int bfq_allow_rq_merge(struct request_queue *q, struct request *rq,
++			      struct request *next)
++{
++	return RQ_BFQQ(rq) == RQ_BFQQ(next);
++}
++
++/*
++ * Set the maximum time for the in-service queue to consume its
++ * budget. This prevents seeky processes from lowering the throughput.
++ * In practice, a time-slice service scheme is used with seeky
++ * processes.
++ */
++static void bfq_set_budget_timeout(struct bfq_data *bfqd,
++				   struct bfq_queue *bfqq)
++{
++	unsigned int timeout_coeff;
++
++	if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
++		timeout_coeff = 1;
++	else
++		timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
++
++	bfqd->last_budget_start = ktime_get();
++
++	bfqq->budget_timeout = jiffies +
++		bfqd->bfq_timeout * timeout_coeff;
++
++	bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
++		jiffies_to_msecs(bfqd->bfq_timeout * timeout_coeff));
++}
++
+ static void __bfq_set_in_service_queue(struct bfq_data *bfqd,
+ 				       struct bfq_queue *bfqq)
+ {
+ 	if (bfqq) {
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 		bfqg_stats_update_avg_queue_size(bfqq_group(bfqq));
+-#endif
+ 		bfq_mark_bfqq_must_alloc(bfqq);
+-		bfq_mark_bfqq_budget_new(bfqq);
+ 		bfq_clear_bfqq_fifo_expire(bfqq);
+ 
+ 		bfqd->budgets_assigned = (bfqd->budgets_assigned*7 + 256) / 8;
+ 
++		BUG_ON(bfqq == bfqd->in_service_queue);
++		BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
++
++		if (time_is_before_jiffies(bfqq->last_wr_start_finish) &&
++		    bfqq->wr_coeff > 1 &&
++		    bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time &&
++		    time_is_before_jiffies(bfqq->budget_timeout)) {
++			/*
++			 * For soft real-time queues, move the start
++			 * of the weight-raising period forward by the
++			 * time the queue has not received any
++			 * service. Otherwise, a relatively long
++			 * service delay is likely to cause the
++			 * weight-raising period of the queue to end,
++			 * because of the short duration of the
++			 * weight-raising period of a soft real-time
++			 * queue.  It is worth noting that this move
++			 * is not so dangerous for the other queues,
++			 * because soft real-time queues are not
++			 * greedy.
++			 *
++			 * To not add a further variable, we use the
++			 * overloaded field budget_timeout to
++			 * determine for how long the queue has not
++			 * received service, i.e., how much time has
++			 * elapsed since the queue expired. However,
++			 * this is a little imprecise, because
++			 * budget_timeout is set to jiffies if bfqq
++			 * not only expires, but also remains with no
++			 * request.
++			 */
++			bfqq->last_wr_start_finish += jiffies -
++				max_t(unsigned long, bfqq->last_wr_start_finish,
++				      bfqq->budget_timeout);
++			if (time_is_after_jiffies(bfqq->last_wr_start_finish)) {
++			       pr_crit(
++			       "BFQ WARNING:last %lu budget %lu jiffies %lu",
++			       bfqq->last_wr_start_finish,
++			       bfqq->budget_timeout,
++			       jiffies);
++			       pr_crit("diff %lu", jiffies -
++				       max_t(unsigned long,
++					     bfqq->last_wr_start_finish,
++					     bfqq->budget_timeout));
++			       bfqq->last_wr_start_finish = jiffies;
++			}
++		}
++
++		bfq_set_budget_timeout(bfqd, bfqq);
+ 		bfq_log_bfqq(bfqd, bfqq,
+ 			     "set_in_service_queue, cur-budget = %d",
+ 			     bfqq->entity.budget);
+-	}
++	} else
++		bfq_log(bfqd, "set_in_service_queue: NULL");
+ 
+ 	bfqd->in_service_queue = bfqq;
+ }
+@@ -1675,36 +2217,11 @@ static struct bfq_queue *bfq_set_in_service_queue(struct bfq_data *bfqd)
+ 	return bfqq;
+ }
+ 
+-/*
+- * If enough samples have been computed, return the current max budget
+- * stored in bfqd, which is dynamically updated according to the
+- * estimated disk peak rate; otherwise return the default max budget
+- */
+-static int bfq_max_budget(struct bfq_data *bfqd)
+-{
+-	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
+-		return bfq_default_max_budget;
+-	else
+-		return bfqd->bfq_max_budget;
+-}
+-
+-/*
+- * Return min budget, which is a fraction of the current or default
+- * max budget (trying with 1/32)
+- */
+-static int bfq_min_budget(struct bfq_data *bfqd)
+-{
+-	if (bfqd->budgets_assigned < bfq_stats_min_budgets)
+-		return bfq_default_max_budget / 32;
+-	else
+-		return bfqd->bfq_max_budget / 32;
+-}
+-
+ static void bfq_arm_slice_timer(struct bfq_data *bfqd)
+ {
+ 	struct bfq_queue *bfqq = bfqd->in_service_queue;
+ 	struct bfq_io_cq *bic;
+-	unsigned long sl;
++	u32 sl;
+ 
+ 	BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
+ 
+@@ -1728,59 +2245,343 @@ static void bfq_arm_slice_timer(struct bfq_data *bfqd)
+ 	sl = bfqd->bfq_slice_idle;
+ 	/*
+ 	 * Unless the queue is being weight-raised or the scenario is
+-	 * asymmetric, grant only minimum idle time if the queue either
+-	 * has been seeky for long enough or has already proved to be
+-	 * constantly seeky.
++	 * asymmetric, grant only minimum idle time if the queue
++	 * is seeky. A long idling is preserved for a weight-raised
++	 * queue, or, more in general, in an asymemtric scenario,
++	 * because a long idling is needed for guaranteeing to a queue
++	 * its reserved share of the throughput (in particular, it is
++	 * needed if the queue has a higher weight than some other
++	 * queue).
+ 	 */
+-	if (bfq_sample_valid(bfqq->seek_samples) &&
+-	    ((BFQQ_SEEKY(bfqq) && bfqq->entity.service >
+-				  bfq_max_budget(bfqq->bfqd) / 8) ||
+-	      bfq_bfqq_constantly_seeky(bfqq)) && bfqq->wr_coeff == 1 &&
++	if (BFQQ_SEEKY(bfqq) && bfqq->wr_coeff == 1 &&
+ 	    bfq_symmetric_scenario(bfqd))
+-		sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
+-	else if (bfqq->wr_coeff > 1)
+-		sl = sl * 3;
++		sl = min_t(u32, sl, BFQ_MIN_TT);
++
+ 	bfqd->last_idling_start = ktime_get();
+-	mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	hrtimer_start(&bfqd->idle_slice_timer, ns_to_ktime(sl),
++		      HRTIMER_MODE_REL);
+ 	bfqg_stats_set_start_idle_time(bfqq_group(bfqq));
+-#endif
+-	bfq_log(bfqd, "arm idle: %u/%u ms",
+-		jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
++	bfq_log(bfqd, "arm idle: %ld/%ld ms",
++		sl / NSEC_PER_MSEC, bfqd->bfq_slice_idle / NSEC_PER_MSEC);
+ }
+ 
+ /*
+- * Set the maximum time for the in-service queue to consume its
+- * budget. This prevents seeky processes from lowering the disk
+- * throughput (always guaranteed with a time slice scheme as in CFQ).
++ * In autotuning mode, max_budget is dynamically recomputed as the
++ * amount of sectors transferred in timeout at the estimated peak
++ * rate. This enables BFQ to utilize a full timeslice with a full
++ * budget, even if the in-service queue is served at peak rate. And
++ * this maximises throughput with sequential workloads.
+  */
+-static void bfq_set_budget_timeout(struct bfq_data *bfqd)
++static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd)
+ {
+-	struct bfq_queue *bfqq = bfqd->in_service_queue;
+-	unsigned int timeout_coeff;
++	return (u64)bfqd->peak_rate * USEC_PER_MSEC *
++		jiffies_to_msecs(bfqd->bfq_timeout)>>BFQ_RATE_SHIFT;
++}
+ 
+-	if (bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time)
+-		timeout_coeff = 1;
++/*
++ * Update parameters related to throughput and responsiveness, as a
++ * function of the estimated peak rate. See comments on
++ * bfq_calc_max_budget(), and on T_slow and T_fast arrays.
++ */
++void update_thr_responsiveness_params(struct bfq_data *bfqd)
++{
++	int dev_type = blk_queue_nonrot(bfqd->queue);
++
++	if (bfqd->bfq_user_max_budget == 0) {
++		bfqd->bfq_max_budget =
++			bfq_calc_max_budget(bfqd);
++		BUG_ON(bfqd->bfq_max_budget < 0);
++		bfq_log(bfqd, "new max_budget = %d",
++			bfqd->bfq_max_budget);
++	}
++
++	if (bfqd->device_speed == BFQ_BFQD_FAST &&
++	    bfqd->peak_rate < device_speed_thresh[dev_type]) {
++		bfqd->device_speed = BFQ_BFQD_SLOW;
++		bfqd->RT_prod = R_slow[dev_type] *
++			T_slow[dev_type];
++	} else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
++		   bfqd->peak_rate > device_speed_thresh[dev_type]) {
++		bfqd->device_speed = BFQ_BFQD_FAST;
++		bfqd->RT_prod = R_fast[dev_type] *
++			T_fast[dev_type];
++	}
++
++	bfq_log(bfqd,
++"dev_type %s dev_speed_class = %s (%llu sects/sec), thresh %llu setcs/sec",
++		dev_type == 0 ? "ROT" : "NONROT",
++		bfqd->device_speed == BFQ_BFQD_FAST ? "FAST" : "SLOW",
++		bfqd->device_speed == BFQ_BFQD_FAST ?
++		(USEC_PER_SEC*(u64)R_fast[dev_type])>>BFQ_RATE_SHIFT :
++		(USEC_PER_SEC*(u64)R_slow[dev_type])>>BFQ_RATE_SHIFT,
++		(USEC_PER_SEC*(u64)device_speed_thresh[dev_type])>>
++		BFQ_RATE_SHIFT);
++}
++
++void bfq_reset_rate_computation(struct bfq_data *bfqd, struct request *rq)
++{
++	if (rq != NULL) { /* new rq dispatch now, reset accordingly */
++		bfqd->last_dispatch = bfqd->first_dispatch = ktime_get_ns() ;
++		bfqd->peak_rate_samples = 1;
++		bfqd->sequential_samples = 0;
++		bfqd->tot_sectors_dispatched = bfqd->last_rq_max_size =
++			blk_rq_sectors(rq);
++	} else /* no new rq dispatched, just reset the number of samples */
++		bfqd->peak_rate_samples = 0; /* full re-init on next disp. */
++
++	bfq_log(bfqd,
++		"reset_rate_computation at end, sample %u/%u tot_sects %llu",
++		bfqd->peak_rate_samples, bfqd->sequential_samples,
++		bfqd->tot_sectors_dispatched);
++}
++
++void bfq_update_rate_reset(struct bfq_data *bfqd, struct request *rq)
++{
++	u32 rate, weight, divisor;
++
++	/*
++	 * For the convergence property to hold (see comments on
++	 * bfq_update_peak_rate()) and for the assessment to be
++	 * reliable, a minimum number of samples must be present, and
++	 * a minimum amount of time must have elapsed. If not so, do
++	 * not compute new rate. Just reset parameters, to get ready
++	 * for a new evaluation attempt.
++	 */
++	if (bfqd->peak_rate_samples < BFQ_RATE_MIN_SAMPLES ||
++	    bfqd->delta_from_first < BFQ_RATE_MIN_INTERVAL) {
++		bfq_log(bfqd,
++	"update_rate_reset: only resetting, delta_first %lluus samples %d",
++			bfqd->delta_from_first>>10, bfqd->peak_rate_samples);
++		goto reset_computation;
++	}
++
++	/*
++	 * If a new request completion has occurred after last
++	 * dispatch, then, to approximate the rate at which requests
++	 * have been served by the device, it is more precise to
++	 * extend the observation interval to the last completion.
++	 */
++	bfqd->delta_from_first =
++		max_t(u64, bfqd->delta_from_first,
++		      bfqd->last_completion - bfqd->first_dispatch);
++
++	BUG_ON(bfqd->delta_from_first == 0);
++	/*
++	 * Rate computed in sects/usec, and not sects/nsec, for
++	 * precision issues.
++	 */
++	rate = div64_ul(bfqd->tot_sectors_dispatched<<BFQ_RATE_SHIFT,
++			div_u64(bfqd->delta_from_first, NSEC_PER_USEC));
++
++	bfq_log(bfqd,
++"update_rate_reset: tot_sects %llu delta_first %lluus rate %llu sects/s (%d)",
++		bfqd->tot_sectors_dispatched, bfqd->delta_from_first>>10,
++		((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT),
++		rate > 20<<BFQ_RATE_SHIFT);
++
++	/*
++	 * Peak rate not updated if:
++	 * - the percentage of sequential dispatches is below 3/4 of the
++	 *   total, and rate is below the current estimated peak rate
++	 * - rate is unreasonably high (> 20M sectors/sec)
++	 */
++	if ((bfqd->peak_rate_samples > (3 * bfqd->sequential_samples)>>2 &&
++	     rate <= bfqd->peak_rate) ||
++		rate > 20<<BFQ_RATE_SHIFT) {
++		bfq_log(bfqd,
++		"update_rate_reset: goto reset, samples %u/%u rate/peak %llu/%llu",
++		bfqd->peak_rate_samples, bfqd->sequential_samples,
++		((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT),
++		((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT));
++		goto reset_computation;
++	} else {
++		bfq_log(bfqd,
++		"update_rate_reset: do update, samples %u/%u rate/peak %llu/%llu",
++		bfqd->peak_rate_samples, bfqd->sequential_samples,
++		((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT),
++		((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT));
++	}
++
++	/*
++	 * We have to update the peak rate, at last! To this purpose,
++	 * we use a low-pass filter. We compute the smoothing constant
++	 * of the filter as a function of the 'weight' of the new
++	 * measured rate.
++	 *
++	 * As can be seen in next formulas, we define this weight as a
++	 * quantity proportional to how sequential the workload is,
++	 * and to how long the observation time interval is.
++	 *
++	 * The weight runs from 0 to 8. The maximum value of the
++	 * weight, 8, yields the minimum value for the smoothing
++	 * constant. At this minimum value for the smoothing constant,
++	 * the measured rate contributes for half of the next value of
++	 * the estimated peak rate.
++	 *
++	 * So, the first step is to compute the weight as a function
++	 * of how sequential the workload is. Note that the weight
++	 * cannot reach 9, because bfqd->sequential_samples cannot
++	 * become equal to bfqd->peak_rate_samples, which, in its
++	 * turn, holds true because bfqd->sequential_samples is not
++	 * incremented for the first sample.
++	 */
++	weight = (9 * bfqd->sequential_samples) / bfqd->peak_rate_samples;
++
++	/*
++	 * Second step: further refine the weight as a function of the
++	 * duration of the observation interval.
++	 */
++	weight = min_t(u32, 8,
++		       div_u64(weight * bfqd->delta_from_first,
++			       BFQ_RATE_REF_INTERVAL));
++
++	/*
++	 * Divisor ranging from 10, for minimum weight, to 2, for
++	 * maximum weight.
++	 */
++	divisor = 10 - weight;
++	BUG_ON(divisor == 0);
++
++	/*
++	 * Finally, update peak rate:
++	 *
++	 * peak_rate = peak_rate * (divisor-1) / divisor  +  rate / divisor
++	 */
++	bfqd->peak_rate *= divisor-1;
++	bfqd->peak_rate /= divisor;
++	rate /= divisor; /* smoothing constant alpha = 1/divisor */
++
++	bfq_log(bfqd,
++		"update_rate_reset: divisor %d tmp_peak_rate %llu tmp_rate %u",
++		divisor,
++		((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT),
++		(u32)((USEC_PER_SEC*(u64)rate)>>BFQ_RATE_SHIFT));
++
++	BUG_ON(bfqd->peak_rate == 0);
++	BUG_ON(bfqd->peak_rate > 20<<BFQ_RATE_SHIFT);
++
++	bfqd->peak_rate += rate;
++	update_thr_responsiveness_params(bfqd);
++	BUG_ON(bfqd->peak_rate > 20<<BFQ_RATE_SHIFT);
++
++reset_computation:
++	bfq_reset_rate_computation(bfqd, rq);
++}
++
++/*
++ * Update the read/write peak rate (the main quantity used for
++ * auto-tuning, see update_thr_responsiveness_params()).
++ *
++ * It is not trivial to estimate the peak rate (correctly): because of
++ * the presence of sw and hw queues between the scheduler and the
++ * device components that finally serve I/O requests, it is hard to
++ * say exactly when a given dispatched request is served inside the
++ * device, and for how long. As a consequence, it is hard to know
++ * precisely at what rate a given set of requests is actually served
++ * by the device.
++ *
++ * On the opposite end, the dispatch time of any request is trivially
++ * available, and, from this piece of information, the "dispatch rate"
++ * of requests can be immediately computed. So, the idea in the next
++ * function is to use what is known, namely request dispatch times
++ * (plus, when useful, request completion times), to estimate what is
++ * unknown, namely in-device request service rate.
++ *
++ * The main issue is that, because of the above facts, the rate at
++ * which a certain set of requests is dispatched over a certain time
++ * interval can vary greatly with respect to the rate at which the
++ * same requests are then served. But, since the size of any
++ * intermediate queue is limited, and the service scheme is lossless
++ * (no request is silently dropped), the following obvious convergence
++ * property holds: the number of requests dispatched MUST become
++ * closer and closer to the number of requests completed as the
++ * observation interval grows. This is the key property used in
++ * the next function to estimate the peak service rate as a function
++ * of the observed dispatch rate. The function assumes to be invoked
++ * on every request dispatch.
++ */
++void bfq_update_peak_rate(struct bfq_data *bfqd, struct request *rq)
++{
++	u64 now_ns = ktime_get_ns();
++
++	if (bfqd->peak_rate_samples == 0) { /* first dispatch */
++		bfq_log(bfqd,
++		"update_peak_rate: goto reset, samples %d",
++				bfqd->peak_rate_samples) ;
++		bfq_reset_rate_computation(bfqd, rq);
++		goto update_last_values; /* will add one sample */
++	}
++
++	/*
++	 * Device idle for very long: the observation interval lasting
++	 * up to this dispatch cannot be a valid observation interval
++	 * for computing a new peak rate (similarly to the late-
++	 * completion event in bfq_completed_request()). Go to
++	 * update_rate_and_reset to have the following three steps
++	 * taken:
++	 * - close the observation interval at the last (previous)
++	 *   request dispatch or completion
++	 * - compute rate, if possible, for that observation interval
++	 * - start a new observation interval with this dispatch
++	 */
++	if (now_ns - bfqd->last_dispatch > 100*NSEC_PER_MSEC &&
++	    bfqd->rq_in_driver == 0) {
++		bfq_log(bfqd,
++"update_peak_rate: jumping to updating&resetting delta_last %lluus samples %d",
++			(now_ns - bfqd->last_dispatch)>>10,
++			bfqd->peak_rate_samples) ;
++		goto update_rate_and_reset;
++	}
++
++	/* Update sampling information */
++	bfqd->peak_rate_samples++;
++
++	if ((bfqd->rq_in_driver > 0 ||
++		now_ns - bfqd->last_completion < BFQ_MIN_TT)
++	     && get_sdist(bfqd->last_position, rq) < BFQQ_SEEK_THR)
++		bfqd->sequential_samples++;
++
++	bfqd->tot_sectors_dispatched += blk_rq_sectors(rq);
++
++	/* Reset max observed rq size every 32 dispatches */
++	if (likely(bfqd->peak_rate_samples % 32))
++		bfqd->last_rq_max_size =
++			max_t(u32, blk_rq_sectors(rq), bfqd->last_rq_max_size);
+ 	else
+-		timeout_coeff = bfqq->entity.weight / bfqq->entity.orig_weight;
++		bfqd->last_rq_max_size = blk_rq_sectors(rq);
+ 
+-	bfqd->last_budget_start = ktime_get();
++	bfqd->delta_from_first = now_ns - bfqd->first_dispatch;
+ 
+-	bfq_clear_bfqq_budget_new(bfqq);
+-	bfqq->budget_timeout = jiffies +
+-		bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] * timeout_coeff;
++	bfq_log(bfqd,
++	"update_peak_rate: added samples %u/%u tot_sects %llu delta_first %lluus",
++		bfqd->peak_rate_samples, bfqd->sequential_samples,
++		bfqd->tot_sectors_dispatched,
++		bfqd->delta_from_first>>10);
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
+-		jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
+-		timeout_coeff));
++	/* Target observation interval not yet reached, go on sampling */
++	if (bfqd->delta_from_first < BFQ_RATE_REF_INTERVAL)
++		goto update_last_values;
++
++update_rate_and_reset:
++	bfq_update_rate_reset(bfqd, rq);
++update_last_values:
++	bfqd->last_position = blk_rq_pos(rq) + blk_rq_sectors(rq);
++	bfqd->last_dispatch = now_ns;
++
++	bfq_log(bfqd,
++	"update_peak_rate: delta_first %lluus last_pos %llu peak_rate %llu",
++		(now_ns - bfqd->first_dispatch)>>10,
++		(unsigned long long) bfqd->last_position,
++		((USEC_PER_SEC*(u64)bfqd->peak_rate)>>BFQ_RATE_SHIFT));
++	bfq_log(bfqd,
++	"update_peak_rate: samples at end %d", bfqd->peak_rate_samples);
+ }
+ 
+ /*
+- * Move request from internal lists to the request queue dispatch list.
++ * Move request from internal lists to the dispatch list of the request queue
+  */
+ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
+ {
+-	struct bfq_data *bfqd = q->elevator->elevator_data;
+ 	struct bfq_queue *bfqq = RQ_BFQQ(rq);
+ 
+ 	/*
+@@ -1794,15 +2595,10 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
+ 	 * incrementing bfqq->dispatched.
+ 	 */
+ 	bfqq->dispatched++;
++	bfq_update_peak_rate(q->elevator->elevator_data, rq);
++
+ 	bfq_remove_request(rq);
+ 	elv_dispatch_sort(q, rq);
+-
+-	if (bfq_bfqq_sync(bfqq))
+-		bfqd->sync_flight++;
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	bfqg_stats_update_dispatch(bfqq_group(bfqq), blk_rq_bytes(rq),
+-				   rq->cmd_flags);
+-#endif
+ }
+ 
+ /*
+@@ -1822,19 +2618,12 @@ static struct request *bfq_check_fifo(struct bfq_queue *bfqq)
+ 
+ 	rq = rq_entry_fifo(bfqq->fifo.next);
+ 
+-	if (time_before(jiffies, rq->fifo_time))
++	if (ktime_get_ns() < rq->fifo_time)
+ 		return NULL;
+ 
+ 	return rq;
+ }
+ 
+-static int bfq_bfqq_budget_left(struct bfq_queue *bfqq)
+-{
+-	struct bfq_entity *entity = &bfqq->entity;
+-
+-	return entity->budget - entity->service;
+-}
+-
+ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ {
+ 	BUG_ON(bfqq != bfqd->in_service_queue);
+@@ -1851,12 +2640,15 @@ static void __bfq_bfqq_expire(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		bfq_mark_bfqq_split_coop(bfqq);
+ 
+ 	if (RB_EMPTY_ROOT(&bfqq->sort_list)) {
+-		/*
+-		 * Overloading budget_timeout field to store the time
+-		 * at which the queue remains with no backlog; used by
+-		 * the weight-raising mechanism.
+-		 */
+-		bfqq->budget_timeout = jiffies;
++		if (bfqq->dispatched == 0)
++			/*
++			 * Overloading budget_timeout field to store
++			 * the time at which the queue remains with no
++			 * backlog and no outstanding request; used by
++			 * the weight-raising mechanism.
++			 */
++			bfqq->budget_timeout = jiffies;
++
+ 		bfq_del_bfqq_busy(bfqd, bfqq, 1);
+ 	} else {
+ 		bfq_activate_bfqq(bfqd, bfqq);
+@@ -1883,10 +2675,19 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
+ 	struct request *next_rq;
+ 	int budget, min_budget;
+ 
+-	budget = bfqq->max_budget;
++	BUG_ON(bfqq != bfqd->in_service_queue);
++
+ 	min_budget = bfq_min_budget(bfqd);
+ 
+-	BUG_ON(bfqq != bfqd->in_service_queue);
++	if (bfqq->wr_coeff == 1)
++		budget = bfqq->max_budget;
++	else /*
++	      * Use a constant, low budget for weight-raised queues,
++	      * to help achieve a low latency. Keep it slightly higher
++	      * than the minimum possible budget, to cause a little
++	      * bit fewer expirations.
++	      */
++		budget = 2 * min_budget;
+ 
+ 	bfq_log_bfqq(bfqd, bfqq, "recalc_budg: last budg %d, budg left %d",
+ 		bfqq->entity.budget, bfq_bfqq_budget_left(bfqq));
+@@ -1895,7 +2696,7 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
+ 	bfq_log_bfqq(bfqd, bfqq, "recalc_budg: sync %d, seeky %d",
+ 		bfq_bfqq_sync(bfqq), BFQQ_SEEKY(bfqd->in_service_queue));
+ 
+-	if (bfq_bfqq_sync(bfqq)) {
++	if (bfq_bfqq_sync(bfqq) && bfqq->wr_coeff == 1) {
+ 		switch (reason) {
+ 		/*
+ 		 * Caveat: in all the following cases we trade latency
+@@ -1937,14 +2738,10 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
+ 			break;
+ 		case BFQ_BFQQ_BUDGET_TIMEOUT:
+ 			/*
+-			 * We double the budget here because: 1) it
+-			 * gives the chance to boost the throughput if
+-			 * this is not a seeky process (which may have
+-			 * bumped into this timeout because of, e.g.,
+-			 * ZBR), 2) together with charge_full_budget
+-			 * it helps give seeky processes higher
+-			 * timestamps, and hence be served less
+-			 * frequently.
++			 * We double the budget here because it gives
++			 * the chance to boost the throughput if this
++			 * is not a seeky process (and has bumped into
++			 * this timeout because of, e.g., ZBR).
+ 			 */
+ 			budget = min(budget * 2, bfqd->bfq_max_budget);
+ 			break;
+@@ -1961,17 +2758,49 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
+ 			budget = min(budget * 4, bfqd->bfq_max_budget);
+ 			break;
+ 		case BFQ_BFQQ_NO_MORE_REQUESTS:
+-		       /*
+-			* Leave the budget unchanged.
+-			*/
++			/*
++			 * For queues that expire for this reason, it
++			 * is particularly important to keep the
++			 * budget close to the actual service they
++			 * need. Doing so reduces the timestamp
++			 * misalignment problem described in the
++			 * comments in the body of
++			 * __bfq_activate_entity. In fact, suppose
++			 * that a queue systematically expires for
++			 * BFQ_BFQQ_NO_MORE_REQUESTS and presents a
++			 * new request in time to enjoy timestamp
++			 * back-shifting. The larger the budget of the
++			 * queue is with respect to the service the
++			 * queue actually requests in each service
++			 * slot, the more times the queue can be
++			 * reactivated with the same virtual finish
++			 * time. It follows that, even if this finish
++			 * time is pushed to the system virtual time
++			 * to reduce the consequent timestamp
++			 * misalignment, the queue unjustly enjoys for
++			 * many re-activations a lower finish time
++			 * than all newly activated queues.
++			 *
++			 * The service needed by bfqq is measured
++			 * quite precisely by bfqq->entity.service.
++			 * Since bfqq does not enjoy device idling,
++			 * bfqq->entity.service is equal to the number
++			 * of sectors that the process associated with
++			 * bfqq requested to read/write before waiting
++			 * for request completions, or blocking for
++			 * other reasons.
++			 */
++			budget = max_t(int, bfqq->entity.service, min_budget);
++			break;
+ 		default:
+ 			return;
+ 		}
+-	} else
++	} else if (!bfq_bfqq_sync(bfqq))
+ 		/*
+-		 * Async queues get always the maximum possible budget
+-		 * (their ability to dispatch is limited by
+-		 * @bfqd->bfq_max_budget_async_rq).
++		 * Async queues get always the maximum possible
++		 * budget, as for them we do not care about latency
++		 * (in addition, their ability to dispatch is limited
++		 * by the charging factor).
+ 		 */
+ 		budget = bfqd->bfq_max_budget;
+ 
+@@ -1982,160 +2811,120 @@ static void __bfq_bfqq_recalc_budget(struct bfq_data *bfqd,
+ 		bfqq->max_budget = min(bfqq->max_budget, bfqd->bfq_max_budget);
+ 
+ 	/*
+-	 * Make sure that we have enough budget for the next request.
+-	 * Since the finish time of the bfqq must be kept in sync with
+-	 * the budget, be sure to call __bfq_bfqq_expire() after the
++	 * If there is still backlog, then assign a new budget, making
++	 * sure that it is large enough for the next request.  Since
++	 * the finish time of bfqq must be kept in sync with the
++	 * budget, be sure to call __bfq_bfqq_expire() *after* this
+ 	 * update.
++	 *
++	 * If there is no backlog, then no need to update the budget;
++	 * it will be updated on the arrival of a new request.
+ 	 */
+ 	next_rq = bfqq->next_rq;
+-	if (next_rq)
++	if (next_rq) {
++		BUG_ON(reason == BFQ_BFQQ_TOO_IDLE ||
++		       reason == BFQ_BFQQ_NO_MORE_REQUESTS);
+ 		bfqq->entity.budget = max_t(unsigned long, bfqq->max_budget,
+ 					    bfq_serv_to_charge(next_rq, bfqq));
+-	else
+-		bfqq->entity.budget = bfqq->max_budget;
++		BUG_ON(!bfq_bfqq_busy(bfqq));
++		BUG_ON(RB_EMPTY_ROOT(&bfqq->sort_list));
++	}
+ 
+ 	bfq_log_bfqq(bfqd, bfqq, "head sect: %u, new budget %d",
+ 			next_rq ? blk_rq_sectors(next_rq) : 0,
+ 			bfqq->entity.budget);
+ }
+ 
+-static unsigned long bfq_calc_max_budget(u64 peak_rate, u64 timeout)
+-{
+-	unsigned long max_budget;
+-
+-	/*
+-	 * The max_budget calculated when autotuning is equal to the
+-	 * amount of sectors transfered in timeout_sync at the
+-	 * estimated peak rate.
+-	 */
+-	max_budget = (unsigned long)(peak_rate * 1000 *
+-				     timeout >> BFQ_RATE_SHIFT);
+-
+-	return max_budget;
+-}
+-
+ /*
+- * In addition to updating the peak rate, checks whether the process
+- * is "slow", and returns 1 if so. This slow flag is used, in addition
+- * to the budget timeout, to reduce the amount of service provided to
+- * seeky processes, and hence reduce their chances to lower the
+- * throughput. See the code for more details.
++ * Return true if the process associated with bfqq is "slow". The slow
++ * flag is used, in addition to the budget timeout, to reduce the
++ * amount of service provided to seeky processes, and thus reduce
++ * their chances to lower the throughput. More details in the comments
++ * on the function bfq_bfqq_expire().
++ *
++ * An important observation is in order: as discussed in the comments
++ * on the function bfq_update_peak_rate(), with devices with internal
++ * queues, it is hard if ever possible to know when and for how long
++ * an I/O request is processed by the device (apart from the trivial
++ * I/O pattern where a new request is dispatched only after the
++ * previous one has been completed). This makes it hard to evaluate
++ * the real rate at which the I/O requests of each bfq_queue are
++ * served.  In fact, for an I/O scheduler like BFQ, serving a
++ * bfq_queue means just dispatching its requests during its service
++ * slot (i.e., until the budget of the queue is exhausted, or the
++ * queue remains idle, or, finally, a timeout fires). But, during the
++ * service slot of a bfq_queue, around 100 ms at most, the device may
++ * be even still processing requests of bfq_queues served in previous
++ * service slots. On the opposite end, the requests of the in-service
++ * bfq_queue may be completed after the service slot of the queue
++ * finishes.
++ *
++ * Anyway, unless more sophisticated solutions are used
++ * (where possible), the sum of the sizes of the requests dispatched
++ * during the service slot of a bfq_queue is probably the only
++ * approximation available for the service received by the bfq_queue
++ * during its service slot. And this sum is the quantity used in this
++ * function to evaluate the I/O speed of a process.
+  */
+-static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+-				 bool compensate, enum bfqq_expiration reason)
++static bool bfq_bfqq_is_slow(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++				 bool compensate, enum bfqq_expiration reason,
++				 unsigned long *delta_ms)
+ {
+-	u64 bw, usecs, expected, timeout;
+-	ktime_t delta;
+-	int update = 0;
++	ktime_t delta_ktime;
++	u32 delta_usecs;
++	bool slow = BFQQ_SEEKY(bfqq); /* if delta too short, use seekyness */
+ 
+-	if (!bfq_bfqq_sync(bfqq) || bfq_bfqq_budget_new(bfqq))
++	if (!bfq_bfqq_sync(bfqq))
+ 		return false;
+ 
+ 	if (compensate)
+-		delta = bfqd->last_idling_start;
+-	else
+-		delta = ktime_get();
+-	delta = ktime_sub(delta, bfqd->last_budget_start);
+-	usecs = ktime_to_us(delta);
+-
+-	/* Don't trust short/unrealistic values. */
+-	if (usecs < 100 || usecs >= LONG_MAX)
+-		return false;
+-
+-	/*
+-	 * Calculate the bandwidth for the last slice.  We use a 64 bit
+-	 * value to store the peak rate, in sectors per usec in fixed
+-	 * point math.  We do so to have enough precision in the estimate
+-	 * and to avoid overflows.
+-	 */
+-	bw = (u64)bfqq->entity.service << BFQ_RATE_SHIFT;
+-	do_div(bw, (unsigned long)usecs);
+-
+-	timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
+-
+-	/*
+-	 * Use only long (> 20ms) intervals to filter out spikes for
+-	 * the peak rate estimation.
+-	 */
+-	if (usecs > 20000) {
+-		if (bw > bfqd->peak_rate ||
+-		   (!BFQQ_SEEKY(bfqq) &&
+-		    reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
+-			bfq_log(bfqd, "measured bw =%llu", bw);
+-			/*
+-			 * To smooth oscillations use a low-pass filter with
+-			 * alpha=7/8, i.e.,
+-			 * new_rate = (7/8) * old_rate + (1/8) * bw
+-			 */
+-			do_div(bw, 8);
+-			if (bw == 0)
+-				return 0;
+-			bfqd->peak_rate *= 7;
+-			do_div(bfqd->peak_rate, 8);
+-			bfqd->peak_rate += bw;
+-			update = 1;
+-			bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
+-		}
+-
+-		update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
+-
+-		if (bfqd->peak_rate_samples < BFQ_PEAK_RATE_SAMPLES)
+-			bfqd->peak_rate_samples++;
+-
+-		if (bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES &&
+-		    update) {
+-			int dev_type = blk_queue_nonrot(bfqd->queue);
+-
+-			if (bfqd->bfq_user_max_budget == 0) {
+-				bfqd->bfq_max_budget =
+-					bfq_calc_max_budget(bfqd->peak_rate,
+-							    timeout);
+-				bfq_log(bfqd, "new max_budget=%d",
+-					bfqd->bfq_max_budget);
+-			}
+-			if (bfqd->device_speed == BFQ_BFQD_FAST &&
+-			    bfqd->peak_rate < device_speed_thresh[dev_type]) {
+-				bfqd->device_speed = BFQ_BFQD_SLOW;
+-				bfqd->RT_prod = R_slow[dev_type] *
+-						T_slow[dev_type];
+-			} else if (bfqd->device_speed == BFQ_BFQD_SLOW &&
+-			    bfqd->peak_rate > device_speed_thresh[dev_type]) {
+-				bfqd->device_speed = BFQ_BFQD_FAST;
+-				bfqd->RT_prod = R_fast[dev_type] *
+-						T_fast[dev_type];
+-			}
+-		}
++		delta_ktime = bfqd->last_idling_start;
++	else
++		delta_ktime = ktime_get();
++	delta_ktime = ktime_sub(delta_ktime, bfqd->last_budget_start);
++	delta_usecs = ktime_to_us(delta_ktime);
++
++	/* don't trust short/unrealistic values. */
++	if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) {
++		if (blk_queue_nonrot(bfqd->queue))
++			 /*
++			  * give same worst-case guarantees as idling
++			  * for seeky
++			  */
++			*delta_ms = BFQ_MIN_TT / NSEC_PER_MSEC;
++		else /* charge at least one seek */
++			*delta_ms = bfq_slice_idle / NSEC_PER_MSEC;
++
++		bfq_log(bfqd, "bfq_bfqq_is_slow: unrealistic %u", delta_usecs);
++
++		return slow;
+ 	}
+ 
+-	/*
+-	 * If the process has been served for a too short time
+-	 * interval to let its possible sequential accesses prevail on
+-	 * the initial seek time needed to move the disk head on the
+-	 * first sector it requested, then give the process a chance
+-	 * and for the moment return false.
+-	 */
+-	if (bfqq->entity.budget <= bfq_max_budget(bfqd) / 8)
+-		return false;
++	*delta_ms = delta_usecs / USEC_PER_MSEC;
+ 
+ 	/*
+-	 * A process is considered ``slow'' (i.e., seeky, so that we
+-	 * cannot treat it fairly in the service domain, as it would
+-	 * slow down too much the other processes) if, when a slice
+-	 * ends for whatever reason, it has received service at a
+-	 * rate that would not be high enough to complete the budget
+-	 * before the budget timeout expiration.
++	 * Use only long (> 20ms) intervals to filter out excessive
++	 * spikes in service rate estimation.
+ 	 */
+-	expected = bw * 1000 * timeout >> BFQ_RATE_SHIFT;
++	if (delta_usecs > 20000) {
++		/*
++		 * Caveat for rotational devices: processes doing I/O
++		 * in the slower disk zones tend to be slow(er) even
++		 * if not seeky. In this respect, the estimated peak
++		 * rate is likely to be an average over the disk
++		 * surface. Accordingly, to not be too harsh with
++		 * unlucky processes, a process is deemed slow only if
++		 * its rate has been lower than half of the estimated
++		 * peak rate.
++		 */
++		slow = bfqq->entity.service < bfqd->bfq_max_budget / 2;
++		bfq_log(bfqd, "bfq_bfqq_is_slow: relative rate %d/%d",
++			bfqq->entity.service, bfqd->bfq_max_budget);
++	}
+ 
+-	/*
+-	 * Caveat: processes doing IO in the slower disk zones will
+-	 * tend to be slow(er) even if not seeky. And the estimated
+-	 * peak rate will actually be an average over the disk
+-	 * surface. Hence, to not be too harsh with unlucky processes,
+-	 * we keep a budget/3 margin of safety before declaring a
+-	 * process slow.
+-	 */
+-	return expected > (4 * bfqq->entity.budget) / 3;
++	bfq_log_bfqq(bfqd, bfqq, "bfq_bfqq_is_slow: slow %d", slow);
++
++	return slow;
+ }
+ 
+ /*
+@@ -2193,20 +2982,35 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
+ 						struct bfq_queue *bfqq)
+ {
++	bfq_log_bfqq(bfqd, bfqq,
++"softrt_next_start: service_blkg %lu soft_rate %u sects/sec interval %u",
++		     bfqq->service_from_backlogged,
++		     bfqd->bfq_wr_max_softrt_rate,
++		     jiffies_to_msecs(HZ * bfqq->service_from_backlogged /
++				      bfqd->bfq_wr_max_softrt_rate));
++
+ 	return max(bfqq->last_idle_bklogged +
+ 		   HZ * bfqq->service_from_backlogged /
+ 		   bfqd->bfq_wr_max_softrt_rate,
+-		   jiffies + bfqq->bfqd->bfq_slice_idle + 4);
++		   jiffies + nsecs_to_jiffies(bfqq->bfqd->bfq_slice_idle) + 4);
++}
++
++/*
++ * Return the farthest future time instant according to jiffies
++ * macros.
++ */
++static unsigned long bfq_greatest_from_now(void)
++{
++	return jiffies + MAX_JIFFY_OFFSET;
+ }
+ 
+ /*
+- * Return the largest-possible time instant such that, for as long as possible,
+- * the current time will be lower than this time instant according to the macro
+- * time_is_before_jiffies().
++ * Return the farthest past time instant according to jiffies
++ * macros.
+  */
+-static unsigned long bfq_infinity_from_now(unsigned long now)
++static unsigned long bfq_smallest_from_now(void)
+ {
+-	return now + ULONG_MAX / 2;
++	return jiffies - MAX_JIFFY_OFFSET;
+ }
+ 
+ /**
+@@ -2216,28 +3020,24 @@ static unsigned long bfq_infinity_from_now(unsigned long now)
+  * @compensate: if true, compensate for the time spent idling.
+  * @reason: the reason causing the expiration.
+  *
++ * If the process associated with bfqq does slow I/O (e.g., because it
++ * issues random requests), we charge bfqq with the time it has been
++ * in service instead of the service it has received (see
++ * bfq_bfqq_charge_time for details on how this goal is achieved). As
++ * a consequence, bfqq will typically get higher timestamps upon
++ * reactivation, and hence it will be rescheduled as if it had
++ * received more service than what it has actually received. In the
++ * end, bfqq receives less service in proportion to how slowly its
++ * associated process consumes its budgets (and hence how seriously it
++ * tends to lower the throughput). In addition, this time-charging
++ * strategy guarantees time fairness among slow processes. In
++ * contrast, if the process associated with bfqq is not slow, we
++ * charge bfqq exactly with the service it has received.
+  *
+- * If the process associated to the queue is slow (i.e., seeky), or in
+- * case of budget timeout, or, finally, if it is async, we
+- * artificially charge it an entire budget (independently of the
+- * actual service it received). As a consequence, the queue will get
+- * higher timestamps than the correct ones upon reactivation, and
+- * hence it will be rescheduled as if it had received more service
+- * than what it actually received. In the end, this class of processes
+- * will receive less service in proportion to how slowly they consume
+- * their budgets (and hence how seriously they tend to lower the
+- * throughput).
+- *
+- * In contrast, when a queue expires because it has been idling for
+- * too much or because it exhausted its budget, we do not touch the
+- * amount of service it has received. Hence when the queue will be
+- * reactivated and its timestamps updated, the latter will be in sync
+- * with the actual service received by the queue until expiration.
+- *
+- * Charging a full budget to the first type of queues and the exact
+- * service to the others has the effect of using the WF2Q+ policy to
+- * schedule the former on a timeslice basis, without violating the
+- * service domain guarantees of the latter.
++ * Charging time to the first type of queues and the exact service to
++ * the other has the effect of using the WF2Q+ policy to schedule the
++ * former on a timeslice basis, without violating service domain
++ * guarantees among the latter.
+  */
+ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 			    struct bfq_queue *bfqq,
+@@ -2245,41 +3045,52 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 			    enum bfqq_expiration reason)
+ {
+ 	bool slow;
++	unsigned long delta = 0;
++	struct bfq_entity *entity = &bfqq->entity;
+ 
+ 	BUG_ON(bfqq != bfqd->in_service_queue);
+ 
+ 	/*
+-	 * Update disk peak rate for autotuning and check whether the
+-	 * process is slow (see bfq_update_peak_rate).
++	 * Check whether the process is slow (see bfq_bfqq_is_slow).
+ 	 */
+-	slow = bfq_update_peak_rate(bfqd, bfqq, compensate, reason);
++	slow = bfq_bfqq_is_slow(bfqd, bfqq, compensate, reason, &delta);
+ 
+ 	/*
+-	 * As above explained, 'punish' slow (i.e., seeky), timed-out
+-	 * and async queues, to favor sequential sync workloads.
+-	 *
+-	 * Processes doing I/O in the slower disk zones will tend to be
+-	 * slow(er) even if not seeky. Hence, since the estimated peak
+-	 * rate is actually an average over the disk surface, these
+-	 * processes may timeout just for bad luck. To avoid punishing
+-	 * them we do not charge a full budget to a process that
+-	 * succeeded in consuming at least 2/3 of its budget.
++	 * Increase service_from_backlogged before next statement,
++	 * because the possible next invocation of
++	 * bfq_bfqq_charge_time would likely inflate
++	 * entity->service. In contrast, service_from_backlogged must
++	 * contain real service, to enable the soft real-time
++	 * heuristic to correctly compute the bandwidth consumed by
++	 * bfqq.
+ 	 */
+-	if (slow || (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
+-		     bfq_bfqq_budget_left(bfqq) >=  bfqq->entity.budget / 3))
+-		bfq_bfqq_charge_full_budget(bfqq);
++	bfqq->service_from_backlogged += entity->service;
+ 
+-	bfqq->service_from_backlogged += bfqq->entity.service;
++	/*
++	 * As above explained, charge slow (typically seeky) and
++	 * timed-out queues with the time and not the service
++	 * received, to favor sequential workloads.
++	 *
++	 * Processes doing I/O in the slower disk zones will tend to
++	 * be slow(er) even if not seeky. Therefore, since the
++	 * estimated peak rate is actually an average over the disk
++	 * surface, these processes may timeout just for bad luck. To
++	 * avoid punishing them, do not charge time to processes that
++	 * succeeded in consuming at least 2/3 of their budget. This
++	 * allows BFQ to preserve enough elasticity to still perform
++	 * bandwidth, and not time, distribution with little unlucky
++	 * or quasi-sequential processes.
++	 */
++	if (bfqq->wr_coeff == 1 &&
++	    (slow ||
++	     (reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
++	      bfq_bfqq_budget_left(bfqq) >=  entity->budget / 3)))
++		bfq_bfqq_charge_time(bfqd, bfqq, delta);
+ 
+-	if (BFQQ_SEEKY(bfqq) && reason == BFQ_BFQQ_BUDGET_TIMEOUT &&
+-	    !bfq_bfqq_constantly_seeky(bfqq)) {
+-		bfq_mark_bfqq_constantly_seeky(bfqq);
+-		if (!blk_queue_nonrot(bfqd->queue))
+-			bfqd->const_seeky_busy_in_flight_queues++;
+-	}
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
+ 
+ 	if (reason == BFQ_BFQQ_TOO_IDLE &&
+-	    bfqq->entity.service <= 2 * bfqq->entity.budget / 10)
++	    entity->service <= 2 * entity->budget / 10)
+ 		bfq_clear_bfqq_IO_bound(bfqq);
+ 
+ 	if (bfqd->low_latency && bfqq->wr_coeff == 1)
+@@ -2288,19 +3099,23 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 	if (bfqd->low_latency && bfqd->bfq_wr_max_softrt_rate > 0 &&
+ 	    RB_EMPTY_ROOT(&bfqq->sort_list)) {
+ 		/*
+-		 * If we get here, and there are no outstanding requests,
+-		 * then the request pattern is isochronous (see the comments
+-		 * to the function bfq_bfqq_softrt_next_start()). Hence we
+-		 * can compute soft_rt_next_start. If, instead, the queue
+-		 * still has outstanding requests, then we have to wait
+-		 * for the completion of all the outstanding requests to
++		 * If we get here, and there are no outstanding
++		 * requests, then the request pattern is isochronous
++		 * (see the comments on the function
++		 * bfq_bfqq_softrt_next_start()). Thus we can compute
++		 * soft_rt_next_start. If, instead, the queue still
++		 * has outstanding requests, then we have to wait for
++		 * the completion of all the outstanding requests to
+ 		 * discover whether the request pattern is actually
+ 		 * isochronous.
+ 		 */
+-		if (bfqq->dispatched == 0)
++		BUG_ON(bfqd->busy_queues < 1);
++		if (bfqq->dispatched == 0) {
+ 			bfqq->soft_rt_next_start =
+ 				bfq_bfqq_softrt_next_start(bfqd, bfqq);
+-		else {
++			bfq_log_bfqq(bfqd, bfqq, "new soft_rt_next %lu",
++				     bfqq->soft_rt_next_start);
++		} else {
+ 			/*
+ 			 * The application is still waiting for the
+ 			 * completion of one or more requests:
+@@ -2317,7 +3132,7 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 			 *    happened to be in the past.
+ 			 */
+ 			bfqq->soft_rt_next_start =
+-				bfq_infinity_from_now(jiffies);
++				bfq_greatest_from_now();
+ 			/*
+ 			 * Schedule an update of soft_rt_next_start to when
+ 			 * the task may be discovered to be isochronous.
+@@ -2327,15 +3142,27 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 	}
+ 
+ 	bfq_log_bfqq(bfqd, bfqq,
+-		"expire (%d, slow %d, num_disp %d, idle_win %d)", reason,
+-		slow, bfqq->dispatched, bfq_bfqq_idle_window(bfqq));
++		"expire (%d, slow %d, num_disp %d, idle_win %d, weight %d)",
++		     reason, slow, bfqq->dispatched,
++		     bfq_bfqq_idle_window(bfqq), entity->weight);
+ 
+ 	/*
+ 	 * Increase, decrease or leave budget unchanged according to
+ 	 * reason.
+ 	 */
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
+ 	__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
++	BUG_ON(bfqq->next_rq == NULL &&
++	       bfqq->entity.budget < bfqq->entity.service);
+ 	__bfq_bfqq_expire(bfqd, bfqq);
++
++	BUG_ON(!bfq_bfqq_busy(bfqq) && reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
++		!bfq_class_idle(bfqq));
++
++	if (!bfq_bfqq_busy(bfqq) &&
++	    reason != BFQ_BFQQ_BUDGET_TIMEOUT &&
++	    reason != BFQ_BFQQ_BUDGET_EXHAUSTED)
++		bfq_mark_bfqq_non_blocking_wait_rq(bfqq);
+ }
+ 
+ /*
+@@ -2345,20 +3172,17 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+  */
+ static bool bfq_bfqq_budget_timeout(struct bfq_queue *bfqq)
+ {
+-	if (bfq_bfqq_budget_new(bfqq) ||
+-	    time_before(jiffies, bfqq->budget_timeout))
+-		return false;
+-	return true;
++	return time_is_before_eq_jiffies(bfqq->budget_timeout);
+ }
+ 
+ /*
+- * If we expire a queue that is waiting for the arrival of a new
+- * request, we may prevent the fictitious timestamp back-shifting that
+- * allows the guarantees of the queue to be preserved (see [1] for
+- * this tricky aspect). Hence we return true only if this condition
+- * does not hold, or if the queue is slow enough to deserve only to be
+- * kicked off for preserving a high throughput.
+-*/
++ * If we expire a queue that is actively waiting (i.e., with the
++ * device idled) for the arrival of a new request, then we may incur
++ * the timestamp misalignment problem described in the body of the
++ * function __bfq_activate_entity. Hence we return true only if this
++ * condition does not hold, or if the queue is slow enough to deserve
++ * only to be kicked off for preserving a high throughput.
++ */
+ static bool bfq_may_expire_for_budg_timeout(struct bfq_queue *bfqq)
+ {
+ 	bfq_log_bfqq(bfqq->bfqd, bfqq,
+@@ -2400,10 +3224,12 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ {
+ 	struct bfq_data *bfqd = bfqq->bfqd;
+ 	bool idling_boosts_thr, idling_boosts_thr_without_issues,
+-		all_queues_seeky, on_hdd_and_not_all_queues_seeky,
+ 		idling_needed_for_service_guarantees,
+ 		asymmetric_scenario;
+ 
++	if (bfqd->strict_guarantees)
++		return true;
++
+ 	/*
+ 	 * The next variable takes into account the cases where idling
+ 	 * boosts the throughput.
+@@ -2466,74 +3292,27 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 		bfqd->wr_busy_queues == 0;
+ 
+ 	/*
+-	 * There are then two cases where idling must be performed not
++	 * There is then a case where idling must be performed not
+ 	 * for throughput concerns, but to preserve service
+-	 * guarantees. In the description of these cases, we say, for
+-	 * short, that a queue is sequential/random if the process
+-	 * associated to the queue issues sequential/random requests
+-	 * (in the second case the queue may be tagged as seeky or
+-	 * even constantly_seeky).
+-	 *
+-	 * To introduce the first case, we note that, since
+-	 * bfq_bfqq_idle_window(bfqq) is false if the device is
+-	 * NCQ-capable and bfqq is random (see
+-	 * bfq_update_idle_window()), then, from the above two
+-	 * assignments it follows that
+-	 * idling_boosts_thr_without_issues is false if the device is
+-	 * NCQ-capable and bfqq is random. Therefore, for this case,
+-	 * device idling would never be allowed if we used just
+-	 * idling_boosts_thr_without_issues to decide whether to allow
+-	 * it. And, beneficially, this would imply that throughput
+-	 * would always be boosted also with random I/O on NCQ-capable
+-	 * HDDs.
++	 * guarantees.
+ 	 *
+-	 * But we must be careful on this point, to avoid an unfair
+-	 * treatment for bfqq. In fact, because of the same above
+-	 * assignments, idling_boosts_thr_without_issues is, on the
+-	 * other hand, true if 1) the device is an HDD and bfqq is
+-	 * sequential, and 2) there are no busy weight-raised
+-	 * queues. As a consequence, if we used just
+-	 * idling_boosts_thr_without_issues to decide whether to idle
+-	 * the device, then with an HDD we might easily bump into a
+-	 * scenario where queues that are sequential and I/O-bound
+-	 * would enjoy idling, whereas random queues would not. The
+-	 * latter might then get a low share of the device throughput,
+-	 * simply because the former would get many requests served
+-	 * after being set as in service, while the latter would not.
+-	 *
+-	 * To address this issue, we start by setting to true a
+-	 * sentinel variable, on_hdd_and_not_all_queues_seeky, if the
+-	 * device is rotational and not all queues with pending or
+-	 * in-flight requests are constantly seeky (i.e., there are
+-	 * active sequential queues, and bfqq might then be mistreated
+-	 * if it does not enjoy idling because it is random).
+-	 */
+-	all_queues_seeky = bfq_bfqq_constantly_seeky(bfqq) &&
+-			   bfqd->busy_in_flight_queues ==
+-			   bfqd->const_seeky_busy_in_flight_queues;
+-
+-	on_hdd_and_not_all_queues_seeky =
+-		!blk_queue_nonrot(bfqd->queue) && !all_queues_seeky;
+-
+-	/*
+-	 * To introduce the second case where idling needs to be
+-	 * performed to preserve service guarantees, we can note that
+-	 * allowing the drive to enqueue more than one request at a
+-	 * time, and hence delegating de facto final scheduling
+-	 * decisions to the drive's internal scheduler, causes loss of
+-	 * control on the actual request service order. In particular,
+-	 * the critical situation is when requests from different
+-	 * processes happens to be present, at the same time, in the
+-	 * internal queue(s) of the drive. In such a situation, the
+-	 * drive, by deciding the service order of the
+-	 * internally-queued requests, does determine also the actual
+-	 * throughput distribution among these processes. But the
+-	 * drive typically has no notion or concern about per-process
+-	 * throughput distribution, and makes its decisions only on a
+-	 * per-request basis. Therefore, the service distribution
+-	 * enforced by the drive's internal scheduler is likely to
+-	 * coincide with the desired device-throughput distribution
+-	 * only in a completely symmetric scenario where:
++	 * To introduce this case, we can note that allowing the drive
++	 * to enqueue more than one request at a time, and hence
++	 * delegating de facto final scheduling decisions to the
++	 * drive's internal scheduler, entails loss of control on the
++	 * actual request service order. In particular, the critical
++	 * situation is when requests from different processes happen
++	 * to be present, at the same time, in the internal queue(s)
++	 * of the drive. In such a situation, the drive, by deciding
++	 * the service order of the internally-queued requests, does
++	 * determine also the actual throughput distribution among
++	 * these processes. But the drive typically has no notion or
++	 * concern about per-process throughput distribution, and
++	 * makes its decisions only on a per-request basis. Therefore,
++	 * the service distribution enforced by the drive's internal
++	 * scheduler is likely to coincide with the desired
++	 * device-throughput distribution only in a completely
++	 * symmetric scenario where:
+ 	 * (i)  each of these processes must get the same throughput as
+ 	 *      the others;
+ 	 * (ii) all these processes have the same I/O pattern
+@@ -2555,26 +3334,53 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 	 * words, only if sub-condition (i) holds, then idling is
+ 	 * allowed, and the device tends to be prevented from queueing
+ 	 * many requests, possibly of several processes. The reason
+-	 * for not controlling also sub-condition (ii) is that, first,
+-	 * in the case of an HDD, the asymmetry in terms of types of
+-	 * I/O patterns is already taken in to account in the above
+-	 * sentinel variable
+-	 * on_hdd_and_not_all_queues_seeky. Secondly, in the case of a
+-	 * flash-based device, we prefer however to privilege
+-	 * throughput (and idling lowers throughput for this type of
+-	 * devices), for the following reasons:
+-	 * 1) differently from HDDs, the service time of random
+-	 *    requests is not orders of magnitudes lower than the service
+-	 *    time of sequential requests; thus, even if processes doing
+-	 *    sequential I/O get a preferential treatment with respect to
+-	 *    others doing random I/O, the consequences are not as
+-	 *    dramatic as with HDDs;
+-	 * 2) if a process doing random I/O does need strong
+-	 *    throughput guarantees, it is hopefully already being
+-	 *    weight-raised, or the user is likely to have assigned it a
+-	 *    higher weight than the other processes (and thus
+-	 *    sub-condition (i) is likely to be false, which triggers
+-	 *    idling).
++	 * for not controlling also sub-condition (ii) is that we
++	 * exploit preemption to preserve guarantees in case of
++	 * symmetric scenarios, even if (ii) does not hold, as
++	 * explained in the next two paragraphs.
++	 *
++	 * Even if a queue, say Q, is expired when it remains idle, Q
++	 * can still preempt the new in-service queue if the next
++	 * request of Q arrives soon (see the comments on
++	 * bfq_bfqq_update_budg_for_activation). If all queues and
++	 * groups have the same weight, this form of preemption,
++	 * combined with the hole-recovery heuristic described in the
++	 * comments on function bfq_bfqq_update_budg_for_activation,
++	 * are enough to preserve a correct bandwidth distribution in
++	 * the mid term, even without idling. In fact, even if not
++	 * idling allows the internal queues of the device to contain
++	 * many requests, and thus to reorder requests, we can rather
++	 * safely assume that the internal scheduler still preserves a
++	 * minimum of mid-term fairness. The motivation for using
++	 * preemption instead of idling is that, by not idling,
++	 * service guarantees are preserved without minimally
++	 * sacrificing throughput. In other words, both a high
++	 * throughput and its desired distribution are obtained.
++	 *
++	 * More precisely, this preemption-based, idleless approach
++	 * provides fairness in terms of IOPS, and not sectors per
++	 * second. This can be seen with a simple example. Suppose
++	 * that there are two queues with the same weight, but that
++	 * the first queue receives requests of 8 sectors, while the
++	 * second queue receives requests of 1024 sectors. In
++	 * addition, suppose that each of the two queues contains at
++	 * most one request at a time, which implies that each queue
++	 * always remains idle after it is served. Finally, after
++	 * remaining idle, each queue receives very quickly a new
++	 * request. It follows that the two queues are served
++	 * alternatively, preempting each other if needed. This
++	 * implies that, although both queues have the same weight,
++	 * the queue with large requests receives a service that is
++	 * 1024/8 times as high as the service received by the other
++	 * queue.
++	 *
++	 * On the other hand, device idling is performed, and thus
++	 * pure sector-domain guarantees are provided, for the
++	 * following queues, which are likely to need stronger
++	 * throughput guarantees: weight-raised queues, and queues
++	 * with a higher weight than other queues. When such queues
++	 * are active, sub-condition (i) is false, which triggers
++	 * device idling.
+ 	 *
+ 	 * According to the above considerations, the next variable is
+ 	 * true (only) if sub-condition (i) holds. To compute the
+@@ -2582,7 +3388,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 	 * the function bfq_symmetric_scenario(), but also check
+ 	 * whether bfqq is being weight-raised, because
+ 	 * bfq_symmetric_scenario() does not take into account also
+-	 * weight-raised queues (see comments to
++	 * weight-raised queues (see comments on
+ 	 * bfq_weights_tree_add()).
+ 	 *
+ 	 * As a side note, it is worth considering that the above
+@@ -2604,17 +3410,16 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 	 * bfqq. Such a case is when bfqq became active in a burst of
+ 	 * queue activations. Queues that became active during a large
+ 	 * burst benefit only from throughput, as discussed in the
+-	 * comments to bfq_handle_burst. Thus, if bfqq became active
++	 * comments on bfq_handle_burst. Thus, if bfqq became active
+ 	 * in a burst and not idling the device maximizes throughput,
+ 	 * then the device must no be idled, because not idling the
+ 	 * device provides bfqq and all other queues in the burst with
+-	 * maximum benefit. Combining this and the two cases above, we
+-	 * can now establish when idling is actually needed to
+-	 * preserve service guarantees.
++	 * maximum benefit. Combining this and the above case, we can
++	 * now establish when idling is actually needed to preserve
++	 * service guarantees.
+ 	 */
+ 	idling_needed_for_service_guarantees =
+-		(on_hdd_and_not_all_queues_seeky || asymmetric_scenario) &&
+-		!bfq_bfqq_in_large_burst(bfqq);
++		asymmetric_scenario && !bfq_bfqq_in_large_burst(bfqq);
+ 
+ 	/*
+ 	 * We have now all the components we need to compute the return
+@@ -2624,6 +3429,16 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 	 * 2) idling either boosts the throughput (without issues), or
+ 	 *    is necessary to preserve service guarantees.
+ 	 */
++	bfq_log_bfqq(bfqd, bfqq, "may_idle: sync %d idling_boosts_thr %d",
++		     bfq_bfqq_sync(bfqq), idling_boosts_thr);
++
++	bfq_log_bfqq(bfqd, bfqq,
++		     "may_idle: wr_busy %d boosts %d IO-bound %d guar %d",
++		     bfqd->wr_busy_queues,
++		     idling_boosts_thr_without_issues,
++		     bfq_bfqq_IO_bound(bfqq),
++		     idling_needed_for_service_guarantees);
++
+ 	return bfq_bfqq_sync(bfqq) &&
+ 		(idling_boosts_thr_without_issues ||
+ 		 idling_needed_for_service_guarantees);
+@@ -2635,7 +3450,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+  * 1) the queue must remain in service and cannot be expired, and
+  * 2) the device must be idled to wait for the possible arrival of a new
+  *    request for the queue.
+- * See the comments to the function bfq_bfqq_may_idle for the reasons
++ * See the comments on the function bfq_bfqq_may_idle for the reasons
+  * why performing device idling is the best choice to boost the throughput
+  * and preserve service guarantees when bfq_bfqq_may_idle itself
+  * returns true.
+@@ -2665,7 +3480,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
+ 	bfq_log_bfqq(bfqd, bfqq, "select_queue: already in-service queue");
+ 
+ 	if (bfq_may_expire_for_budg_timeout(bfqq) &&
+-	    !timer_pending(&bfqd->idle_slice_timer) &&
++	    !hrtimer_active(&bfqd->idle_slice_timer) &&
+ 	    !bfq_bfqq_must_idle(bfqq))
+ 		goto expire;
+ 
+@@ -2685,7 +3500,8 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
+ 			 * not disable disk idling even when a new request
+ 			 * arrives.
+ 			 */
+-			if (timer_pending(&bfqd->idle_slice_timer)) {
++			if (bfq_bfqq_wait_request(bfqq)) {
++				BUG_ON(!hrtimer_active(&bfqd->idle_slice_timer));
+ 				/*
+ 				 * If we get here: 1) at least a new request
+ 				 * has arrived but we have not disabled the
+@@ -2700,10 +3516,8 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
+ 				 * So we disable idling.
+ 				 */
+ 				bfq_clear_bfqq_wait_request(bfqq);
+-				del_timer(&bfqd->idle_slice_timer);
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
++				hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
+ 				bfqg_stats_update_idle_time(bfqq_group(bfqq));
+-#endif
+ 			}
+ 			goto keep_queue;
+ 		}
+@@ -2714,7 +3528,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
+ 	 * for a new request, or has requests waiting for a completion and
+ 	 * may idle after their completion, then keep it anyway.
+ 	 */
+-	if (timer_pending(&bfqd->idle_slice_timer) ||
++	if (hrtimer_active(&bfqd->idle_slice_timer) ||
+ 	    (bfqq->dispatched != 0 && bfq_bfqq_may_idle(bfqq))) {
+ 		bfqq = NULL;
+ 		goto keep_queue;
+@@ -2736,6 +3550,9 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 	struct bfq_entity *entity = &bfqq->entity;
+ 
+ 	if (bfqq->wr_coeff > 1) { /* queue is being weight-raised */
++		BUG_ON(bfqq->wr_cur_max_time == bfqd->bfq_wr_rt_max_time &&
++		       time_is_after_jiffies(bfqq->last_wr_start_finish));
++
+ 		bfq_log_bfqq(bfqd, bfqq,
+ 			"raising period dur %u/%u msec, old coeff %u, w %d(%d)",
+ 			jiffies_to_msecs(jiffies - bfqq->last_wr_start_finish),
+@@ -2749,22 +3566,30 @@ static void bfq_update_wr_data(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 			bfq_log_bfqq(bfqd, bfqq, "WARN: pending prio change");
+ 
+ 		/*
+-		 * If the queue was activated in a burst, or
+-		 * too much time has elapsed from the beginning
+-		 * of this weight-raising period, or the queue has
+-		 * exceeded the acceptable number of cooperations,
+-		 * then end weight raising.
++		 * If the queue was activated in a burst, or too much
++		 * time has elapsed from the beginning of this
++		 * weight-raising period, then end weight raising.
+ 		 */
+-		if (bfq_bfqq_in_large_burst(bfqq) ||
+-		    bfq_bfqq_cooperations(bfqq) >= bfqd->bfq_coop_thresh ||
+-		    time_is_before_jiffies(bfqq->last_wr_start_finish +
+-					   bfqq->wr_cur_max_time)) {
+-			bfqq->last_wr_start_finish = jiffies;
+-			bfq_log_bfqq(bfqd, bfqq,
+-				     "wrais ending at %lu, rais_max_time %u",
+-				     bfqq->last_wr_start_finish,
+-				     jiffies_to_msecs(bfqq->wr_cur_max_time));
++		if (bfq_bfqq_in_large_burst(bfqq))
+ 			bfq_bfqq_end_wr(bfqq);
++		else if (time_is_before_jiffies(bfqq->last_wr_start_finish +
++					   bfqq->wr_cur_max_time)) {
++			if (bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time ||
++			time_is_before_jiffies(bfqq->wr_start_at_switch_to_srt +
++					bfq_wr_duration(bfqd)))
++				bfq_bfqq_end_wr(bfqq);
++			else {
++				/* switch back to interactive wr */
++				bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++				bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++				bfqq->last_wr_start_finish =
++					bfqq->wr_start_at_switch_to_srt;
++				BUG_ON(time_is_after_jiffies(
++					       bfqq->last_wr_start_finish));
++				bfqq->entity.prio_changed = 1;
++				bfq_log_bfqq(bfqd, bfqq,
++					"back to interactive wr");
++			}
+ 		}
+ 	}
+ 	/* Update weight both if it must be raised and if it must be lowered */
+@@ -2815,13 +3640,29 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
+ 		 */
+ 		if (!bfqd->rq_in_driver)
+ 			bfq_schedule_dispatch(bfqd);
++		BUG_ON(bfqq->entity.budget < bfqq->entity.service);
+ 		goto expire;
+ 	}
+ 
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
+ 	/* Finally, insert request into driver dispatch list. */
+ 	bfq_bfqq_served(bfqq, service_to_charge);
++
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
++
+ 	bfq_dispatch_insert(bfqd->queue, rq);
+ 
++	/*
++	 * If weight raising has to terminate for bfqq, then next
++	 * function causes an immediate update of bfqq's weight,
++	 * without waiting for next activation. As a consequence, on
++	 * expiration, bfqq will be timestamped as if has never been
++	 * weight-raised during this service slot, even if it has
++	 * received part or even most of the service as a
++	 * weight-raised queue. This inflates bfqq's timestamps, which
++	 * is beneficial, as bfqq is then more willing to leave the
++	 * device immediately to possible other weight-raised queues.
++	 */
+ 	bfq_update_wr_data(bfqd, bfqq);
+ 
+ 	bfq_log_bfqq(bfqd, bfqq,
+@@ -2837,9 +3678,7 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
+ 		bfqd->in_service_bic = RQ_BIC(rq);
+ 	}
+ 
+-	if (bfqd->busy_queues > 1 && ((!bfq_bfqq_sync(bfqq) &&
+-	    dispatched >= bfqd->bfq_max_budget_async_rq) ||
+-	    bfq_class_idle(bfqq)))
++	if (bfqd->busy_queues > 1 && bfq_class_idle(bfqq))
+ 		goto expire;
+ 
+ 	return dispatched;
+@@ -2885,8 +3724,8 @@ static int bfq_forced_dispatch(struct bfq_data *bfqd)
+ 		st = bfq_entity_service_tree(&bfqq->entity);
+ 
+ 		dispatched += __bfq_forced_dispatch_bfqq(bfqq);
+-		bfqq->max_budget = bfq_max_budget(bfqd);
+ 
++		bfqq->max_budget = bfq_max_budget(bfqd);
+ 		bfq_forget_idle(st);
+ 	}
+ 
+@@ -2899,37 +3738,37 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+ 	struct bfq_queue *bfqq;
+-	int max_dispatch;
+ 
+ 	bfq_log(bfqd, "dispatch requests: %d busy queues", bfqd->busy_queues);
++
+ 	if (bfqd->busy_queues == 0)
+ 		return 0;
+ 
+ 	if (unlikely(force))
+ 		return bfq_forced_dispatch(bfqd);
+ 
++	/*
++	 * Force device to serve one request at a time if
++	 * strict_guarantees is true. Forcing this service scheme is
++	 * currently the ONLY way to guarantee that the request
++	 * service order enforced by the scheduler is respected by a
++	 * queueing device. Otherwise the device is free even to make
++	 * some unlucky request wait for as long as the device
++	 * wishes.
++	 *
++	 * Of course, serving one request at at time may cause loss of
++	 * throughput.
++	 */
++	if (bfqd->strict_guarantees && bfqd->rq_in_driver > 0)
++		return 0;
++
+ 	bfqq = bfq_select_queue(bfqd);
+ 	if (!bfqq)
+ 		return 0;
+ 
+-	if (bfq_class_idle(bfqq))
+-		max_dispatch = 1;
+-
+-	if (!bfq_bfqq_sync(bfqq))
+-		max_dispatch = bfqd->bfq_max_budget_async_rq;
+-
+-	if (!bfq_bfqq_sync(bfqq) && bfqq->dispatched >= max_dispatch) {
+-		if (bfqd->busy_queues > 1)
+-			return 0;
+-		if (bfqq->dispatched >= 4 * max_dispatch)
+-			return 0;
+-	}
+-
+-	if (bfqd->sync_flight != 0 && !bfq_bfqq_sync(bfqq))
+-		return 0;
++	BUG_ON(bfqq->entity.budget < bfqq->entity.service);
+ 
+-	bfq_clear_bfqq_wait_request(bfqq);
+-	BUG_ON(timer_pending(&bfqd->idle_slice_timer));
++	BUG_ON(bfq_bfqq_wait_request(bfqq));
+ 
+ 	if (!bfq_dispatch_request(bfqd, bfqq))
+ 		return 0;
+@@ -2937,6 +3776,8 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
+ 	bfq_log_bfqq(bfqd, bfqq, "dispatched %s request",
+ 			bfq_bfqq_sync(bfqq) ? "sync" : "async");
+ 
++	BUG_ON(bfqq->next_rq == NULL &&
++	       bfqq->entity.budget < bfqq->entity.service);
+ 	return 1;
+ }
+ 
+@@ -2948,23 +3789,22 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
+  */
+ static void bfq_put_queue(struct bfq_queue *bfqq)
+ {
+-	struct bfq_data *bfqd = bfqq->bfqd;
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	struct bfq_group *bfqg = bfqq_group(bfqq);
+ #endif
+ 
+-	BUG_ON(atomic_read(&bfqq->ref) <= 0);
++	BUG_ON(bfqq->ref <= 0);
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "put_queue: %p %d", bfqq,
+-		     atomic_read(&bfqq->ref));
+-	if (!atomic_dec_and_test(&bfqq->ref))
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref);
++	bfqq->ref--;
++	if (bfqq->ref)
+ 		return;
+ 
+ 	BUG_ON(rb_first(&bfqq->sort_list));
+ 	BUG_ON(bfqq->allocated[READ] + bfqq->allocated[WRITE] != 0);
+ 	BUG_ON(bfqq->entity.tree);
+ 	BUG_ON(bfq_bfqq_busy(bfqq));
+-	BUG_ON(bfqd->in_service_queue == bfqq);
++	BUG_ON(bfqq->bfqd->in_service_queue == bfqq);
+ 
+ 	if (bfq_bfqq_sync(bfqq))
+ 		/*
+@@ -2977,7 +3817,7 @@ static void bfq_put_queue(struct bfq_queue *bfqq)
+ 		 */
+ 		hlist_del_init(&bfqq->burst_list_node);
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "put_queue: %p freed", bfqq);
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p freed", bfqq);
+ 
+ 	kmem_cache_free(bfq_pool, bfqq);
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+@@ -3011,8 +3851,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 		bfq_schedule_dispatch(bfqd);
+ 	}
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq,
+-		     atomic_read(&bfqq->ref));
++	bfq_log_bfqq(bfqd, bfqq, "exit_bfqq: %p, %d", bfqq, bfqq->ref);
+ 
+ 	bfq_put_cooperator(bfqq);
+ 
+@@ -3021,28 +3860,7 @@ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 
+ static void bfq_init_icq(struct io_cq *icq)
+ {
+-	struct bfq_io_cq *bic = icq_to_bic(icq);
+-
+-	bic->ttime.last_end_request = jiffies;
+-	/*
+-	 * A newly created bic indicates that the process has just
+-	 * started doing I/O, and is probably mapping into memory its
+-	 * executable and libraries: it definitely needs weight raising.
+-	 * There is however the possibility that the process performs,
+-	 * for a while, I/O close to some other process. EQM intercepts
+-	 * this behavior and may merge the queue corresponding to the
+-	 * process  with some other queue, BEFORE the weight of the queue
+-	 * is raised. Merged queues are not weight-raised (they are assumed
+-	 * to belong to processes that benefit only from high throughput).
+-	 * If the merge is basically the consequence of an accident, then
+-	 * the queue will be split soon and will get back its old weight.
+-	 * It is then important to write down somewhere that this queue
+-	 * does need weight raising, even if it did not make it to get its
+-	 * weight raised before being merged. To this purpose, we overload
+-	 * the field raising_time_left and assign 1 to it, to mark the queue
+-	 * as needing weight raising.
+-	 */
+-	bic->wr_time_left = 1;
++	icq_to_bic(icq)->ttime.last_end_request = ktime_get_ns() - (1ULL<<32);
+ }
+ 
+ static void bfq_exit_icq(struct io_cq *icq)
+@@ -3050,21 +3868,21 @@ static void bfq_exit_icq(struct io_cq *icq)
+ 	struct bfq_io_cq *bic = icq_to_bic(icq);
+ 	struct bfq_data *bfqd = bic_to_bfqd(bic);
+ 
+-	if (bic->bfqq[BLK_RW_ASYNC]) {
+-		bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_ASYNC]);
+-		bic->bfqq[BLK_RW_ASYNC] = NULL;
++	if (bic_to_bfqq(bic, false)) {
++		bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, false));
++		bic_set_bfqq(bic, NULL, false);
+ 	}
+ 
+-	if (bic->bfqq[BLK_RW_SYNC]) {
++	if (bic_to_bfqq(bic, true)) {
+ 		/*
+ 		 * If the bic is using a shared queue, put the reference
+ 		 * taken on the io_context when the bic started using a
+ 		 * shared bfq_queue.
+ 		 */
+-		if (bfq_bfqq_coop(bic->bfqq[BLK_RW_SYNC]))
++		if (bfq_bfqq_coop(bic_to_bfqq(bic, true)))
+ 			put_io_context(icq->ioc);
+-		bfq_exit_bfqq(bfqd, bic->bfqq[BLK_RW_SYNC]);
+-		bic->bfqq[BLK_RW_SYNC] = NULL;
++		bfq_exit_bfqq(bfqd, bic_to_bfqq(bic, true));
++		bic_set_bfqq(bic, NULL, true);
+ 	}
+ }
+ 
+@@ -3072,8 +3890,8 @@ static void bfq_exit_icq(struct io_cq *icq)
+  * Update the entity prio values; note that the new values will not
+  * be used until the next (re)activation.
+  */
+-static void
+-bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
++static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq,
++				     struct bfq_io_cq *bic)
+ {
+ 	struct task_struct *tsk = current;
+ 	int ioprio_class;
+@@ -3105,7 +3923,7 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
+ 		break;
+ 	}
+ 
+-	if (bfqq->new_ioprio < 0 || bfqq->new_ioprio >= IOPRIO_BE_NR) {
++	if (bfqq->new_ioprio >= IOPRIO_BE_NR) {
+ 		pr_crit("bfq_set_next_ioprio_data: new_ioprio %d\n",
+ 			bfqq->new_ioprio);
+ 		BUG();
+@@ -3113,45 +3931,40 @@ bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *bic)
+ 
+ 	bfqq->entity.new_weight = bfq_ioprio_to_weight(bfqq->new_ioprio);
+ 	bfqq->entity.prio_changed = 1;
++	bfq_log_bfqq(bfqq->bfqd, bfqq,
++		     "set_next_ioprio_data: bic_class %d prio %d class %d",
++		     ioprio_class, bfqq->new_ioprio, bfqq->new_ioprio_class);
+ }
+ 
+ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio)
+ {
+-	struct bfq_data *bfqd;
+-	struct bfq_queue *bfqq, *new_bfqq;
++	struct bfq_data *bfqd = bic_to_bfqd(bic);
++	struct bfq_queue *bfqq;
+ 	unsigned long uninitialized_var(flags);
+ 	int ioprio = bic->icq.ioc->ioprio;
+ 
+-	bfqd = bfq_get_bfqd_locked(&(bic->icq.q->elevator->elevator_data),
+-				   &flags);
+ 	/*
+ 	 * This condition may trigger on a newly created bic, be sure to
+ 	 * drop the lock before returning.
+ 	 */
+ 	if (unlikely(!bfqd) || likely(bic->ioprio == ioprio))
+-		goto out;
++		return;
+ 
+ 	bic->ioprio = ioprio;
+ 
+-	bfqq = bic->bfqq[BLK_RW_ASYNC];
++	bfqq = bic_to_bfqq(bic, false);
+ 	if (bfqq) {
+-		new_bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic,
+-					 GFP_ATOMIC);
+-		if (new_bfqq) {
+-			bic->bfqq[BLK_RW_ASYNC] = new_bfqq;
+-			bfq_log_bfqq(bfqd, bfqq,
+-				     "check_ioprio_change: bfqq %p %d",
+-				     bfqq, atomic_read(&bfqq->ref));
+-			bfq_put_queue(bfqq);
+-		}
++		bfq_put_queue(bfqq);
++		bfqq = bfq_get_queue(bfqd, bio, BLK_RW_ASYNC, bic);
++		bic_set_bfqq(bic, bfqq, false);
++		bfq_log_bfqq(bfqd, bfqq,
++			     "check_ioprio_change: bfqq %p %d",
++			     bfqq, bfqq->ref);
+ 	}
+ 
+-	bfqq = bic->bfqq[BLK_RW_SYNC];
++	bfqq = bic_to_bfqq(bic, true);
+ 	if (bfqq)
+ 		bfq_set_next_ioprio_data(bfqq, bic);
+-
+-out:
+-	bfq_put_bfqd_unlock(bfqd, &flags);
+ }
+ 
+ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+@@ -3160,8 +3973,9 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	RB_CLEAR_NODE(&bfqq->entity.rb_node);
+ 	INIT_LIST_HEAD(&bfqq->fifo);
+ 	INIT_HLIST_NODE(&bfqq->burst_list_node);
++	BUG_ON(!hlist_unhashed(&bfqq->burst_list_node));
+ 
+-	atomic_set(&bfqq->ref, 0);
++	bfqq->ref = 0;
+ 	bfqq->bfqd = bfqd;
+ 
+ 	if (bic)
+@@ -3171,6 +3985,7 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 		if (!bfq_class_idle(bfqq))
+ 			bfq_mark_bfqq_idle_window(bfqq);
+ 		bfq_mark_bfqq_sync(bfqq);
++		bfq_mark_bfqq_just_created(bfqq);
+ 	} else
+ 		bfq_clear_bfqq_sync(bfqq);
+ 	bfq_mark_bfqq_IO_bound(bfqq);
+@@ -3180,72 +3995,19 @@ static void bfq_init_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	bfqq->pid = pid;
+ 
+ 	bfqq->wr_coeff = 1;
+-	bfqq->last_wr_start_finish = 0;
++	bfqq->last_wr_start_finish = jiffies;
++	bfqq->wr_start_at_switch_to_srt = bfq_smallest_from_now();
++	bfqq->budget_timeout = bfq_smallest_from_now();
++	bfqq->split_time = bfq_smallest_from_now();
++
+ 	/*
+ 	 * Set to the value for which bfqq will not be deemed as
+ 	 * soft rt when it becomes backlogged.
+ 	 */
+-	bfqq->soft_rt_next_start = bfq_infinity_from_now(jiffies);
+-}
+-
+-static struct bfq_queue *bfq_find_alloc_queue(struct bfq_data *bfqd,
+-					      struct bio *bio, int is_sync,
+-					      struct bfq_io_cq *bic,
+-					      gfp_t gfp_mask)
+-{
+-	struct bfq_group *bfqg;
+-	struct bfq_queue *bfqq, *new_bfqq = NULL;
+-	struct blkcg *blkcg;
+-
+-retry:
+-	rcu_read_lock();
+-
+-	blkcg = bio_blkcg(bio);
+-	bfqg = bfq_find_alloc_group(bfqd, blkcg);
+-	/* bic always exists here */
+-	bfqq = bic_to_bfqq(bic, is_sync);
+-
+-	/*
+-	 * Always try a new alloc if we fall back to the OOM bfqq
+-	 * originally, since it should just be a temporary situation.
+-	 */
+-	if (!bfqq || bfqq == &bfqd->oom_bfqq) {
+-		bfqq = NULL;
+-		if (new_bfqq) {
+-			bfqq = new_bfqq;
+-			new_bfqq = NULL;
+-		} else if (gfpflags_allow_blocking(gfp_mask)) {
+-			rcu_read_unlock();
+-			spin_unlock_irq(bfqd->queue->queue_lock);
+-			new_bfqq = kmem_cache_alloc_node(bfq_pool,
+-					gfp_mask | __GFP_ZERO,
+-					bfqd->queue->node);
+-			spin_lock_irq(bfqd->queue->queue_lock);
+-			if (new_bfqq)
+-				goto retry;
+-		} else {
+-			bfqq = kmem_cache_alloc_node(bfq_pool,
+-					gfp_mask | __GFP_ZERO,
+-					bfqd->queue->node);
+-		}
+-
+-		if (bfqq) {
+-			bfq_init_bfqq(bfqd, bfqq, bic, current->pid,
+-				      is_sync);
+-			bfq_init_entity(&bfqq->entity, bfqg);
+-			bfq_log_bfqq(bfqd, bfqq, "allocated");
+-		} else {
+-			bfqq = &bfqd->oom_bfqq;
+-			bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
+-		}
+-	}
+-
+-	if (new_bfqq)
+-		kmem_cache_free(bfq_pool, new_bfqq);
+-
+-	rcu_read_unlock();
++	bfqq->soft_rt_next_start = bfq_greatest_from_now();
+ 
+-	return bfqq;
++	/* first request is almost certainly seeky */
++	bfqq->seek_history = 1;
+ }
+ 
+ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
+@@ -3268,90 +4030,84 @@ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
+ }
+ 
+ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
+-				       struct bio *bio, int is_sync,
+-				       struct bfq_io_cq *bic, gfp_t gfp_mask)
++				       struct bio *bio, bool is_sync,
++				       struct bfq_io_cq *bic)
+ {
+ 	const int ioprio = IOPRIO_PRIO_DATA(bic->ioprio);
+ 	const int ioprio_class = IOPRIO_PRIO_CLASS(bic->ioprio);
+ 	struct bfq_queue **async_bfqq = NULL;
+-	struct bfq_queue *bfqq = NULL;
++	struct bfq_queue *bfqq;
++	struct bfq_group *bfqg;
+ 
+-	if (!is_sync) {
+-		struct blkcg *blkcg;
+-		struct bfq_group *bfqg;
++	rcu_read_lock();
++
++	bfqg = bfq_find_set_group(bfqd, bio_blkcg(bio));
++	if (!bfqg) {
++		bfqq = &bfqd->oom_bfqq;
++		goto out;
++	}
+ 
+-		rcu_read_lock();
+-		blkcg = bio_blkcg(bio);
+-		rcu_read_unlock();
+-		bfqg = bfq_find_alloc_group(bfqd, blkcg);
++	if (!is_sync) {
+ 		async_bfqq = bfq_async_queue_prio(bfqd, bfqg, ioprio_class,
+ 						  ioprio);
+ 		bfqq = *async_bfqq;
++		if (bfqq)
++			goto out;
+ 	}
+ 
+-	if (!bfqq)
+-		bfqq = bfq_find_alloc_queue(bfqd, bio, is_sync, bic, gfp_mask);
++	bfqq = kmem_cache_alloc_node(bfq_pool, GFP_NOWAIT | __GFP_ZERO,
++				     bfqd->queue->node);
++
++	if (bfqq) {
++		bfq_init_bfqq(bfqd, bfqq, bic, current->pid,
++			      is_sync);
++		bfq_init_entity(&bfqq->entity, bfqg);
++		bfq_log_bfqq(bfqd, bfqq, "allocated");
++	} else {
++		bfqq = &bfqd->oom_bfqq;
++		bfq_log_bfqq(bfqd, bfqq, "using oom bfqq");
++		goto out;
++	}
+ 
+ 	/*
+ 	 * Pin the queue now that it's allocated, scheduler exit will
+ 	 * prune it.
+ 	 */
+-	if (!is_sync && !(*async_bfqq)) {
+-		atomic_inc(&bfqq->ref);
++	if (async_bfqq) {
++		bfqq->ref++;
+ 		bfq_log_bfqq(bfqd, bfqq, "get_queue, bfqq not in async: %p, %d",
+-			     bfqq, atomic_read(&bfqq->ref));
++			     bfqq, bfqq->ref);
+ 		*async_bfqq = bfqq;
+ 	}
+ 
+-	atomic_inc(&bfqq->ref);
+-	bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq,
+-		     atomic_read(&bfqq->ref));
++out:
++	bfqq->ref++;
++	bfq_log_bfqq(bfqd, bfqq, "get_queue, at end: %p, %d", bfqq, bfqq->ref);
++	rcu_read_unlock();
+ 	return bfqq;
+ }
+ 
+ static void bfq_update_io_thinktime(struct bfq_data *bfqd,
+ 				    struct bfq_io_cq *bic)
+ {
+-	unsigned long elapsed = jiffies - bic->ttime.last_end_request;
+-	unsigned long ttime = min(elapsed, 2UL * bfqd->bfq_slice_idle);
++	struct bfq_ttime *ttime = &bic->ttime;
++	u64 elapsed = ktime_get_ns() - bic->ttime.last_end_request;
++
++	elapsed = min_t(u64, elapsed, 2 * bfqd->bfq_slice_idle);
+ 
+-	bic->ttime.ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
+-	bic->ttime.ttime_total = (7*bic->ttime.ttime_total + 256*ttime) / 8;
+-	bic->ttime.ttime_mean = (bic->ttime.ttime_total + 128) /
+-				bic->ttime.ttime_samples;
++	ttime->ttime_samples = (7*bic->ttime.ttime_samples + 256) / 8;
++	ttime->ttime_total = div_u64(7*ttime->ttime_total + 256*elapsed,  8);
++	ttime->ttime_mean = div64_ul(ttime->ttime_total + 128,
++				     ttime->ttime_samples);
+ }
+ 
+-static void bfq_update_io_seektime(struct bfq_data *bfqd,
+-				   struct bfq_queue *bfqq,
+-				   struct request *rq)
++static void
++bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++		       struct request *rq)
+ {
+-	sector_t sdist;
+-	u64 total;
+-
+-	if (bfqq->last_request_pos < blk_rq_pos(rq))
+-		sdist = blk_rq_pos(rq) - bfqq->last_request_pos;
+-	else
+-		sdist = bfqq->last_request_pos - blk_rq_pos(rq);
+-
+-	/*
+-	 * Don't allow the seek distance to get too large from the
+-	 * odd fragment, pagein, etc.
+-	 */
+-	if (bfqq->seek_samples == 0) /* first request, not really a seek */
+-		sdist = 0;
+-	else if (bfqq->seek_samples <= 60) /* second & third seek */
+-		sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*1024);
+-	else
+-		sdist = min(sdist, (bfqq->seek_mean * 4) + 2*1024*64);
+-
+-	bfqq->seek_samples = (7*bfqq->seek_samples + 256) / 8;
+-	bfqq->seek_total = (7*bfqq->seek_total + (u64)256*sdist) / 8;
+-	total = bfqq->seek_total + (bfqq->seek_samples/2);
+-	do_div(total, bfqq->seek_samples);
+-	bfqq->seek_mean = (sector_t)total;
+-
+-	bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
+-			(u64)bfqq->seek_mean);
++	bfqq->seek_history <<= 1;
++	bfqq->seek_history |=
++		get_sdist(bfqq->last_request_pos, rq) > BFQQ_SEEK_THR;
+ }
+ 
+ /*
+@@ -3369,7 +4125,8 @@ static void bfq_update_idle_window(struct bfq_data *bfqd,
+ 		return;
+ 
+ 	/* Idle window just restored, statistics are meaningless. */
+-	if (bfq_bfqq_just_split(bfqq))
++	if (time_is_after_eq_jiffies(bfqq->split_time +
++				     bfqd->bfq_wr_min_idle_time))
+ 		return;
+ 
+ 	enable_idle = bfq_bfqq_idle_window(bfqq);
+@@ -3409,22 +4166,13 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 
+ 	bfq_update_io_thinktime(bfqd, bic);
+ 	bfq_update_io_seektime(bfqd, bfqq, rq);
+-	if (!BFQQ_SEEKY(bfqq) && bfq_bfqq_constantly_seeky(bfqq)) {
+-		bfq_clear_bfqq_constantly_seeky(bfqq);
+-		if (!blk_queue_nonrot(bfqd->queue)) {
+-			BUG_ON(!bfqd->const_seeky_busy_in_flight_queues);
+-			bfqd->const_seeky_busy_in_flight_queues--;
+-		}
+-	}
+ 	if (bfqq->entity.service > bfq_max_budget(bfqd) / 8 ||
+ 	    !BFQQ_SEEKY(bfqq))
+ 		bfq_update_idle_window(bfqd, bfqq, bic);
+-	bfq_clear_bfqq_just_split(bfqq);
+ 
+ 	bfq_log_bfqq(bfqd, bfqq,
+-		     "rq_enqueued: idle_window=%d (seeky %d, mean %llu)",
+-		     bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq),
+-		     (unsigned long long) bfqq->seek_mean);
++		     "rq_enqueued: idle_window=%d (seeky %d)",
++		     bfq_bfqq_idle_window(bfqq), BFQQ_SEEKY(bfqq));
+ 
+ 	bfqq->last_request_pos = blk_rq_pos(rq) + blk_rq_sectors(rq);
+ 
+@@ -3438,14 +4186,15 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 		 * is small and the queue is not to be expired, then
+ 		 * just exit.
+ 		 *
+-		 * In this way, if the disk is being idled to wait for
+-		 * a new request from the in-service queue, we avoid
+-		 * unplugging the device and committing the disk to serve
+-		 * just a small request. On the contrary, we wait for
+-		 * the block layer to decide when to unplug the device:
+-		 * hopefully, new requests will be merged to this one
+-		 * quickly, then the device will be unplugged and
+-		 * larger requests will be dispatched.
++		 * In this way, if the device is being idled to wait
++		 * for a new request from the in-service queue, we
++		 * avoid unplugging the device and committing the
++		 * device to serve just a small request. On the
++		 * contrary, we wait for the block layer to decide
++		 * when to unplug the device: hopefully, new requests
++		 * will be merged to this one quickly, then the device
++		 * will be unplugged and larger requests will be
++		 * dispatched.
+ 		 */
+ 		if (small_req && !budget_timeout)
+ 			return;
+@@ -3457,10 +4206,8 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 		 * timer.
+ 		 */
+ 		bfq_clear_bfqq_wait_request(bfqq);
+-		del_timer(&bfqd->idle_slice_timer);
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
+ 		bfqg_stats_update_idle_time(bfqq_group(bfqq));
+-#endif
+ 
+ 		/*
+ 		 * The queue is not empty, because a new request just
+@@ -3504,28 +4251,21 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq)
+ 			 */
+ 			new_bfqq->allocated[rq_data_dir(rq)]++;
+ 			bfqq->allocated[rq_data_dir(rq)]--;
+-			atomic_inc(&new_bfqq->ref);
++			new_bfqq->ref++;
++			bfq_clear_bfqq_just_created(bfqq);
+ 			bfq_put_queue(bfqq);
+ 			if (bic_to_bfqq(RQ_BIC(rq), 1) == bfqq)
+ 				bfq_merge_bfqqs(bfqd, RQ_BIC(rq),
+ 						bfqq, new_bfqq);
+ 			rq->elv.priv[1] = new_bfqq;
+ 			bfqq = new_bfqq;
+-		} else
+-			bfq_bfqq_increase_failed_cooperations(bfqq);
++		}
+ 	}
+ 
+ 	bfq_add_request(rq);
+ 
+-	/*
+-	 * Here a newly-created bfq_queue has already started a weight-raising
+-	 * period: clear raising_time_left to prevent bfq_bfqq_save_state()
+-	 * from assigning it a full weight-raising period. See the detailed
+-	 * comments about this field in bfq_init_icq().
+-	 */
+-	if (bfqq->bic)
+-		bfqq->bic->wr_time_left = 0;
+-	rq->fifo_time = jiffies + bfqd->bfq_fifo_expire[rq_is_sync(rq)];
++	rq->fifo_time = ktime_get_ns() +
++	  jiffies_to_nsecs(bfqd->bfq_fifo_expire[rq_is_sync(rq)]);
+ 	list_add_tail(&rq->queuelist, &bfqq->fifo);
+ 
+ 	bfq_rq_enqueued(bfqd, bfqq, rq);
+@@ -3533,8 +4273,8 @@ static void bfq_insert_request(struct request_queue *q, struct request *rq)
+ 
+ static void bfq_update_hw_tag(struct bfq_data *bfqd)
+ {
+-	bfqd->max_rq_in_driver = max(bfqd->max_rq_in_driver,
+-				     bfqd->rq_in_driver);
++	bfqd->max_rq_in_driver = max_t(int, bfqd->max_rq_in_driver,
++				       bfqd->rq_in_driver);
+ 
+ 	if (bfqd->hw_tag == 1)
+ 		return;
+@@ -3560,48 +4300,85 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq)
+ {
+ 	struct bfq_queue *bfqq = RQ_BFQQ(rq);
+ 	struct bfq_data *bfqd = bfqq->bfqd;
+-	bool sync = bfq_bfqq_sync(bfqq);
++	u64 now_ns;
++	u32 delta_us;
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
+-		     blk_rq_sectors(rq), sync);
++	bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left",
++		     blk_rq_sectors(rq));
+ 
++	assert_spin_locked(bfqd->queue->queue_lock);
+ 	bfq_update_hw_tag(bfqd);
+ 
+ 	BUG_ON(!bfqd->rq_in_driver);
+ 	BUG_ON(!bfqq->dispatched);
+ 	bfqd->rq_in_driver--;
+ 	bfqq->dispatched--;
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	bfqg_stats_update_completion(bfqq_group(bfqq),
+ 				     rq_start_time_ns(rq),
+-				     rq_io_start_time_ns(rq), rq->cmd_flags);
+-#endif
++				     rq_io_start_time_ns(rq), req_op(rq),
++				     rq->cmd_flags);
+ 
+ 	if (!bfqq->dispatched && !bfq_bfqq_busy(bfqq)) {
++		BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
++		/*
++		 * Set budget_timeout (which we overload to store the
++		 * time at which the queue remains with no backlog and
++		 * no outstanding request; used by the weight-raising
++		 * mechanism).
++		 */
++		bfqq->budget_timeout = jiffies;
++
+ 		bfq_weights_tree_remove(bfqd, &bfqq->entity,
+ 					&bfqd->queue_weights_tree);
+-		if (!blk_queue_nonrot(bfqd->queue)) {
+-			BUG_ON(!bfqd->busy_in_flight_queues);
+-			bfqd->busy_in_flight_queues--;
+-			if (bfq_bfqq_constantly_seeky(bfqq)) {
+-				BUG_ON(!bfqd->
+-					const_seeky_busy_in_flight_queues);
+-				bfqd->const_seeky_busy_in_flight_queues--;
+-			}
+-		}
+ 	}
+ 
+-	if (sync) {
+-		bfqd->sync_flight--;
+-		RQ_BIC(rq)->ttime.last_end_request = jiffies;
+-	}
++	now_ns = ktime_get_ns();
++
++	RQ_BIC(rq)->ttime.last_end_request = now_ns;
++
++	/*
++	 * Using us instead of ns, to get a reasonable precision in
++	 * computing rate in next check.
++	 */
++	delta_us = div_u64(now_ns - bfqd->last_completion, NSEC_PER_USEC);
++
++	bfq_log(bfqd, "rq_completed: delta %uus/%luus max_size %u rate %llu/%llu",
++		delta_us, BFQ_MIN_TT/NSEC_PER_USEC, bfqd->last_rq_max_size,
++		(USEC_PER_SEC*
++		(u64)((bfqd->last_rq_max_size<<BFQ_RATE_SHIFT)/delta_us))
++			>>BFQ_RATE_SHIFT,
++		(USEC_PER_SEC*(u64)(1UL<<(BFQ_RATE_SHIFT-10)))>>BFQ_RATE_SHIFT);
++
++	/*
++	 * If the request took rather long to complete, and, according
++	 * to the maximum request size recorded, this completion latency
++	 * implies that the request was certainly served at a very low
++	 * rate (less than 1M sectors/sec), then the whole observation
++	 * interval that lasts up to this time instant cannot be a
++	 * valid time interval for computing a new peak rate.  Invoke
++	 * bfq_update_rate_reset to have the following three steps
++	 * taken:
++	 * - close the observation interval at the last (previous)
++	 *   request dispatch or completion
++	 * - compute rate, if possible, for that observation interval
++	 * - reset to zero samples, which will trigger a proper
++	 *   re-initialization of the observation interval on next
++	 *   dispatch
++	 */
++	if (delta_us > BFQ_MIN_TT/NSEC_PER_USEC &&
++	   (bfqd->last_rq_max_size<<BFQ_RATE_SHIFT)/delta_us <
++			1UL<<(BFQ_RATE_SHIFT - 10))
++		bfq_update_rate_reset(bfqd, NULL);
++	bfqd->last_completion = now_ns;
+ 
+ 	/*
+-	 * If we are waiting to discover whether the request pattern of the
+-	 * task associated with the queue is actually isochronous, and
+-	 * both requisites for this condition to hold are satisfied, then
+-	 * compute soft_rt_next_start (see the comments to the function
+-	 * bfq_bfqq_softrt_next_start()).
++	 * If we are waiting to discover whether the request pattern
++	 * of the task associated with the queue is actually
++	 * isochronous, and both requisites for this condition to hold
++	 * are now satisfied, then compute soft_rt_next_start (see the
++	 * comments on the function bfq_bfqq_softrt_next_start()). We
++	 * schedule this delayed check when bfqq expires, if it still
++	 * has in-flight requests.
+ 	 */
+ 	if (bfq_bfqq_softrt_update(bfqq) && bfqq->dispatched == 0 &&
+ 	    RB_EMPTY_ROOT(&bfqq->sort_list))
+@@ -3613,10 +4390,7 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq)
+ 	 * or if we want to idle in case it has no pending requests.
+ 	 */
+ 	if (bfqd->in_service_queue == bfqq) {
+-		if (bfq_bfqq_budget_new(bfqq))
+-			bfq_set_budget_timeout(bfqd);
+-
+-		if (bfq_bfqq_must_idle(bfqq)) {
++		if (bfqq->dispatched == 0 && bfq_bfqq_must_idle(bfqq)) {
+ 			bfq_arm_slice_timer(bfqd);
+ 			goto out;
+ 		} else if (bfq_may_expire_for_budg_timeout(bfqq))
+@@ -3646,7 +4420,7 @@ static int __bfq_may_queue(struct bfq_queue *bfqq)
+ 	return ELV_MQUEUE_MAY;
+ }
+ 
+-static int bfq_may_queue(struct request_queue *q, int rw)
++static int bfq_may_queue(struct request_queue *q, int op, int op_flags)
+ {
+ 	struct bfq_data *bfqd = q->elevator->elevator_data;
+ 	struct task_struct *tsk = current;
+@@ -3663,7 +4437,7 @@ static int bfq_may_queue(struct request_queue *q, int rw)
+ 	if (!bic)
+ 		return ELV_MQUEUE_MAY;
+ 
+-	bfqq = bic_to_bfqq(bic, rw_is_sync(rw));
++	bfqq = bic_to_bfqq(bic, rw_is_sync(op, op_flags));
+ 	if (bfqq)
+ 		return __bfq_may_queue(bfqq);
+ 
+@@ -3687,14 +4461,14 @@ static void bfq_put_request(struct request *rq)
+ 		rq->elv.priv[1] = NULL;
+ 
+ 		bfq_log_bfqq(bfqq->bfqd, bfqq, "put_request %p, %d",
+-			     bfqq, atomic_read(&bfqq->ref));
++			     bfqq, bfqq->ref);
+ 		bfq_put_queue(bfqq);
+ 	}
+ }
+ 
+ /*
+  * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
+- * was the last process referring to said bfqq.
++ * was the last process referring to that bfqq.
+  */
+ static struct bfq_queue *
+ bfq_split_bfqq(struct bfq_io_cq *bic, struct bfq_queue *bfqq)
+@@ -3732,11 +4506,8 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
+ 	unsigned long flags;
+ 	bool split = false;
+ 
+-	might_sleep_if(gfpflags_allow_blocking(gfp_mask));
+-
+-	bfq_check_ioprio_change(bic, bio);
+-
+ 	spin_lock_irqsave(q->queue_lock, flags);
++	bfq_check_ioprio_change(bic, bio);
+ 
+ 	if (!bic)
+ 		goto queue_fail;
+@@ -3746,23 +4517,47 @@ static int bfq_set_request(struct request_queue *q, struct request *rq,
+ new_queue:
+ 	bfqq = bic_to_bfqq(bic, is_sync);
+ 	if (!bfqq || bfqq == &bfqd->oom_bfqq) {
+-		bfqq = bfq_get_queue(bfqd, bio, is_sync, bic, gfp_mask);
++		if (bfqq)
++			bfq_put_queue(bfqq);
++		bfqq = bfq_get_queue(bfqd, bio, is_sync, bic);
++		BUG_ON(!hlist_unhashed(&bfqq->burst_list_node));
++
+ 		bic_set_bfqq(bic, bfqq, is_sync);
+ 		if (split && is_sync) {
++			bfq_log_bfqq(bfqd, bfqq,
++				     "set_request: was_in_list %d "
++				     "was_in_large_burst %d "
++				     "large burst in progress %d",
++				     bic->was_in_burst_list,
++				     bic->saved_in_large_burst,
++				     bfqd->large_burst);
++
+ 			if ((bic->was_in_burst_list && bfqd->large_burst) ||
+-			    bic->saved_in_large_burst)
++			    bic->saved_in_large_burst) {
++				bfq_log_bfqq(bfqd, bfqq,
++					     "set_request: marking in "
++					     "large burst");
+ 				bfq_mark_bfqq_in_large_burst(bfqq);
+-			else {
++			} else {
++				bfq_log_bfqq(bfqd, bfqq,
++					     "set_request: clearing in "
++					     "large burst");
+ 				bfq_clear_bfqq_in_large_burst(bfqq);
+ 				if (bic->was_in_burst_list)
+ 					hlist_add_head(&bfqq->burst_list_node,
+ 						       &bfqd->burst_list);
+ 			}
++			bfqq->split_time = jiffies;
+ 		}
+ 	} else {
+ 		/* If the queue was seeky for too long, break it apart. */
+ 		if (bfq_bfqq_coop(bfqq) && bfq_bfqq_split_coop(bfqq)) {
+ 			bfq_log_bfqq(bfqd, bfqq, "breaking apart bfqq");
++
++			/* Update bic before losing reference to bfqq */
++			if (bfq_bfqq_in_large_burst(bfqq))
++				bic->saved_in_large_burst = true;
++
+ 			bfqq = bfq_split_bfqq(bic, bfqq);
+ 			split = true;
+ 			if (!bfqq)
+@@ -3771,9 +4566,8 @@ new_queue:
+ 	}
+ 
+ 	bfqq->allocated[rw]++;
+-	atomic_inc(&bfqq->ref);
+-	bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq,
+-		     atomic_read(&bfqq->ref));
++	bfqq->ref++;
++	bfq_log_bfqq(bfqd, bfqq, "set_request: bfqq %p, %d", bfqq, bfqq->ref);
+ 
+ 	rq->elv.priv[0] = bic;
+ 	rq->elv.priv[1] = bfqq;
+@@ -3788,7 +4582,6 @@ new_queue:
+ 	if (likely(bfqq != &bfqd->oom_bfqq) && bfqq_process_refs(bfqq) == 1) {
+ 		bfqq->bic = bic;
+ 		if (split) {
+-			bfq_mark_bfqq_just_split(bfqq);
+ 			/*
+ 			 * If the queue has just been split from a shared
+ 			 * queue, restore the idle window and the possible
+@@ -3798,6 +4591,9 @@ new_queue:
+ 		}
+ 	}
+ 
++	if (unlikely(bfq_bfqq_just_created(bfqq)))
++		bfq_handle_burst(bfqd, bfqq);
++
+ 	spin_unlock_irqrestore(q->queue_lock, flags);
+ 
+ 	return 0;
+@@ -3824,9 +4620,10 @@ static void bfq_kick_queue(struct work_struct *work)
+  * Handler of the expiration of the timer running if the in-service queue
+  * is idling inside its time slice.
+  */
+-static void bfq_idle_slice_timer(unsigned long data)
++static enum hrtimer_restart bfq_idle_slice_timer(struct hrtimer *timer)
+ {
+-	struct bfq_data *bfqd = (struct bfq_data *)data;
++	struct bfq_data *bfqd = container_of(timer, struct bfq_data,
++					     idle_slice_timer);
+ 	struct bfq_queue *bfqq;
+ 	unsigned long flags;
+ 	enum bfqq_expiration reason;
+@@ -3844,6 +4641,8 @@ static void bfq_idle_slice_timer(unsigned long data)
+ 	 */
+ 	if (bfqq) {
+ 		bfq_log_bfqq(bfqd, bfqq, "slice_timer expired");
++		bfq_clear_bfqq_wait_request(bfqq);
++
+ 		if (bfq_bfqq_budget_timeout(bfqq))
+ 			/*
+ 			 * Also here the queue can be safely expired
+@@ -3869,14 +4668,16 @@ schedule_dispatch:
+ 	bfq_schedule_dispatch(bfqd);
+ 
+ 	spin_unlock_irqrestore(bfqd->queue->queue_lock, flags);
++	return HRTIMER_NORESTART;
+ }
+ 
+ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
+ {
+-	del_timer_sync(&bfqd->idle_slice_timer);
++	hrtimer_cancel(&bfqd->idle_slice_timer);
+ 	cancel_work_sync(&bfqd->unplug_work);
+ }
+ 
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
+ 					struct bfq_queue **bfqq_ptr)
+ {
+@@ -3885,9 +4686,9 @@ static void __bfq_put_async_bfqq(struct bfq_data *bfqd,
+ 
+ 	bfq_log(bfqd, "put_async_bfqq: %p", bfqq);
+ 	if (bfqq) {
+-		bfq_bfqq_move(bfqd, bfqq, &bfqq->entity, root_group);
++		bfq_bfqq_move(bfqd, bfqq, root_group);
+ 		bfq_log_bfqq(bfqd, bfqq, "put_async_bfqq: putting %p, %d",
+-			     bfqq, atomic_read(&bfqq->ref));
++			     bfqq, bfqq->ref);
+ 		bfq_put_queue(bfqq);
+ 		*bfqq_ptr = NULL;
+ 	}
+@@ -3909,6 +4710,7 @@ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg)
+ 
+ 	__bfq_put_async_bfqq(bfqd, &bfqg->async_idle_bfqq);
+ }
++#endif
+ 
+ static void bfq_exit_queue(struct elevator_queue *e)
+ {
+@@ -3928,9 +4730,7 @@ static void bfq_exit_queue(struct elevator_queue *e)
+ 
+ 	bfq_shutdown_timer_wq(bfqd);
+ 
+-	synchronize_rcu();
+-
+-	BUG_ON(timer_pending(&bfqd->idle_slice_timer));
++	BUG_ON(hrtimer_active(&bfqd->idle_slice_timer));
+ 
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	blkcg_deactivate_policy(q, &blkcg_policy_bfq);
+@@ -3978,11 +4778,14 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ 	 * will not attempt to free it.
+ 	 */
+ 	bfq_init_bfqq(bfqd, &bfqd->oom_bfqq, NULL, 1, 0);
+-	atomic_inc(&bfqd->oom_bfqq.ref);
++	bfqd->oom_bfqq.ref++;
+ 	bfqd->oom_bfqq.new_ioprio = BFQ_DEFAULT_QUEUE_IOPRIO;
+ 	bfqd->oom_bfqq.new_ioprio_class = IOPRIO_CLASS_BE;
+ 	bfqd->oom_bfqq.entity.new_weight =
+ 		bfq_ioprio_to_weight(bfqd->oom_bfqq.new_ioprio);
++
++	/* oom_bfqq does not participate to bursts */
++	bfq_clear_bfqq_just_created(&bfqd->oom_bfqq);
+ 	/*
+ 	 * Trigger weight initialization, according to ioprio, at the
+ 	 * oom_bfqq's first activation. The oom_bfqq's ioprio and ioprio
+@@ -4001,13 +4804,10 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ 		goto out_free;
+ 	bfq_init_root_group(bfqd->root_group, bfqd);
+ 	bfq_init_entity(&bfqd->oom_bfqq.entity, bfqd->root_group);
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	bfqd->active_numerous_groups = 0;
+-#endif
+ 
+-	init_timer(&bfqd->idle_slice_timer);
++	hrtimer_init(&bfqd->idle_slice_timer, CLOCK_MONOTONIC,
++		     HRTIMER_MODE_REL);
+ 	bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
+-	bfqd->idle_slice_timer.data = (unsigned long)bfqd;
+ 
+ 	bfqd->queue_weights_tree = RB_ROOT;
+ 	bfqd->group_weights_tree = RB_ROOT;
+@@ -4028,20 +4828,19 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ 	bfqd->bfq_back_penalty = bfq_back_penalty;
+ 	bfqd->bfq_slice_idle = bfq_slice_idle;
+ 	bfqd->bfq_class_idle_last_service = 0;
+-	bfqd->bfq_max_budget_async_rq = bfq_max_budget_async_rq;
+-	bfqd->bfq_timeout[BLK_RW_ASYNC] = bfq_timeout_async;
+-	bfqd->bfq_timeout[BLK_RW_SYNC] = bfq_timeout_sync;
++	bfqd->bfq_timeout = bfq_timeout;
+ 
+-	bfqd->bfq_coop_thresh = 2;
+-	bfqd->bfq_failed_cooperations = 7000;
+ 	bfqd->bfq_requests_within_timer = 120;
+ 
+-	bfqd->bfq_large_burst_thresh = 11;
+-	bfqd->bfq_burst_interval = msecs_to_jiffies(500);
++	bfqd->bfq_large_burst_thresh = 8;
++	bfqd->bfq_burst_interval = msecs_to_jiffies(180);
+ 
+ 	bfqd->low_latency = true;
+ 
+-	bfqd->bfq_wr_coeff = 20;
++	/*
++	 * Trade-off between responsiveness and fairness.
++	 */
++	bfqd->bfq_wr_coeff = 30;
+ 	bfqd->bfq_wr_rt_max_time = msecs_to_jiffies(300);
+ 	bfqd->bfq_wr_max_time = 0;
+ 	bfqd->bfq_wr_min_idle_time = msecs_to_jiffies(2000);
+@@ -4053,16 +4852,15 @@ static int bfq_init_queue(struct request_queue *q, struct elevator_type *e)
+ 					      * video.
+ 					      */
+ 	bfqd->wr_busy_queues = 0;
+-	bfqd->busy_in_flight_queues = 0;
+-	bfqd->const_seeky_busy_in_flight_queues = 0;
+ 
+ 	/*
+-	 * Begin by assuming, optimistically, that the device peak rate is
+-	 * equal to the highest reference rate.
++	 * Begin by assuming, optimistically, that the device is a
++	 * high-speed one, and that its peak rate is equal to 2/3 of
++	 * the highest reference rate.
+ 	 */
+ 	bfqd->RT_prod = R_fast[blk_queue_nonrot(bfqd->queue)] *
+ 			T_fast[blk_queue_nonrot(bfqd->queue)];
+-	bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)];
++	bfqd->peak_rate = R_fast[blk_queue_nonrot(bfqd->queue)] * 2 / 3;
+ 	bfqd->device_speed = BFQ_BFQD_FAST;
+ 
+ 	return 0;
+@@ -4088,7 +4886,7 @@ static int __init bfq_slab_setup(void)
+ 
+ static ssize_t bfq_var_show(unsigned int var, char *page)
+ {
+-	return sprintf(page, "%d\n", var);
++	return sprintf(page, "%u\n", var);
+ }
+ 
+ static ssize_t bfq_var_store(unsigned long *var, const char *page,
+@@ -4159,21 +4957,21 @@ static ssize_t bfq_weights_show(struct elevator_queue *e, char *page)
+ static ssize_t __FUNC(struct elevator_queue *e, char *page)		\
+ {									\
+ 	struct bfq_data *bfqd = e->elevator_data;			\
+-	unsigned int __data = __VAR;					\
+-	if (__CONV)							\
++	u64 __data = __VAR;						\
++	if (__CONV == 1)						\
+ 		__data = jiffies_to_msecs(__data);			\
++	else if (__CONV == 2)						\
++		__data = div_u64(__data, NSEC_PER_MSEC);		\
+ 	return bfq_var_show(__data, (page));				\
+ }
+-SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 1);
+-SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 1);
++SHOW_FUNCTION(bfq_fifo_expire_sync_show, bfqd->bfq_fifo_expire[1], 2);
++SHOW_FUNCTION(bfq_fifo_expire_async_show, bfqd->bfq_fifo_expire[0], 2);
+ SHOW_FUNCTION(bfq_back_seek_max_show, bfqd->bfq_back_max, 0);
+ SHOW_FUNCTION(bfq_back_seek_penalty_show, bfqd->bfq_back_penalty, 0);
+-SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 1);
++SHOW_FUNCTION(bfq_slice_idle_show, bfqd->bfq_slice_idle, 2);
+ SHOW_FUNCTION(bfq_max_budget_show, bfqd->bfq_user_max_budget, 0);
+-SHOW_FUNCTION(bfq_max_budget_async_rq_show,
+-	      bfqd->bfq_max_budget_async_rq, 0);
+-SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout[BLK_RW_SYNC], 1);
+-SHOW_FUNCTION(bfq_timeout_async_show, bfqd->bfq_timeout[BLK_RW_ASYNC], 1);
++SHOW_FUNCTION(bfq_timeout_sync_show, bfqd->bfq_timeout, 1);
++SHOW_FUNCTION(bfq_strict_guarantees_show, bfqd->strict_guarantees, 0);
+ SHOW_FUNCTION(bfq_low_latency_show, bfqd->low_latency, 0);
+ SHOW_FUNCTION(bfq_wr_coeff_show, bfqd->bfq_wr_coeff, 0);
+ SHOW_FUNCTION(bfq_wr_rt_max_time_show, bfqd->bfq_wr_rt_max_time, 1);
+@@ -4183,6 +4981,17 @@ SHOW_FUNCTION(bfq_wr_min_inter_arr_async_show, bfqd->bfq_wr_min_inter_arr_async,
+ SHOW_FUNCTION(bfq_wr_max_softrt_rate_show, bfqd->bfq_wr_max_softrt_rate, 0);
+ #undef SHOW_FUNCTION
+ 
++#define USEC_SHOW_FUNCTION(__FUNC, __VAR)				\
++static ssize_t __FUNC(struct elevator_queue *e, char *page)		\
++{									\
++	struct bfq_data *bfqd = e->elevator_data;			\
++	u64 __data = __VAR;						\
++	__data = div_u64(__data, NSEC_PER_USEC);			\
++	return bfq_var_show(__data, (page));				\
++}
++USEC_SHOW_FUNCTION(bfq_slice_idle_us_show, bfqd->bfq_slice_idle);
++#undef USEC_SHOW_FUNCTION
++
+ #define STORE_FUNCTION(__FUNC, __PTR, MIN, MAX, __CONV)			\
+ static ssize_t								\
+ __FUNC(struct elevator_queue *e, const char *page, size_t count)	\
+@@ -4194,24 +5003,22 @@ __FUNC(struct elevator_queue *e, const char *page, size_t count)	\
+ 		__data = (MIN);						\
+ 	else if (__data > (MAX))					\
+ 		__data = (MAX);						\
+-	if (__CONV)							\
++	if (__CONV == 1)						\
+ 		*(__PTR) = msecs_to_jiffies(__data);			\
++	else if (__CONV == 2)						\
++		*(__PTR) = (u64)__data * NSEC_PER_MSEC;			\
+ 	else								\
+ 		*(__PTR) = __data;					\
+ 	return ret;							\
+ }
+ STORE_FUNCTION(bfq_fifo_expire_sync_store, &bfqd->bfq_fifo_expire[1], 1,
+-		INT_MAX, 1);
++		INT_MAX, 2);
+ STORE_FUNCTION(bfq_fifo_expire_async_store, &bfqd->bfq_fifo_expire[0], 1,
+-		INT_MAX, 1);
++		INT_MAX, 2);
+ STORE_FUNCTION(bfq_back_seek_max_store, &bfqd->bfq_back_max, 0, INT_MAX, 0);
+ STORE_FUNCTION(bfq_back_seek_penalty_store, &bfqd->bfq_back_penalty, 1,
+ 		INT_MAX, 0);
+-STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 1);
+-STORE_FUNCTION(bfq_max_budget_async_rq_store, &bfqd->bfq_max_budget_async_rq,
+-		1, INT_MAX, 0);
+-STORE_FUNCTION(bfq_timeout_async_store, &bfqd->bfq_timeout[BLK_RW_ASYNC], 0,
+-		INT_MAX, 1);
++STORE_FUNCTION(bfq_slice_idle_store, &bfqd->bfq_slice_idle, 0, INT_MAX, 2);
+ STORE_FUNCTION(bfq_wr_coeff_store, &bfqd->bfq_wr_coeff, 1, INT_MAX, 0);
+ STORE_FUNCTION(bfq_wr_max_time_store, &bfqd->bfq_wr_max_time, 0, INT_MAX, 1);
+ STORE_FUNCTION(bfq_wr_rt_max_time_store, &bfqd->bfq_wr_rt_max_time, 0, INT_MAX,
+@@ -4224,6 +5031,23 @@ STORE_FUNCTION(bfq_wr_max_softrt_rate_store, &bfqd->bfq_wr_max_softrt_rate, 0,
+ 		INT_MAX, 0);
+ #undef STORE_FUNCTION
+ 
++#define USEC_STORE_FUNCTION(__FUNC, __PTR, MIN, MAX)			\
++static ssize_t __FUNC(struct elevator_queue *e, const char *page, size_t count)\
++{									\
++	struct bfq_data *bfqd = e->elevator_data;			\
++	unsigned long __data;						\
++	int ret = bfq_var_store(&__data, (page), count);		\
++	if (__data < (MIN))						\
++		__data = (MIN);						\
++	else if (__data > (MAX))					\
++		__data = (MAX);						\
++	*(__PTR) = (u64)__data * NSEC_PER_USEC;				\
++	return ret;							\
++}
++USEC_STORE_FUNCTION(bfq_slice_idle_us_store, &bfqd->bfq_slice_idle, 0,
++		    UINT_MAX);
++#undef USEC_STORE_FUNCTION
++
+ /* do nothing for the moment */
+ static ssize_t bfq_weights_store(struct elevator_queue *e,
+ 				    const char *page, size_t count)
+@@ -4231,16 +5055,6 @@ static ssize_t bfq_weights_store(struct elevator_queue *e,
+ 	return count;
+ }
+ 
+-static unsigned long bfq_estimated_max_budget(struct bfq_data *bfqd)
+-{
+-	u64 timeout = jiffies_to_msecs(bfqd->bfq_timeout[BLK_RW_SYNC]);
+-
+-	if (bfqd->peak_rate_samples >= BFQ_PEAK_RATE_SAMPLES)
+-		return bfq_calc_max_budget(bfqd->peak_rate, timeout);
+-	else
+-		return bfq_default_max_budget;
+-}
+-
+ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
+ 				    const char *page, size_t count)
+ {
+@@ -4249,7 +5063,7 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
+ 	int ret = bfq_var_store(&__data, (page), count);
+ 
+ 	if (__data == 0)
+-		bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
++		bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
+ 	else {
+ 		if (__data > INT_MAX)
+ 			__data = INT_MAX;
+@@ -4261,6 +5075,10 @@ static ssize_t bfq_max_budget_store(struct elevator_queue *e,
+ 	return ret;
+ }
+ 
++/*
++ * Leaving this name to preserve name compatibility with cfq
++ * parameters, but this timeout is used for both sync and async.
++ */
+ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
+ 				      const char *page, size_t count)
+ {
+@@ -4273,9 +5091,27 @@ static ssize_t bfq_timeout_sync_store(struct elevator_queue *e,
+ 	else if (__data > INT_MAX)
+ 		__data = INT_MAX;
+ 
+-	bfqd->bfq_timeout[BLK_RW_SYNC] = msecs_to_jiffies(__data);
++	bfqd->bfq_timeout = msecs_to_jiffies(__data);
+ 	if (bfqd->bfq_user_max_budget == 0)
+-		bfqd->bfq_max_budget = bfq_estimated_max_budget(bfqd);
++		bfqd->bfq_max_budget = bfq_calc_max_budget(bfqd);
++
++	return ret;
++}
++
++static ssize_t bfq_strict_guarantees_store(struct elevator_queue *e,
++				     const char *page, size_t count)
++{
++	struct bfq_data *bfqd = e->elevator_data;
++	unsigned long uninitialized_var(__data);
++	int ret = bfq_var_store(&__data, (page), count);
++
++	if (__data > 1)
++		__data = 1;
++	if (!bfqd->strict_guarantees && __data == 1
++	    && bfqd->bfq_slice_idle < 8 * NSEC_PER_MSEC)
++		bfqd->bfq_slice_idle = 8 * NSEC_PER_MSEC;
++
++	bfqd->strict_guarantees = __data;
+ 
+ 	return ret;
+ }
+@@ -4305,10 +5141,10 @@ static struct elv_fs_entry bfq_attrs[] = {
+ 	BFQ_ATTR(back_seek_max),
+ 	BFQ_ATTR(back_seek_penalty),
+ 	BFQ_ATTR(slice_idle),
++	BFQ_ATTR(slice_idle_us),
+ 	BFQ_ATTR(max_budget),
+-	BFQ_ATTR(max_budget_async_rq),
+ 	BFQ_ATTR(timeout_sync),
+-	BFQ_ATTR(timeout_async),
++	BFQ_ATTR(strict_guarantees),
+ 	BFQ_ATTR(low_latency),
+ 	BFQ_ATTR(wr_coeff),
+ 	BFQ_ATTR(wr_max_time),
+@@ -4328,7 +5164,8 @@ static struct elevator_type iosched_bfq = {
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 		.elevator_bio_merged_fn =	bfq_bio_merged,
+ #endif
+-		.elevator_allow_merge_fn =	bfq_allow_merge,
++		.elevator_allow_bio_merge_fn =	bfq_allow_bio_merge,
++		.elevator_allow_rq_merge_fn =	bfq_allow_rq_merge,
+ 		.elevator_dispatch_fn =		bfq_dispatch_requests,
+ 		.elevator_add_req_fn =		bfq_insert_request,
+ 		.elevator_activate_req_fn =	bfq_activate_request,
+@@ -4351,18 +5188,28 @@ static struct elevator_type iosched_bfq = {
+ 	.elevator_owner =	THIS_MODULE,
+ };
+ 
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++static struct blkcg_policy blkcg_policy_bfq = {
++	.dfl_cftypes		= bfq_blkg_files,
++	.legacy_cftypes		= bfq_blkcg_legacy_files,
++
++	.cpd_alloc_fn		= bfq_cpd_alloc,
++	.cpd_init_fn		= bfq_cpd_init,
++	.cpd_bind_fn	        = bfq_cpd_init,
++	.cpd_free_fn		= bfq_cpd_free,
++
++	.pd_alloc_fn		= bfq_pd_alloc,
++	.pd_init_fn		= bfq_pd_init,
++	.pd_offline_fn		= bfq_pd_offline,
++	.pd_free_fn		= bfq_pd_free,
++	.pd_reset_stats_fn	= bfq_pd_reset_stats,
++};
++#endif
++
+ static int __init bfq_init(void)
+ {
+ 	int ret;
+-
+-	/*
+-	 * Can be 0 on HZ < 1000 setups.
+-	 */
+-	if (bfq_slice_idle == 0)
+-		bfq_slice_idle = 1;
+-
+-	if (bfq_timeout_async == 0)
+-		bfq_timeout_async = 1;
++	char msg[50] = "BFQ I/O-scheduler: v8r4";
+ 
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	ret = blkcg_policy_register(&blkcg_policy_bfq);
+@@ -4375,27 +5222,46 @@ static int __init bfq_init(void)
+ 		goto err_pol_unreg;
+ 
+ 	/*
+-	 * Times to load large popular applications for the typical systems
+-	 * installed on the reference devices (see the comments before the
+-	 * definitions of the two arrays).
++	 * Times to load large popular applications for the typical
++	 * systems installed on the reference devices (see the
++	 * comments before the definitions of the next two
++	 * arrays). Actually, we use slightly slower values, as the
++	 * estimated peak rate tends to be smaller than the actual
++	 * peak rate.  The reason for this last fact is that estimates
++	 * are computed over much shorter time intervals than the long
++	 * intervals typically used for benchmarking. Why? First, to
++	 * adapt more quickly to variations. Second, because an I/O
++	 * scheduler cannot rely on a peak-rate-evaluation workload to
++	 * be run for a long time.
+ 	 */
+-	T_slow[0] = msecs_to_jiffies(2600);
+-	T_slow[1] = msecs_to_jiffies(1000);
+-	T_fast[0] = msecs_to_jiffies(5500);
+-	T_fast[1] = msecs_to_jiffies(2000);
++	T_slow[0] = msecs_to_jiffies(3500); /* actually 4 sec */
++	T_slow[1] = msecs_to_jiffies(1000); /* actually 1.5 sec */
++	T_fast[0] = msecs_to_jiffies(7000); /* actually 8 sec */
++	T_fast[1] = msecs_to_jiffies(2500); /* actually 3 sec */
+ 
+ 	/*
+-	 * Thresholds that determine the switch between speed classes (see
+-	 * the comments before the definition of the array).
++	 * Thresholds that determine the switch between speed classes
++	 * (see the comments before the definition of the array
++	 * device_speed_thresh). These thresholds are biased towards
++	 * transitions to the fast class. This is safer than the
++	 * opposite bias. In fact, a wrong transition to the slow
++	 * class results in short weight-raising periods, because the
++	 * speed of the device then tends to be higher that the
++	 * reference peak rate. On the opposite end, a wrong
++	 * transition to the fast class tends to increase
++	 * weight-raising periods, because of the opposite reason.
+ 	 */
+-	device_speed_thresh[0] = (R_fast[0] + R_slow[0]) / 2;
+-	device_speed_thresh[1] = (R_fast[1] + R_slow[1]) / 2;
++	device_speed_thresh[0] = (4 * R_slow[0]) / 3;
++	device_speed_thresh[1] = (4 * R_slow[1]) / 3;
+ 
+ 	ret = elv_register(&iosched_bfq);
+ 	if (ret)
+ 		goto err_pol_unreg;
+ 
+-	pr_info("BFQ I/O-scheduler: v7r11");
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	strcat(msg, " (with cgroups support)");
++#endif
++	pr_info("%s", msg);
+ 
+ 	return 0;
+ 
+diff --git a/block/bfq-sched.c b/block/bfq-sched.c
+index a5ed694..45d63d3 100644
+--- a/block/bfq-sched.c
++++ b/block/bfq-sched.c
+@@ -7,9 +7,13 @@
+  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+  *		      Paolo Valente <paolo.valente@unimore.it>
+  *
+- * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+  */
+ 
++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
++
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ #define for_each_entity(entity)	\
+ 	for (; entity ; entity = entity->parent)
+@@ -22,8 +26,6 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+ 						 int extract,
+ 						 struct bfq_data *bfqd);
+ 
+-static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
+-
+ static void bfq_update_budget(struct bfq_entity *next_in_service)
+ {
+ 	struct bfq_entity *bfqg_entity;
+@@ -48,6 +50,7 @@ static void bfq_update_budget(struct bfq_entity *next_in_service)
+ static int bfq_update_next_in_service(struct bfq_sched_data *sd)
+ {
+ 	struct bfq_entity *next_in_service;
++	struct bfq_queue *bfqq;
+ 
+ 	if (sd->in_service_entity)
+ 		/* will update/requeue at the end of service */
+@@ -65,14 +68,29 @@ static int bfq_update_next_in_service(struct bfq_sched_data *sd)
+ 
+ 	if (next_in_service)
+ 		bfq_update_budget(next_in_service);
++	else
++		goto exit;
++
++	bfqq = bfq_entity_to_bfqq(next_in_service);
++	if (bfqq)
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			     "update_next_in_service: chosen this queue");
++	else {
++		struct bfq_group *bfqg =
++			container_of(next_in_service,
++				     struct bfq_group, entity);
+ 
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			     "update_next_in_service: chosen this entity");
++	}
++exit:
+ 	return 1;
+ }
+ 
+ static void bfq_check_next_in_service(struct bfq_sched_data *sd,
+ 				      struct bfq_entity *entity)
+ {
+-	BUG_ON(sd->next_in_service != entity);
++	WARN_ON(sd->next_in_service != entity);
+ }
+ #else
+ #define for_each_entity(entity)	\
+@@ -151,20 +169,36 @@ static u64 bfq_delta(unsigned long service, unsigned long weight)
+ static void bfq_calc_finish(struct bfq_entity *entity, unsigned long service)
+ {
+ 	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	unsigned long long start, finish, delta;
+ 
+ 	BUG_ON(entity->weight == 0);
+ 
+ 	entity->finish = entity->start +
+ 		bfq_delta(service, entity->weight);
+ 
++	start = ((entity->start>>10)*1000)>>12;
++	finish = ((entity->finish>>10)*1000)>>12;
++	delta = ((bfq_delta(service, entity->weight)>>10)*1000)>>12;
++
+ 	if (bfqq) {
+ 		bfq_log_bfqq(bfqq->bfqd, bfqq,
+ 			"calc_finish: serv %lu, w %d",
+ 			service, entity->weight);
+ 		bfq_log_bfqq(bfqq->bfqd, bfqq,
+ 			"calc_finish: start %llu, finish %llu, delta %llu",
+-			entity->start, entity->finish,
+-			bfq_delta(service, entity->weight));
++			start, finish, delta);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	} else {
++		struct bfq_group *bfqg =
++			container_of(entity, struct bfq_group, entity);
++
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			"calc_finish group: serv %lu, w %d",
++			     service, entity->weight);
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			"calc_finish group: start %llu, finish %llu, delta %llu",
++			start, finish, delta);
++#endif
+ 	}
+ }
+ 
+@@ -293,10 +327,26 @@ static void bfq_update_min(struct bfq_entity *entity, struct rb_node *node)
+ static void bfq_update_active_node(struct rb_node *node)
+ {
+ 	struct bfq_entity *entity = rb_entry(node, struct bfq_entity, rb_node);
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
+ 
+ 	entity->min_start = entity->start;
+ 	bfq_update_min(entity, node->rb_right);
+ 	bfq_update_min(entity, node->rb_left);
++
++	if (bfqq) {
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			     "update_active_node: new min_start %llu",
++			     ((entity->min_start>>10)*1000)>>12);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	} else {
++		struct bfq_group *bfqg =
++			container_of(entity, struct bfq_group, entity);
++
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			     "update_active_node: new min_start %llu",
++			     ((entity->min_start>>10)*1000)>>12);
++#endif
++	}
+ }
+ 
+ /**
+@@ -386,8 +436,6 @@ static void bfq_active_insert(struct bfq_service_tree *st,
+ 		BUG_ON(!bfqg);
+ 		BUG_ON(!bfqd);
+ 		bfqg->active_entities++;
+-		if (bfqg->active_entities == 2)
+-			bfqd->active_numerous_groups++;
+ 	}
+ #endif
+ }
+@@ -399,7 +447,7 @@ static void bfq_active_insert(struct bfq_service_tree *st,
+ static unsigned short bfq_ioprio_to_weight(int ioprio)
+ {
+ 	BUG_ON(ioprio < 0 || ioprio >= IOPRIO_BE_NR);
+-	return IOPRIO_BE_NR * BFQ_WEIGHT_CONVERSION_COEFF - ioprio;
++	return (IOPRIO_BE_NR - ioprio) * BFQ_WEIGHT_CONVERSION_COEFF;
+ }
+ 
+ /**
+@@ -422,9 +470,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
+ 	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
+ 
+ 	if (bfqq) {
+-		atomic_inc(&bfqq->ref);
++		bfqq->ref++;
+ 		bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
+-			     bfqq, atomic_read(&bfqq->ref));
++			     bfqq, bfqq->ref);
+ 	}
+ }
+ 
+@@ -499,10 +547,6 @@ static void bfq_active_extract(struct bfq_service_tree *st,
+ 		BUG_ON(!bfqd);
+ 		BUG_ON(!bfqg->active_entities);
+ 		bfqg->active_entities--;
+-		if (bfqg->active_entities == 1) {
+-			BUG_ON(!bfqd->active_numerous_groups);
+-			bfqd->active_numerous_groups--;
+-		}
+ 	}
+ #endif
+ }
+@@ -552,7 +596,7 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
+ 	if (bfqq) {
+ 		sd = entity->sched_data;
+ 		bfq_log_bfqq(bfqq->bfqd, bfqq, "forget_entity: %p %d",
+-			     bfqq, atomic_read(&bfqq->ref));
++			     bfqq, bfqq->ref);
+ 		bfq_put_queue(bfqq);
+ 	}
+ }
+@@ -602,7 +646,7 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+ 
+ 	if (entity->prio_changed) {
+ 		struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
+-		unsigned short prev_weight, new_weight;
++		unsigned int prev_weight, new_weight;
+ 		struct bfq_data *bfqd = NULL;
+ 		struct rb_root *root;
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+@@ -630,7 +674,10 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+ 			    entity->new_weight > BFQ_MAX_WEIGHT) {
+ 				pr_crit("update_weight_prio: new_weight %d\n",
+ 					entity->new_weight);
+-				BUG();
++				if (entity->new_weight < BFQ_MIN_WEIGHT)
++					entity->new_weight = BFQ_MIN_WEIGHT;
++				else
++					entity->new_weight = BFQ_MAX_WEIGHT;
+ 			}
+ 			entity->orig_weight = entity->new_weight;
+ 			if (bfqq)
+@@ -661,6 +708,13 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+ 		 * associated with its new weight.
+ 		 */
+ 		if (prev_weight != new_weight) {
++			if (bfqq)
++				bfq_log_bfqq(bfqq->bfqd, bfqq,
++					     "weight changed %d %d(%d %d)",
++					     prev_weight, new_weight,
++					     entity->orig_weight,
++					     bfqq->wr_coeff);
++
+ 			root = bfqq ? &bfqd->queue_weights_tree :
+ 				      &bfqd->group_weights_tree;
+ 			bfq_weights_tree_remove(bfqd, entity, root);
+@@ -707,7 +761,7 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
+ 		st = bfq_entity_service_tree(entity);
+ 
+ 		entity->service += served;
+-		BUG_ON(entity->service > entity->budget);
++
+ 		BUG_ON(st->wsum == 0);
+ 
+ 		st->vtime += bfq_delta(served, st->wsum);
+@@ -716,31 +770,69 @@ static void bfq_bfqq_served(struct bfq_queue *bfqq, int served)
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	bfqg_stats_set_start_empty_time(bfqq_group(bfqq));
+ #endif
+-	bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs", served);
++	st = bfq_entity_service_tree(&bfqq->entity);
++	bfq_log_bfqq(bfqq->bfqd, bfqq, "bfqq_served %d secs, vtime %llu on %p",
++		     served,  ((st->vtime>>10)*1000)>>12, st);
+ }
+ 
+ /**
+- * bfq_bfqq_charge_full_budget - set the service to the entity budget.
++ * bfq_bfqq_charge_time - charge an amount of service equivalent to the length
++ *			  of the time interval during which bfqq has been in
++ *			  service.
++ * @bfqd: the device
+  * @bfqq: the queue that needs a service update.
++ * @time_ms: the amount of time during which the queue has received service
+  *
+- * When it's not possible to be fair in the service domain, because
+- * a queue is not consuming its budget fast enough (the meaning of
+- * fast depends on the timeout parameter), we charge it a full
+- * budget.  In this way we should obtain a sort of time-domain
+- * fairness among all the seeky/slow queues.
++ * If a queue does not consume its budget fast enough, then providing
++ * the queue with service fairness may impair throughput, more or less
++ * severely. For this reason, queues that consume their budget slowly
++ * are provided with time fairness instead of service fairness. This
++ * goal is achieved through the BFQ scheduling engine, even if such an
++ * engine works in the service, and not in the time domain. The trick
++ * is charging these queues with an inflated amount of service, equal
++ * to the amount of service that they would have received during their
++ * service slot if they had been fast, i.e., if their requests had
++ * been dispatched at a rate equal to the estimated peak rate.
++ *
++ * It is worth noting that time fairness can cause important
++ * distortions in terms of bandwidth distribution, on devices with
++ * internal queueing. The reason is that I/O requests dispatched
++ * during the service slot of a queue may be served after that service
++ * slot is finished, and may have a total processing time loosely
++ * correlated with the duration of the service slot. This is
++ * especially true for short service slots.
+  */
+-static void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
++static void bfq_bfqq_charge_time(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++				 unsigned long time_ms)
+ {
+ 	struct bfq_entity *entity = &bfqq->entity;
++	int tot_serv_to_charge = entity->service;
++	unsigned int timeout_ms = jiffies_to_msecs(bfq_timeout);
++
++	if (time_ms > 0 && time_ms < timeout_ms)
++		tot_serv_to_charge =
++			(bfqd->bfq_max_budget * time_ms) / timeout_ms;
+ 
+-	bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
++	if (tot_serv_to_charge < entity->service)
++		tot_serv_to_charge = entity->service;
+ 
+-	bfq_bfqq_served(bfqq, entity->budget - entity->service);
++	bfq_log_bfqq(bfqq->bfqd, bfqq,
++		     "charge_time: %lu/%u ms, %d/%d/%d sectors",
++		     time_ms, timeout_ms, entity->service,
++		     tot_serv_to_charge, entity->budget);
++
++	/* Increase budget to avoid inconsistencies */
++	if (tot_serv_to_charge > entity->budget)
++		entity->budget = tot_serv_to_charge;
++
++	bfq_bfqq_served(bfqq,
++			max_t(int, 0, tot_serv_to_charge - entity->service));
+ }
+ 
+ /**
+  * __bfq_activate_entity - activate an entity.
+  * @entity: the entity being activated.
++ * @non_blocking_wait_rq: true if this entity was waiting for a request
+  *
+  * Called whenever an entity is activated, i.e., it is not active and one
+  * of its children receives a new request, or has to be reactivated due to
+@@ -748,11 +840,16 @@ static void bfq_bfqq_charge_full_budget(struct bfq_queue *bfqq)
+  * service received if @entity is active) of the queue to calculate its
+  * timestamps.
+  */
+-static void __bfq_activate_entity(struct bfq_entity *entity)
++static void __bfq_activate_entity(struct bfq_entity *entity,
++				  bool non_blocking_wait_rq)
+ {
+ 	struct bfq_sched_data *sd = entity->sched_data;
+ 	struct bfq_service_tree *st = bfq_entity_service_tree(entity);
++	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++	bool backshifted = false;
+ 
++	BUG_ON(!sd);
++	BUG_ON(!st);
+ 	if (entity == sd->in_service_entity) {
+ 		BUG_ON(entity->tree);
+ 		/*
+@@ -770,45 +867,133 @@ static void __bfq_activate_entity(struct bfq_entity *entity)
+ 		 * old start time.
+ 		 */
+ 		bfq_active_extract(st, entity);
+-	} else if (entity->tree == &st->idle) {
+-		/*
+-		 * Must be on the idle tree, bfq_idle_extract() will
+-		 * check for that.
+-		 */
+-		bfq_idle_extract(st, entity);
+-		entity->start = bfq_gt(st->vtime, entity->finish) ?
+-				       st->vtime : entity->finish;
+ 	} else {
+-		/*
+-		 * The finish time of the entity may be invalid, and
+-		 * it is in the past for sure, otherwise the queue
+-		 * would have been on the idle tree.
+-		 */
+-		entity->start = st->vtime;
+-		st->wsum += entity->weight;
+-		bfq_get_entity(entity);
++		unsigned long long min_vstart;
++
++		/* See comments on bfq_fqq_update_budg_for_activation */
++		if (non_blocking_wait_rq && bfq_gt(st->vtime, entity->finish)) {
++			backshifted = true;
++			min_vstart = entity->finish;
++		} else
++			min_vstart = st->vtime;
++
++		if (entity->tree == &st->idle) {
++			/*
++			 * Must be on the idle tree, bfq_idle_extract() will
++			 * check for that.
++			 */
++			bfq_idle_extract(st, entity);
++			entity->start = bfq_gt(min_vstart, entity->finish) ?
++				min_vstart : entity->finish;
++		} else {
++			/*
++			 * The finish time of the entity may be invalid, and
++			 * it is in the past for sure, otherwise the queue
++			 * would have been on the idle tree.
++			 */
++			entity->start = min_vstart;
++			st->wsum += entity->weight;
++			bfq_get_entity(entity);
+ 
+-		BUG_ON(entity->on_st);
+-		entity->on_st = 1;
++			BUG_ON(entity->on_st);
++			entity->on_st = 1;
++		}
+ 	}
+ 
+ 	st = __bfq_entity_update_weight_prio(st, entity);
+ 	bfq_calc_finish(entity, entity->budget);
++
++	/*
++	 * If some queues enjoy backshifting for a while, then their
++	 * (virtual) finish timestamps may happen to become lower and
++	 * lower than the system virtual time.  In particular, if
++	 * these queues often happen to be idle for short time
++	 * periods, and during such time periods other queues with
++	 * higher timestamps happen to be busy, then the backshifted
++	 * timestamps of the former queues can become much lower than
++	 * the system virtual time. In fact, to serve the queues with
++	 * higher timestamps while the ones with lower timestamps are
++	 * idle, the system virtual time may be pushed-up to much
++	 * higher values than the finish timestamps of the idle
++	 * queues. As a consequence, the finish timestamps of all new
++	 * or newly activated queues may end up being much larger than
++	 * those of lucky queues with backshifted timestamps. The
++	 * latter queues may then monopolize the device for a lot of
++	 * time. This would simply break service guarantees.
++	 *
++	 * To reduce this problem, push up a little bit the
++	 * backshifted timestamps of the queue associated with this
++	 * entity (only a queue can happen to have the backshifted
++	 * flag set): just enough to let the finish timestamp of the
++	 * queue be equal to the current value of the system virtual
++	 * time. This may introduce a little unfairness among queues
++	 * with backshifted timestamps, but it does not break
++	 * worst-case fairness guarantees.
++	 *
++	 * As a special case, if bfqq is weight-raised, push up
++	 * timestamps much less, to keep very low the probability that
++	 * this push up causes the backshifted finish timestamps of
++	 * weight-raised queues to become higher than the backshifted
++	 * finish timestamps of non weight-raised queues.
++	 */
++	if (backshifted && bfq_gt(st->vtime, entity->finish)) {
++		unsigned long delta = st->vtime - entity->finish;
++
++		if (bfqq)
++			delta /= bfqq->wr_coeff;
++
++		entity->start += delta;
++		entity->finish += delta;
++
++		if (bfqq) {
++			bfq_log_bfqq(bfqq->bfqd, bfqq,
++				     "__activate_entity: new queue finish %llu",
++				     ((entity->finish>>10)*1000)>>12);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		} else {
++			struct bfq_group *bfqg =
++				container_of(entity, struct bfq_group, entity);
++
++			bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++				     "__activate_entity: new group finish %llu",
++				     ((entity->finish>>10)*1000)>>12);
++#endif
++		}
++	}
++
+ 	bfq_active_insert(st, entity);
++
++	if (bfqq) {
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			"__activate_entity: queue %seligible in st %p",
++			     entity->start <= st->vtime ? "" : "non ", st);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	} else {
++		struct bfq_group *bfqg =
++			container_of(entity, struct bfq_group, entity);
++
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			"__activate_entity: group %seligible in st %p",
++			     entity->start <= st->vtime ? "" : "non ", st);
++#endif
++	}
+ }
+ 
+ /**
+  * bfq_activate_entity - activate an entity and its ancestors if necessary.
+  * @entity: the entity to activate.
++ * @non_blocking_wait_rq: true if this entity was waiting for a request
+  *
+  * Activate @entity and all the entities on the path from it to the root.
+  */
+-static void bfq_activate_entity(struct bfq_entity *entity)
++static void bfq_activate_entity(struct bfq_entity *entity,
++				bool non_blocking_wait_rq)
+ {
+ 	struct bfq_sched_data *sd;
+ 
+ 	for_each_entity(entity) {
+-		__bfq_activate_entity(entity);
++		BUG_ON(!entity);
++		__bfq_activate_entity(entity, non_blocking_wait_rq);
+ 
+ 		sd = entity->sched_data;
+ 		if (!bfq_update_next_in_service(sd))
+@@ -889,23 +1074,24 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
+ 
+ 		if (!__bfq_deactivate_entity(entity, requeue))
+ 			/*
+-			 * The parent entity is still backlogged, and
+-			 * we don't need to update it as it is still
+-			 * in service.
++			 * next_in_service has not been changed, so
++			 * no upwards update is needed
+ 			 */
+ 			break;
+ 
+ 		if (sd->next_in_service)
+ 			/*
+-			 * The parent entity is still backlogged and
+-			 * the budgets on the path towards the root
+-			 * need to be updated.
++			 * The parent entity is still backlogged,
++			 * because next_in_service is not NULL, and
++			 * next_in_service has been updated (see
++			 * comment on the body of the above if):
++			 * upwards update of the schedule is needed.
+ 			 */
+ 			goto update;
+ 
+ 		/*
+-		 * If we reach there the parent is no more backlogged and
+-		 * we want to propagate the dequeue upwards.
++		 * If we get here, then the parent is no more backlogged and
++		 * we want to propagate the deactivation upwards.
+ 		 */
+ 		requeue = 1;
+ 	}
+@@ -915,9 +1101,23 @@ static void bfq_deactivate_entity(struct bfq_entity *entity, int requeue)
+ update:
+ 	entity = parent;
+ 	for_each_entity(entity) {
+-		__bfq_activate_entity(entity);
++		struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++		__bfq_activate_entity(entity, false);
+ 
+ 		sd = entity->sched_data;
++		if (bfqq)
++			bfq_log_bfqq(bfqq->bfqd, bfqq,
++				     "invoking udpdate_next for this queue");
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		else {
++			struct bfq_group *bfqg =
++				container_of(entity,
++					     struct bfq_group, entity);
++
++			bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++				     "invoking udpdate_next for this entity");
++		}
++#endif
+ 		if (!bfq_update_next_in_service(sd))
+ 			break;
+ 	}
+@@ -943,7 +1143,23 @@ static void bfq_update_vtime(struct bfq_service_tree *st)
+ 
+ 	entry = rb_entry(node, struct bfq_entity, rb_node);
+ 	if (bfq_gt(entry->min_start, st->vtime)) {
++		struct bfq_queue *bfqq = bfq_entity_to_bfqq(entry);
+ 		st->vtime = entry->min_start;
++
++		if (bfqq)
++			bfq_log_bfqq(bfqq->bfqd, bfqq,
++				     "update_vtime: new vtime %llu %p",
++				     ((st->vtime>>10)*1000)>>12, st);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		else {
++			struct bfq_group *bfqg =
++				container_of(entry, struct bfq_group, entity);
++
++			bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++				     "update_vtime: new vtime %llu %p",
++				     ((st->vtime>>10)*1000)>>12, st);
++		}
++#endif
+ 		bfq_forget_idle(st);
+ 	}
+ }
+@@ -996,10 +1212,11 @@ left:
+  * Update the virtual time in @st and return the first eligible entity
+  * it contains.
+  */
+-static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
+-						   bool force)
++static struct bfq_entity *
++__bfq_lookup_next_entity(struct bfq_service_tree *st, bool force)
+ {
+ 	struct bfq_entity *entity, *new_next_in_service = NULL;
++	struct bfq_queue *bfqq;
+ 
+ 	if (RB_EMPTY_ROOT(&st->active))
+ 		return NULL;
+@@ -1008,6 +1225,24 @@ static struct bfq_entity *__bfq_lookup_next_entity(struct bfq_service_tree *st,
+ 	entity = bfq_first_active_entity(st);
+ 	BUG_ON(bfq_gt(entity->start, st->vtime));
+ 
++	bfqq = bfq_entity_to_bfqq(entity);
++	if (bfqq)
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			     "__lookup_next: start %llu vtime %llu st %p",
++			     ((entity->start>>10)*1000)>>12,
++			     ((st->vtime>>10)*1000)>>12, st);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	else {
++		struct bfq_group *bfqg =
++			container_of(entity, struct bfq_group, entity);
++
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			     "__lookup_next: start %llu vtime %llu st %p",
++			     ((entity->start>>10)*1000)>>12,
++			     ((st->vtime>>10)*1000)>>12, st);
++	}
++#endif
++
+ 	/*
+ 	 * If the chosen entity does not match with the sched_data's
+ 	 * next_in_service and we are forcedly serving the IDLE priority
+@@ -1043,11 +1278,36 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+ 
+ 	BUG_ON(sd->in_service_entity);
+ 
++	/*
++	 * Choose from idle class, if needed to guarantee a minimum
++	 * bandwidth to this class. This should also mitigate
++	 * priority-inversion problems in case a low priority task is
++	 * holding file system resources.
++	 */
+ 	if (bfqd &&
+-	    jiffies - bfqd->bfq_class_idle_last_service > BFQ_CL_IDLE_TIMEOUT) {
++	    jiffies - bfqd->bfq_class_idle_last_service >
++	    BFQ_CL_IDLE_TIMEOUT) {
+ 		entity = __bfq_lookup_next_entity(st + BFQ_IOPRIO_CLASSES - 1,
+ 						  true);
+ 		if (entity) {
++			struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++			if (bfqq)
++				bfq_log_bfqq(bfqd, bfqq,
++					     "idle chosen from st %p %d",
++					     st + BFQ_IOPRIO_CLASSES - 1,
++					BFQ_IOPRIO_CLASSES - 1);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++			else {
++				struct bfq_group *bfqg =
++				container_of(entity, struct bfq_group, entity);
++
++				bfq_log_bfqg(bfqd, bfqg,
++					     "idle chosen from st %p %d",
++					     st + BFQ_IOPRIO_CLASSES - 1,
++					BFQ_IOPRIO_CLASSES - 1);
++			}
++#endif
+ 			i = BFQ_IOPRIO_CLASSES - 1;
+ 			bfqd->bfq_class_idle_last_service = jiffies;
+ 			sd->next_in_service = entity;
+@@ -1056,6 +1316,25 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+ 	for (; i < BFQ_IOPRIO_CLASSES; i++) {
+ 		entity = __bfq_lookup_next_entity(st + i, false);
+ 		if (entity) {
++			if (bfqd != NULL) {
++			struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
++
++			if (bfqq)
++				bfq_log_bfqq(bfqd, bfqq,
++					     "chosen from st %p %d",
++					     st + i, i);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++			else {
++				struct bfq_group *bfqg =
++				container_of(entity, struct bfq_group, entity);
++
++				bfq_log_bfqg(bfqd, bfqg,
++					     "chosen from st %p %d",
++					     st + i, i);
++			}
++#endif
++			}
++
+ 			if (extract) {
+ 				bfq_check_next_in_service(sd, entity);
+ 				bfq_active_extract(st + i, entity);
+@@ -1069,6 +1348,13 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+ 	return entity;
+ }
+ 
++static bool next_queue_may_preempt(struct bfq_data *bfqd)
++{
++	struct bfq_sched_data *sd = &bfqd->root_group->sched_data;
++
++	return sd->next_in_service != sd->in_service_entity;
++}
++
+ /*
+  * Get next queue for service.
+  */
+@@ -1085,7 +1371,36 @@ static struct bfq_queue *bfq_get_next_queue(struct bfq_data *bfqd)
+ 
+ 	sd = &bfqd->root_group->sched_data;
+ 	for (; sd ; sd = entity->my_sched_data) {
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		if (entity) {
++			struct bfq_group *bfqg =
++				container_of(entity, struct bfq_group, entity);
++
++			bfq_log_bfqg(bfqd, bfqg,
++				     "get_next_queue: lookup in this group");
++		} else
++			bfq_log_bfqg(bfqd, bfqd->root_group,
++				     "get_next_queue: lookup in root group");
++#endif
++
+ 		entity = bfq_lookup_next_entity(sd, 1, bfqd);
++
++		bfqq = bfq_entity_to_bfqq(entity);
++		if (bfqq)
++			bfq_log_bfqq(bfqd, bfqq,
++			     "get_next_queue: this queue, finish %llu",
++				(((entity->finish>>10)*1000)>>10)>>2);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++		else {
++			struct bfq_group *bfqg =
++				container_of(entity, struct bfq_group, entity);
++
++			bfq_log_bfqg(bfqd, bfqg,
++			     "get_next_queue: this entity, finish %llu",
++				(((entity->finish>>10)*1000)>>10)>>2);
++		}
++#endif
++
+ 		BUG_ON(!entity);
+ 		entity->service = 0;
+ 	}
+@@ -1103,8 +1418,9 @@ static void __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
+ 		bfqd->in_service_bic = NULL;
+ 	}
+ 
++	bfq_clear_bfqq_wait_request(bfqd->in_service_queue);
++	hrtimer_try_to_cancel(&bfqd->idle_slice_timer);
+ 	bfqd->in_service_queue = NULL;
+-	del_timer(&bfqd->idle_slice_timer);
+ }
+ 
+ static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+@@ -1112,9 +1428,7 @@ static void bfq_deactivate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ {
+ 	struct bfq_entity *entity = &bfqq->entity;
+ 
+-	if (bfqq == bfqd->in_service_queue)
+-		__bfq_bfqd_reset_in_service(bfqd);
+-
++	BUG_ON(bfqq == bfqd->in_service_queue);
+ 	bfq_deactivate_entity(entity, requeue);
+ }
+ 
+@@ -1122,12 +1436,11 @@ static void bfq_activate_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ {
+ 	struct bfq_entity *entity = &bfqq->entity;
+ 
+-	bfq_activate_entity(entity);
++	bfq_activate_entity(entity, bfq_bfqq_non_blocking_wait_rq(bfqq));
++	bfq_clear_bfqq_non_blocking_wait_rq(bfqq);
+ }
+ 
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ static void bfqg_stats_update_dequeue(struct bfq_group *bfqg);
+-#endif
+ 
+ /*
+  * Called when the bfqq no longer has requests pending, remove it from
+@@ -1138,6 +1451,7 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ {
+ 	BUG_ON(!bfq_bfqq_busy(bfqq));
+ 	BUG_ON(!RB_EMPTY_ROOT(&bfqq->sort_list));
++	BUG_ON(bfqq == bfqd->in_service_queue);
+ 
+ 	bfq_log_bfqq(bfqd, bfqq, "del from busy");
+ 
+@@ -1146,27 +1460,20 @@ static void bfq_del_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	BUG_ON(bfqd->busy_queues == 0);
+ 	bfqd->busy_queues--;
+ 
+-	if (!bfqq->dispatched) {
++	if (!bfqq->dispatched)
+ 		bfq_weights_tree_remove(bfqd, &bfqq->entity,
+ 					&bfqd->queue_weights_tree);
+-		if (!blk_queue_nonrot(bfqd->queue)) {
+-			BUG_ON(!bfqd->busy_in_flight_queues);
+-			bfqd->busy_in_flight_queues--;
+-			if (bfq_bfqq_constantly_seeky(bfqq)) {
+-				BUG_ON(!bfqd->
+-					const_seeky_busy_in_flight_queues);
+-				bfqd->const_seeky_busy_in_flight_queues--;
+-			}
+-		}
+-	}
++
+ 	if (bfqq->wr_coeff > 1)
+ 		bfqd->wr_busy_queues--;
+ 
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	bfqg_stats_update_dequeue(bfqq_group(bfqq));
+-#endif
++
++	BUG_ON(bfqq->entity.budget < 0);
+ 
+ 	bfq_deactivate_bfqq(bfqd, bfqq, requeue);
++
++	BUG_ON(bfqq->entity.budget < 0);
+ }
+ 
+ /*
+@@ -1184,16 +1491,11 @@ static void bfq_add_bfqq_busy(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+ 	bfq_mark_bfqq_busy(bfqq);
+ 	bfqd->busy_queues++;
+ 
+-	if (!bfqq->dispatched) {
++	if (!bfqq->dispatched)
+ 		if (bfqq->wr_coeff == 1)
+ 			bfq_weights_tree_add(bfqd, &bfqq->entity,
+ 					     &bfqd->queue_weights_tree);
+-		if (!blk_queue_nonrot(bfqd->queue)) {
+-			bfqd->busy_in_flight_queues++;
+-			if (bfq_bfqq_constantly_seeky(bfqq))
+-				bfqd->const_seeky_busy_in_flight_queues++;
+-		}
+-	}
++
+ 	if (bfqq->wr_coeff > 1)
+ 		bfqd->wr_busy_queues++;
+ }
+diff --git a/block/bfq.h b/block/bfq.h
+index fcce855..ea1e7d8 100644
+--- a/block/bfq.h
++++ b/block/bfq.h
+@@ -1,5 +1,5 @@
+ /*
+- * BFQ-v7r11 for 4.5.0: data structures and common functions prototypes.
++ * BFQ-v8r4 for 4.8.0: data structures and common functions prototypes.
+  *
+  * Based on ideas and code from CFQ:
+  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
+@@ -7,7 +7,9 @@
+  * Copyright (C) 2008 Fabio Checconi <fabio@gandalf.sssup.it>
+  *		      Paolo Valente <paolo.valente@unimore.it>
+  *
+- * Copyright (C) 2010 Paolo Valente <paolo.valente@unimore.it>
++ * Copyright (C) 2015 Paolo Valente <paolo.valente@unimore.it>
++ *
++ * Copyright (C) 2016 Paolo Valente <paolo.valente@linaro.org>
+  */
+ 
+ #ifndef _BFQ_H
+@@ -28,20 +30,21 @@
+ 
+ #define BFQ_DEFAULT_QUEUE_IOPRIO	4
+ 
+-#define BFQ_DEFAULT_GRP_WEIGHT	10
++#define BFQ_WEIGHT_LEGACY_DFL	100
+ #define BFQ_DEFAULT_GRP_IOPRIO	0
+ #define BFQ_DEFAULT_GRP_CLASS	IOPRIO_CLASS_BE
+ 
++/*
++ * Soft real-time applications are extremely more latency sensitive
++ * than interactive ones. Over-raise the weight of the former to
++ * privilege them against the latter.
++ */
++#define BFQ_SOFTRT_WEIGHT_FACTOR	100
++
+ struct bfq_entity;
+ 
+ /**
+  * struct bfq_service_tree - per ioprio_class service tree.
+- * @active: tree for active entities (i.e., those backlogged).
+- * @idle: tree for idle entities (i.e., those not backlogged, with V <= F_i).
+- * @first_idle: idle entity with minimum F_i.
+- * @last_idle: idle entity with maximum F_i.
+- * @vtime: scheduler virtual time.
+- * @wsum: scheduler weight sum; active and idle entities contribute to it.
+  *
+  * Each service tree represents a B-WF2Q+ scheduler on its own.  Each
+  * ioprio_class has its own independent scheduler, and so its own
+@@ -49,27 +52,28 @@ struct bfq_entity;
+  * of the containing bfqd.
+  */
+ struct bfq_service_tree {
++	/* tree for active entities (i.e., those backlogged) */
+ 	struct rb_root active;
++	/* tree for idle entities (i.e., not backlogged, with V <= F_i)*/
+ 	struct rb_root idle;
+ 
+-	struct bfq_entity *first_idle;
+-	struct bfq_entity *last_idle;
++	struct bfq_entity *first_idle;	/* idle entity with minimum F_i */
++	struct bfq_entity *last_idle;	/* idle entity with maximum F_i */
+ 
+-	u64 vtime;
++	u64 vtime; /* scheduler virtual time */
++	/* scheduler weight sum; active and idle entities contribute to it */
+ 	unsigned long wsum;
+ };
+ 
+ /**
+  * struct bfq_sched_data - multi-class scheduler.
+- * @in_service_entity: entity in service.
+- * @next_in_service: head-of-the-line entity in the scheduler.
+- * @service_tree: array of service trees, one per ioprio_class.
+  *
+  * bfq_sched_data is the basic scheduler queue.  It supports three
+- * ioprio_classes, and can be used either as a toplevel queue or as
+- * an intermediate queue on a hierarchical setup.
+- * @next_in_service points to the active entity of the sched_data
+- * service trees that will be scheduled next.
++ * ioprio_classes, and can be used either as a toplevel queue or as an
++ * intermediate queue on a hierarchical setup.  @next_in_service
++ * points to the active entity of the sched_data service trees that
++ * will be scheduled next. It is used to reduce the number of steps
++ * needed for each hierarchical-schedule update.
+  *
+  * The supported ioprio_classes are the same as in CFQ, in descending
+  * priority order, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE.
+@@ -79,48 +83,29 @@ struct bfq_service_tree {
+  * All the fields are protected by the queue lock of the containing bfqd.
+  */
+ struct bfq_sched_data {
+-	struct bfq_entity *in_service_entity;
++	struct bfq_entity *in_service_entity;  /* entity in service */
++	/* head-of-the-line entity in the scheduler (see comments above) */
+ 	struct bfq_entity *next_in_service;
++	/* array of service trees, one per ioprio_class */
+ 	struct bfq_service_tree service_tree[BFQ_IOPRIO_CLASSES];
+ };
+ 
+ /**
+  * struct bfq_weight_counter - counter of the number of all active entities
+  *                             with a given weight.
+- * @weight: weight of the entities that this counter refers to.
+- * @num_active: number of active entities with this weight.
+- * @weights_node: weights tree member (see bfq_data's @queue_weights_tree
+- *                and @group_weights_tree).
+  */
+ struct bfq_weight_counter {
+-	short int weight;
+-	unsigned int num_active;
++	unsigned int weight; /* weight of the entities this counter refers to */
++	unsigned int num_active; /* nr of active entities with this weight */
++	/*
++	 * Weights tree member (see bfq_data's @queue_weights_tree and
++	 * @group_weights_tree)
++	 */
+ 	struct rb_node weights_node;
+ };
+ 
+ /**
+  * struct bfq_entity - schedulable entity.
+- * @rb_node: service_tree member.
+- * @weight_counter: pointer to the weight counter associated with this entity.
+- * @on_st: flag, true if the entity is on a tree (either the active or
+- *         the idle one of its service_tree).
+- * @finish: B-WF2Q+ finish timestamp (aka F_i).
+- * @start: B-WF2Q+ start timestamp (aka S_i).
+- * @tree: tree the entity is enqueued into; %NULL if not on a tree.
+- * @min_start: minimum start time of the (active) subtree rooted at
+- *             this entity; used for O(log N) lookups into active trees.
+- * @service: service received during the last round of service.
+- * @budget: budget used to calculate F_i; F_i = S_i + @budget / @weight.
+- * @weight: weight of the queue
+- * @parent: parent entity, for hierarchical scheduling.
+- * @my_sched_data: for non-leaf nodes in the cgroup hierarchy, the
+- *                 associated scheduler queue, %NULL on leaf nodes.
+- * @sched_data: the scheduler queue this entity belongs to.
+- * @ioprio: the ioprio in use.
+- * @new_weight: when a weight change is requested, the new weight value.
+- * @orig_weight: original weight, used to implement weight boosting
+- * @prio_changed: flag, true when the user requested a weight, ioprio or
+- *		  ioprio_class change.
+  *
+  * A bfq_entity is used to represent either a bfq_queue (leaf node in the
+  * cgroup hierarchy) or a bfq_group into the upper level scheduler.  Each
+@@ -147,27 +132,52 @@ struct bfq_weight_counter {
+  * containing bfqd.
+  */
+ struct bfq_entity {
+-	struct rb_node rb_node;
++	struct rb_node rb_node; /* service_tree member */
++	/* pointer to the weight counter associated with this entity */
+ 	struct bfq_weight_counter *weight_counter;
+ 
++	/*
++	 * flag, true if the entity is on a tree (either the active or
++	 * the idle one of its service_tree).
++	 */
+ 	int on_st;
+ 
+-	u64 finish;
+-	u64 start;
++	u64 finish; /* B-WF2Q+ finish timestamp (aka F_i) */
++	u64 start;  /* B-WF2Q+ start timestamp (aka S_i) */
+ 
++	/* tree the entity is enqueued into; %NULL if not on a tree */
+ 	struct rb_root *tree;
+ 
++	/*
++	 * minimum start time of the (active) subtree rooted at this
++	 * entity; used for O(log N) lookups into active trees
++	 */
+ 	u64 min_start;
+ 
+-	int service, budget;
+-	unsigned short weight, new_weight;
+-	unsigned short orig_weight;
++	/* amount of service received during the last service slot */
++	int service;
++
++	/* budget, used also to calculate F_i: F_i = S_i + @budget / @weight */
++	int budget;
++
++	unsigned int weight;	 /* weight of the queue */
++	unsigned int new_weight; /* next weight if a change is in progress */
++
++	/* original weight, used to implement weight boosting */
++	unsigned int orig_weight;
+ 
++	/* parent entity, for hierarchical scheduling */
+ 	struct bfq_entity *parent;
+ 
++	/*
++	 * For non-leaf nodes in the hierarchy, the associated
++	 * scheduler queue, %NULL on leaf nodes.
++	 */
+ 	struct bfq_sched_data *my_sched_data;
++	/* the scheduler queue this entity belongs to */
+ 	struct bfq_sched_data *sched_data;
+ 
++	/* flag, set to request a weight, ioprio or ioprio_class change  */
+ 	int prio_changed;
+ };
+ 
+@@ -175,56 +185,6 @@ struct bfq_group;
+ 
+ /**
+  * struct bfq_queue - leaf schedulable entity.
+- * @ref: reference counter.
+- * @bfqd: parent bfq_data.
+- * @new_ioprio: when an ioprio change is requested, the new ioprio value.
+- * @ioprio_class: the ioprio_class in use.
+- * @new_ioprio_class: when an ioprio_class change is requested, the new
+- *                    ioprio_class value.
+- * @new_bfqq: shared bfq_queue if queue is cooperating with
+- *           one or more other queues.
+- * @pos_node: request-position tree member (see bfq_group's @rq_pos_tree).
+- * @pos_root: request-position tree root (see bfq_group's @rq_pos_tree).
+- * @sort_list: sorted list of pending requests.
+- * @next_rq: if fifo isn't expired, next request to serve.
+- * @queued: nr of requests queued in @sort_list.
+- * @allocated: currently allocated requests.
+- * @meta_pending: pending metadata requests.
+- * @fifo: fifo list of requests in sort_list.
+- * @entity: entity representing this queue in the scheduler.
+- * @max_budget: maximum budget allowed from the feedback mechanism.
+- * @budget_timeout: budget expiration (in jiffies).
+- * @dispatched: number of requests on the dispatch list or inside driver.
+- * @flags: status flags.
+- * @bfqq_list: node for active/idle bfqq list inside our bfqd.
+- * @burst_list_node: node for the device's burst list.
+- * @seek_samples: number of seeks sampled
+- * @seek_total: sum of the distances of the seeks sampled
+- * @seek_mean: mean seek distance
+- * @last_request_pos: position of the last request enqueued
+- * @requests_within_timer: number of consecutive pairs of request completion
+- *                         and arrival, such that the queue becomes idle
+- *                         after the completion, but the next request arrives
+- *                         within an idle time slice; used only if the queue's
+- *                         IO_bound has been cleared.
+- * @pid: pid of the process owning the queue, used for logging purposes.
+- * @last_wr_start_finish: start time of the current weight-raising period if
+- *                        the @bfq-queue is being weight-raised, otherwise
+- *                        finish time of the last weight-raising period
+- * @wr_cur_max_time: current max raising time for this queue
+- * @soft_rt_next_start: minimum time instant such that, only if a new
+- *                      request is enqueued after this time instant in an
+- *                      idle @bfq_queue with no outstanding requests, then
+- *                      the task associated with the queue it is deemed as
+- *                      soft real-time (see the comments to the function
+- *                      bfq_bfqq_softrt_next_start())
+- * @last_idle_bklogged: time of the last transition of the @bfq_queue from
+- *                      idle to backlogged
+- * @service_from_backlogged: cumulative service received from the @bfq_queue
+- *                           since the last transition from idle to
+- *                           backlogged
+- * @bic: pointer to the bfq_io_cq owning the bfq_queue, set to %NULL if the
+- *	 queue is shared
+  *
+  * A bfq_queue is a leaf request queue; it can be associated with an
+  * io_context or more, if it  is  async or shared  between  cooperating
+@@ -235,117 +195,174 @@ struct bfq_group;
+  * All the fields are protected by the queue lock of the containing bfqd.
+  */
+ struct bfq_queue {
+-	atomic_t ref;
++	/* reference counter */
++	int ref;
++	/* parent bfq_data */
+ 	struct bfq_data *bfqd;
+ 
+-	unsigned short ioprio, new_ioprio;
+-	unsigned short ioprio_class, new_ioprio_class;
++	/* current ioprio and ioprio class */
++	unsigned short ioprio, ioprio_class;
++	/* next ioprio and ioprio class if a change is in progress */
++	unsigned short new_ioprio, new_ioprio_class;
+ 
+-	/* fields for cooperating queues handling */
++	/*
++	 * Shared bfq_queue if queue is cooperating with one or more
++	 * other queues.
++	 */
+ 	struct bfq_queue *new_bfqq;
++	/* request-position tree member (see bfq_group's @rq_pos_tree) */
+ 	struct rb_node pos_node;
++	/* request-position tree root (see bfq_group's @rq_pos_tree) */
+ 	struct rb_root *pos_root;
+ 
++	/* sorted list of pending requests */
+ 	struct rb_root sort_list;
++	/* if fifo isn't expired, next request to serve */
+ 	struct request *next_rq;
++	/* number of sync and async requests queued */
+ 	int queued[2];
++	/* number of sync and async requests currently allocated */
+ 	int allocated[2];
++	/* number of pending metadata requests */
+ 	int meta_pending;
++	/* fifo list of requests in sort_list */
+ 	struct list_head fifo;
+ 
++	/* entity representing this queue in the scheduler */
+ 	struct bfq_entity entity;
+ 
++	/* maximum budget allowed from the feedback mechanism */
+ 	int max_budget;
++	/* budget expiration (in jiffies) */
+ 	unsigned long budget_timeout;
+ 
++	/* number of requests on the dispatch list or inside driver */
+ 	int dispatched;
+ 
+-	unsigned int flags;
++	unsigned int flags; /* status flags.*/
+ 
++	/* node for active/idle bfqq list inside parent bfqd */
+ 	struct list_head bfqq_list;
+ 
++	/* bit vector: a 1 for each seeky requests in history */
++	u32 seek_history;
++
++	/* node for the device's burst list */
+ 	struct hlist_node burst_list_node;
+ 
+-	unsigned int seek_samples;
+-	u64 seek_total;
+-	sector_t seek_mean;
++	/* position of the last request enqueued */
+ 	sector_t last_request_pos;
+ 
++	/* Number of consecutive pairs of request completion and
++	 * arrival, such that the queue becomes idle after the
++	 * completion, but the next request arrives within an idle
++	 * time slice; used only if the queue's IO_bound flag has been
++	 * cleared.
++	 */
+ 	unsigned int requests_within_timer;
+ 
++	/* pid of the process owning the queue, used for logging purposes */
+ 	pid_t pid;
++
++	/*
++	 * Pointer to the bfq_io_cq owning the bfq_queue, set to %NULL
++	 * if the queue is shared.
++	 */
+ 	struct bfq_io_cq *bic;
+ 
+-	/* weight-raising fields */
++	/* current maximum weight-raising time for this queue */
+ 	unsigned long wr_cur_max_time;
++	/*
++	 * Minimum time instant such that, only if a new request is
++	 * enqueued after this time instant in an idle @bfq_queue with
++	 * no outstanding requests, then the task associated with the
++	 * queue it is deemed as soft real-time (see the comments on
++	 * the function bfq_bfqq_softrt_next_start())
++	 */
+ 	unsigned long soft_rt_next_start;
++	/*
++	 * Start time of the current weight-raising period if
++	 * the @bfq-queue is being weight-raised, otherwise
++	 * finish time of the last weight-raising period.
++	 */
+ 	unsigned long last_wr_start_finish;
++	/* factor by which the weight of this queue is multiplied */
+ 	unsigned int wr_coeff;
++	/*
++	 * Time of the last transition of the @bfq_queue from idle to
++	 * backlogged.
++	 */
+ 	unsigned long last_idle_bklogged;
++	/*
++	 * Cumulative service received from the @bfq_queue since the
++	 * last transition from idle to backlogged.
++	 */
+ 	unsigned long service_from_backlogged;
++	/*
++	 * Value of wr start time when switching to soft rt
++	 */
++	unsigned long wr_start_at_switch_to_srt;
++
++	unsigned long split_time; /* time of last split */
+ };
+ 
+ /**
+  * struct bfq_ttime - per process thinktime stats.
+- * @ttime_total: total process thinktime
+- * @ttime_samples: number of thinktime samples
+- * @ttime_mean: average process thinktime
+  */
+ struct bfq_ttime {
+-	unsigned long last_end_request;
++	u64 last_end_request; /* completion time of last request */
++
++	u64 ttime_total; /* total process thinktime */
++	unsigned long ttime_samples; /* number of thinktime samples */
++	u64 ttime_mean; /* average process thinktime */
+ 
+-	unsigned long ttime_total;
+-	unsigned long ttime_samples;
+-	unsigned long ttime_mean;
+ };
+ 
+ /**
+  * struct bfq_io_cq - per (request_queue, io_context) structure.
+- * @icq: associated io_cq structure
+- * @bfqq: array of two process queues, the sync and the async
+- * @ttime: associated @bfq_ttime struct
+- * @ioprio: per (request_queue, blkcg) ioprio.
+- * @blkcg_id: id of the blkcg the related io_cq belongs to.
+- * @wr_time_left: snapshot of the time left before weight raising ends
+- *                for the sync queue associated to this process; this
+- *		  snapshot is taken to remember this value while the weight
+- *		  raising is suspended because the queue is merged with a
+- *		  shared queue, and is used to set @raising_cur_max_time
+- *		  when the queue is split from the shared queue and its
+- *		  weight is raised again
+- * @saved_idle_window: same purpose as the previous field for the idle
+- *                     window
+- * @saved_IO_bound: same purpose as the previous two fields for the I/O
+- *                  bound classification of a queue
+- * @saved_in_large_burst: same purpose as the previous fields for the
+- *                        value of the field keeping the queue's belonging
+- *                        to a large burst
+- * @was_in_burst_list: true if the queue belonged to a burst list
+- *                     before its merge with another cooperating queue
+- * @cooperations: counter of consecutive successful queue merges underwent
+- *                by any of the process' @bfq_queues
+- * @failed_cooperations: counter of consecutive failed queue merges of any
+- *                       of the process' @bfq_queues
+  */
+ struct bfq_io_cq {
++	/* associated io_cq structure */
+ 	struct io_cq icq; /* must be the first member */
++	/* array of two process queues, the sync and the async */
+ 	struct bfq_queue *bfqq[2];
++	/* associated @bfq_ttime struct */
+ 	struct bfq_ttime ttime;
++	/* per (request_queue, blkcg) ioprio */
+ 	int ioprio;
+-
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	uint64_t blkcg_id; /* the current blkcg ID */
++	uint64_t blkcg_serial_nr; /* the current blkcg serial */
+ #endif
+ 
+-	unsigned int wr_time_left;
++	/*
++	 * Snapshot of the idle window before merging; taken to
++	 * remember this value while the queue is merged, so as to be
++	 * able to restore it in case of split.
++	 */
+ 	bool saved_idle_window;
++	/*
++	 * Same purpose as the previous two fields for the I/O bound
++	 * classification of a queue.
++	 */
+ 	bool saved_IO_bound;
+ 
++	/*
++	 * Same purpose as the previous fields for the value of the
++	 * field keeping the queue's belonging to a large burst
++	 */
+ 	bool saved_in_large_burst;
++	/*
++	 * True if the queue belonged to a burst list before its merge
++	 * with another cooperating queue.
++	 */
+ 	bool was_in_burst_list;
+ 
+-	unsigned int cooperations;
+-	unsigned int failed_cooperations;
++	/*
++	 * Similar to previous fields: save wr information.
++	 */
++	unsigned long saved_wr_coeff;
++	unsigned long saved_last_wr_start_finish;
++	unsigned long saved_wr_start_at_switch_to_srt;
+ };
+ 
+ enum bfq_device_speed {
+@@ -354,224 +371,234 @@ enum bfq_device_speed {
+ };
+ 
+ /**
+- * struct bfq_data - per device data structure.
+- * @queue: request queue for the managed device.
+- * @root_group: root bfq_group for the device.
+- * @active_numerous_groups: number of bfq_groups containing more than one
+- *                          active @bfq_entity.
+- * @queue_weights_tree: rbtree of weight counters of @bfq_queues, sorted by
+- *                      weight. Used to keep track of whether all @bfq_queues
+- *                     have the same weight. The tree contains one counter
+- *                     for each distinct weight associated to some active
+- *                     and not weight-raised @bfq_queue (see the comments to
+- *                      the functions bfq_weights_tree_[add|remove] for
+- *                     further details).
+- * @group_weights_tree: rbtree of non-queue @bfq_entity weight counters, sorted
+- *                      by weight. Used to keep track of whether all
+- *                     @bfq_groups have the same weight. The tree contains
+- *                     one counter for each distinct weight associated to
+- *                     some active @bfq_group (see the comments to the
+- *                     functions bfq_weights_tree_[add|remove] for further
+- *                     details).
+- * @busy_queues: number of bfq_queues containing requests (including the
+- *		 queue in service, even if it is idling).
+- * @busy_in_flight_queues: number of @bfq_queues containing pending or
+- *                         in-flight requests, plus the @bfq_queue in
+- *                         service, even if idle but waiting for the
+- *                         possible arrival of its next sync request. This
+- *                         field is updated only if the device is rotational,
+- *                         but used only if the device is also NCQ-capable.
+- *                         The reason why the field is updated also for non-
+- *                         NCQ-capable rotational devices is related to the
+- *                         fact that the value of @hw_tag may be set also
+- *                         later than when busy_in_flight_queues may need to
+- *                         be incremented for the first time(s). Taking also
+- *                         this possibility into account, to avoid unbalanced
+- *                         increments/decrements, would imply more overhead
+- *                         than just updating busy_in_flight_queues
+- *                         regardless of the value of @hw_tag.
+- * @const_seeky_busy_in_flight_queues: number of constantly-seeky @bfq_queues
+- *                                     (that is, seeky queues that expired
+- *                                     for budget timeout at least once)
+- *                                     containing pending or in-flight
+- *                                     requests, including the in-service
+- *                                     @bfq_queue if constantly seeky. This
+- *                                     field is updated only if the device
+- *                                     is rotational, but used only if the
+- *                                     device is also NCQ-capable (see the
+- *                                     comments to @busy_in_flight_queues).
+- * @wr_busy_queues: number of weight-raised busy @bfq_queues.
+- * @queued: number of queued requests.
+- * @rq_in_driver: number of requests dispatched and waiting for completion.
+- * @sync_flight: number of sync requests in the driver.
+- * @max_rq_in_driver: max number of reqs in driver in the last
+- *                    @hw_tag_samples completed requests.
+- * @hw_tag_samples: nr of samples used to calculate hw_tag.
+- * @hw_tag: flag set to one if the driver is showing a queueing behavior.
+- * @budgets_assigned: number of budgets assigned.
+- * @idle_slice_timer: timer set when idling for the next sequential request
+- *                    from the queue in service.
+- * @unplug_work: delayed work to restart dispatching on the request queue.
+- * @in_service_queue: bfq_queue in service.
+- * @in_service_bic: bfq_io_cq (bic) associated with the @in_service_queue.
+- * @last_position: on-disk position of the last served request.
+- * @last_budget_start: beginning of the last budget.
+- * @last_idling_start: beginning of the last idle slice.
+- * @peak_rate: peak transfer rate observed for a budget.
+- * @peak_rate_samples: number of samples used to calculate @peak_rate.
+- * @bfq_max_budget: maximum budget allotted to a bfq_queue before
+- *                  rescheduling.
+- * @active_list: list of all the bfq_queues active on the device.
+- * @idle_list: list of all the bfq_queues idle on the device.
+- * @bfq_fifo_expire: timeout for async/sync requests; when it expires
+- *                   requests are served in fifo order.
+- * @bfq_back_penalty: weight of backward seeks wrt forward ones.
+- * @bfq_back_max: maximum allowed backward seek.
+- * @bfq_slice_idle: maximum idling time.
+- * @bfq_user_max_budget: user-configured max budget value
+- *                       (0 for auto-tuning).
+- * @bfq_max_budget_async_rq: maximum budget (in nr of requests) allotted to
+- *                           async queues.
+- * @bfq_timeout: timeout for bfq_queues to consume their budget; used to
+- *               to prevent seeky queues to impose long latencies to well
+- *               behaved ones (this also implies that seeky queues cannot
+- *               receive guarantees in the service domain; after a timeout
+- *               they are charged for the whole allocated budget, to try
+- *               to preserve a behavior reasonably fair among them, but
+- *               without service-domain guarantees).
+- * @bfq_coop_thresh: number of queue merges after which a @bfq_queue is
+- *                   no more granted any weight-raising.
+- * @bfq_failed_cooperations: number of consecutive failed cooperation
+- *                           chances after which weight-raising is restored
+- *                           to a queue subject to more than bfq_coop_thresh
+- *                           queue merges.
+- * @bfq_requests_within_timer: number of consecutive requests that must be
+- *                             issued within the idle time slice to set
+- *                             again idling to a queue which was marked as
+- *                             non-I/O-bound (see the definition of the
+- *                             IO_bound flag for further details).
+- * @last_ins_in_burst: last time at which a queue entered the current
+- *                     burst of queues being activated shortly after
+- *                     each other; for more details about this and the
+- *                     following parameters related to a burst of
+- *                     activations, see the comments to the function
+- *                     @bfq_handle_burst.
+- * @bfq_burst_interval: reference time interval used to decide whether a
+- *                      queue has been activated shortly after
+- *                      @last_ins_in_burst.
+- * @burst_size: number of queues in the current burst of queue activations.
+- * @bfq_large_burst_thresh: maximum burst size above which the current
+- *			    queue-activation burst is deemed as 'large'.
+- * @large_burst: true if a large queue-activation burst is in progress.
+- * @burst_list: head of the burst list (as for the above fields, more details
+- *		in the comments to the function bfq_handle_burst).
+- * @low_latency: if set to true, low-latency heuristics are enabled.
+- * @bfq_wr_coeff: maximum factor by which the weight of a weight-raised
+- *                queue is multiplied.
+- * @bfq_wr_max_time: maximum duration of a weight-raising period (jiffies).
+- * @bfq_wr_rt_max_time: maximum duration for soft real-time processes.
+- * @bfq_wr_min_idle_time: minimum idle period after which weight-raising
+- *			  may be reactivated for a queue (in jiffies).
+- * @bfq_wr_min_inter_arr_async: minimum period between request arrivals
+- *				after which weight-raising may be
+- *				reactivated for an already busy queue
+- *				(in jiffies).
+- * @bfq_wr_max_softrt_rate: max service-rate for a soft real-time queue,
+- *			    sectors per seconds.
+- * @RT_prod: cached value of the product R*T used for computing the maximum
+- *	     duration of the weight raising automatically.
+- * @device_speed: device-speed class for the low-latency heuristic.
+- * @oom_bfqq: fallback dummy bfqq for extreme OOM conditions.
++ * struct bfq_data - per-device data structure.
+  *
+  * All the fields are protected by the @queue lock.
+  */
+ struct bfq_data {
++	/* request queue for the device */
+ 	struct request_queue *queue;
+ 
++	/* root bfq_group for the device */
+ 	struct bfq_group *root_group;
+ 
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+-	int active_numerous_groups;
+-#endif
+-
++	/*
++	 * rbtree of weight counters of @bfq_queues, sorted by
++	 * weight. Used to keep track of whether all @bfq_queues have
++	 * the same weight. The tree contains one counter for each
++	 * distinct weight associated to some active and not
++	 * weight-raised @bfq_queue (see the comments to the functions
++	 * bfq_weights_tree_[add|remove] for further details).
++	 */
+ 	struct rb_root queue_weights_tree;
++	/*
++	 * rbtree of non-queue @bfq_entity weight counters, sorted by
++	 * weight. Used to keep track of whether all @bfq_groups have
++	 * the same weight. The tree contains one counter for each
++	 * distinct weight associated to some active @bfq_group (see
++	 * the comments to the functions bfq_weights_tree_[add|remove]
++	 * for further details).
++	 */
+ 	struct rb_root group_weights_tree;
+ 
++	/*
++	 * Number of bfq_queues containing requests (including the
++	 * queue in service, even if it is idling).
++	 */
+ 	int busy_queues;
+-	int busy_in_flight_queues;
+-	int const_seeky_busy_in_flight_queues;
++	/* number of weight-raised busy @bfq_queues */
+ 	int wr_busy_queues;
++	/* number of queued requests */
+ 	int queued;
++	/* number of requests dispatched and waiting for completion */
+ 	int rq_in_driver;
+-	int sync_flight;
+ 
++	/*
++	 * Maximum number of requests in driver in the last
++	 * @hw_tag_samples completed requests.
++	 */
+ 	int max_rq_in_driver;
++	/* number of samples used to calculate hw_tag */
+ 	int hw_tag_samples;
++	/* flag set to one if the driver is showing a queueing behavior */
+ 	int hw_tag;
+ 
++	/* number of budgets assigned */
+ 	int budgets_assigned;
+ 
+-	struct timer_list idle_slice_timer;
++	/*
++	 * Timer set when idling (waiting) for the next request from
++	 * the queue in service.
++	 */
++	struct hrtimer idle_slice_timer;
++	/* delayed work to restart dispatching on the request queue */
+ 	struct work_struct unplug_work;
+ 
++	/* bfq_queue in service */
+ 	struct bfq_queue *in_service_queue;
++	/* bfq_io_cq (bic) associated with the @in_service_queue */
+ 	struct bfq_io_cq *in_service_bic;
+ 
++	/* on-disk position of the last served request */
+ 	sector_t last_position;
+ 
++	/* time of last request completion (ns) */
++	u64 last_completion;
++
++	/* time of first rq dispatch in current observation interval (ns) */
++	u64 first_dispatch;
++	/* time of last rq dispatch in current observation interval (ns) */
++	u64 last_dispatch;
++
++	/* beginning of the last budget */
+ 	ktime_t last_budget_start;
++	/* beginning of the last idle slice */
+ 	ktime_t last_idling_start;
++
++	/* number of samples in current observation interval */
+ 	int peak_rate_samples;
+-	u64 peak_rate;
++	/* num of samples of seq dispatches in current observation interval */
++	u32 sequential_samples;
++	/* total num of sectors transferred in current observation interval */
++	u64 tot_sectors_dispatched;
++	/* max rq size seen during current observation interval (sectors) */
++	u32 last_rq_max_size;
++	/* time elapsed from first dispatch in current observ. interval (us) */
++	u64 delta_from_first;
++	/* current estimate of device peak rate */
++	u32 peak_rate;
++
++	/* maximum budget allotted to a bfq_queue before rescheduling */
+ 	int bfq_max_budget;
+ 
++	/* list of all the bfq_queues active on the device */
+ 	struct list_head active_list;
++	/* list of all the bfq_queues idle on the device */
+ 	struct list_head idle_list;
+ 
+-	unsigned int bfq_fifo_expire[2];
++	/*
++	 * Timeout for async/sync requests; when it fires, requests
++	 * are served in fifo order.
++	 */
++	u64 bfq_fifo_expire[2];
++	/* weight of backward seeks wrt forward ones */
+ 	unsigned int bfq_back_penalty;
++	/* maximum allowed backward seek */
+ 	unsigned int bfq_back_max;
+-	unsigned int bfq_slice_idle;
++	/* maximum idling time */
++	u32 bfq_slice_idle;
++	/* last time CLASS_IDLE was served */
+ 	u64 bfq_class_idle_last_service;
+ 
++	/* user-configured max budget value (0 for auto-tuning) */
+ 	int bfq_user_max_budget;
+-	int bfq_max_budget_async_rq;
+-	unsigned int bfq_timeout[2];
+-
+-	unsigned int bfq_coop_thresh;
+-	unsigned int bfq_failed_cooperations;
++	/*
++	 * Timeout for bfq_queues to consume their budget; used to
++	 * prevent seeky queues from imposing long latencies to
++	 * sequential or quasi-sequential ones (this also implies that
++	 * seeky queues cannot receive guarantees in the service
++	 * domain; after a timeout they are charged for the time they
++	 * have been in service, to preserve fairness among them, but
++	 * without service-domain guarantees).
++	 */
++	unsigned int bfq_timeout;
++
++	/*
++	 * Number of consecutive requests that must be issued within
++	 * the idle time slice to set again idling to a queue which
++	 * was marked as non-I/O-bound (see the definition of the
++	 * IO_bound flag for further details).
++	 */
+ 	unsigned int bfq_requests_within_timer;
+ 
++	/*
++	 * Force device idling whenever needed to provide accurate
++	 * service guarantees, without caring about throughput
++	 * issues. CAVEAT: this may even increase latencies, in case
++	 * of useless idling for processes that did stop doing I/O.
++	 */
++	bool strict_guarantees;
++
++	/*
++	 * Last time at which a queue entered the current burst of
++	 * queues being activated shortly after each other; for more
++	 * details about this and the following parameters related to
++	 * a burst of activations, see the comments on the function
++	 * bfq_handle_burst.
++	 */
+ 	unsigned long last_ins_in_burst;
++	/*
++	 * Reference time interval used to decide whether a queue has
++	 * been activated shortly after @last_ins_in_burst.
++	 */
+ 	unsigned long bfq_burst_interval;
++	/* number of queues in the current burst of queue activations */
+ 	int burst_size;
++
++	/* common parent entity for the queues in the burst */
++	struct bfq_entity *burst_parent_entity;
++	/* Maximum burst size above which the current queue-activation
++	 * burst is deemed as 'large'.
++	 */
+ 	unsigned long bfq_large_burst_thresh;
++	/* true if a large queue-activation burst is in progress */
+ 	bool large_burst;
++	/*
++	 * Head of the burst list (as for the above fields, more
++	 * details in the comments on the function bfq_handle_burst).
++	 */
+ 	struct hlist_head burst_list;
+ 
++	/* if set to true, low-latency heuristics are enabled */
+ 	bool low_latency;
+-
+-	/* parameters of the low_latency heuristics */
++	/*
++	 * Maximum factor by which the weight of a weight-raised queue
++	 * is multiplied.
++	 */
+ 	unsigned int bfq_wr_coeff;
++	/* maximum duration of a weight-raising period (jiffies) */
+ 	unsigned int bfq_wr_max_time;
++
++	/* Maximum weight-raising duration for soft real-time processes */
+ 	unsigned int bfq_wr_rt_max_time;
++	/*
++	 * Minimum idle period after which weight-raising may be
++	 * reactivated for a queue (in jiffies).
++	 */
+ 	unsigned int bfq_wr_min_idle_time;
++	/*
++	 * Minimum period between request arrivals after which
++	 * weight-raising may be reactivated for an already busy async
++	 * queue (in jiffies).
++	 */
+ 	unsigned long bfq_wr_min_inter_arr_async;
++
++	/* Max service-rate for a soft real-time queue, in sectors/sec */
+ 	unsigned int bfq_wr_max_softrt_rate;
++	/*
++	 * Cached value of the product R*T, used for computing the
++	 * maximum duration of weight raising automatically.
++	 */
+ 	u64 RT_prod;
++	/* device-speed class for the low-latency heuristic */
+ 	enum bfq_device_speed device_speed;
+ 
++	/* fallback dummy bfqq for extreme OOM conditions */
+ 	struct bfq_queue oom_bfqq;
+ };
+ 
+ enum bfqq_state_flags {
+-	BFQ_BFQQ_FLAG_busy = 0,		/* has requests or is in service */
++	BFQ_BFQQ_FLAG_just_created = 0,	/* queue just allocated */
++	BFQ_BFQQ_FLAG_busy,		/* has requests or is in service */
+ 	BFQ_BFQQ_FLAG_wait_request,	/* waiting for a request */
++	BFQ_BFQQ_FLAG_non_blocking_wait_rq, /*
++					     * waiting for a request
++					     * without idling the device
++					     */
+ 	BFQ_BFQQ_FLAG_must_alloc,	/* must be allowed rq alloc */
+ 	BFQ_BFQQ_FLAG_fifo_expire,	/* FIFO checked in this slice */
+ 	BFQ_BFQQ_FLAG_idle_window,	/* slice idling enabled */
+ 	BFQ_BFQQ_FLAG_sync,		/* synchronous queue */
+-	BFQ_BFQQ_FLAG_budget_new,	/* no completion with this budget */
+ 	BFQ_BFQQ_FLAG_IO_bound,		/*
+ 					 * bfqq has timed-out at least once
+ 					 * having consumed at most 2/10 of
+@@ -581,17 +608,12 @@ enum bfqq_state_flags {
+ 					 * bfqq activated in a large burst,
+ 					 * see comments to bfq_handle_burst.
+ 					 */
+-	BFQ_BFQQ_FLAG_constantly_seeky,	/*
+-					 * bfqq has proved to be slow and
+-					 * seeky until budget timeout
+-					 */
+ 	BFQ_BFQQ_FLAG_softrt_update,	/*
+ 					 * may need softrt-next-start
+ 					 * update
+ 					 */
+ 	BFQ_BFQQ_FLAG_coop,		/* bfqq is shared */
+-	BFQ_BFQQ_FLAG_split_coop,	/* shared bfqq will be split */
+-	BFQ_BFQQ_FLAG_just_split,	/* queue has just been split */
++	BFQ_BFQQ_FLAG_split_coop	/* shared bfqq will be split */
+ };
+ 
+ #define BFQ_BFQQ_FNS(name)						\
+@@ -608,25 +630,53 @@ static int bfq_bfqq_##name(const struct bfq_queue *bfqq)		\
+ 	return ((bfqq)->flags & (1 << BFQ_BFQQ_FLAG_##name)) != 0;	\
+ }
+ 
++BFQ_BFQQ_FNS(just_created);
+ BFQ_BFQQ_FNS(busy);
+ BFQ_BFQQ_FNS(wait_request);
++BFQ_BFQQ_FNS(non_blocking_wait_rq);
+ BFQ_BFQQ_FNS(must_alloc);
+ BFQ_BFQQ_FNS(fifo_expire);
+ BFQ_BFQQ_FNS(idle_window);
+ BFQ_BFQQ_FNS(sync);
+-BFQ_BFQQ_FNS(budget_new);
+ BFQ_BFQQ_FNS(IO_bound);
+ BFQ_BFQQ_FNS(in_large_burst);
+-BFQ_BFQQ_FNS(constantly_seeky);
+ BFQ_BFQQ_FNS(coop);
+ BFQ_BFQQ_FNS(split_coop);
+-BFQ_BFQQ_FNS(just_split);
+ BFQ_BFQQ_FNS(softrt_update);
+ #undef BFQ_BFQQ_FNS
+ 
+ /* Logging facilities. */
+-#define bfq_log_bfqq(bfqd, bfqq, fmt, args...) \
+-	blk_add_trace_msg((bfqd)->queue, "bfq%d " fmt, (bfqq)->pid, ##args)
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++static struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
++static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg);
++
++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...)	do {			\
++	char __pbuf[128];						\
++									\
++	assert_spin_locked((bfqd)->queue->queue_lock);			\
++	blkg_path(bfqg_to_blkg(bfqq_group(bfqq)), __pbuf, sizeof(__pbuf)); \
++	blk_add_trace_msg((bfqd)->queue, "bfq%d%c %s " fmt, \
++			  (bfqq)->pid,			  \
++			  bfq_bfqq_sync((bfqq)) ? 'S' : 'A',	\
++			  __pbuf, ##args);				\
++} while (0)
++
++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...)	do {			\
++	char __pbuf[128];						\
++									\
++	blkg_path(bfqg_to_blkg(bfqg), __pbuf, sizeof(__pbuf));		\
++	blk_add_trace_msg((bfqd)->queue, "%s " fmt, __pbuf, ##args);	\
++} while (0)
++
++#else /* CONFIG_BFQ_GROUP_IOSCHED */
++
++#define bfq_log_bfqq(bfqd, bfqq, fmt, args...)	\
++	blk_add_trace_msg((bfqd)->queue, "bfq%d%c " fmt, (bfqq)->pid,	\
++			bfq_bfqq_sync((bfqq)) ? 'S' : 'A',		\
++				##args)
++#define bfq_log_bfqg(bfqd, bfqg, fmt, args...)		do {} while (0)
++
++#endif /* CONFIG_BFQ_GROUP_IOSCHED */
+ 
+ #define bfq_log(bfqd, fmt, args...) \
+ 	blk_add_trace_msg((bfqd)->queue, "bfq " fmt, ##args)
+@@ -640,15 +690,12 @@ enum bfqq_expiration {
+ 	BFQ_BFQQ_BUDGET_TIMEOUT,	/* budget took too long to be used */
+ 	BFQ_BFQQ_BUDGET_EXHAUSTED,	/* budget consumed */
+ 	BFQ_BFQQ_NO_MORE_REQUESTS,	/* the queue has no more requests */
++	BFQ_BFQQ_PREEMPTED		/* preemption in progress */
+ };
+ 
+-#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 
+ struct bfqg_stats {
+-	/* total bytes transferred */
+-	struct blkg_rwstat		service_bytes;
+-	/* total IOs serviced, post merge */
+-	struct blkg_rwstat		serviced;
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 	/* number of ios merged */
+ 	struct blkg_rwstat		merged;
+ 	/* total time spent on device in ns, may not be accurate w/ queueing */
+@@ -657,12 +704,8 @@ struct bfqg_stats {
+ 	struct blkg_rwstat		wait_time;
+ 	/* number of IOs queued up */
+ 	struct blkg_rwstat		queued;
+-	/* total sectors transferred */
+-	struct blkg_stat		sectors;
+ 	/* total disk time and nr sectors dispatched by this group */
+ 	struct blkg_stat		time;
+-	/* time not charged to this cgroup */
+-	struct blkg_stat		unaccounted_time;
+ 	/* sum of number of ios queued across all samples */
+ 	struct blkg_stat		avg_queue_size_sum;
+ 	/* count of samples taken for average */
+@@ -680,8 +723,10 @@ struct bfqg_stats {
+ 	uint64_t			start_idle_time;
+ 	uint64_t			start_empty_time;
+ 	uint16_t			flags;
++#endif
+ };
+ 
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ /*
+  * struct bfq_group_data - per-blkcg storage for the blkio subsystem.
+  *
+@@ -692,7 +737,7 @@ struct bfq_group_data {
+ 	/* must be the first member */
+ 	struct blkcg_policy_data pd;
+ 
+-	unsigned short weight;
++	unsigned int weight;
+ };
+ 
+ /**
+@@ -712,7 +757,7 @@ struct bfq_group_data {
+  *                   unused for the root group. Used to know whether there
+  *                   are groups with more than one active @bfq_entity
+  *                   (see the comments to the function
+- *                   bfq_bfqq_must_not_expire()).
++ *                   bfq_bfqq_may_idle()).
+  * @rq_pos_tree: rbtree sorted by next_request position, used when
+  *               determining if two or more queues have interleaving
+  *               requests (see bfq_find_close_cooperator()).
+@@ -745,7 +790,6 @@ struct bfq_group {
+ 	struct rb_root rq_pos_tree;
+ 
+ 	struct bfqg_stats stats;
+-	struct bfqg_stats dead_stats;	/* stats pushed from dead children */
+ };
+ 
+ #else
+@@ -767,11 +811,25 @@ bfq_entity_service_tree(struct bfq_entity *entity)
+ 	struct bfq_sched_data *sched_data = entity->sched_data;
+ 	struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
+ 	unsigned int idx = bfqq ? bfqq->ioprio_class - 1 :
+-				  BFQ_DEFAULT_GRP_CLASS;
++				  BFQ_DEFAULT_GRP_CLASS - 1;
+ 
+ 	BUG_ON(idx >= BFQ_IOPRIO_CLASSES);
+ 	BUG_ON(sched_data == NULL);
+ 
++	if (bfqq)
++		bfq_log_bfqq(bfqq->bfqd, bfqq,
++			     "entity_service_tree %p %d",
++			     sched_data->service_tree + idx, idx);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
++	else {
++		struct bfq_group *bfqg =
++			container_of(entity, struct bfq_group, entity);
++
++		bfq_log_bfqg((struct bfq_data *)bfqg->bfqd, bfqg,
++			     "entity_service_tree %p %d",
++			     sched_data->service_tree + idx, idx);
++	}
++#endif
+ 	return sched_data->service_tree + idx;
+ }
+ 
+@@ -791,47 +849,6 @@ static struct bfq_data *bic_to_bfqd(struct bfq_io_cq *bic)
+ 	return bic->icq.q->elevator->elevator_data;
+ }
+ 
+-/**
+- * bfq_get_bfqd_locked - get a lock to a bfqd using a RCU protected pointer.
+- * @ptr: a pointer to a bfqd.
+- * @flags: storage for the flags to be saved.
+- *
+- * This function allows bfqg->bfqd to be protected by the
+- * queue lock of the bfqd they reference; the pointer is dereferenced
+- * under RCU, so the storage for bfqd is assured to be safe as long
+- * as the RCU read side critical section does not end.  After the
+- * bfqd->queue->queue_lock is taken the pointer is rechecked, to be
+- * sure that no other writer accessed it.  If we raced with a writer,
+- * the function returns NULL, with the queue unlocked, otherwise it
+- * returns the dereferenced pointer, with the queue locked.
+- */
+-static struct bfq_data *bfq_get_bfqd_locked(void **ptr, unsigned long *flags)
+-{
+-	struct bfq_data *bfqd;
+-
+-	rcu_read_lock();
+-	bfqd = rcu_dereference(*(struct bfq_data **)ptr);
+-
+-	if (bfqd != NULL) {
+-		spin_lock_irqsave(bfqd->queue->queue_lock, *flags);
+-		if (ptr == NULL)
+-			printk(KERN_CRIT "get_bfqd_locked pointer NULL\n");
+-		else if (*ptr == bfqd)
+-			goto out;
+-		spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
+-	}
+-
+-	bfqd = NULL;
+-out:
+-	rcu_read_unlock();
+-	return bfqd;
+-}
+-
+-static void bfq_put_bfqd_unlock(struct bfq_data *bfqd, unsigned long *flags)
+-{
+-	spin_unlock_irqrestore(bfqd->queue->queue_lock, *flags);
+-}
+-
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+ 
+ static struct bfq_group *bfq_bfqq_to_bfqg(struct bfq_queue *bfqq)
+@@ -857,11 +874,13 @@ static void bfq_check_ioprio_change(struct bfq_io_cq *bic, struct bio *bio);
+ static void bfq_put_queue(struct bfq_queue *bfqq);
+ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq);
+ static struct bfq_queue *bfq_get_queue(struct bfq_data *bfqd,
+-				       struct bio *bio, int is_sync,
+-				       struct bfq_io_cq *bic, gfp_t gfp_mask);
++				       struct bio *bio, bool is_sync,
++				       struct bfq_io_cq *bic);
+ static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
+ 				    struct bfq_group *bfqg);
++#ifdef CONFIG_BFQ_GROUP_IOSCHED
+ static void bfq_put_async_queues(struct bfq_data *bfqd, struct bfq_group *bfqg);
++#endif
+ static void bfq_exit_bfqq(struct bfq_data *bfqd, struct bfq_queue *bfqq);
+ 
+ #endif /* _BFQ_H */
+-- 
+2.7.4 (Apple Git-66)
+


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-28 14:03 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-10-28 14:03 UTC (permalink / raw
  To: gentoo-commits

commit:     311c3d27cdc9e022bf07925e0c8ff10c8d610c26
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 28 14:04:27 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Fri Oct 28 14:04:27 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=311c3d27

Linux patch 4.8.5

 0000_README            |    4 +
 1004_linux-4.8.5.patch | 5397 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 5401 insertions(+)

diff --git a/0000_README b/0000_README
index c65f1ed..a5b48e4 100644
--- a/0000_README
+++ b/0000_README
@@ -59,6 +59,10 @@ Patch:  1003_linux-4.8.4.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.4
 
+Patch:  1003_linux-4.8.4.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.4
+
 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/1004_linux-4.8.5.patch b/1004_linux-4.8.5.patch
new file mode 100644
index 0000000..2074a32
--- /dev/null
+++ b/1004_linux-4.8.5.patch
@@ -0,0 +1,5397 @@
+diff --git a/Documentation/ABI/testing/sysfs-class-cxl b/Documentation/ABI/testing/sysfs-class-cxl
+index 4ba0a2a61926..640f65e79ef1 100644
+--- a/Documentation/ABI/testing/sysfs-class-cxl
++++ b/Documentation/ABI/testing/sysfs-class-cxl
+@@ -220,8 +220,11 @@ What:           /sys/class/cxl/<card>/reset
+ Date:           October 2014
+ Contact:        linuxppc-dev@lists.ozlabs.org
+ Description:    write only
+-                Writing 1 will issue a PERST to card which may cause the card
+-                to reload the FPGA depending on load_image_on_perst.
++                Writing 1 will issue a PERST to card provided there are no
++                contexts active on any one of the card AFUs. This may cause
++                the card to reload the FPGA depending on load_image_on_perst.
++                Writing -1 will do a force PERST irrespective of any active
++                contexts on the card AFUs.
+ Users:		https://github.com/ibm-capi/libcxl
+ 
+ What:		/sys/class/cxl/<card>/perst_reloads_same_image (not in a guest)
+diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
+index a4f4d693e2c1..46726d4899fe 100644
+--- a/Documentation/kernel-parameters.txt
++++ b/Documentation/kernel-parameters.txt
+@@ -1457,7 +1457,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
+ 	i8042.nopnp	[HW] Don't use ACPIPnP / PnPBIOS to discover KBD/AUX
+ 			     controllers
+ 	i8042.notimeout	[HW] Ignore timeout condition signalled by controller
+-	i8042.reset	[HW] Reset the controller during init and cleanup
++	i8042.reset	[HW] Reset the controller during init, cleanup and
++			     suspend-to-ram transitions, only during s2r
++			     transitions, or never reset
++			Format: { 1 | Y | y | 0 | N | n }
++			1, Y, y: always reset controller
++			0, N, n: don't ever reset controller
++			Default: only on s2r transitions on x86; most other
++			architectures force reset to be always executed
+ 	i8042.unlock	[HW] Unlock (ignore) the keylock
+ 	i8042.kbdreset  [HW] Reset device connected to KBD port
+ 
+diff --git a/Makefile b/Makefile
+index 82a36ab540a4..daa3a01d2525 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 4
++SUBLEVEL = 5
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
+index 6cb3736b6b83..d347bbc086fe 100644
+--- a/arch/arc/kernel/signal.c
++++ b/arch/arc/kernel/signal.c
+@@ -107,13 +107,13 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
+ 	struct user_regs_struct uregs;
+ 
+ 	err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
+-	if (!err)
+-		set_current_blocked(&set);
+-
+ 	err |= __copy_from_user(&uregs.scratch,
+ 				&(sf->uc.uc_mcontext.regs.scratch),
+ 				sizeof(sf->uc.uc_mcontext.regs.scratch));
++	if (err)
++		return err;
+ 
++	set_current_blocked(&set);
+ 	regs->bta	= uregs.scratch.bta;
+ 	regs->lp_start	= uregs.scratch.lp_start;
+ 	regs->lp_end	= uregs.scratch.lp_end;
+@@ -138,7 +138,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
+ 	regs->r0	= uregs.scratch.r0;
+ 	regs->sp	= uregs.scratch.sp;
+ 
+-	return err;
++	return 0;
+ }
+ 
+ static inline int is_do_ss_needed(unsigned int magic)
+diff --git a/arch/arm64/include/asm/kvm_emulate.h b/arch/arm64/include/asm/kvm_emulate.h
+index 4cdeae3b17c6..948a9a8a9297 100644
+--- a/arch/arm64/include/asm/kvm_emulate.h
++++ b/arch/arm64/include/asm/kvm_emulate.h
+@@ -167,11 +167,6 @@ static inline bool kvm_vcpu_dabt_isvalid(const struct kvm_vcpu *vcpu)
+ 	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_ISV);
+ }
+ 
+-static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
+-{
+-	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR);
+-}
+-
+ static inline bool kvm_vcpu_dabt_issext(const struct kvm_vcpu *vcpu)
+ {
+ 	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_SSE);
+@@ -192,6 +187,12 @@ static inline bool kvm_vcpu_dabt_iss1tw(const struct kvm_vcpu *vcpu)
+ 	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_S1PTW);
+ }
+ 
++static inline bool kvm_vcpu_dabt_iswrite(const struct kvm_vcpu *vcpu)
++{
++	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_WNR) ||
++		kvm_vcpu_dabt_iss1tw(vcpu); /* AF/DBM update */
++}
++
+ static inline bool kvm_vcpu_dabt_is_cm(const struct kvm_vcpu *vcpu)
+ {
+ 	return !!(kvm_vcpu_get_hsr(vcpu) & ESR_ELx_CM);
+diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h
+index e12af6754634..06ff7fd9e81f 100644
+--- a/arch/arm64/include/asm/module.h
++++ b/arch/arm64/include/asm/module.h
+@@ -17,6 +17,7 @@
+ #define __ASM_MODULE_H
+ 
+ #include <asm-generic/module.h>
++#include <asm/memory.h>
+ 
+ #define MODULE_ARCH_VERMAGIC	"aarch64"
+ 
+@@ -32,6 +33,10 @@ u64 module_emit_plt_entry(struct module *mod, const Elf64_Rela *rela,
+ 			  Elf64_Sym *sym);
+ 
+ #ifdef CONFIG_RANDOMIZE_BASE
++#ifdef CONFIG_MODVERSIONS
++#define ARCH_RELOCATES_KCRCTAB
++#define reloc_start 		(kimage_vaddr - KIMAGE_VADDR)
++#endif
+ extern u64 module_alloc_base;
+ #else
+ #define module_alloc_base	((u64)_etext - MODULES_VSIZE)
+diff --git a/arch/arm64/include/asm/percpu.h b/arch/arm64/include/asm/percpu.h
+index 2fee2f59288c..5394c8405e66 100644
+--- a/arch/arm64/include/asm/percpu.h
++++ b/arch/arm64/include/asm/percpu.h
+@@ -44,48 +44,44 @@ static inline unsigned long __percpu_##op(void *ptr,			\
+ 									\
+ 	switch (size) {							\
+ 	case 1:								\
+-		do {							\
+-			asm ("//__per_cpu_" #op "_1\n"			\
+-			"ldxrb	  %w[ret], %[ptr]\n"			\
++		asm ("//__per_cpu_" #op "_1\n"				\
++		"1:	ldxrb	  %w[ret], %[ptr]\n"			\
+ 			#asm_op " %w[ret], %w[ret], %w[val]\n"		\
+-			"stxrb	  %w[loop], %w[ret], %[ptr]\n"		\
+-			: [loop] "=&r" (loop), [ret] "=&r" (ret),	\
+-			  [ptr] "+Q"(*(u8 *)ptr)			\
+-			: [val] "Ir" (val));				\
+-		} while (loop);						\
++		"	stxrb	  %w[loop], %w[ret], %[ptr]\n"		\
++		"	cbnz	  %w[loop], 1b"				\
++		: [loop] "=&r" (loop), [ret] "=&r" (ret),		\
++		  [ptr] "+Q"(*(u8 *)ptr)				\
++		: [val] "Ir" (val));					\
+ 		break;							\
+ 	case 2:								\
+-		do {							\
+-			asm ("//__per_cpu_" #op "_2\n"			\
+-			"ldxrh	  %w[ret], %[ptr]\n"			\
++		asm ("//__per_cpu_" #op "_2\n"				\
++		"1:	ldxrh	  %w[ret], %[ptr]\n"			\
+ 			#asm_op " %w[ret], %w[ret], %w[val]\n"		\
+-			"stxrh	  %w[loop], %w[ret], %[ptr]\n"		\
+-			: [loop] "=&r" (loop), [ret] "=&r" (ret),	\
+-			  [ptr]  "+Q"(*(u16 *)ptr)			\
+-			: [val] "Ir" (val));				\
+-		} while (loop);						\
++		"	stxrh	  %w[loop], %w[ret], %[ptr]\n"		\
++		"	cbnz	  %w[loop], 1b"				\
++		: [loop] "=&r" (loop), [ret] "=&r" (ret),		\
++		  [ptr]  "+Q"(*(u16 *)ptr)				\
++		: [val] "Ir" (val));					\
+ 		break;							\
+ 	case 4:								\
+-		do {							\
+-			asm ("//__per_cpu_" #op "_4\n"			\
+-			"ldxr	  %w[ret], %[ptr]\n"			\
++		asm ("//__per_cpu_" #op "_4\n"				\
++		"1:	ldxr	  %w[ret], %[ptr]\n"			\
+ 			#asm_op " %w[ret], %w[ret], %w[val]\n"		\
+-			"stxr	  %w[loop], %w[ret], %[ptr]\n"		\
+-			: [loop] "=&r" (loop), [ret] "=&r" (ret),	\
+-			  [ptr] "+Q"(*(u32 *)ptr)			\
+-			: [val] "Ir" (val));				\
+-		} while (loop);						\
++		"	stxr	  %w[loop], %w[ret], %[ptr]\n"		\
++		"	cbnz	  %w[loop], 1b"				\
++		: [loop] "=&r" (loop), [ret] "=&r" (ret),		\
++		  [ptr] "+Q"(*(u32 *)ptr)				\
++		: [val] "Ir" (val));					\
+ 		break;							\
+ 	case 8:								\
+-		do {							\
+-			asm ("//__per_cpu_" #op "_8\n"			\
+-			"ldxr	  %[ret], %[ptr]\n"			\
++		asm ("//__per_cpu_" #op "_8\n"				\
++		"1:	ldxr	  %[ret], %[ptr]\n"			\
+ 			#asm_op " %[ret], %[ret], %[val]\n"		\
+-			"stxr	  %w[loop], %[ret], %[ptr]\n"		\
+-			: [loop] "=&r" (loop), [ret] "=&r" (ret),	\
+-			  [ptr] "+Q"(*(u64 *)ptr)			\
+-			: [val] "Ir" (val));				\
+-		} while (loop);						\
++		"	stxr	  %w[loop], %[ret], %[ptr]\n"		\
++		"	cbnz	  %w[loop], 1b"				\
++		: [loop] "=&r" (loop), [ret] "=&r" (ret),		\
++		  [ptr] "+Q"(*(u64 *)ptr)				\
++		: [val] "Ir" (val));					\
+ 		break;							\
+ 	default:							\
+ 		BUILD_BUG();						\
+@@ -150,44 +146,40 @@ static inline unsigned long __percpu_xchg(void *ptr, unsigned long val,
+ 
+ 	switch (size) {
+ 	case 1:
+-		do {
+-			asm ("//__percpu_xchg_1\n"
+-			"ldxrb %w[ret], %[ptr]\n"
+-			"stxrb %w[loop], %w[val], %[ptr]\n"
+-			: [loop] "=&r"(loop), [ret] "=&r"(ret),
+-			  [ptr] "+Q"(*(u8 *)ptr)
+-			: [val] "r" (val));
+-		} while (loop);
++		asm ("//__percpu_xchg_1\n"
++		"1:	ldxrb	%w[ret], %[ptr]\n"
++		"	stxrb	%w[loop], %w[val], %[ptr]\n"
++		"	cbnz	%w[loop], 1b"
++		: [loop] "=&r"(loop), [ret] "=&r"(ret),
++		  [ptr] "+Q"(*(u8 *)ptr)
++		: [val] "r" (val));
+ 		break;
+ 	case 2:
+-		do {
+-			asm ("//__percpu_xchg_2\n"
+-			"ldxrh %w[ret], %[ptr]\n"
+-			"stxrh %w[loop], %w[val], %[ptr]\n"
+-			: [loop] "=&r"(loop), [ret] "=&r"(ret),
+-			  [ptr] "+Q"(*(u16 *)ptr)
+-			: [val] "r" (val));
+-		} while (loop);
++		asm ("//__percpu_xchg_2\n"
++		"1:	ldxrh	%w[ret], %[ptr]\n"
++		"	stxrh	%w[loop], %w[val], %[ptr]\n"
++		"	cbnz	%w[loop], 1b"
++		: [loop] "=&r"(loop), [ret] "=&r"(ret),
++		  [ptr] "+Q"(*(u16 *)ptr)
++		: [val] "r" (val));
+ 		break;
+ 	case 4:
+-		do {
+-			asm ("//__percpu_xchg_4\n"
+-			"ldxr %w[ret], %[ptr]\n"
+-			"stxr %w[loop], %w[val], %[ptr]\n"
+-			: [loop] "=&r"(loop), [ret] "=&r"(ret),
+-			  [ptr] "+Q"(*(u32 *)ptr)
+-			: [val] "r" (val));
+-		} while (loop);
++		asm ("//__percpu_xchg_4\n"
++		"1:	ldxr	%w[ret], %[ptr]\n"
++		"	stxr	%w[loop], %w[val], %[ptr]\n"
++		"	cbnz	%w[loop], 1b"
++		: [loop] "=&r"(loop), [ret] "=&r"(ret),
++		  [ptr] "+Q"(*(u32 *)ptr)
++		: [val] "r" (val));
+ 		break;
+ 	case 8:
+-		do {
+-			asm ("//__percpu_xchg_8\n"
+-			"ldxr %[ret], %[ptr]\n"
+-			"stxr %w[loop], %[val], %[ptr]\n"
+-			: [loop] "=&r"(loop), [ret] "=&r"(ret),
+-			  [ptr] "+Q"(*(u64 *)ptr)
+-			: [val] "r" (val));
+-		} while (loop);
++		asm ("//__percpu_xchg_8\n"
++		"1:	ldxr	%[ret], %[ptr]\n"
++		"	stxr	%w[loop], %[val], %[ptr]\n"
++		"	cbnz	%w[loop], 1b"
++		: [loop] "=&r"(loop), [ret] "=&r"(ret),
++		  [ptr] "+Q"(*(u64 *)ptr)
++		: [val] "r" (val));
+ 		break;
+ 	default:
+ 		BUILD_BUG();
+diff --git a/arch/arm64/include/asm/uaccess.h b/arch/arm64/include/asm/uaccess.h
+index c47257c91b77..db849839e07b 100644
+--- a/arch/arm64/include/asm/uaccess.h
++++ b/arch/arm64/include/asm/uaccess.h
+@@ -21,6 +21,7 @@
+ /*
+  * User space memory access functions
+  */
++#include <linux/bitops.h>
+ #include <linux/kasan-checks.h>
+ #include <linux/string.h>
+ #include <linux/thread_info.h>
+@@ -102,6 +103,13 @@ static inline void set_fs(mm_segment_t fs)
+ 	flag;								\
+ })
+ 
++/*
++ * When dealing with data aborts or instruction traps we may end up with
++ * a tagged userland pointer. Clear the tag to get a sane pointer to pass
++ * on to access_ok(), for instance.
++ */
++#define untagged_addr(addr)		sign_extend64(addr, 55)
++
+ #define access_ok(type, addr, size)	__range_ok(addr, size)
+ #define user_addr_max			get_fs
+ 
+diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
+index 42ffdb54e162..b0988bb1bf64 100644
+--- a/arch/arm64/kernel/armv8_deprecated.c
++++ b/arch/arm64/kernel/armv8_deprecated.c
+@@ -280,35 +280,43 @@ static void __init register_insn_emulation_sysctl(struct ctl_table *table)
+ /*
+  * Error-checking SWP macros implemented using ldxr{b}/stxr{b}
+  */
+-#define __user_swpX_asm(data, addr, res, temp, B)		\
++
++/* Arbitrary constant to ensure forward-progress of the LL/SC loop */
++#define __SWP_LL_SC_LOOPS	4
++
++#define __user_swpX_asm(data, addr, res, temp, temp2, B)	\
+ 	__asm__ __volatile__(					\
++	"	mov		%w3, %w7\n"			\
+ 	ALTERNATIVE("nop", SET_PSTATE_PAN(0), ARM64_HAS_PAN,	\
+ 		    CONFIG_ARM64_PAN)				\
+-	"0:	ldxr"B"		%w2, [%3]\n"			\
+-	"1:	stxr"B"		%w0, %w1, [%3]\n"		\
++	"0:	ldxr"B"		%w2, [%4]\n"			\
++	"1:	stxr"B"		%w0, %w1, [%4]\n"		\
+ 	"	cbz		%w0, 2f\n"			\
+-	"	mov		%w0, %w4\n"			\
++	"	sub		%w3, %w3, #1\n"			\
++	"	cbnz		%w3, 0b\n"			\
++	"	mov		%w0, %w5\n"			\
+ 	"	b		3f\n"				\
+ 	"2:\n"							\
+ 	"	mov		%w1, %w2\n"			\
+ 	"3:\n"							\
+ 	"	.pushsection	 .fixup,\"ax\"\n"		\
+ 	"	.align		2\n"				\
+-	"4:	mov		%w0, %w5\n"			\
++	"4:	mov		%w0, %w6\n"			\
+ 	"	b		3b\n"				\
+ 	"	.popsection"					\
+ 	_ASM_EXTABLE(0b, 4b)					\
+ 	_ASM_EXTABLE(1b, 4b)					\
+ 	ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,	\
+ 		CONFIG_ARM64_PAN)				\
+-	: "=&r" (res), "+r" (data), "=&r" (temp)		\
+-	: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT)		\
++	: "=&r" (res), "+r" (data), "=&r" (temp), "=&r" (temp2)	\
++	: "r" (addr), "i" (-EAGAIN), "i" (-EFAULT),		\
++	  "i" (__SWP_LL_SC_LOOPS)				\
+ 	: "memory")
+ 
+-#define __user_swp_asm(data, addr, res, temp) \
+-	__user_swpX_asm(data, addr, res, temp, "")
+-#define __user_swpb_asm(data, addr, res, temp) \
+-	__user_swpX_asm(data, addr, res, temp, "b")
++#define __user_swp_asm(data, addr, res, temp, temp2) \
++	__user_swpX_asm(data, addr, res, temp, temp2, "")
++#define __user_swpb_asm(data, addr, res, temp, temp2) \
++	__user_swpX_asm(data, addr, res, temp, temp2, "b")
+ 
+ /*
+  * Bit 22 of the instruction encoding distinguishes between
+@@ -328,12 +336,12 @@ static int emulate_swpX(unsigned int address, unsigned int *data,
+ 	}
+ 
+ 	while (1) {
+-		unsigned long temp;
++		unsigned long temp, temp2;
+ 
+ 		if (type == TYPE_SWPB)
+-			__user_swpb_asm(*data, address, res, temp);
++			__user_swpb_asm(*data, address, res, temp, temp2);
+ 		else
+-			__user_swp_asm(*data, address, res, temp);
++			__user_swp_asm(*data, address, res, temp, temp2);
+ 
+ 		if (likely(res != -EAGAIN) || signal_pending(current))
+ 			break;
+diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
+index 3e7b050e99dc..4d19508c55a3 100644
+--- a/arch/arm64/kernel/head.S
++++ b/arch/arm64/kernel/head.S
+@@ -578,8 +578,9 @@ CPU_LE(	movk	x0, #0x30d0, lsl #16	)	// Clear EE and E0E on LE systems
+ 	b.lt	4f				// Skip if no PMU present
+ 	mrs	x0, pmcr_el0			// Disable debug access traps
+ 	ubfx	x0, x0, #11, #5			// to EL2 and allow access to
+-	msr	mdcr_el2, x0			// all PMU counters from EL1
+ 4:
++	csel	x0, xzr, x0, lt			// all PMU counters from EL1
++	msr	mdcr_el2, x0			// (if they exist)
+ 
+ 	/* Stage-2 translation */
+ 	msr	vttbr_el2, xzr
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index df06750846de..771a01a7fbce 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -434,18 +434,21 @@ void cpu_enable_cache_maint_trap(void *__unused)
+ }
+ 
+ #define __user_cache_maint(insn, address, res)			\
+-	asm volatile (						\
+-		"1:	" insn ", %1\n"				\
+-		"	mov	%w0, #0\n"			\
+-		"2:\n"						\
+-		"	.pushsection .fixup,\"ax\"\n"		\
+-		"	.align	2\n"				\
+-		"3:	mov	%w0, %w2\n"			\
+-		"	b	2b\n"				\
+-		"	.popsection\n"				\
+-		_ASM_EXTABLE(1b, 3b)				\
+-		: "=r" (res)					\
+-		: "r" (address), "i" (-EFAULT) )
++	if (untagged_addr(address) >= user_addr_max())		\
++		res = -EFAULT;					\
++	else							\
++		asm volatile (					\
++			"1:	" insn ", %1\n"			\
++			"	mov	%w0, #0\n"		\
++			"2:\n"					\
++			"	.pushsection .fixup,\"ax\"\n"	\
++			"	.align	2\n"			\
++			"3:	mov	%w0, %w2\n"		\
++			"	b	2b\n"			\
++			"	.popsection\n"			\
++			_ASM_EXTABLE(1b, 3b)			\
++			: "=r" (res)				\
++			: "r" (address), "i" (-EFAULT) )
+ 
+ asmlinkage void __exception do_sysinstr(unsigned int esr, struct pt_regs *regs)
+ {
+diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S
+index ce9e5e5f28cf..eaf08d3abbef 100644
+--- a/arch/arm64/kvm/hyp/entry.S
++++ b/arch/arm64/kvm/hyp/entry.S
+@@ -98,6 +98,8 @@ ENTRY(__guest_exit)
+ 	// x4-x29,lr: vcpu regs
+ 	// vcpu x0-x3 on the stack
+ 
++	ALTERNATIVE(nop, SET_PSTATE_PAN(1), ARM64_HAS_PAN, CONFIG_ARM64_PAN)
++
+ 	add	x2, x0, #VCPU_CONTEXT
+ 
+ 	stp	x4, x5,   [x2, #CPU_XREG_OFFSET(4)]
+diff --git a/arch/metag/include/asm/atomic.h b/arch/metag/include/asm/atomic.h
+index 470e365f04ea..8ff0a70865f6 100644
+--- a/arch/metag/include/asm/atomic.h
++++ b/arch/metag/include/asm/atomic.h
+@@ -39,11 +39,10 @@
+ #define atomic_dec(v) atomic_sub(1, (v))
+ 
+ #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0)
++#define atomic_dec_if_positive(v)       atomic_sub_if_positive(1, v)
+ 
+ #endif
+ 
+-#define atomic_dec_if_positive(v)       atomic_sub_if_positive(1, v)
+-
+ #include <asm-generic/atomic64.h>
+ 
+ #endif /* __ASM_METAG_ATOMIC_H */
+diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
+index f6fc6aac5496..b6578611dddb 100644
+--- a/arch/mips/include/asm/ptrace.h
++++ b/arch/mips/include/asm/ptrace.h
+@@ -152,7 +152,7 @@ static inline int is_syscall_success(struct pt_regs *regs)
+ 
+ static inline long regs_return_value(struct pt_regs *regs)
+ {
+-	if (is_syscall_success(regs))
++	if (is_syscall_success(regs) || !user_mode(regs))
+ 		return regs->regs[2];
+ 	else
+ 		return -regs->regs[2];
+diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
+index 3b4538ec0102..de9e8836d248 100644
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -82,7 +82,7 @@ obj-vdso := $(obj-vdso-y:%.o=$(obj)/%.o)
+ $(obj-vdso): KBUILD_CFLAGS := $(cflags-vdso) $(native-abi)
+ $(obj-vdso): KBUILD_AFLAGS := $(aflags-vdso) $(native-abi)
+ 
+-$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(native-abi)
++$(obj)/vdso.lds: KBUILD_CPPFLAGS := $(ccflags-vdso) $(native-abi)
+ 
+ $(obj)/vdso.so.dbg.raw: $(obj)/vdso.lds $(obj-vdso) FORCE
+ 	$(call if_changed,vdsold)
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index 291cee28ccb6..c2c43f714684 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -83,10 +83,10 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
+ 	printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, (unsigned long)pgd_val(e))
+ 
+ /* This is the size of the initially mapped kernel memory */
+-#ifdef CONFIG_64BIT
+-#define KERNEL_INITIAL_ORDER	25	/* 1<<25 = 32MB */
++#if defined(CONFIG_64BIT)
++#define KERNEL_INITIAL_ORDER	26	/* 1<<26 = 64MB */
+ #else
+-#define KERNEL_INITIAL_ORDER	24	/* 1<<24 = 16MB */
++#define KERNEL_INITIAL_ORDER	25	/* 1<<25 = 32MB */
+ #endif
+ #define KERNEL_INITIAL_SIZE	(1 << KERNEL_INITIAL_ORDER)
+ 
+diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
+index f7ea626e29c9..81d6f6391944 100644
+--- a/arch/parisc/kernel/setup.c
++++ b/arch/parisc/kernel/setup.c
+@@ -38,6 +38,7 @@
+ #include <linux/export.h>
+ 
+ #include <asm/processor.h>
++#include <asm/sections.h>
+ #include <asm/pdc.h>
+ #include <asm/led.h>
+ #include <asm/machdep.h>	/* for pa7300lc_init() proto */
+@@ -140,6 +141,13 @@ void __init setup_arch(char **cmdline_p)
+ #endif
+ 	printk(KERN_CONT ".\n");
+ 
++	/*
++	 * Check if initial kernel page mappings are sufficient.
++	 * panic early if not, else we may access kernel functions
++	 * and variables which can't be reached.
++	 */
++	if (__pa((unsigned long) &_end) >= KERNEL_INITIAL_SIZE)
++		panic("KERNEL_INITIAL_ORDER too small!");
+ 
+ 	pdc_console_init();
+ 
+diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
+index 4b0b963d52a7..9b63b876a13a 100644
+--- a/arch/parisc/kernel/time.c
++++ b/arch/parisc/kernel/time.c
+@@ -226,12 +226,6 @@ void __init start_cpu_itimer(void)
+ 	unsigned int cpu = smp_processor_id();
+ 	unsigned long next_tick = mfctl(16) + clocktick;
+ 
+-#if defined(CONFIG_HAVE_UNSTABLE_SCHED_CLOCK) && defined(CONFIG_64BIT)
+-	/* With multiple 64bit CPUs online, the cr16's are not syncronized. */
+-	if (cpu != 0)
+-		clear_sched_clock_stable();
+-#endif
+-
+ 	mtctl(next_tick, 16);		/* kick off Interval Timer (CR16) */
+ 
+ 	per_cpu(cpu_data, cpu).it_value = next_tick;
+diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S
+index f3ead0b6ce46..75304af9f742 100644
+--- a/arch/parisc/kernel/vmlinux.lds.S
++++ b/arch/parisc/kernel/vmlinux.lds.S
+@@ -89,8 +89,9 @@ SECTIONS
+ 	/* Start of data section */
+ 	_sdata = .;
+ 
+-	RO_DATA_SECTION(8)
+-
++	/* Architecturally we need to keep __gp below 0x1000000 and thus
++	 * in front of RO_DATA_SECTION() which stores lots of tracepoint
++	 * and ftrace symbols. */
+ #ifdef CONFIG_64BIT
+ 	. = ALIGN(16);
+ 	/* Linkage tables */
+@@ -105,6 +106,8 @@ SECTIONS
+ 	}
+ #endif
+ 
++	RO_DATA_SECTION(8)
++
+ 	/* unwind info */
+ 	.PARISC.unwind : {
+ 		__start___unwind = .;
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 927d2ab2ce08..792cb1768c8f 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -637,7 +637,7 @@ config FORCE_MAX_ZONEORDER
+ 	int "Maximum zone order"
+ 	range 8 9 if PPC64 && PPC_64K_PAGES
+ 	default "9" if PPC64 && PPC_64K_PAGES
+-	range 9 13 if PPC64 && !PPC_64K_PAGES
++	range 13 13 if PPC64 && !PPC_64K_PAGES
+ 	default "13" if PPC64 && !PPC_64K_PAGES
+ 	range 9 64 if PPC32 && PPC_16K_PAGES
+ 	default "9" if PPC32 && PPC_16K_PAGES
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index 5f36e8a70daa..29aa8d1ce273 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -994,6 +994,14 @@ static void eeh_handle_special_event(void)
+ 				/* Notify all devices to be down */
+ 				eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 				bus = eeh_pe_bus_get(phb_pe);
++				if (!bus) {
++					pr_err("%s: Cannot find PCI bus for "
++					       "PHB#%d-PE#%x\n",
++					       __func__,
++					       pe->phb->global_number,
++					       pe->addr);
++					break;
++				}
+ 				eeh_pe_dev_traverse(pe,
+ 					eeh_report_failure, NULL);
+ 				pci_hp_remove_devices(bus);
+diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
+index 184a6ba7f283..abf17feffe40 100644
+--- a/arch/powerpc/kernel/vdso64/datapage.S
++++ b/arch/powerpc/kernel/vdso64/datapage.S
+@@ -59,7 +59,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
+ 	bl	V_LOCAL_FUNC(__get_datapage)
+ 	mtlr	r12
+ 	addi	r3,r3,CFG_SYSCALL_MAP64
+-	cmpli	cr0,r4,0
++	cmpldi	cr0,r4,0
+ 	crclr	cr0*4+so
+ 	beqlr
+ 	li	r0,NR_syscalls
+diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
+index a76b4af37ef2..382021324883 100644
+--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
++++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
+@@ -145,7 +145,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
+ 	bne	cr0,99f
+ 
+ 	li	r3,0
+-	cmpli	cr0,r4,0
++	cmpldi	cr0,r4,0
+ 	crclr	cr0*4+so
+ 	beqlr
+ 	lis	r5,CLOCK_REALTIME_RES@h
+diff --git a/arch/powerpc/lib/copyuser_64.S b/arch/powerpc/lib/copyuser_64.S
+index f09899e35991..7b22624f332c 100644
+--- a/arch/powerpc/lib/copyuser_64.S
++++ b/arch/powerpc/lib/copyuser_64.S
+@@ -359,6 +359,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
+ 	addi	r3,r3,8
+ 171:
+ 177:
++179:
+ 	addi	r3,r3,8
+ 370:
+ 372:
+@@ -373,7 +374,6 @@ END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
+ 173:
+ 174:
+ 175:
+-179:
+ 181:
+ 184:
+ 186:
+diff --git a/arch/powerpc/mm/copro_fault.c b/arch/powerpc/mm/copro_fault.c
+index bb0354222b11..362954f98029 100644
+--- a/arch/powerpc/mm/copro_fault.c
++++ b/arch/powerpc/mm/copro_fault.c
+@@ -106,6 +106,8 @@ int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
+ 	switch (REGION_ID(ea)) {
+ 	case USER_REGION_ID:
+ 		pr_devel("%s: 0x%llx -- USER_REGION_ID\n", __func__, ea);
++		if (mm == NULL)
++			return 1;
+ 		psize = get_slice_psize(mm, ea);
+ 		ssize = user_segment_size(ea);
+ 		vsid = get_vsid(mm->context.id, ea, ssize);
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+index 0821556e16f4..28923b2e2df1 100644
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -526,7 +526,7 @@ static bool might_have_hea(void)
+ 	 */
+ #ifdef CONFIG_IBMEBUS
+ 	return !cpu_has_feature(CPU_FTR_ARCH_207S) &&
+-		!firmware_has_feature(FW_FEATURE_SPLPAR);
++		firmware_has_feature(FW_FEATURE_SPLPAR);
+ #else
+ 	return false;
+ #endif
+diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
+index 86544ea85dc3..ba17fdd87ab0 100644
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -1091,6 +1091,11 @@ static int pnv_eeh_reset(struct eeh_pe *pe, int option)
+ 	}
+ 
+ 	bus = eeh_pe_bus_get(pe);
++	if (!bus) {
++		pr_err("%s: Cannot find PCI bus for PHB#%d-PE#%x\n",
++			__func__, pe->phb->global_number, pe->addr);
++		return -EIO;
++	}
+ 	if (pe->type & EEH_PE_VF)
+ 		return pnv_eeh_reset_vf_pe(pe, option);
+ 
+@@ -1306,7 +1311,7 @@ static void pnv_eeh_get_and_dump_hub_diag(struct pci_controller *hose)
+ 		return;
+ 	}
+ 
+-	switch (data->type) {
++	switch (be16_to_cpu(data->type)) {
+ 	case OPAL_P7IOC_DIAG_TYPE_RGC:
+ 		pr_info("P7IOC diag-data for RGC\n\n");
+ 		pnv_eeh_dump_hub_diag_common(data);
+@@ -1538,7 +1543,7 @@ static int pnv_eeh_next_error(struct eeh_pe **pe)
+ 
+ 				/* Try best to clear it */
+ 				opal_pci_eeh_freeze_clear(phb->opal_id,
+-					frozen_pe_no,
++					be64_to_cpu(frozen_pe_no),
+ 					OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+ 				ret = EEH_NEXT_ERR_NONE;
+ 			} else if ((*pe)->state & EEH_PE_ISOLATED ||
+diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
+index a21d831c1114..0fe3520058a5 100644
+--- a/arch/powerpc/platforms/powernv/pci.c
++++ b/arch/powerpc/platforms/powernv/pci.c
+@@ -309,8 +309,8 @@ static void pnv_pci_dump_p7ioc_diag_data(struct pci_controller *hose,
+ 			be64_to_cpu(data->dma1ErrorLog1));
+ 
+ 	for (i = 0; i < OPAL_P7IOC_NUM_PEST_REGS; i++) {
+-		if ((data->pestA[i] >> 63) == 0 &&
+-		    (data->pestB[i] >> 63) == 0)
++		if ((be64_to_cpu(data->pestA[i]) >> 63) == 0 &&
++		    (be64_to_cpu(data->pestB[i]) >> 63) == 0)
+ 			continue;
+ 
+ 		pr_info("PE[%3d] A/B: %016llx %016llx\n",
+diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
+index 86707e67843f..aa35245d8d6d 100644
+--- a/arch/powerpc/platforms/pseries/lpar.c
++++ b/arch/powerpc/platforms/pseries/lpar.c
+@@ -393,7 +393,7 @@ static void __pSeries_lpar_hugepage_invalidate(unsigned long *slot,
+ 					     unsigned long *vpn, int count,
+ 					     int psize, int ssize)
+ {
+-	unsigned long param[8];
++	unsigned long param[PLPAR_HCALL9_BUFSIZE];
+ 	int i = 0, pix = 0, rc;
+ 	unsigned long flags = 0;
+ 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+@@ -522,7 +522,7 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
+ 	unsigned long flags = 0;
+ 	struct ppc64_tlb_batch *batch = this_cpu_ptr(&ppc64_tlb_batch);
+ 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+-	unsigned long param[9];
++	unsigned long param[PLPAR_HCALL9_BUFSIZE];
+ 	unsigned long hash, index, shift, hidx, slot;
+ 	real_pte_t pte;
+ 	int psize, ssize;
+diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c
+index 81d49476c47e..82e8e2b6a3c4 100644
+--- a/arch/powerpc/sysdev/cpm1.c
++++ b/arch/powerpc/sysdev/cpm1.c
+@@ -233,8 +233,6 @@ void __init cpm_reset(void)
+ 	else
+ 		out_be32(&siu_conf->sc_sdcr, 1);
+ 	immr_unmap(siu_conf);
+-
+-	cpm_muram_init();
+ }
+ 
+ static DEFINE_SPINLOCK(cmd_lock);
+diff --git a/arch/powerpc/sysdev/cpm2.c b/arch/powerpc/sysdev/cpm2.c
+index 8dc1e24f3c23..f78ff841652c 100644
+--- a/arch/powerpc/sysdev/cpm2.c
++++ b/arch/powerpc/sysdev/cpm2.c
+@@ -66,10 +66,6 @@ void __init cpm2_reset(void)
+ 	cpm2_immr = ioremap(get_immrbase(), CPM_MAP_SIZE);
+ #endif
+ 
+-	/* Reclaim the DP memory for our use.
+-	 */
+-	cpm_muram_init();
+-
+ 	/* Tell everyone where the comm processor resides.
+ 	 */
+ 	cpmp = &cpm2_immr->im_cpm;
+diff --git a/arch/powerpc/sysdev/cpm_common.c b/arch/powerpc/sysdev/cpm_common.c
+index 947f42007734..51bf749a4f3a 100644
+--- a/arch/powerpc/sysdev/cpm_common.c
++++ b/arch/powerpc/sysdev/cpm_common.c
+@@ -37,6 +37,21 @@
+ #include <linux/of_gpio.h>
+ #endif
+ 
++static int __init cpm_init(void)
++{
++	struct device_node *np;
++
++	np = of_find_compatible_node(NULL, NULL, "fsl,cpm1");
++	if (!np)
++		np = of_find_compatible_node(NULL, NULL, "fsl,cpm2");
++	if (!np)
++		return -ENODEV;
++	cpm_muram_init();
++	of_node_put(np);
++	return 0;
++}
++subsys_initcall(cpm_init);
++
+ #ifdef CONFIG_PPC_EARLY_DEBUG_CPM
+ static u32 __iomem *cpm_udbg_txdesc;
+ static u8 __iomem *cpm_udbg_txbuf;
+diff --git a/arch/powerpc/xmon/spr_access.S b/arch/powerpc/xmon/spr_access.S
+index 84ad74213c83..7d8b0e8ed6d9 100644
+--- a/arch/powerpc/xmon/spr_access.S
++++ b/arch/powerpc/xmon/spr_access.S
+@@ -2,12 +2,12 @@
+ 
+ /* unsigned long xmon_mfspr(sprn, default_value) */
+ _GLOBAL(xmon_mfspr)
+-	ld	r5, .Lmfspr_table@got(r2)
++	PPC_LL	r5, .Lmfspr_table@got(r2)
+ 	b	xmon_mxspr
+ 
+ /* void xmon_mtspr(sprn, new_value) */
+ _GLOBAL(xmon_mtspr)
+-	ld	r5, .Lmtspr_table@got(r2)
++	PPC_LL	r5, .Lmtspr_table@got(r2)
+ 	b	xmon_mxspr
+ 
+ /*
+diff --git a/arch/s390/kvm/intercept.c b/arch/s390/kvm/intercept.c
+index dfd0ca2638fa..9746b780ad5a 100644
+--- a/arch/s390/kvm/intercept.c
++++ b/arch/s390/kvm/intercept.c
+@@ -118,8 +118,13 @@ static int handle_validity(struct kvm_vcpu *vcpu)
+ 
+ 	vcpu->stat.exit_validity++;
+ 	trace_kvm_s390_intercept_validity(vcpu, viwhy);
+-	WARN_ONCE(true, "kvm: unhandled validity intercept 0x%x\n", viwhy);
+-	return -EOPNOTSUPP;
++	KVM_EVENT(3, "validity intercept 0x%x for pid %u (kvm 0x%pK)", viwhy,
++		  current->pid, vcpu->kvm);
++
++	/* do not warn on invalid runtime instrumentation mode */
++	WARN_ONCE(viwhy != 0x44, "kvm: unhandled validity intercept 0x%x\n",
++		  viwhy);
++	return -EINVAL;
+ }
+ 
+ static int handle_instruction(struct kvm_vcpu *vcpu)
+diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
+index 8a90f1517837..625eb698c780 100644
+--- a/arch/x86/kernel/e820.c
++++ b/arch/x86/kernel/e820.c
+@@ -348,7 +348,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
+ 		 * continue building up new bios map based on this
+ 		 * information
+ 		 */
+-		if (current_type != last_type) {
++		if (current_type != last_type || current_type == E820_PRAM) {
+ 			if (last_type != 0)	 {
+ 				new_bios[new_bios_entry].size =
+ 					change_point[chgidx]->addr - last_addr;
+diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
+index 82b17373b66a..9e152cdab0f3 100644
+--- a/arch/x86/kernel/smpboot.c
++++ b/arch/x86/kernel/smpboot.c
+@@ -1408,15 +1408,17 @@ __init void prefill_possible_map(void)
+ 
+ 	/* No boot processor was found in mptable or ACPI MADT */
+ 	if (!num_processors) {
+-		int apicid = boot_cpu_physical_apicid;
+-		int cpu = hard_smp_processor_id();
++		if (boot_cpu_has(X86_FEATURE_APIC)) {
++			int apicid = boot_cpu_physical_apicid;
++			int cpu = hard_smp_processor_id();
+ 
+-		pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu);
++			pr_warn("Boot CPU (id %d) not listed by BIOS\n", cpu);
+ 
+-		/* Make sure boot cpu is enumerated */
+-		if (apic->cpu_present_to_apicid(0) == BAD_APICID &&
+-		    apic->apic_id_valid(apicid))
+-			generic_processor_info(apicid, boot_cpu_apic_version);
++			/* Make sure boot cpu is enumerated */
++			if (apic->cpu_present_to_apicid(0) == BAD_APICID &&
++			    apic->apic_id_valid(apicid))
++				generic_processor_info(apicid, boot_cpu_apic_version);
++		}
+ 
+ 		if (!num_processors)
+ 			num_processors = 1;
+diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
+index c7220ba94aa7..1a22de70f7f7 100644
+--- a/arch/x86/kvm/ioapic.c
++++ b/arch/x86/kvm/ioapic.c
+@@ -594,7 +594,7 @@ static void kvm_ioapic_reset(struct kvm_ioapic *ioapic)
+ 	ioapic->irr = 0;
+ 	ioapic->irr_delivered = 0;
+ 	ioapic->id = 0;
+-	memset(ioapic->irq_eoi, 0x00, IOAPIC_NUM_PINS);
++	memset(ioapic->irq_eoi, 0x00, sizeof(ioapic->irq_eoi));
+ 	rtc_irq_eoi_tracking_reset(ioapic);
+ }
+ 
+diff --git a/arch/x86/platform/uv/bios_uv.c b/arch/x86/platform/uv/bios_uv.c
+index 23f2f3e41c7f..58e152b3bd90 100644
+--- a/arch/x86/platform/uv/bios_uv.c
++++ b/arch/x86/platform/uv/bios_uv.c
+@@ -40,7 +40,15 @@ s64 uv_bios_call(enum uv_bios_cmd which, u64 a1, u64 a2, u64 a3, u64 a4, u64 a5)
+ 		 */
+ 		return BIOS_STATUS_UNIMPLEMENTED;
+ 
+-	ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5);
++	/*
++	 * If EFI_OLD_MEMMAP is set, we need to fall back to using our old EFI
++	 * callback method, which uses efi_call() directly, with the kernel page tables:
++	 */
++	if (unlikely(test_bit(EFI_OLD_MEMMAP, &efi.flags)))
++		ret = efi_call((void *)__va(tab->function), (u64)which, a1, a2, a3, a4, a5);
++	else
++		ret = efi_call_virt_pointer(tab, function, (u64)which, a1, a2, a3, a4, a5);
++
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(uv_bios_call);
+diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
+index dd38e5ced4a3..b08ccbb9393a 100644
+--- a/block/blk-cgroup.c
++++ b/block/blk-cgroup.c
+@@ -1340,10 +1340,8 @@ int blkcg_policy_register(struct blkcg_policy *pol)
+ 			struct blkcg_policy_data *cpd;
+ 
+ 			cpd = pol->cpd_alloc_fn(GFP_KERNEL);
+-			if (!cpd) {
+-				mutex_unlock(&blkcg_pol_mutex);
++			if (!cpd)
+ 				goto err_free_cpds;
+-			}
+ 
+ 			blkcg->cpd[pol->plid] = cpd;
+ 			cpd->blkcg = blkcg;
+diff --git a/drivers/base/platform.c b/drivers/base/platform.c
+index 6482d47deb50..d5572295cad3 100644
+--- a/drivers/base/platform.c
++++ b/drivers/base/platform.c
+@@ -97,7 +97,7 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
+ 		int ret;
+ 
+ 		ret = of_irq_get(dev->dev.of_node, num);
+-		if (ret >= 0 || ret == -EPROBE_DEFER)
++		if (ret > 0 || ret == -EPROBE_DEFER)
+ 			return ret;
+ 	}
+ 
+@@ -175,7 +175,7 @@ int platform_get_irq_byname(struct platform_device *dev, const char *name)
+ 		int ret;
+ 
+ 		ret = of_irq_get_byname(dev->dev.of_node, name);
+-		if (ret >= 0 || ret == -EPROBE_DEFER)
++		if (ret > 0 || ret == -EPROBE_DEFER)
+ 			return ret;
+ 	}
+ 
+diff --git a/drivers/clk/imx/clk-imx6q.c b/drivers/clk/imx/clk-imx6q.c
+index ba1c1ae72ac2..ce8ea10407e4 100644
+--- a/drivers/clk/imx/clk-imx6q.c
++++ b/drivers/clk/imx/clk-imx6q.c
+@@ -318,11 +318,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ 		clk[IMX6QDL_CLK_IPG_PER_SEL] = imx_clk_mux("ipg_per_sel", base + 0x1c, 6, 1, ipg_per_sels, ARRAY_SIZE(ipg_per_sels));
+ 		clk[IMX6QDL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
+ 		clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 16, 2, gpu2d_core_sels_2, ARRAY_SIZE(gpu2d_core_sels_2));
++	} else if (clk_on_imx6dl()) {
++		clk[IMX6QDL_CLK_MLB_SEL] = imx_clk_mux("mlb_sel",   base + 0x18, 16, 2, gpu2d_core_sels,   ARRAY_SIZE(gpu2d_core_sels));
+ 	} else {
+ 		clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel",   base + 0x18, 16, 2, gpu2d_core_sels,   ARRAY_SIZE(gpu2d_core_sels));
+ 	}
+ 	clk[IMX6QDL_CLK_GPU3D_CORE_SEL]   = imx_clk_mux("gpu3d_core_sel",   base + 0x18, 4,  2, gpu3d_core_sels,   ARRAY_SIZE(gpu3d_core_sels));
+-	clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8,  2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
++	if (clk_on_imx6dl())
++		clk[IMX6QDL_CLK_GPU2D_CORE_SEL] = imx_clk_mux("gpu2d_core_sel", base + 0x18, 8,  2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
++	else
++		clk[IMX6QDL_CLK_GPU3D_SHADER_SEL] = imx_clk_mux("gpu3d_shader_sel", base + 0x18, 8,  2, gpu3d_shader_sels, ARRAY_SIZE(gpu3d_shader_sels));
+ 	clk[IMX6QDL_CLK_IPU1_SEL]         = imx_clk_mux("ipu1_sel",         base + 0x3c, 9,  2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+ 	clk[IMX6QDL_CLK_IPU2_SEL]         = imx_clk_mux("ipu2_sel",         base + 0x3c, 14, 2, ipu_sels,          ARRAY_SIZE(ipu_sels));
+ 	clk[IMX6QDL_CLK_LDB_DI0_SEL]      = imx_clk_mux_flags("ldb_di0_sel", base + 0x2c, 9,  3, ldb_di_sels,      ARRAY_SIZE(ldb_di_sels), CLK_SET_RATE_PARENT);
+@@ -400,9 +405,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ 		clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5] = imx_clk_fixed_factor("ldb_di0_div_3_5", "ldb_di0_sel", 2, 7);
+ 		clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5] = imx_clk_fixed_factor("ldb_di1_div_3_5", "ldb_di1_sel", 2, 7);
+ 	}
+-	clk[IMX6QDL_CLK_GPU2D_CORE_PODF]  = imx_clk_divider("gpu2d_core_podf",  "gpu2d_core_sel",    base + 0x18, 23, 3);
++	if (clk_on_imx6dl())
++		clk[IMX6QDL_CLK_MLB_PODF]  = imx_clk_divider("mlb_podf",  "mlb_sel",    base + 0x18, 23, 3);
++	else
++		clk[IMX6QDL_CLK_GPU2D_CORE_PODF]  = imx_clk_divider("gpu2d_core_podf",  "gpu2d_core_sel",    base + 0x18, 23, 3);
+ 	clk[IMX6QDL_CLK_GPU3D_CORE_PODF]  = imx_clk_divider("gpu3d_core_podf",  "gpu3d_core_sel",    base + 0x18, 26, 3);
+-	clk[IMX6QDL_CLK_GPU3D_SHADER]     = imx_clk_divider("gpu3d_shader",     "gpu3d_shader_sel",  base + 0x18, 29, 3);
++	if (clk_on_imx6dl())
++		clk[IMX6QDL_CLK_GPU2D_CORE_PODF]  = imx_clk_divider("gpu2d_core_podf",     "gpu2d_core_sel",  base + 0x18, 29, 3);
++	else
++		clk[IMX6QDL_CLK_GPU3D_SHADER]     = imx_clk_divider("gpu3d_shader",     "gpu3d_shader_sel",  base + 0x18, 29, 3);
+ 	clk[IMX6QDL_CLK_IPU1_PODF]        = imx_clk_divider("ipu1_podf",        "ipu1_sel",          base + 0x3c, 11, 3);
+ 	clk[IMX6QDL_CLK_IPU2_PODF]        = imx_clk_divider("ipu2_podf",        "ipu2_sel",          base + 0x3c, 16, 3);
+ 	clk[IMX6QDL_CLK_LDB_DI0_PODF]     = imx_clk_divider_flags("ldb_di0_podf", "ldb_di0_div_3_5", base + 0x20, 10, 1, 0);
+@@ -473,14 +484,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ 	clk[IMX6QDL_CLK_ESAI_MEM]     = imx_clk_gate2_shared("esai_mem", "ahb",             base + 0x6c, 16, &share_count_esai);
+ 	clk[IMX6QDL_CLK_GPT_IPG]      = imx_clk_gate2("gpt_ipg",       "ipg",               base + 0x6c, 20);
+ 	clk[IMX6QDL_CLK_GPT_IPG_PER]  = imx_clk_gate2("gpt_ipg_per",   "ipg_per",           base + 0x6c, 22);
+-	if (clk_on_imx6dl())
+-		/*
+-		 * The multiplexer and divider of imx6q clock gpu3d_shader get
+-		 * redefined/reused as gpu2d_core_sel and gpu2d_core_podf on imx6dl.
+-		 */
+-		clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu3d_shader", base + 0x6c, 24);
+-	else
+-		clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
++	clk[IMX6QDL_CLK_GPU2D_CORE] = imx_clk_gate2("gpu2d_core", "gpu2d_core_podf", base + 0x6c, 24);
+ 	clk[IMX6QDL_CLK_GPU3D_CORE]   = imx_clk_gate2("gpu3d_core",    "gpu3d_core_podf",   base + 0x6c, 26);
+ 	clk[IMX6QDL_CLK_HDMI_IAHB]    = imx_clk_gate2("hdmi_iahb",     "ahb",               base + 0x70, 0);
+ 	clk[IMX6QDL_CLK_HDMI_ISFR]    = imx_clk_gate2("hdmi_isfr",     "video_27m",         base + 0x70, 4);
+@@ -511,7 +515,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ 		 * The multiplexer and divider of the imx6q clock gpu2d get
+ 		 * redefined/reused as mlb_sys_sel and mlb_sys_clk_podf on imx6dl.
+ 		 */
+-		clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb",            "gpu2d_core_podf",   base + 0x74, 18);
++		clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb",            "mlb_podf",   base + 0x74, 18);
+ 	else
+ 		clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb",            "axi",               base + 0x74, 18);
+ 	clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2("mmdc_ch0_axi",  "mmdc_ch0_axi_podf", base + 0x74, 20);
+@@ -629,6 +633,24 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+ 	if (IS_ENABLED(CONFIG_PCI_IMX6))
+ 		clk_set_parent(clk[IMX6QDL_CLK_LVDS1_SEL], clk[IMX6QDL_CLK_SATA_REF_100M]);
+ 
++	/*
++	 * Initialize the GPU clock muxes, so that the maximum specified clock
++	 * rates for the respective SoC are not exceeded.
++	 */
++	if (clk_on_imx6dl()) {
++		clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL],
++			       clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
++		clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL],
++			       clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
++	} else if (clk_on_imx6q()) {
++		clk_set_parent(clk[IMX6QDL_CLK_GPU3D_CORE_SEL],
++			       clk[IMX6QDL_CLK_MMDC_CH0_AXI]);
++		clk_set_parent(clk[IMX6QDL_CLK_GPU3D_SHADER_SEL],
++			       clk[IMX6QDL_CLK_PLL2_PFD1_594M]);
++		clk_set_parent(clk[IMX6QDL_CLK_GPU2D_CORE_SEL],
++			       clk[IMX6QDL_CLK_PLL3_USB_OTG]);
++	}
++
+ 	imx_register_uart_clocks(uart_clks);
+ }
+ CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);
+diff --git a/drivers/cpufreq/cpufreq-dt-platdev.c b/drivers/cpufreq/cpufreq-dt-platdev.c
+index 2ee40fd360ca..e1aa531a4c34 100644
+--- a/drivers/cpufreq/cpufreq-dt-platdev.c
++++ b/drivers/cpufreq/cpufreq-dt-platdev.c
+@@ -68,6 +68,8 @@ static const struct of_device_id machines[] __initconst = {
+ 
+ 	{ .compatible = "sigma,tango4" },
+ 
++	{ .compatible = "ti,am33xx", },
++	{ .compatible = "ti,dra7", },
+ 	{ .compatible = "ti,omap2", },
+ 	{ .compatible = "ti,omap3", },
+ 	{ .compatible = "ti,omap4", },
+diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c
+index 18da4f8051d3..13475890d792 100644
+--- a/drivers/cpufreq/cpufreq_conservative.c
++++ b/drivers/cpufreq/cpufreq_conservative.c
+@@ -17,6 +17,7 @@
+ struct cs_policy_dbs_info {
+ 	struct policy_dbs_info policy_dbs;
+ 	unsigned int down_skip;
++	unsigned int requested_freq;
+ };
+ 
+ static inline struct cs_policy_dbs_info *to_dbs_info(struct policy_dbs_info *policy_dbs)
+@@ -61,6 +62,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
+ {
+ 	struct policy_dbs_info *policy_dbs = policy->governor_data;
+ 	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy_dbs);
++	unsigned int requested_freq = dbs_info->requested_freq;
+ 	struct dbs_data *dbs_data = policy_dbs->dbs_data;
+ 	struct cs_dbs_tuners *cs_tuners = dbs_data->tuners;
+ 	unsigned int load = dbs_update(policy);
+@@ -72,10 +74,16 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
+ 	if (cs_tuners->freq_step == 0)
+ 		goto out;
+ 
++	/*
++	 * If requested_freq is out of range, it is likely that the limits
++	 * changed in the meantime, so fall back to current frequency in that
++	 * case.
++	 */
++	if (requested_freq > policy->max || requested_freq < policy->min)
++		requested_freq = policy->cur;
++
+ 	/* Check for frequency increase */
+ 	if (load > dbs_data->up_threshold) {
+-		unsigned int requested_freq = policy->cur;
+-
+ 		dbs_info->down_skip = 0;
+ 
+ 		/* if we are already at full speed then break out early */
+@@ -83,8 +91,11 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
+ 			goto out;
+ 
+ 		requested_freq += get_freq_target(cs_tuners, policy);
++		if (requested_freq > policy->max)
++			requested_freq = policy->max;
+ 
+ 		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_H);
++		dbs_info->requested_freq = requested_freq;
+ 		goto out;
+ 	}
+ 
+@@ -95,7 +106,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
+ 
+ 	/* Check for frequency decrease */
+ 	if (load < cs_tuners->down_threshold) {
+-		unsigned int freq_target, requested_freq = policy->cur;
++		unsigned int freq_target;
+ 		/*
+ 		 * if we cannot reduce the frequency anymore, break out early
+ 		 */
+@@ -109,6 +120,7 @@ static unsigned int cs_dbs_timer(struct cpufreq_policy *policy)
+ 			requested_freq = policy->min;
+ 
+ 		__cpufreq_driver_target(policy, requested_freq, CPUFREQ_RELATION_L);
++		dbs_info->requested_freq = requested_freq;
+ 	}
+ 
+  out:
+@@ -287,6 +299,7 @@ static void cs_start(struct cpufreq_policy *policy)
+ 	struct cs_policy_dbs_info *dbs_info = to_dbs_info(policy->governor_data);
+ 
+ 	dbs_info->down_skip = 0;
++	dbs_info->requested_freq = policy->cur;
+ }
+ 
+ static struct dbs_governor cs_governor = {
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index be9eade147f2..b46547e907be 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -556,12 +556,12 @@ static void intel_pstate_hwp_set(const struct cpumask *cpumask)
+ 	int min, hw_min, max, hw_max, cpu, range, adj_range;
+ 	u64 value, cap;
+ 
+-	rdmsrl(MSR_HWP_CAPABILITIES, cap);
+-	hw_min = HWP_LOWEST_PERF(cap);
+-	hw_max = HWP_HIGHEST_PERF(cap);
+-	range = hw_max - hw_min;
+-
+ 	for_each_cpu(cpu, cpumask) {
++		rdmsrl_on_cpu(cpu, MSR_HWP_CAPABILITIES, &cap);
++		hw_min = HWP_LOWEST_PERF(cap);
++		hw_max = HWP_HIGHEST_PERF(cap);
++		range = hw_max - hw_min;
++
+ 		rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
+ 		adj_range = limits->min_perf_pct * range / 100;
+ 		min = hw_min + adj_range;
+diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c
+index 425501c39527..793518a30afe 100644
+--- a/drivers/gpio/gpio-mpc8xxx.c
++++ b/drivers/gpio/gpio-mpc8xxx.c
+@@ -239,7 +239,7 @@ static int mpc8xxx_gpio_irq_map(struct irq_domain *h, unsigned int irq,
+ 				irq_hw_number_t hwirq)
+ {
+ 	irq_set_chip_data(irq, h->host_data);
+-	irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_level_irq);
++	irq_set_chip_and_handler(irq, &mpc8xxx_irq_chip, handle_edge_irq);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
+index f2b776efab3a..5f88ccd6806b 100644
+--- a/drivers/infiniband/core/verbs.c
++++ b/drivers/infiniband/core/verbs.c
+@@ -821,7 +821,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
+ 		if (ret) {
+ 			pr_err("failed to init MR pool ret= %d\n", ret);
+ 			ib_destroy_qp(qp);
+-			qp = ERR_PTR(ret);
++			return ERR_PTR(ret);
+ 		}
+ 	}
+ 
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index 3322ed750172..6b07d4bca764 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -1400,7 +1400,9 @@ static int srp_map_sg_entry(struct srp_map_state *state,
+ 
+ 	while (dma_len) {
+ 		unsigned offset = dma_addr & ~dev->mr_page_mask;
+-		if (state->npages == dev->max_pages_per_mr || offset != 0) {
++
++		if (state->npages == dev->max_pages_per_mr ||
++		    (state->npages > 0 && offset != 0)) {
+ 			ret = srp_map_finish_fmr(state, ch);
+ 			if (ret)
+ 				return ret;
+@@ -1417,12 +1419,12 @@ static int srp_map_sg_entry(struct srp_map_state *state,
+ 	}
+ 
+ 	/*
+-	 * If the last entry of the MR wasn't a full page, then we need to
++	 * If the end of the MR is not on a page boundary then we need to
+ 	 * close it out and start a new one -- we can only merge at page
+ 	 * boundaries.
+ 	 */
+ 	ret = 0;
+-	if (len != dev->mr_page_size)
++	if ((dma_addr & ~dev->mr_page_mask) != 0)
+ 		ret = srp_map_finish_fmr(state, ch);
+ 	return ret;
+ }
+diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
+index 08e252a42480..ff8c10749e57 100644
+--- a/drivers/input/mouse/elantech.c
++++ b/drivers/input/mouse/elantech.c
+@@ -1159,6 +1159,13 @@ static const struct dmi_system_id elantech_dmi_has_middle_button[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H730"),
+ 		},
+ 	},
++	{
++		/* Fujitsu H760 also has a middle button */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
++		},
++	},
+ #endif
+ 	{ }
+ };
+@@ -1503,10 +1510,10 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
+ 		},
+ 	},
+ 	{
+-		/* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
++		/* Fujitsu H760 does not work with crc_enabled == 0 */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+-			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "CELSIUS H760"),
+ 		},
+ 	},
+ 	{
+@@ -1517,6 +1524,20 @@ static const struct dmi_system_id elantech_dmi_force_crc_enabled[] = {
+ 		},
+ 	},
+ 	{
++		/* Fujitsu LIFEBOOK E554  does not work with crc_enabled == 0 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E554"),
++		},
++	},
++	{
++		/* Fujitsu LIFEBOOK E556 does not work with crc_enabled == 0 */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "LIFEBOOK E556"),
++		},
++	},
++	{
+ 		/* Fujitsu LIFEBOOK U745 does not work with crc_enabled == 0 */
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU"),
+diff --git a/drivers/input/serio/i8042-io.h b/drivers/input/serio/i8042-io.h
+index a5eed2ade53d..34da81c006b6 100644
+--- a/drivers/input/serio/i8042-io.h
++++ b/drivers/input/serio/i8042-io.h
+@@ -81,7 +81,7 @@ static inline int i8042_platform_init(void)
+ 		return -EBUSY;
+ #endif
+ 
+-	i8042_reset = 1;
++	i8042_reset = I8042_RESET_ALWAYS;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/input/serio/i8042-ip22io.h b/drivers/input/serio/i8042-ip22io.h
+index ee1ad27d6ed0..08a1c10a1448 100644
+--- a/drivers/input/serio/i8042-ip22io.h
++++ b/drivers/input/serio/i8042-ip22io.h
+@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void)
+ 		return -EBUSY;
+ #endif
+ 
+-	i8042_reset = 1;
++	i8042_reset = I8042_RESET_ALWAYS;
+ 
+ 	return 0;
+ }
+diff --git a/drivers/input/serio/i8042-ppcio.h b/drivers/input/serio/i8042-ppcio.h
+index f708c75d16f1..1aabea43329e 100644
+--- a/drivers/input/serio/i8042-ppcio.h
++++ b/drivers/input/serio/i8042-ppcio.h
+@@ -44,7 +44,7 @@ static inline void i8042_write_command(int val)
+ 
+ static inline int i8042_platform_init(void)
+ {
+-	i8042_reset = 1;
++	i8042_reset = I8042_RESET_ALWAYS;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/input/serio/i8042-sparcio.h b/drivers/input/serio/i8042-sparcio.h
+index afcd1c1a05b2..6231d63860ee 100644
+--- a/drivers/input/serio/i8042-sparcio.h
++++ b/drivers/input/serio/i8042-sparcio.h
+@@ -130,7 +130,7 @@ static int __init i8042_platform_init(void)
+ 		}
+ 	}
+ 
+-	i8042_reset = 1;
++	i8042_reset = I8042_RESET_ALWAYS;
+ 
+ 	return 0;
+ }
+diff --git a/drivers/input/serio/i8042-unicore32io.h b/drivers/input/serio/i8042-unicore32io.h
+index 73f5cc124a36..455747552f85 100644
+--- a/drivers/input/serio/i8042-unicore32io.h
++++ b/drivers/input/serio/i8042-unicore32io.h
+@@ -61,7 +61,7 @@ static inline int i8042_platform_init(void)
+ 	if (!request_mem_region(I8042_REGION_START, I8042_REGION_SIZE, "i8042"))
+ 		return -EBUSY;
+ 
+-	i8042_reset = 1;
++	i8042_reset = I8042_RESET_ALWAYS;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index 68f5f4a0f1e7..f4bfb4b2d50a 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -510,6 +510,90 @@ static const struct dmi_system_id __initconst i8042_dmi_nomux_table[] = {
+ 	{ }
+ };
+ 
++/*
++ * On some Asus laptops, just running self tests cause problems.
++ */
++static const struct dmi_system_id i8042_dmi_noselftest_table[] = {
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "A455LD"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "K401LB"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "K501LB"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "K501LX"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "R409L"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "V502LX"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X302LA"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X450LCP"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X450LD"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X455LAB"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X455LDB"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X455LF"),
++		},
++	},
++	{
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "Z450LA"),
++		},
++	},
++	{ }
++};
+ static const struct dmi_system_id __initconst i8042_dmi_reset_table[] = {
+ 	{
+ 		/* MSI Wind U-100 */
+@@ -1072,12 +1156,18 @@ static int __init i8042_platform_init(void)
+ 		return retval;
+ 
+ #if defined(__ia64__)
+-        i8042_reset = true;
++        i8042_reset = I8042_RESET_ALWAYS;
+ #endif
+ 
+ #ifdef CONFIG_X86
+-	if (dmi_check_system(i8042_dmi_reset_table))
+-		i8042_reset = true;
++	/* Honor module parameter when value is not default */
++	if (i8042_reset == I8042_RESET_DEFAULT) {
++		if (dmi_check_system(i8042_dmi_reset_table))
++			i8042_reset = I8042_RESET_ALWAYS;
++
++		if (dmi_check_system(i8042_dmi_noselftest_table))
++			i8042_reset = I8042_RESET_NEVER;
++	}
+ 
+ 	if (dmi_check_system(i8042_dmi_noloop_table))
+ 		i8042_noloop = true;
+diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
+index 405252a884dd..89abfdb539ac 100644
+--- a/drivers/input/serio/i8042.c
++++ b/drivers/input/serio/i8042.c
+@@ -48,9 +48,39 @@ static bool i8042_unlock;
+ module_param_named(unlock, i8042_unlock, bool, 0);
+ MODULE_PARM_DESC(unlock, "Ignore keyboard lock.");
+ 
+-static bool i8042_reset;
+-module_param_named(reset, i8042_reset, bool, 0);
+-MODULE_PARM_DESC(reset, "Reset controller during init and cleanup.");
++enum i8042_controller_reset_mode {
++	I8042_RESET_NEVER,
++	I8042_RESET_ALWAYS,
++	I8042_RESET_ON_S2RAM,
++#define I8042_RESET_DEFAULT	I8042_RESET_ON_S2RAM
++};
++static enum i8042_controller_reset_mode i8042_reset = I8042_RESET_DEFAULT;
++static int i8042_set_reset(const char *val, const struct kernel_param *kp)
++{
++	enum i8042_controller_reset_mode *arg = kp->arg;
++	int error;
++	bool reset;
++
++	if (val) {
++		error = kstrtobool(val, &reset);
++		if (error)
++			return error;
++	} else {
++		reset = true;
++	}
++
++	*arg = reset ? I8042_RESET_ALWAYS : I8042_RESET_NEVER;
++	return 0;
++}
++
++static const struct kernel_param_ops param_ops_reset_param = {
++	.flags = KERNEL_PARAM_OPS_FL_NOARG,
++	.set = i8042_set_reset,
++};
++#define param_check_reset_param(name, p)	\
++	__param_check(name, p, enum i8042_controller_reset_mode)
++module_param_named(reset, i8042_reset, reset_param, 0);
++MODULE_PARM_DESC(reset, "Reset controller on resume, cleanup or both");
+ 
+ static bool i8042_direct;
+ module_param_named(direct, i8042_direct, bool, 0);
+@@ -1019,7 +1049,7 @@ static int i8042_controller_init(void)
+  * Reset the controller and reset CRT to the original value set by BIOS.
+  */
+ 
+-static void i8042_controller_reset(bool force_reset)
++static void i8042_controller_reset(bool s2r_wants_reset)
+ {
+ 	i8042_flush();
+ 
+@@ -1044,8 +1074,10 @@ static void i8042_controller_reset(bool force_reset)
+  * Reset the controller if requested.
+  */
+ 
+-	if (i8042_reset || force_reset)
++	if (i8042_reset == I8042_RESET_ALWAYS ||
++	    (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
+ 		i8042_controller_selftest();
++	}
+ 
+ /*
+  * Restore the original control register setting.
+@@ -1110,7 +1142,7 @@ static void i8042_dritek_enable(void)
+  * before suspending.
+  */
+ 
+-static int i8042_controller_resume(bool force_reset)
++static int i8042_controller_resume(bool s2r_wants_reset)
+ {
+ 	int error;
+ 
+@@ -1118,7 +1150,8 @@ static int i8042_controller_resume(bool force_reset)
+ 	if (error)
+ 		return error;
+ 
+-	if (i8042_reset || force_reset) {
++	if (i8042_reset == I8042_RESET_ALWAYS ||
++	    (i8042_reset == I8042_RESET_ON_S2RAM && s2r_wants_reset)) {
+ 		error = i8042_controller_selftest();
+ 		if (error)
+ 			return error;
+@@ -1195,7 +1228,7 @@ static int i8042_pm_resume_noirq(struct device *dev)
+ 
+ static int i8042_pm_resume(struct device *dev)
+ {
+-	bool force_reset;
++	bool want_reset;
+ 	int i;
+ 
+ 	for (i = 0; i < I8042_NUM_PORTS; i++) {
+@@ -1218,9 +1251,9 @@ static int i8042_pm_resume(struct device *dev)
+ 	 * off control to the platform firmware, otherwise we can simply restore
+ 	 * the mode.
+ 	 */
+-	force_reset = pm_resume_via_firmware();
++	want_reset = pm_resume_via_firmware();
+ 
+-	return i8042_controller_resume(force_reset);
++	return i8042_controller_resume(want_reset);
+ }
+ 
+ static int i8042_pm_thaw(struct device *dev)
+@@ -1482,7 +1515,7 @@ static int __init i8042_probe(struct platform_device *dev)
+ 
+ 	i8042_platform_device = dev;
+ 
+-	if (i8042_reset) {
++	if (i8042_reset == I8042_RESET_ALWAYS) {
+ 		error = i8042_controller_selftest();
+ 		if (error)
+ 			return error;
+diff --git a/drivers/irqchip/irq-eznps.c b/drivers/irqchip/irq-eznps.c
+index efbf0e4304b7..ebc2b0b15f67 100644
+--- a/drivers/irqchip/irq-eznps.c
++++ b/drivers/irqchip/irq-eznps.c
+@@ -85,7 +85,7 @@ static void nps400_irq_eoi_global(struct irq_data *irqd)
+ 	nps_ack_gic();
+ }
+ 
+-static void nps400_irq_eoi(struct irq_data *irqd)
++static void nps400_irq_ack(struct irq_data *irqd)
+ {
+ 	unsigned int __maybe_unused irq = irqd_to_hwirq(irqd);
+ 
+@@ -103,7 +103,7 @@ static struct irq_chip nps400_irq_chip_percpu = {
+ 	.name		= "NPS400 IC",
+ 	.irq_mask	= nps400_irq_mask,
+ 	.irq_unmask	= nps400_irq_unmask,
+-	.irq_eoi	= nps400_irq_eoi,
++	.irq_ack	= nps400_irq_ack,
+ };
+ 
+ static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index da6c0ba61d4f..708a2604a7b5 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -153,7 +153,7 @@ static void gic_enable_redist(bool enable)
+ 			return;	/* No PM support in this redistributor */
+ 	}
+ 
+-	while (count--) {
++	while (--count) {
+ 		val = readl_relaxed(rbase + GICR_WAKER);
+ 		if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
+ 			break;
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 874295757caa..6fc8923bd92a 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -113,8 +113,7 @@ struct iv_tcw_private {
+  * and encrypts / decrypts at the same time.
+  */
+ enum flags { DM_CRYPT_SUSPENDED, DM_CRYPT_KEY_VALID,
+-	     DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD,
+-	     DM_CRYPT_EXIT_THREAD};
++	     DM_CRYPT_SAME_CPU, DM_CRYPT_NO_OFFLOAD };
+ 
+ /*
+  * The fields in here must be read only after initialization.
+@@ -1207,18 +1206,20 @@ continue_locked:
+ 		if (!RB_EMPTY_ROOT(&cc->write_tree))
+ 			goto pop_from_list;
+ 
+-		if (unlikely(test_bit(DM_CRYPT_EXIT_THREAD, &cc->flags))) {
+-			spin_unlock_irq(&cc->write_thread_wait.lock);
+-			break;
+-		}
+-
+-		__set_current_state(TASK_INTERRUPTIBLE);
++		set_current_state(TASK_INTERRUPTIBLE);
+ 		__add_wait_queue(&cc->write_thread_wait, &wait);
+ 
+ 		spin_unlock_irq(&cc->write_thread_wait.lock);
+ 
++		if (unlikely(kthread_should_stop())) {
++			set_task_state(current, TASK_RUNNING);
++			remove_wait_queue(&cc->write_thread_wait, &wait);
++			break;
++		}
++
+ 		schedule();
+ 
++		set_task_state(current, TASK_RUNNING);
+ 		spin_lock_irq(&cc->write_thread_wait.lock);
+ 		__remove_wait_queue(&cc->write_thread_wait, &wait);
+ 		goto continue_locked;
+@@ -1533,13 +1534,8 @@ static void crypt_dtr(struct dm_target *ti)
+ 	if (!cc)
+ 		return;
+ 
+-	if (cc->write_thread) {
+-		spin_lock_irq(&cc->write_thread_wait.lock);
+-		set_bit(DM_CRYPT_EXIT_THREAD, &cc->flags);
+-		wake_up_locked(&cc->write_thread_wait);
+-		spin_unlock_irq(&cc->write_thread_wait.lock);
++	if (cc->write_thread)
+ 		kthread_stop(cc->write_thread);
+-	}
+ 
+ 	if (cc->io_queue)
+ 		destroy_workqueue(cc->io_queue);
+diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c
+index ac734e5bbe48..15db5e9c572e 100644
+--- a/drivers/md/dm-mpath.c
++++ b/drivers/md/dm-mpath.c
+@@ -1521,10 +1521,10 @@ static void activate_path(struct work_struct *work)
+ {
+ 	struct pgpath *pgpath =
+ 		container_of(work, struct pgpath, activate_path.work);
++	struct request_queue *q = bdev_get_queue(pgpath->path.dev->bdev);
+ 
+-	if (pgpath->is_active)
+-		scsi_dh_activate(bdev_get_queue(pgpath->path.dev->bdev),
+-				 pg_init_done, pgpath);
++	if (pgpath->is_active && !blk_queue_dying(q))
++		scsi_dh_activate(q, pg_init_done, pgpath);
+ 	else
+ 		pg_init_done(pgpath, SCSI_DH_DEV_OFFLINED);
+ }
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 1ca7463e8bb2..5da86c8b6545 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -73,15 +73,24 @@ static void dm_old_start_queue(struct request_queue *q)
+ 	spin_unlock_irqrestore(q->queue_lock, flags);
+ }
+ 
++static void dm_mq_start_queue(struct request_queue *q)
++{
++	unsigned long flags;
++
++	spin_lock_irqsave(q->queue_lock, flags);
++	queue_flag_clear(QUEUE_FLAG_STOPPED, q);
++	spin_unlock_irqrestore(q->queue_lock, flags);
++
++	blk_mq_start_stopped_hw_queues(q, true);
++	blk_mq_kick_requeue_list(q);
++}
++
+ void dm_start_queue(struct request_queue *q)
+ {
+ 	if (!q->mq_ops)
+ 		dm_old_start_queue(q);
+-	else {
+-		queue_flag_clear_unlocked(QUEUE_FLAG_STOPPED, q);
+-		blk_mq_start_stopped_hw_queues(q, true);
+-		blk_mq_kick_requeue_list(q);
+-	}
++	else
++		dm_mq_start_queue(q);
+ }
+ 
+ static void dm_old_stop_queue(struct request_queue *q)
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index fa9b1cb4438a..0f2928b3136b 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1873,6 +1873,7 @@ EXPORT_SYMBOL_GPL(dm_device_name);
+ 
+ static void __dm_destroy(struct mapped_device *md, bool wait)
+ {
++	struct request_queue *q = dm_get_md_queue(md);
+ 	struct dm_table *map;
+ 	int srcu_idx;
+ 
+@@ -1883,6 +1884,10 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
+ 	set_bit(DMF_FREEING, &md->flags);
+ 	spin_unlock(&_minor_lock);
+ 
++	spin_lock_irq(q->queue_lock);
++	queue_flag_set(QUEUE_FLAG_DYING, q);
++	spin_unlock_irq(q->queue_lock);
++
+ 	if (dm_request_based(md) && md->kworker_task)
+ 		flush_kthread_worker(&md->kworker);
+ 
+@@ -2249,10 +2254,11 @@ static int __dm_resume(struct mapped_device *md, struct dm_table *map)
+ 
+ int dm_resume(struct mapped_device *md)
+ {
+-	int r = -EINVAL;
++	int r;
+ 	struct dm_table *map = NULL;
+ 
+ retry:
++	r = -EINVAL;
+ 	mutex_lock_nested(&md->suspend_lock, SINGLE_DEPTH_NESTING);
+ 
+ 	if (!dm_suspended_md(md))
+@@ -2276,8 +2282,6 @@ retry:
+ 		goto out;
+ 
+ 	clear_bit(DMF_SUSPENDED, &md->flags);
+-
+-	r = 0;
+ out:
+ 	mutex_unlock(&md->suspend_lock);
+ 
+diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c
+index 41325328a22e..fe79358b035e 100644
+--- a/drivers/media/dvb-frontends/mb86a20s.c
++++ b/drivers/media/dvb-frontends/mb86a20s.c
+@@ -71,25 +71,27 @@ static struct regdata mb86a20s_init1[] = {
+ };
+ 
+ static struct regdata mb86a20s_init2[] = {
+-	{ 0x28, 0x22 }, { 0x29, 0x00 }, { 0x2a, 0x1f }, { 0x2b, 0xf0 },
++	{ 0x50, 0xd1 }, { 0x51, 0x22 },
++	{ 0x39, 0x01 },
++	{ 0x71, 0x00 },
+ 	{ 0x3b, 0x21 },
+-	{ 0x3c, 0x38 },
++	{ 0x3c, 0x3a },
+ 	{ 0x01, 0x0d },
+-	{ 0x04, 0x08 }, { 0x05, 0x03 },
++	{ 0x04, 0x08 }, { 0x05, 0x05 },
+ 	{ 0x04, 0x0e }, { 0x05, 0x00 },
+-	{ 0x04, 0x0f }, { 0x05, 0x37 },
+-	{ 0x04, 0x0b }, { 0x05, 0x78 },
++	{ 0x04, 0x0f }, { 0x05, 0x14 },
++	{ 0x04, 0x0b }, { 0x05, 0x8c },
+ 	{ 0x04, 0x00 }, { 0x05, 0x00 },
+-	{ 0x04, 0x01 }, { 0x05, 0x1e },
+-	{ 0x04, 0x02 }, { 0x05, 0x07 },
+-	{ 0x04, 0x03 }, { 0x05, 0xd0 },
++	{ 0x04, 0x01 }, { 0x05, 0x07 },
++	{ 0x04, 0x02 }, { 0x05, 0x0f },
++	{ 0x04, 0x03 }, { 0x05, 0xa0 },
+ 	{ 0x04, 0x09 }, { 0x05, 0x00 },
+ 	{ 0x04, 0x0a }, { 0x05, 0xff },
+-	{ 0x04, 0x27 }, { 0x05, 0x00 },
++	{ 0x04, 0x27 }, { 0x05, 0x64 },
+ 	{ 0x04, 0x28 }, { 0x05, 0x00 },
+-	{ 0x04, 0x1e }, { 0x05, 0x00 },
+-	{ 0x04, 0x29 }, { 0x05, 0x64 },
+-	{ 0x04, 0x32 }, { 0x05, 0x02 },
++	{ 0x04, 0x1e }, { 0x05, 0xff },
++	{ 0x04, 0x29 }, { 0x05, 0x0a },
++	{ 0x04, 0x32 }, { 0x05, 0x0a },
+ 	{ 0x04, 0x14 }, { 0x05, 0x02 },
+ 	{ 0x04, 0x04 }, { 0x05, 0x00 },
+ 	{ 0x04, 0x05 }, { 0x05, 0x22 },
+@@ -97,8 +99,6 @@ static struct regdata mb86a20s_init2[] = {
+ 	{ 0x04, 0x07 }, { 0x05, 0xd8 },
+ 	{ 0x04, 0x12 }, { 0x05, 0x00 },
+ 	{ 0x04, 0x13 }, { 0x05, 0xff },
+-	{ 0x04, 0x15 }, { 0x05, 0x4e },
+-	{ 0x04, 0x16 }, { 0x05, 0x20 },
+ 
+ 	/*
+ 	 * On this demod, when the bit count reaches the count below,
+@@ -152,42 +152,36 @@ static struct regdata mb86a20s_init2[] = {
+ 	{ 0x50, 0x51 }, { 0x51, 0x04 },		/* MER symbol 4 */
+ 	{ 0x45, 0x04 },				/* CN symbol 4 */
+ 	{ 0x48, 0x04 },				/* CN manual mode */
+-
++	{ 0x50, 0xd5 }, { 0x51, 0x01 },
+ 	{ 0x50, 0xd6 }, { 0x51, 0x1f },
+ 	{ 0x50, 0xd2 }, { 0x51, 0x03 },
+-	{ 0x50, 0xd7 }, { 0x51, 0xbf },
+-	{ 0x28, 0x74 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xff },
+-	{ 0x28, 0x46 }, { 0x29, 0x00 }, { 0x2a, 0x1a }, { 0x2b, 0x0c },
+-
+-	{ 0x04, 0x40 }, { 0x05, 0x00 },
+-	{ 0x28, 0x00 }, { 0x2b, 0x08 },
+-	{ 0x28, 0x05 }, { 0x2b, 0x00 },
++	{ 0x50, 0xd7 }, { 0x51, 0x3f },
+ 	{ 0x1c, 0x01 },
+-	{ 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x1f },
+-	{ 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x18 },
+-	{ 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x12 },
+-	{ 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x30 },
+-	{ 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x37 },
+-	{ 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
+-	{ 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x09 },
+-	{ 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x06 },
+-	{ 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7b },
+-	{ 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x76 },
+-	{ 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x7d },
+-	{ 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x08 },
+-	{ 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0b },
+-	{ 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
+-	{ 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf2 },
+-	{ 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xf3 },
+-	{ 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x05 },
+-	{ 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
+-	{ 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
+-	{ 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xef },
+-	{ 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xd8 },
+-	{ 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xf1 },
+-	{ 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x3d },
+-	{ 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x94 },
+-	{ 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0xba },
++	{ 0x28, 0x06 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x03 },
++	{ 0x28, 0x07 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0d },
++	{ 0x28, 0x08 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x02 },
++	{ 0x28, 0x09 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x01 },
++	{ 0x28, 0x0a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x21 },
++	{ 0x28, 0x0b }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x29 },
++	{ 0x28, 0x0c }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x16 },
++	{ 0x28, 0x0d }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x31 },
++	{ 0x28, 0x0e }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0e },
++	{ 0x28, 0x0f }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x4e },
++	{ 0x28, 0x10 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x46 },
++	{ 0x28, 0x11 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x0f },
++	{ 0x28, 0x12 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x56 },
++	{ 0x28, 0x13 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x35 },
++	{ 0x28, 0x14 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbe },
++	{ 0x28, 0x15 }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0x84 },
++	{ 0x28, 0x16 }, { 0x29, 0x00 }, { 0x2a, 0x03 }, { 0x2b, 0xee },
++	{ 0x28, 0x17 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x98 },
++	{ 0x28, 0x18 }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x9f },
++	{ 0x28, 0x19 }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0xb2 },
++	{ 0x28, 0x1a }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0xc2 },
++	{ 0x28, 0x1b }, { 0x29, 0x00 }, { 0x2a, 0x07 }, { 0x2b, 0x4a },
++	{ 0x28, 0x1c }, { 0x29, 0x00 }, { 0x2a, 0x01 }, { 0x2b, 0xbc },
++	{ 0x28, 0x1d }, { 0x29, 0x00 }, { 0x2a, 0x04 }, { 0x2b, 0xba },
++	{ 0x28, 0x1e }, { 0x29, 0x00 }, { 0x2a, 0x06 }, { 0x2b, 0x14 },
+ 	{ 0x50, 0x1e }, { 0x51, 0x5d },
+ 	{ 0x50, 0x22 }, { 0x51, 0x00 },
+ 	{ 0x50, 0x23 }, { 0x51, 0xc8 },
+@@ -196,9 +190,7 @@ static struct regdata mb86a20s_init2[] = {
+ 	{ 0x50, 0x26 }, { 0x51, 0x00 },
+ 	{ 0x50, 0x27 }, { 0x51, 0xc3 },
+ 	{ 0x50, 0x39 }, { 0x51, 0x02 },
+-	{ 0xec, 0x0f },
+-	{ 0xeb, 0x1f },
+-	{ 0x28, 0x6a }, { 0x29, 0x00 }, { 0x2a, 0x00 }, { 0x2b, 0x00 },
++	{ 0x50, 0xd5 }, { 0x51, 0x01 },
+ 	{ 0xd0, 0x00 },
+ };
+ 
+@@ -318,7 +310,11 @@ static int mb86a20s_read_status(struct dvb_frontend *fe, enum fe_status *status)
+ 	if (val >= 7)
+ 		*status |= FE_HAS_SYNC;
+ 
+-	if (val >= 8)				/* Maybe 9? */
++	/*
++	 * Actually, on state S8, it starts receiving TS, but the TS
++	 * output is only on normal state after the transition to S9.
++	 */
++	if (val >= 9)
+ 		*status |= FE_HAS_LOCK;
+ 
+ 	dev_dbg(&state->i2c->dev, "%s: Status = 0x%02x (state = %d)\n",
+@@ -2058,6 +2054,11 @@ static void mb86a20s_release(struct dvb_frontend *fe)
+ 	kfree(state);
+ }
+ 
++static int mb86a20s_get_frontend_algo(struct dvb_frontend *fe)
++{
++        return DVBFE_ALGO_HW;
++}
++
+ static struct dvb_frontend_ops mb86a20s_ops;
+ 
+ struct dvb_frontend *mb86a20s_attach(const struct mb86a20s_config *config,
+@@ -2130,6 +2131,7 @@ static struct dvb_frontend_ops mb86a20s_ops = {
+ 	.read_status = mb86a20s_read_status_and_stats,
+ 	.read_signal_strength = mb86a20s_read_signal_strength_from_cache,
+ 	.tune = mb86a20s_tune,
++	.get_frontend_algo = mb86a20s_get_frontend_algo,
+ };
+ 
+ MODULE_DESCRIPTION("DVB Frontend module for Fujitsu mb86A20s hardware");
+diff --git a/drivers/media/usb/cx231xx/cx231xx-avcore.c b/drivers/media/usb/cx231xx/cx231xx-avcore.c
+index 491913778bcc..2f52d66b4dae 100644
+--- a/drivers/media/usb/cx231xx/cx231xx-avcore.c
++++ b/drivers/media/usb/cx231xx/cx231xx-avcore.c
+@@ -1264,7 +1264,10 @@ int cx231xx_set_agc_analog_digital_mux_select(struct cx231xx *dev,
+ 				   dev->board.agc_analog_digital_select_gpio,
+ 				   analog_or_digital);
+ 
+-	return status;
++	if (status < 0)
++		return status;
++
++	return 0;
+ }
+ 
+ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
+diff --git a/drivers/media/usb/cx231xx/cx231xx-cards.c b/drivers/media/usb/cx231xx/cx231xx-cards.c
+index c63248a18823..72c246bfaa1c 100644
+--- a/drivers/media/usb/cx231xx/cx231xx-cards.c
++++ b/drivers/media/usb/cx231xx/cx231xx-cards.c
+@@ -486,7 +486,7 @@ struct cx231xx_board cx231xx_boards[] = {
+ 		.output_mode = OUT_MODE_VIP11,
+ 		.demod_xfer_mode = 0,
+ 		.ctl_pin_status_mask = 0xFFFFFFC4,
+-		.agc_analog_digital_select_gpio = 0x00,	/* According with PV cxPolaris.inf file */
++		.agc_analog_digital_select_gpio = 0x1c,
+ 		.tuner_sif_gpio = -1,
+ 		.tuner_scl_gpio = -1,
+ 		.tuner_sda_gpio = -1,
+diff --git a/drivers/media/usb/cx231xx/cx231xx-core.c b/drivers/media/usb/cx231xx/cx231xx-core.c
+index 630f4fc5155f..ea9a99e41581 100644
+--- a/drivers/media/usb/cx231xx/cx231xx-core.c
++++ b/drivers/media/usb/cx231xx/cx231xx-core.c
+@@ -712,6 +712,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
+ 			break;
+ 		case CX231XX_BOARD_CNXT_RDE_253S:
+ 		case CX231XX_BOARD_CNXT_RDU_253S:
++		case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+ 			errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 1);
+ 			break;
+ 		case CX231XX_BOARD_HAUPPAUGE_EXETER:
+@@ -738,7 +739,7 @@ int cx231xx_set_mode(struct cx231xx *dev, enum cx231xx_mode set_mode)
+ 		case CX231XX_BOARD_PV_PLAYTV_USB_HYBRID:
+ 		case CX231XX_BOARD_HAUPPAUGE_USB2_FM_PAL:
+ 		case CX231XX_BOARD_HAUPPAUGE_USB2_FM_NTSC:
+-		errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
++			errCode = cx231xx_set_agc_analog_digital_mux_select(dev, 0);
+ 			break;
+ 		default:
+ 			break;
+@@ -1301,15 +1302,29 @@ int cx231xx_dev_init(struct cx231xx *dev)
+ 	dev->i2c_bus[2].i2c_reserve = 0;
+ 
+ 	/* register I2C buses */
+-	cx231xx_i2c_register(&dev->i2c_bus[0]);
+-	cx231xx_i2c_register(&dev->i2c_bus[1]);
+-	cx231xx_i2c_register(&dev->i2c_bus[2]);
++	errCode = cx231xx_i2c_register(&dev->i2c_bus[0]);
++	if (errCode < 0)
++		return errCode;
++	errCode = cx231xx_i2c_register(&dev->i2c_bus[1]);
++	if (errCode < 0)
++		return errCode;
++	errCode = cx231xx_i2c_register(&dev->i2c_bus[2]);
++	if (errCode < 0)
++		return errCode;
+ 
+ 	errCode = cx231xx_i2c_mux_create(dev);
++	if (errCode < 0) {
++		dev_err(dev->dev,
++			"%s: Failed to create I2C mux\n", __func__);
++		return errCode;
++	}
++	errCode = cx231xx_i2c_mux_register(dev, 0);
++	if (errCode < 0)
++		return errCode;
++
++	errCode = cx231xx_i2c_mux_register(dev, 1);
+ 	if (errCode < 0)
+ 		return errCode;
+-	cx231xx_i2c_mux_register(dev, 0);
+-	cx231xx_i2c_mux_register(dev, 1);
+ 
+ 	/* scan the real bus segments in the order of physical port numbers */
+ 	cx231xx_do_i2c_scan(dev, I2C_0);
+diff --git a/drivers/memstick/host/rtsx_usb_ms.c b/drivers/memstick/host/rtsx_usb_ms.c
+index d34bc3530385..2e3cf012ef48 100644
+--- a/drivers/memstick/host/rtsx_usb_ms.c
++++ b/drivers/memstick/host/rtsx_usb_ms.c
+@@ -524,6 +524,7 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work)
+ 	int rc;
+ 
+ 	if (!host->req) {
++		pm_runtime_get_sync(ms_dev(host));
+ 		do {
+ 			rc = memstick_next_req(msh, &host->req);
+ 			dev_dbg(ms_dev(host), "next req %d\n", rc);
+@@ -544,6 +545,7 @@ static void rtsx_usb_ms_handle_req(struct work_struct *work)
+ 						host->req->error);
+ 			}
+ 		} while (!rc);
++		pm_runtime_put(ms_dev(host));
+ 	}
+ 
+ }
+@@ -570,6 +572,7 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
+ 	dev_dbg(ms_dev(host), "%s: param = %d, value = %d\n",
+ 			__func__, param, value);
+ 
++	pm_runtime_get_sync(ms_dev(host));
+ 	mutex_lock(&ucr->dev_mutex);
+ 
+ 	err = rtsx_usb_card_exclusive_check(ucr, RTSX_USB_MS_CARD);
+@@ -635,6 +638,7 @@ static int rtsx_usb_ms_set_param(struct memstick_host *msh,
+ 	}
+ out:
+ 	mutex_unlock(&ucr->dev_mutex);
++	pm_runtime_put(ms_dev(host));
+ 
+ 	/* power-on delay */
+ 	if (param == MEMSTICK_POWER && value == MEMSTICK_POWER_ON)
+@@ -681,6 +685,7 @@ static int rtsx_usb_detect_ms_card(void *__host)
+ 	int err;
+ 
+ 	for (;;) {
++		pm_runtime_get_sync(ms_dev(host));
+ 		mutex_lock(&ucr->dev_mutex);
+ 
+ 		/* Check pending MS card changes */
+@@ -703,6 +708,7 @@ static int rtsx_usb_detect_ms_card(void *__host)
+ 		}
+ 
+ poll_again:
++		pm_runtime_put(ms_dev(host));
+ 		if (host->eject)
+ 			break;
+ 
+diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
+index f3d34b941f85..af23d7dfe752 100644
+--- a/drivers/misc/cxl/api.c
++++ b/drivers/misc/cxl/api.c
+@@ -229,6 +229,14 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
+ 	if (ctx->status == STARTED)
+ 		goto out; /* already started */
+ 
++	/*
++	 * Increment the mapped context count for adapter. This also checks
++	 * if adapter_context_lock is taken.
++	 */
++	rc = cxl_adapter_context_get(ctx->afu->adapter);
++	if (rc)
++		goto out;
++
+ 	if (task) {
+ 		ctx->pid = get_task_pid(task, PIDTYPE_PID);
+ 		ctx->glpid = get_task_pid(task->group_leader, PIDTYPE_PID);
+@@ -240,6 +248,7 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
+ 
+ 	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
+ 		put_pid(ctx->pid);
++		cxl_adapter_context_put(ctx->afu->adapter);
+ 		cxl_ctx_put();
+ 		goto out;
+ 	}
+diff --git a/drivers/misc/cxl/context.c b/drivers/misc/cxl/context.c
+index c466ee2b0c97..5e506c19108a 100644
+--- a/drivers/misc/cxl/context.c
++++ b/drivers/misc/cxl/context.c
+@@ -238,6 +238,9 @@ int __detach_context(struct cxl_context *ctx)
+ 	put_pid(ctx->glpid);
+ 
+ 	cxl_ctx_put();
++
++	/* Decrease the attached context count on the adapter */
++	cxl_adapter_context_put(ctx->afu->adapter);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/misc/cxl/cxl.h b/drivers/misc/cxl/cxl.h
+index 344a0ff8f8c7..19aa2aca9683 100644
+--- a/drivers/misc/cxl/cxl.h
++++ b/drivers/misc/cxl/cxl.h
+@@ -615,6 +615,14 @@ struct cxl {
+ 	bool perst_select_user;
+ 	bool perst_same_image;
+ 	bool psl_timebase_synced;
++
++	/*
++	 * number of contexts mapped on to this card. Possible values are:
++	 * >0: Number of contexts mapped and new one can be mapped.
++	 *  0: No active contexts and new ones can be mapped.
++	 * -1: No contexts mapped and new ones cannot be mapped.
++	 */
++	atomic_t contexts_num;
+ };
+ 
+ int cxl_pci_alloc_one_irq(struct cxl *adapter);
+@@ -940,4 +948,20 @@ bool cxl_pci_is_vphb_device(struct pci_dev *dev);
+ 
+ /* decode AFU error bits in the PSL register PSL_SERR_An */
+ void cxl_afu_decode_psl_serr(struct cxl_afu *afu, u64 serr);
++
++/*
++ * Increments the number of attached contexts on an adapter.
++ * In case an adapter_context_lock is taken the return -EBUSY.
++ */
++int cxl_adapter_context_get(struct cxl *adapter);
++
++/* Decrements the number of attached contexts on an adapter */
++void cxl_adapter_context_put(struct cxl *adapter);
++
++/* If no active contexts then prevents contexts from being attached */
++int cxl_adapter_context_lock(struct cxl *adapter);
++
++/* Unlock the contexts-lock if taken. Warn and force unlock otherwise */
++void cxl_adapter_context_unlock(struct cxl *adapter);
++
+ #endif
+diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
+index 5fb9894b157f..d0b421f49b39 100644
+--- a/drivers/misc/cxl/file.c
++++ b/drivers/misc/cxl/file.c
+@@ -205,11 +205,22 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
+ 	ctx->pid = get_task_pid(current, PIDTYPE_PID);
+ 	ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
+ 
++	/*
++	 * Increment the mapped context count for adapter. This also checks
++	 * if adapter_context_lock is taken.
++	 */
++	rc = cxl_adapter_context_get(ctx->afu->adapter);
++	if (rc) {
++		afu_release_irqs(ctx, ctx);
++		goto out;
++	}
++
+ 	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
+ 
+ 	if ((rc = cxl_ops->attach_process(ctx, false, work.work_element_descriptor,
+ 							amr))) {
+ 		afu_release_irqs(ctx, ctx);
++		cxl_adapter_context_put(ctx->afu->adapter);
+ 		goto out;
+ 	}
+ 
+diff --git a/drivers/misc/cxl/guest.c b/drivers/misc/cxl/guest.c
+index 9aa58a77a24d..3e102cd6ed91 100644
+--- a/drivers/misc/cxl/guest.c
++++ b/drivers/misc/cxl/guest.c
+@@ -1152,6 +1152,9 @@ struct cxl *cxl_guest_init_adapter(struct device_node *np, struct platform_devic
+ 	if ((rc = cxl_sysfs_adapter_add(adapter)))
+ 		goto err_put1;
+ 
++	/* release the context lock as the adapter is configured */
++	cxl_adapter_context_unlock(adapter);
++
+ 	return adapter;
+ 
+ err_put1:
+diff --git a/drivers/misc/cxl/main.c b/drivers/misc/cxl/main.c
+index d9be23b24aa3..62e0dfb5f15b 100644
+--- a/drivers/misc/cxl/main.c
++++ b/drivers/misc/cxl/main.c
+@@ -243,8 +243,10 @@ struct cxl *cxl_alloc_adapter(void)
+ 	if (dev_set_name(&adapter->dev, "card%i", adapter->adapter_num))
+ 		goto err2;
+ 
+-	return adapter;
++	/* start with context lock taken */
++	atomic_set(&adapter->contexts_num, -1);
+ 
++	return adapter;
+ err2:
+ 	cxl_remove_adapter_nr(adapter);
+ err1:
+@@ -286,6 +288,44 @@ int cxl_afu_select_best_mode(struct cxl_afu *afu)
+ 	return 0;
+ }
+ 
++int cxl_adapter_context_get(struct cxl *adapter)
++{
++	int rc;
++
++	rc = atomic_inc_unless_negative(&adapter->contexts_num);
++	return rc >= 0 ? 0 : -EBUSY;
++}
++
++void cxl_adapter_context_put(struct cxl *adapter)
++{
++	atomic_dec_if_positive(&adapter->contexts_num);
++}
++
++int cxl_adapter_context_lock(struct cxl *adapter)
++{
++	int rc;
++	/* no active contexts -> contexts_num == 0 */
++	rc = atomic_cmpxchg(&adapter->contexts_num, 0, -1);
++	return rc ? -EBUSY : 0;
++}
++
++void cxl_adapter_context_unlock(struct cxl *adapter)
++{
++	int val = atomic_cmpxchg(&adapter->contexts_num, -1, 0);
++
++	/*
++	 * contexts lock taken -> contexts_num == -1
++	 * If not true then show a warning and force reset the lock.
++	 * This will happen when context_unlock was requested without
++	 * doing a context_lock.
++	 */
++	if (val != -1) {
++		atomic_set(&adapter->contexts_num, 0);
++		WARN(1, "Adapter context unlocked with %d active contexts",
++		     val);
++	}
++}
++
+ static int __init init_cxl(void)
+ {
+ 	int rc = 0;
+diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
+index 6f0c4ac4b649..8ad4e4f6ff77 100644
+--- a/drivers/misc/cxl/pci.c
++++ b/drivers/misc/cxl/pci.c
+@@ -1484,6 +1484,8 @@ static int cxl_configure_adapter(struct cxl *adapter, struct pci_dev *dev)
+ 	if ((rc = cxl_native_register_psl_err_irq(adapter)))
+ 		goto err;
+ 
++	/* Release the context lock as adapter is configured */
++	cxl_adapter_context_unlock(adapter);
+ 	return 0;
+ 
+ err:
+diff --git a/drivers/misc/cxl/sysfs.c b/drivers/misc/cxl/sysfs.c
+index b043c20f158f..a8b6d6a635e9 100644
+--- a/drivers/misc/cxl/sysfs.c
++++ b/drivers/misc/cxl/sysfs.c
+@@ -75,12 +75,31 @@ static ssize_t reset_adapter_store(struct device *device,
+ 	int val;
+ 
+ 	rc = sscanf(buf, "%i", &val);
+-	if ((rc != 1) || (val != 1))
++	if ((rc != 1) || (val != 1 && val != -1))
+ 		return -EINVAL;
+ 
+-	if ((rc = cxl_ops->adapter_reset(adapter)))
+-		return rc;
+-	return count;
++	/*
++	 * See if we can lock the context mapping that's only allowed
++	 * when there are no contexts attached to the adapter. Once
++	 * taken this will also prevent any context from getting activated.
++	 */
++	if (val == 1) {
++		rc =  cxl_adapter_context_lock(adapter);
++		if (rc)
++			goto out;
++
++		rc = cxl_ops->adapter_reset(adapter);
++		/* In case reset failed release context lock */
++		if (rc)
++			cxl_adapter_context_unlock(adapter);
++
++	} else if (val == -1) {
++		/* Perform a forced adapter reset */
++		rc = cxl_ops->adapter_reset(adapter);
++	}
++
++out:
++	return rc ? rc : count;
+ }
+ 
+ static ssize_t load_image_on_perst_show(struct device *device,
+diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
+index fd9271bc1a11..cd01e342bc78 100644
+--- a/drivers/misc/mei/amthif.c
++++ b/drivers/misc/mei/amthif.c
+@@ -139,7 +139,7 @@ int mei_amthif_read(struct mei_device *dev, struct file *file,
+ 			return -ERESTARTSYS;
+ 
+ 		if (!mei_cl_is_connected(cl)) {
+-			rets = -EBUSY;
++			rets = -ENODEV;
+ 			goto out;
+ 		}
+ 
+diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
+index e094df3cf2d5..5b5b2e07e99e 100644
+--- a/drivers/misc/mei/bus.c
++++ b/drivers/misc/mei/bus.c
+@@ -142,7 +142,7 @@ ssize_t __mei_cl_recv(struct mei_cl *cl, u8 *buf, size_t length)
+ 		mutex_lock(&bus->device_lock);
+ 
+ 		if (!mei_cl_is_connected(cl)) {
+-			rets = -EBUSY;
++			rets = -ENODEV;
+ 			goto out;
+ 		}
+ 	}
+diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
+index 0dcb854b4bfc..7ad15d678878 100644
+--- a/drivers/misc/mei/hw-me-regs.h
++++ b/drivers/misc/mei/hw-me-regs.h
+@@ -125,6 +125,9 @@
+ #define MEI_DEV_ID_BXT_M      0x1A9A  /* Broxton M */
+ #define MEI_DEV_ID_APL_I      0x5A9A  /* Apollo Lake I */
+ 
++#define MEI_DEV_ID_KBP        0xA2BA  /* Kaby Point */
++#define MEI_DEV_ID_KBP_2      0xA2BB  /* Kaby Point 2 */
++
+ /*
+  * MEI HW Section
+  */
+diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
+index 52635b063873..080208dc5516 100644
+--- a/drivers/misc/mei/main.c
++++ b/drivers/misc/mei/main.c
+@@ -202,7 +202,7 @@ static ssize_t mei_read(struct file *file, char __user *ubuf,
+ 
+ 		mutex_lock(&dev->device_lock);
+ 		if (!mei_cl_is_connected(cl)) {
+-			rets = -EBUSY;
++			rets = -ENODEV;
+ 			goto out;
+ 		}
+ 	}
+diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
+index 71cea9b296b2..5eb9b75ae9ec 100644
+--- a/drivers/misc/mei/pci-me.c
++++ b/drivers/misc/mei/pci-me.c
+@@ -91,6 +91,9 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)},
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)},
+ 
++	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP, mei_me_pch8_cfg)},
++	{MEI_PCI_DEVICE(MEI_DEV_ID_KBP_2, mei_me_pch8_cfg)},
++
+ 	/* required last entry */
+ 	{0, }
+ };
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index 2206d4477dbb..17891f17f39d 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -1778,7 +1778,7 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
+ 	struct mmc_blk_data *md = mq->data;
+ 	struct mmc_packed *packed = mqrq->packed;
+ 	bool do_rel_wr, do_data_tag;
+-	u32 *packed_cmd_hdr;
++	__le32 *packed_cmd_hdr;
+ 	u8 hdr_blocks;
+ 	u8 i = 1;
+ 
+@@ -2303,7 +2303,8 @@ again:
+ 	set_capacity(md->disk, size);
+ 
+ 	if (mmc_host_cmd23(card->host)) {
+-		if (mmc_card_mmc(card) ||
++		if ((mmc_card_mmc(card) &&
++		     card->csd.mmca_vsn >= CSD_SPEC_VER_3) ||
+ 		    (mmc_card_sd(card) &&
+ 		     card->scr.cmds & SD_SCR_CMD23_SUPPORT))
+ 			md->flags |= MMC_BLK_CMD23;
+diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
+index fee5e1271465..7f16709a5bd5 100644
+--- a/drivers/mmc/card/queue.h
++++ b/drivers/mmc/card/queue.h
+@@ -31,7 +31,7 @@ enum mmc_packed_type {
+ 
+ struct mmc_packed {
+ 	struct list_head	list;
+-	u32			cmd_hdr[1024];
++	__le32			cmd_hdr[1024];
+ 	unsigned int		blocks;
+ 	u8			nr_entries;
+ 	u8			retries;
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index f2d185cf8a8b..c57eb32dc075 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -1259,6 +1259,16 @@ static int mmc_select_hs400es(struct mmc_card *card)
+ 		goto out_err;
+ 	}
+ 
++	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_2V)
++		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_120);
++
++	if (err && card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400_1_8V)
++		err = __mmc_set_signal_voltage(host, MMC_SIGNAL_VOLTAGE_180);
++
++	/* If fails try again during next card power cycle */
++	if (err)
++		goto out_err;
++
+ 	err = mmc_select_bus_width(card);
+ 	if (err < 0)
+ 		goto out_err;
+diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c
+index 6c71fc9f76c7..da9f71b8deb0 100644
+--- a/drivers/mmc/host/rtsx_usb_sdmmc.c
++++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
+@@ -1138,11 +1138,6 @@ static void sdmmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
+ 	dev_dbg(sdmmc_dev(host), "%s\n", __func__);
+ 	mutex_lock(&ucr->dev_mutex);
+ 
+-	if (rtsx_usb_card_exclusive_check(ucr, RTSX_USB_SD_CARD)) {
+-		mutex_unlock(&ucr->dev_mutex);
+-		return;
+-	}
+-
+ 	sd_set_power_mode(host, ios->power_mode);
+ 	sd_set_bus_width(host, ios->bus_width);
+ 	sd_set_timing(host, ios->timing, &host->ddr_mode);
+@@ -1314,6 +1309,7 @@ static void rtsx_usb_update_led(struct work_struct *work)
+ 		container_of(work, struct rtsx_usb_sdmmc, led_work);
+ 	struct rtsx_ucr *ucr = host->ucr;
+ 
++	pm_runtime_get_sync(sdmmc_dev(host));
+ 	mutex_lock(&ucr->dev_mutex);
+ 
+ 	if (host->led.brightness == LED_OFF)
+@@ -1322,6 +1318,7 @@ static void rtsx_usb_update_led(struct work_struct *work)
+ 		rtsx_usb_turn_on_led(ucr);
+ 
+ 	mutex_unlock(&ucr->dev_mutex);
++	pm_runtime_put(sdmmc_dev(host));
+ }
+ #endif
+ 
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index cd65d474afa2..a8a022a7358f 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -687,7 +687,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd)
+ 			 * host->clock is in Hz.  target_timeout is in us.
+ 			 * Hence, us = 1000000 * cycles / Hz.  Round up.
+ 			 */
+-			val = 1000000 * data->timeout_clks;
++			val = 1000000ULL * data->timeout_clks;
+ 			if (do_div(val, host->clock))
+ 				target_timeout++;
+ 			target_timeout += val;
+diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c
+index f4533266d7b2..b419c7cfd014 100644
+--- a/drivers/mtd/ubi/wl.c
++++ b/drivers/mtd/ubi/wl.c
+@@ -644,7 +644,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ 				int shutdown)
+ {
+ 	int err, scrubbing = 0, torture = 0, protect = 0, erroneous = 0;
+-	int vol_id = -1, lnum = -1;
++	int erase = 0, keep = 0, vol_id = -1, lnum = -1;
+ #ifdef CONFIG_MTD_UBI_FASTMAP
+ 	int anchor = wrk->anchor;
+ #endif
+@@ -780,6 +780,16 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ 			       e1->pnum);
+ 			scrubbing = 1;
+ 			goto out_not_moved;
++		} else if (ubi->fast_attach && err == UBI_IO_BAD_HDR_EBADMSG) {
++			/*
++			 * While a full scan would detect interrupted erasures
++			 * at attach time we can face them here when attached from
++			 * Fastmap.
++			 */
++			dbg_wl("PEB %d has ECC errors, maybe from an interrupted erasure",
++			       e1->pnum);
++			erase = 1;
++			goto out_not_moved;
+ 		}
+ 
+ 		ubi_err(ubi, "error %d while reading VID header from PEB %d",
+@@ -815,6 +825,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk,
+ 			 * Target PEB had bit-flips or write error - torture it.
+ 			 */
+ 			torture = 1;
++			keep = 1;
+ 			goto out_not_moved;
+ 		}
+ 
+@@ -901,7 +912,7 @@ out_not_moved:
+ 		ubi->erroneous_peb_count += 1;
+ 	} else if (scrubbing)
+ 		wl_tree_add(e1, &ubi->scrub);
+-	else
++	else if (keep)
+ 		wl_tree_add(e1, &ubi->used);
+ 	if (dst_leb_clean) {
+ 		wl_tree_add(e2, &ubi->free);
+@@ -922,6 +933,12 @@ out_not_moved:
+ 			goto out_ro;
+ 	}
+ 
++	if (erase) {
++		err = do_sync_erase(ubi, e1, vol_id, lnum, 1);
++		if (err)
++			goto out_ro;
++	}
++
+ 	mutex_unlock(&ubi->move_mutex);
+ 	return 0;
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c
+index 9fb8d7472d18..da9998ea9271 100644
+--- a/drivers/net/wireless/ath/ath10k/ce.c
++++ b/drivers/net/wireless/ath/ath10k/ce.c
+@@ -433,6 +433,13 @@ void ath10k_ce_rx_update_write_idx(struct ath10k_ce_pipe *pipe, u32 nentries)
+ 	unsigned int nentries_mask = dest_ring->nentries_mask;
+ 	unsigned int write_index = dest_ring->write_index;
+ 	u32 ctrl_addr = pipe->ctrl_addr;
++	u32 cur_write_idx = ath10k_ce_dest_ring_write_index_get(ar, ctrl_addr);
++
++	/* Prevent CE ring stuck issue that will occur when ring is full.
++	 * Make sure that write index is 1 less than read index.
++	 */
++	if ((cur_write_idx + nentries)  == dest_ring->sw_index)
++		nentries -= 1;
+ 
+ 	write_index = CE_RING_IDX_ADD(nentries_mask, write_index, nentries);
+ 	ath10k_ce_dest_ring_write_index_set(ar, ctrl_addr, write_index);
+diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c
+index 3524441fd516..6ee6bf8e7eaf 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/regd.c
++++ b/drivers/net/wireless/realtek/rtlwifi/regd.c
+@@ -345,9 +345,9 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select(
+ 		return &rtl_regdom_no_midband;
+ 	case COUNTRY_CODE_IC:
+ 		return &rtl_regdom_11;
+-	case COUNTRY_CODE_ETSI:
+ 	case COUNTRY_CODE_TELEC_NETGEAR:
+ 		return &rtl_regdom_60_64;
++	case COUNTRY_CODE_ETSI:
+ 	case COUNTRY_CODE_SPAIN:
+ 	case COUNTRY_CODE_FRANCE:
+ 	case COUNTRY_CODE_ISRAEL:
+@@ -406,6 +406,8 @@ static u8 channel_plan_to_country_code(u8 channelplan)
+ 		return COUNTRY_CODE_WORLD_WIDE_13;
+ 	case 0x22:
+ 		return COUNTRY_CODE_IC;
++	case 0x25:
++		return COUNTRY_CODE_ETSI;
+ 	case 0x32:
+ 		return COUNTRY_CODE_TELEC_NETGEAR;
+ 	case 0x41:
+diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
+index 6de0757b11e4..84d650d892e7 100644
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -856,7 +856,7 @@ static int tegra_pcie_phy_disable(struct tegra_pcie *pcie)
+ 	/* override IDDQ */
+ 	value = pads_readl(pcie, PADS_CTL);
+ 	value |= PADS_CTL_IDDQ_1L;
+-	pads_writel(pcie, PADS_CTL, value);
++	pads_writel(pcie, value, PADS_CTL);
+ 
+ 	/* reset PLL */
+ 	value = pads_readl(pcie, soc->pads_pll_ctl);
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
+index 44e0ff37480b..4bf1a88d7ba7 100644
+--- a/drivers/pci/quirks.c
++++ b/drivers/pci/quirks.c
+@@ -3198,6 +3198,7 @@ static void quirk_no_bus_reset(struct pci_dev *dev)
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0030, quirk_no_bus_reset);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0032, quirk_no_bus_reset);
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x003c, quirk_no_bus_reset);
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATHEROS, 0x0033, quirk_no_bus_reset);
+ 
+ static void quirk_no_pm_reset(struct pci_dev *dev)
+ {
+diff --git a/drivers/pinctrl/intel/pinctrl-baytrail.c b/drivers/pinctrl/intel/pinctrl-baytrail.c
+index d22a9fe2e6df..71bbeb9321ba 100644
+--- a/drivers/pinctrl/intel/pinctrl-baytrail.c
++++ b/drivers/pinctrl/intel/pinctrl-baytrail.c
+@@ -1808,6 +1808,8 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
+ 		return PTR_ERR(vg->pctl_dev);
+ 	}
+ 
++	raw_spin_lock_init(&vg->lock);
++
+ 	ret = byt_gpio_probe(vg);
+ 	if (ret) {
+ 		pinctrl_unregister(vg->pctl_dev);
+@@ -1815,7 +1817,6 @@ static int byt_pinctrl_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	platform_set_drvdata(pdev, vg);
+-	raw_spin_lock_init(&vg->lock);
+ 	pm_runtime_enable(&pdev->dev);
+ 
+ 	return 0;
+diff --git a/drivers/pinctrl/intel/pinctrl-intel.c b/drivers/pinctrl/intel/pinctrl-intel.c
+index 257cab129692..2b5b20bf7d99 100644
+--- a/drivers/pinctrl/intel/pinctrl-intel.c
++++ b/drivers/pinctrl/intel/pinctrl-intel.c
+@@ -19,6 +19,7 @@
+ #include <linux/pinctrl/pinconf.h>
+ #include <linux/pinctrl/pinconf-generic.h>
+ 
++#include "../core.h"
+ #include "pinctrl-intel.h"
+ 
+ /* Offset from regs */
+@@ -1079,6 +1080,26 @@ int intel_pinctrl_remove(struct platform_device *pdev)
+ EXPORT_SYMBOL_GPL(intel_pinctrl_remove);
+ 
+ #ifdef CONFIG_PM_SLEEP
++static bool intel_pinctrl_should_save(struct intel_pinctrl *pctrl, unsigned pin)
++{
++	const struct pin_desc *pd = pin_desc_get(pctrl->pctldev, pin);
++
++	if (!pd || !intel_pad_usable(pctrl, pin))
++		return false;
++
++	/*
++	 * Only restore the pin if it is actually in use by the kernel (or
++	 * by userspace). It is possible that some pins are used by the
++	 * BIOS during resume and those are not always locked down so leave
++	 * them alone.
++	 */
++	if (pd->mux_owner || pd->gpio_owner ||
++	    gpiochip_line_is_irq(&pctrl->chip, pin))
++		return true;
++
++	return false;
++}
++
+ int intel_pinctrl_suspend(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+@@ -1092,7 +1113,7 @@ int intel_pinctrl_suspend(struct device *dev)
+ 		const struct pinctrl_pin_desc *desc = &pctrl->soc->pins[i];
+ 		u32 val;
+ 
+-		if (!intel_pad_usable(pctrl, desc->number))
++		if (!intel_pinctrl_should_save(pctrl, desc->number))
+ 			continue;
+ 
+ 		val = readl(intel_get_padcfg(pctrl, desc->number, PADCFG0));
+@@ -1153,7 +1174,7 @@ int intel_pinctrl_resume(struct device *dev)
+ 		void __iomem *padcfg;
+ 		u32 val;
+ 
+-		if (!intel_pad_usable(pctrl, desc->number))
++		if (!intel_pinctrl_should_save(pctrl, desc->number))
+ 			continue;
+ 
+ 		padcfg = intel_get_padcfg(pctrl, desc->number, PADCFG0);
+diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
+index fb991ec76423..696116ebdf50 100644
+--- a/drivers/regulator/tps65910-regulator.c
++++ b/drivers/regulator/tps65910-regulator.c
+@@ -1111,6 +1111,12 @@ static int tps65910_probe(struct platform_device *pdev)
+ 		pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
+ 		pmic->ext_sleep_control = tps65910_ext_sleep_control;
+ 		info = tps65910_regs;
++		/* Work around silicon erratum SWCZ010: output programmed
++		 * voltage level can go higher than expected or crash
++		 * Workaround: use no synchronization of DCDC clocks
++		 */
++		tps65910_reg_clear_bits(pmic->mfd, TPS65910_DCDCCTRL,
++					DCDCCTRL_DCDCCKSYNC_MASK);
+ 		break;
+ 	case TPS65911:
+ 		pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
+diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
+index 5d7fbe4e907e..581001989937 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, 2013
++ * Copyright IBM Corp. 2002, 2016
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -65,7 +65,7 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area,
+  * @tag: tag indicating which kind of unsolicited status has been received
+  * @req: request for which a response was received
+  */
+-void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
++void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
+ {
+ 	struct zfcp_dbf *dbf = req->adapter->dbf;
+ 	struct fsf_qtcb_prefix *q_pref = &req->qtcb->prefix;
+@@ -85,6 +85,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
+ 	rec->u.res.req_issued = req->issued;
+ 	rec->u.res.prot_status = q_pref->prot_status;
+ 	rec->u.res.fsf_status = q_head->fsf_status;
++	rec->u.res.port_handle = q_head->port_handle;
++	rec->u.res.lun_handle = q_head->lun_handle;
+ 
+ 	memcpy(rec->u.res.prot_status_qual, &q_pref->prot_status_qual,
+ 	       FSF_PROT_STATUS_QUAL_SIZE);
+@@ -97,7 +99,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, struct zfcp_fsf_req *req)
+ 				  rec->pl_len, "fsf_res", req->req_id);
+ 	}
+ 
+-	debug_event(dbf->hba, 1, rec, sizeof(*rec));
++	debug_event(dbf->hba, level, rec, sizeof(*rec));
+ 	spin_unlock_irqrestore(&dbf->hba_lock, flags);
+ }
+ 
+@@ -241,7 +243,8 @@ static void zfcp_dbf_set_common(struct zfcp_dbf_rec *rec,
+ 	if (sdev) {
+ 		rec->lun_status = atomic_read(&sdev_to_zfcp(sdev)->status);
+ 		rec->lun = zfcp_scsi_dev_lun(sdev);
+-	}
++	} else
++		rec->lun = ZFCP_DBF_INVALID_LUN;
+ }
+ 
+ /**
+@@ -320,13 +323,48 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
+ 	spin_unlock_irqrestore(&dbf->rec_lock, flags);
+ }
+ 
++/**
++ * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery
++ * @tag: identifier for event
++ * @wka_port: well known address port
++ * @req_id: request ID to correlate with potential HBA trace record
++ */
++void zfcp_dbf_rec_run_wka(char *tag, struct zfcp_fc_wka_port *wka_port,
++			  u64 req_id)
++{
++	struct zfcp_dbf *dbf = wka_port->adapter->dbf;
++	struct zfcp_dbf_rec *rec = &dbf->rec_buf;
++	unsigned long flags;
++
++	spin_lock_irqsave(&dbf->rec_lock, flags);
++	memset(rec, 0, sizeof(*rec));
++
++	rec->id = ZFCP_DBF_REC_RUN;
++	memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
++	rec->port_status = wka_port->status;
++	rec->d_id = wka_port->d_id;
++	rec->lun = ZFCP_DBF_INVALID_LUN;
++
++	rec->u.run.fsf_req_id = req_id;
++	rec->u.run.rec_status = ~0;
++	rec->u.run.rec_step = ~0;
++	rec->u.run.rec_action = ~0;
++	rec->u.run.rec_count = ~0;
++
++	debug_event(dbf->rec, 1, rec, sizeof(*rec));
++	spin_unlock_irqrestore(&dbf->rec_lock, flags);
++}
++
+ static inline
+-void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+-		  u64 req_id, u32 d_id)
++void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf,
++		  char *paytag, struct scatterlist *sg, u8 id, u16 len,
++		  u64 req_id, u32 d_id, u16 cap_len)
+ {
+ 	struct zfcp_dbf_san *rec = &dbf->san_buf;
+ 	u16 rec_len;
+ 	unsigned long flags;
++	struct zfcp_dbf_pay *payload = &dbf->pay_buf;
++	u16 pay_sum = 0;
+ 
+ 	spin_lock_irqsave(&dbf->san_lock, flags);
+ 	memset(rec, 0, sizeof(*rec));
+@@ -334,10 +372,41 @@ void zfcp_dbf_san(char *tag, struct zfcp_dbf *dbf, void *data, u8 id, u16 len,
+ 	rec->id = id;
+ 	rec->fsf_req_id = req_id;
+ 	rec->d_id = d_id;
+-	rec_len = min(len, (u16)ZFCP_DBF_SAN_MAX_PAYLOAD);
+-	memcpy(rec->payload, data, rec_len);
+ 	memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
++	rec->pl_len = len; /* full length even if we cap pay below */
++	if (!sg)
++		goto out;
++	rec_len = min_t(unsigned int, sg->length, ZFCP_DBF_SAN_MAX_PAYLOAD);
++	memcpy(rec->payload, sg_virt(sg), rec_len); /* part of 1st sg entry */
++	if (len <= rec_len)
++		goto out; /* skip pay record if full content in rec->payload */
++
++	/* if (len > rec_len):
++	 * dump data up to cap_len ignoring small duplicate in rec->payload
++	 */
++	spin_lock(&dbf->pay_lock);
++	memset(payload, 0, sizeof(*payload));
++	memcpy(payload->area, paytag, ZFCP_DBF_TAG_LEN);
++	payload->fsf_req_id = req_id;
++	payload->counter = 0;
++	for (; sg && pay_sum < cap_len; sg = sg_next(sg)) {
++		u16 pay_len, offset = 0;
++
++		while (offset < sg->length && pay_sum < cap_len) {
++			pay_len = min((u16)ZFCP_DBF_PAY_MAX_REC,
++				      (u16)(sg->length - offset));
++			/* cap_len <= pay_sum < cap_len+ZFCP_DBF_PAY_MAX_REC */
++			memcpy(payload->data, sg_virt(sg) + offset, pay_len);
++			debug_event(dbf->pay, 1, payload,
++				    zfcp_dbf_plen(pay_len));
++			payload->counter++;
++			offset += pay_len;
++			pay_sum += pay_len;
++		}
++	}
++	spin_unlock(&dbf->pay_lock);
+ 
++out:
+ 	debug_event(dbf->san, 1, rec, sizeof(*rec));
+ 	spin_unlock_irqrestore(&dbf->san_lock, flags);
+ }
+@@ -354,9 +423,62 @@ void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
+ 	struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ 	u16 length;
+ 
+-	length = (u16)(ct_els->req->length + FC_CT_HDR_LEN);
+-	zfcp_dbf_san(tag, dbf, sg_virt(ct_els->req), ZFCP_DBF_SAN_REQ, length,
+-		     fsf->req_id, d_id);
++	length = (u16)zfcp_qdio_real_bytes(ct_els->req);
++	zfcp_dbf_san(tag, dbf, "san_req", ct_els->req, ZFCP_DBF_SAN_REQ,
++		     length, fsf->req_id, d_id, length);
++}
++
++static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag,
++					      struct zfcp_fsf_req *fsf,
++					      u16 len)
++{
++	struct zfcp_fsf_ct_els *ct_els = fsf->data;
++	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_gpn_ft_resp *acc;
++	int max_entries, x, last = 0;
++
++	if (!(memcmp(tag, "fsscth2", 7) == 0
++	      && ct_els->d_id == FC_FID_DIR_SERV
++	      && reqh->ct_rev == FC_CT_REV
++	      && reqh->ct_in_id[0] == 0
++	      && reqh->ct_in_id[1] == 0
++	      && reqh->ct_in_id[2] == 0
++	      && reqh->ct_fs_type == FC_FST_DIR
++	      && reqh->ct_fs_subtype == FC_NS_SUBTYPE
++	      && reqh->ct_options == 0
++	      && reqh->_ct_resvd1 == 0
++	      && reqh->ct_cmd == FC_NS_GPN_FT
++	      /* reqh->ct_mr_size can vary so do not match but read below */
++	      && reqh->_ct_resvd2 == 0
++	      && reqh->ct_reason == 0
++	      && reqh->ct_explan == 0
++	      && reqh->ct_vendor == 0
++	      && reqn->fn_resvd == 0
++	      && reqn->fn_domain_id_scope == 0
++	      && reqn->fn_area_id_scope == 0
++	      && reqn->fn_fc4_type == FC_TYPE_FCP))
++		return len; /* not GPN_FT response so do not cap */
++
++	acc = sg_virt(resp_entry);
++	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" */;
++
++	/* the basic CT_IU preamble is the same size as one entry in the GPN_FT
++	 * response, allowing us to skip special handling for it - just skip it
++	 */
++	for (x = 1; x < max_entries && !last; x++) {
++		if (x % (ZFCP_FC_GPN_FT_ENT_PAGE + 1))
++			acc++;
++		else
++			acc = sg_virt(++resp_entry);
++
++		last = acc->fp_flags & FC_NS_FID_LAST;
++	}
++	len = min(len, (u16)(x * sizeof(struct fc_gpn_ft_resp)));
++	return len; /* cap after last entry */
+ }
+ 
+ /**
+@@ -370,9 +492,10 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
+ 	struct zfcp_fsf_ct_els *ct_els = fsf->data;
+ 	u16 length;
+ 
+-	length = (u16)(ct_els->resp->length + FC_CT_HDR_LEN);
+-	zfcp_dbf_san(tag, dbf, sg_virt(ct_els->resp), ZFCP_DBF_SAN_RES, length,
+-		     fsf->req_id, 0);
++	length = (u16)zfcp_qdio_real_bytes(ct_els->resp);
++	zfcp_dbf_san(tag, dbf, "san_res", ct_els->resp, ZFCP_DBF_SAN_RES,
++		     length, fsf->req_id, ct_els->d_id,
++		     zfcp_dbf_san_res_cap_len_if_gpn_ft(tag, fsf, length));
+ }
+ 
+ /**
+@@ -386,11 +509,13 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
+ 	struct fsf_status_read_buffer *srb =
+ 		(struct fsf_status_read_buffer *) fsf->data;
+ 	u16 length;
++	struct scatterlist sg;
+ 
+ 	length = (u16)(srb->length -
+ 			offsetof(struct fsf_status_read_buffer, payload));
+-	zfcp_dbf_san(tag, dbf, srb->payload.data, ZFCP_DBF_SAN_ELS, length,
+-		     fsf->req_id, ntoh24(srb->d_id));
++	sg_init_one(&sg, srb->payload.data, length);
++	zfcp_dbf_san(tag, dbf, "san_els", &sg, ZFCP_DBF_SAN_ELS, length,
++		     fsf->req_id, ntoh24(srb->d_id), length);
+ }
+ 
+ /**
+@@ -399,7 +524,8 @@ void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
+  * @sc: pointer to struct scsi_cmnd
+  * @fsf: pointer to struct zfcp_fsf_req
+  */
+-void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
++void zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *sc,
++		   struct zfcp_fsf_req *fsf)
+ {
+ 	struct zfcp_adapter *adapter =
+ 		(struct zfcp_adapter *) sc->device->host->hostdata[0];
+@@ -442,7 +568,7 @@ void zfcp_dbf_scsi(char *tag, struct scsi_cmnd *sc, struct zfcp_fsf_req *fsf)
+ 		}
+ 	}
+ 
+-	debug_event(dbf->scsi, 1, rec, sizeof(*rec));
++	debug_event(dbf->scsi, level, rec, sizeof(*rec));
+ 	spin_unlock_irqrestore(&dbf->scsi_lock, flags);
+ }
+ 
+diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
+index 0be3d48681ae..36d07584271d 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, 2010
++ * Copyright IBM Corp. 2008, 2015
+  */
+ 
+ #ifndef ZFCP_DBF_H
+@@ -17,6 +17,11 @@
+ 
+ #define ZFCP_DBF_INVALID_LUN	0xFFFFFFFFFFFFFFFFull
+ 
++enum zfcp_dbf_pseudo_erp_act_type {
++	ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD = 0xff,
++	ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL = 0xfe,
++};
++
+ /**
+  * struct zfcp_dbf_rec_trigger - trace record for triggered recovery action
+  * @ready: number of ready recovery actions
+@@ -110,6 +115,7 @@ struct zfcp_dbf_san {
+ 	u32 d_id;
+ #define ZFCP_DBF_SAN_MAX_PAYLOAD (FC_CT_HDR_LEN + 32)
+ 	char payload[ZFCP_DBF_SAN_MAX_PAYLOAD];
++	u16 pl_len;
+ } __packed;
+ 
+ /**
+@@ -126,6 +132,8 @@ struct zfcp_dbf_hba_res {
+ 	u8  prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
+ 	u32 fsf_status;
+ 	u8  fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
++	u32 port_handle;
++	u32 lun_handle;
+ } __packed;
+ 
+ /**
+@@ -279,7 +287,7 @@ static inline
+ void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
+ {
+ 	if (debug_level_enabled(req->adapter->dbf->hba, level))
+-		zfcp_dbf_hba_fsf_res(tag, req);
++		zfcp_dbf_hba_fsf_res(tag, level, req);
+ }
+ 
+ /**
+@@ -318,7 +326,7 @@ void _zfcp_dbf_scsi(char *tag, int level, struct scsi_cmnd *scmd,
+ 					scmd->device->host->hostdata[0];
+ 
+ 	if (debug_level_enabled(adapter->dbf->scsi, level))
+-		zfcp_dbf_scsi(tag, scmd, req);
++		zfcp_dbf_scsi(tag, level, scmd, req);
+ }
+ 
+ /**
+diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
+index 3fb410977014..a59d678125bd 100644
+--- a/drivers/s390/scsi/zfcp_erp.c
++++ b/drivers/s390/scsi/zfcp_erp.c
+@@ -3,7 +3,7 @@
+  *
+  * Error Recovery Procedures (ERP).
+  *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -1217,8 +1217,14 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
+ 		break;
+ 
+ 	case ZFCP_ERP_ACTION_REOPEN_PORT:
+-		if (result == ZFCP_ERP_SUCCEEDED)
+-			zfcp_scsi_schedule_rport_register(port);
++		/* This switch case might also happen after a forced reopen
++		 * was successfully done and thus overwritten with a new
++		 * non-forced reopen at `ersfs_2'. In this case, we must not
++		 * do the clean-up of the non-forced version.
++		 */
++		if (act->step != ZFCP_ERP_STEP_UNINITIALIZED)
++			if (result == ZFCP_ERP_SUCCEEDED)
++				zfcp_scsi_schedule_rport_register(port);
+ 		/* fall through */
+ 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
+ 		put_device(&port->dev);
+diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
+index 5b500652572b..c8fed9fa1cca 100644
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -3,7 +3,7 @@
+  *
+  * External function declarations.
+  *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+  */
+ 
+ #ifndef ZFCP_EXT_H
+@@ -35,8 +35,9 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
+ extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+ 			      struct zfcp_port *, struct scsi_device *, u8, u8);
+ extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
++extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64);
+ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+-extern void zfcp_dbf_hba_fsf_res(char *, struct zfcp_fsf_req *);
++extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_berr(struct zfcp_dbf *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
+@@ -44,7 +45,8 @@ extern void zfcp_dbf_hba_basic(char *, struct zfcp_adapter *);
+ extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
+ extern void zfcp_dbf_san_res(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_san_in_els(char *, struct zfcp_fsf_req *);
+-extern void zfcp_dbf_scsi(char *, struct scsi_cmnd *, struct zfcp_fsf_req *);
++extern void zfcp_dbf_scsi(char *, int, struct scsi_cmnd *,
++			  struct zfcp_fsf_req *);
+ 
+ /* zfcp_erp.c */
+ extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
+diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
+index 522a633c866a..75f820ca17b7 100644
+--- a/drivers/s390/scsi/zfcp_fsf.c
++++ b/drivers/s390/scsi/zfcp_fsf.c
+@@ -3,7 +3,7 @@
+  *
+  * Implementation of FSF commands.
+  *
+- * Copyright IBM Corp. 2002, 2013
++ * Copyright IBM Corp. 2002, 2015
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -508,7 +508,10 @@ static int zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *req)
+ 		fc_host_port_type(shost) = FC_PORTTYPE_PTP;
+ 		break;
+ 	case FSF_TOPO_FABRIC:
+-		fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
++		if (bottom->connection_features & FSF_FEATURE_NPIV_MODE)
++			fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
++		else
++			fc_host_port_type(shost) = FC_PORTTYPE_NPORT;
+ 		break;
+ 	case FSF_TOPO_AL:
+ 		fc_host_port_type(shost) = FC_PORTTYPE_NLPORT;
+@@ -613,7 +616,6 @@ static void zfcp_fsf_exchange_port_evaluate(struct zfcp_fsf_req *req)
+ 
+ 	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE) {
+ 		fc_host_permanent_port_name(shost) = bottom->wwpn;
+-		fc_host_port_type(shost) = FC_PORTTYPE_NPIV;
+ 	} else
+ 		fc_host_permanent_port_name(shost) = fc_host_port_name(shost);
+ 	fc_host_maxframe_size(shost) = bottom->maximum_frame_size;
+@@ -982,8 +984,12 @@ static int zfcp_fsf_setup_ct_els_sbals(struct zfcp_fsf_req *req,
+ 	if (zfcp_adapter_multi_buffer_active(adapter)) {
+ 		if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_req))
+ 			return -EIO;
++		qtcb->bottom.support.req_buf_length =
++			zfcp_qdio_real_bytes(sg_req);
+ 		if (zfcp_qdio_sbals_from_sg(qdio, &req->qdio_req, sg_resp))
+ 			return -EIO;
++		qtcb->bottom.support.resp_buf_length =
++			zfcp_qdio_real_bytes(sg_resp);
+ 
+ 		zfcp_qdio_set_data_div(qdio, &req->qdio_req,
+ 					zfcp_qdio_sbale_count(sg_req));
+@@ -1073,6 +1079,7 @@ int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
+ 
+ 	req->handler = zfcp_fsf_send_ct_handler;
+ 	req->qtcb->header.port_handle = wka_port->handle;
++	ct->d_id = wka_port->d_id;
+ 	req->data = ct;
+ 
+ 	zfcp_dbf_san_req("fssct_1", req, wka_port->d_id);
+@@ -1169,6 +1176,7 @@ int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
+ 
+ 	hton24(req->qtcb->bottom.support.d_id, d_id);
+ 	req->handler = zfcp_fsf_send_els_handler;
++	els->d_id = d_id;
+ 	req->data = els;
+ 
+ 	zfcp_dbf_san_req("fssels1", req, d_id);
+@@ -1575,7 +1583,7 @@ out:
+ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
+ {
+ 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
+-	struct zfcp_fsf_req *req;
++	struct zfcp_fsf_req *req = NULL;
+ 	int retval = -EIO;
+ 
+ 	spin_lock_irq(&qdio->req_q_lock);
+@@ -1604,6 +1612,8 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
+ 		zfcp_fsf_req_free(req);
+ out:
+ 	spin_unlock_irq(&qdio->req_q_lock);
++	if (req && !IS_ERR(req))
++		zfcp_dbf_rec_run_wka("fsowp_1", wka_port, req->req_id);
+ 	return retval;
+ }
+ 
+@@ -1628,7 +1638,7 @@ static void zfcp_fsf_close_wka_port_handler(struct zfcp_fsf_req *req)
+ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
+ {
+ 	struct zfcp_qdio *qdio = wka_port->adapter->qdio;
+-	struct zfcp_fsf_req *req;
++	struct zfcp_fsf_req *req = NULL;
+ 	int retval = -EIO;
+ 
+ 	spin_lock_irq(&qdio->req_q_lock);
+@@ -1657,6 +1667,8 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
+ 		zfcp_fsf_req_free(req);
+ out:
+ 	spin_unlock_irq(&qdio->req_q_lock);
++	if (req && !IS_ERR(req))
++		zfcp_dbf_rec_run_wka("fscwp_1", wka_port, req->req_id);
+ 	return retval;
+ }
+ 
+diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
+index 57ae3ae1046d..be1c04b334c5 100644
+--- a/drivers/s390/scsi/zfcp_fsf.h
++++ b/drivers/s390/scsi/zfcp_fsf.h
+@@ -3,7 +3,7 @@
+  *
+  * Interface to the FSF support functions.
+  *
+- * Copyright IBM Corp. 2002, 2010
++ * Copyright IBM Corp. 2002, 2015
+  */
+ 
+ #ifndef FSF_H
+@@ -436,6 +436,7 @@ struct zfcp_blk_drv_data {
+  * @handler_data: data passed to handler function
+  * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)
+  * @status: used to pass error status to calling function
++ * @d_id: Destination ID of either open WKA port for CT or of D_ID for ELS
+  */
+ struct zfcp_fsf_ct_els {
+ 	struct scatterlist *req;
+@@ -444,6 +445,7 @@ struct zfcp_fsf_ct_els {
+ 	void *handler_data;
+ 	struct zfcp_port *port;
+ 	int status;
++	u32 d_id;
+ };
+ 
+ #endif				/* FSF_H */
+diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
+index b3c6ff49103b..9069f98a1817 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, 2013
++ * Copyright IBM Corp. 2002, 2015
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -556,6 +556,9 @@ static void zfcp_scsi_rport_register(struct zfcp_port *port)
+ 	ids.port_id = port->d_id;
+ 	ids.roles = FC_RPORT_ROLE_FCP_TARGET;
+ 
++	zfcp_dbf_rec_trig("scpaddy", port->adapter, port, NULL,
++			  ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD,
++			  ZFCP_PSEUDO_ERP_ACTION_RPORT_ADD);
+ 	rport = fc_remote_port_add(port->adapter->scsi_host, 0, &ids);
+ 	if (!rport) {
+ 		dev_err(&port->adapter->ccw_device->dev,
+@@ -577,6 +580,9 @@ static void zfcp_scsi_rport_block(struct zfcp_port *port)
+ 	struct fc_rport *rport = port->rport;
+ 
+ 	if (rport) {
++		zfcp_dbf_rec_trig("scpdely", port->adapter, port, NULL,
++				  ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL,
++				  ZFCP_PSEUDO_ERP_ACTION_RPORT_DEL);
+ 		fc_remote_port_delete(rport);
+ 		port->rport = NULL;
+ 	}
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index e0a78f53d809..bac8cdf9fb23 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -1472,12 +1472,12 @@ retry:
+  out_err:
+ 	kfree(lun_data);
+  out:
+-	scsi_device_put(sdev);
+ 	if (scsi_device_created(sdev))
+ 		/*
+ 		 * the sdev we used didn't appear in the report luns scan
+ 		 */
+ 		__scsi_remove_device(sdev);
++	scsi_device_put(sdev);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c
+index 333eb2215a57..0aaf429f31d5 100644
+--- a/drivers/soc/fsl/qe/gpio.c
++++ b/drivers/soc/fsl/qe/gpio.c
+@@ -41,7 +41,8 @@ struct qe_gpio_chip {
+ 
+ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
+ {
+-	struct qe_gpio_chip *qe_gc = gpiochip_get_data(&mm_gc->gc);
++	struct qe_gpio_chip *qe_gc =
++		container_of(mm_gc, struct qe_gpio_chip, mm_gc);
+ 	struct qe_pio_regs __iomem *regs = mm_gc->regs;
+ 
+ 	qe_gc->cpdata = in_be32(&regs->cpdata);
+diff --git a/drivers/soc/fsl/qe/qe_common.c b/drivers/soc/fsl/qe/qe_common.c
+index 41eff805a904..104e68d9b84f 100644
+--- a/drivers/soc/fsl/qe/qe_common.c
++++ b/drivers/soc/fsl/qe/qe_common.c
+@@ -70,6 +70,11 @@ int cpm_muram_init(void)
+ 	}
+ 
+ 	muram_pool = gen_pool_create(0, -1);
++	if (!muram_pool) {
++		pr_err("Cannot allocate memory pool for CPM/QE muram");
++		ret = -ENOMEM;
++		goto out_muram;
++	}
+ 	muram_pbase = of_translate_address(np, zero);
+ 	if (muram_pbase == (phys_addr_t)OF_BAD_ADDR) {
+ 		pr_err("Cannot translate zero through CPM muram node");
+@@ -116,6 +121,9 @@ static unsigned long cpm_muram_alloc_common(unsigned long size,
+ 	struct muram_block *entry;
+ 	unsigned long start;
+ 
++	if (!muram_pool && cpm_muram_init())
++		goto out2;
++
+ 	start = gen_pool_alloc_algo(muram_pool, size, algo, data);
+ 	if (!start)
+ 		goto out2;
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 6094a6beddde..e825d580ccee 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -754,15 +754,7 @@ EXPORT_SYMBOL(target_complete_cmd);
+ 
+ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int length)
+ {
+-	if (scsi_status != SAM_STAT_GOOD) {
+-		return;
+-	}
+-
+-	/*
+-	 * Calculate new residual count based upon length of SCSI data
+-	 * transferred.
+-	 */
+-	if (length < cmd->data_length) {
++	if (scsi_status == SAM_STAT_GOOD && length < cmd->data_length) {
+ 		if (cmd->se_cmd_flags & SCF_UNDERFLOW_BIT) {
+ 			cmd->residual_count += cmd->data_length - length;
+ 		} else {
+@@ -771,12 +763,6 @@ void target_complete_cmd_with_length(struct se_cmd *cmd, u8 scsi_status, int len
+ 		}
+ 
+ 		cmd->data_length = length;
+-	} else if (length > cmd->data_length) {
+-		cmd->se_cmd_flags |= SCF_OVERFLOW_BIT;
+-		cmd->residual_count = length - cmd->data_length;
+-	} else {
+-		cmd->se_cmd_flags &= ~(SCF_OVERFLOW_BIT | SCF_UNDERFLOW_BIT);
+-		cmd->residual_count = 0;
+ 	}
+ 
+ 	target_complete_cmd(cmd, scsi_status);
+@@ -1706,6 +1692,7 @@ void transport_generic_request_failure(struct se_cmd *cmd,
+ 	case TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED:
+ 	case TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED:
+ 	case TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED:
++	case TCM_COPY_TARGET_DEVICE_NOT_REACHABLE:
+ 		break;
+ 	case TCM_OUT_OF_RESOURCES:
+ 		sense_reason = TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+@@ -2547,8 +2534,10 @@ int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
+ 	 * fabric acknowledgement that requires two target_put_sess_cmd()
+ 	 * invocations before se_cmd descriptor release.
+ 	 */
+-	if (ack_kref)
++	if (ack_kref) {
+ 		kref_get(&se_cmd->cmd_kref);
++		se_cmd->se_cmd_flags |= SCF_ACK_KREF;
++	}
+ 
+ 	spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+ 	if (se_sess->sess_tearing_down) {
+@@ -2871,6 +2860,12 @@ static const struct sense_info sense_info_table[] = {
+ 		.ascq = 0x03, /* LOGICAL BLOCK REFERENCE TAG CHECK FAILED */
+ 		.add_sector_info = true,
+ 	},
++	[TCM_COPY_TARGET_DEVICE_NOT_REACHABLE] = {
++		.key = COPY_ABORTED,
++		.asc = 0x0d,
++		.ascq = 0x02, /* COPY TARGET DEVICE NOT REACHABLE */
++
++	},
+ 	[TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE] = {
+ 		/*
+ 		 * Returning ILLEGAL REQUEST would cause immediate IO errors on
+diff --git a/drivers/target/target_core_xcopy.c b/drivers/target/target_core_xcopy.c
+index 75cd85426ae3..094a1440eacb 100644
+--- a/drivers/target/target_core_xcopy.c
++++ b/drivers/target/target_core_xcopy.c
+@@ -104,7 +104,7 @@ static int target_xcopy_locate_se_dev_e4(struct se_cmd *se_cmd, struct xcopy_op
+ 	}
+ 	mutex_unlock(&g_device_mutex);
+ 
+-	pr_err("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
++	pr_debug_ratelimited("Unable to locate 0xe4 descriptor for EXTENDED_COPY\n");
+ 	return -EINVAL;
+ }
+ 
+@@ -185,7 +185,7 @@ static int target_xcopy_parse_tiddesc_e4(struct se_cmd *se_cmd, struct xcopy_op
+ 
+ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
+ 				struct xcopy_op *xop, unsigned char *p,
+-				unsigned short tdll)
++				unsigned short tdll, sense_reason_t *sense_ret)
+ {
+ 	struct se_device *local_dev = se_cmd->se_dev;
+ 	unsigned char *desc = p;
+@@ -193,6 +193,8 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
+ 	unsigned short start = 0;
+ 	bool src = true;
+ 
++	*sense_ret = TCM_INVALID_PARAMETER_LIST;
++
+ 	if (offset != 0) {
+ 		pr_err("XCOPY target descriptor list length is not"
+ 			" multiple of %d\n", XCOPY_TARGET_DESC_LEN);
+@@ -243,9 +245,16 @@ static int target_xcopy_parse_target_descriptors(struct se_cmd *se_cmd,
+ 		rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, true);
+ 	else
+ 		rc = target_xcopy_locate_se_dev_e4(se_cmd, xop, false);
+-
+-	if (rc < 0)
++	/*
++	 * If a matching IEEE NAA 0x83 descriptor for the requested device
++	 * is not located on this node, return COPY_ABORTED with ASQ/ASQC
++	 * 0x0d/0x02 - COPY_TARGET_DEVICE_NOT_REACHABLE to request the
++	 * initiator to fall back to normal copy method.
++	 */
++	if (rc < 0) {
++		*sense_ret = TCM_COPY_TARGET_DEVICE_NOT_REACHABLE;
+ 		goto out;
++	}
+ 
+ 	pr_debug("XCOPY TGT desc: Source dev: %p NAA IEEE WWN: 0x%16phN\n",
+ 		 xop->src_dev, &xop->src_tid_wwn[0]);
+@@ -653,6 +662,7 @@ static int target_xcopy_read_source(
+ 	rc = target_xcopy_setup_pt_cmd(xpt_cmd, xop, src_dev, &cdb[0],
+ 				remote_port, true);
+ 	if (rc < 0) {
++		ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
+ 		transport_generic_free_cmd(se_cmd, 0);
+ 		return rc;
+ 	}
+@@ -664,6 +674,7 @@ static int target_xcopy_read_source(
+ 
+ 	rc = target_xcopy_issue_pt_cmd(xpt_cmd);
+ 	if (rc < 0) {
++		ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
+ 		transport_generic_free_cmd(se_cmd, 0);
+ 		return rc;
+ 	}
+@@ -714,6 +725,7 @@ static int target_xcopy_write_destination(
+ 				remote_port, false);
+ 	if (rc < 0) {
+ 		struct se_cmd *src_cmd = &xop->src_pt_cmd->se_cmd;
++		ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
+ 		/*
+ 		 * If the failure happened before the t_mem_list hand-off in
+ 		 * target_xcopy_setup_pt_cmd(), Reset memory + clear flag so that
+@@ -729,6 +741,7 @@ static int target_xcopy_write_destination(
+ 
+ 	rc = target_xcopy_issue_pt_cmd(xpt_cmd);
+ 	if (rc < 0) {
++		ec_cmd->scsi_status = xpt_cmd->se_cmd.scsi_status;
+ 		se_cmd->se_cmd_flags &= ~SCF_PASSTHROUGH_SG_TO_MEM_NOALLOC;
+ 		transport_generic_free_cmd(se_cmd, 0);
+ 		return rc;
+@@ -815,9 +828,14 @@ static void target_xcopy_do_work(struct work_struct *work)
+ out:
+ 	xcopy_pt_undepend_remotedev(xop);
+ 	kfree(xop);
+-
+-	pr_warn("target_xcopy_do_work: Setting X-COPY CHECK_CONDITION -> sending response\n");
+-	ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
++	/*
++	 * Don't override an error scsi status if it has already been set
++	 */
++	if (ec_cmd->scsi_status == SAM_STAT_GOOD) {
++		pr_warn_ratelimited("target_xcopy_do_work: rc: %d, Setting X-COPY"
++			" CHECK_CONDITION -> sending response\n", rc);
++		ec_cmd->scsi_status = SAM_STAT_CHECK_CONDITION;
++	}
+ 	target_complete_cmd(ec_cmd, SAM_STAT_CHECK_CONDITION);
+ }
+ 
+@@ -875,7 +893,7 @@ sense_reason_t target_do_xcopy(struct se_cmd *se_cmd)
+ 		" tdll: %hu sdll: %u inline_dl: %u\n", list_id, list_id_usage,
+ 		tdll, sdll, inline_dl);
+ 
+-	rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll);
++	rc = target_xcopy_parse_target_descriptors(se_cmd, xop, &p[16], tdll, &ret);
+ 	if (rc <= 0)
+ 		goto out;
+ 
+diff --git a/drivers/target/tcm_fc/tfc_cmd.c b/drivers/target/tcm_fc/tfc_cmd.c
+index 216e18cc9133..9a874a89941d 100644
+--- a/drivers/target/tcm_fc/tfc_cmd.c
++++ b/drivers/target/tcm_fc/tfc_cmd.c
+@@ -572,7 +572,7 @@ static void ft_send_work(struct work_struct *work)
+ 	if (target_submit_cmd(&cmd->se_cmd, cmd->sess->se_sess, fcp->fc_cdb,
+ 			      &cmd->ft_sense_buffer[0], scsilun_to_int(&fcp->fc_lun),
+ 			      ntohl(fcp->fc_dl), task_attr, data_dir,
+-			      TARGET_SCF_ACK_KREF))
++			      TARGET_SCF_ACK_KREF | TARGET_SCF_USE_CPUID))
+ 		goto err;
+ 
+ 	pr_debug("r_ctl %x alloc target_submit_cmd\n", fh->fh_r_ctl);
+diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
+index 924bad45c176..37a37c4d04cb 100644
+--- a/drivers/video/fbdev/efifb.c
++++ b/drivers/video/fbdev/efifb.c
+@@ -50,9 +50,9 @@ static int efifb_setcolreg(unsigned regno, unsigned red, unsigned green,
+ 		return 1;
+ 
+ 	if (regno < 16) {
+-		red   >>= 8;
+-		green >>= 8;
+-		blue  >>= 8;
++		red   >>= 16 - info->var.red.length;
++		green >>= 16 - info->var.green.length;
++		blue  >>= 16 - info->var.blue.length;
+ 		((u32 *)(info->pseudo_palette))[regno] =
+ 			(red   << info->var.red.offset)   |
+ 			(green << info->var.green.offset) |
+diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c
+index 4a2290f900a8..d5735c12067d 100644
+--- a/drivers/watchdog/mt7621_wdt.c
++++ b/drivers/watchdog/mt7621_wdt.c
+@@ -139,7 +139,6 @@ static int mt7621_wdt_probe(struct platform_device *pdev)
+ 	if (!IS_ERR(mt7621_wdt_reset))
+ 		reset_control_deassert(mt7621_wdt_reset);
+ 
+-	mt7621_wdt_dev.dev = &pdev->dev;
+ 	mt7621_wdt_dev.bootstatus = mt7621_wdt_bootcause();
+ 
+ 	watchdog_init_timeout(&mt7621_wdt_dev, mt7621_wdt_dev.max_timeout,
+diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c
+index 1967919ae743..14b4fd428fff 100644
+--- a/drivers/watchdog/rt2880_wdt.c
++++ b/drivers/watchdog/rt2880_wdt.c
+@@ -158,7 +158,6 @@ static int rt288x_wdt_probe(struct platform_device *pdev)
+ 
+ 	rt288x_wdt_freq = clk_get_rate(rt288x_wdt_clk) / RALINK_WDT_PRESCALE;
+ 
+-	rt288x_wdt_dev.dev = &pdev->dev;
+ 	rt288x_wdt_dev.bootstatus = rt288x_wdt_bootcause();
+ 	rt288x_wdt_dev.max_timeout = (0xfffful / rt288x_wdt_freq);
+ 	rt288x_wdt_dev.parent = &pdev->dev;
+diff --git a/fs/ceph/file.c b/fs/ceph/file.c
+index 0f5375d8e030..eede975e85c0 100644
+--- a/fs/ceph/file.c
++++ b/fs/ceph/file.c
+@@ -1272,7 +1272,8 @@ again:
+ 		statret = __ceph_do_getattr(inode, page,
+ 					    CEPH_STAT_CAP_INLINE_DATA, !!page);
+ 		if (statret < 0) {
+-			 __free_page(page);
++			if (page)
++				__free_page(page);
+ 			if (statret == -ENODATA) {
+ 				BUG_ON(retry_op != READ_INLINE);
+ 				goto again;
+diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
+index 6c58e13fed2f..3d03e48a9213 100644
+--- a/fs/cifs/cifs_debug.c
++++ b/fs/cifs/cifs_debug.c
+@@ -152,6 +152,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)
+ 	list_for_each(tmp1, &cifs_tcp_ses_list) {
+ 		server = list_entry(tmp1, struct TCP_Server_Info,
+ 				    tcp_ses_list);
++		seq_printf(m, "\nNumber of credits: %d", server->credits);
+ 		i++;
+ 		list_for_each(tmp2, &server->smb_ses_list) {
+ 			ses = list_entry(tmp2, struct cifs_ses,
+diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
+index 14ae4b8e1a3c..8c68d03a6949 100644
+--- a/fs/cifs/cifsfs.c
++++ b/fs/cifs/cifsfs.c
+@@ -271,7 +271,7 @@ cifs_alloc_inode(struct super_block *sb)
+ 	cifs_inode->createtime = 0;
+ 	cifs_inode->epoch = 0;
+ #ifdef CONFIG_CIFS_SMB2
+-	get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE);
++	generate_random_uuid(cifs_inode->lease_key);
+ #endif
+ 	/*
+ 	 * Can not set i_flags here - they get immediately overwritten to zero
+@@ -1271,7 +1271,6 @@ init_cifs(void)
+ 	GlobalTotalActiveXid = 0;
+ 	GlobalMaxActiveXid = 0;
+ 	spin_lock_init(&cifs_tcp_ses_lock);
+-	spin_lock_init(&cifs_file_list_lock);
+ 	spin_lock_init(&GlobalMid_Lock);
+ 
+ 	get_random_bytes(&cifs_lock_secret, sizeof(cifs_lock_secret));
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 8f1d8c1e72be..65f78b7a9062 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -833,6 +833,7 @@ struct cifs_tcon {
+ 	struct list_head tcon_list;
+ 	int tc_count;
+ 	struct list_head openFileList;
++	spinlock_t open_file_lock; /* protects list above */
+ 	struct cifs_ses *ses;	/* pointer to session associated with */
+ 	char treeName[MAX_TREE_SIZE + 1]; /* UNC name of resource in ASCII */
+ 	char *nativeFileSystem;
+@@ -889,7 +890,7 @@ struct cifs_tcon {
+ #endif /* CONFIG_CIFS_STATS2 */
+ 	__u64    bytes_read;
+ 	__u64    bytes_written;
+-	spinlock_t stat_lock;
++	spinlock_t stat_lock;  /* protects the two fields above */
+ #endif /* CONFIG_CIFS_STATS */
+ 	FILE_SYSTEM_DEVICE_INFO fsDevInfo;
+ 	FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */
+@@ -1040,8 +1041,10 @@ struct cifs_fid_locks {
+ };
+ 
+ struct cifsFileInfo {
++	/* following two lists are protected by tcon->open_file_lock */
+ 	struct list_head tlist;	/* pointer to next fid owned by tcon */
+ 	struct list_head flist;	/* next fid (file instance) for this inode */
++	/* lock list below protected by cifsi->lock_sem */
+ 	struct cifs_fid_locks *llist;	/* brlocks held by this fid */
+ 	kuid_t uid;		/* allows finding which FileInfo structure */
+ 	__u32 pid;		/* process id who opened file */
+@@ -1049,11 +1052,12 @@ struct cifsFileInfo {
+ 	/* BB add lock scope info here if needed */ ;
+ 	/* lock scope id (0 if none) */
+ 	struct dentry *dentry;
+-	unsigned int f_flags;
+ 	struct tcon_link *tlink;
++	unsigned int f_flags;
+ 	bool invalidHandle:1;	/* file closed via session abend */
+ 	bool oplock_break_cancelled:1;
+-	int count;		/* refcount protected by cifs_file_list_lock */
++	int count;
++	spinlock_t file_info_lock; /* protects four flag/count fields above */
+ 	struct mutex fh_mutex; /* prevents reopen race after dead ses*/
+ 	struct cifs_search_info srch_inf;
+ 	struct work_struct oplock_break; /* work for oplock breaks */
+@@ -1120,7 +1124,7 @@ struct cifs_writedata {
+ 
+ /*
+  * Take a reference on the file private data. Must be called with
+- * cifs_file_list_lock held.
++ * cfile->file_info_lock held.
+  */
+ static inline void
+ cifsFileInfo_get_locked(struct cifsFileInfo *cifs_file)
+@@ -1514,8 +1518,10 @@ require use of the stronger protocol */
+  *  GlobalMid_Lock protects:
+  *	list operations on pending_mid_q and oplockQ
+  *      updates to XID counters, multiplex id  and SMB sequence numbers
+- *  cifs_file_list_lock protects:
+- *	list operations on tcp and SMB session lists and tCon lists
++ *  tcp_ses_lock protects:
++ *	list operations on tcp and SMB session lists
++ *  tcon->open_file_lock protects the list of open files hanging off the tcon
++ *  cfile->file_info_lock protects counters and fields in cifs file struct
+  *  f_owner.lock protects certain per file struct operations
+  *  mapping->page_lock protects certain per page operations
+  *
+@@ -1547,18 +1553,12 @@ GLOBAL_EXTERN struct list_head		cifs_tcp_ses_list;
+  * tcp session, and the list of tcon's per smb session. It also protects
+  * the reference counters for the server, smb session, and tcon. Finally,
+  * changes to the tcon->tidStatus should be done while holding this lock.
++ * generally the locks should be taken in order tcp_ses_lock before
++ * tcon->open_file_lock and that before file->file_info_lock since the
++ * structure order is cifs_socket-->cifs_ses-->cifs_tcon-->cifs_file
+  */
+ GLOBAL_EXTERN spinlock_t		cifs_tcp_ses_lock;
+ 
+-/*
+- * This lock protects the cifs_file->llist and cifs_file->flist
+- * list operations, and updates to some flags (cifs_file->invalidHandle)
+- * It will be moved to either use the tcon->stat_lock or equivalent later.
+- * If cifs_tcp_ses_lock and the lock below are both needed to be held, then
+- * the cifs_tcp_ses_lock must be grabbed first and released last.
+- */
+-GLOBAL_EXTERN spinlock_t	cifs_file_list_lock;
+-
+ #ifdef CONFIG_CIFS_DNOTIFY_EXPERIMENTAL /* unused temporarily */
+ /* Outstanding dir notify requests */
+ GLOBAL_EXTERN struct list_head GlobalDnotifyReqList;
+diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
+index d47197ea4ab6..78046051bbbc 100644
+--- a/fs/cifs/cifssmb.c
++++ b/fs/cifs/cifssmb.c
+@@ -98,13 +98,13 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
+ 	struct list_head *tmp1;
+ 
+ 	/* list all files open on tree connection and mark them invalid */
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
+ 	list_for_each_safe(tmp, tmp1, &tcon->openFileList) {
+ 		open_file = list_entry(tmp, struct cifsFileInfo, tlist);
+ 		open_file->invalidHandle = true;
+ 		open_file->oplock_break_cancelled = true;
+ 	}
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tcon->open_file_lock);
+ 	/*
+ 	 * BB Add call to invalidate_inodes(sb) for all superblocks mounted
+ 	 * to this tcon.
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 2e4f4bad8b1e..7b67179521cf 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -2163,7 +2163,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
+ 	memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
+ 		sizeof(tcp_ses->dstaddr));
+ #ifdef CONFIG_CIFS_SMB2
+-	get_random_bytes(tcp_ses->client_guid, SMB2_CLIENT_GUID_SIZE);
++	generate_random_uuid(tcp_ses->client_guid);
+ #endif
+ 	/*
+ 	 * at this point we are the only ones with the pointer
+@@ -3688,14 +3688,16 @@ remote_path_check:
+ 			goto mount_fail_check;
+ 		}
+ 
+-		rc = cifs_are_all_path_components_accessible(server,
++		if (rc != -EREMOTE) {
++			rc = cifs_are_all_path_components_accessible(server,
+ 							     xid, tcon, cifs_sb,
+ 							     full_path);
+-		if (rc != 0) {
+-			cifs_dbg(VFS, "cannot query dirs between root and final path, "
+-				 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
+-			cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
+-			rc = 0;
++			if (rc != 0) {
++				cifs_dbg(VFS, "cannot query dirs between root and final path, "
++					 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n");
++				cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH;
++				rc = 0;
++			}
+ 		}
+ 		kfree(full_path);
+ 	}
+diff --git a/fs/cifs/file.c b/fs/cifs/file.c
+index 579e41b350a2..605438afe7ef 100644
+--- a/fs/cifs/file.c
++++ b/fs/cifs/file.c
+@@ -305,6 +305,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ 	cfile->tlink = cifs_get_tlink(tlink);
+ 	INIT_WORK(&cfile->oplock_break, cifs_oplock_break);
+ 	mutex_init(&cfile->fh_mutex);
++	spin_lock_init(&cfile->file_info_lock);
+ 
+ 	cifs_sb_active(inode->i_sb);
+ 
+@@ -317,7 +318,7 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ 		oplock = 0;
+ 	}
+ 
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
+ 	if (fid->pending_open->oplock != CIFS_OPLOCK_NO_CHANGE && oplock)
+ 		oplock = fid->pending_open->oplock;
+ 	list_del(&fid->pending_open->olist);
+@@ -326,12 +327,13 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ 	server->ops->set_fid(cfile, fid, oplock);
+ 
+ 	list_add(&cfile->tlist, &tcon->openFileList);
++
+ 	/* if readable file instance put first in list*/
+ 	if (file->f_mode & FMODE_READ)
+ 		list_add(&cfile->flist, &cinode->openFileList);
+ 	else
+ 		list_add_tail(&cfile->flist, &cinode->openFileList);
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tcon->open_file_lock);
+ 
+ 	if (fid->purge_cache)
+ 		cifs_zap_mapping(inode);
+@@ -343,16 +345,16 @@ cifs_new_fileinfo(struct cifs_fid *fid, struct file *file,
+ struct cifsFileInfo *
+ cifsFileInfo_get(struct cifsFileInfo *cifs_file)
+ {
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&cifs_file->file_info_lock);
+ 	cifsFileInfo_get_locked(cifs_file);
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&cifs_file->file_info_lock);
+ 	return cifs_file;
+ }
+ 
+ /*
+  * Release a reference on the file private data. This may involve closing
+  * the filehandle out on the server. Must be called without holding
+- * cifs_file_list_lock.
++ * tcon->open_file_lock and cifs_file->file_info_lock.
+  */
+ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
+ {
+@@ -367,11 +369,15 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
+ 	struct cifs_pending_open open;
+ 	bool oplock_break_cancelled;
+ 
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
++
++	spin_lock(&cifs_file->file_info_lock);
+ 	if (--cifs_file->count > 0) {
+-		spin_unlock(&cifs_file_list_lock);
++		spin_unlock(&cifs_file->file_info_lock);
++		spin_unlock(&tcon->open_file_lock);
+ 		return;
+ 	}
++	spin_unlock(&cifs_file->file_info_lock);
+ 
+ 	if (server->ops->get_lease_key)
+ 		server->ops->get_lease_key(inode, &fid);
+@@ -395,7 +401,8 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
+ 			set_bit(CIFS_INO_INVALID_MAPPING, &cifsi->flags);
+ 		cifs_set_oplock_level(cifsi, 0);
+ 	}
+-	spin_unlock(&cifs_file_list_lock);
++
++	spin_unlock(&tcon->open_file_lock);
+ 
+ 	oplock_break_cancelled = cancel_work_sync(&cifs_file->oplock_break);
+ 
+@@ -772,10 +779,10 @@ int cifs_closedir(struct inode *inode, struct file *file)
+ 	server = tcon->ses->server;
+ 
+ 	cifs_dbg(FYI, "Freeing private data in close dir\n");
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&cfile->file_info_lock);
+ 	if (server->ops->dir_needs_close(cfile)) {
+ 		cfile->invalidHandle = true;
+-		spin_unlock(&cifs_file_list_lock);
++		spin_unlock(&cfile->file_info_lock);
+ 		if (server->ops->close_dir)
+ 			rc = server->ops->close_dir(xid, tcon, &cfile->fid);
+ 		else
+@@ -784,7 +791,7 @@ int cifs_closedir(struct inode *inode, struct file *file)
+ 		/* not much we can do if it fails anyway, ignore rc */
+ 		rc = 0;
+ 	} else
+-		spin_unlock(&cifs_file_list_lock);
++		spin_unlock(&cfile->file_info_lock);
+ 
+ 	buf = cfile->srch_inf.ntwrk_buf_start;
+ 	if (buf) {
+@@ -1728,12 +1735,13 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
+ {
+ 	struct cifsFileInfo *open_file = NULL;
+ 	struct cifs_sb_info *cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
++	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ 
+ 	/* only filter by fsuid on multiuser mounts */
+ 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
+ 		fsuid_only = false;
+ 
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
+ 	/* we could simply get the first_list_entry since write-only entries
+ 	   are always at the end of the list but since the first entry might
+ 	   have a close pending, we go through the whole list */
+@@ -1744,8 +1752,8 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
+ 			if (!open_file->invalidHandle) {
+ 				/* found a good file */
+ 				/* lock it so it will not be closed on us */
+-				cifsFileInfo_get_locked(open_file);
+-				spin_unlock(&cifs_file_list_lock);
++				cifsFileInfo_get(open_file);
++				spin_unlock(&tcon->open_file_lock);
+ 				return open_file;
+ 			} /* else might as well continue, and look for
+ 			     another, or simply have the caller reopen it
+@@ -1753,7 +1761,7 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
+ 		} else /* write only file */
+ 			break; /* write only files are last so must be done */
+ 	}
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tcon->open_file_lock);
+ 	return NULL;
+ }
+ 
+@@ -1762,6 +1770,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
+ {
+ 	struct cifsFileInfo *open_file, *inv_file = NULL;
+ 	struct cifs_sb_info *cifs_sb;
++	struct cifs_tcon *tcon;
+ 	bool any_available = false;
+ 	int rc;
+ 	unsigned int refind = 0;
+@@ -1777,15 +1786,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode,
+ 	}
+ 
+ 	cifs_sb = CIFS_SB(cifs_inode->vfs_inode.i_sb);
++	tcon = cifs_sb_master_tcon(cifs_sb);
+ 
+ 	/* only filter by fsuid on multiuser mounts */
+ 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
+ 		fsuid_only = false;
+ 
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
+ refind_writable:
+ 	if (refind > MAX_REOPEN_ATT) {
+-		spin_unlock(&cifs_file_list_lock);
++		spin_unlock(&tcon->open_file_lock);
+ 		return NULL;
+ 	}
+ 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+@@ -1796,8 +1806,8 @@ refind_writable:
+ 		if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
+ 			if (!open_file->invalidHandle) {
+ 				/* found a good writable file */
+-				cifsFileInfo_get_locked(open_file);
+-				spin_unlock(&cifs_file_list_lock);
++				cifsFileInfo_get(open_file);
++				spin_unlock(&tcon->open_file_lock);
+ 				return open_file;
+ 			} else {
+ 				if (!inv_file)
+@@ -1813,24 +1823,24 @@ refind_writable:
+ 
+ 	if (inv_file) {
+ 		any_available = false;
+-		cifsFileInfo_get_locked(inv_file);
++		cifsFileInfo_get(inv_file);
+ 	}
+ 
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tcon->open_file_lock);
+ 
+ 	if (inv_file) {
+ 		rc = cifs_reopen_file(inv_file, false);
+ 		if (!rc)
+ 			return inv_file;
+ 		else {
+-			spin_lock(&cifs_file_list_lock);
++			spin_lock(&tcon->open_file_lock);
+ 			list_move_tail(&inv_file->flist,
+ 					&cifs_inode->openFileList);
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&tcon->open_file_lock);
+ 			cifsFileInfo_put(inv_file);
+-			spin_lock(&cifs_file_list_lock);
+ 			++refind;
+ 			inv_file = NULL;
++			spin_lock(&tcon->open_file_lock);
+ 			goto refind_writable;
+ 		}
+ 	}
+@@ -3618,15 +3628,17 @@ static int cifs_readpage(struct file *file, struct page *page)
+ static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
+ {
+ 	struct cifsFileInfo *open_file;
++	struct cifs_tcon *tcon =
++		cifs_sb_master_tcon(CIFS_SB(cifs_inode->vfs_inode.i_sb));
+ 
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tcon->open_file_lock);
+ 	list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
+ 		if (OPEN_FMODE(open_file->f_flags) & FMODE_WRITE) {
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&tcon->open_file_lock);
+ 			return 1;
+ 		}
+ 	}
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tcon->open_file_lock);
+ 	return 0;
+ }
+ 
+diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
+index 813fe13c2ae1..c6729156f9a0 100644
+--- a/fs/cifs/misc.c
++++ b/fs/cifs/misc.c
+@@ -120,6 +120,7 @@ tconInfoAlloc(void)
+ 		++ret_buf->tc_count;
+ 		INIT_LIST_HEAD(&ret_buf->openFileList);
+ 		INIT_LIST_HEAD(&ret_buf->tcon_list);
++		spin_lock_init(&ret_buf->open_file_lock);
+ #ifdef CONFIG_CIFS_STATS
+ 		spin_lock_init(&ret_buf->stat_lock);
+ #endif
+@@ -465,7 +466,7 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ 				continue;
+ 
+ 			cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
+-			spin_lock(&cifs_file_list_lock);
++			spin_lock(&tcon->open_file_lock);
+ 			list_for_each(tmp2, &tcon->openFileList) {
+ 				netfile = list_entry(tmp2, struct cifsFileInfo,
+ 						     tlist);
+@@ -495,11 +496,11 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
+ 					   &netfile->oplock_break);
+ 				netfile->oplock_break_cancelled = false;
+ 
+-				spin_unlock(&cifs_file_list_lock);
++				spin_unlock(&tcon->open_file_lock);
+ 				spin_unlock(&cifs_tcp_ses_lock);
+ 				return true;
+ 			}
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&tcon->open_file_lock);
+ 			spin_unlock(&cifs_tcp_ses_lock);
+ 			cifs_dbg(FYI, "No matching file for oplock break\n");
+ 			return true;
+@@ -613,9 +614,9 @@ backup_cred(struct cifs_sb_info *cifs_sb)
+ void
+ cifs_del_pending_open(struct cifs_pending_open *open)
+ {
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tlink_tcon(open->tlink)->open_file_lock);
+ 	list_del(&open->olist);
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tlink_tcon(open->tlink)->open_file_lock);
+ }
+ 
+ void
+@@ -635,7 +636,7 @@ void
+ cifs_add_pending_open(struct cifs_fid *fid, struct tcon_link *tlink,
+ 		      struct cifs_pending_open *open)
+ {
+-	spin_lock(&cifs_file_list_lock);
++	spin_lock(&tlink_tcon(tlink)->open_file_lock);
+ 	cifs_add_pending_open_locked(fid, tlink, open);
+-	spin_unlock(&cifs_file_list_lock);
++	spin_unlock(&tlink_tcon(open->tlink)->open_file_lock);
+ }
+diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
+index 65cf85dcda09..8f6a2a5863b9 100644
+--- a/fs/cifs/readdir.c
++++ b/fs/cifs/readdir.c
+@@ -597,14 +597,14 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
+ 	     is_dir_changed(file)) || (index_to_find < first_entry_in_buffer)) {
+ 		/* close and restart search */
+ 		cifs_dbg(FYI, "search backing up - close and restart search\n");
+-		spin_lock(&cifs_file_list_lock);
++		spin_lock(&cfile->file_info_lock);
+ 		if (server->ops->dir_needs_close(cfile)) {
+ 			cfile->invalidHandle = true;
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&cfile->file_info_lock);
+ 			if (server->ops->close_dir)
+ 				server->ops->close_dir(xid, tcon, &cfile->fid);
+ 		} else
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&cfile->file_info_lock);
+ 		if (cfile->srch_inf.ntwrk_buf_start) {
+ 			cifs_dbg(FYI, "freeing SMB ff cache buf on search rewind\n");
+ 			if (cfile->srch_inf.smallBuf)
+diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
+index 0ffa18094335..238759c146ba 100644
+--- a/fs/cifs/smb2glob.h
++++ b/fs/cifs/smb2glob.h
+@@ -61,4 +61,14 @@
+ /* Maximum buffer size value we can send with 1 credit */
+ #define SMB2_MAX_BUFFER_SIZE 65536
+ 
++/*
++ * Maximum number of credits to keep available.
++ * This value is chosen somewhat arbitrarily. The Windows client
++ * defaults to 128 credits, the Windows server allows clients up to
++ * 512 credits, and the NetApp server does not limit clients at all.
++ * Choose a high enough value such that the client shouldn't limit
++ * performance.
++ */
++#define SMB2_MAX_CREDITS_AVAILABLE 32000
++
+ #endif	/* _SMB2_GLOB_H */
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index 4f0231e685a9..1238cd3552f9 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -266,9 +266,15 @@ smb2_set_file_info(struct inode *inode, const char *full_path,
+ 	struct tcon_link *tlink;
+ 	int rc;
+ 
++	if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
++	    (buf->LastWriteTime == 0) && (buf->ChangeTime) &&
++	    (buf->Attributes == 0))
++		return 0; /* would be a no op, no sense sending this */
++
+ 	tlink = cifs_sb_tlink(cifs_sb);
+ 	if (IS_ERR(tlink))
+ 		return PTR_ERR(tlink);
++
+ 	rc = smb2_open_op_close(xid, tlink_tcon(tlink), cifs_sb, full_path,
+ 				FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
+ 				SMB2_OP_SET_INFO);
+diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
+index 389fb9f8c84e..3d383489b9cf 100644
+--- a/fs/cifs/smb2misc.c
++++ b/fs/cifs/smb2misc.c
+@@ -549,19 +549,19 @@ smb2_is_valid_lease_break(char *buffer)
+ 		list_for_each(tmp1, &server->smb_ses_list) {
+ 			ses = list_entry(tmp1, struct cifs_ses, smb_ses_list);
+ 
+-			spin_lock(&cifs_file_list_lock);
+ 			list_for_each(tmp2, &ses->tcon_list) {
+ 				tcon = list_entry(tmp2, struct cifs_tcon,
+ 						  tcon_list);
++				spin_lock(&tcon->open_file_lock);
+ 				cifs_stats_inc(
+ 				    &tcon->stats.cifs_stats.num_oplock_brks);
+ 				if (smb2_tcon_has_lease(tcon, rsp, lw)) {
+-					spin_unlock(&cifs_file_list_lock);
++					spin_unlock(&tcon->open_file_lock);
+ 					spin_unlock(&cifs_tcp_ses_lock);
+ 					return true;
+ 				}
++				spin_unlock(&tcon->open_file_lock);
+ 			}
+-			spin_unlock(&cifs_file_list_lock);
+ 		}
+ 	}
+ 	spin_unlock(&cifs_tcp_ses_lock);
+@@ -603,7 +603,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ 			tcon = list_entry(tmp1, struct cifs_tcon, tcon_list);
+ 
+ 			cifs_stats_inc(&tcon->stats.cifs_stats.num_oplock_brks);
+-			spin_lock(&cifs_file_list_lock);
++			spin_lock(&tcon->open_file_lock);
+ 			list_for_each(tmp2, &tcon->openFileList) {
+ 				cfile = list_entry(tmp2, struct cifsFileInfo,
+ 						     tlist);
+@@ -615,7 +615,7 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ 
+ 				cifs_dbg(FYI, "file id match, oplock break\n");
+ 				cinode = CIFS_I(d_inode(cfile->dentry));
+-
++				spin_lock(&cfile->file_info_lock);
+ 				if (!CIFS_CACHE_WRITE(cinode) &&
+ 				    rsp->OplockLevel == SMB2_OPLOCK_LEVEL_NONE)
+ 					cfile->oplock_break_cancelled = true;
+@@ -637,14 +637,14 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
+ 					clear_bit(
+ 					   CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ 					   &cinode->flags);
+-
++				spin_unlock(&cfile->file_info_lock);
+ 				queue_work(cifsiod_wq, &cfile->oplock_break);
+ 
+-				spin_unlock(&cifs_file_list_lock);
++				spin_unlock(&tcon->open_file_lock);
+ 				spin_unlock(&cifs_tcp_ses_lock);
+ 				return true;
+ 			}
+-			spin_unlock(&cifs_file_list_lock);
++			spin_unlock(&tcon->open_file_lock);
+ 			spin_unlock(&cifs_tcp_ses_lock);
+ 			cifs_dbg(FYI, "No matching file for oplock break\n");
+ 			return true;
+diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
+index d203c0329626..0e73cefca65e 100644
+--- a/fs/cifs/smb2ops.c
++++ b/fs/cifs/smb2ops.c
+@@ -287,7 +287,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
+ 		cifs_dbg(FYI, "Link Speed %lld\n",
+ 			le64_to_cpu(out_buf->LinkSpeed));
+ 	}
+-
++	kfree(out_buf);
+ 	return rc;
+ }
+ #endif /* STATS2 */
+@@ -541,6 +541,7 @@ smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
+ 	server->ops->set_oplock_level(cinode, oplock, fid->epoch,
+ 				      &fid->purge_cache);
+ 	cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
++	memcpy(cfile->fid.create_guid, fid->create_guid, 16);
+ }
+ 
+ static void
+@@ -699,6 +700,7 @@ smb2_clone_range(const unsigned int xid,
+ 
+ cchunk_out:
+ 	kfree(pcchunk);
++	kfree(retbuf);
+ 	return rc;
+ }
+ 
+@@ -823,7 +825,6 @@ smb2_duplicate_extents(const unsigned int xid,
+ {
+ 	int rc;
+ 	unsigned int ret_data_len;
+-	char *retbuf = NULL;
+ 	struct duplicate_extents_to_file dup_ext_buf;
+ 	struct cifs_tcon *tcon = tlink_tcon(trgtfile->tlink);
+ 
+@@ -849,7 +850,7 @@ smb2_duplicate_extents(const unsigned int xid,
+ 			FSCTL_DUPLICATE_EXTENTS_TO_FILE,
+ 			true /* is_fsctl */, (char *)&dup_ext_buf,
+ 			sizeof(struct duplicate_extents_to_file),
+-			(char **)&retbuf,
++			NULL,
+ 			&ret_data_len);
+ 
+ 	if (ret_data_len > 0)
+@@ -872,7 +873,6 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
+ 		   struct cifsFileInfo *cfile)
+ {
+ 	struct fsctl_set_integrity_information_req integr_info;
+-	char *retbuf = NULL;
+ 	unsigned int ret_data_len;
+ 
+ 	integr_info.ChecksumAlgorithm = cpu_to_le16(CHECKSUM_TYPE_UNCHANGED);
+@@ -884,7 +884,7 @@ smb3_set_integrity(const unsigned int xid, struct cifs_tcon *tcon,
+ 			FSCTL_SET_INTEGRITY_INFORMATION,
+ 			true /* is_fsctl */, (char *)&integr_info,
+ 			sizeof(struct fsctl_set_integrity_information_req),
+-			(char **)&retbuf,
++			NULL,
+ 			&ret_data_len);
+ 
+ }
+@@ -1041,7 +1041,7 @@ smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
+ static void
+ smb2_new_lease_key(struct cifs_fid *fid)
+ {
+-	get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
++	generate_random_uuid(fid->lease_key);
+ }
+ 
+ #define SMB2_SYMLINK_STRUCT_SIZE \
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 29e06db5f187..3eec96ca87d9 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -100,7 +100,21 @@ smb2_hdr_assemble(struct smb2_hdr *hdr, __le16 smb2_cmd /* command */ ,
+ 	hdr->ProtocolId = SMB2_PROTO_NUMBER;
+ 	hdr->StructureSize = cpu_to_le16(64);
+ 	hdr->Command = smb2_cmd;
+-	hdr->CreditRequest = cpu_to_le16(2); /* BB make this dynamic */
++	if (tcon && tcon->ses && tcon->ses->server) {
++		struct TCP_Server_Info *server = tcon->ses->server;
++
++		spin_lock(&server->req_lock);
++		/* Request up to 2 credits but don't go over the limit. */
++		if (server->credits >= SMB2_MAX_CREDITS_AVAILABLE)
++			hdr->CreditRequest = cpu_to_le16(0);
++		else
++			hdr->CreditRequest = cpu_to_le16(
++				min_t(int, SMB2_MAX_CREDITS_AVAILABLE -
++						server->credits, 2));
++		spin_unlock(&server->req_lock);
++	} else {
++		hdr->CreditRequest = cpu_to_le16(2);
++	}
+ 	hdr->ProcessId = cpu_to_le32((__u16)current->tgid);
+ 
+ 	if (!tcon)
+@@ -590,6 +604,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
+ 	char *security_blob = NULL;
+ 	unsigned char *ntlmssp_blob = NULL;
+ 	bool use_spnego = false; /* else use raw ntlmssp */
++	u64 previous_session = ses->Suid;
+ 
+ 	cifs_dbg(FYI, "Session Setup\n");
+ 
+@@ -627,6 +642,10 @@ ssetup_ntlmssp_authenticate:
+ 		return rc;
+ 
+ 	req->hdr.SessionId = 0; /* First session, not a reauthenticate */
++
++	/* if reconnect, we need to send previous sess id, otherwise it is 0 */
++	req->PreviousSessionId = previous_session;
++
+ 	req->Flags = 0; /* MBZ */
+ 	/* to enable echos and oplocks */
+ 	req->hdr.CreditRequest = cpu_to_le16(3);
+@@ -1164,7 +1183,7 @@ create_durable_v2_buf(struct cifs_fid *pfid)
+ 
+ 	buf->dcontext.Timeout = 0; /* Should this be configurable by workload */
+ 	buf->dcontext.Flags = cpu_to_le32(SMB2_DHANDLE_FLAG_PERSISTENT);
+-	get_random_bytes(buf->dcontext.CreateGuid, 16);
++	generate_random_uuid(buf->dcontext.CreateGuid);
+ 	memcpy(pfid->create_guid, buf->dcontext.CreateGuid, 16);
+ 
+ 	/* SMB2_CREATE_DURABLE_HANDLE_REQUEST is "DH2Q" */
+@@ -2057,6 +2076,7 @@ smb2_async_readv(struct cifs_readdata *rdata)
+ 	if (rdata->credits) {
+ 		buf->CreditCharge = cpu_to_le16(DIV_ROUND_UP(rdata->bytes,
+ 						SMB2_MAX_BUFFER_SIZE));
++		buf->CreditRequest = buf->CreditCharge;
+ 		spin_lock(&server->req_lock);
+ 		server->credits += rdata->credits -
+ 						le16_to_cpu(buf->CreditCharge);
+@@ -2243,6 +2263,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
+ 	if (wdata->credits) {
+ 		req->hdr.CreditCharge = cpu_to_le16(DIV_ROUND_UP(wdata->bytes,
+ 						    SMB2_MAX_BUFFER_SIZE));
++		req->hdr.CreditRequest = req->hdr.CreditCharge;
+ 		spin_lock(&server->req_lock);
+ 		server->credits += wdata->credits -
+ 					le16_to_cpu(req->hdr.CreditCharge);
+diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h
+index ff88d9feb01e..fd3709e8de33 100644
+--- a/fs/cifs/smb2pdu.h
++++ b/fs/cifs/smb2pdu.h
+@@ -276,7 +276,7 @@ struct smb2_sess_setup_req {
+ 	__le32 Channel;
+ 	__le16 SecurityBufferOffset;
+ 	__le16 SecurityBufferLength;
+-	__le64 PreviousSessionId;
++	__u64 PreviousSessionId;
+ 	__u8   Buffer[1];	/* variable length GSS security buffer */
+ } __packed;
+ 
+diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
+index c502c116924c..55d64fba1e87 100644
+--- a/fs/crypto/crypto.c
++++ b/fs/crypto/crypto.c
+@@ -152,7 +152,10 @@ static int do_page_crypto(struct inode *inode,
+ 			struct page *src_page, struct page *dest_page,
+ 			gfp_t gfp_flags)
+ {
+-	u8 xts_tweak[FS_XTS_TWEAK_SIZE];
++	struct {
++		__le64 index;
++		u8 padding[FS_XTS_TWEAK_SIZE - sizeof(__le64)];
++	} xts_tweak;
+ 	struct skcipher_request *req = NULL;
+ 	DECLARE_FS_COMPLETION_RESULT(ecr);
+ 	struct scatterlist dst, src;
+@@ -172,17 +175,15 @@ static int do_page_crypto(struct inode *inode,
+ 		req, CRYPTO_TFM_REQ_MAY_BACKLOG | CRYPTO_TFM_REQ_MAY_SLEEP,
+ 		fscrypt_complete, &ecr);
+ 
+-	BUILD_BUG_ON(FS_XTS_TWEAK_SIZE < sizeof(index));
+-	memcpy(xts_tweak, &index, sizeof(index));
+-	memset(&xts_tweak[sizeof(index)], 0,
+-			FS_XTS_TWEAK_SIZE - sizeof(index));
++	BUILD_BUG_ON(sizeof(xts_tweak) != FS_XTS_TWEAK_SIZE);
++	xts_tweak.index = cpu_to_le64(index);
++	memset(xts_tweak.padding, 0, sizeof(xts_tweak.padding));
+ 
+ 	sg_init_table(&dst, 1);
+ 	sg_set_page(&dst, dest_page, PAGE_SIZE, 0);
+ 	sg_init_table(&src, 1);
+ 	sg_set_page(&src, src_page, PAGE_SIZE, 0);
+-	skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE,
+-					xts_tweak);
++	skcipher_request_set_crypt(req, &src, &dst, PAGE_SIZE, &xts_tweak);
+ 	if (rw == FS_DECRYPT)
+ 		res = crypto_skcipher_decrypt(req);
+ 	else
+diff --git a/fs/crypto/policy.c b/fs/crypto/policy.c
+index ed115acb5dee..6865663aac69 100644
+--- a/fs/crypto/policy.c
++++ b/fs/crypto/policy.c
+@@ -109,6 +109,8 @@ int fscrypt_process_policy(struct file *filp,
+ 	if (ret)
+ 		return ret;
+ 
++	inode_lock(inode);
++
+ 	if (!inode_has_encryption_context(inode)) {
+ 		if (!S_ISDIR(inode->i_mode))
+ 			ret = -EINVAL;
+@@ -127,6 +129,8 @@ int fscrypt_process_policy(struct file *filp,
+ 		ret = -EINVAL;
+ 	}
+ 
++	inode_unlock(inode);
++
+ 	mnt_drop_write_file(filp);
+ 	return ret;
+ }
+diff --git a/fs/ext4/sysfs.c b/fs/ext4/sysfs.c
+index 73bcfd41f5f2..42145be5c6b4 100644
+--- a/fs/ext4/sysfs.c
++++ b/fs/ext4/sysfs.c
+@@ -223,14 +223,18 @@ static struct attribute *ext4_attrs[] = {
+ EXT4_ATTR_FEATURE(lazy_itable_init);
+ EXT4_ATTR_FEATURE(batched_discard);
+ EXT4_ATTR_FEATURE(meta_bg_resize);
++#ifdef CONFIG_EXT4_FS_ENCRYPTION
+ EXT4_ATTR_FEATURE(encryption);
++#endif
+ EXT4_ATTR_FEATURE(metadata_csum_seed);
+ 
+ static struct attribute *ext4_feat_attrs[] = {
+ 	ATTR_LIST(lazy_itable_init),
+ 	ATTR_LIST(batched_discard),
+ 	ATTR_LIST(meta_bg_resize),
++#ifdef CONFIG_EXT4_FS_ENCRYPTION
+ 	ATTR_LIST(encryption),
++#endif
+ 	ATTR_LIST(metadata_csum_seed),
+ 	NULL,
+ };
+diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
+index ad0c745ebad7..871c8b392099 100644
+--- a/fs/isofs/inode.c
++++ b/fs/isofs/inode.c
+@@ -687,6 +687,11 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent)
+ 	pri_bh = NULL;
+ 
+ root_found:
++	/* We don't support read-write mounts */
++	if (!(s->s_flags & MS_RDONLY)) {
++		error = -EACCES;
++		goto out_freebh;
++	}
+ 
+ 	if (joliet_level && (pri == NULL || !opt.rock)) {
+ 		/* This is the case of Joliet with the norock mount flag.
+@@ -1501,9 +1506,6 @@ struct inode *__isofs_iget(struct super_block *sb,
+ static struct dentry *isofs_mount(struct file_system_type *fs_type,
+ 	int flags, const char *dev_name, void *data)
+ {
+-	/* We don't support read-write mounts */
+-	if (!(flags & MS_RDONLY))
+-		return ERR_PTR(-EACCES);
+ 	return mount_bdev(fs_type, flags, dev_name, data, isofs_fill_super);
+ }
+ 
+diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c
+index 3d8246a9faa4..e1652665bd93 100644
+--- a/fs/jbd2/transaction.c
++++ b/fs/jbd2/transaction.c
+@@ -1149,6 +1149,7 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
+ 		JBUFFER_TRACE(jh, "file as BJ_Reserved");
+ 		spin_lock(&journal->j_list_lock);
+ 		__jbd2_journal_file_buffer(jh, transaction, BJ_Reserved);
++		spin_unlock(&journal->j_list_lock);
+ 	} else if (jh->b_transaction == journal->j_committing_transaction) {
+ 		/* first access by this transaction */
+ 		jh->b_modified = 0;
+@@ -1156,8 +1157,8 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh)
+ 		JBUFFER_TRACE(jh, "set next transaction");
+ 		spin_lock(&journal->j_list_lock);
+ 		jh->b_next_transaction = transaction;
++		spin_unlock(&journal->j_list_lock);
+ 	}
+-	spin_unlock(&journal->j_list_lock);
+ 	jbd_unlock_bh_state(bh);
+ 
+ 	/*
+diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
+index 217847679f0e..2905479f214a 100644
+--- a/fs/nfs/blocklayout/blocklayout.c
++++ b/fs/nfs/blocklayout/blocklayout.c
+@@ -344,9 +344,10 @@ static void bl_write_cleanup(struct work_struct *work)
+ 		u64 start = hdr->args.offset & (loff_t)PAGE_MASK;
+ 		u64 end = (hdr->args.offset + hdr->args.count +
+ 			PAGE_SIZE - 1) & (loff_t)PAGE_MASK;
++		u64 lwb = hdr->args.offset + hdr->args.count;
+ 
+ 		ext_tree_mark_written(bl, start >> SECTOR_SHIFT,
+-					(end - start) >> SECTOR_SHIFT, end);
++					(end - start) >> SECTOR_SHIFT, lwb);
+ 	}
+ 
+ 	pnfs_ld_write_done(hdr);
+diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
+index 322c2585bc34..b9c65421ed81 100644
+--- a/fs/nfs/delegation.c
++++ b/fs/nfs/delegation.c
+@@ -41,6 +41,17 @@ void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
+ 	set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
+ }
+ 
++static bool
++nfs4_is_valid_delegation(const struct nfs_delegation *delegation,
++		fmode_t flags)
++{
++	if (delegation != NULL && (delegation->type & flags) == flags &&
++	    !test_bit(NFS_DELEGATION_REVOKED, &delegation->flags) &&
++	    !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags))
++		return true;
++	return false;
++}
++
+ static int
+ nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
+ {
+@@ -50,8 +61,7 @@ nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark)
+ 	flags &= FMODE_READ|FMODE_WRITE;
+ 	rcu_read_lock();
+ 	delegation = rcu_dereference(NFS_I(inode)->delegation);
+-	if (delegation != NULL && (delegation->type & flags) == flags &&
+-	    !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
++	if (nfs4_is_valid_delegation(delegation, flags)) {
+ 		if (mark)
+ 			nfs_mark_delegation_referenced(delegation);
+ 		ret = 1;
+@@ -893,7 +903,7 @@ bool nfs4_copy_delegation_stateid(struct inode *inode, fmode_t flags,
+ 	flags &= FMODE_READ|FMODE_WRITE;
+ 	rcu_read_lock();
+ 	delegation = rcu_dereference(nfsi->delegation);
+-	ret = (delegation != NULL && (delegation->type & flags) == flags);
++	ret = nfs4_is_valid_delegation(delegation, flags);
+ 	if (ret) {
+ 		nfs4_stateid_copy(dst, &delegation->stateid);
+ 		nfs_mark_delegation_referenced(delegation);
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 177fefb26c18..6bc5a68e39f1 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -435,11 +435,11 @@ int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
+ 		return 0;
+ 
+ 	nfsi = NFS_I(inode);
+-	if (entry->fattr->fileid == nfsi->fileid)
+-		return 1;
+-	if (nfs_compare_fh(entry->fh, &nfsi->fh) == 0)
+-		return 1;
+-	return 0;
++	if (entry->fattr->fileid != nfsi->fileid)
++		return 0;
++	if (entry->fh->size && nfs_compare_fh(entry->fh, &nfsi->fh) != 0)
++		return 0;
++	return 1;
+ }
+ 
+ static
+@@ -517,6 +517,8 @@ again:
+ 					&entry->fattr->fsid))
+ 			goto out;
+ 		if (nfs_same_file(dentry, entry)) {
++			if (!entry->fh->size)
++				goto out;
+ 			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+ 			status = nfs_refresh_inode(d_inode(dentry), entry->fattr);
+ 			if (!status)
+@@ -529,6 +531,10 @@ again:
+ 			goto again;
+ 		}
+ 	}
++	if (!entry->fh->size) {
++		d_lookup_done(dentry);
++		goto out;
++	}
+ 
+ 	inode = nfs_fhget(dentry->d_sb, entry->fh, entry->fattr, entry->label);
+ 	alias = d_splice_alias(inode, dentry);
+diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
+index 64b43b4ad9dd..608501971fe0 100644
+--- a/fs/nfs/nfs42proc.c
++++ b/fs/nfs/nfs42proc.c
+@@ -443,6 +443,7 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server,
+ 	task = rpc_run_task(&task_setup);
+ 	if (IS_ERR(task))
+ 		return PTR_ERR(task);
++	rpc_put_task(task);
+ 	return 0;
+ }
+ 
+diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
+index cada00aa5096..8353f33f0466 100644
+--- a/fs/nfs/nfs4state.c
++++ b/fs/nfs/nfs4state.c
+@@ -1498,6 +1498,9 @@ restart:
+ 					__func__, status);
+ 			case -ENOENT:
+ 			case -ENOMEM:
++			case -EACCES:
++			case -EROFS:
++			case -EIO:
+ 			case -ESTALE:
+ 				/* Open state on this file cannot be recovered */
+ 				nfs4_state_mark_recovery_failed(state, status);
+diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
+index 45007acaf364..a2b65fc56dd6 100644
+--- a/fs/nfsd/nfssvc.c
++++ b/fs/nfsd/nfssvc.c
+@@ -366,14 +366,21 @@ static struct notifier_block nfsd_inet6addr_notifier = {
+ };
+ #endif
+ 
++/* Only used under nfsd_mutex, so this atomic may be overkill: */
++static atomic_t nfsd_notifier_refcount = ATOMIC_INIT(0);
++
+ static void nfsd_last_thread(struct svc_serv *serv, struct net *net)
+ {
+ 	struct nfsd_net *nn = net_generic(net, nfsd_net_id);
+ 
+-	unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
++	/* check if the notifier still has clients */
++	if (atomic_dec_return(&nfsd_notifier_refcount) == 0) {
++		unregister_inetaddr_notifier(&nfsd_inetaddr_notifier);
+ #if IS_ENABLED(CONFIG_IPV6)
+-	unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
++		unregister_inet6addr_notifier(&nfsd_inet6addr_notifier);
+ #endif
++	}
++
+ 	/*
+ 	 * write_ports can create the server without actually starting
+ 	 * any threads--if we get shut down before any threads are
+@@ -488,10 +495,13 @@ int nfsd_create_serv(struct net *net)
+ 	}
+ 
+ 	set_max_drc();
+-	register_inetaddr_notifier(&nfsd_inetaddr_notifier);
++	/* check if the notifier is already set */
++	if (atomic_inc_return(&nfsd_notifier_refcount) == 1) {
++		register_inetaddr_notifier(&nfsd_inetaddr_notifier);
+ #if IS_ENABLED(CONFIG_IPV6)
+-	register_inet6addr_notifier(&nfsd_inet6addr_notifier);
++		register_inet6addr_notifier(&nfsd_inet6addr_notifier);
+ #endif
++	}
+ 	do_gettimeofday(&nn->nfssvc_boot);		/* record boot time */
+ 	return 0;
+ }
+diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index 43fdc2765aea..abadbc30e013 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -57,6 +57,7 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
+ 	ssize_t list_size, size, value_size = 0;
+ 	char *buf, *name, *value = NULL;
+ 	int uninitialized_var(error);
++	size_t slen;
+ 
+ 	if (!old->d_inode->i_op->getxattr ||
+ 	    !new->d_inode->i_op->getxattr)
+@@ -79,7 +80,16 @@ int ovl_copy_xattr(struct dentry *old, struct dentry *new)
+ 		goto out;
+ 	}
+ 
+-	for (name = buf; name < (buf + list_size); name += strlen(name) + 1) {
++	for (name = buf; list_size; name += slen) {
++		slen = strnlen(name, list_size) + 1;
++
++		/* underlying fs providing us with an broken xattr list? */
++		if (WARN_ON(slen > list_size)) {
++			error = -EIO;
++			break;
++		}
++		list_size -= slen;
++
+ 		if (ovl_is_private_xattr(name))
+ 			continue;
+ retry:
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index 1560fdc09a5f..74e696426aae 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -14,6 +14,7 @@
+ #include <linux/cred.h>
+ #include <linux/posix_acl.h>
+ #include <linux/posix_acl_xattr.h>
++#include <linux/atomic.h>
+ #include "overlayfs.h"
+ 
+ void ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
+@@ -37,8 +38,10 @@ struct dentry *ovl_lookup_temp(struct dentry *workdir, struct dentry *dentry)
+ {
+ 	struct dentry *temp;
+ 	char name[20];
++	static atomic_t temp_id = ATOMIC_INIT(0);
+ 
+-	snprintf(name, sizeof(name), "#%lx", (unsigned long) dentry);
++	/* counter is allowed to wrap, since temp dentries are ephemeral */
++	snprintf(name, sizeof(name), "#%x", atomic_inc_return(&temp_id));
+ 
+ 	temp = lookup_one_len(name, workdir, strlen(name));
+ 	if (!IS_ERR(temp) && temp->d_inode) {
+diff --git a/fs/pstore/ram.c b/fs/pstore/ram.c
+index 7a034d62cf8c..2340262a7e97 100644
+--- a/fs/pstore/ram.c
++++ b/fs/pstore/ram.c
+@@ -377,13 +377,14 @@ static void ramoops_free_przs(struct ramoops_context *cxt)
+ {
+ 	int i;
+ 
+-	cxt->max_dump_cnt = 0;
+ 	if (!cxt->przs)
+ 		return;
+ 
+-	for (i = 0; !IS_ERR_OR_NULL(cxt->przs[i]); i++)
++	for (i = 0; i < cxt->max_dump_cnt; i++)
+ 		persistent_ram_free(cxt->przs[i]);
++
+ 	kfree(cxt->przs);
++	cxt->max_dump_cnt = 0;
+ }
+ 
+ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
+@@ -408,7 +409,7 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
+ 			     GFP_KERNEL);
+ 	if (!cxt->przs) {
+ 		dev_err(dev, "failed to initialize a prz array for dumps\n");
+-		goto fail_prz;
++		goto fail_mem;
+ 	}
+ 
+ 	for (i = 0; i < cxt->max_dump_cnt; i++) {
+@@ -419,6 +420,11 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
+ 			err = PTR_ERR(cxt->przs[i]);
+ 			dev_err(dev, "failed to request mem region (0x%zx@0x%llx): %d\n",
+ 				cxt->record_size, (unsigned long long)*paddr, err);
++
++			while (i > 0) {
++				i--;
++				persistent_ram_free(cxt->przs[i]);
++			}
+ 			goto fail_prz;
+ 		}
+ 		*paddr += cxt->record_size;
+@@ -426,7 +432,9 @@ static int ramoops_init_przs(struct device *dev, struct ramoops_context *cxt,
+ 
+ 	return 0;
+ fail_prz:
+-	ramoops_free_przs(cxt);
++	kfree(cxt->przs);
++fail_mem:
++	cxt->max_dump_cnt = 0;
+ 	return err;
+ }
+ 
+@@ -659,7 +667,6 @@ static int ramoops_remove(struct platform_device *pdev)
+ 	struct ramoops_context *cxt = &oops_cxt;
+ 
+ 	pstore_unregister(&cxt->pstore);
+-	cxt->max_dump_cnt = 0;
+ 
+ 	kfree(cxt->pstore.buf);
+ 	cxt->pstore.bufsize = 0;
+diff --git a/fs/pstore/ram_core.c b/fs/pstore/ram_core.c
+index 76c3f80efdfa..364d2dffe5a6 100644
+--- a/fs/pstore/ram_core.c
++++ b/fs/pstore/ram_core.c
+@@ -47,43 +47,10 @@ static inline size_t buffer_start(struct persistent_ram_zone *prz)
+ 	return atomic_read(&prz->buffer->start);
+ }
+ 
+-/* increase and wrap the start pointer, returning the old value */
+-static size_t buffer_start_add_atomic(struct persistent_ram_zone *prz, size_t a)
+-{
+-	int old;
+-	int new;
+-
+-	do {
+-		old = atomic_read(&prz->buffer->start);
+-		new = old + a;
+-		while (unlikely(new >= prz->buffer_size))
+-			new -= prz->buffer_size;
+-	} while (atomic_cmpxchg(&prz->buffer->start, old, new) != old);
+-
+-	return old;
+-}
+-
+-/* increase the size counter until it hits the max size */
+-static void buffer_size_add_atomic(struct persistent_ram_zone *prz, size_t a)
+-{
+-	size_t old;
+-	size_t new;
+-
+-	if (atomic_read(&prz->buffer->size) == prz->buffer_size)
+-		return;
+-
+-	do {
+-		old = atomic_read(&prz->buffer->size);
+-		new = old + a;
+-		if (new > prz->buffer_size)
+-			new = prz->buffer_size;
+-	} while (atomic_cmpxchg(&prz->buffer->size, old, new) != old);
+-}
+-
+ static DEFINE_RAW_SPINLOCK(buffer_lock);
+ 
+ /* increase and wrap the start pointer, returning the old value */
+-static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
++static size_t buffer_start_add(struct persistent_ram_zone *prz, size_t a)
+ {
+ 	int old;
+ 	int new;
+@@ -103,7 +70,7 @@ static size_t buffer_start_add_locked(struct persistent_ram_zone *prz, size_t a)
+ }
+ 
+ /* increase the size counter until it hits the max size */
+-static void buffer_size_add_locked(struct persistent_ram_zone *prz, size_t a)
++static void buffer_size_add(struct persistent_ram_zone *prz, size_t a)
+ {
+ 	size_t old;
+ 	size_t new;
+@@ -124,9 +91,6 @@ exit:
+ 	raw_spin_unlock_irqrestore(&buffer_lock, flags);
+ }
+ 
+-static size_t (*buffer_start_add)(struct persistent_ram_zone *, size_t) = buffer_start_add_atomic;
+-static void (*buffer_size_add)(struct persistent_ram_zone *, size_t) = buffer_size_add_atomic;
+-
+ static void notrace persistent_ram_encode_rs8(struct persistent_ram_zone *prz,
+ 	uint8_t *data, size_t len, uint8_t *ecc)
+ {
+@@ -299,7 +263,7 @@ static void notrace persistent_ram_update(struct persistent_ram_zone *prz,
+ 	const void *s, unsigned int start, unsigned int count)
+ {
+ 	struct persistent_ram_buffer *buffer = prz->buffer;
+-	memcpy(buffer->data + start, s, count);
++	memcpy_toio(buffer->data + start, s, count);
+ 	persistent_ram_update_ecc(prz, start, count);
+ }
+ 
+@@ -322,8 +286,8 @@ void persistent_ram_save_old(struct persistent_ram_zone *prz)
+ 	}
+ 
+ 	prz->old_log_size = size;
+-	memcpy(prz->old_log, &buffer->data[start], size - start);
+-	memcpy(prz->old_log + size - start, &buffer->data[0], start);
++	memcpy_fromio(prz->old_log, &buffer->data[start], size - start);
++	memcpy_fromio(prz->old_log + size - start, &buffer->data[0], start);
+ }
+ 
+ int notrace persistent_ram_write(struct persistent_ram_zone *prz,
+@@ -426,9 +390,6 @@ static void *persistent_ram_iomap(phys_addr_t start, size_t size,
+ 		return NULL;
+ 	}
+ 
+-	buffer_start_add = buffer_start_add_locked;
+-	buffer_size_add = buffer_size_add_locked;
+-
+ 	if (memtype)
+ 		va = ioremap(start, size);
+ 	else
+diff --git a/fs/super.c b/fs/super.c
+index c2ff475c1711..47d11e0462d0 100644
+--- a/fs/super.c
++++ b/fs/super.c
+@@ -1379,8 +1379,8 @@ int freeze_super(struct super_block *sb)
+ 		}
+ 	}
+ 	/*
+-	 * This is just for debugging purposes so that fs can warn if it
+-	 * sees write activity when frozen is set to SB_FREEZE_COMPLETE.
++	 * For debugging purposes so that fs can warn if it sees write activity
++	 * when frozen is set to SB_FREEZE_COMPLETE, and for thaw_super().
+ 	 */
+ 	sb->s_writers.frozen = SB_FREEZE_COMPLETE;
+ 	up_write(&sb->s_umount);
+@@ -1399,7 +1399,7 @@ int thaw_super(struct super_block *sb)
+ 	int error;
+ 
+ 	down_write(&sb->s_umount);
+-	if (sb->s_writers.frozen == SB_UNFROZEN) {
++	if (sb->s_writers.frozen != SB_FREEZE_COMPLETE) {
+ 		up_write(&sb->s_umount);
+ 		return -EINVAL;
+ 	}
+diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
+index 11a004114eba..c9ee6f6efa07 100644
+--- a/fs/ubifs/xattr.c
++++ b/fs/ubifs/xattr.c
+@@ -172,6 +172,7 @@ out_cancel:
+ 	host_ui->xattr_cnt -= 1;
+ 	host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
+ 	host_ui->xattr_size -= CALC_XATTR_BYTES(size);
++	host_ui->xattr_names -= nm->len;
+ 	mutex_unlock(&host_ui->ui_mutex);
+ out_free:
+ 	make_bad_inode(inode);
+@@ -476,6 +477,7 @@ out_cancel:
+ 	host_ui->xattr_cnt += 1;
+ 	host_ui->xattr_size += CALC_DENT_SIZE(nm->len);
+ 	host_ui->xattr_size += CALC_XATTR_BYTES(ui->data_len);
++	host_ui->xattr_names += nm->len;
+ 	mutex_unlock(&host_ui->ui_mutex);
+ 	ubifs_release_budget(c, &req);
+ 	make_bad_inode(inode);
+diff --git a/include/dt-bindings/clock/imx6qdl-clock.h b/include/dt-bindings/clock/imx6qdl-clock.h
+index 29050337d9d5..da59fd9cdb5e 100644
+--- a/include/dt-bindings/clock/imx6qdl-clock.h
++++ b/include/dt-bindings/clock/imx6qdl-clock.h
+@@ -269,6 +269,8 @@
+ #define IMX6QDL_CLK_PRG0_APB			256
+ #define IMX6QDL_CLK_PRG1_APB			257
+ #define IMX6QDL_CLK_PRE_AXI			258
+-#define IMX6QDL_CLK_END				259
++#define IMX6QDL_CLK_MLB_SEL			259
++#define IMX6QDL_CLK_MLB_PODF			260
++#define IMX6QDL_CLK_END				261
+ 
+ #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
+diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h
+index 631ba33bbe9f..32dc0cbd51ca 100644
+--- a/include/linux/cpufreq.h
++++ b/include/linux/cpufreq.h
+@@ -639,19 +639,19 @@ static inline int cpufreq_table_find_index_al(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq >= target_freq)
+-			return i;
++			return pos - table;
+ 
+-		best = i;
++		best = pos;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Find lowest freq at or above target in a table in descending order */
+@@ -659,28 +659,28 @@ static inline int cpufreq_table_find_index_dl(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq == target_freq)
+-			return i;
++			return pos - table;
+ 
+ 		if (freq > target_freq) {
+-			best = i;
++			best = pos;
+ 			continue;
+ 		}
+ 
+ 		/* No freq found above target_freq */
+-		if (best == -1)
+-			return i;
++		if (best == table - 1)
++			return pos - table;
+ 
+-		return best;
++		return best - table;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Works only on sorted freq-tables */
+@@ -700,28 +700,28 @@ static inline int cpufreq_table_find_index_ah(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq == target_freq)
+-			return i;
++			return pos - table;
+ 
+ 		if (freq < target_freq) {
+-			best = i;
++			best = pos;
+ 			continue;
+ 		}
+ 
+ 		/* No freq found below target_freq */
+-		if (best == -1)
+-			return i;
++		if (best == table - 1)
++			return pos - table;
+ 
+-		return best;
++		return best - table;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Find highest freq at or below target in a table in descending order */
+@@ -729,19 +729,19 @@ static inline int cpufreq_table_find_index_dh(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq <= target_freq)
+-			return i;
++			return pos - table;
+ 
+-		best = i;
++		best = pos;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Works only on sorted freq-tables */
+@@ -761,32 +761,32 @@ static inline int cpufreq_table_find_index_ac(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq == target_freq)
+-			return i;
++			return pos - table;
+ 
+ 		if (freq < target_freq) {
+-			best = i;
++			best = pos;
+ 			continue;
+ 		}
+ 
+ 		/* No freq found below target_freq */
+-		if (best == -1)
+-			return i;
++		if (best == table - 1)
++			return pos - table;
+ 
+ 		/* Choose the closest freq */
+-		if (target_freq - table[best].frequency > freq - target_freq)
+-			return i;
++		if (target_freq - best->frequency > freq - target_freq)
++			return pos - table;
+ 
+-		return best;
++		return best - table;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Find closest freq to target in a table in descending order */
+@@ -794,32 +794,32 @@ static inline int cpufreq_table_find_index_dc(struct cpufreq_policy *policy,
+ 					      unsigned int target_freq)
+ {
+ 	struct cpufreq_frequency_table *table = policy->freq_table;
++	struct cpufreq_frequency_table *pos, *best = table - 1;
+ 	unsigned int freq;
+-	int i, best = -1;
+ 
+-	for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
+-		freq = table[i].frequency;
++	cpufreq_for_each_valid_entry(pos, table) {
++		freq = pos->frequency;
+ 
+ 		if (freq == target_freq)
+-			return i;
++			return pos - table;
+ 
+ 		if (freq > target_freq) {
+-			best = i;
++			best = pos;
+ 			continue;
+ 		}
+ 
+ 		/* No freq found above target_freq */
+-		if (best == -1)
+-			return i;
++		if (best == table - 1)
++			return pos - table;
+ 
+ 		/* Choose the closest freq */
+-		if (table[best].frequency - target_freq > target_freq - freq)
+-			return i;
++		if (best->frequency - target_freq > target_freq - freq)
++			return pos - table;
+ 
+-		return best;
++		return best - table;
+ 	}
+ 
+-	return best;
++	return best - table;
+ }
+ 
+ /* Works only on sorted freq-tables */
+diff --git a/include/linux/devfreq-event.h b/include/linux/devfreq-event.h
+index 0a83a1e648b0..4db00b02ca3f 100644
+--- a/include/linux/devfreq-event.h
++++ b/include/linux/devfreq-event.h
+@@ -148,11 +148,6 @@ static inline int devfreq_event_reset_event(struct devfreq_event_dev *edev)
+ 	return -EINVAL;
+ }
+ 
+-static inline void *devfreq_event_get_drvdata(struct devfreq_event_dev *edev)
+-{
+-	return ERR_PTR(-EINVAL);
+-}
+-
+ static inline struct devfreq_event_dev *devfreq_event_get_edev_by_phandle(
+ 					struct device *dev, int index)
+ {
+diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
+index 99ac022edc60..3a8610ea6ab7 100644
+--- a/include/linux/irqchip/arm-gic-v3.h
++++ b/include/linux/irqchip/arm-gic-v3.h
+@@ -290,7 +290,7 @@
+ #define GITS_BASER_TYPE_SHIFT			(56)
+ #define GITS_BASER_TYPE(r)		(((r) >> GITS_BASER_TYPE_SHIFT) & 7)
+ #define GITS_BASER_ENTRY_SIZE_SHIFT		(48)
+-#define GITS_BASER_ENTRY_SIZE(r)	((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0xff) + 1)
++#define GITS_BASER_ENTRY_SIZE(r)	((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
+ #define GITS_BASER_SHAREABILITY_SHIFT	(10)
+ #define GITS_BASER_InnerShareable					\
+ 	GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
+diff --git a/include/target/target_core_base.h b/include/target/target_core_base.h
+index fb8e3b6febdf..c2119008990a 100644
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -177,6 +177,7 @@ enum tcm_sense_reason_table {
+ 	TCM_LOGICAL_BLOCK_GUARD_CHECK_FAILED	= R(0x15),
+ 	TCM_LOGICAL_BLOCK_APP_TAG_CHECK_FAILED	= R(0x16),
+ 	TCM_LOGICAL_BLOCK_REF_TAG_CHECK_FAILED	= R(0x17),
++	TCM_COPY_TARGET_DEVICE_NOT_REACHABLE	= R(0x18),
+ #undef R
+ };
+ 
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index 039de34f1521..8b3610c871f2 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -456,17 +456,23 @@ static inline int entity_before(struct sched_entity *a,
+ 
+ static void update_min_vruntime(struct cfs_rq *cfs_rq)
+ {
++	struct sched_entity *curr = cfs_rq->curr;
++
+ 	u64 vruntime = cfs_rq->min_vruntime;
+ 
+-	if (cfs_rq->curr)
+-		vruntime = cfs_rq->curr->vruntime;
++	if (curr) {
++		if (curr->on_rq)
++			vruntime = curr->vruntime;
++		else
++			curr = NULL;
++	}
+ 
+ 	if (cfs_rq->rb_leftmost) {
+ 		struct sched_entity *se = rb_entry(cfs_rq->rb_leftmost,
+ 						   struct sched_entity,
+ 						   run_node);
+ 
+-		if (!cfs_rq->curr)
++		if (!curr)
+ 			vruntime = se->vruntime;
+ 		else
+ 			vruntime = min_vruntime(vruntime, se->vruntime);
+@@ -680,7 +686,14 @@ void init_entity_runnable_average(struct sched_entity *se)
+ 	 * will definitely be update (after enqueue).
+ 	 */
+ 	sa->period_contrib = 1023;
+-	sa->load_avg = scale_load_down(se->load.weight);
++	/*
++	 * Tasks are intialized with full load to be seen as heavy tasks until
++	 * they get a chance to stabilize to their real load level.
++	 * Group entities are intialized with zero load to reflect the fact that
++	 * nothing has been attached to the task group yet.
++	 */
++	if (entity_is_task(se))
++		sa->load_avg = scale_load_down(se->load.weight);
+ 	sa->load_sum = sa->load_avg * LOAD_AVG_MAX;
+ 	/*
+ 	 * At this point, util_avg won't be used in select_task_rq_fair anyway
+@@ -3459,9 +3472,10 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
+ 	account_entity_dequeue(cfs_rq, se);
+ 
+ 	/*
+-	 * Normalize the entity after updating the min_vruntime because the
+-	 * update can refer to the ->curr item and we need to reflect this
+-	 * movement in our normalized position.
++	 * Normalize after update_curr(); which will also have moved
++	 * min_vruntime if @se is the one holding it back. But before doing
++	 * update_min_vruntime() again, which will discount @se's position and
++	 * can move min_vruntime forward still more.
+ 	 */
+ 	if (!(flags & DEQUEUE_SLEEP))
+ 		se->vruntime -= cfs_rq->min_vruntime;
+@@ -3469,8 +3483,16 @@ dequeue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int flags)
+ 	/* return excess runtime on last dequeue */
+ 	return_cfs_rq_runtime(cfs_rq);
+ 
+-	update_min_vruntime(cfs_rq);
+ 	update_cfs_shares(cfs_rq);
++
++	/*
++	 * Now advance min_vruntime if @se was the entity holding it back,
++	 * except when: DEQUEUE_SAVE && !DEQUEUE_MOVE, in this case we'll be
++	 * put back on, and if we advance min_vruntime, we'll be placed back
++	 * further than we started -- ie. we'll be penalized.
++	 */
++	if ((flags & (DEQUEUE_SAVE | DEQUEUE_MOVE)) == DEQUEUE_SAVE)
++		update_min_vruntime(cfs_rq);
+ }
+ 
+ /*
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index bf168838a029..e72581da9648 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -473,7 +473,16 @@ static int xs_nospace(struct rpc_task *task)
+ 	spin_unlock_bh(&xprt->transport_lock);
+ 
+ 	/* Race breaker in case memory is freed before above code is called */
+-	sk->sk_write_space(sk);
++	if (ret == -EAGAIN) {
++		struct socket_wq *wq;
++
++		rcu_read_lock();
++		wq = rcu_dereference(sk->sk_wq);
++		set_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags);
++		rcu_read_unlock();
++
++		sk->sk_write_space(sk);
++	}
+ 	return ret;
+ }
+ 
+diff --git a/sound/pci/hda/dell_wmi_helper.c b/sound/pci/hda/dell_wmi_helper.c
+index 9c22f95838ef..19d41da79f93 100644
+--- a/sound/pci/hda/dell_wmi_helper.c
++++ b/sound/pci/hda/dell_wmi_helper.c
+@@ -49,7 +49,7 @@ static void alc_fixup_dell_wmi(struct hda_codec *codec,
+ 		removefunc = true;
+ 		if (dell_led_set_func(DELL_LED_MICMUTE, false) >= 0) {
+ 			dell_led_value = 0;
+-			if (spec->gen.num_adc_nids > 1)
++			if (spec->gen.num_adc_nids > 1 && !spec->gen.dyn_adc_switch)
+ 				codec_dbg(codec, "Skipping micmute LED control due to several ADCs");
+ 			else {
+ 				dell_old_cap_hook = spec->gen.cap_sync_hook;
+diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
+index f0955fd7a2e7..6a23302297c9 100644
+--- a/sound/pci/hda/thinkpad_helper.c
++++ b/sound/pci/hda/thinkpad_helper.c
+@@ -62,7 +62,7 @@ static void hda_fixup_thinkpad_acpi(struct hda_codec *codec,
+ 			removefunc = false;
+ 		}
+ 		if (led_set_func(TPACPI_LED_MICMUTE, false) >= 0) {
+-			if (spec->num_adc_nids > 1)
++			if (spec->num_adc_nids > 1 && !spec->dyn_adc_switch)
+ 				codec_dbg(codec,
+ 					  "Skipping micmute LED control due to several ADCs");
+ 			else {
+diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+index 8ff6c6a61291..c9c8dc330116 100644
+--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
++++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+@@ -89,6 +89,7 @@ struct intel_pt_decoder {
+ 	bool pge;
+ 	bool have_tma;
+ 	bool have_cyc;
++	bool fixup_last_mtc;
+ 	uint64_t pos;
+ 	uint64_t last_ip;
+ 	uint64_t ip;
+@@ -584,10 +585,31 @@ struct intel_pt_calc_cyc_to_tsc_info {
+ 	uint64_t        tsc_timestamp;
+ 	uint64_t        timestamp;
+ 	bool            have_tma;
++	bool            fixup_last_mtc;
+ 	bool            from_mtc;
+ 	double          cbr_cyc_to_tsc;
+ };
+ 
++/*
++ * MTC provides a 8-bit slice of CTC but the TMA packet only provides the lower
++ * 16 bits of CTC. If mtc_shift > 8 then some of the MTC bits are not in the CTC
++ * provided by the TMA packet. Fix-up the last_mtc calculated from the TMA
++ * packet by copying the missing bits from the current MTC assuming the least
++ * difference between the two, and that the current MTC comes after last_mtc.
++ */
++static void intel_pt_fixup_last_mtc(uint32_t mtc, int mtc_shift,
++				    uint32_t *last_mtc)
++{
++	uint32_t first_missing_bit = 1U << (16 - mtc_shift);
++	uint32_t mask = ~(first_missing_bit - 1);
++
++	*last_mtc |= mtc & mask;
++	if (*last_mtc >= mtc) {
++		*last_mtc -= first_missing_bit;
++		*last_mtc &= 0xff;
++	}
++}
++
+ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
+ {
+ 	struct intel_pt_decoder *decoder = pkt_info->decoder;
+@@ -617,6 +639,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
+ 			return 0;
+ 
+ 		mtc = pkt_info->packet.payload;
++		if (decoder->mtc_shift > 8 && data->fixup_last_mtc) {
++			data->fixup_last_mtc = false;
++			intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
++						&data->last_mtc);
++		}
+ 		if (mtc > data->last_mtc)
+ 			mtc_delta = mtc - data->last_mtc;
+ 		else
+@@ -685,6 +712,7 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
+ 
+ 		data->ctc_delta = 0;
+ 		data->have_tma = true;
++		data->fixup_last_mtc = true;
+ 
+ 		return 0;
+ 
+@@ -751,6 +779,7 @@ static void intel_pt_calc_cyc_to_tsc(struct intel_pt_decoder *decoder,
+ 		.tsc_timestamp  = decoder->tsc_timestamp,
+ 		.timestamp      = decoder->timestamp,
+ 		.have_tma       = decoder->have_tma,
++		.fixup_last_mtc = decoder->fixup_last_mtc,
+ 		.from_mtc       = from_mtc,
+ 		.cbr_cyc_to_tsc = 0,
+ 	};
+@@ -1241,6 +1270,7 @@ static void intel_pt_calc_tma(struct intel_pt_decoder *decoder)
+ 	}
+ 	decoder->ctc_delta = 0;
+ 	decoder->have_tma = true;
++	decoder->fixup_last_mtc = true;
+ 	intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x  CTC rem %#x\n",
+ 		     decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
+ }
+@@ -1255,6 +1285,12 @@ static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
+ 
+ 	mtc = decoder->packet.payload;
+ 
++	if (decoder->mtc_shift > 8 && decoder->fixup_last_mtc) {
++		decoder->fixup_last_mtc = false;
++		intel_pt_fixup_last_mtc(mtc, decoder->mtc_shift,
++					&decoder->last_mtc);
++	}
++
+ 	if (mtc > decoder->last_mtc)
+ 		mtc_delta = mtc - decoder->last_mtc;
+ 	else
+@@ -1323,6 +1359,8 @@ static void intel_pt_calc_cyc_timestamp(struct intel_pt_decoder *decoder)
+ 			     timestamp, decoder->timestamp);
+ 	else
+ 		decoder->timestamp = timestamp;
++
++	decoder->timestamp_insn_cnt = 0;
+ }
+ 
+ /* Walk PSB+ packets when already in sync. */
+diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
+index 551ff6f640be..b2878d2b2d67 100644
+--- a/tools/perf/util/intel-pt.c
++++ b/tools/perf/util/intel-pt.c
+@@ -241,7 +241,7 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data)
+ 	}
+ 
+ 	queue = &ptq->pt->queues.queue_array[ptq->queue_nr];
+-
++next:
+ 	buffer = auxtrace_buffer__next(queue, buffer);
+ 	if (!buffer) {
+ 		if (old_buffer)
+@@ -264,9 +264,6 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data)
+ 	    intel_pt_do_fix_overlap(ptq->pt, old_buffer, buffer))
+ 		return -ENOMEM;
+ 
+-	if (old_buffer)
+-		auxtrace_buffer__drop_data(old_buffer);
+-
+ 	if (buffer->use_data) {
+ 		b->len = buffer->use_size;
+ 		b->buf = buffer->use_data;
+@@ -276,6 +273,16 @@ static int intel_pt_get_trace(struct intel_pt_buffer *b, void *data)
+ 	}
+ 	b->ref_timestamp = buffer->reference;
+ 
++	/*
++	 * If in snapshot mode and the buffer has no usable data, get next
++	 * buffer and again check overlap against old_buffer.
++	 */
++	if (ptq->pt->snapshot_mode && !b->len)
++		goto next;
++
++	if (old_buffer)
++		auxtrace_buffer__drop_data(old_buffer);
++
+ 	if (!old_buffer || ptq->pt->sampling_mode || (ptq->pt->snapshot_mode &&
+ 						      !buffer->consecutive)) {
+ 		b->consecutive = false;
+diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c
+index 8a73d8185316..f3825b676e38 100644
+--- a/tools/spi/spidev_test.c
++++ b/tools/spi/spidev_test.c
+@@ -284,7 +284,7 @@ static void parse_opts(int argc, char *argv[])
+ 
+ static void transfer_escaped_string(int fd, char *str)
+ {
+-	size_t size = strlen(str + 1);
++	size_t size = strlen(str);
+ 	uint8_t *tx;
+ 	uint8_t *rx;
+ 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-10-31 12:34 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-10-31 12:34 UTC (permalink / raw
  To: gentoo-commits

commit:     27f3971a11c5ea990bee74d6c8fa48eed0fecadb
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 31 08:01:26 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Mon Oct 31 08:01:26 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=27f3971a

Linux patch 4.8.6

 0000_README            |    8 +-
 1005_linux-4.8.6.patch | 5137 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 5143 insertions(+), 2 deletions(-)

diff --git a/0000_README b/0000_README
index a5b48e4..cd373fa 100644
--- a/0000_README
+++ b/0000_README
@@ -59,9 +59,13 @@ Patch:  1003_linux-4.8.4.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.4
 
-Patch:  1003_linux-4.8.4.patch
+Patch:  1004_linux-4.8.5.patch
 From:   http://www.kernel.org
-Desc:   Linux 4.8.4
+Desc:   Linux 4.8.5
+
+Patch:  1005_linux-4.8.6.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.6
 
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644

diff --git a/1005_linux-4.8.6.patch b/1005_linux-4.8.6.patch
new file mode 100644
index 0000000..e2d7370
--- /dev/null
+++ b/1005_linux-4.8.6.patch
@@ -0,0 +1,5137 @@
+diff --git a/Makefile b/Makefile
+index daa3a01d2525..b249529204cd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 5
++SUBLEVEL = 6
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/boot/dts/arm-realview-eb.dtsi b/arch/arm/boot/dts/arm-realview-eb.dtsi
+index 1c6a040218e3..e2e9599596e2 100644
+--- a/arch/arm/boot/dts/arm-realview-eb.dtsi
++++ b/arch/arm/boot/dts/arm-realview-eb.dtsi
+@@ -51,14 +51,6 @@
+ 		regulator-boot-on;
+         };
+ 
+-	veth: fixedregulator@0 {
+-		compatible = "regulator-fixed";
+-		regulator-name = "veth";
+-		regulator-min-microvolt = <3300000>;
+-		regulator-max-microvolt = <3300000>;
+-		regulator-boot-on;
+-	};
+-
+ 	xtal24mhz: xtal24mhz@24M {
+ 		#clock-cells = <0>;
+ 		compatible = "fixed-clock";
+@@ -134,16 +126,15 @@
+ 		bank-width = <4>;
+ 	};
+ 
+-	/* SMSC 9118 ethernet with PHY and EEPROM */
++	/* SMSC LAN91C111 ethernet with PHY and EEPROM */
+ 	ethernet: ethernet@4e000000 {
+-		compatible = "smsc,lan9118", "smsc,lan9115";
++		compatible = "smsc,lan91c111";
+ 		reg = <0x4e000000 0x10000>;
+-		phy-mode = "mii";
+-		reg-io-width = <4>;
+-		smsc,irq-active-high;
+-		smsc,irq-push-pull;
+-		vdd33a-supply = <&veth>;
+-		vddvario-supply = <&veth>;
++		/*
++		 * This means the adapter can be accessed with 8, 16 or
++		 * 32 bit reads/writes.
++		 */
++		reg-io-width = <7>;
+ 	};
+ 
+ 	usb: usb@4f000000 {
+diff --git a/arch/arm/boot/dts/bcm958625hr.dts b/arch/arm/boot/dts/bcm958625hr.dts
+index 03b8bbeb694f..652418aa2700 100644
+--- a/arch/arm/boot/dts/bcm958625hr.dts
++++ b/arch/arm/boot/dts/bcm958625hr.dts
+@@ -47,7 +47,8 @@
+ 	};
+ 
+ 	memory {
+-		reg = <0x60000000 0x20000000>;
++		device_type = "memory";
++		reg = <0x60000000 0x80000000>;
+ 	};
+ };
+ 
+diff --git a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
+index ca86da68220c..854117dc0b77 100644
+--- a/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
++++ b/arch/arm/boot/dts/omap3-overo-common-lcd35.dtsi
+@@ -119,7 +119,7 @@
+ 	pinctrl-names = "default";
+ 	pinctrl-0 = <&mcspi1_pins>;
+ 
+-	lcd0: display {
++	lcd0: display@1 {
+ 		compatible = "lgphilips,lb035q02";
+ 		label = "lcd35";
+ 
+diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
+index f68b3242b33a..3f528a379288 100644
+--- a/arch/arm/boot/dts/sun9i-a80.dtsi
++++ b/arch/arm/boot/dts/sun9i-a80.dtsi
+@@ -899,8 +899,7 @@
+ 			resets = <&apbs_rst 0>;
+ 			gpio-controller;
+ 			interrupt-controller;
+-			#address-cells = <1>;
+-			#size-cells = <0>;
++			#interrupt-cells = <3>;
+ 			#gpio-cells = <3>;
+ 
+ 			r_ir_pins: r_ir {
+diff --git a/arch/arm/crypto/ghash-ce-glue.c b/arch/arm/crypto/ghash-ce-glue.c
+index 1568cb5cd870..b88364aa149a 100644
+--- a/arch/arm/crypto/ghash-ce-glue.c
++++ b/arch/arm/crypto/ghash-ce-glue.c
+@@ -220,6 +220,27 @@ static int ghash_async_digest(struct ahash_request *req)
+ 	}
+ }
+ 
++static int ghash_async_import(struct ahash_request *req, const void *in)
++{
++	struct ahash_request *cryptd_req = ahash_request_ctx(req);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
++	struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
++	struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
++
++	desc->tfm = cryptd_ahash_child(ctx->cryptd_tfm);
++	desc->flags = req->base.flags;
++
++	return crypto_shash_import(desc, in);
++}
++
++static int ghash_async_export(struct ahash_request *req, void *out)
++{
++	struct ahash_request *cryptd_req = ahash_request_ctx(req);
++	struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
++
++	return crypto_shash_export(desc, out);
++}
++
+ static int ghash_async_setkey(struct crypto_ahash *tfm, const u8 *key,
+ 			      unsigned int keylen)
+ {
+@@ -268,7 +289,10 @@ static struct ahash_alg ghash_async_alg = {
+ 	.final			= ghash_async_final,
+ 	.setkey			= ghash_async_setkey,
+ 	.digest			= ghash_async_digest,
++	.import			= ghash_async_import,
++	.export			= ghash_async_export,
+ 	.halg.digestsize	= GHASH_DIGEST_SIZE,
++	.halg.statesize		= sizeof(struct ghash_desc_ctx),
+ 	.halg.base		= {
+ 		.cra_name	= "ghash",
+ 		.cra_driver_name = "ghash-ce",
+diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c
+index d9206811be9b..c71c483f410e 100644
+--- a/arch/arm/mach-pxa/corgi_pm.c
++++ b/arch/arm/mach-pxa/corgi_pm.c
+@@ -131,16 +131,11 @@ static int corgi_should_wakeup(unsigned int resume_on_alarm)
+ 	return is_resume;
+ }
+ 
+-static unsigned long corgi_charger_wakeup(void)
++static bool corgi_charger_wakeup(void)
+ {
+-	unsigned long ret;
+-
+-	ret = (!gpio_get_value(CORGI_GPIO_AC_IN) << GPIO_bit(CORGI_GPIO_AC_IN))
+-		| (!gpio_get_value(CORGI_GPIO_KEY_INT)
+-		<< GPIO_bit(CORGI_GPIO_KEY_INT))
+-		| (!gpio_get_value(CORGI_GPIO_WAKEUP)
+-		<< GPIO_bit(CORGI_GPIO_WAKEUP));
+-	return ret;
++	return !gpio_get_value(CORGI_GPIO_AC_IN) ||
++		!gpio_get_value(CORGI_GPIO_KEY_INT) ||
++		!gpio_get_value(CORGI_GPIO_WAKEUP);
+ }
+ 
+ unsigned long corgipm_read_devdata(int type)
+diff --git a/arch/arm/mach-pxa/pxa_cplds_irqs.c b/arch/arm/mach-pxa/pxa_cplds_irqs.c
+index 2385052b0ce1..e362f865fcd2 100644
+--- a/arch/arm/mach-pxa/pxa_cplds_irqs.c
++++ b/arch/arm/mach-pxa/pxa_cplds_irqs.c
+@@ -41,30 +41,35 @@ static irqreturn_t cplds_irq_handler(int in_irq, void *d)
+ 	unsigned long pending;
+ 	unsigned int bit;
+ 
+-	pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
+-	for_each_set_bit(bit, &pending, CPLDS_NB_IRQ)
+-		generic_handle_irq(irq_find_mapping(fpga->irqdomain, bit));
++	do {
++		pending = readl(fpga->base + FPGA_IRQ_SET_CLR) & fpga->irq_mask;
++		for_each_set_bit(bit, &pending, CPLDS_NB_IRQ) {
++			generic_handle_irq(irq_find_mapping(fpga->irqdomain,
++							    bit));
++		}
++	} while (pending);
+ 
+ 	return IRQ_HANDLED;
+ }
+ 
+-static void cplds_irq_mask_ack(struct irq_data *d)
++static void cplds_irq_mask(struct irq_data *d)
+ {
+ 	struct cplds *fpga = irq_data_get_irq_chip_data(d);
+ 	unsigned int cplds_irq = irqd_to_hwirq(d);
+-	unsigned int set, bit = BIT(cplds_irq);
++	unsigned int bit = BIT(cplds_irq);
+ 
+ 	fpga->irq_mask &= ~bit;
+ 	writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+-	set = readl(fpga->base + FPGA_IRQ_SET_CLR);
+-	writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
+ }
+ 
+ static void cplds_irq_unmask(struct irq_data *d)
+ {
+ 	struct cplds *fpga = irq_data_get_irq_chip_data(d);
+ 	unsigned int cplds_irq = irqd_to_hwirq(d);
+-	unsigned int bit = BIT(cplds_irq);
++	unsigned int set, bit = BIT(cplds_irq);
++
++	set = readl(fpga->base + FPGA_IRQ_SET_CLR);
++	writel(set & ~bit, fpga->base + FPGA_IRQ_SET_CLR);
+ 
+ 	fpga->irq_mask |= bit;
+ 	writel(fpga->irq_mask, fpga->base + FPGA_IRQ_MASK_EN);
+@@ -72,7 +77,8 @@ static void cplds_irq_unmask(struct irq_data *d)
+ 
+ static struct irq_chip cplds_irq_chip = {
+ 	.name		= "pxa_cplds",
+-	.irq_mask_ack	= cplds_irq_mask_ack,
++	.irq_ack	= cplds_irq_mask,
++	.irq_mask	= cplds_irq_mask,
+ 	.irq_unmask	= cplds_irq_unmask,
+ 	.flags		= IRQCHIP_MASK_ON_SUSPEND | IRQCHIP_SKIP_SET_WAKE,
+ };
+diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c
+index b80eab9993c5..249b7bd5fbc4 100644
+--- a/arch/arm/mach-pxa/sharpsl_pm.c
++++ b/arch/arm/mach-pxa/sharpsl_pm.c
+@@ -744,7 +744,7 @@ static int sharpsl_off_charge_battery(void)
+ 		time = RCNR;
+ 		while (1) {
+ 			/* Check if any wakeup event had occurred */
+-			if (sharpsl_pm.machinfo->charger_wakeup() != 0)
++			if (sharpsl_pm.machinfo->charger_wakeup())
+ 				return 0;
+ 			/* Check for timeout */
+ 			if ((RCNR - time) > SHARPSL_WAIT_CO_TIME)
+diff --git a/arch/arm/mach-pxa/sharpsl_pm.h b/arch/arm/mach-pxa/sharpsl_pm.h
+index 905be6755f04..fa75b6df8134 100644
+--- a/arch/arm/mach-pxa/sharpsl_pm.h
++++ b/arch/arm/mach-pxa/sharpsl_pm.h
+@@ -34,7 +34,7 @@ struct sharpsl_charger_machinfo {
+ #define SHARPSL_STATUS_LOCK     5
+ #define SHARPSL_STATUS_CHRGFULL 6
+ #define SHARPSL_STATUS_FATAL    7
+-	unsigned long (*charger_wakeup)(void);
++	bool (*charger_wakeup)(void);
+ 	int (*should_wakeup)(unsigned int resume_on_alarm);
+ 	void (*backlight_limit)(int);
+ 	int (*backlight_get_status) (void);
+diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c
+index ea9f9034cb54..4e64a140252e 100644
+--- a/arch/arm/mach-pxa/spitz_pm.c
++++ b/arch/arm/mach-pxa/spitz_pm.c
+@@ -165,13 +165,10 @@ static int spitz_should_wakeup(unsigned int resume_on_alarm)
+ 	return is_resume;
+ }
+ 
+-static unsigned long spitz_charger_wakeup(void)
++static bool spitz_charger_wakeup(void)
+ {
+-	unsigned long ret;
+-	ret = ((!gpio_get_value(SPITZ_GPIO_KEY_INT)
+-		<< GPIO_bit(SPITZ_GPIO_KEY_INT))
+-		| gpio_get_value(SPITZ_GPIO_SYNC));
+-	return ret;
++	return !gpio_get_value(SPITZ_GPIO_KEY_INT) ||
++		gpio_get_value(SPITZ_GPIO_SYNC);
+ }
+ 
+ unsigned long spitzpm_read_devdata(int type)
+diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h
+index 263bf39ced40..9bd84ba06ec4 100644
+--- a/arch/powerpc/include/asm/book3s/64/pgtable.h
++++ b/arch/powerpc/include/asm/book3s/64/pgtable.h
+@@ -6,6 +6,8 @@
+  */
+ #define _PAGE_BIT_SWAP_TYPE	0
+ 
++#define _PAGE_RO		0
++
+ #define _PAGE_EXEC		0x00001 /* execute permission */
+ #define _PAGE_WRITE		0x00002 /* write access allowed */
+ #define _PAGE_READ		0x00004	/* read access allowed */
+diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c
+index 64174bf95611..05a0a913ec38 100644
+--- a/arch/powerpc/kernel/nvram_64.c
++++ b/arch/powerpc/kernel/nvram_64.c
+@@ -956,7 +956,7 @@ int __init nvram_remove_partition(const char *name, int sig,
+ 
+ 		/* Make partition a free partition */
+ 		part->header.signature = NVRAM_SIG_FREE;
+-		strncpy(part->header.name, "wwwwwwwwwwww", 12);
++		memset(part->header.name, 'w', 12);
+ 		part->header.checksum = nvram_checksum(&part->header);
+ 		rc = nvram_write_header(part);
+ 		if (rc <= 0) {
+@@ -974,8 +974,8 @@ int __init nvram_remove_partition(const char *name, int sig,
+ 		}
+ 		if (prev) {
+ 			prev->header.length += part->header.length;
+-			prev->header.checksum = nvram_checksum(&part->header);
+-			rc = nvram_write_header(part);
++			prev->header.checksum = nvram_checksum(&prev->header);
++			rc = nvram_write_header(prev);
+ 			if (rc <= 0) {
+ 				printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc);
+ 				return rc;
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index 9ee2623e0f67..ad37aa175f59 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -88,7 +88,13 @@ static void check_if_tm_restore_required(struct task_struct *tsk)
+ 		set_thread_flag(TIF_RESTORE_TM);
+ 	}
+ }
++
++static inline bool msr_tm_active(unsigned long msr)
++{
++	return MSR_TM_ACTIVE(msr);
++}
+ #else
++static inline bool msr_tm_active(unsigned long msr) { return false; }
+ static inline void check_if_tm_restore_required(struct task_struct *tsk) { }
+ #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+ 
+@@ -208,7 +214,7 @@ void enable_kernel_fp(void)
+ EXPORT_SYMBOL(enable_kernel_fp);
+ 
+ static int restore_fp(struct task_struct *tsk) {
+-	if (tsk->thread.load_fp) {
++	if (tsk->thread.load_fp || msr_tm_active(tsk->thread.regs->msr)) {
+ 		load_fp_state(&current->thread.fp_state);
+ 		current->thread.load_fp++;
+ 		return 1;
+@@ -278,7 +284,8 @@ EXPORT_SYMBOL_GPL(flush_altivec_to_thread);
+ 
+ static int restore_altivec(struct task_struct *tsk)
+ {
+-	if (cpu_has_feature(CPU_FTR_ALTIVEC) && tsk->thread.load_vec) {
++	if (cpu_has_feature(CPU_FTR_ALTIVEC) &&
++		(tsk->thread.load_vec || msr_tm_active(tsk->thread.regs->msr))) {
+ 		load_vr_state(&tsk->thread.vr_state);
+ 		tsk->thread.used_vr = 1;
+ 		tsk->thread.load_vec++;
+@@ -438,6 +445,7 @@ void giveup_all(struct task_struct *tsk)
+ 		return;
+ 
+ 	msr_check_and_set(msr_all_available);
++	check_if_tm_restore_required(tsk);
+ 
+ #ifdef CONFIG_PPC_FPU
+ 	if (usermsr & MSR_FP)
+@@ -464,7 +472,8 @@ void restore_math(struct pt_regs *regs)
+ {
+ 	unsigned long msr;
+ 
+-	if (!current->thread.load_fp && !loadvec(current->thread))
++	if (!msr_tm_active(regs->msr) &&
++		!current->thread.load_fp && !loadvec(current->thread))
+ 		return;
+ 
+ 	msr = regs->msr;
+@@ -983,6 +992,13 @@ void restore_tm_state(struct pt_regs *regs)
+ 	msr_diff = current->thread.ckpt_regs.msr & ~regs->msr;
+ 	msr_diff &= MSR_FP | MSR_VEC | MSR_VSX;
+ 
++	/* Ensure that restore_math() will restore */
++	if (msr_diff & MSR_FP)
++		current->thread.load_fp = 1;
++#ifdef CONFIG_ALIVEC
++	if (cpu_has_feature(CPU_FTR_ALTIVEC) && msr_diff & MSR_VEC)
++		current->thread.load_vec = 1;
++#endif
+ 	restore_math(regs);
+ 
+ 	regs->msr |= msr_diff;
+diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c
+index 7372ee13eb1e..a5d3ecdabc44 100644
+--- a/arch/powerpc/mm/hugetlbpage.c
++++ b/arch/powerpc/mm/hugetlbpage.c
+@@ -1019,8 +1019,15 @@ int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
+ 
+ 	pte = READ_ONCE(*ptep);
+ 	mask = _PAGE_PRESENT | _PAGE_READ;
++
++	/*
++	 * On some CPUs like the 8xx, _PAGE_RW hence _PAGE_WRITE is defined
++	 * as 0 and _PAGE_RO has to be set when a page is not writable
++	 */
+ 	if (write)
+ 		mask |= _PAGE_WRITE;
++	else
++		mask |= _PAGE_RO;
+ 
+ 	if ((pte_val(pte) & mask) != mask)
+ 		return 0;
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index de7501edb21c..8b8852bc2f4a 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -317,16 +317,11 @@ static phys_addr_t __init i85x_stolen_base(int num, int slot, int func,
+ static phys_addr_t __init i865_stolen_base(int num, int slot, int func,
+ 					   size_t stolen_size)
+ {
+-	u16 toud;
++	u16 toud = 0;
+ 
+-	/*
+-	 * FIXME is the graphics stolen memory region
+-	 * always at TOUD? Ie. is it always the last
+-	 * one to be allocated by the BIOS?
+-	 */
+ 	toud = read_pci_config_16(0, 0, 0, I865_TOUD);
+ 
+-	return (phys_addr_t)toud << 16;
++	return (phys_addr_t)(toud << 16) + i845_tseg_size();
+ }
+ 
+ static phys_addr_t __init gen3_stolen_base(int num, int slot, int func,
+diff --git a/crypto/gcm.c b/crypto/gcm.c
+index 70a892e87ccb..f624ac98c94e 100644
+--- a/crypto/gcm.c
++++ b/crypto/gcm.c
+@@ -117,7 +117,7 @@ static int crypto_gcm_setkey(struct crypto_aead *aead, const u8 *key,
+ 	struct crypto_skcipher *ctr = ctx->ctr;
+ 	struct {
+ 		be128 hash;
+-		u8 iv[8];
++		u8 iv[16];
+ 
+ 		struct crypto_gcm_setkey_result result;
+ 
+diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c
+index 01d4be2c354b..f5c26a5f6875 100644
+--- a/drivers/char/hw_random/omap-rng.c
++++ b/drivers/char/hw_random/omap-rng.c
+@@ -385,7 +385,7 @@ static int omap_rng_probe(struct platform_device *pdev)
+ 
+ 	pm_runtime_enable(&pdev->dev);
+ 	ret = pm_runtime_get_sync(&pdev->dev);
+-	if (ret) {
++	if (ret < 0) {
+ 		dev_err(&pdev->dev, "Failed to runtime_get device: %d\n", ret);
+ 		pm_runtime_put_noidle(&pdev->dev);
+ 		goto err_ioremap;
+@@ -443,7 +443,7 @@ static int __maybe_unused omap_rng_resume(struct device *dev)
+ 	int ret;
+ 
+ 	ret = pm_runtime_get_sync(dev);
+-	if (ret) {
++	if (ret < 0) {
+ 		dev_err(dev, "Failed to runtime_get device: %d\n", ret);
+ 		pm_runtime_put_noidle(dev);
+ 		return ret;
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 7a7970865c2d..0fc71cbaa440 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1006,16 +1006,28 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
+ 	return 0;
+ }
+ 
++static bool
++bcm2835_clk_is_pllc(struct clk_hw *hw)
++{
++	if (!hw)
++		return false;
++
++	return strncmp(clk_hw_get_name(hw), "pllc", 4) == 0;
++}
++
+ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
+ 					struct clk_rate_request *req)
+ {
+ 	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
+ 	struct clk_hw *parent, *best_parent = NULL;
++	bool current_parent_is_pllc;
+ 	unsigned long rate, best_rate = 0;
+ 	unsigned long prate, best_prate = 0;
+ 	size_t i;
+ 	u32 div;
+ 
++	current_parent_is_pllc = bcm2835_clk_is_pllc(clk_hw_get_parent(hw));
++
+ 	/*
+ 	 * Select parent clock that results in the closest but lower rate
+ 	 */
+@@ -1023,6 +1035,17 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw,
+ 		parent = clk_hw_get_parent_by_index(hw, i);
+ 		if (!parent)
+ 			continue;
++
++		/*
++		 * Don't choose a PLLC-derived clock as our parent
++		 * unless it had been manually set that way.  PLLC's
++		 * frequency gets adjusted by the firmware due to
++		 * over-temp or under-voltage conditions, without
++		 * prior notification to our clock consumer.
++		 */
++		if (bcm2835_clk_is_pllc(parent) && !current_parent_is_pllc)
++			continue;
++
+ 		prate = clk_hw_get_rate(parent);
+ 		div = bcm2835_clock_choose_div(hw, req->rate, prate, true);
+ 		rate = bcm2835_clock_rate_from_divisor(clock, prate, div);
+diff --git a/drivers/clk/clk-divider.c b/drivers/clk/clk-divider.c
+index a0f55bc1ad3d..96386ffc8483 100644
+--- a/drivers/clk/clk-divider.c
++++ b/drivers/clk/clk-divider.c
+@@ -352,7 +352,7 @@ static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
+ 
+ 	/* if read only, just return current value */
+ 	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
+-		bestdiv = readl(divider->reg) >> divider->shift;
++		bestdiv = clk_readl(divider->reg) >> divider->shift;
+ 		bestdiv &= div_mask(divider->width);
+ 		bestdiv = _get_div(divider->table, bestdiv, divider->flags,
+ 			divider->width);
+diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
+index 58566a17944a..20b105584f82 100644
+--- a/drivers/clk/clk-qoriq.c
++++ b/drivers/clk/clk-qoriq.c
+@@ -766,7 +766,11 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
+ 	if (!hwc)
+ 		return NULL;
+ 
+-	hwc->reg = cg->regs + 0x20 * idx;
++	if (cg->info.flags & CG_VER3)
++		hwc->reg = cg->regs + 0x70000 + 0x20 * idx;
++	else
++		hwc->reg = cg->regs + 0x20 * idx;
++
+ 	hwc->info = cg->info.cmux_groups[cg->info.cmux_to_group[idx]];
+ 
+ 	/*
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
+index 820a939fb6bb..2877a4ddeda2 100644
+--- a/drivers/clk/clk.c
++++ b/drivers/clk/clk.c
+@@ -1908,10 +1908,6 @@ int clk_set_phase(struct clk *clk, int degrees)
+ 
+ 	clk_prepare_lock();
+ 
+-	/* bail early if nothing to do */
+-	if (degrees == clk->core->phase)
+-		goto out;
+-
+ 	trace_clk_set_phase(clk->core, degrees);
+ 
+ 	if (clk->core->ops->set_phase)
+@@ -1922,7 +1918,6 @@ int clk_set_phase(struct clk *clk, int degrees)
+ 	if (!ret)
+ 		clk->core->phase = degrees;
+ 
+-out:
+ 	clk_prepare_unlock();
+ 
+ 	return ret;
+@@ -3186,7 +3181,7 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
+ {
+ 	struct of_clk_provider *provider;
+ 	struct clk *clk = ERR_PTR(-EPROBE_DEFER);
+-	struct clk_hw *hw = ERR_PTR(-EPROBE_DEFER);
++	struct clk_hw *hw;
+ 
+ 	if (!clkspec)
+ 		return ERR_PTR(-EINVAL);
+@@ -3194,12 +3189,13 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
+ 	/* Check if we have such a provider in our array */
+ 	mutex_lock(&of_clk_mutex);
+ 	list_for_each_entry(provider, &of_clk_providers, link) {
+-		if (provider->node == clkspec->np)
++		if (provider->node == clkspec->np) {
+ 			hw = __of_clk_get_hw_from_provider(provider, clkspec);
+-		if (!IS_ERR(hw)) {
+ 			clk = __clk_create_clk(hw, dev_id, con_id);
++		}
+ 
+-			if (!IS_ERR(clk) && !__clk_get(clk)) {
++		if (!IS_ERR(clk)) {
++			if (!__clk_get(clk)) {
+ 				__clk_free_clk(clk);
+ 				clk = ERR_PTR(-ENOENT);
+ 			}
+diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
+index b0978d3b83e2..d302ed3b8225 100644
+--- a/drivers/clk/imx/clk-imx35.c
++++ b/drivers/clk/imx/clk-imx35.c
+@@ -115,7 +115,7 @@ static void __init _mx35_clocks_init(void)
+ 	}
+ 
+ 	clk[ckih] = imx_clk_fixed("ckih", 24000000);
+-	clk[ckil] = imx_clk_fixed("ckih", 32768);
++	clk[ckil] = imx_clk_fixed("ckil", 32768);
+ 	clk[mpll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "mpll", "ckih", base + MX35_CCM_MPCTL);
+ 	clk[ppll] = imx_clk_pllv1(IMX_PLLV1_IMX35, "ppll", "ckih", base + MX35_CCM_PPCTL);
+ 
+diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig
+index 95e3b3e0fa1c..98909b184d44 100644
+--- a/drivers/clk/qcom/Kconfig
++++ b/drivers/clk/qcom/Kconfig
+@@ -117,6 +117,7 @@ config MSM_MMCC_8974
+ 
+ config MSM_GCC_8996
+ 	tristate "MSM8996 Global Clock Controller"
++	select QCOM_GDSC
+ 	depends on COMMON_CLK_QCOM
+ 	help
+ 	  Support for the global clock controller on msm8996 devices.
+@@ -126,6 +127,7 @@ config MSM_GCC_8996
+ config MSM_MMCC_8996
+ 	tristate "MSM8996 Multimedia Clock Controller"
+ 	select MSM_GCC_8996
++	select QCOM_GDSC
+ 	depends on COMMON_CLK_QCOM
+ 	help
+ 	  Support for the multimedia clock controller on msm8996 devices.
+diff --git a/drivers/clk/qcom/gcc-msm8996.c b/drivers/clk/qcom/gcc-msm8996.c
+index bbf732bbc3fd..9f643cca85d0 100644
+--- a/drivers/clk/qcom/gcc-msm8996.c
++++ b/drivers/clk/qcom/gcc-msm8996.c
+@@ -2592,9 +2592,9 @@ static struct clk_branch gcc_pcie_2_aux_clk = {
+ };
+ 
+ static struct clk_branch gcc_pcie_2_pipe_clk = {
+-	.halt_reg = 0x6e108,
++	.halt_reg = 0x6e018,
+ 	.clkr = {
+-		.enable_reg = 0x6e108,
++		.enable_reg = 0x6e018,
+ 		.enable_mask = BIT(0),
+ 		.hw.init = &(struct clk_init_data){
+ 			.name = "gcc_pcie_2_pipe_clk",
+diff --git a/drivers/crypto/ccp/ccp-dmaengine.c b/drivers/crypto/ccp/ccp-dmaengine.c
+index 94f77b0f9ae7..32f645ea77b8 100644
+--- a/drivers/crypto/ccp/ccp-dmaengine.c
++++ b/drivers/crypto/ccp/ccp-dmaengine.c
+@@ -650,7 +650,7 @@ int ccp_dmaengine_register(struct ccp_device *ccp)
+ 	dma_desc_cache_name = devm_kasprintf(ccp->dev, GFP_KERNEL,
+ 					     "%s-dmaengine-desc-cache",
+ 					     ccp->name);
+-	if (!dma_cmd_cache_name)
++	if (!dma_desc_cache_name)
+ 		return -ENOMEM;
+ 	ccp->dma_desc_cache = kmem_cache_create(dma_desc_cache_name,
+ 						sizeof(struct ccp_dma_desc),
+diff --git a/drivers/crypto/marvell/cesa.c b/drivers/crypto/marvell/cesa.c
+index d64af8625d7e..37dadb2a4feb 100644
+--- a/drivers/crypto/marvell/cesa.c
++++ b/drivers/crypto/marvell/cesa.c
+@@ -166,6 +166,7 @@ static irqreturn_t mv_cesa_int(int irq, void *priv)
+ 			if (!req)
+ 				break;
+ 
++			ctx = crypto_tfm_ctx(req->tfm);
+ 			mv_cesa_complete_req(ctx, req, 0);
+ 		}
+ 	}
+diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
+index 82e0f4e6eb1c..b111e14bac1e 100644
+--- a/drivers/crypto/marvell/hash.c
++++ b/drivers/crypto/marvell/hash.c
+@@ -805,13 +805,14 @@ static int mv_cesa_md5_init(struct ahash_request *req)
+ 	struct mv_cesa_op_ctx tmpl = { };
+ 
+ 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_MD5);
++
++	mv_cesa_ahash_init(req, &tmpl, true);
++
+ 	creq->state[0] = MD5_H0;
+ 	creq->state[1] = MD5_H1;
+ 	creq->state[2] = MD5_H2;
+ 	creq->state[3] = MD5_H3;
+ 
+-	mv_cesa_ahash_init(req, &tmpl, true);
+-
+ 	return 0;
+ }
+ 
+@@ -873,14 +874,15 @@ static int mv_cesa_sha1_init(struct ahash_request *req)
+ 	struct mv_cesa_op_ctx tmpl = { };
+ 
+ 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA1);
++
++	mv_cesa_ahash_init(req, &tmpl, false);
++
+ 	creq->state[0] = SHA1_H0;
+ 	creq->state[1] = SHA1_H1;
+ 	creq->state[2] = SHA1_H2;
+ 	creq->state[3] = SHA1_H3;
+ 	creq->state[4] = SHA1_H4;
+ 
+-	mv_cesa_ahash_init(req, &tmpl, false);
+-
+ 	return 0;
+ }
+ 
+@@ -942,6 +944,9 @@ static int mv_cesa_sha256_init(struct ahash_request *req)
+ 	struct mv_cesa_op_ctx tmpl = { };
+ 
+ 	mv_cesa_set_op_cfg(&tmpl, CESA_SA_DESC_CFG_MACM_SHA256);
++
++	mv_cesa_ahash_init(req, &tmpl, false);
++
+ 	creq->state[0] = SHA256_H0;
+ 	creq->state[1] = SHA256_H1;
+ 	creq->state[2] = SHA256_H2;
+@@ -951,8 +956,6 @@ static int mv_cesa_sha256_init(struct ahash_request *req)
+ 	creq->state[6] = SHA256_H6;
+ 	creq->state[7] = SHA256_H7;
+ 
+-	mv_cesa_ahash_init(req, &tmpl, false);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
+index 2bf37e68ad0f..dd184b50e5b4 100644
+--- a/drivers/dma/ipu/ipu_irq.c
++++ b/drivers/dma/ipu/ipu_irq.c
+@@ -286,22 +286,21 @@ static void ipu_irq_handler(struct irq_desc *desc)
+ 		raw_spin_unlock(&bank_lock);
+ 		while ((line = ffs(status))) {
+ 			struct ipu_irq_map *map;
+-			unsigned int irq = NO_IRQ;
++			unsigned int irq;
+ 
+ 			line--;
+ 			status &= ~(1UL << line);
+ 
+ 			raw_spin_lock(&bank_lock);
+ 			map = src2map(32 * i + line);
+-			if (map)
+-				irq = map->irq;
+-			raw_spin_unlock(&bank_lock);
+-
+ 			if (!map) {
++				raw_spin_unlock(&bank_lock);
+ 				pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
+ 				       line, i);
+ 				continue;
+ 			}
++			irq = map->irq;
++			raw_spin_unlock(&bank_lock);
+ 			generic_handle_irq(irq);
+ 		}
+ 	}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+index 17e13621fae9..4e71a680e91b 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
+@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx)
+ 		ctx->rings[i].sequence = 1;
+ 		ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];
+ 	}
++
++	ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
++
+ 	/* create context entity for each ring */
+ 	for (i = 0; i < adev->num_rings; i++) {
+ 		struct amdgpu_ring *ring = adev->rings[i];
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+index fe36caf1b7d7..14f57d9915e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
+ 	printk("\n");
+ }
+ 
++
+ u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
+ {
+ 	struct drm_device *dev = adev->ddev;
+ 	struct drm_crtc *crtc;
+ 	struct amdgpu_crtc *amdgpu_crtc;
+-	u32 line_time_us, vblank_lines;
++	u32 vblank_in_pixels;
+ 	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
+ 
+ 	if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
+ 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ 			amdgpu_crtc = to_amdgpu_crtc(crtc);
+ 			if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
+-				line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
+-					amdgpu_crtc->hw_mode.clock;
+-				vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
++				vblank_in_pixels =
++					amdgpu_crtc->hw_mode.crtc_htotal *
++					(amdgpu_crtc->hw_mode.crtc_vblank_end -
+ 					amdgpu_crtc->hw_mode.crtc_vdisplay +
+-					(amdgpu_crtc->v_border * 2);
+-				vblank_time_us = vblank_lines * line_time_us;
++					(amdgpu_crtc->v_border * 2));
++
++				vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
+ 				break;
+ 			}
+ 		}
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index d942654a1de0..e24a8af72d90 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -292,7 +292,7 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
+ 			type = AMD_IP_BLOCK_TYPE_UVD;
+ 			ring_mask = adev->uvd.ring.ready ? 1 : 0;
+ 			ib_start_alignment = AMDGPU_GPU_PAGE_SIZE;
+-			ib_size_alignment = 8;
++			ib_size_alignment = 16;
+ 			break;
+ 		case AMDGPU_HW_IP_VCE:
+ 			type = AMD_IP_BLOCK_TYPE_VCE;
+diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+index c1b04e9aab57..172bed946287 100644
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+@@ -425,16 +425,6 @@ static void dce_v10_0_hpd_init(struct amdgpu_device *adev)
+ 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
+ 
+-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+-			 * aux dp channel on imac and help (but not completely fix)
+-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+-			 * also avoid interrupt storms during dpms.
+-			 */
+-			continue;
+-		}
+-
+ 		switch (amdgpu_connector->hpd.hpd) {
+ 		case AMDGPU_HPD_1:
+ 			idx = 0;
+@@ -458,6 +448,19 @@ static void dce_v10_0_hpd_init(struct amdgpu_device *adev)
+ 			continue;
+ 		}
+ 
++		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
++		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
++			/* don't try to enable hpd on eDP or LVDS avoid breaking the
++			 * aux dp channel on imac and help (but not completely fix)
++			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
++			 * also avoid interrupt storms during dpms.
++			 */
++			tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]);
++			tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0);
++			WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp);
++			continue;
++		}
++
+ 		tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]);
+ 		tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1);
+ 		WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp);
+diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+index d4bf133908b1..67c7c05a751c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+@@ -443,16 +443,6 @@ static void dce_v11_0_hpd_init(struct amdgpu_device *adev)
+ 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
+ 
+-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+-			 * aux dp channel on imac and help (but not completely fix)
+-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+-			 * also avoid interrupt storms during dpms.
+-			 */
+-			continue;
+-		}
+-
+ 		switch (amdgpu_connector->hpd.hpd) {
+ 		case AMDGPU_HPD_1:
+ 			idx = 0;
+@@ -476,6 +466,19 @@ static void dce_v11_0_hpd_init(struct amdgpu_device *adev)
+ 			continue;
+ 		}
+ 
++		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
++		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
++			/* don't try to enable hpd on eDP or LVDS avoid breaking the
++			 * aux dp channel on imac and help (but not completely fix)
++			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
++			 * also avoid interrupt storms during dpms.
++			 */
++			tmp = RREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx]);
++			tmp = REG_SET_FIELD(tmp, DC_HPD_INT_CONTROL, DC_HPD_INT_EN, 0);
++			WREG32(mmDC_HPD_INT_CONTROL + hpd_offsets[idx], tmp);
++			continue;
++		}
++
+ 		tmp = RREG32(mmDC_HPD_CONTROL + hpd_offsets[idx]);
+ 		tmp = REG_SET_FIELD(tmp, DC_HPD_CONTROL, DC_HPD_EN, 1);
+ 		WREG32(mmDC_HPD_CONTROL + hpd_offsets[idx], tmp);
+@@ -3109,6 +3112,7 @@ static int dce_v11_0_sw_fini(void *handle)
+ 
+ 	dce_v11_0_afmt_fini(adev);
+ 
++	drm_mode_config_cleanup(adev->ddev);
+ 	adev->mode_info.mode_config_initialized = false;
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+index 4fdfab1e9200..ea07c50369b4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+@@ -395,15 +395,6 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev)
+ 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ 		struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
+ 
+-		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
+-		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
+-			/* don't try to enable hpd on eDP or LVDS avoid breaking the
+-			 * aux dp channel on imac and help (but not completely fix)
+-			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
+-			 * also avoid interrupt storms during dpms.
+-			 */
+-			continue;
+-		}
+ 		switch (amdgpu_connector->hpd.hpd) {
+ 		case AMDGPU_HPD_1:
+ 			WREG32(mmDC_HPD1_CONTROL, tmp);
+@@ -426,6 +417,45 @@ static void dce_v8_0_hpd_init(struct amdgpu_device *adev)
+ 		default:
+ 			break;
+ 		}
++
++		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
++		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
++			/* don't try to enable hpd on eDP or LVDS avoid breaking the
++			 * aux dp channel on imac and help (but not completely fix)
++			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
++			 * also avoid interrupt storms during dpms.
++			 */
++			u32 dc_hpd_int_cntl_reg, dc_hpd_int_cntl;
++
++			switch (amdgpu_connector->hpd.hpd) {
++			case AMDGPU_HPD_1:
++				dc_hpd_int_cntl_reg = mmDC_HPD1_INT_CONTROL;
++				break;
++			case AMDGPU_HPD_2:
++				dc_hpd_int_cntl_reg = mmDC_HPD2_INT_CONTROL;
++				break;
++			case AMDGPU_HPD_3:
++				dc_hpd_int_cntl_reg = mmDC_HPD3_INT_CONTROL;
++				break;
++			case AMDGPU_HPD_4:
++				dc_hpd_int_cntl_reg = mmDC_HPD4_INT_CONTROL;
++				break;
++			case AMDGPU_HPD_5:
++				dc_hpd_int_cntl_reg = mmDC_HPD5_INT_CONTROL;
++				break;
++			case AMDGPU_HPD_6:
++				dc_hpd_int_cntl_reg = mmDC_HPD6_INT_CONTROL;
++				break;
++			default:
++				continue;
++			}
++
++			dc_hpd_int_cntl = RREG32(dc_hpd_int_cntl_reg);
++			dc_hpd_int_cntl &= ~DC_HPD1_INT_CONTROL__DC_HPD1_INT_EN_MASK;
++			WREG32(dc_hpd_int_cntl_reg, dc_hpd_int_cntl);
++			continue;
++		}
++
+ 		dce_v8_0_hpd_set_polarity(adev, amdgpu_connector->hpd.hpd);
+ 		amdgpu_irq_get(adev, &adev->hpd_irq, amdgpu_connector->hpd.hpd);
+ 	}
+diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
+index 635fc4b48184..92b117843875 100644
+--- a/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
+@@ -262,6 +262,8 @@ static const pem_event_action * const display_config_change_event[] = {
+ 	unblock_adjust_power_state_tasks,
+ 	set_cpu_power_state,
+ 	notify_hw_power_source_tasks,
++	get_2d_performance_state_tasks,
++	set_performance_state_tasks,
+ 	/* updateDALConfigurationTasks,
+ 	variBrightDisplayConfigurationChangeTasks, */
+ 	adjust_power_state_tasks,
+diff --git a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
+index a46225c0fc01..d6bee727497c 100644
+--- a/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
++++ b/drivers/gpu/drm/amd/powerplay/eventmgr/psm.c
+@@ -100,11 +100,12 @@ int psm_adjust_power_state_dynamic(struct pp_eventmgr *eventmgr, bool skip)
+ 	if (requested == NULL)
+ 		return 0;
+ 
++	phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
++
+ 	if (pcurrent == NULL || (0 != phm_check_states_equal(hwmgr, &pcurrent->hardware, &requested->hardware, &equal)))
+ 		equal = false;
+ 
+ 	if (!equal || phm_check_smc_update_required_for_display_configuration(hwmgr)) {
+-		phm_apply_state_adjust_rules(hwmgr, requested, pcurrent);
+ 		phm_set_power_state(hwmgr, &pcurrent->hardware, &requested->hardware);
+ 		hwmgr->current_ps = requested;
+ 	}
+diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
+index 780589b420a4..9c4387d79d11 100644
+--- a/drivers/gpu/drm/drm_prime.c
++++ b/drivers/gpu/drm/drm_prime.c
+@@ -335,14 +335,17 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops =  {
+  * using the PRIME helpers.
+  */
+ struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
+-				     struct drm_gem_object *obj, int flags)
++				     struct drm_gem_object *obj,
++				     int flags)
+ {
+-	DEFINE_DMA_BUF_EXPORT_INFO(exp_info);
+-
+-	exp_info.ops = &drm_gem_prime_dmabuf_ops;
+-	exp_info.size = obj->size;
+-	exp_info.flags = flags;
+-	exp_info.priv = obj;
++	struct dma_buf_export_info exp_info = {
++		.exp_name = KBUILD_MODNAME, /* white lie for debug */
++		.owner = dev->driver->fops->owner,
++		.ops = &drm_gem_prime_dmabuf_ops,
++		.size = obj->size,
++		.flags = flags,
++		.priv = obj,
++	};
+ 
+ 	if (dev->driver->gem_prime_res_obj)
+ 		exp_info.resv = dev->driver->gem_prime_res_obj(obj);
+diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+index 7882387f9bff..5fc8ebdf40b2 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -330,6 +330,7 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
+ 	const char *pix_clk_in_name;
+ 	const struct of_device_id *id;
+ 	int ret;
++	u8 div_ratio_shift = 0;
+ 
+ 	fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL);
+ 	if (!fsl_dev)
+@@ -382,11 +383,14 @@ static int fsl_dcu_drm_probe(struct platform_device *pdev)
+ 		pix_clk_in = fsl_dev->clk;
+ 	}
+ 
++	if (of_property_read_bool(dev->of_node, "big-endian"))
++		div_ratio_shift = 24;
++
+ 	pix_clk_in_name = __clk_get_name(pix_clk_in);
+ 	snprintf(pix_clk_name, sizeof(pix_clk_name), "%s_pix", pix_clk_in_name);
+ 	fsl_dev->pix_clk = clk_register_divider(dev, pix_clk_name,
+ 			pix_clk_in_name, 0, base + DCU_DIV_RATIO,
+-			0, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
++			div_ratio_shift, 8, CLK_DIVIDER_ROUND_CLOSEST, NULL);
+ 	if (IS_ERR(fsl_dev->pix_clk)) {
+ 		dev_err(dev, "failed to register pix clk\n");
+ 		ret = PTR_ERR(fsl_dev->pix_clk);
+diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
+index f68c78918d63..84a00105871d 100644
+--- a/drivers/gpu/drm/i915/i915_drv.h
++++ b/drivers/gpu/drm/i915/i915_drv.h
+@@ -631,6 +631,8 @@ struct drm_i915_display_funcs {
+ 				  struct intel_crtc_state *crtc_state);
+ 	void (*crtc_enable)(struct drm_crtc *crtc);
+ 	void (*crtc_disable)(struct drm_crtc *crtc);
++	void (*update_crtcs)(struct drm_atomic_state *state,
++			     unsigned int *crtc_vblank_mask);
+ 	void (*audio_codec_enable)(struct drm_connector *connector,
+ 				   struct intel_encoder *encoder,
+ 				   const struct drm_display_mode *adjusted_mode);
+@@ -1965,11 +1967,11 @@ struct drm_i915_private {
+ 	struct vlv_s0ix_state vlv_s0ix_state;
+ 
+ 	enum {
+-		I915_SKL_SAGV_UNKNOWN = 0,
+-		I915_SKL_SAGV_DISABLED,
+-		I915_SKL_SAGV_ENABLED,
+-		I915_SKL_SAGV_NOT_CONTROLLED
+-	} skl_sagv_status;
++		I915_SAGV_UNKNOWN = 0,
++		I915_SAGV_DISABLED,
++		I915_SAGV_ENABLED,
++		I915_SAGV_NOT_CONTROLLED
++	} sagv_status;
+ 
+ 	struct {
+ 		/*
+@@ -2280,21 +2282,19 @@ struct drm_i915_gem_object {
+ 	/** Record of address bit 17 of each page at last unbind. */
+ 	unsigned long *bit_17;
+ 
+-	union {
+-		/** for phy allocated objects */
+-		struct drm_dma_handle *phys_handle;
+-
+-		struct i915_gem_userptr {
+-			uintptr_t ptr;
+-			unsigned read_only :1;
+-			unsigned workers :4;
++	struct i915_gem_userptr {
++		uintptr_t ptr;
++		unsigned read_only :1;
++		unsigned workers :4;
+ #define I915_GEM_USERPTR_MAX_WORKERS 15
+ 
+-			struct i915_mm_struct *mm;
+-			struct i915_mmu_object *mmu_object;
+-			struct work_struct *work;
+-		} userptr;
+-	};
++		struct i915_mm_struct *mm;
++		struct i915_mmu_object *mmu_object;
++		struct work_struct *work;
++	} userptr;
++
++	/** for phys allocated objects */
++	struct drm_dma_handle *phys_handle;
+ };
+ #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base)
+ 
+diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
+index 66be299a1486..2bb69f3c5b84 100644
+--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
+@@ -115,17 +115,28 @@ static unsigned long i915_stolen_to_physical(struct drm_device *dev)
+ 
+ 		base = bsm & INTEL_BSM_MASK;
+ 	} else if (IS_I865G(dev)) {
++		u32 tseg_size = 0;
+ 		u16 toud = 0;
++		u8 tmp;
++
++		pci_bus_read_config_byte(dev->pdev->bus, PCI_DEVFN(0, 0),
++					 I845_ESMRAMC, &tmp);
++
++		if (tmp & TSEG_ENABLE) {
++			switch (tmp & I845_TSEG_SIZE_MASK) {
++			case I845_TSEG_SIZE_512K:
++				tseg_size = KB(512);
++				break;
++			case I845_TSEG_SIZE_1M:
++				tseg_size = MB(1);
++				break;
++			}
++		}
+ 
+-		/*
+-		 * FIXME is the graphics stolen memory region
+-		 * always at TOUD? Ie. is it always the last
+-		 * one to be allocated by the BIOS?
+-		 */
+ 		pci_bus_read_config_word(dev->pdev->bus, PCI_DEVFN(0, 0),
+ 					 I865_TOUD, &toud);
+ 
+-		base = toud << 16;
++		base = (toud << 16) + tseg_size;
+ 	} else if (IS_I85X(dev)) {
+ 		u32 tseg_size = 0;
+ 		u32 tom;
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 175595fc3e45..e9a64fba6333 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -2980,6 +2980,7 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
+ 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc_state->base.crtc);
+ 	struct drm_framebuffer *fb = plane_state->base.fb;
+ 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
++	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
+ 	int pipe = intel_crtc->pipe;
+ 	u32 plane_ctl, stride_div, stride;
+ 	u32 tile_height, plane_offset, plane_size;
+@@ -3031,6 +3032,9 @@ static void skylake_update_primary_plane(struct drm_plane *plane,
+ 	intel_crtc->adjusted_x = x_offset;
+ 	intel_crtc->adjusted_y = y_offset;
+ 
++	if (wm->dirty_pipes & drm_crtc_mask(&intel_crtc->base))
++		skl_write_plane_wm(intel_crtc, wm, 0);
++
+ 	I915_WRITE(PLANE_CTL(pipe, 0), plane_ctl);
+ 	I915_WRITE(PLANE_OFFSET(pipe, 0), plane_offset);
+ 	I915_WRITE(PLANE_SIZE(pipe, 0), plane_size);
+@@ -3061,7 +3065,15 @@ static void skylake_disable_primary_plane(struct drm_plane *primary,
+ {
+ 	struct drm_device *dev = crtc->dev;
+ 	struct drm_i915_private *dev_priv = to_i915(dev);
+-	int pipe = to_intel_crtc(crtc)->pipe;
++	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++	int pipe = intel_crtc->pipe;
++
++	/*
++	 * We only populate skl_results on watermark updates, and if the
++	 * plane's visiblity isn't actually changing neither is its watermarks.
++	 */
++	if (!to_intel_plane_state(crtc->primary->state)->visible)
++		skl_write_plane_wm(intel_crtc, &dev_priv->wm.skl_results, 0);
+ 
+ 	I915_WRITE(PLANE_CTL(pipe, 0), 0);
+ 	I915_WRITE(PLANE_SURF(pipe, 0), 0);
+@@ -8995,6 +9007,24 @@ static void ironlake_compute_dpll(struct intel_crtc *intel_crtc,
+ 	if (intel_crtc_has_dp_encoder(crtc_state))
+ 		dpll |= DPLL_SDVO_HIGH_SPEED;
+ 
++	/*
++	 * The high speed IO clock is only really required for
++	 * SDVO/HDMI/DP, but we also enable it for CRT to make it
++	 * possible to share the DPLL between CRT and HDMI. Enabling
++	 * the clock needlessly does no real harm, except use up a
++	 * bit of power potentially.
++	 *
++	 * We'll limit this to IVB with 3 pipes, since it has only two
++	 * DPLLs and so DPLL sharing is the only way to get three pipes
++	 * driving PCH ports at the same time. On SNB we could do this,
++	 * and potentially avoid enabling the second DPLL, but it's not
++	 * clear if it''s a win or loss power wise. No point in doing
++	 * this on ILK at all since it has a fixed DPLL<->pipe mapping.
++	 */
++	if (INTEL_INFO(dev_priv)->num_pipes == 3 &&
++	    intel_crtc_has_type(crtc_state, INTEL_OUTPUT_ANALOG))
++		dpll |= DPLL_SDVO_HIGH_SPEED;
++
+ 	/* compute bitmask from p1 value */
+ 	dpll |= (1 << (crtc_state->dpll.p1 - 1)) << DPLL_FPA01_P1_POST_DIV_SHIFT;
+ 	/* also FPA1 */
+@@ -10306,9 +10336,13 @@ static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base,
+ 	struct drm_device *dev = crtc->dev;
+ 	struct drm_i915_private *dev_priv = to_i915(dev);
+ 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
+ 	int pipe = intel_crtc->pipe;
+ 	uint32_t cntl = 0;
+ 
++	if (INTEL_GEN(dev_priv) >= 9 && wm->dirty_pipes & drm_crtc_mask(crtc))
++		skl_write_cursor_wm(intel_crtc, wm);
++
+ 	if (plane_state && plane_state->visible) {
+ 		cntl = MCURSOR_GAMMA_ENABLE;
+ 		switch (plane_state->base.crtc_w) {
+@@ -12956,16 +12990,23 @@ static void verify_wm_state(struct drm_crtc *crtc,
+ 			  hw_entry->start, hw_entry->end);
+ 	}
+ 
+-	/* cursor */
+-	hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
+-	sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
+-
+-	if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
+-		DRM_ERROR("mismatch in DDB state pipe %c cursor "
+-			  "(expected (%u,%u), found (%u,%u))\n",
+-			  pipe_name(pipe),
+-			  sw_entry->start, sw_entry->end,
+-			  hw_entry->start, hw_entry->end);
++	/*
++	 * cursor
++	 * If the cursor plane isn't active, we may not have updated it's ddb
++	 * allocation. In that case since the ddb allocation will be updated
++	 * once the plane becomes visible, we can skip this check
++	 */
++	if (intel_crtc->cursor_addr) {
++		hw_entry = &hw_ddb.plane[pipe][PLANE_CURSOR];
++		sw_entry = &sw_ddb->plane[pipe][PLANE_CURSOR];
++
++		if (!skl_ddb_entry_equal(hw_entry, sw_entry)) {
++			DRM_ERROR("mismatch in DDB state pipe %c cursor "
++				  "(expected (%u,%u), found (%u,%u))\n",
++				  pipe_name(pipe),
++				  sw_entry->start, sw_entry->end,
++				  hw_entry->start, hw_entry->end);
++		}
+ 	}
+ }
+ 
+@@ -13671,6 +13712,111 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
+ 	return false;
+ }
+ 
++static void intel_update_crtc(struct drm_crtc *crtc,
++			      struct drm_atomic_state *state,
++			      struct drm_crtc_state *old_crtc_state,
++			      unsigned int *crtc_vblank_mask)
++{
++	struct drm_device *dev = crtc->dev;
++	struct drm_i915_private *dev_priv = to_i915(dev);
++	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++	struct intel_crtc_state *pipe_config = to_intel_crtc_state(crtc->state);
++	bool modeset = needs_modeset(crtc->state);
++
++	if (modeset) {
++		update_scanline_offset(intel_crtc);
++		dev_priv->display.crtc_enable(crtc);
++	} else {
++		intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
++	}
++
++	if (drm_atomic_get_existing_plane_state(state, crtc->primary)) {
++		intel_fbc_enable(
++		    intel_crtc, pipe_config,
++		    to_intel_plane_state(crtc->primary->state));
++	}
++
++	drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
++
++	if (needs_vblank_wait(pipe_config))
++		*crtc_vblank_mask |= drm_crtc_mask(crtc);
++}
++
++static void intel_update_crtcs(struct drm_atomic_state *state,
++			       unsigned int *crtc_vblank_mask)
++{
++	struct drm_crtc *crtc;
++	struct drm_crtc_state *old_crtc_state;
++	int i;
++
++	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
++		if (!crtc->state->active)
++			continue;
++
++		intel_update_crtc(crtc, state, old_crtc_state,
++				  crtc_vblank_mask);
++	}
++}
++
++static void skl_update_crtcs(struct drm_atomic_state *state,
++			     unsigned int *crtc_vblank_mask)
++{
++	struct drm_device *dev = state->dev;
++	struct drm_i915_private *dev_priv = to_i915(dev);
++	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
++	struct drm_crtc *crtc;
++	struct drm_crtc_state *old_crtc_state;
++	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
++	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
++	unsigned int updated = 0;
++	bool progress;
++	enum pipe pipe;
++
++	/*
++	 * Whenever the number of active pipes changes, we need to make sure we
++	 * update the pipes in the right order so that their ddb allocations
++	 * never overlap with eachother inbetween CRTC updates. Otherwise we'll
++	 * cause pipe underruns and other bad stuff.
++	 */
++	do {
++		int i;
++		progress = false;
++
++		for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
++			bool vbl_wait = false;
++			unsigned int cmask = drm_crtc_mask(crtc);
++			pipe = to_intel_crtc(crtc)->pipe;
++
++			if (updated & cmask || !crtc->state->active)
++				continue;
++			if (skl_ddb_allocation_overlaps(state, cur_ddb, new_ddb,
++							pipe))
++				continue;
++
++			updated |= cmask;
++
++			/*
++			 * If this is an already active pipe, it's DDB changed,
++			 * and this isn't the last pipe that needs updating
++			 * then we need to wait for a vblank to pass for the
++			 * new ddb allocation to take effect.
++			 */
++			if (!skl_ddb_allocation_equals(cur_ddb, new_ddb, pipe) &&
++			    !crtc->state->active_changed &&
++			    intel_state->wm_results.dirty_pipes != updated)
++				vbl_wait = true;
++
++			intel_update_crtc(crtc, state, old_crtc_state,
++					  crtc_vblank_mask);
++
++			if (vbl_wait)
++				intel_wait_for_vblank(dev, pipe);
++
++			progress = true;
++		}
++	} while (progress);
++}
++
+ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
+ {
+ 	struct drm_device *dev = state->dev;
+@@ -13763,23 +13909,15 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
+ 		 * SKL workaround: bspec recommends we disable the SAGV when we
+ 		 * have more then one pipe enabled
+ 		 */
+-		if (IS_SKYLAKE(dev_priv) && !skl_can_enable_sagv(state))
+-			skl_disable_sagv(dev_priv);
++		if (!intel_can_enable_sagv(state))
++			intel_disable_sagv(dev_priv);
+ 
+ 		intel_modeset_verify_disabled(dev);
+ 	}
+ 
+-	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
++	/* Complete the events for pipes that have now been disabled */
+ 	for_each_crtc_in_state(state, crtc, old_crtc_state, i) {
+-		struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ 		bool modeset = needs_modeset(crtc->state);
+-		struct intel_crtc_state *pipe_config =
+-			to_intel_crtc_state(crtc->state);
+-
+-		if (modeset && crtc->state->active) {
+-			update_scanline_offset(to_intel_crtc(crtc));
+-			dev_priv->display.crtc_enable(crtc);
+-		}
+ 
+ 		/* Complete events for now disable pipes here. */
+ 		if (modeset && !crtc->state->active && crtc->state->event) {
+@@ -13789,21 +13927,11 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
+ 
+ 			crtc->state->event = NULL;
+ 		}
+-
+-		if (!modeset)
+-			intel_pre_plane_update(to_intel_crtc_state(old_crtc_state));
+-
+-		if (crtc->state->active &&
+-		    drm_atomic_get_existing_plane_state(state, crtc->primary))
+-			intel_fbc_enable(intel_crtc, pipe_config, to_intel_plane_state(crtc->primary->state));
+-
+-		if (crtc->state->active)
+-			drm_atomic_helper_commit_planes_on_crtc(old_crtc_state);
+-
+-		if (pipe_config->base.active && needs_vblank_wait(pipe_config))
+-			crtc_vblank_mask |= 1 << i;
+ 	}
+ 
++	/* Now enable the clocks, plane, pipe, and connectors that we set up. */
++	dev_priv->display.update_crtcs(state, &crtc_vblank_mask);
++
+ 	/* FIXME: We should call drm_atomic_helper_commit_hw_done() here
+ 	 * already, but still need the state for the delayed optimization. To
+ 	 * fix this:
+@@ -13839,9 +13967,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
+ 		intel_modeset_verify_crtc(crtc, old_crtc_state, crtc->state);
+ 	}
+ 
+-	if (IS_SKYLAKE(dev_priv) && intel_state->modeset &&
+-	    skl_can_enable_sagv(state))
+-		skl_enable_sagv(dev_priv);
++	if (intel_state->modeset && intel_can_enable_sagv(state))
++		intel_enable_sagv(dev_priv);
+ 
+ 	drm_atomic_helper_commit_hw_done(state);
+ 
+@@ -14221,10 +14348,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+ 				    struct drm_crtc_state *old_crtc_state)
+ {
+ 	struct drm_device *dev = crtc->dev;
++	struct drm_i915_private *dev_priv = to_i915(dev);
+ 	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ 	struct intel_crtc_state *old_intel_state =
+ 		to_intel_crtc_state(old_crtc_state);
+ 	bool modeset = needs_modeset(crtc->state);
++	enum pipe pipe = intel_crtc->pipe;
+ 
+ 	/* Perform vblank evasion around commit operation */
+ 	intel_pipe_update_start(intel_crtc);
+@@ -14239,8 +14368,12 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc,
+ 
+ 	if (to_intel_crtc_state(crtc->state)->update_pipe)
+ 		intel_update_pipe_config(intel_crtc, old_intel_state);
+-	else if (INTEL_INFO(dev)->gen >= 9)
++	else if (INTEL_GEN(dev_priv) >= 9) {
+ 		skl_detach_scalers(intel_crtc);
++
++		I915_WRITE(PIPE_WM_LINETIME(pipe),
++			   dev_priv->wm.skl_hw.wm_linetime[pipe]);
++	}
+ }
+ 
+ static void intel_finish_crtc_commit(struct drm_crtc *crtc,
+@@ -15347,6 +15480,11 @@ void intel_init_display_hooks(struct drm_i915_private *dev_priv)
+ 			skl_modeset_calc_cdclk;
+ 	}
+ 
++	if (dev_priv->info.gen >= 9)
++		dev_priv->display.update_crtcs = skl_update_crtcs;
++	else
++		dev_priv->display.update_crtcs = intel_update_crtcs;
++
+ 	switch (INTEL_INFO(dev_priv)->gen) {
+ 	case 2:
+ 		dev_priv->display.queue_flip = intel_gen2_queue_flip;
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 21b04c3eda41..1ca155f4d368 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -4148,7 +4148,7 @@ static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv,
+  *
+  * Return %true if @port is connected, %false otherwise.
+  */
+-bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
++static bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+ 					 struct intel_digital_port *port)
+ {
+ 	if (HAS_PCH_IBX(dev_priv))
+@@ -4207,7 +4207,7 @@ intel_dp_unset_edid(struct intel_dp *intel_dp)
+ 	intel_dp->has_audio = false;
+ }
+ 
+-static void
++static enum drm_connector_status
+ intel_dp_long_pulse(struct intel_connector *intel_connector)
+ {
+ 	struct drm_connector *connector = &intel_connector->base;
+@@ -4232,7 +4232,7 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
+ 	else
+ 		status = connector_status_disconnected;
+ 
+-	if (status != connector_status_connected) {
++	if (status == connector_status_disconnected) {
+ 		intel_dp->compliance_test_active = 0;
+ 		intel_dp->compliance_test_type = 0;
+ 		intel_dp->compliance_test_data = 0;
+@@ -4284,8 +4284,8 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
+ 	intel_dp->aux.i2c_defer_count = 0;
+ 
+ 	intel_dp_set_edid(intel_dp);
+-
+-	status = connector_status_connected;
++	if (is_edp(intel_dp) || intel_connector->detect_edid)
++		status = connector_status_connected;
+ 	intel_dp->detect_done = true;
+ 
+ 	/* Try to read the source of the interrupt */
+@@ -4303,12 +4303,11 @@ intel_dp_long_pulse(struct intel_connector *intel_connector)
+ 	}
+ 
+ out:
+-	if ((status != connector_status_connected) &&
+-	    (intel_dp->is_mst == false))
++	if (status != connector_status_connected && !intel_dp->is_mst)
+ 		intel_dp_unset_edid(intel_dp);
+ 
+ 	intel_display_power_put(to_i915(dev), power_domain);
+-	return;
++	return status;
+ }
+ 
+ static enum drm_connector_status
+@@ -4317,7 +4316,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
+ 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+ 	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+ 	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+-	struct intel_connector *intel_connector = to_intel_connector(connector);
++	enum drm_connector_status status = connector->status;
+ 
+ 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+ 		      connector->base.id, connector->name);
+@@ -4332,14 +4331,11 @@ intel_dp_detect(struct drm_connector *connector, bool force)
+ 
+ 	/* If full detect is not performed yet, do a full detect */
+ 	if (!intel_dp->detect_done)
+-		intel_dp_long_pulse(intel_dp->attached_connector);
++		status = intel_dp_long_pulse(intel_dp->attached_connector);
+ 
+ 	intel_dp->detect_done = false;
+ 
+-	if (is_edp(intel_dp) || intel_connector->detect_edid)
+-		return connector_status_connected;
+-	else
+-		return connector_status_disconnected;
++	return status;
+ }
+ 
+ static void
+@@ -4696,36 +4692,34 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
+ 		      port_name(intel_dig_port->port),
+ 		      long_hpd ? "long" : "short");
+ 
++	if (long_hpd) {
++		intel_dp->detect_done = false;
++		return IRQ_NONE;
++	}
++
+ 	power_domain = intel_display_port_aux_power_domain(intel_encoder);
+ 	intel_display_power_get(dev_priv, power_domain);
+ 
+-	if (long_hpd) {
+-		intel_dp_long_pulse(intel_dp->attached_connector);
+-		if (intel_dp->is_mst)
+-			ret = IRQ_HANDLED;
+-		goto put_power;
+-
+-	} else {
+-		if (intel_dp->is_mst) {
+-			if (intel_dp_check_mst_status(intel_dp) == -EINVAL) {
+-				/*
+-				 * If we were in MST mode, and device is not
+-				 * there, get out of MST mode
+-				 */
+-				DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
+-					      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
+-				intel_dp->is_mst = false;
+-				drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
+-								intel_dp->is_mst);
+-				goto put_power;
+-			}
++	if (intel_dp->is_mst) {
++		if (intel_dp_check_mst_status(intel_dp) == -EINVAL) {
++			/*
++			 * If we were in MST mode, and device is not
++			 * there, get out of MST mode
++			 */
++			DRM_DEBUG_KMS("MST device may have disappeared %d vs %d\n",
++				      intel_dp->is_mst, intel_dp->mst_mgr.mst_state);
++			intel_dp->is_mst = false;
++			drm_dp_mst_topology_mgr_set_mst(&intel_dp->mst_mgr,
++							intel_dp->is_mst);
++			intel_dp->detect_done = false;
++			goto put_power;
+ 		}
++	}
+ 
+-		if (!intel_dp->is_mst) {
+-			if (!intel_dp_short_pulse(intel_dp)) {
+-				intel_dp_long_pulse(intel_dp->attached_connector);
+-				goto put_power;
+-			}
++	if (!intel_dp->is_mst) {
++		if (!intel_dp_short_pulse(intel_dp)) {
++			intel_dp->detect_done = false;
++			goto put_power;
+ 		}
+ 	}
+ 
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index ff399b9a5c1f..9a58800cba3b 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -236,6 +236,7 @@ struct intel_panel {
+ 		bool enabled;
+ 		bool combination_mode;	/* gen 2/4 only */
+ 		bool active_low_pwm;
++		bool alternate_pwm_increment;	/* lpt+ */
+ 
+ 		/* PWM chip */
+ 		bool util_pin_active_low;	/* bxt+ */
+@@ -1387,8 +1388,6 @@ void intel_edp_drrs_disable(struct intel_dp *intel_dp);
+ void intel_edp_drrs_invalidate(struct drm_device *dev,
+ 		unsigned frontbuffer_bits);
+ void intel_edp_drrs_flush(struct drm_device *dev, unsigned frontbuffer_bits);
+-bool intel_digital_port_connected(struct drm_i915_private *dev_priv,
+-					 struct intel_digital_port *port);
+ 
+ void
+ intel_dp_program_link_training_pattern(struct intel_dp *intel_dp,
+@@ -1716,9 +1715,21 @@ void ilk_wm_get_hw_state(struct drm_device *dev);
+ void skl_wm_get_hw_state(struct drm_device *dev);
+ void skl_ddb_get_hw_state(struct drm_i915_private *dev_priv,
+ 			  struct skl_ddb_allocation *ddb /* out */);
+-bool skl_can_enable_sagv(struct drm_atomic_state *state);
+-int skl_enable_sagv(struct drm_i915_private *dev_priv);
+-int skl_disable_sagv(struct drm_i915_private *dev_priv);
++bool intel_can_enable_sagv(struct drm_atomic_state *state);
++int intel_enable_sagv(struct drm_i915_private *dev_priv);
++int intel_disable_sagv(struct drm_i915_private *dev_priv);
++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
++			       const struct skl_ddb_allocation *new,
++			       enum pipe pipe);
++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
++				 const struct skl_ddb_allocation *old,
++				 const struct skl_ddb_allocation *new,
++				 enum pipe pipe);
++void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
++			 const struct skl_wm_values *wm);
++void skl_write_plane_wm(struct intel_crtc *intel_crtc,
++			const struct skl_wm_values *wm,
++			int plane);
+ uint32_t ilk_pipe_pixel_rate(const struct intel_crtc_state *pipe_config);
+ bool ilk_disable_lp_wm(struct drm_device *dev);
+ int sanitize_rc6_option(struct drm_i915_private *dev_priv, int enable_rc6);
+diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
+index 4df9f384910c..c3aa9e670d15 100644
+--- a/drivers/gpu/drm/i915/intel_hdmi.c
++++ b/drivers/gpu/drm/i915/intel_hdmi.c
+@@ -1422,24 +1422,22 @@ intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector, bool has_edid)
+ }
+ 
+ static bool
+-intel_hdmi_set_edid(struct drm_connector *connector, bool force)
++intel_hdmi_set_edid(struct drm_connector *connector)
+ {
+ 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+ 	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+-	struct edid *edid = NULL;
++	struct edid *edid;
+ 	bool connected = false;
+ 
+-	if (force) {
+-		intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
++	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+ 
+-		edid = drm_get_edid(connector,
+-				    intel_gmbus_get_adapter(dev_priv,
+-				    intel_hdmi->ddc_bus));
++	edid = drm_get_edid(connector,
++			    intel_gmbus_get_adapter(dev_priv,
++			    intel_hdmi->ddc_bus));
+ 
+-		intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
++	intel_hdmi_dp_dual_mode_detect(connector, edid != NULL);
+ 
+-		intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+-	}
++	intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+ 
+ 	to_intel_connector(connector)->detect_edid = edid;
+ 	if (edid && edid->input & DRM_EDID_INPUT_DIGITAL) {
+@@ -1465,37 +1463,16 @@ static enum drm_connector_status
+ intel_hdmi_detect(struct drm_connector *connector, bool force)
+ {
+ 	enum drm_connector_status status;
+-	struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ 	struct drm_i915_private *dev_priv = to_i915(connector->dev);
+-	bool live_status = false;
+-	unsigned int try;
+ 
+ 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+ 		      connector->base.id, connector->name);
+ 
+ 	intel_display_power_get(dev_priv, POWER_DOMAIN_GMBUS);
+ 
+-	for (try = 0; !live_status && try < 9; try++) {
+-		if (try)
+-			msleep(10);
+-		live_status = intel_digital_port_connected(dev_priv,
+-				hdmi_to_dig_port(intel_hdmi));
+-	}
+-
+-	if (!live_status) {
+-		DRM_DEBUG_KMS("HDMI live status down\n");
+-		/*
+-		 * Live status register is not reliable on all intel platforms.
+-		 * So consider live_status only for certain platforms, for
+-		 * others, read EDID to determine presence of sink.
+-		 */
+-		if (INTEL_INFO(dev_priv)->gen < 7 || IS_IVYBRIDGE(dev_priv))
+-			live_status = true;
+-	}
+-
+ 	intel_hdmi_unset_edid(connector);
+ 
+-	if (intel_hdmi_set_edid(connector, live_status)) {
++	if (intel_hdmi_set_edid(connector)) {
+ 		struct intel_hdmi *intel_hdmi = intel_attached_hdmi(connector);
+ 
+ 		hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
+@@ -1521,7 +1498,7 @@ intel_hdmi_force(struct drm_connector *connector)
+ 	if (connector->status != connector_status_connected)
+ 		return;
+ 
+-	intel_hdmi_set_edid(connector, true);
++	intel_hdmi_set_edid(connector);
+ 	hdmi_to_dig_port(intel_hdmi)->base.type = INTEL_OUTPUT_HDMI;
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
+index 96c65d77e886..9a2393a6b277 100644
+--- a/drivers/gpu/drm/i915/intel_panel.c
++++ b/drivers/gpu/drm/i915/intel_panel.c
+@@ -841,7 +841,7 @@ static void lpt_enable_backlight(struct intel_connector *connector)
+ {
+ 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ 	struct intel_panel *panel = &connector->panel;
+-	u32 pch_ctl1, pch_ctl2;
++	u32 pch_ctl1, pch_ctl2, schicken;
+ 
+ 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+ 	if (pch_ctl1 & BLM_PCH_PWM_ENABLE) {
+@@ -850,6 +850,22 @@ static void lpt_enable_backlight(struct intel_connector *connector)
+ 		I915_WRITE(BLC_PWM_PCH_CTL1, pch_ctl1);
+ 	}
+ 
++	if (HAS_PCH_LPT(dev_priv)) {
++		schicken = I915_READ(SOUTH_CHICKEN2);
++		if (panel->backlight.alternate_pwm_increment)
++			schicken |= LPT_PWM_GRANULARITY;
++		else
++			schicken &= ~LPT_PWM_GRANULARITY;
++		I915_WRITE(SOUTH_CHICKEN2, schicken);
++	} else {
++		schicken = I915_READ(SOUTH_CHICKEN1);
++		if (panel->backlight.alternate_pwm_increment)
++			schicken |= SPT_PWM_GRANULARITY;
++		else
++			schicken &= ~SPT_PWM_GRANULARITY;
++		I915_WRITE(SOUTH_CHICKEN1, schicken);
++	}
++
+ 	pch_ctl2 = panel->backlight.max << 16;
+ 	I915_WRITE(BLC_PWM_PCH_CTL2, pch_ctl2);
+ 
+@@ -1242,10 +1258,10 @@ static u32 bxt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+  */
+ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+ {
+-	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
++	struct intel_panel *panel = &connector->panel;
+ 	u32 mul;
+ 
+-	if (I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY)
++	if (panel->backlight.alternate_pwm_increment)
+ 		mul = 128;
+ 	else
+ 		mul = 16;
+@@ -1261,9 +1277,10 @@ static u32 spt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+ static u32 lpt_hz_to_pwm(struct intel_connector *connector, u32 pwm_freq_hz)
+ {
+ 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
++	struct intel_panel *panel = &connector->panel;
+ 	u32 mul, clock;
+ 
+-	if (I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY)
++	if (panel->backlight.alternate_pwm_increment)
+ 		mul = 16;
+ 	else
+ 		mul = 128;
+@@ -1414,6 +1431,13 @@ static int lpt_setup_backlight(struct intel_connector *connector, enum pipe unus
+ 	struct drm_i915_private *dev_priv = to_i915(connector->base.dev);
+ 	struct intel_panel *panel = &connector->panel;
+ 	u32 pch_ctl1, pch_ctl2, val;
++	bool alt;
++
++	if (HAS_PCH_LPT(dev_priv))
++		alt = I915_READ(SOUTH_CHICKEN2) & LPT_PWM_GRANULARITY;
++	else
++		alt = I915_READ(SOUTH_CHICKEN1) & SPT_PWM_GRANULARITY;
++	panel->backlight.alternate_pwm_increment = alt;
+ 
+ 	pch_ctl1 = I915_READ(BLC_PWM_PCH_CTL1);
+ 	panel->backlight.active_low_pwm = pch_ctl1 & BLM_PCH_POLARITY;
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 2d2481392824..e59a28cb3158 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2119,32 +2119,34 @@ static void intel_read_wm_latency(struct drm_device *dev, uint16_t wm[8])
+ 				GEN9_MEM_LATENCY_LEVEL_MASK;
+ 
+ 		/*
++		 * If a level n (n > 1) has a 0us latency, all levels m (m >= n)
++		 * need to be disabled. We make sure to sanitize the values out
++		 * of the punit to satisfy this requirement.
++		 */
++		for (level = 1; level <= max_level; level++) {
++			if (wm[level] == 0) {
++				for (i = level + 1; i <= max_level; i++)
++					wm[i] = 0;
++				break;
++			}
++		}
++
++		/*
+ 		 * WaWmMemoryReadLatency:skl
+ 		 *
+ 		 * punit doesn't take into account the read latency so we need
+-		 * to add 2us to the various latency levels we retrieve from
+-		 * the punit.
+-		 *   - W0 is a bit special in that it's the only level that
+-		 *   can't be disabled if we want to have display working, so
+-		 *   we always add 2us there.
+-		 *   - For levels >=1, punit returns 0us latency when they are
+-		 *   disabled, so we respect that and don't add 2us then
+-		 *
+-		 * Additionally, if a level n (n > 1) has a 0us latency, all
+-		 * levels m (m >= n) need to be disabled. We make sure to
+-		 * sanitize the values out of the punit to satisfy this
+-		 * requirement.
++		 * to add 2us to the various latency levels we retrieve from the
++		 * punit when level 0 response data us 0us.
+ 		 */
+-		wm[0] += 2;
+-		for (level = 1; level <= max_level; level++)
+-			if (wm[level] != 0)
++		if (wm[0] == 0) {
++			wm[0] += 2;
++			for (level = 1; level <= max_level; level++) {
++				if (wm[level] == 0)
++					break;
+ 				wm[level] += 2;
+-			else {
+-				for (i = level + 1; i <= max_level; i++)
+-					wm[i] = 0;
+-
+-				break;
+ 			}
++		}
++
+ 	} else if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+ 		uint64_t sskpd = I915_READ64(MCH_SSKPD);
+ 
+@@ -2876,6 +2878,19 @@ skl_wm_plane_id(const struct intel_plane *plane)
+ 	}
+ }
+ 
++static bool
++intel_has_sagv(struct drm_i915_private *dev_priv)
++{
++	if (IS_KABYLAKE(dev_priv))
++		return true;
++
++	if (IS_SKYLAKE(dev_priv) &&
++	    dev_priv->sagv_status != I915_SAGV_NOT_CONTROLLED)
++		return true;
++
++	return false;
++}
++
+ /*
+  * SAGV dynamically adjusts the system agent voltage and clock frequencies
+  * depending on power and performance requirements. The display engine access
+@@ -2888,12 +2903,14 @@ skl_wm_plane_id(const struct intel_plane *plane)
+  *  - We're not using an interlaced display configuration
+  */
+ int
+-skl_enable_sagv(struct drm_i915_private *dev_priv)
++intel_enable_sagv(struct drm_i915_private *dev_priv)
+ {
+ 	int ret;
+ 
+-	if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
+-	    dev_priv->skl_sagv_status == I915_SKL_SAGV_ENABLED)
++	if (!intel_has_sagv(dev_priv))
++		return 0;
++
++	if (dev_priv->sagv_status == I915_SAGV_ENABLED)
+ 		return 0;
+ 
+ 	DRM_DEBUG_KMS("Enabling the SAGV\n");
+@@ -2909,21 +2926,21 @@ skl_enable_sagv(struct drm_i915_private *dev_priv)
+ 	 * Some skl systems, pre-release machines in particular,
+ 	 * don't actually have an SAGV.
+ 	 */
+-	if (ret == -ENXIO) {
++	if (IS_SKYLAKE(dev_priv) && ret == -ENXIO) {
+ 		DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+-		dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
++		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ 		return 0;
+ 	} else if (ret < 0) {
+ 		DRM_ERROR("Failed to enable the SAGV\n");
+ 		return ret;
+ 	}
+ 
+-	dev_priv->skl_sagv_status = I915_SKL_SAGV_ENABLED;
++	dev_priv->sagv_status = I915_SAGV_ENABLED;
+ 	return 0;
+ }
+ 
+ static int
+-skl_do_sagv_disable(struct drm_i915_private *dev_priv)
++intel_do_sagv_disable(struct drm_i915_private *dev_priv)
+ {
+ 	int ret;
+ 	uint32_t temp = GEN9_SAGV_DISABLE;
+@@ -2937,19 +2954,21 @@ skl_do_sagv_disable(struct drm_i915_private *dev_priv)
+ }
+ 
+ int
+-skl_disable_sagv(struct drm_i915_private *dev_priv)
++intel_disable_sagv(struct drm_i915_private *dev_priv)
+ {
+ 	int ret, result;
+ 
+-	if (dev_priv->skl_sagv_status == I915_SKL_SAGV_NOT_CONTROLLED ||
+-	    dev_priv->skl_sagv_status == I915_SKL_SAGV_DISABLED)
++	if (!intel_has_sagv(dev_priv))
++		return 0;
++
++	if (dev_priv->sagv_status == I915_SAGV_DISABLED)
+ 		return 0;
+ 
+ 	DRM_DEBUG_KMS("Disabling the SAGV\n");
+ 	mutex_lock(&dev_priv->rps.hw_lock);
+ 
+ 	/* bspec says to keep retrying for at least 1 ms */
+-	ret = wait_for(result = skl_do_sagv_disable(dev_priv), 1);
++	ret = wait_for(result = intel_do_sagv_disable(dev_priv), 1);
+ 	mutex_unlock(&dev_priv->rps.hw_lock);
+ 
+ 	if (ret == -ETIMEDOUT) {
+@@ -2961,20 +2980,20 @@ skl_disable_sagv(struct drm_i915_private *dev_priv)
+ 	 * Some skl systems, pre-release machines in particular,
+ 	 * don't actually have an SAGV.
+ 	 */
+-	if (result == -ENXIO) {
++	if (IS_SKYLAKE(dev_priv) && result == -ENXIO) {
+ 		DRM_DEBUG_DRIVER("No SAGV found on system, ignoring\n");
+-		dev_priv->skl_sagv_status = I915_SKL_SAGV_NOT_CONTROLLED;
++		dev_priv->sagv_status = I915_SAGV_NOT_CONTROLLED;
+ 		return 0;
+ 	} else if (result < 0) {
+ 		DRM_ERROR("Failed to disable the SAGV\n");
+ 		return result;
+ 	}
+ 
+-	dev_priv->skl_sagv_status = I915_SKL_SAGV_DISABLED;
++	dev_priv->sagv_status = I915_SAGV_DISABLED;
+ 	return 0;
+ }
+ 
+-bool skl_can_enable_sagv(struct drm_atomic_state *state)
++bool intel_can_enable_sagv(struct drm_atomic_state *state)
+ {
+ 	struct drm_device *dev = state->dev;
+ 	struct drm_i915_private *dev_priv = to_i915(dev);
+@@ -2983,6 +3002,9 @@ bool skl_can_enable_sagv(struct drm_atomic_state *state)
+ 	enum pipe pipe;
+ 	int level, plane;
+ 
++	if (!intel_has_sagv(dev_priv))
++		return false;
++
+ 	/*
+ 	 * SKL workaround: bspec recommends we disable the SAGV when we have
+ 	 * more then one pipe enabled
+@@ -3473,29 +3495,14 @@ static uint32_t skl_wm_method1(uint32_t pixel_rate, uint8_t cpp, uint32_t latenc
+ }
+ 
+ static uint32_t skl_wm_method2(uint32_t pixel_rate, uint32_t pipe_htotal,
+-			       uint32_t horiz_pixels, uint8_t cpp,
+-			       uint64_t tiling, uint32_t latency)
++			       uint32_t latency, uint32_t plane_blocks_per_line)
+ {
+ 	uint32_t ret;
+-	uint32_t plane_bytes_per_line, plane_blocks_per_line;
+ 	uint32_t wm_intermediate_val;
+ 
+ 	if (latency == 0)
+ 		return UINT_MAX;
+ 
+-	plane_bytes_per_line = horiz_pixels * cpp;
+-
+-	if (tiling == I915_FORMAT_MOD_Y_TILED ||
+-	    tiling == I915_FORMAT_MOD_Yf_TILED) {
+-		plane_bytes_per_line *= 4;
+-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+-		plane_blocks_per_line /= 4;
+-	} else if (tiling == DRM_FORMAT_MOD_NONE) {
+-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512) + 1;
+-	} else {
+-		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
+-	}
+-
+ 	wm_intermediate_val = latency * pixel_rate;
+ 	ret = DIV_ROUND_UP(wm_intermediate_val, pipe_htotal * 1000) *
+ 				plane_blocks_per_line;
+@@ -3546,6 +3553,7 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ 	uint8_t cpp;
+ 	uint32_t width = 0, height = 0;
+ 	uint32_t plane_pixel_rate;
++	uint32_t y_tile_minimum, y_min_scanlines;
+ 
+ 	if (latency == 0 || !cstate->base.active || !intel_pstate->visible) {
+ 		*enabled = false;
+@@ -3561,38 +3569,51 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ 	cpp = drm_format_plane_cpp(fb->pixel_format, 0);
+ 	plane_pixel_rate = skl_adjusted_plane_pixel_rate(cstate, intel_pstate);
+ 
++	if (intel_rotation_90_or_270(pstate->rotation)) {
++		int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
++			drm_format_plane_cpp(fb->pixel_format, 1) :
++			drm_format_plane_cpp(fb->pixel_format, 0);
++
++		switch (cpp) {
++		case 1:
++			y_min_scanlines = 16;
++			break;
++		case 2:
++			y_min_scanlines = 8;
++			break;
++		default:
++			WARN(1, "Unsupported pixel depth for rotation");
++		case 4:
++			y_min_scanlines = 4;
++			break;
++		}
++	} else {
++		y_min_scanlines = 4;
++	}
++
++	plane_bytes_per_line = width * cpp;
++	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
++	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
++		plane_blocks_per_line =
++		      DIV_ROUND_UP(plane_bytes_per_line * y_min_scanlines, 512);
++		plane_blocks_per_line /= y_min_scanlines;
++	} else if (fb->modifier[0] == DRM_FORMAT_MOD_NONE) {
++		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512)
++					+ 1;
++	} else {
++		plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
++	}
++
+ 	method1 = skl_wm_method1(plane_pixel_rate, cpp, latency);
+ 	method2 = skl_wm_method2(plane_pixel_rate,
+ 				 cstate->base.adjusted_mode.crtc_htotal,
+-				 width,
+-				 cpp,
+-				 fb->modifier[0],
+-				 latency);
++				 latency,
++				 plane_blocks_per_line);
+ 
+-	plane_bytes_per_line = width * cpp;
+-	plane_blocks_per_line = DIV_ROUND_UP(plane_bytes_per_line, 512);
++	y_tile_minimum = plane_blocks_per_line * y_min_scanlines;
+ 
+ 	if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+ 	    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
+-		uint32_t min_scanlines = 4;
+-		uint32_t y_tile_minimum;
+-		if (intel_rotation_90_or_270(pstate->rotation)) {
+-			int cpp = (fb->pixel_format == DRM_FORMAT_NV12) ?
+-				drm_format_plane_cpp(fb->pixel_format, 1) :
+-				drm_format_plane_cpp(fb->pixel_format, 0);
+-
+-			switch (cpp) {
+-			case 1:
+-				min_scanlines = 16;
+-				break;
+-			case 2:
+-				min_scanlines = 8;
+-				break;
+-			case 8:
+-				WARN(1, "Unsupported pixel depth for rotation");
+-			}
+-		}
+-		y_tile_minimum = plane_blocks_per_line * min_scanlines;
+ 		selected_result = max(method2, y_tile_minimum);
+ 	} else {
+ 		if ((ddb_allocation / plane_blocks_per_line) >= 1)
+@@ -3606,10 +3627,12 @@ static int skl_compute_plane_wm(const struct drm_i915_private *dev_priv,
+ 
+ 	if (level >= 1 && level <= 7) {
+ 		if (fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
+-		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)
+-			res_lines += 4;
+-		else
++		    fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED) {
++			res_blocks += y_tile_minimum;
++			res_lines += y_min_scanlines;
++		} else {
+ 			res_blocks++;
++		}
+ 	}
+ 
+ 	if (res_blocks >= ddb_allocation || res_lines > 31) {
+@@ -3828,183 +3851,82 @@ static void skl_ddb_entry_write(struct drm_i915_private *dev_priv,
+ 		I915_WRITE(reg, 0);
+ }
+ 
+-static void skl_write_wm_values(struct drm_i915_private *dev_priv,
+-				const struct skl_wm_values *new)
++void skl_write_plane_wm(struct intel_crtc *intel_crtc,
++			const struct skl_wm_values *wm,
++			int plane)
+ {
+-	struct drm_device *dev = &dev_priv->drm;
+-	struct intel_crtc *crtc;
+-
+-	for_each_intel_crtc(dev, crtc) {
+-		int i, level, max_level = ilk_wm_max_level(dev);
+-		enum pipe pipe = crtc->pipe;
+-
+-		if ((new->dirty_pipes & drm_crtc_mask(&crtc->base)) == 0)
+-			continue;
+-		if (!crtc->active)
+-			continue;
+-
+-		I915_WRITE(PIPE_WM_LINETIME(pipe), new->wm_linetime[pipe]);
+-
+-		for (level = 0; level <= max_level; level++) {
+-			for (i = 0; i < intel_num_planes(crtc); i++)
+-				I915_WRITE(PLANE_WM(pipe, i, level),
+-					   new->plane[pipe][i][level]);
+-			I915_WRITE(CUR_WM(pipe, level),
+-				   new->plane[pipe][PLANE_CURSOR][level]);
+-		}
+-		for (i = 0; i < intel_num_planes(crtc); i++)
+-			I915_WRITE(PLANE_WM_TRANS(pipe, i),
+-				   new->plane_trans[pipe][i]);
+-		I915_WRITE(CUR_WM_TRANS(pipe),
+-			   new->plane_trans[pipe][PLANE_CURSOR]);
+-
+-		for (i = 0; i < intel_num_planes(crtc); i++) {
+-			skl_ddb_entry_write(dev_priv,
+-					    PLANE_BUF_CFG(pipe, i),
+-					    &new->ddb.plane[pipe][i]);
+-			skl_ddb_entry_write(dev_priv,
+-					    PLANE_NV12_BUF_CFG(pipe, i),
+-					    &new->ddb.y_plane[pipe][i]);
+-		}
++	struct drm_crtc *crtc = &intel_crtc->base;
++	struct drm_device *dev = crtc->dev;
++	struct drm_i915_private *dev_priv = to_i915(dev);
++	int level, max_level = ilk_wm_max_level(dev);
++	enum pipe pipe = intel_crtc->pipe;
+ 
+-		skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
+-				    &new->ddb.plane[pipe][PLANE_CURSOR]);
++	for (level = 0; level <= max_level; level++) {
++		I915_WRITE(PLANE_WM(pipe, plane, level),
++			   wm->plane[pipe][plane][level]);
+ 	}
+-}
++	I915_WRITE(PLANE_WM_TRANS(pipe, plane), wm->plane_trans[pipe][plane]);
+ 
+-/*
+- * When setting up a new DDB allocation arrangement, we need to correctly
+- * sequence the times at which the new allocations for the pipes are taken into
+- * account or we'll have pipes fetching from space previously allocated to
+- * another pipe.
+- *
+- * Roughly the sequence looks like:
+- *  1. re-allocate the pipe(s) with the allocation being reduced and not
+- *     overlapping with a previous light-up pipe (another way to put it is:
+- *     pipes with their new allocation strickly included into their old ones).
+- *  2. re-allocate the other pipes that get their allocation reduced
+- *  3. allocate the pipes having their allocation increased
+- *
+- * Steps 1. and 2. are here to take care of the following case:
+- * - Initially DDB looks like this:
+- *     |   B    |   C    |
+- * - enable pipe A.
+- * - pipe B has a reduced DDB allocation that overlaps with the old pipe C
+- *   allocation
+- *     |  A  |  B  |  C  |
+- *
+- * We need to sequence the re-allocation: C, B, A (and not B, C, A).
+- */
++	skl_ddb_entry_write(dev_priv, PLANE_BUF_CFG(pipe, plane),
++			    &wm->ddb.plane[pipe][plane]);
++	skl_ddb_entry_write(dev_priv, PLANE_NV12_BUF_CFG(pipe, plane),
++			    &wm->ddb.y_plane[pipe][plane]);
++}
+ 
+-static void
+-skl_wm_flush_pipe(struct drm_i915_private *dev_priv, enum pipe pipe, int pass)
++void skl_write_cursor_wm(struct intel_crtc *intel_crtc,
++			 const struct skl_wm_values *wm)
+ {
+-	int plane;
+-
+-	DRM_DEBUG_KMS("flush pipe %c (pass %d)\n", pipe_name(pipe), pass);
++	struct drm_crtc *crtc = &intel_crtc->base;
++	struct drm_device *dev = crtc->dev;
++	struct drm_i915_private *dev_priv = to_i915(dev);
++	int level, max_level = ilk_wm_max_level(dev);
++	enum pipe pipe = intel_crtc->pipe;
+ 
+-	for_each_plane(dev_priv, pipe, plane) {
+-		I915_WRITE(PLANE_SURF(pipe, plane),
+-			   I915_READ(PLANE_SURF(pipe, plane)));
++	for (level = 0; level <= max_level; level++) {
++		I915_WRITE(CUR_WM(pipe, level),
++			   wm->plane[pipe][PLANE_CURSOR][level]);
+ 	}
+-	I915_WRITE(CURBASE(pipe), I915_READ(CURBASE(pipe)));
++	I915_WRITE(CUR_WM_TRANS(pipe), wm->plane_trans[pipe][PLANE_CURSOR]);
++
++	skl_ddb_entry_write(dev_priv, CUR_BUF_CFG(pipe),
++			    &wm->ddb.plane[pipe][PLANE_CURSOR]);
+ }
+ 
+-static bool
+-skl_ddb_allocation_included(const struct skl_ddb_allocation *old,
+-			    const struct skl_ddb_allocation *new,
+-			    enum pipe pipe)
++bool skl_ddb_allocation_equals(const struct skl_ddb_allocation *old,
++			       const struct skl_ddb_allocation *new,
++			       enum pipe pipe)
+ {
+-	uint16_t old_size, new_size;
+-
+-	old_size = skl_ddb_entry_size(&old->pipe[pipe]);
+-	new_size = skl_ddb_entry_size(&new->pipe[pipe]);
+-
+-	return old_size != new_size &&
+-	       new->pipe[pipe].start >= old->pipe[pipe].start &&
+-	       new->pipe[pipe].end <= old->pipe[pipe].end;
++	return new->pipe[pipe].start == old->pipe[pipe].start &&
++	       new->pipe[pipe].end == old->pipe[pipe].end;
+ }
+ 
+-static void skl_flush_wm_values(struct drm_i915_private *dev_priv,
+-				struct skl_wm_values *new_values)
++static inline bool skl_ddb_entries_overlap(const struct skl_ddb_entry *a,
++					   const struct skl_ddb_entry *b)
+ {
+-	struct drm_device *dev = &dev_priv->drm;
+-	struct skl_ddb_allocation *cur_ddb, *new_ddb;
+-	bool reallocated[I915_MAX_PIPES] = {};
+-	struct intel_crtc *crtc;
+-	enum pipe pipe;
+-
+-	new_ddb = &new_values->ddb;
+-	cur_ddb = &dev_priv->wm.skl_hw.ddb;
+-
+-	/*
+-	 * First pass: flush the pipes with the new allocation contained into
+-	 * the old space.
+-	 *
+-	 * We'll wait for the vblank on those pipes to ensure we can safely
+-	 * re-allocate the freed space without this pipe fetching from it.
+-	 */
+-	for_each_intel_crtc(dev, crtc) {
+-		if (!crtc->active)
+-			continue;
+-
+-		pipe = crtc->pipe;
+-
+-		if (!skl_ddb_allocation_included(cur_ddb, new_ddb, pipe))
+-			continue;
+-
+-		skl_wm_flush_pipe(dev_priv, pipe, 1);
+-		intel_wait_for_vblank(dev, pipe);
+-
+-		reallocated[pipe] = true;
+-	}
+-
++	return a->start < b->end && b->start < a->end;
++}
+ 
+-	/*
+-	 * Second pass: flush the pipes that are having their allocation
+-	 * reduced, but overlapping with a previous allocation.
+-	 *
+-	 * Here as well we need to wait for the vblank to make sure the freed
+-	 * space is not used anymore.
+-	 */
+-	for_each_intel_crtc(dev, crtc) {
+-		if (!crtc->active)
+-			continue;
++bool skl_ddb_allocation_overlaps(struct drm_atomic_state *state,
++				 const struct skl_ddb_allocation *old,
++				 const struct skl_ddb_allocation *new,
++				 enum pipe pipe)
++{
++	struct drm_device *dev = state->dev;
++	struct intel_crtc *intel_crtc;
++	enum pipe otherp;
+ 
+-		pipe = crtc->pipe;
++	for_each_intel_crtc(dev, intel_crtc) {
++		otherp = intel_crtc->pipe;
+ 
+-		if (reallocated[pipe])
++		if (otherp == pipe)
+ 			continue;
+ 
+-		if (skl_ddb_entry_size(&new_ddb->pipe[pipe]) <
+-		    skl_ddb_entry_size(&cur_ddb->pipe[pipe])) {
+-			skl_wm_flush_pipe(dev_priv, pipe, 2);
+-			intel_wait_for_vblank(dev, pipe);
+-			reallocated[pipe] = true;
+-		}
++		if (skl_ddb_entries_overlap(&new->pipe[pipe],
++					    &old->pipe[otherp]))
++			return true;
+ 	}
+ 
+-	/*
+-	 * Third pass: flush the pipes that got more space allocated.
+-	 *
+-	 * We don't need to actively wait for the update here, next vblank
+-	 * will just get more DDB space with the correct WM values.
+-	 */
+-	for_each_intel_crtc(dev, crtc) {
+-		if (!crtc->active)
+-			continue;
+-
+-		pipe = crtc->pipe;
+-
+-		/*
+-		 * At this point, only the pipes more space than before are
+-		 * left to re-allocate.
+-		 */
+-		if (reallocated[pipe])
+-			continue;
+-
+-		skl_wm_flush_pipe(dev_priv, pipe, 3);
+-	}
++	return false;
+ }
+ 
+ static int skl_update_pipe_wm(struct drm_crtc_state *cstate,
+@@ -4041,6 +3963,41 @@ pipes_modified(struct drm_atomic_state *state)
+ 	return ret;
+ }
+ 
++int
++skl_ddb_add_affected_planes(struct intel_crtc_state *cstate)
++{
++	struct drm_atomic_state *state = cstate->base.state;
++	struct drm_device *dev = state->dev;
++	struct drm_crtc *crtc = cstate->base.crtc;
++	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
++	struct drm_i915_private *dev_priv = to_i915(dev);
++	struct intel_atomic_state *intel_state = to_intel_atomic_state(state);
++	struct skl_ddb_allocation *new_ddb = &intel_state->wm_results.ddb;
++	struct skl_ddb_allocation *cur_ddb = &dev_priv->wm.skl_hw.ddb;
++	struct drm_plane_state *plane_state;
++	struct drm_plane *plane;
++	enum pipe pipe = intel_crtc->pipe;
++	int id;
++
++	WARN_ON(!drm_atomic_get_existing_crtc_state(state, crtc));
++
++	drm_for_each_plane_mask(plane, dev, crtc->state->plane_mask) {
++		id = skl_wm_plane_id(to_intel_plane(plane));
++
++		if (skl_ddb_entry_equal(&cur_ddb->plane[pipe][id],
++					&new_ddb->plane[pipe][id]) &&
++		    skl_ddb_entry_equal(&cur_ddb->y_plane[pipe][id],
++					&new_ddb->y_plane[pipe][id]))
++			continue;
++
++		plane_state = drm_atomic_get_plane_state(state, plane);
++		if (IS_ERR(plane_state))
++			return PTR_ERR(plane_state);
++	}
++
++	return 0;
++}
++
+ static int
+ skl_compute_ddb(struct drm_atomic_state *state)
+ {
+@@ -4105,6 +4062,10 @@ skl_compute_ddb(struct drm_atomic_state *state)
+ 		if (ret)
+ 			return ret;
+ 
++		ret = skl_ddb_add_affected_planes(cstate);
++		if (ret)
++			return ret;
++
+ 		ret = drm_atomic_add_affected_planes(state, &intel_crtc->base);
+ 		if (ret)
+ 			return ret;
+@@ -4206,7 +4167,7 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ 	struct skl_wm_values *hw_vals = &dev_priv->wm.skl_hw;
+ 	struct intel_crtc_state *cstate = to_intel_crtc_state(crtc->state);
+ 	struct skl_pipe_wm *pipe_wm = &cstate->wm.skl.optimal;
+-	int pipe;
++	enum pipe pipe = intel_crtc->pipe;
+ 
+ 	if ((results->dirty_pipes & drm_crtc_mask(crtc)) == 0)
+ 		return;
+@@ -4215,15 +4176,22 @@ static void skl_update_wm(struct drm_crtc *crtc)
+ 
+ 	mutex_lock(&dev_priv->wm.wm_mutex);
+ 
+-	skl_write_wm_values(dev_priv, results);
+-	skl_flush_wm_values(dev_priv, results);
+-
+ 	/*
+-	 * Store the new configuration (but only for the pipes that have
+-	 * changed; the other values weren't recomputed).
++	 * If this pipe isn't active already, we're going to be enabling it
++	 * very soon. Since it's safe to update a pipe's ddb allocation while
++	 * the pipe's shut off, just do so here. Already active pipes will have
++	 * their watermarks updated once we update their planes.
+ 	 */
+-	for_each_pipe_masked(dev_priv, pipe, results->dirty_pipes)
+-		skl_copy_wm_for_pipe(hw_vals, results, pipe);
++	if (crtc->state->active_changed) {
++		int plane;
++
++		for (plane = 0; plane < intel_num_planes(intel_crtc); plane++)
++			skl_write_plane_wm(intel_crtc, results, plane);
++
++		skl_write_cursor_wm(intel_crtc, results);
++	}
++
++	skl_copy_wm_for_pipe(hw_vals, results, pipe);
+ 
+ 	mutex_unlock(&dev_priv->wm.wm_mutex);
+ }
+diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
+index 7c08e4f29032..4178849631ad 100644
+--- a/drivers/gpu/drm/i915/intel_sprite.c
++++ b/drivers/gpu/drm/i915/intel_sprite.c
+@@ -203,6 +203,9 @@ skl_update_plane(struct drm_plane *drm_plane,
+ 	struct intel_plane *intel_plane = to_intel_plane(drm_plane);
+ 	struct drm_framebuffer *fb = plane_state->base.fb;
+ 	struct drm_i915_gem_object *obj = intel_fb_obj(fb);
++	const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
++	struct drm_crtc *crtc = crtc_state->base.crtc;
++	struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
+ 	const int pipe = intel_plane->pipe;
+ 	const int plane = intel_plane->plane + 1;
+ 	u32 plane_ctl, stride_div, stride;
+@@ -238,6 +241,9 @@ skl_update_plane(struct drm_plane *drm_plane,
+ 	crtc_w--;
+ 	crtc_h--;
+ 
++	if (wm->dirty_pipes & drm_crtc_mask(crtc))
++		skl_write_plane_wm(intel_crtc, wm, plane);
++
+ 	if (key->flags) {
+ 		I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
+ 		I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
+@@ -308,6 +314,14 @@ skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
+ 	const int pipe = intel_plane->pipe;
+ 	const int plane = intel_plane->plane + 1;
+ 
++	/*
++	 * We only populate skl_results on watermark updates, and if the
++	 * plane's visiblity isn't actually changing neither is its watermarks.
++	 */
++	if (!to_intel_plane_state(dplane->state)->visible)
++		skl_write_plane_wm(to_intel_crtc(crtc),
++				   &dev_priv->wm.skl_results, plane);
++
+ 	I915_WRITE(PLANE_CTL(pipe, plane), 0);
+ 
+ 	I915_WRITE(PLANE_SURF(pipe, plane), 0);
+diff --git a/drivers/gpu/drm/i915/intel_uncore.c b/drivers/gpu/drm/i915/intel_uncore.c
+index ff80a81b1a84..ec28b15f2724 100644
+--- a/drivers/gpu/drm/i915/intel_uncore.c
++++ b/drivers/gpu/drm/i915/intel_uncore.c
+@@ -796,10 +796,9 @@ __unclaimed_reg_debug(struct drm_i915_private *dev_priv,
+ 		      const bool read,
+ 		      const bool before)
+ {
+-	if (WARN(check_for_unclaimed_mmio(dev_priv),
+-		 "Unclaimed register detected %s %s register 0x%x\n",
+-		 before ? "before" : "after",
+-		 read ? "reading" : "writing to",
++	if (WARN(check_for_unclaimed_mmio(dev_priv) && !before,
++		 "Unclaimed %s register 0x%x\n",
++		 read ? "read from" : "write to",
+ 		 i915_mmio_reg_offset(reg)))
+ 		i915.mmio_debug--; /* Only report the first N failures */
+ }
+diff --git a/drivers/gpu/drm/radeon/r600_dpm.c b/drivers/gpu/drm/radeon/r600_dpm.c
+index 6a4b020dd0b4..5a26eb4545aa 100644
+--- a/drivers/gpu/drm/radeon/r600_dpm.c
++++ b/drivers/gpu/drm/radeon/r600_dpm.c
+@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
+ 	struct drm_device *dev = rdev->ddev;
+ 	struct drm_crtc *crtc;
+ 	struct radeon_crtc *radeon_crtc;
+-	u32 line_time_us, vblank_lines;
++	u32 vblank_in_pixels;
+ 	u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
+ 
+ 	if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
+ 		list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ 			radeon_crtc = to_radeon_crtc(crtc);
+ 			if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
+-				line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
+-					radeon_crtc->hw_mode.clock;
+-				vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
+-					radeon_crtc->hw_mode.crtc_vdisplay +
+-					(radeon_crtc->v_border * 2);
+-				vblank_time_us = vblank_lines * line_time_us;
++				vblank_in_pixels =
++					radeon_crtc->hw_mode.crtc_htotal *
++					(radeon_crtc->hw_mode.crtc_vblank_end -
++					 radeon_crtc->hw_mode.crtc_vdisplay +
++					 (radeon_crtc->v_border * 2));
++
++				vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
+ 				break;
+ 			}
+ 		}
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index a00dd2f74527..554ca7115f98 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -661,8 +661,9 @@ bool radeon_card_posted(struct radeon_device *rdev)
+ {
+ 	uint32_t reg;
+ 
+-	/* for pass through, always force asic_init */
+-	if (radeon_device_is_virtual())
++	/* for pass through, always force asic_init for CI */
++	if (rdev->family >= CHIP_BONAIRE &&
++	    radeon_device_is_virtual())
+ 		return false;
+ 
+ 	/* required for EFI mode on macbook2,1 which uses an r5xx asic */
+diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
+index 1f78ec2548ec..89bdf20344ae 100644
+--- a/drivers/gpu/drm/radeon/si_dpm.c
++++ b/drivers/gpu/drm/radeon/si_dpm.c
+@@ -4112,7 +4112,7 @@ static int si_populate_smc_voltage_tables(struct radeon_device *rdev,
+ 							      &rdev->pm.dpm.dyn_state.phase_shedding_limits_table)) {
+ 				si_populate_smc_voltage_table(rdev, &si_pi->vddc_phase_shed_table, table);
+ 
+-				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC] =
++				table->phaseMaskTable.lowMask[SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING] =
+ 					cpu_to_be32(si_pi->vddc_phase_shed_table.mask_low);
+ 
+ 				si_write_smc_soft_register(rdev, SI_SMC_SOFT_REGISTER_phase_shedding_delay,
+diff --git a/drivers/gpu/drm/radeon/sislands_smc.h b/drivers/gpu/drm/radeon/sislands_smc.h
+index 3c779838d9ab..966e3a556011 100644
+--- a/drivers/gpu/drm/radeon/sislands_smc.h
++++ b/drivers/gpu/drm/radeon/sislands_smc.h
+@@ -194,6 +194,7 @@ typedef struct SISLANDS_SMC_SWSTATE SISLANDS_SMC_SWSTATE;
+ #define SISLANDS_SMC_VOLTAGEMASK_VDDC  0
+ #define SISLANDS_SMC_VOLTAGEMASK_MVDD  1
+ #define SISLANDS_SMC_VOLTAGEMASK_VDDCI 2
++#define SISLANDS_SMC_VOLTAGEMASK_VDDC_PHASE_SHEDDING 3
+ #define SISLANDS_SMC_VOLTAGEMASK_MAX   4
+ 
+ struct SISLANDS_SMC_VOLTAGEMASKTABLE
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
+index 428e24919ef1..f696b752886b 100644
+--- a/drivers/gpu/drm/vc4/vc4_drv.h
++++ b/drivers/gpu/drm/vc4/vc4_drv.h
+@@ -122,9 +122,16 @@ to_vc4_dev(struct drm_device *dev)
+ struct vc4_bo {
+ 	struct drm_gem_cma_object base;
+ 
+-	/* seqno of the last job to render to this BO. */
++	/* seqno of the last job to render using this BO. */
+ 	uint64_t seqno;
+ 
++	/* seqno of the last job to use the RCL to write to this BO.
++	 *
++	 * Note that this doesn't include binner overflow memory
++	 * writes.
++	 */
++	uint64_t write_seqno;
++
+ 	/* List entry for the BO's position in either
+ 	 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
+ 	 */
+@@ -216,6 +223,9 @@ struct vc4_exec_info {
+ 	/* Sequence number for this bin/render job. */
+ 	uint64_t seqno;
+ 
++	/* Latest write_seqno of any BO that binning depends on. */
++	uint64_t bin_dep_seqno;
++
+ 	/* Last current addresses the hardware was processing when the
+ 	 * hangcheck timer checked on us.
+ 	 */
+@@ -230,6 +240,13 @@ struct vc4_exec_info {
+ 	struct drm_gem_cma_object **bo;
+ 	uint32_t bo_count;
+ 
++	/* List of BOs that are being written by the RCL.  Other than
++	 * the binner temporary storage, this is all the BOs written
++	 * by the job.
++	 */
++	struct drm_gem_cma_object *rcl_write_bo[4];
++	uint32_t rcl_write_bo_count;
++
+ 	/* Pointers for our position in vc4->job_list */
+ 	struct list_head head;
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_gem.c b/drivers/gpu/drm/vc4/vc4_gem.c
+index b262c5c26f10..ae1609e739ef 100644
+--- a/drivers/gpu/drm/vc4/vc4_gem.c
++++ b/drivers/gpu/drm/vc4/vc4_gem.c
+@@ -471,6 +471,11 @@ vc4_update_bo_seqnos(struct vc4_exec_info *exec, uint64_t seqno)
+ 	list_for_each_entry(bo, &exec->unref_list, unref_head) {
+ 		bo->seqno = seqno;
+ 	}
++
++	for (i = 0; i < exec->rcl_write_bo_count; i++) {
++		bo = to_vc4_bo(&exec->rcl_write_bo[i]->base);
++		bo->write_seqno = seqno;
++	}
+ }
+ 
+ /* Queues a struct vc4_exec_info for execution.  If no job is
+@@ -673,6 +678,14 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
+ 		goto fail;
+ 
+ 	ret = vc4_validate_shader_recs(dev, exec);
++	if (ret)
++		goto fail;
++
++	/* Block waiting on any previous rendering into the CS's VBO,
++	 * IB, or textures, so that pixels are actually written by the
++	 * time we try to read them.
++	 */
++	ret = vc4_wait_for_seqno(dev, exec->bin_dep_seqno, ~0ull, true);
+ 
+ fail:
+ 	drm_free_large(temp);
+diff --git a/drivers/gpu/drm/vc4/vc4_render_cl.c b/drivers/gpu/drm/vc4/vc4_render_cl.c
+index 0f12418725e5..08886a309757 100644
+--- a/drivers/gpu/drm/vc4/vc4_render_cl.c
++++ b/drivers/gpu/drm/vc4/vc4_render_cl.c
+@@ -45,6 +45,8 @@ struct vc4_rcl_setup {
+ 
+ 	struct drm_gem_cma_object *rcl;
+ 	u32 next_offset;
++
++	u32 next_write_bo_index;
+ };
+ 
+ static inline void rcl_u8(struct vc4_rcl_setup *setup, u8 val)
+@@ -407,6 +409,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
+ 	if (!*obj)
+ 		return -EINVAL;
+ 
++	exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
++
+ 	if (surf->offset & 0xf) {
+ 		DRM_ERROR("MSAA write must be 16b aligned.\n");
+ 		return -EINVAL;
+@@ -417,7 +421,8 @@ static int vc4_rcl_msaa_surface_setup(struct vc4_exec_info *exec,
+ 
+ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
+ 				 struct drm_gem_cma_object **obj,
+-				 struct drm_vc4_submit_rcl_surface *surf)
++				 struct drm_vc4_submit_rcl_surface *surf,
++				 bool is_write)
+ {
+ 	uint8_t tiling = VC4_GET_FIELD(surf->bits,
+ 				       VC4_LOADSTORE_TILE_BUFFER_TILING);
+@@ -440,6 +445,9 @@ static int vc4_rcl_surface_setup(struct vc4_exec_info *exec,
+ 	if (!*obj)
+ 		return -EINVAL;
+ 
++	if (is_write)
++		exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
++
+ 	if (surf->flags & VC4_SUBMIT_RCL_SURFACE_READ_IS_FULL_RES) {
+ 		if (surf == &exec->args->zs_write) {
+ 			DRM_ERROR("general zs write may not be a full-res.\n");
+@@ -542,6 +550,8 @@ vc4_rcl_render_config_surface_setup(struct vc4_exec_info *exec,
+ 	if (!*obj)
+ 		return -EINVAL;
+ 
++	exec->rcl_write_bo[exec->rcl_write_bo_count++] = *obj;
++
+ 	if (tiling > VC4_TILING_FORMAT_LT) {
+ 		DRM_ERROR("Bad tiling format\n");
+ 		return -EINVAL;
+@@ -599,15 +609,18 @@ int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec)
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read);
++	ret = vc4_rcl_surface_setup(exec, &setup.color_read, &args->color_read,
++				    false);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read);
++	ret = vc4_rcl_surface_setup(exec, &setup.zs_read, &args->zs_read,
++				    false);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write);
++	ret = vc4_rcl_surface_setup(exec, &setup.zs_write, &args->zs_write,
++				    true);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/drivers/gpu/drm/vc4/vc4_validate.c b/drivers/gpu/drm/vc4/vc4_validate.c
+index 9ce1d0adf882..26503e307438 100644
+--- a/drivers/gpu/drm/vc4/vc4_validate.c
++++ b/drivers/gpu/drm/vc4/vc4_validate.c
+@@ -267,6 +267,9 @@ validate_indexed_prim_list(VALIDATE_ARGS)
+ 	if (!ib)
+ 		return -EINVAL;
+ 
++	exec->bin_dep_seqno = max(exec->bin_dep_seqno,
++				  to_vc4_bo(&ib->base)->write_seqno);
++
+ 	if (offset > ib->base.size ||
+ 	    (ib->base.size - offset) / index_size < length) {
+ 		DRM_ERROR("IB access overflow (%d + %d*%d > %zd)\n",
+@@ -555,8 +558,7 @@ static bool
+ reloc_tex(struct vc4_exec_info *exec,
+ 	  void *uniform_data_u,
+ 	  struct vc4_texture_sample_info *sample,
+-	  uint32_t texture_handle_index)
+-
++	  uint32_t texture_handle_index, bool is_cs)
+ {
+ 	struct drm_gem_cma_object *tex;
+ 	uint32_t p0 = *(uint32_t *)(uniform_data_u + sample->p_offset[0]);
+@@ -714,6 +716,11 @@ reloc_tex(struct vc4_exec_info *exec,
+ 
+ 	*validated_p0 = tex->paddr + p0;
+ 
++	if (is_cs) {
++		exec->bin_dep_seqno = max(exec->bin_dep_seqno,
++					  to_vc4_bo(&tex->base)->write_seqno);
++	}
++
+ 	return true;
+  fail:
+ 	DRM_INFO("Texture p0 at %d: 0x%08x\n", sample->p_offset[0], p0);
+@@ -835,7 +842,8 @@ validate_gl_shader_rec(struct drm_device *dev,
+ 			if (!reloc_tex(exec,
+ 				       uniform_data_u,
+ 				       &validated_shader->texture_samples[tex],
+-				       texture_handles_u[tex])) {
++				       texture_handles_u[tex],
++				       i == 2)) {
+ 				return -EINVAL;
+ 			}
+ 		}
+@@ -867,6 +875,9 @@ validate_gl_shader_rec(struct drm_device *dev,
+ 		uint32_t stride = *(uint8_t *)(pkt_u + o + 5);
+ 		uint32_t max_index;
+ 
++		exec->bin_dep_seqno = max(exec->bin_dep_seqno,
++					  to_vc4_bo(&vbo->base)->write_seqno);
++
+ 		if (state->addr & 0x8)
+ 			stride |= (*(uint32_t *)(pkt_u + 100 + i * 4)) & ~0xff;
+ 
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+index dc5beff2b4aa..8a15c4aa84c1 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c
+@@ -34,6 +34,24 @@
+ 
+ #define VMW_RES_HT_ORDER 12
+ 
++ /**
++ * enum vmw_resource_relocation_type - Relocation type for resources
++ *
++ * @vmw_res_rel_normal: Traditional relocation. The resource id in the
++ * command stream is replaced with the actual id after validation.
++ * @vmw_res_rel_nop: NOP relocation. The command is unconditionally replaced
++ * with a NOP.
++ * @vmw_res_rel_cond_nop: Conditional NOP relocation. If the resource id
++ * after validation is -1, the command is replaced with a NOP. Otherwise no
++ * action.
++ */
++enum vmw_resource_relocation_type {
++	vmw_res_rel_normal,
++	vmw_res_rel_nop,
++	vmw_res_rel_cond_nop,
++	vmw_res_rel_max
++};
++
+ /**
+  * struct vmw_resource_relocation - Relocation info for resources
+  *
+@@ -41,11 +59,13 @@
+  * @res: Non-ref-counted pointer to the resource.
+  * @offset: Offset of 4 byte entries into the command buffer where the
+  * id that needs fixup is located.
++ * @rel_type: Type of relocation.
+  */
+ struct vmw_resource_relocation {
+ 	struct list_head head;
+ 	const struct vmw_resource *res;
+-	unsigned long offset;
++	u32 offset:29;
++	enum vmw_resource_relocation_type rel_type:3;
+ };
+ 
+ /**
+@@ -410,10 +430,13 @@ static int vmw_resource_context_res_add(struct vmw_private *dev_priv,
+  * @res: The resource.
+  * @offset: Offset into the command buffer currently being parsed where the
+  * id that needs fixup is located. Granularity is 4 bytes.
++ * @rel_type: Relocation type.
+  */
+ static int vmw_resource_relocation_add(struct list_head *list,
+ 				       const struct vmw_resource *res,
+-				       unsigned long offset)
++				       unsigned long offset,
++				       enum vmw_resource_relocation_type
++				       rel_type)
+ {
+ 	struct vmw_resource_relocation *rel;
+ 
+@@ -425,6 +448,7 @@ static int vmw_resource_relocation_add(struct list_head *list,
+ 
+ 	rel->res = res;
+ 	rel->offset = offset;
++	rel->rel_type = rel_type;
+ 	list_add_tail(&rel->head, list);
+ 
+ 	return 0;
+@@ -459,11 +483,23 @@ static void vmw_resource_relocations_apply(uint32_t *cb,
+ {
+ 	struct vmw_resource_relocation *rel;
+ 
++	/* Validate the struct vmw_resource_relocation member size */
++	BUILD_BUG_ON(SVGA_CB_MAX_SIZE >= (1 << 29));
++	BUILD_BUG_ON(vmw_res_rel_max >= (1 << 3));
++
+ 	list_for_each_entry(rel, list, head) {
+-		if (likely(rel->res != NULL))
++		switch (rel->rel_type) {
++		case vmw_res_rel_normal:
+ 			cb[rel->offset] = rel->res->id;
+-		else
++			break;
++		case vmw_res_rel_nop:
+ 			cb[rel->offset] = SVGA_3D_CMD_NOP;
++			break;
++		default:
++			if (rel->res->id == -1)
++				cb[rel->offset] = SVGA_3D_CMD_NOP;
++			break;
++		}
+ 	}
+ }
+ 
+@@ -655,7 +691,8 @@ static int vmw_cmd_res_reloc_add(struct vmw_private *dev_priv,
+ 	*p_val = NULL;
+ 	ret = vmw_resource_relocation_add(&sw_context->res_relocations,
+ 					  res,
+-					  id_loc - sw_context->buf_start);
++					  id_loc - sw_context->buf_start,
++					  vmw_res_rel_normal);
+ 	if (unlikely(ret != 0))
+ 		return ret;
+ 
+@@ -721,7 +758,8 @@ vmw_cmd_res_check(struct vmw_private *dev_priv,
+ 
+ 		return vmw_resource_relocation_add
+ 			(&sw_context->res_relocations, res,
+-			 id_loc - sw_context->buf_start);
++			 id_loc - sw_context->buf_start,
++			 vmw_res_rel_normal);
+ 	}
+ 
+ 	ret = vmw_user_resource_lookup_handle(dev_priv,
+@@ -2144,7 +2182,8 @@ static int vmw_cmd_shader_define(struct vmw_private *dev_priv,
+ 
+ 	return vmw_resource_relocation_add(&sw_context->res_relocations,
+ 					   NULL, &cmd->header.id -
+-					   sw_context->buf_start);
++					   sw_context->buf_start,
++					   vmw_res_rel_nop);
+ 
+ 	return 0;
+ }
+@@ -2189,7 +2228,8 @@ static int vmw_cmd_shader_destroy(struct vmw_private *dev_priv,
+ 
+ 	return vmw_resource_relocation_add(&sw_context->res_relocations,
+ 					   NULL, &cmd->header.id -
+-					   sw_context->buf_start);
++					   sw_context->buf_start,
++					   vmw_res_rel_nop);
+ 
+ 	return 0;
+ }
+@@ -2848,8 +2888,7 @@ static int vmw_cmd_dx_cid_check(struct vmw_private *dev_priv,
+  * @header: Pointer to the command header in the command stream.
+  *
+  * Check that the view exists, and if it was not created using this
+- * command batch, make sure it's validated (present in the device) so that
+- * the remove command will not confuse the device.
++ * command batch, conditionally make this command a NOP.
+  */
+ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
+ 				  struct vmw_sw_context *sw_context,
+@@ -2877,10 +2916,15 @@ static int vmw_cmd_dx_view_remove(struct vmw_private *dev_priv,
+ 		return ret;
+ 
+ 	/*
+-	 * Add view to the validate list iff it was not created using this
+-	 * command batch.
++	 * If the view wasn't created during this command batch, it might
++	 * have been removed due to a context swapout, so add a
++	 * relocation to conditionally make this command a NOP to avoid
++	 * device errors.
+ 	 */
+-	return vmw_view_res_val_add(sw_context, view);
++	return vmw_resource_relocation_add(&sw_context->res_relocations,
++					   view,
++					   &cmd->header.id - sw_context->buf_start,
++					   vmw_res_rel_cond_nop);
+ }
+ 
+ /**
+@@ -3848,14 +3892,14 @@ static void *vmw_execbuf_cmdbuf(struct vmw_private *dev_priv,
+ 	int ret;
+ 
+ 	*header = NULL;
+-	if (!dev_priv->cman || kernel_commands)
+-		return kernel_commands;
+-
+ 	if (command_size > SVGA_CB_MAX_SIZE) {
+ 		DRM_ERROR("Command buffer is too large.\n");
+ 		return ERR_PTR(-EINVAL);
+ 	}
+ 
++	if (!dev_priv->cman || kernel_commands)
++		return kernel_commands;
++
+ 	/* If possible, add a little space for fencing. */
+ 	cmdbuf_size = command_size + 512;
+ 	cmdbuf_size = min_t(size_t, cmdbuf_size, SVGA_CB_MAX_SIZE);
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index 4ed9a4fdfea7..e92b09d32605 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -64,6 +64,9 @@
+ #define USB_VENDOR_ID_AKAI		0x2011
+ #define USB_DEVICE_ID_AKAI_MPKMINI2	0x0715
+ 
++#define USB_VENDOR_ID_AKAI_09E8		0x09E8
++#define USB_DEVICE_ID_AKAI_09E8_MIDIMIX	0x0031
++
+ #define USB_VENDOR_ID_ALCOR		0x058f
+ #define USB_DEVICE_ID_ALCOR_USBRS232	0x9720
+ 
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index b4b8c6abb03e..bb400081efe4 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -56,6 +56,7 @@ static const struct hid_blacklist {
+ 
+ 	{ USB_VENDOR_ID_AIREN, USB_DEVICE_ID_AIREN_SLIMPLUS, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_AKAI, USB_DEVICE_ID_AKAI_MPKMINI2, HID_QUIRK_NO_INIT_REPORTS },
++	{ USB_VENDOR_ID_AKAI_09E8, USB_DEVICE_ID_AKAI_09E8_MIDIMIX, HID_QUIRK_NO_INIT_REPORTS },
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS124U, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_2PORTKVM, HID_QUIRK_NOGET },
+diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c
+index 9e02ac963cd0..3978cbb6b038 100644
+--- a/drivers/hwtracing/coresight/coresight-tmc.c
++++ b/drivers/hwtracing/coresight/coresight-tmc.c
+@@ -388,9 +388,6 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id)
+ err_misc_register:
+ 	coresight_unregister(drvdata->csdev);
+ err_devm_kzalloc:
+-	if (drvdata->config_type == TMC_CONFIG_TYPE_ETR)
+-		dma_free_coherent(dev, drvdata->size,
+-				drvdata->vaddr, drvdata->paddr);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/iio/dac/ad5755.c b/drivers/iio/dac/ad5755.c
+index 0fde593ec0d9..5f7968232564 100644
+--- a/drivers/iio/dac/ad5755.c
++++ b/drivers/iio/dac/ad5755.c
+@@ -655,7 +655,7 @@ static struct ad5755_platform_data *ad5755_parse_dt(struct device *dev)
+ 
+ 	devnr = 0;
+ 	for_each_child_of_node(np, pp) {
+-		if (devnr > AD5755_NUM_CHANNELS) {
++		if (devnr >= AD5755_NUM_CHANNELS) {
+ 			dev_err(dev,
+ 				"There is to many channels defined in DT\n");
+ 			goto error_out;
+diff --git a/drivers/iio/light/us5182d.c b/drivers/iio/light/us5182d.c
+index 20c40f780964..18cf2e29e4d5 100644
+--- a/drivers/iio/light/us5182d.c
++++ b/drivers/iio/light/us5182d.c
+@@ -894,7 +894,7 @@ static int us5182d_probe(struct i2c_client *client,
+ 		goto out_err;
+ 
+ 	if (data->default_continuous) {
+-		pm_runtime_set_active(&client->dev);
++		ret = pm_runtime_set_active(&client->dev);
+ 		if (ret < 0)
+ 			goto out_err;
+ 	}
+diff --git a/drivers/infiniband/hw/hfi1/qp.c b/drivers/infiniband/hw/hfi1/qp.c
+index 4e4d8317c281..c17c9dd7cde1 100644
+--- a/drivers/infiniband/hw/hfi1/qp.c
++++ b/drivers/infiniband/hw/hfi1/qp.c
+@@ -808,6 +808,13 @@ void *qp_priv_alloc(struct rvt_dev_info *rdi, struct rvt_qp *qp,
+ 		kfree(priv);
+ 		return ERR_PTR(-ENOMEM);
+ 	}
++	iowait_init(
++		&priv->s_iowait,
++		1,
++		_hfi1_do_send,
++		iowait_sleep,
++		iowait_wakeup,
++		iowait_sdma_drained);
+ 	setup_timer(&priv->s_rnr_timer, hfi1_rc_rnr_retry, (unsigned long)qp);
+ 	qp->s_timer.function = hfi1_rc_timeout;
+ 	return priv;
+@@ -873,13 +880,6 @@ void notify_qp_reset(struct rvt_qp *qp)
+ {
+ 	struct hfi1_qp_priv *priv = qp->priv;
+ 
+-	iowait_init(
+-		&priv->s_iowait,
+-		1,
+-		_hfi1_do_send,
+-		iowait_sleep,
+-		iowait_wakeup,
+-		iowait_sdma_drained);
+ 	priv->r_adefered = 0;
+ 	clear_ahg(qp);
+ }
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index e19537cf44ab..bff8707a2f1f 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -1843,6 +1843,7 @@ static struct mlx5_ib_flow_handler *create_leftovers_rule(struct mlx5_ib_dev *de
+ 						 &leftovers_specs[LEFTOVERS_UC].flow_attr,
+ 						 dst);
+ 		if (IS_ERR(handler_ucast)) {
++			mlx5_del_flow_rule(handler->rule);
+ 			kfree(handler);
+ 			handler = handler_ucast;
+ 		} else {
+diff --git a/drivers/infiniband/hw/qib/qib.h b/drivers/infiniband/hw/qib/qib.h
+index bbf0a163aeab..54bb655f5332 100644
+--- a/drivers/infiniband/hw/qib/qib.h
++++ b/drivers/infiniband/hw/qib/qib.h
+@@ -1131,7 +1131,6 @@ extern spinlock_t qib_devs_lock;
+ extern struct qib_devdata *qib_lookup(int unit);
+ extern u32 qib_cpulist_count;
+ extern unsigned long *qib_cpulist;
+-extern u16 qpt_mask;
+ extern unsigned qib_cc_table_size;
+ 
+ int qib_init(struct qib_devdata *, int);
+diff --git a/drivers/infiniband/hw/qib/qib_qp.c b/drivers/infiniband/hw/qib/qib_qp.c
+index f9b8cd2354d1..99d31efe4c2f 100644
+--- a/drivers/infiniband/hw/qib/qib_qp.c
++++ b/drivers/infiniband/hw/qib/qib_qp.c
+@@ -41,14 +41,6 @@
+ 
+ #include "qib.h"
+ 
+-/*
+- * mask field which was present in now deleted qib_qpn_table
+- * is not present in rvt_qpn_table. Defining the same field
+- * as qpt_mask here instead of adding the mask field to
+- * rvt_qpn_table.
+- */
+-u16 qpt_mask;
+-
+ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
+ 			      struct rvt_qpn_map *map, unsigned off)
+ {
+@@ -57,7 +49,7 @@ static inline unsigned mk_qpn(struct rvt_qpn_table *qpt,
+ 
+ static inline unsigned find_next_offset(struct rvt_qpn_table *qpt,
+ 					struct rvt_qpn_map *map, unsigned off,
+-					unsigned n)
++					unsigned n, u16 qpt_mask)
+ {
+ 	if (qpt_mask) {
+ 		off++;
+@@ -179,6 +171,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
+ 	struct qib_ibdev *verbs_dev = container_of(rdi, struct qib_ibdev, rdi);
+ 	struct qib_devdata *dd = container_of(verbs_dev, struct qib_devdata,
+ 					      verbs_dev);
++	u16 qpt_mask = dd->qpn_mask;
+ 
+ 	if (type == IB_QPT_SMI || type == IB_QPT_GSI) {
+ 		unsigned n;
+@@ -215,7 +208,7 @@ int qib_alloc_qpn(struct rvt_dev_info *rdi, struct rvt_qpn_table *qpt,
+ 				goto bail;
+ 			}
+ 			offset = find_next_offset(qpt, map, offset,
+-				dd->n_krcv_queues);
++				dd->n_krcv_queues, qpt_mask);
+ 			qpn = mk_qpn(qpt, map, offset);
+ 			/*
+ 			 * This test differs from alloc_pidmap().
+diff --git a/drivers/infiniband/hw/qib/qib_verbs.c b/drivers/infiniband/hw/qib/qib_verbs.c
+index fd1dfbce5539..b2b845f9f7df 100644
+--- a/drivers/infiniband/hw/qib/qib_verbs.c
++++ b/drivers/infiniband/hw/qib/qib_verbs.c
+@@ -1606,8 +1606,6 @@ int qib_register_ib_device(struct qib_devdata *dd)
+ 	/* Only need to initialize non-zero fields. */
+ 	setup_timer(&dev->mem_timer, mem_timer, (unsigned long)dev);
+ 
+-	qpt_mask = dd->qpn_mask;
+-
+ 	INIT_LIST_HEAD(&dev->piowait);
+ 	INIT_LIST_HEAD(&dev->dmawait);
+ 	INIT_LIST_HEAD(&dev->txwait);
+diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
+index 870b4f212fbc..5911c534cc18 100644
+--- a/drivers/infiniband/sw/rdmavt/qp.c
++++ b/drivers/infiniband/sw/rdmavt/qp.c
+@@ -501,12 +501,9 @@ static void rvt_remove_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp)
+  */
+ static void rvt_reset_qp(struct rvt_dev_info *rdi, struct rvt_qp *qp,
+ 		  enum ib_qp_type type)
+-	__releases(&qp->s_lock)
+-	__releases(&qp->s_hlock)
+-	__releases(&qp->r_lock)
+-	__acquires(&qp->r_lock)
+-	__acquires(&qp->s_hlock)
+-	__acquires(&qp->s_lock)
++	__must_hold(&qp->r_lock)
++	__must_hold(&qp->s_hlock)
++	__must_hold(&qp->s_lock)
+ {
+ 	if (qp->state != IB_QPS_RESET) {
+ 		qp->state = IB_QPS_RESET;
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
+index 618f18436618..c65e17fae24e 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
+@@ -1009,7 +1009,6 @@ int i40e_unregister_client(struct i40e_client *client)
+ 	if (!i40e_client_is_registered(client)) {
+ 		pr_info("i40e: Client %s has not been registered\n",
+ 			client->name);
+-		mutex_unlock(&i40e_client_mutex);
+ 		ret = -ENODEV;
+ 		goto out;
+ 	}
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index dad15b6c66dd..c74d16409941 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -7990,45 +7990,34 @@ static int i40e_setup_misc_vector(struct i40e_pf *pf)
+ static int i40e_config_rss_aq(struct i40e_vsi *vsi, const u8 *seed,
+ 			      u8 *lut, u16 lut_size)
+ {
+-	struct i40e_aqc_get_set_rss_key_data rss_key;
+ 	struct i40e_pf *pf = vsi->back;
+ 	struct i40e_hw *hw = &pf->hw;
+-	bool pf_lut = false;
+-	u8 *rss_lut;
+-	int ret, i;
+-
+-	memcpy(&rss_key, seed, sizeof(rss_key));
+-
+-	rss_lut = kzalloc(pf->rss_table_size, GFP_KERNEL);
+-	if (!rss_lut)
+-		return -ENOMEM;
+-
+-	/* Populate the LUT with max no. of queues in round robin fashion */
+-	for (i = 0; i < vsi->rss_table_size; i++)
+-		rss_lut[i] = i % vsi->rss_size;
++	int ret = 0;
+ 
+-	ret = i40e_aq_set_rss_key(hw, vsi->id, &rss_key);
+-	if (ret) {
+-		dev_info(&pf->pdev->dev,
+-			 "Cannot set RSS key, err %s aq_err %s\n",
+-			 i40e_stat_str(&pf->hw, ret),
+-			 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+-		goto config_rss_aq_out;
++	if (seed) {
++		struct i40e_aqc_get_set_rss_key_data *seed_dw =
++			(struct i40e_aqc_get_set_rss_key_data *)seed;
++		ret = i40e_aq_set_rss_key(hw, vsi->id, seed_dw);
++		if (ret) {
++			dev_info(&pf->pdev->dev,
++				 "Cannot set RSS key, err %s aq_err %s\n",
++				 i40e_stat_str(hw, ret),
++				 i40e_aq_str(hw, hw->aq.asq_last_status));
++			return ret;
++		}
+ 	}
++	if (lut) {
++		bool pf_lut = vsi->type == I40E_VSI_MAIN ? true : false;
+ 
+-	if (vsi->type == I40E_VSI_MAIN)
+-		pf_lut = true;
+-
+-	ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, rss_lut,
+-				  vsi->rss_table_size);
+-	if (ret)
+-		dev_info(&pf->pdev->dev,
+-			 "Cannot set RSS lut, err %s aq_err %s\n",
+-			 i40e_stat_str(&pf->hw, ret),
+-			 i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
+-
+-config_rss_aq_out:
+-	kfree(rss_lut);
++		ret = i40e_aq_set_rss_lut(hw, vsi->id, pf_lut, lut, lut_size);
++		if (ret) {
++			dev_info(&pf->pdev->dev,
++				 "Cannot set RSS lut, err %s aq_err %s\n",
++				 i40e_stat_str(hw, ret),
++				 i40e_aq_str(hw, hw->aq.asq_last_status));
++			return ret;
++		}
++	}
+ 	return ret;
+ }
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c b/drivers/net/wireless/ath/ath10k/htt_rx.c
+index 24c8d65bcf34..09ca63466504 100644
+--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
++++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
+@@ -2394,6 +2394,8 @@ static void ath10k_htt_txrx_compl_task(unsigned long ptr)
+ 	skb_queue_splice_init(&htt->rx_in_ord_compl_q, &rx_ind_q);
+ 	spin_unlock_irqrestore(&htt->rx_in_ord_compl_q.lock, flags);
+ 
++	ath10k_mac_tx_push_pending(ar);
++
+ 	spin_lock_irqsave(&htt->tx_fetch_ind_q.lock, flags);
+ 	skb_queue_splice_init(&htt->tx_fetch_ind_q, &tx_ind_q);
+ 	spin_unlock_irqrestore(&htt->tx_fetch_ind_q.lock, flags);
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 0bbd0a00edcc..146365b93ff5 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -3777,7 +3777,9 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
+ 	enum ath10k_hw_txrx_mode txmode;
+ 	enum ath10k_mac_tx_path txpath;
+ 	struct sk_buff *skb;
++	struct ieee80211_hdr *hdr;
+ 	size_t skb_len;
++	bool is_mgmt, is_presp;
+ 	int ret;
+ 
+ 	spin_lock_bh(&ar->htt.tx_lock);
+@@ -3801,6 +3803,22 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
+ 	skb_len = skb->len;
+ 	txmode = ath10k_mac_tx_h_get_txmode(ar, vif, sta, skb);
+ 	txpath = ath10k_mac_tx_h_get_txpath(ar, skb, txmode);
++	is_mgmt = (txpath == ATH10K_MAC_TX_HTT_MGMT);
++
++	if (is_mgmt) {
++		hdr = (struct ieee80211_hdr *)skb->data;
++		is_presp = ieee80211_is_probe_resp(hdr->frame_control);
++
++		spin_lock_bh(&ar->htt.tx_lock);
++		ret = ath10k_htt_tx_mgmt_inc_pending(htt, is_mgmt, is_presp);
++
++		if (ret) {
++			ath10k_htt_tx_dec_pending(htt);
++			spin_unlock_bh(&ar->htt.tx_lock);
++			return ret;
++		}
++		spin_unlock_bh(&ar->htt.tx_lock);
++	}
+ 
+ 	ret = ath10k_mac_tx(ar, vif, sta, txmode, txpath, skb);
+ 	if (unlikely(ret)) {
+@@ -3808,6 +3826,8 @@ int ath10k_mac_tx_push_txq(struct ieee80211_hw *hw,
+ 
+ 		spin_lock_bh(&ar->htt.tx_lock);
+ 		ath10k_htt_tx_dec_pending(htt);
++		if (is_mgmt)
++			ath10k_htt_tx_mgmt_dec_pending(htt);
+ 		spin_unlock_bh(&ar->htt.tx_lock);
+ 
+ 		return ret;
+@@ -6538,7 +6558,7 @@ static int ath10k_get_survey(struct ieee80211_hw *hw, int idx,
+ 		goto exit;
+ 	}
+ 
+-	ath10k_mac_update_bss_chan_survey(ar, survey->channel);
++	ath10k_mac_update_bss_chan_survey(ar, &sband->channels[idx]);
+ 
+ 	spin_lock_bh(&ar->data_lock);
+ 	memcpy(survey, ar_survey, sizeof(*survey));
+diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c
+index b29a86a26c13..28ff5cb4ec28 100644
+--- a/drivers/net/wireless/ath/ath10k/txrx.c
++++ b/drivers/net/wireless/ath/ath10k/txrx.c
+@@ -119,8 +119,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt,
+ 	ieee80211_tx_status(htt->ar->hw, msdu);
+ 	/* we do not own the msdu anymore */
+ 
+-	ath10k_mac_tx_push_pending(ar);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/wmi.h b/drivers/net/wireless/ath/ath10k/wmi.h
+index 3ef468893b3f..f67cc198bc0e 100644
+--- a/drivers/net/wireless/ath/ath10k/wmi.h
++++ b/drivers/net/wireless/ath/ath10k/wmi.h
+@@ -180,6 +180,7 @@ enum wmi_service {
+ 	WMI_SERVICE_MESH_NON_11S,
+ 	WMI_SERVICE_PEER_STATS,
+ 	WMI_SERVICE_RESTRT_CHNL_SUPPORT,
++	WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
+ 	WMI_SERVICE_TX_MODE_PUSH_ONLY,
+ 	WMI_SERVICE_TX_MODE_PUSH_PULL,
+ 	WMI_SERVICE_TX_MODE_DYNAMIC,
+@@ -305,6 +306,7 @@ enum wmi_10_4_service {
+ 	WMI_10_4_SERVICE_RESTRT_CHNL_SUPPORT,
+ 	WMI_10_4_SERVICE_PEER_STATS,
+ 	WMI_10_4_SERVICE_MESH_11S,
++	WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
+ 	WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
+ 	WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
+ 	WMI_10_4_SERVICE_TX_MODE_DYNAMIC,
+@@ -402,6 +404,7 @@ static inline char *wmi_service_name(int service_id)
+ 	SVCSTR(WMI_SERVICE_MESH_NON_11S);
+ 	SVCSTR(WMI_SERVICE_PEER_STATS);
+ 	SVCSTR(WMI_SERVICE_RESTRT_CHNL_SUPPORT);
++	SVCSTR(WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT);
+ 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_ONLY);
+ 	SVCSTR(WMI_SERVICE_TX_MODE_PUSH_PULL);
+ 	SVCSTR(WMI_SERVICE_TX_MODE_DYNAMIC);
+@@ -652,6 +655,8 @@ static inline void wmi_10_4_svc_map(const __le32 *in, unsigned long *out,
+ 	       WMI_SERVICE_PEER_STATS, len);
+ 	SVCMAP(WMI_10_4_SERVICE_MESH_11S,
+ 	       WMI_SERVICE_MESH_11S, len);
++	SVCMAP(WMI_10_4_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
++	       WMI_SERVICE_PERIODIC_CHAN_STAT_SUPPORT, len);
+ 	SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_ONLY,
+ 	       WMI_SERVICE_TX_MODE_PUSH_ONLY, len);
+ 	SVCMAP(WMI_10_4_SERVICE_TX_MODE_PUSH_PULL,
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+index 43f8f7d45ddb..adba3b003f55 100644
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
+@@ -564,11 +564,16 @@ static void iwl_set_hw_address_from_csr(struct iwl_trans *trans,
+ 	__le32 mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_STRAP));
+ 	__le32 mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_STRAP));
+ 
+-	/* If OEM did not fuse address - get it from OTP */
+-	if (!mac_addr0 && !mac_addr1) {
+-		mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
+-		mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
+-	}
++	iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
++	/*
++	 * If the OEM fused a valid address, use it instead of the one in the
++	 * OTP
++	 */
++	if (is_valid_ether_addr(data->hw_addr))
++		return;
++
++	mac_addr0 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR0_OTP));
++	mac_addr1 = cpu_to_le32(iwl_read32(trans, CSR_MAC_ADDR1_OTP));
+ 
+ 	iwl_flip_hw_address(mac_addr0, mac_addr1, data->hw_addr);
+ }
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+index 7e0cdbf8bf74..794c57486e02 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+@@ -1214,9 +1214,12 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
+ 	}
+ 
+ 	/* TODO: read the budget from BIOS / Platform NVM */
+-	if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0)
++	if (iwl_mvm_is_ctdp_supported(mvm) && mvm->cooling_dev.cur_state > 0) {
+ 		ret = iwl_mvm_ctdp_command(mvm, CTDP_CMD_OPERATION_START,
+ 					   mvm->cooling_dev.cur_state);
++		if (ret)
++			goto error;
++	}
+ #else
+ 	/* Initialize tx backoffs to the minimal possible */
+ 	iwl_mvm_tt_tx_backoff(mvm, 0);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+index 69c42ce45b8a..d742d27d8de0 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
+@@ -539,6 +539,11 @@ void iwl_mvm_mac_ctxt_release(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
+ 			iwl_mvm_disable_txq(mvm, IWL_MVM_OFFCHANNEL_QUEUE,
+ 					    IWL_MVM_OFFCHANNEL_QUEUE,
+ 					    IWL_MAX_TID_COUNT, 0);
++		else
++			iwl_mvm_disable_txq(mvm,
++					    IWL_MVM_DQA_P2P_DEVICE_QUEUE,
++					    vif->hw_queue[0], IWL_MAX_TID_COUNT,
++					    0);
+ 
+ 		break;
+ 	case NL80211_IFTYPE_AP:
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index df6c32caa5f0..afb7eb60e454 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -598,9 +598,10 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
+ 
+ 	mvm_sta = iwl_mvm_sta_from_mac80211(sta);
+ 
+-	/* not a data packet */
+-	if (!ieee80211_is_data_qos(hdr->frame_control) ||
+-	    is_multicast_ether_addr(hdr->addr1))
++	/* not a data packet or a bar */
++	if (!ieee80211_is_back_req(hdr->frame_control) &&
++	    (!ieee80211_is_data_qos(hdr->frame_control) ||
++	     is_multicast_ether_addr(hdr->addr1)))
+ 		return false;
+ 
+ 	if (unlikely(!ieee80211_is_data_present(hdr->frame_control)))
+@@ -624,6 +625,11 @@ static bool iwl_mvm_reorder(struct iwl_mvm *mvm,
+ 
+ 	spin_lock_bh(&buffer->lock);
+ 
++	if (ieee80211_is_back_req(hdr->frame_control)) {
++		iwl_mvm_release_frames(mvm, sta, napi, buffer, nssn);
++		goto drop;
++	}
++
+ 	/*
+ 	 * If there was a significant jump in the nssn - adjust.
+ 	 * If the SN is smaller than the NSSN it might need to first go into
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+index 3130b9c68a74..e933c12d80aa 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+@@ -576,9 +576,7 @@ static int iwl_mvm_scd_queue_redirect(struct iwl_mvm *mvm, int queue, int tid,
+ 			ret);
+ 
+ 	/* Make sure the SCD wrptr is correctly set before reconfiguring */
+-	iwl_trans_txq_enable(mvm->trans, queue, iwl_mvm_ac_to_tx_fifo[ac],
+-			     cmd.sta_id, tid, LINK_QUAL_AGG_FRAME_LIMIT_DEF,
+-			     ssn, wdg_timeout);
++	iwl_trans_txq_enable_cfg(mvm->trans, queue, ssn, NULL, wdg_timeout);
+ 
+ 	/* TODO: Work-around SCD bug when moving back by multiples of 0x40 */
+ 
+@@ -1270,9 +1268,31 @@ int iwl_mvm_rm_sta(struct iwl_mvm *mvm,
+ 		ret = iwl_mvm_drain_sta(mvm, mvm_sta, false);
+ 
+ 		/* If DQA is supported - the queues can be disabled now */
+-		if (iwl_mvm_is_dqa_supported(mvm))
++		if (iwl_mvm_is_dqa_supported(mvm)) {
++			u8 reserved_txq = mvm_sta->reserved_queue;
++			enum iwl_mvm_queue_status *status;
++
+ 			iwl_mvm_disable_sta_queues(mvm, vif, mvm_sta);
+ 
++			/*
++			 * If no traffic has gone through the reserved TXQ - it
++			 * is still marked as IWL_MVM_QUEUE_RESERVED, and
++			 * should be manually marked as free again
++			 */
++			spin_lock_bh(&mvm->queue_info_lock);
++			status = &mvm->queue_info[reserved_txq].status;
++			if (WARN((*status != IWL_MVM_QUEUE_RESERVED) &&
++				 (*status != IWL_MVM_QUEUE_FREE),
++				 "sta_id %d reserved txq %d status %d",
++				 mvm_sta->sta_id, reserved_txq, *status)) {
++				spin_unlock_bh(&mvm->queue_info_lock);
++				return -EINVAL;
++			}
++
++			*status = IWL_MVM_QUEUE_FREE;
++			spin_unlock_bh(&mvm->queue_info_lock);
++		}
++
+ 		if (vif->type == NL80211_IFTYPE_STATION &&
+ 		    mvmvif->ap_sta_id == mvm_sta->sta_id) {
+ 			/* if associated - we can't remove the AP STA now */
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+index b3a87a31de30..a0c1e3d07db5 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/tx.c
+@@ -903,9 +903,13 @@ static int iwl_mvm_tx_mpdu(struct iwl_mvm *mvm, struct sk_buff *skb,
+ 		tid = IWL_MAX_TID_COUNT;
+ 	}
+ 
+-	if (iwl_mvm_is_dqa_supported(mvm))
++	if (iwl_mvm_is_dqa_supported(mvm)) {
+ 		txq_id = mvmsta->tid_data[tid].txq_id;
+ 
++		if (ieee80211_is_mgmt(fc))
++			tx_cmd->tid_tspec = IWL_TID_NON_QOS;
++	}
++
+ 	/* Copy MAC header from skb into command buffer */
+ 	memcpy(tx_cmd->hdr, hdr, hdrlen);
+ 
+diff --git a/drivers/net/wireless/marvell/mwifiex/join.c b/drivers/net/wireless/marvell/mwifiex/join.c
+index 1c7b00630b90..b89596c18b41 100644
+--- a/drivers/net/wireless/marvell/mwifiex/join.c
++++ b/drivers/net/wireless/marvell/mwifiex/join.c
+@@ -669,9 +669,8 @@ int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
+ 	priv->assoc_rsp_size = min(le16_to_cpu(resp->size) - S_DS_GEN,
+ 				   sizeof(priv->assoc_rsp_buf));
+ 
+-	memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
+-
+ 	assoc_rsp->a_id = cpu_to_le16(aid);
++	memcpy(priv->assoc_rsp_buf, &resp->params, priv->assoc_rsp_size);
+ 
+ 	if (status_code) {
+ 		priv->adapter->dbg.num_cmd_assoc_failure++;
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+index a422f3306d4d..7e394d485f54 100644
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c
+@@ -708,7 +708,11 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
+ 
+ 	case EVENT_EXT_SCAN_REPORT:
+ 		mwifiex_dbg(adapter, EVENT, "event: EXT_SCAN Report\n");
+-		if (adapter->ext_scan && !priv->scan_aborting)
++		/* We intend to skip this event during suspend, but handle
++		 * it in interface disabled case
++		 */
++		if (adapter->ext_scan && (!priv->scan_aborting ||
++					  !netif_running(priv->netdev)))
+ 			ret = mwifiex_handle_event_ext_scan_report(priv,
+ 						adapter->event_skb->data);
+ 
+diff --git a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+index 7cf26c6124d1..6005e14213ca 100644
+--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c
+@@ -831,8 +831,10 @@ int rt2x00usb_probe(struct usb_interface *usb_intf,
+ 	rt2x00dev->anchor = devm_kmalloc(&usb_dev->dev,
+ 					sizeof(struct usb_anchor),
+ 					GFP_KERNEL);
+-	if (!rt2x00dev->anchor)
++	if (!rt2x00dev->anchor) {
++		retval = -ENOMEM;
+ 		goto exit_free_reg;
++	}
+ 
+ 	init_usb_anchor(rt2x00dev->anchor);
+ 	return 0;
+diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
+index 935866fe5ec2..a8b6949a8778 100644
+--- a/drivers/nvdimm/bus.c
++++ b/drivers/nvdimm/bus.c
+@@ -217,6 +217,8 @@ long nvdimm_clear_poison(struct device *dev, phys_addr_t phys,
+ 		return rc;
+ 	if (cmd_rc < 0)
+ 		return cmd_rc;
++
++	nvdimm_clear_from_poison_list(nvdimm_bus, phys, len);
+ 	return clear_err.cleared;
+ }
+ EXPORT_SYMBOL_GPL(nvdimm_clear_poison);
+diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
+index 4d7bbd2df5c0..7ceba08774b6 100644
+--- a/drivers/nvdimm/core.c
++++ b/drivers/nvdimm/core.c
+@@ -547,11 +547,12 @@ void nvdimm_badblocks_populate(struct nd_region *nd_region,
+ }
+ EXPORT_SYMBOL_GPL(nvdimm_badblocks_populate);
+ 
+-static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
++static int add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length,
++			gfp_t flags)
+ {
+ 	struct nd_poison *pl;
+ 
+-	pl = kzalloc(sizeof(*pl), GFP_KERNEL);
++	pl = kzalloc(sizeof(*pl), flags);
+ 	if (!pl)
+ 		return -ENOMEM;
+ 
+@@ -567,7 +568,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
+ 	struct nd_poison *pl;
+ 
+ 	if (list_empty(&nvdimm_bus->poison_list))
+-		return add_poison(nvdimm_bus, addr, length);
++		return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
+ 
+ 	/*
+ 	 * There is a chance this is a duplicate, check for those first.
+@@ -587,7 +588,7 @@ static int bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
+ 	 * as any overlapping ranges will get resolved when the list is consumed
+ 	 * and converted to badblocks
+ 	 */
+-	return add_poison(nvdimm_bus, addr, length);
++	return add_poison(nvdimm_bus, addr, length, GFP_KERNEL);
+ }
+ 
+ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
+@@ -602,6 +603,70 @@ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length)
+ }
+ EXPORT_SYMBOL_GPL(nvdimm_bus_add_poison);
+ 
++void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
++		phys_addr_t start, unsigned int len)
++{
++	struct list_head *poison_list = &nvdimm_bus->poison_list;
++	u64 clr_end = start + len - 1;
++	struct nd_poison *pl, *next;
++
++	nvdimm_bus_lock(&nvdimm_bus->dev);
++	WARN_ON_ONCE(list_empty(poison_list));
++
++	/*
++	 * [start, clr_end] is the poison interval being cleared.
++	 * [pl->start, pl_end] is the poison_list entry we're comparing
++	 * the above interval against. The poison list entry may need
++	 * to be modified (update either start or length), deleted, or
++	 * split into two based on the overlap characteristics
++	 */
++
++	list_for_each_entry_safe(pl, next, poison_list, list) {
++		u64 pl_end = pl->start + pl->length - 1;
++
++		/* Skip intervals with no intersection */
++		if (pl_end < start)
++			continue;
++		if (pl->start >  clr_end)
++			continue;
++		/* Delete completely overlapped poison entries */
++		if ((pl->start >= start) && (pl_end <= clr_end)) {
++			list_del(&pl->list);
++			kfree(pl);
++			continue;
++		}
++		/* Adjust start point of partially cleared entries */
++		if ((start <= pl->start) && (clr_end > pl->start)) {
++			pl->length -= clr_end - pl->start + 1;
++			pl->start = clr_end + 1;
++			continue;
++		}
++		/* Adjust pl->length for partial clearing at the tail end */
++		if ((pl->start < start) && (pl_end <= clr_end)) {
++			/* pl->start remains the same */
++			pl->length = start - pl->start;
++			continue;
++		}
++		/*
++		 * If clearing in the middle of an entry, we split it into
++		 * two by modifying the current entry to represent one half of
++		 * the split, and adding a new entry for the second half.
++		 */
++		if ((pl->start < start) && (pl_end > clr_end)) {
++			u64 new_start = clr_end + 1;
++			u64 new_len = pl_end - new_start + 1;
++
++			/* Add new entry covering the right half */
++			add_poison(nvdimm_bus, new_start, new_len, GFP_NOIO);
++			/* Adjust this entry to cover the left half */
++			pl->length = start - pl->start;
++			continue;
++		}
++	}
++	nvdimm_bus_unlock(&nvdimm_bus->dev);
++}
++EXPORT_SYMBOL_GPL(nvdimm_clear_from_poison_list);
++
+ #ifdef CONFIG_BLK_DEV_INTEGRITY
+ int nd_integrity_init(struct gendisk *disk, unsigned long meta_size)
+ {
+diff --git a/drivers/pci/host/pci-aardvark.c b/drivers/pci/host/pci-aardvark.c
+index ef9893fa3176..4f5e567fd7e0 100644
+--- a/drivers/pci/host/pci-aardvark.c
++++ b/drivers/pci/host/pci-aardvark.c
+@@ -848,7 +848,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
+ 	int err, res_valid = 0;
+ 	struct device *dev = &pcie->pdev->dev;
+ 	struct device_node *np = dev->of_node;
+-	struct resource_entry *win;
++	struct resource_entry *win, *tmp;
+ 	resource_size_t iobase;
+ 
+ 	INIT_LIST_HEAD(&pcie->resources);
+@@ -862,7 +862,7 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
+ 	if (err)
+ 		goto out_release_res;
+ 
+-	resource_list_for_each_entry(win, &pcie->resources) {
++	resource_list_for_each_entry_safe(win, tmp, &pcie->resources) {
+ 		struct resource *res = win->res;
+ 
+ 		switch (resource_type(res)) {
+@@ -874,9 +874,11 @@ static int advk_pcie_parse_request_of_pci_ranges(struct advk_pcie *pcie)
+ 					     lower_32_bits(res->start),
+ 					     OB_PCIE_IO);
+ 			err = pci_remap_iospace(res, iobase);
+-			if (err)
++			if (err) {
+ 				dev_warn(dev, "error %d: failed to map resource %pR\n",
+ 					 err, res);
++				resource_list_destroy_entry(win);
++			}
+ 			break;
+ 		case IORESOURCE_MEM:
+ 			advk_pcie_set_ob_win(pcie, 0,
+diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c
+index 9d9d34e959b6..61eb4d46eb50 100644
+--- a/drivers/pci/host/pci-host-common.c
++++ b/drivers/pci/host/pci-host-common.c
+@@ -29,7 +29,7 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
+ 	int err, res_valid = 0;
+ 	struct device_node *np = dev->of_node;
+ 	resource_size_t iobase;
+-	struct resource_entry *win;
++	struct resource_entry *win, *tmp;
+ 
+ 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, &iobase);
+ 	if (err)
+@@ -39,15 +39,17 @@ static int gen_pci_parse_request_of_pci_ranges(struct device *dev,
+ 	if (err)
+ 		return err;
+ 
+-	resource_list_for_each_entry(win, resources) {
++	resource_list_for_each_entry_safe(win, tmp, resources) {
+ 		struct resource *res = win->res;
+ 
+ 		switch (resource_type(res)) {
+ 		case IORESOURCE_IO:
+ 			err = pci_remap_iospace(res, iobase);
+-			if (err)
++			if (err) {
+ 				dev_warn(dev, "error %d: failed to map resource %pR\n",
+ 					 err, res);
++				resource_list_destroy_entry(win);
++			}
+ 			break;
+ 		case IORESOURCE_MEM:
+ 			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
+index 84d650d892e7..7ec1e800096a 100644
+--- a/drivers/pci/host/pci-tegra.c
++++ b/drivers/pci/host/pci-tegra.c
+@@ -621,7 +621,11 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
+ 	if (err < 0)
+ 		return err;
+ 
+-	pci_add_resource_offset(&sys->resources, &pcie->pio, sys->io_offset);
++	err = pci_remap_iospace(&pcie->pio, pcie->io.start);
++	if (!err)
++		pci_add_resource_offset(&sys->resources, &pcie->pio,
++					sys->io_offset);
++
+ 	pci_add_resource_offset(&sys->resources, &pcie->mem, sys->mem_offset);
+ 	pci_add_resource_offset(&sys->resources, &pcie->prefetch,
+ 				sys->mem_offset);
+@@ -631,7 +635,6 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
+ 	if (err < 0)
+ 		return err;
+ 
+-	pci_remap_iospace(&pcie->pio, pcie->io.start);
+ 	return 1;
+ }
+ 
+diff --git a/drivers/pci/host/pci-versatile.c b/drivers/pci/host/pci-versatile.c
+index f234405770ab..b7dc07002f13 100644
+--- a/drivers/pci/host/pci-versatile.c
++++ b/drivers/pci/host/pci-versatile.c
+@@ -74,7 +74,7 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
+ 	int err, mem = 1, res_valid = 0;
+ 	struct device_node *np = dev->of_node;
+ 	resource_size_t iobase;
+-	struct resource_entry *win;
++	struct resource_entry *win, *tmp;
+ 
+ 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, res, &iobase);
+ 	if (err)
+@@ -84,15 +84,17 @@ static int versatile_pci_parse_request_of_pci_ranges(struct device *dev,
+ 	if (err)
+ 		goto out_release_res;
+ 
+-	resource_list_for_each_entry(win, res) {
++	resource_list_for_each_entry_safe(win, tmp, res) {
+ 		struct resource *res = win->res;
+ 
+ 		switch (resource_type(res)) {
+ 		case IORESOURCE_IO:
+ 			err = pci_remap_iospace(res, iobase);
+-			if (err)
++			if (err) {
+ 				dev_warn(dev, "error %d: failed to map resource %pR\n",
+ 					 err, res);
++				resource_list_destroy_entry(win);
++			}
+ 			break;
+ 		case IORESOURCE_MEM:
+ 			res_valid |= !(res->flags & IORESOURCE_PREFETCH);
+diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
+index 12afce19890b..2a500f270c01 100644
+--- a/drivers/pci/host/pcie-designware.c
++++ b/drivers/pci/host/pcie-designware.c
+@@ -436,7 +436,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
+ 	struct resource *cfg_res;
+ 	int i, ret;
+ 	LIST_HEAD(res);
+-	struct resource_entry *win;
++	struct resource_entry *win, *tmp;
+ 
+ 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
+ 	if (cfg_res) {
+@@ -457,17 +457,20 @@ int dw_pcie_host_init(struct pcie_port *pp)
+ 		goto error;
+ 
+ 	/* Get the I/O and memory ranges from DT */
+-	resource_list_for_each_entry(win, &res) {
++	resource_list_for_each_entry_safe(win, tmp, &res) {
+ 		switch (resource_type(win->res)) {
+ 		case IORESOURCE_IO:
+-			pp->io = win->res;
+-			pp->io->name = "I/O";
+-			pp->io_size = resource_size(pp->io);
+-			pp->io_bus_addr = pp->io->start - win->offset;
+-			ret = pci_remap_iospace(pp->io, pp->io_base);
+-			if (ret)
++			ret = pci_remap_iospace(win->res, pp->io_base);
++			if (ret) {
+ 				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+-					 ret, pp->io);
++					 ret, win->res);
++				resource_list_destroy_entry(win);
++			} else {
++				pp->io = win->res;
++				pp->io->name = "I/O";
++				pp->io_size = resource_size(pp->io);
++				pp->io_bus_addr = pp->io->start - win->offset;
++			}
+ 			break;
+ 		case IORESOURCE_MEM:
+ 			pp->mem = win->res;
+diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
+index 65db7a221509..5f7fcc971cae 100644
+--- a/drivers/pci/host/pcie-rcar.c
++++ b/drivers/pci/host/pcie-rcar.c
+@@ -945,7 +945,7 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+ 	struct device *dev = pci->dev;
+ 	struct device_node *np = dev->of_node;
+ 	resource_size_t iobase;
+-	struct resource_entry *win;
++	struct resource_entry *win, *tmp;
+ 
+ 	err = of_pci_get_host_bridge_resources(np, 0, 0xff, &pci->resources, &iobase);
+ 	if (err)
+@@ -955,14 +955,17 @@ static int rcar_pcie_parse_request_of_pci_ranges(struct rcar_pcie *pci)
+ 	if (err)
+ 		goto out_release_res;
+ 
+-	resource_list_for_each_entry(win, &pci->resources) {
++	resource_list_for_each_entry_safe(win, tmp, &pci->resources) {
+ 		struct resource *res = win->res;
+ 
+ 		if (resource_type(res) == IORESOURCE_IO) {
+ 			err = pci_remap_iospace(res, iobase);
+-			if (err)
++			if (err) {
+ 				dev_warn(dev, "error %d: failed to map resource %pR\n",
+ 					 err, res);
++
++				resource_list_destroy_entry(win);
++			}
+ 		}
+ 	}
+ 
+diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c
+index 51c42d746883..775c88303017 100644
+--- a/drivers/pinctrl/qcom/pinctrl-msm.c
++++ b/drivers/pinctrl/qcom/pinctrl-msm.c
+@@ -156,7 +156,7 @@ static int msm_pinmux_set_mux(struct pinctrl_dev *pctldev,
+ 	spin_lock_irqsave(&pctrl->lock, flags);
+ 
+ 	val = readl(pctrl->regs + g->ctl_reg);
+-	val &= mask;
++	val &= ~mask;
+ 	val |= i << g->mux_bit;
+ 	writel(val, pctrl->regs + g->ctl_reg);
+ 
+diff --git a/drivers/power/bq24257_charger.c b/drivers/power/bq24257_charger.c
+index 1fea2c7ef97f..6fc31bdc639b 100644
+--- a/drivers/power/bq24257_charger.c
++++ b/drivers/power/bq24257_charger.c
+@@ -1068,6 +1068,12 @@ static int bq24257_probe(struct i2c_client *client,
+ 		return ret;
+ 	}
+ 
++	ret = bq24257_power_supply_init(bq);
++	if (ret < 0) {
++		dev_err(dev, "Failed to register power supply\n");
++		return ret;
++	}
++
+ 	ret = devm_request_threaded_irq(dev, client->irq, NULL,
+ 					bq24257_irq_handler_thread,
+ 					IRQF_TRIGGER_FALLING |
+@@ -1078,12 +1084,6 @@ static int bq24257_probe(struct i2c_client *client,
+ 		return ret;
+ 	}
+ 
+-	ret = bq24257_power_supply_init(bq);
+-	if (ret < 0) {
+-		dev_err(dev, "Failed to register power supply\n");
+-		return ret;
+-	}
+-
+ 	ret = sysfs_create_group(&bq->charger->dev.kobj, &bq24257_attr_group);
+ 	if (ret < 0) {
+ 		dev_err(dev, "Can't create sysfs entries\n");
+diff --git a/drivers/s390/char/con3270.c b/drivers/s390/char/con3270.c
+index 6b1577c73fe7..285b4006f44b 100644
+--- a/drivers/s390/char/con3270.c
++++ b/drivers/s390/char/con3270.c
+@@ -124,7 +124,12 @@ con3270_create_status(struct con3270 *cp)
+ static void
+ con3270_update_string(struct con3270 *cp, struct string *s, int nr)
+ {
+-	if (s->len >= cp->view.cols - 5)
++	if (s->len < 4) {
++		/* This indicates a bug, but printing a warning would
++		 * cause a deadlock. */
++		return;
++	}
++	if (s->string[s->len - 4] != TO_RA)
+ 		return;
+ 	raw3270_buffer_address(cp->view.dev, s->string + s->len - 3,
+ 			       cp->view.cols * (nr + 1));
+@@ -460,11 +465,11 @@ con3270_cline_end(struct con3270 *cp)
+ 		cp->cline->len + 4 : cp->view.cols;
+ 	s = con3270_alloc_string(cp, size);
+ 	memcpy(s->string, cp->cline->string, cp->cline->len);
+-	if (s->len < cp->view.cols - 5) {
++	if (cp->cline->len < cp->view.cols - 5) {
+ 		s->string[s->len - 4] = TO_RA;
+ 		s->string[s->len - 1] = 0;
+ 	} else {
+-		while (--size > cp->cline->len)
++		while (--size >= cp->cline->len)
+ 			s->string[size] = cp->view.ascebc[' '];
+ 	}
+ 	/* Replace cline with allocated line s and reset cline. */
+diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
+index 940e725bde1e..11674698b36d 100644
+--- a/drivers/s390/cio/chsc.c
++++ b/drivers/s390/cio/chsc.c
+@@ -95,12 +95,13 @@ struct chsc_ssd_area {
+ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
+ {
+ 	struct chsc_ssd_area *ssd_area;
++	unsigned long flags;
+ 	int ccode;
+ 	int ret;
+ 	int i;
+ 	int mask;
+ 
+-	spin_lock_irq(&chsc_page_lock);
++	spin_lock_irqsave(&chsc_page_lock, flags);
+ 	memset(chsc_page, 0, PAGE_SIZE);
+ 	ssd_area = chsc_page;
+ 	ssd_area->request.length = 0x0010;
+@@ -144,7 +145,7 @@ int chsc_get_ssd_info(struct subchannel_id schid, struct chsc_ssd_info *ssd)
+ 			ssd->fla[i] = ssd_area->fla[i];
+ 	}
+ out:
+-	spin_unlock_irq(&chsc_page_lock);
++	spin_unlock_irqrestore(&chsc_page_lock, flags);
+ 	return ret;
+ }
+ 
+@@ -832,9 +833,10 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
+ 		u32 fmt : 4;
+ 		u32 : 16;
+ 	} __attribute__ ((packed)) *secm_area;
++	unsigned long flags;
+ 	int ret, ccode;
+ 
+-	spin_lock_irq(&chsc_page_lock);
++	spin_lock_irqsave(&chsc_page_lock, flags);
+ 	memset(chsc_page, 0, PAGE_SIZE);
+ 	secm_area = chsc_page;
+ 	secm_area->request.length = 0x0050;
+@@ -864,7 +866,7 @@ int __chsc_do_secm(struct channel_subsystem *css, int enable)
+ 		CIO_CRW_EVENT(2, "chsc: secm failed (rc=%04x)\n",
+ 			      secm_area->response.code);
+ out:
+-	spin_unlock_irq(&chsc_page_lock);
++	spin_unlock_irqrestore(&chsc_page_lock, flags);
+ 	return ret;
+ }
+ 
+@@ -992,6 +994,7 @@ chsc_initialize_cmg_chars(struct channel_path *chp, u8 cmcv,
+ 
+ int chsc_get_channel_measurement_chars(struct channel_path *chp)
+ {
++	unsigned long flags;
+ 	int ccode, ret;
+ 
+ 	struct {
+@@ -1021,7 +1024,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
+ 	if (!css_chsc_characteristics.scmc || !css_chsc_characteristics.secm)
+ 		return -EINVAL;
+ 
+-	spin_lock_irq(&chsc_page_lock);
++	spin_lock_irqsave(&chsc_page_lock, flags);
+ 	memset(chsc_page, 0, PAGE_SIZE);
+ 	scmc_area = chsc_page;
+ 	scmc_area->request.length = 0x0010;
+@@ -1053,7 +1056,7 @@ int chsc_get_channel_measurement_chars(struct channel_path *chp)
+ 	chsc_initialize_cmg_chars(chp, scmc_area->cmcv,
+ 				  (struct cmg_chars *) &scmc_area->data);
+ out:
+-	spin_unlock_irq(&chsc_page_lock);
++	spin_unlock_irqrestore(&chsc_page_lock, flags);
+ 	return ret;
+ }
+ 
+@@ -1134,6 +1137,7 @@ struct css_chsc_char css_chsc_characteristics;
+ int __init
+ chsc_determine_css_characteristics(void)
+ {
++	unsigned long flags;
+ 	int result;
+ 	struct {
+ 		struct chsc_header request;
+@@ -1146,7 +1150,7 @@ chsc_determine_css_characteristics(void)
+ 		u32 chsc_char[508];
+ 	} __attribute__ ((packed)) *scsc_area;
+ 
+-	spin_lock_irq(&chsc_page_lock);
++	spin_lock_irqsave(&chsc_page_lock, flags);
+ 	memset(chsc_page, 0, PAGE_SIZE);
+ 	scsc_area = chsc_page;
+ 	scsc_area->request.length = 0x0010;
+@@ -1168,7 +1172,7 @@ chsc_determine_css_characteristics(void)
+ 		CIO_CRW_EVENT(2, "chsc: scsc failed (rc=%04x)\n",
+ 			      scsc_area->response.code);
+ exit:
+-	spin_unlock_irq(&chsc_page_lock);
++	spin_unlock_irqrestore(&chsc_page_lock, flags);
+ 	return result;
+ }
+ 
+diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c
+index 661bb94e2548..228b99ee0483 100644
+--- a/drivers/scsi/cxlflash/main.c
++++ b/drivers/scsi/cxlflash/main.c
+@@ -823,17 +823,6 @@ static void notify_shutdown(struct cxlflash_cfg *cfg, bool wait)
+ }
+ 
+ /**
+- * cxlflash_shutdown() - shutdown handler
+- * @pdev:	PCI device associated with the host.
+- */
+-static void cxlflash_shutdown(struct pci_dev *pdev)
+-{
+-	struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+-
+-	notify_shutdown(cfg, false);
+-}
+-
+-/**
+  * cxlflash_remove() - PCI entry point to tear down host
+  * @pdev:	PCI device associated with the host.
+  *
+@@ -844,6 +833,11 @@ static void cxlflash_remove(struct pci_dev *pdev)
+ 	struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
+ 	ulong lock_flags;
+ 
++	if (!pci_is_enabled(pdev)) {
++		pr_debug("%s: Device is disabled\n", __func__);
++		return;
++	}
++
+ 	/* If a Task Management Function is active, wait for it to complete
+ 	 * before continuing with remove.
+ 	 */
+@@ -2685,7 +2679,7 @@ static struct pci_driver cxlflash_driver = {
+ 	.id_table = cxlflash_pci_table,
+ 	.probe = cxlflash_probe,
+ 	.remove = cxlflash_remove,
+-	.shutdown = cxlflash_shutdown,
++	.shutdown = cxlflash_remove,
+ 	.err_handler = &cxlflash_err_handler,
+ };
+ 
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index cd91a684c945..4cb79902e7a8 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -4701,7 +4701,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
+ 			    le16_to_cpu(mpi_reply->DevHandle));
+ 		mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq);
+ 
+-		if (!(ioc->logging_level & MPT_DEBUG_REPLY) &&
++		if ((ioc->logging_level & MPT_DEBUG_REPLY) &&
+ 		     ((scmd->sense_buffer[2] == UNIT_ATTENTION) ||
+ 		     (scmd->sense_buffer[2] == MEDIUM_ERROR) ||
+ 		     (scmd->sense_buffer[2] == HARDWARE_ERROR)))
+diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
+index 9e9dadb52b3d..eec5e3f6e06b 100644
+--- a/drivers/spi/spi-fsl-dspi.c
++++ b/drivers/spi/spi-fsl-dspi.c
+@@ -760,7 +760,6 @@ static int dspi_remove(struct platform_device *pdev)
+ 	/* Disconnect from the SPI framework */
+ 	clk_disable_unprepare(dspi->clk);
+ 	spi_unregister_master(dspi->master);
+-	spi_master_put(dspi->master);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/staging/android/ion/Kconfig b/drivers/staging/android/ion/Kconfig
+index 19c1572f1525..800245eac390 100644
+--- a/drivers/staging/android/ion/Kconfig
++++ b/drivers/staging/android/ion/Kconfig
+@@ -36,6 +36,7 @@ config ION_TEGRA
+ config ION_HISI
+ 	tristate "Ion for Hisilicon"
+ 	depends on ARCH_HISI && ION
++	select ION_OF
+ 	help
+ 	  Choose this option if you wish to use ion on Hisilicon Platform.
+ 
+diff --git a/drivers/staging/ks7010/ks_hostif.c b/drivers/staging/ks7010/ks_hostif.c
+index a8822fe2bd60..f4cee811cabd 100644
+--- a/drivers/staging/ks7010/ks_hostif.c
++++ b/drivers/staging/ks7010/ks_hostif.c
+@@ -69,16 +69,20 @@ inline u32 get_DWORD(struct ks_wlan_private *priv)
+ 	return data;
+ }
+ 
+-void ks_wlan_hw_wakeup_task(struct work_struct *work)
++static void ks_wlan_hw_wakeup_task(struct work_struct *work)
+ {
+ 	struct ks_wlan_private *priv =
+ 	    container_of(work, struct ks_wlan_private, ks_wlan_wakeup_task);
+ 	int ps_status = atomic_read(&priv->psstatus.status);
++	long time_left;
+ 
+ 	if (ps_status == PS_SNOOZE) {
+ 		ks_wlan_hw_wakeup_request(priv);
+-		if (!wait_for_completion_interruptible_timeout(&priv->psstatus.wakeup_wait, HZ / 50)) {	/* 20ms timeout */
+-			DPRINTK(1, "wake up timeout !!!\n");
++		time_left = wait_for_completion_interruptible_timeout(
++				&priv->psstatus.wakeup_wait,
++				msecs_to_jiffies(20));
++		if (time_left <= 0) {
++			DPRINTK(1, "wake up timeout or interrupted !!!\n");
+ 			schedule_work(&priv->ks_wlan_wakeup_task);
+ 			return;
+ 		}
+@@ -1505,7 +1509,7 @@ void hostif_infrastructure_set_request(struct ks_wlan_private *priv)
+ 	ks_wlan_hw_tx(priv, pp, hif_align_size(sizeof(*pp)), NULL, NULL, NULL);
+ }
+ 
+-void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
++static void hostif_infrastructure_set2_request(struct ks_wlan_private *priv)
+ {
+ 	struct hostif_infrastructure_set2_request_t *pp;
+ 	uint16_t capability;
+diff --git a/drivers/staging/rtl8188eu/core/rtw_cmd.c b/drivers/staging/rtl8188eu/core/rtw_cmd.c
+index 77485235c615..32d3a9c07aa3 100644
+--- a/drivers/staging/rtl8188eu/core/rtw_cmd.c
++++ b/drivers/staging/rtl8188eu/core/rtw_cmd.c
+@@ -670,13 +670,13 @@ u8 rtw_addbareq_cmd(struct adapter *padapter, u8 tid, u8 *addr)
+ 	u8	res = _SUCCESS;
+ 
+ 
+-	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_KERNEL);
++	ph2c = kzalloc(sizeof(struct cmd_obj), GFP_ATOMIC);
+ 	if (!ph2c) {
+ 		res = _FAIL;
+ 		goto exit;
+ 	}
+ 
+-	paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_KERNEL);
++	paddbareq_parm = kzalloc(sizeof(struct addBaReq_parm), GFP_ATOMIC);
+ 	if (!paddbareq_parm) {
+ 		kfree(ph2c);
+ 		res = _FAIL;
+diff --git a/drivers/staging/sm750fb/ddk750_mode.c b/drivers/staging/sm750fb/ddk750_mode.c
+index ccb4e067661a..e29d4bd5dcec 100644
+--- a/drivers/staging/sm750fb/ddk750_mode.c
++++ b/drivers/staging/sm750fb/ddk750_mode.c
+@@ -63,7 +63,7 @@ static unsigned long displayControlAdjust_SM750LE(mode_parameter_t *pModeParam,
+ 	dispControl |= (CRT_DISPLAY_CTRL_CRTSELECT | CRT_DISPLAY_CTRL_RGBBIT);
+ 
+ 	/* Set bit 14 of display controller */
+-	dispControl = DISPLAY_CTRL_CLOCK_PHASE;
++	dispControl |= DISPLAY_CTRL_CLOCK_PHASE;
+ 
+ 	POKE32(CRT_DISPLAY_CTRL, dispControl);
+ 
+diff --git a/drivers/uio/uio_dmem_genirq.c b/drivers/uio/uio_dmem_genirq.c
+index 915facbf552e..e1134a4d97f3 100644
+--- a/drivers/uio/uio_dmem_genirq.c
++++ b/drivers/uio/uio_dmem_genirq.c
+@@ -229,7 +229,7 @@ static int uio_dmem_genirq_probe(struct platform_device *pdev)
+ 		++uiomem;
+ 	}
+ 
+-	priv->dmem_region_start = i;
++	priv->dmem_region_start = uiomem - &uioinfo->mem[0];
+ 	priv->num_dmem_regions = pdata->num_dynamic_regions;
+ 
+ 	for (i = 0; i < pdata->num_dynamic_regions; ++i) {
+diff --git a/fs/9p/acl.c b/fs/9p/acl.c
+index 5b6a1743ea17..b3c2cc79c20d 100644
+--- a/fs/9p/acl.c
++++ b/fs/9p/acl.c
+@@ -276,32 +276,26 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
+ 	switch (handler->flags) {
+ 	case ACL_TYPE_ACCESS:
+ 		if (acl) {
+-			umode_t mode = inode->i_mode;
+-			retval = posix_acl_equiv_mode(acl, &mode);
+-			if (retval < 0)
++			struct iattr iattr;
++
++			retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
++			if (retval)
+ 				goto err_out;
+-			else {
+-				struct iattr iattr;
+-				if (retval == 0) {
+-					/*
+-					 * ACL can be represented
+-					 * by the mode bits. So don't
+-					 * update ACL.
+-					 */
+-					acl = NULL;
+-					value = NULL;
+-					size = 0;
+-				}
+-				/* Updte the mode bits */
+-				iattr.ia_mode = ((mode & S_IALLUGO) |
+-						 (inode->i_mode & ~S_IALLUGO));
+-				iattr.ia_valid = ATTR_MODE;
+-				/* FIXME should we update ctime ?
+-				 * What is the following setxattr update the
+-				 * mode ?
++			if (!acl) {
++				/*
++				 * ACL can be represented
++				 * by the mode bits. So don't
++				 * update ACL.
+ 				 */
+-				v9fs_vfs_setattr_dotl(dentry, &iattr);
++				value = NULL;
++				size = 0;
+ 			}
++			iattr.ia_valid = ATTR_MODE;
++			/* FIXME should we update ctime ?
++			 * What is the following setxattr update the
++			 * mode ?
++			 */
++			v9fs_vfs_setattr_dotl(dentry, &iattr);
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
+index 53bb7af4e5f0..247b8dfaf6e5 100644
+--- a/fs/btrfs/acl.c
++++ b/fs/btrfs/acl.c
+@@ -79,11 +79,9 @@ static int __btrfs_set_acl(struct btrfs_trans_handle *trans,
+ 	case ACL_TYPE_ACCESS:
+ 		name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			ret = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (ret < 0)
++			ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (ret)
+ 				return ret;
+-			if (ret == 0)
+-				acl = NULL;
+ 		}
+ 		ret = 0;
+ 		break;
+diff --git a/fs/ceph/acl.c b/fs/ceph/acl.c
+index 4f67227f69a5..d0b6b342dff9 100644
+--- a/fs/ceph/acl.c
++++ b/fs/ceph/acl.c
+@@ -95,11 +95,9 @@ int ceph_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 	case ACL_TYPE_ACCESS:
+ 		name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			ret = posix_acl_equiv_mode(acl, &new_mode);
+-			if (ret < 0)
++			ret = posix_acl_update_mode(inode, &new_mode, &acl);
++			if (ret)
+ 				goto out;
+-			if (ret == 0)
+-				acl = NULL;
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
+index 42f1d1814083..e725aa0890e0 100644
+--- a/fs/ext2/acl.c
++++ b/fs/ext2/acl.c
+@@ -190,15 +190,11 @@ ext2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 		case ACL_TYPE_ACCESS:
+ 			name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
+ 			if (acl) {
+-				error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-				if (error < 0)
++				error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++				if (error)
+ 					return error;
+-				else {
+-					inode->i_ctime = CURRENT_TIME_SEC;
+-					mark_inode_dirty(inode);
+-					if (error == 0)
+-						acl = NULL;
+-				}
++				inode->i_ctime = CURRENT_TIME_SEC;
++				mark_inode_dirty(inode);
+ 			}
+ 			break;
+ 
+diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
+index c6601a476c02..dfa519979038 100644
+--- a/fs/ext4/acl.c
++++ b/fs/ext4/acl.c
+@@ -193,15 +193,11 @@ __ext4_set_acl(handle_t *handle, struct inode *inode, int type,
+ 	case ACL_TYPE_ACCESS:
+ 		name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (error < 0)
++			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (error)
+ 				return error;
+-			else {
+-				inode->i_ctime = ext4_current_time(inode);
+-				ext4_mark_inode_dirty(handle, inode);
+-				if (error == 0)
+-					acl = NULL;
+-			}
++			inode->i_ctime = ext4_current_time(inode);
++			ext4_mark_inode_dirty(handle, inode);
+ 		}
+ 		break;
+ 
+diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
+index 4dcc9e28dc5c..31344247ce89 100644
+--- a/fs/f2fs/acl.c
++++ b/fs/f2fs/acl.c
+@@ -210,12 +210,10 @@ static int __f2fs_set_acl(struct inode *inode, int type,
+ 	case ACL_TYPE_ACCESS:
+ 		name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (error < 0)
++			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (error)
+ 				return error;
+ 			set_acl_inode(inode, inode->i_mode);
+-			if (error == 0)
+-				acl = NULL;
+ 		}
+ 		break;
+ 
+diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
+index 363ba9e9d8d0..2524807ee070 100644
+--- a/fs/gfs2/acl.c
++++ b/fs/gfs2/acl.c
+@@ -92,17 +92,11 @@ int __gfs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 	if (type == ACL_TYPE_ACCESS) {
+ 		umode_t mode = inode->i_mode;
+ 
+-		error = posix_acl_equiv_mode(acl, &mode);
+-		if (error < 0)
++		error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++		if (error)
+ 			return error;
+-
+-		if (error == 0)
+-			acl = NULL;
+-
+-		if (mode != inode->i_mode) {
+-			inode->i_mode = mode;
++		if (mode != inode->i_mode)
+ 			mark_inode_dirty(inode);
+-		}
+ 	}
+ 
+ 	if (acl) {
+diff --git a/fs/hfsplus/posix_acl.c b/fs/hfsplus/posix_acl.c
+index ab7ea2506b4d..9b92058a1240 100644
+--- a/fs/hfsplus/posix_acl.c
++++ b/fs/hfsplus/posix_acl.c
+@@ -65,8 +65,8 @@ int hfsplus_set_posix_acl(struct inode *inode, struct posix_acl *acl,
+ 	case ACL_TYPE_ACCESS:
+ 		xattr_name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			err = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (err < 0)
++			err = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (err)
+ 				return err;
+ 		}
+ 		err = 0;
+diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
+index bc2693d56298..2a0f2a1044c1 100644
+--- a/fs/jffs2/acl.c
++++ b/fs/jffs2/acl.c
+@@ -233,9 +233,10 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 	case ACL_TYPE_ACCESS:
+ 		xprefix = JFFS2_XPREFIX_ACL_ACCESS;
+ 		if (acl) {
+-			umode_t mode = inode->i_mode;
+-			rc = posix_acl_equiv_mode(acl, &mode);
+-			if (rc < 0)
++			umode_t mode;
++
++			rc = posix_acl_update_mode(inode, &mode, &acl);
++			if (rc)
+ 				return rc;
+ 			if (inode->i_mode != mode) {
+ 				struct iattr attr;
+@@ -247,8 +248,6 @@ int jffs2_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 				if (rc < 0)
+ 					return rc;
+ 			}
+-			if (rc == 0)
+-				acl = NULL;
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/jfs/acl.c b/fs/jfs/acl.c
+index 21fa92ba2c19..3a1e1554a4e3 100644
+--- a/fs/jfs/acl.c
++++ b/fs/jfs/acl.c
+@@ -78,13 +78,11 @@ static int __jfs_set_acl(tid_t tid, struct inode *inode, int type,
+ 	case ACL_TYPE_ACCESS:
+ 		ea_name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			rc = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (rc < 0)
++			rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (rc)
+ 				return rc;
+ 			inode->i_ctime = CURRENT_TIME;
+ 			mark_inode_dirty(inode);
+-			if (rc == 0)
+-				acl = NULL;
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
+index 2162434728c0..164307b99405 100644
+--- a/fs/ocfs2/acl.c
++++ b/fs/ocfs2/acl.c
+@@ -241,13 +241,11 @@ int ocfs2_set_acl(handle_t *handle,
+ 	case ACL_TYPE_ACCESS:
+ 		name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			umode_t mode = inode->i_mode;
+-			ret = posix_acl_equiv_mode(acl, &mode);
+-			if (ret < 0)
+-				return ret;
++			umode_t mode;
+ 
+-			if (ret == 0)
+-				acl = NULL;
++			ret = posix_acl_update_mode(inode, &mode, &acl);
++			if (ret)
++				return ret;
+ 
+ 			ret = ocfs2_acl_set_mode(inode, di_bh,
+ 						 handle, mode);
+diff --git a/fs/orangefs/acl.c b/fs/orangefs/acl.c
+index 28f2195cd798..7a3754488312 100644
+--- a/fs/orangefs/acl.c
++++ b/fs/orangefs/acl.c
+@@ -73,14 +73,11 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 	case ACL_TYPE_ACCESS:
+ 		name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			umode_t mode = inode->i_mode;
+-			/*
+-			 * can we represent this with the traditional file
+-			 * mode permission bits?
+-			 */
+-			error = posix_acl_equiv_mode(acl, &mode);
+-			if (error < 0) {
+-				gossip_err("%s: posix_acl_equiv_mode err: %d\n",
++			umode_t mode;
++
++			error = posix_acl_update_mode(inode, &mode, &acl);
++			if (error) {
++				gossip_err("%s: posix_acl_update_mode err: %d\n",
+ 					   __func__,
+ 					   error);
+ 				return error;
+@@ -90,8 +87,6 @@ int orangefs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 				SetModeFlag(orangefs_inode);
+ 			inode->i_mode = mode;
+ 			mark_inode_dirty_sync(inode);
+-			if (error == 0)
+-				acl = NULL;
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/posix_acl.c b/fs/posix_acl.c
+index 59d47ab0791a..bfc3ec388322 100644
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -626,6 +626,37 @@ no_mem:
+ }
+ EXPORT_SYMBOL_GPL(posix_acl_create);
+ 
++/**
++ * posix_acl_update_mode  -  update mode in set_acl
++ *
++ * Update the file mode when setting an ACL: compute the new file permission
++ * bits based on the ACL.  In addition, if the ACL is equivalent to the new
++ * file mode, set *acl to NULL to indicate that no ACL should be set.
++ *
++ * As with chmod, clear the setgit bit if the caller is not in the owning group
++ * or capable of CAP_FSETID (see inode_change_ok).
++ *
++ * Called from set_acl inode operations.
++ */
++int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
++			  struct posix_acl **acl)
++{
++	umode_t mode = inode->i_mode;
++	int error;
++
++	error = posix_acl_equiv_mode(*acl, &mode);
++	if (error < 0)
++		return error;
++	if (error == 0)
++		*acl = NULL;
++	if (!in_group_p(inode->i_gid) &&
++	    !capable_wrt_inode_uidgid(inode, CAP_FSETID))
++		mode &= ~S_ISGID;
++	*mode_p = mode;
++	return 0;
++}
++EXPORT_SYMBOL(posix_acl_update_mode);
++
+ /*
+  * Fix up the uids and gids in posix acl extended attributes in place.
+  */
+diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
+index dbed42f755e0..27376681c640 100644
+--- a/fs/reiserfs/xattr_acl.c
++++ b/fs/reiserfs/xattr_acl.c
+@@ -242,13 +242,9 @@ __reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
+ 	case ACL_TYPE_ACCESS:
+ 		name = XATTR_NAME_POSIX_ACL_ACCESS;
+ 		if (acl) {
+-			error = posix_acl_equiv_mode(acl, &inode->i_mode);
+-			if (error < 0)
++			error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
++			if (error)
+ 				return error;
+-			else {
+-				if (error == 0)
+-					acl = NULL;
+-			}
+ 		}
+ 		break;
+ 	case ACL_TYPE_DEFAULT:
+diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
+index b6e527b8eccb..8a0dec89ca56 100644
+--- a/fs/xfs/xfs_acl.c
++++ b/fs/xfs/xfs_acl.c
+@@ -257,16 +257,11 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
+ 		return error;
+ 
+ 	if (type == ACL_TYPE_ACCESS) {
+-		umode_t mode = inode->i_mode;
+-		error = posix_acl_equiv_mode(acl, &mode);
+-
+-		if (error <= 0) {
+-			acl = NULL;
+-
+-			if (error < 0)
+-				return error;
+-		}
++		umode_t mode;
+ 
++		error = posix_acl_update_mode(inode, &mode, &acl);
++		if (error)
++			return error;
+ 		error = xfs_set_mode(inode, mode);
+ 		if (error)
+ 			return error;
+diff --git a/include/drm/drmP.h b/include/drm/drmP.h
+index d3778652e462..988903a59007 100644
+--- a/include/drm/drmP.h
++++ b/include/drm/drmP.h
+@@ -938,7 +938,8 @@ static inline int drm_debugfs_remove_files(const struct drm_info_list *files,
+ #endif
+ 
+ extern struct dma_buf *drm_gem_prime_export(struct drm_device *dev,
+-		struct drm_gem_object *obj, int flags);
++					    struct drm_gem_object *obj,
++					    int flags);
+ extern int drm_gem_prime_handle_to_fd(struct drm_device *dev,
+ 		struct drm_file *file_priv, uint32_t handle, uint32_t flags,
+ 		int *prime_fd);
+diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
+index c26d4638f665..fe99e6f956e2 100644
+--- a/include/linux/hugetlb.h
++++ b/include/linux/hugetlb.h
+@@ -450,8 +450,8 @@ static inline pgoff_t basepage_index(struct page *page)
+ 	return __basepage_index(page);
+ }
+ 
+-extern void dissolve_free_huge_pages(unsigned long start_pfn,
+-				     unsigned long end_pfn);
++extern int dissolve_free_huge_pages(unsigned long start_pfn,
++				    unsigned long end_pfn);
+ static inline bool hugepage_migration_supported(struct hstate *h)
+ {
+ #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION
+@@ -518,7 +518,7 @@ static inline pgoff_t basepage_index(struct page *page)
+ {
+ 	return page->index;
+ }
+-#define dissolve_free_huge_pages(s, e)	do {} while (0)
++#define dissolve_free_huge_pages(s, e)	0
+ #define hugepage_migration_supported(h)	false
+ 
+ static inline spinlock_t *huge_pte_lockptr(struct hstate *h,
+diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
+index b519e137b9b7..bbfce62a0bd7 100644
+--- a/include/linux/libnvdimm.h
++++ b/include/linux/libnvdimm.h
+@@ -129,6 +129,8 @@ static inline struct nd_blk_region_desc *to_blk_region_desc(
+ }
+ 
+ int nvdimm_bus_add_poison(struct nvdimm_bus *nvdimm_bus, u64 addr, u64 length);
++void nvdimm_clear_from_poison_list(struct nvdimm_bus *nvdimm_bus,
++		phys_addr_t start, unsigned int len);
+ struct nvdimm_bus *nvdimm_bus_register(struct device *parent,
+ 		struct nvdimm_bus_descriptor *nfit_desc);
+ void nvdimm_bus_unregister(struct nvdimm_bus *nvdimm_bus);
+diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
+index d5d3d741f028..bf1046d0397b 100644
+--- a/include/linux/posix_acl.h
++++ b/include/linux/posix_acl.h
+@@ -93,6 +93,7 @@ extern int set_posix_acl(struct inode *, int, struct posix_acl *);
+ extern int posix_acl_chmod(struct inode *, umode_t);
+ extern int posix_acl_create(struct inode *, umode_t *, struct posix_acl **,
+ 		struct posix_acl **);
++extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
+ 
+ extern int simple_set_acl(struct inode *, struct posix_acl *, int);
+ extern int simple_acl_create(struct inode *, struct inode *);
+diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
+index abd286afbd27..a4775f3451b9 100644
+--- a/kernel/irq/generic-chip.c
++++ b/kernel/irq/generic-chip.c
+@@ -411,8 +411,29 @@ int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
+ }
+ EXPORT_SYMBOL_GPL(irq_map_generic_chip);
+ 
++static void irq_unmap_generic_chip(struct irq_domain *d, unsigned int virq)
++{
++	struct irq_data *data = irq_domain_get_irq_data(d, virq);
++	struct irq_domain_chip_generic *dgc = d->gc;
++	unsigned int hw_irq = data->hwirq;
++	struct irq_chip_generic *gc;
++	int irq_idx;
++
++	gc = irq_get_domain_generic_chip(d, hw_irq);
++	if (!gc)
++		return;
++
++	irq_idx = hw_irq % dgc->irqs_per_chip;
++
++	clear_bit(irq_idx, &gc->installed);
++	irq_domain_set_info(d, virq, hw_irq, &no_irq_chip, NULL, NULL, NULL,
++			    NULL);
++
++}
++
+ struct irq_domain_ops irq_generic_chip_ops = {
+ 	.map	= irq_map_generic_chip,
++	.unmap  = irq_unmap_generic_chip,
+ 	.xlate	= irq_domain_xlate_onetwocell,
+ };
+ EXPORT_SYMBOL_GPL(irq_generic_chip_ops);
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 603bdd01ec2c..770d83eb3f48 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1437,22 +1437,32 @@ static int free_pool_huge_page(struct hstate *h, nodemask_t *nodes_allowed,
+ 
+ /*
+  * Dissolve a given free hugepage into free buddy pages. This function does
+- * nothing for in-use (including surplus) hugepages.
++ * nothing for in-use (including surplus) hugepages. Returns -EBUSY if the
++ * number of free hugepages would be reduced below the number of reserved
++ * hugepages.
+  */
+-static void dissolve_free_huge_page(struct page *page)
++static int dissolve_free_huge_page(struct page *page)
+ {
++	int rc = 0;
++
+ 	spin_lock(&hugetlb_lock);
+ 	if (PageHuge(page) && !page_count(page)) {
+ 		struct page *head = compound_head(page);
+ 		struct hstate *h = page_hstate(head);
+ 		int nid = page_to_nid(head);
++		if (h->free_huge_pages - h->resv_huge_pages == 0) {
++			rc = -EBUSY;
++			goto out;
++		}
+ 		list_del(&head->lru);
+ 		h->free_huge_pages--;
+ 		h->free_huge_pages_node[nid]--;
+ 		h->max_huge_pages--;
+ 		update_and_free_page(h, head);
+ 	}
++out:
+ 	spin_unlock(&hugetlb_lock);
++	return rc;
+ }
+ 
+ /*
+@@ -1460,16 +1470,28 @@ static void dissolve_free_huge_page(struct page *page)
+  * make specified memory blocks removable from the system.
+  * Note that this will dissolve a free gigantic hugepage completely, if any
+  * part of it lies within the given range.
++ * Also note that if dissolve_free_huge_page() returns with an error, all
++ * free hugepages that were dissolved before that error are lost.
+  */
+-void dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
++int dissolve_free_huge_pages(unsigned long start_pfn, unsigned long end_pfn)
+ {
+ 	unsigned long pfn;
++	struct page *page;
++	int rc = 0;
+ 
+ 	if (!hugepages_supported())
+-		return;
++		return rc;
++
++	for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order) {
++		page = pfn_to_page(pfn);
++		if (PageHuge(page) && !page_count(page)) {
++			rc = dissolve_free_huge_page(page);
++			if (rc)
++				break;
++		}
++	}
+ 
+-	for (pfn = start_pfn; pfn < end_pfn; pfn += 1 << minimum_order)
+-		dissolve_free_huge_page(pfn_to_page(pfn));
++	return rc;
+ }
+ 
+ /*
+diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
+index 9d29ba0f7192..962927309b6e 100644
+--- a/mm/memory_hotplug.c
++++ b/mm/memory_hotplug.c
+@@ -1945,7 +1945,9 @@ repeat:
+ 	 * dissolve free hugepages in the memory block before doing offlining
+ 	 * actually in order to make hugetlbfs's object counting consistent.
+ 	 */
+-	dissolve_free_huge_pages(start_pfn, end_pfn);
++	ret = dissolve_free_huge_pages(start_pfn, end_pfn);
++	if (ret)
++		goto failed_removal;
+ 	/* check again */
+ 	offlined_pages = check_pages_isolated(start_pfn, end_pfn);
+ 	if (offlined_pages < 0) {
+diff --git a/sound/soc/intel/boards/bxt_da7219_max98357a.c b/sound/soc/intel/boards/bxt_da7219_max98357a.c
+index 3774b117d365..49b65d481949 100644
+--- a/sound/soc/intel/boards/bxt_da7219_max98357a.c
++++ b/sound/soc/intel/boards/bxt_da7219_max98357a.c
+@@ -255,7 +255,7 @@ static struct snd_soc_ops broxton_da7219_ops = {
+ /* broxton digital audio interface glue - connects codec <--> CPU */
+ static struct snd_soc_dai_link broxton_dais[] = {
+ 	/* Front End DAI links */
+-	[BXT_DPCM_AUDIO_PB]
++	[BXT_DPCM_AUDIO_PB] =
+ 	{
+ 		.name = "Bxt Audio Port",
+ 		.stream_name = "Audio",
+@@ -271,7 +271,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
+ 		.dpcm_playback = 1,
+ 		.ops = &broxton_da7219_fe_ops,
+ 	},
+-	[BXT_DPCM_AUDIO_CP]
++	[BXT_DPCM_AUDIO_CP] =
+ 	{
+ 		.name = "Bxt Audio Capture Port",
+ 		.stream_name = "Audio Record",
+@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
+ 		.dpcm_capture = 1,
+ 		.ops = &broxton_da7219_fe_ops,
+ 	},
+-	[BXT_DPCM_AUDIO_REF_CP]
++	[BXT_DPCM_AUDIO_REF_CP] =
+ 	{
+ 		.name = "Bxt Audio Reference cap",
+ 		.stream_name = "Refcap",
+@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI1_PB]
++	[BXT_DPCM_AUDIO_HDMI1_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port1",
+ 		.stream_name = "Hdmi1",
+@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI2_PB]
++	[BXT_DPCM_AUDIO_HDMI2_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port2",
+ 		.stream_name = "Hdmi2",
+@@ -326,7 +326,7 @@ static struct snd_soc_dai_link broxton_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI3_PB]
++	[BXT_DPCM_AUDIO_HDMI3_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port3",
+ 		.stream_name = "Hdmi3",
+diff --git a/sound/soc/intel/boards/bxt_rt298.c b/sound/soc/intel/boards/bxt_rt298.c
+index 253d7bfbf511..d610bdca1608 100644
+--- a/sound/soc/intel/boards/bxt_rt298.c
++++ b/sound/soc/intel/boards/bxt_rt298.c
+@@ -271,7 +271,7 @@ static const struct snd_soc_ops broxton_rt286_fe_ops = {
+ /* broxton digital audio interface glue - connects codec <--> CPU */
+ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 	/* Front End DAI links */
+-	[BXT_DPCM_AUDIO_PB]
++	[BXT_DPCM_AUDIO_PB] =
+ 	{
+ 		.name = "Bxt Audio Port",
+ 		.stream_name = "Audio",
+@@ -286,7 +286,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.dpcm_playback = 1,
+ 		.ops = &broxton_rt286_fe_ops,
+ 	},
+-	[BXT_DPCM_AUDIO_CP]
++	[BXT_DPCM_AUDIO_CP] =
+ 	{
+ 		.name = "Bxt Audio Capture Port",
+ 		.stream_name = "Audio Record",
+@@ -300,7 +300,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.dpcm_capture = 1,
+ 		.ops = &broxton_rt286_fe_ops,
+ 	},
+-	[BXT_DPCM_AUDIO_REF_CP]
++	[BXT_DPCM_AUDIO_REF_CP] =
+ 	{
+ 		.name = "Bxt Audio Reference cap",
+ 		.stream_name = "refcap",
+@@ -313,7 +313,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_DMIC_CP]
++	[BXT_DPCM_AUDIO_DMIC_CP] =
+ 	{
+ 		.name = "Bxt Audio DMIC cap",
+ 		.stream_name = "dmiccap",
+@@ -327,7 +327,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.dynamic = 1,
+ 		.ops = &broxton_dmic_ops,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI1_PB]
++	[BXT_DPCM_AUDIO_HDMI1_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port1",
+ 		.stream_name = "Hdmi1",
+@@ -340,7 +340,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI2_PB]
++	[BXT_DPCM_AUDIO_HDMI2_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port2",
+ 		.stream_name = "Hdmi2",
+@@ -353,7 +353,7 @@ static struct snd_soc_dai_link broxton_rt298_dais[] = {
+ 		.nonatomic = 1,
+ 		.dynamic = 1,
+ 	},
+-	[BXT_DPCM_AUDIO_HDMI3_PB]
++	[BXT_DPCM_AUDIO_HDMI3_PB] =
+ 	{
+ 		.name = "Bxt HDMI Port3",
+ 		.stream_name = "Hdmi3",
+diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
+index d908ff8f9755..801082fdc3e0 100644
+--- a/sound/soc/soc-dapm.c
++++ b/sound/soc/soc-dapm.c
+@@ -823,6 +823,7 @@ static int dapm_create_or_share_kcontrol(struct snd_soc_dapm_widget *w,
+ 			case snd_soc_dapm_switch:
+ 			case snd_soc_dapm_mixer:
+ 			case snd_soc_dapm_pga:
++			case snd_soc_dapm_out_drv:
+ 				wname_in_long_name = true;
+ 				kcname_in_long_name = true;
+ 				break;
+@@ -3049,6 +3050,9 @@ int snd_soc_dapm_get_volsw(struct snd_kcontrol *kcontrol,
+ 	}
+ 	mutex_unlock(&card->dapm_mutex);
+ 
++	if (ret)
++		return ret;
++
+ 	if (invert)
+ 		ucontrol->value.integer.value[0] = max - val;
+ 	else
+@@ -3200,7 +3204,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol,
+ 	if (e->shift_l != e->shift_r) {
+ 		if (item[1] > e->items)
+ 			return -EINVAL;
+-		val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_l;
++		val |= snd_soc_enum_item_to_val(e, item[1]) << e->shift_r;
+ 		mask |= e->mask << e->shift_r;
+ 	}
+ 
+diff --git a/sound/soc/soc-topology.c b/sound/soc/soc-topology.c
+index ee7f15aa46fc..34069076bf8e 100644
+--- a/sound/soc/soc-topology.c
++++ b/sound/soc/soc-topology.c
+@@ -1475,6 +1475,7 @@ widget:
+ 	if (widget == NULL) {
+ 		dev_err(tplg->dev, "ASoC: failed to create widget %s controls\n",
+ 			w->name);
++		ret = -ENOMEM;
+ 		goto hdr_err;
+ 	}
+ 
+diff --git a/tools/perf/perf-sys.h b/tools/perf/perf-sys.h
+index 7ed72a475c57..e4b717e9eb6c 100644
+--- a/tools/perf/perf-sys.h
++++ b/tools/perf/perf-sys.h
+@@ -20,7 +20,6 @@
+ #endif
+ 
+ #ifdef __powerpc__
+-#include "../../arch/powerpc/include/uapi/asm/unistd.h"
+ #define CPUINFO_PROC	{"cpu"}
+ #endif
+ 
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index 13d414384739..7aee954b307f 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -1091,7 +1091,6 @@ static int __hpp__slsmg_color_printf(struct perf_hpp *hpp, const char *fmt, ...)
+ 	ret = scnprintf(hpp->buf, hpp->size, fmt, len, percent);
+ 	ui_browser__printf(arg->b, "%s", hpp->buf);
+ 
+-	advance_hpp(hpp, ret);
+ 	return ret;
+ }
+ 
+@@ -2046,6 +2045,7 @@ void hist_browser__init(struct hist_browser *browser,
+ 			struct hists *hists)
+ {
+ 	struct perf_hpp_fmt *fmt;
++	struct perf_hpp_list_node *node;
+ 
+ 	browser->hists			= hists;
+ 	browser->b.refresh		= hist_browser__refresh;
+@@ -2058,6 +2058,11 @@ void hist_browser__init(struct hist_browser *browser,
+ 		perf_hpp__reset_width(fmt, hists);
+ 		++browser->b.columns;
+ 	}
++	/* hierarchy entries have their own hpp list */
++	list_for_each_entry(node, &hists->hpp_formats, list) {
++		perf_hpp_list__for_each_format(&node->hpp, fmt)
++			perf_hpp__reset_width(fmt, hists);
++	}
+ }
+ 
+ struct hist_browser *hist_browser__new(struct hists *hists)
+diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
+index f04a63112079..d0cae75408ff 100644
+--- a/tools/perf/ui/stdio/hist.c
++++ b/tools/perf/ui/stdio/hist.c
+@@ -628,14 +628,6 @@ hists__fprintf_hierarchy_headers(struct hists *hists,
+ 				 struct perf_hpp *hpp,
+ 				 FILE *fp)
+ {
+-	struct perf_hpp_list_node *fmt_node;
+-	struct perf_hpp_fmt *fmt;
+-
+-	list_for_each_entry(fmt_node, &hists->hpp_formats, list) {
+-		perf_hpp_list__for_each_format(&fmt_node->hpp, fmt)
+-			perf_hpp__reset_width(fmt, hists);
+-	}
+-
+ 	return print_hierarchy_header(hists, hpp, symbol_conf.field_sep, fp);
+ }
+ 
+@@ -714,6 +706,7 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
+ 		      bool use_callchain)
+ {
+ 	struct perf_hpp_fmt *fmt;
++	struct perf_hpp_list_node *node;
+ 	struct rb_node *nd;
+ 	size_t ret = 0;
+ 	const char *sep = symbol_conf.field_sep;
+@@ -726,6 +719,11 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
+ 
+ 	hists__for_each_format(hists, fmt)
+ 		perf_hpp__reset_width(fmt, hists);
++	/* hierarchy entries have their own hpp list */
++	list_for_each_entry(node, &hists->hpp_formats, list) {
++		perf_hpp_list__for_each_format(&node->hpp, fmt)
++			perf_hpp__reset_width(fmt, hists);
++	}
+ 
+ 	if (symbol_conf.col_width_list_str)
+ 		perf_hpp__set_user_width(symbol_conf.col_width_list_str);
+diff --git a/tools/perf/util/data-convert-bt.c b/tools/perf/util/data-convert-bt.c
+index 4f979bb27b6c..7123f4de32cc 100644
+--- a/tools/perf/util/data-convert-bt.c
++++ b/tools/perf/util/data-convert-bt.c
+@@ -437,7 +437,7 @@ add_bpf_output_values(struct bt_ctf_event_class *event_class,
+ 	int ret;
+ 
+ 	if (nr_elements * sizeof(u32) != raw_size)
+-		pr_warning("Incorrect raw_size (%u) in bpf output event, skip %lu bytes\n",
++		pr_warning("Incorrect raw_size (%u) in bpf output event, skip %zu bytes\n",
+ 			   raw_size, nr_elements * sizeof(u32) - raw_size);
+ 
+ 	len_type = bt_ctf_event_class_get_field_by_name(event_class, "raw_len");
+diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
+index a811c13a74d6..f77b3167585c 100644
+--- a/tools/perf/util/symbol-elf.c
++++ b/tools/perf/util/symbol-elf.c
+@@ -1113,9 +1113,8 @@ new_symbol:
+ 	 * For misannotated, zeroed, ASM function sizes.
+ 	 */
+ 	if (nr > 0) {
+-		if (!symbol_conf.allow_aliases)
+-			symbols__fixup_duplicate(&dso->symbols[map->type]);
+ 		symbols__fixup_end(&dso->symbols[map->type]);
++		symbols__fixup_duplicate(&dso->symbols[map->type]);
+ 		if (kmap) {
+ 			/*
+ 			 * We need to fixup this here too because we create new
+diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
+index 37e8d20ae03e..f29f336ed17b 100644
+--- a/tools/perf/util/symbol.c
++++ b/tools/perf/util/symbol.c
+@@ -152,6 +152,9 @@ void symbols__fixup_duplicate(struct rb_root *symbols)
+ 	struct rb_node *nd;
+ 	struct symbol *curr, *next;
+ 
++	if (symbol_conf.allow_aliases)
++		return;
++
+ 	nd = rb_first(symbols);
+ 
+ 	while (nd) {
+@@ -1234,8 +1237,8 @@ int __dso__load_kallsyms(struct dso *dso, const char *filename,
+ 	if (kallsyms__delta(map, filename, &delta))
+ 		return -1;
+ 
+-	symbols__fixup_duplicate(&dso->symbols[map->type]);
+ 	symbols__fixup_end(&dso->symbols[map->type]);
++	symbols__fixup_duplicate(&dso->symbols[map->type]);
+ 
+ 	if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
+ 		dso->symtab_type = DSO_BINARY_TYPE__GUEST_KALLSYMS;


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-04 17:17 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-11-04 17:17 UTC (permalink / raw
  To: gentoo-commits

commit:     b83b53d35e700f57f880fc71bfe91ff2b06f1560
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Nov  4 17:17:26 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Nov  4 17:17:26 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=b83b53d3

BFQ v8r4 for kernel version 4.8

 0000_README                                                             | 2 +-
 ...3-for-4.patch1 => 5004_Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch1 | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/0000_README b/0000_README
index cd373fa..ef025ef 100644
--- a/0000_README
+++ b/0000_README
@@ -107,7 +107,7 @@ Patch:  5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.8.patch
 From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
 Desc:   BFQ v7r11 patch 3 for 4.8: Early Queue Merge (EQM)
 
-Patch:  5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1
+Patch:  5004_Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch1
 From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
 Desc:   BFQ v8r3 patch 4 for 4.8: Early Queue Merge (EQM)
 

diff --git a/5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1 b/5004_Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch1
similarity index 100%
rename from 5004_blkck-bfq-turn-BFQ-v7r11-for-4.8.0-into-BFQ-v8r3-for-4.patch1
rename to 5004_Turn-BFQ-v7r11-into-BFQ-v8r4-for-4.8.0.patch1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-10 16:37 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-11-10 16:37 UTC (permalink / raw
  To: gentoo-commits

commit:     a75f22819733b4f5c7e9081b4805a4f378a873d7
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 10 16:36:53 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Thu Nov 10 16:36:53 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a75f2281

Linux patch 4.8.7

 0000_README            |    4 +
 1006_linux-4.8.7.patch | 4331 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4335 insertions(+)

diff --git a/0000_README b/0000_README
index ef025ef..9cd8633 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,10 @@ Patch:  1005_linux-4.8.6.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.6
 
+Patch:  1006_linux-4.8.7.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.7
+
 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/1006_linux-4.8.7.patch b/1006_linux-4.8.7.patch
new file mode 100644
index 0000000..652f761
--- /dev/null
+++ b/1006_linux-4.8.7.patch
@@ -0,0 +1,4331 @@
+diff --git a/Documentation/device-mapper/dm-raid.txt b/Documentation/device-mapper/dm-raid.txt
+index e5b6497116f4..c75b64a85859 100644
+--- a/Documentation/device-mapper/dm-raid.txt
++++ b/Documentation/device-mapper/dm-raid.txt
+@@ -309,3 +309,4 @@ Version History
+ 	with a reshape in progress.
+ 1.9.0   Add support for RAID level takeover/reshape/region size
+ 	and set size reduction.
++1.9.1   Fix activation of existing RAID 4/10 mapped devices
+diff --git a/Makefile b/Makefile
+index b249529204cd..4d0f28cb481d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/boot/dts/ste-snowball.dts b/arch/arm/boot/dts/ste-snowball.dts
+index b3df1c60d465..386eee6de232 100644
+--- a/arch/arm/boot/dts/ste-snowball.dts
++++ b/arch/arm/boot/dts/ste-snowball.dts
+@@ -239,14 +239,25 @@
+ 			arm,primecell-periphid = <0x10480180>;
+ 			max-frequency = <100000000>;
+ 			bus-width = <4>;
++			cap-sd-highspeed;
+ 			cap-mmc-highspeed;
++			sd-uhs-sdr12;
++			sd-uhs-sdr25;
++			/* All direction control is used */
++			st,sig-dir-cmd;
++			st,sig-dir-dat0;
++			st,sig-dir-dat2;
++			st,sig-dir-dat31;
++			st,sig-pin-fbclk;
++			full-pwr-cycle;
+ 			vmmc-supply = <&ab8500_ldo_aux3_reg>;
+ 			vqmmc-supply = <&vmmci>;
+ 			pinctrl-names = "default", "sleep";
+ 			pinctrl-0 = <&sdi0_default_mode>;
+ 			pinctrl-1 = <&sdi0_sleep_mode>;
+ 
+-			cd-gpios  = <&gpio6 26 GPIO_ACTIVE_LOW>; // 218
++			/* GPIO218 MMC_CD */
++			cd-gpios  = <&gpio6 26 GPIO_ACTIVE_LOW>;
+ 
+ 			status = "okay";
+ 		};
+@@ -549,7 +560,7 @@
+ 					/* VMMCI level-shifter enable */
+ 					snowball_cfg3 {
+ 						pins = "GPIO217_AH12";
+-						ste,config = <&gpio_out_lo>;
++						ste,config = <&gpio_out_hi>;
+ 					};
+ 					/* VMMCI level-shifter voltage select */
+ 					snowball_cfg4 {
+diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
+index f9b6bd306cfe..541647f57192 100644
+--- a/arch/arm/mach-mvebu/Kconfig
++++ b/arch/arm/mach-mvebu/Kconfig
+@@ -23,6 +23,7 @@ config MACH_MVEBU_V7
+ 	select CACHE_L2X0
+ 	select ARM_CPU_SUSPEND
+ 	select MACH_MVEBU_ANY
++	select MVEBU_CLK_COREDIV
+ 
+ config MACH_ARMADA_370
+ 	bool "Marvell Armada 370 boards"
+@@ -32,7 +33,6 @@ config MACH_ARMADA_370
+ 	select CPU_PJ4B
+ 	select MACH_MVEBU_V7
+ 	select PINCTRL_ARMADA_370
+-	select MVEBU_CLK_COREDIV
+ 	help
+ 	  Say 'Y' here if you want your kernel to support boards based
+ 	  on the Marvell Armada 370 SoC with device tree.
+@@ -50,7 +50,6 @@ config MACH_ARMADA_375
+ 	select HAVE_SMP
+ 	select MACH_MVEBU_V7
+ 	select PINCTRL_ARMADA_375
+-	select MVEBU_CLK_COREDIV
+ 	help
+ 	  Say 'Y' here if you want your kernel to support boards based
+ 	  on the Marvell Armada 375 SoC with device tree.
+@@ -68,7 +67,6 @@ config MACH_ARMADA_38X
+ 	select HAVE_SMP
+ 	select MACH_MVEBU_V7
+ 	select PINCTRL_ARMADA_38X
+-	select MVEBU_CLK_COREDIV
+ 	help
+ 	  Say 'Y' here if you want your kernel to support boards based
+ 	  on the Marvell Armada 380/385 SoC with device tree.
+diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S
+index 6d8e8e3365d1..4cdfab31a0b6 100644
+--- a/arch/arm/mm/abort-lv4t.S
++++ b/arch/arm/mm/abort-lv4t.S
+@@ -7,7 +7,7 @@
+  *	   : r4 = aborted context pc
+  *	   : r5 = aborted context psr
+  *
+- * Returns : r4-r5, r10-r11, r13 preserved
++ * Returns : r4-r5, r9-r11, r13 preserved
+  *
+  * Purpose : obtain information about current aborted instruction.
+  * Note: we read user space.  This means we might cause a data
+@@ -48,7 +48,10 @@ ENTRY(v4t_late_abort)
+ /* c */	b	do_DataAbort			@ ldc	rd, [rn], #m	@ Same as ldr	rd, [rn], #m
+ /* d */	b	do_DataAbort			@ ldc	rd, [rn, #m]
+ /* e */	b	.data_unknown
+-/* f */
++/* f */	b	.data_unknown
++
++.data_unknown_r9:
++	ldr	r9, [sp], #4
+ .data_unknown:	@ Part of jumptable
+ 	mov	r0, r4
+ 	mov	r1, r8
+@@ -57,6 +60,7 @@ ENTRY(v4t_late_abort)
+ .data_arm_ldmstm:
+ 	tst	r8, #1 << 21			@ check writeback bit
+ 	beq	do_DataAbort			@ no writeback -> no fixup
++	str	r9, [sp, #-4]!
+ 	mov	r7, #0x11
+ 	orr	r7, r7, #0x1100
+ 	and	r6, r8, r7
+@@ -75,12 +79,14 @@ ENTRY(v4t_late_abort)
+ 	subne	r7, r7, r6, lsl #2		@ Undo increment
+ 	addeq	r7, r7, r6, lsl #2		@ Undo decrement
+ 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
++	ldr	r9, [sp], #4
+ 	b	do_DataAbort
+ 
+ .data_arm_lateldrhpre:
+ 	tst	r8, #1 << 21			@ Check writeback bit
+ 	beq	do_DataAbort			@ No writeback -> no fixup
+ .data_arm_lateldrhpost:
++	str	r9, [sp, #-4]!
+ 	and	r9, r8, #0x00f			@ get Rm / low nibble of immediate value
+ 	tst	r8, #1 << 22			@ if (immediate offset)
+ 	andne	r6, r8, #0xf00			@ { immediate high nibble
+@@ -93,6 +99,7 @@ ENTRY(v4t_late_abort)
+ 	subne	r7, r7, r6			@ Undo incrmenet
+ 	addeq	r7, r7, r6			@ Undo decrement
+ 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
++	ldr	r9, [sp], #4
+ 	b	do_DataAbort
+ 
+ .data_arm_lateldrpreconst:
+@@ -101,12 +108,14 @@ ENTRY(v4t_late_abort)
+ .data_arm_lateldrpostconst:
+ 	movs	r6, r8, lsl #20			@ Get offset
+ 	beq	do_DataAbort			@ zero -> no fixup
++	str	r9, [sp, #-4]!
+ 	and	r9, r8, #15 << 16		@ Extract 'n' from instruction
+ 	ldr	r7, [r2, r9, lsr #14]		@ Get register 'Rn'
+ 	tst	r8, #1 << 23			@ Check U bit
+ 	subne	r7, r7, r6, lsr #20		@ Undo increment
+ 	addeq	r7, r7, r6, lsr #20		@ Undo decrement
+ 	str	r7, [r2, r9, lsr #14]		@ Put register 'Rn'
++	ldr	r9, [sp], #4
+ 	b	do_DataAbort
+ 
+ .data_arm_lateldrprereg:
+@@ -115,6 +124,7 @@ ENTRY(v4t_late_abort)
+ .data_arm_lateldrpostreg:
+ 	and	r7, r8, #15			@ Extract 'm' from instruction
+ 	ldr	r6, [r2, r7, lsl #2]		@ Get register 'Rm'
++	str	r9, [sp, #-4]!
+ 	mov	r9, r8, lsr #7			@ get shift count
+ 	ands	r9, r9, #31
+ 	and	r7, r8, #0x70			@ get shift type
+@@ -126,33 +136,33 @@ ENTRY(v4t_late_abort)
+ 	b	.data_arm_apply_r6_and_rn
+ 	b	.data_arm_apply_r6_and_rn	@ 1: LSL #0
+ 	nop
+-	b	.data_unknown			@ 2: MUL?
++	b	.data_unknown_r9		@ 2: MUL?
+ 	nop
+-	b	.data_unknown			@ 3: MUL?
++	b	.data_unknown_r9		@ 3: MUL?
+ 	nop
+ 	mov	r6, r6, lsr r9			@ 4: LSR #!0
+ 	b	.data_arm_apply_r6_and_rn
+ 	mov	r6, r6, lsr #32			@ 5: LSR #32
+ 	b	.data_arm_apply_r6_and_rn
+-	b	.data_unknown			@ 6: MUL?
++	b	.data_unknown_r9		@ 6: MUL?
+ 	nop
+-	b	.data_unknown			@ 7: MUL?
++	b	.data_unknown_r9		@ 7: MUL?
+ 	nop
+ 	mov	r6, r6, asr r9			@ 8: ASR #!0
+ 	b	.data_arm_apply_r6_and_rn
+ 	mov	r6, r6, asr #32			@ 9: ASR #32
+ 	b	.data_arm_apply_r6_and_rn
+-	b	.data_unknown			@ A: MUL?
++	b	.data_unknown_r9		@ A: MUL?
+ 	nop
+-	b	.data_unknown			@ B: MUL?
++	b	.data_unknown_r9		@ B: MUL?
+ 	nop
+ 	mov	r6, r6, ror r9			@ C: ROR #!0
+ 	b	.data_arm_apply_r6_and_rn
+ 	mov	r6, r6, rrx			@ D: RRX
+ 	b	.data_arm_apply_r6_and_rn
+-	b	.data_unknown			@ E: MUL?
++	b	.data_unknown_r9		@ E: MUL?
+ 	nop
+-	b	.data_unknown			@ F: MUL?
++	b	.data_unknown_r9		@ F: MUL?
+ 
+ .data_thumb_abort:
+ 	ldrh	r8, [r4]			@ read instruction
+@@ -190,6 +200,7 @@ ENTRY(v4t_late_abort)
+ .data_thumb_pushpop:
+ 	tst	r8, #1 << 10
+ 	beq	.data_unknown
++	str	r9, [sp, #-4]!
+ 	and	r6, r8, #0x55			@ hweight8(r8) + R bit
+ 	and	r9, r8, #0xaa
+ 	add	r6, r6, r9, lsr #1
+@@ -204,9 +215,11 @@ ENTRY(v4t_late_abort)
+ 	addeq	r7, r7, r6, lsl #2		@ increment SP if PUSH
+ 	subne	r7, r7, r6, lsl #2		@ decrement SP if POP
+ 	str	r7, [r2, #13 << 2]
++	ldr	r9, [sp], #4
+ 	b	do_DataAbort
+ 
+ .data_thumb_ldmstm:
++	str	r9, [sp, #-4]!
+ 	and	r6, r8, #0x55			@ hweight8(r8)
+ 	and	r9, r8, #0xaa
+ 	add	r6, r6, r9, lsr #1
+@@ -219,4 +232,5 @@ ENTRY(v4t_late_abort)
+ 	and	r6, r6, #15			@ number of regs to transfer
+ 	sub	r7, r7, r6, lsl #2		@ always decrement
+ 	str	r7, [r2, r9, lsr #6]
++	ldr	r9, [sp], #4
+ 	b	do_DataAbort
+diff --git a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+index da31bbbbb59e..399271853aad 100644
+--- a/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
++++ b/arch/arm64/boot/dts/marvell/armada-cp110-master.dtsi
+@@ -131,7 +131,7 @@
+ 				#address-cells = <0x1>;
+ 				#size-cells = <0x0>;
+ 				cell-index = <1>;
+-				clocks = <&cpm_syscon0 0 3>;
++				clocks = <&cpm_syscon0 1 21>;
+ 				status = "disabled";
+ 			};
+ 
+diff --git a/arch/h8300/include/asm/thread_info.h b/arch/h8300/include/asm/thread_info.h
+index b408fe660cf8..3cef06875f5c 100644
+--- a/arch/h8300/include/asm/thread_info.h
++++ b/arch/h8300/include/asm/thread_info.h
+@@ -31,7 +31,6 @@ struct thread_info {
+ 	int		   cpu;			/* cpu we're on */
+ 	int		   preempt_count;	/* 0 => preemptable, <0 => BUG */
+ 	mm_segment_t		addr_limit;
+-	struct restart_block restart_block;
+ };
+ 
+ /*
+@@ -44,9 +43,6 @@ struct thread_info {
+ 	.cpu =		0,			\
+ 	.preempt_count = INIT_PREEMPT_COUNT,	\
+ 	.addr_limit	= KERNEL_DS,		\
+-	.restart_block	= {			\
+-		.fn = do_no_restart_syscall,	\
+-	},					\
+ }
+ 
+ #define init_thread_info	(init_thread_union.thread_info)
+diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c
+index ad1f81f574e5..7138303cbbf2 100644
+--- a/arch/h8300/kernel/signal.c
++++ b/arch/h8300/kernel/signal.c
+@@ -79,7 +79,7 @@ restore_sigcontext(struct sigcontext *usc, int *pd0)
+ 	unsigned int er0;
+ 
+ 	/* Always make any pending restarted system calls return -EINTR */
+-	current_thread_info()->restart_block.fn = do_no_restart_syscall;
++	current->restart_block.fn = do_no_restart_syscall;
+ 
+ 	/* restore passed registers */
+ #define COPY(r)  do { err |= get_user(regs->r, &usc->sc_##r); } while (0)
+diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
+index b54bcadd8aec..45799ef232df 100644
+--- a/arch/mips/include/asm/kvm_host.h
++++ b/arch/mips/include/asm/kvm_host.h
+@@ -279,7 +279,10 @@ struct kvm_vcpu_arch {
+ 	/* Host KSEG0 address of the EI/DI offset */
+ 	void *kseg0_commpage;
+ 
+-	u32 io_gpr;		/* GPR used as IO source/target */
++	/* Resume PC after MMIO completion */
++	unsigned long io_pc;
++	/* GPR used as IO source/target */
++	u32 io_gpr;
+ 
+ 	struct hrtimer comparecount_timer;
+ 	/* Count timer control KVM register */
+@@ -301,8 +304,6 @@ struct kvm_vcpu_arch {
+ 	/* Bitmask of pending exceptions to be cleared */
+ 	unsigned long pending_exceptions_clr;
+ 
+-	u32 pending_load_cause;
+-
+ 	/* Save/Restore the entryhi register when are are preempted/scheduled back in */
+ 	unsigned long preempt_entryhi;
+ 
+diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c
+index ca1cc30c0891..1958910b75c0 100644
+--- a/arch/mips/kernel/relocate.c
++++ b/arch/mips/kernel/relocate.c
+@@ -200,7 +200,7 @@ static inline __init unsigned long get_random_boot(void)
+ 
+ #if defined(CONFIG_USE_OF)
+ 	/* Get any additional entropy passed in device tree */
+-	{
++	if (initial_boot_params) {
+ 		int node, len;
+ 		u64 *prop;
+ 
+diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
+index 43853ec6e160..4d65285ca418 100644
+--- a/arch/mips/kvm/emulate.c
++++ b/arch/mips/kvm/emulate.c
+@@ -791,15 +791,15 @@ enum emulation_result kvm_mips_emul_eret(struct kvm_vcpu *vcpu)
+ 	struct mips_coproc *cop0 = vcpu->arch.cop0;
+ 	enum emulation_result er = EMULATE_DONE;
+ 
+-	if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
++	if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
++		kvm_clear_c0_guest_status(cop0, ST0_ERL);
++		vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
++	} else if (kvm_read_c0_guest_status(cop0) & ST0_EXL) {
+ 		kvm_debug("[%#lx] ERET to %#lx\n", vcpu->arch.pc,
+ 			  kvm_read_c0_guest_epc(cop0));
+ 		kvm_clear_c0_guest_status(cop0, ST0_EXL);
+ 		vcpu->arch.pc = kvm_read_c0_guest_epc(cop0);
+ 
+-	} else if (kvm_read_c0_guest_status(cop0) & ST0_ERL) {
+-		kvm_clear_c0_guest_status(cop0, ST0_ERL);
+-		vcpu->arch.pc = kvm_read_c0_guest_errorepc(cop0);
+ 	} else {
+ 		kvm_err("[%#lx] ERET when MIPS_SR_EXL|MIPS_SR_ERL == 0\n",
+ 			vcpu->arch.pc);
+@@ -1522,13 +1522,25 @@ enum emulation_result kvm_mips_emulate_load(union mips_instruction inst,
+ 					    struct kvm_vcpu *vcpu)
+ {
+ 	enum emulation_result er = EMULATE_DO_MMIO;
++	unsigned long curr_pc;
+ 	u32 op, rt;
+ 	u32 bytes;
+ 
+ 	rt = inst.i_format.rt;
+ 	op = inst.i_format.opcode;
+ 
+-	vcpu->arch.pending_load_cause = cause;
++	/*
++	 * Find the resume PC now while we have safe and easy access to the
++	 * prior branch instruction, and save it for
++	 * kvm_mips_complete_mmio_load() to restore later.
++	 */
++	curr_pc = vcpu->arch.pc;
++	er = update_pc(vcpu, cause);
++	if (er == EMULATE_FAIL)
++		return er;
++	vcpu->arch.io_pc = vcpu->arch.pc;
++	vcpu->arch.pc = curr_pc;
++
+ 	vcpu->arch.io_gpr = rt;
+ 
+ 	switch (op) {
+@@ -2488,9 +2500,8 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
+ 		goto done;
+ 	}
+ 
+-	er = update_pc(vcpu, vcpu->arch.pending_load_cause);
+-	if (er == EMULATE_FAIL)
+-		return er;
++	/* Restore saved resume PC */
++	vcpu->arch.pc = vcpu->arch.io_pc;
+ 
+ 	switch (run->mmio.len) {
+ 	case 4:
+@@ -2512,11 +2523,6 @@ enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
+ 		break;
+ 	}
+ 
+-	if (vcpu->arch.pending_load_cause & CAUSEF_BD)
+-		kvm_debug("[%#lx] Completing %d byte BD Load to gpr %d (0x%08lx) type %d\n",
+-			  vcpu->arch.pc, run->mmio.len, vcpu->arch.io_gpr, *gpr,
+-			  vcpu->mmio_needed);
+-
+ done:
+ 	return er;
+ }
+diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
+index d03422e5f188..7ed036c57d00 100644
+--- a/arch/parisc/kernel/syscall.S
++++ b/arch/parisc/kernel/syscall.S
+@@ -106,8 +106,6 @@ linux_gateway_entry:
+ 	mtsp	%r0,%sr4			/* get kernel space into sr4 */
+ 	mtsp	%r0,%sr5			/* get kernel space into sr5 */
+ 	mtsp	%r0,%sr6			/* get kernel space into sr6 */
+-	mfsp    %sr7,%r1                        /* save user sr7 */
+-	mtsp    %r1,%sr3                        /* and store it in sr3 */
+ 
+ #ifdef CONFIG_64BIT
+ 	/* for now we can *always* set the W bit on entry to the syscall
+@@ -133,6 +131,14 @@ linux_gateway_entry:
+ 	depdi	0, 31, 32, %r21
+ 1:	
+ #endif
++
++	/* We use a rsm/ssm pair to prevent sr3 from being clobbered
++	 * by external interrupts.
++	 */
++	mfsp    %sr7,%r1                        /* save user sr7 */
++	rsm	PSW_SM_I, %r0			/* disable interrupts */
++	mtsp    %r1,%sr3                        /* and store it in sr3 */
++
+ 	mfctl   %cr30,%r1
+ 	xor     %r1,%r30,%r30                   /* ye olde xor trick */
+ 	xor     %r1,%r30,%r1
+@@ -147,6 +153,7 @@ linux_gateway_entry:
+ 	 */
+ 
+ 	mtsp	%r0,%sr7			/* get kernel space into sr7 */
++	ssm	PSW_SM_I, %r0			/* enable interrupts */
+ 	STREGM	%r1,FRAME_SIZE(%r30)		/* save r1 (usp) here for now */
+ 	mfctl	%cr30,%r1			/* get task ptr in %r1 */
+ 	LDREG	TI_TASK(%r1),%r1
+diff --git a/arch/powerpc/include/asm/cpuidle.h b/arch/powerpc/include/asm/cpuidle.h
+index 01b8a13f0224..3919332965af 100644
+--- a/arch/powerpc/include/asm/cpuidle.h
++++ b/arch/powerpc/include/asm/cpuidle.h
+@@ -26,7 +26,7 @@ extern u64 pnv_first_deep_stop_state;
+ 	std	r0,0(r1);					\
+ 	ptesync;						\
+ 	ld	r0,0(r1);					\
+-1:	cmp	cr0,r0,r0;					\
++1:	cmpd	cr0,r0,r0;					\
+ 	bne	1b;						\
+ 	IDLE_INST;						\
+ 	b	.
+diff --git a/arch/powerpc/include/asm/tlb.h b/arch/powerpc/include/asm/tlb.h
+index f6f68f73e858..99e1397b71da 100644
+--- a/arch/powerpc/include/asm/tlb.h
++++ b/arch/powerpc/include/asm/tlb.h
+@@ -52,11 +52,23 @@ static inline int mm_is_core_local(struct mm_struct *mm)
+ 	return cpumask_subset(mm_cpumask(mm),
+ 			      topology_sibling_cpumask(smp_processor_id()));
+ }
++
++static inline int mm_is_thread_local(struct mm_struct *mm)
++{
++	return cpumask_equal(mm_cpumask(mm),
++			      cpumask_of(smp_processor_id()));
++}
++
+ #else
+ static inline int mm_is_core_local(struct mm_struct *mm)
+ {
+ 	return 1;
+ }
++
++static inline int mm_is_thread_local(struct mm_struct *mm)
++{
++	return 1;
++}
+ #endif
+ 
+ #endif /* __KERNEL__ */
+diff --git a/arch/powerpc/kernel/idle_book3s.S b/arch/powerpc/kernel/idle_book3s.S
+index bd739fed26e3..72dac0b58061 100644
+--- a/arch/powerpc/kernel/idle_book3s.S
++++ b/arch/powerpc/kernel/idle_book3s.S
+@@ -90,6 +90,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_ARCH_300)
+  * Threads will spin in HMT_LOW until the lock bit is cleared.
+  * r14 - pointer to core_idle_state
+  * r15 - used to load contents of core_idle_state
++ * r9  - used as a temporary variable
+  */
+ 
+ core_idle_lock_held:
+@@ -99,6 +100,8 @@ core_idle_lock_held:
+ 	bne	3b
+ 	HMT_MEDIUM
+ 	lwarx	r15,0,r14
++	andi.	r9,r15,PNV_CORE_IDLE_LOCK_BIT
++	bne	core_idle_lock_held
+ 	blr
+ 
+ /*
+@@ -163,12 +166,6 @@ _GLOBAL(pnv_powersave_common)
+ 	std	r9,_MSR(r1)
+ 	std	r1,PACAR1(r13)
+ 
+-#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
+-	/* Tell KVM we're entering idle */
+-	li	r4,KVM_HWTHREAD_IN_IDLE
+-	stb	r4,HSTATE_HWTHREAD_STATE(r13)
+-#endif
+-
+ 	/*
+ 	 * Go to real mode to do the nap, as required by the architecture.
+ 	 * Also, we need to be in real mode before setting hwthread_state,
+@@ -185,6 +182,26 @@ _GLOBAL(pnv_powersave_common)
+ 
+ 	.globl pnv_enter_arch207_idle_mode
+ pnv_enter_arch207_idle_mode:
++#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
++	/* Tell KVM we're entering idle */
++	li	r4,KVM_HWTHREAD_IN_IDLE
++	/******************************************************/
++	/*  N O T E   W E L L    ! ! !    N O T E   W E L L   */
++	/* The following store to HSTATE_HWTHREAD_STATE(r13)  */
++	/* MUST occur in real mode, i.e. with the MMU off,    */
++	/* and the MMU must stay off until we clear this flag */
++	/* and test HSTATE_HWTHREAD_REQ(r13) in the system    */
++	/* reset interrupt vector in exceptions-64s.S.        */
++	/* The reason is that another thread can switch the   */
++	/* MMU to a guest context whenever this flag is set   */
++	/* to KVM_HWTHREAD_IN_IDLE, and if the MMU was on,    */
++	/* that would potentially cause this thread to start  */
++	/* executing instructions from guest memory in        */
++	/* hypervisor mode, leading to a host crash or data   */
++	/* corruption, or worse.                              */
++	/******************************************************/
++	stb	r4,HSTATE_HWTHREAD_STATE(r13)
++#endif
+ 	stb	r3,PACA_THREAD_IDLE_STATE(r13)
+ 	cmpwi	cr3,r3,PNV_THREAD_SLEEP
+ 	bge	cr3,2f
+@@ -250,6 +267,12 @@ enter_winkle:
+  * r3 - requested stop state
+  */
+ power_enter_stop:
++#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
++	/* Tell KVM we're entering idle */
++	li	r4,KVM_HWTHREAD_IN_IDLE
++	/* DO THIS IN REAL MODE!  See comment above. */
++	stb	r4,HSTATE_HWTHREAD_STATE(r13)
++#endif
+ /*
+  * Check if the requested state is a deep idle state.
+  */
+diff --git a/arch/powerpc/mm/tlb-radix.c b/arch/powerpc/mm/tlb-radix.c
+index 48df05ef5231..d6960681939a 100644
+--- a/arch/powerpc/mm/tlb-radix.c
++++ b/arch/powerpc/mm/tlb-radix.c
+@@ -175,7 +175,7 @@ void radix__flush_tlb_mm(struct mm_struct *mm)
+ 	if (unlikely(pid == MMU_NO_CONTEXT))
+ 		goto no_context;
+ 
+-	if (!mm_is_core_local(mm)) {
++	if (!mm_is_thread_local(mm)) {
+ 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+ 
+ 		if (lock_tlbie)
+@@ -201,7 +201,7 @@ void radix__flush_tlb_pwc(struct mmu_gather *tlb, unsigned long addr)
+ 	if (unlikely(pid == MMU_NO_CONTEXT))
+ 		goto no_context;
+ 
+-	if (!mm_is_core_local(mm)) {
++	if (!mm_is_thread_local(mm)) {
+ 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+ 
+ 		if (lock_tlbie)
+@@ -226,7 +226,7 @@ void radix__flush_tlb_page_psize(struct mm_struct *mm, unsigned long vmaddr,
+ 	pid = mm ? mm->context.id : 0;
+ 	if (unlikely(pid == MMU_NO_CONTEXT))
+ 		goto bail;
+-	if (!mm_is_core_local(mm)) {
++	if (!mm_is_thread_local(mm)) {
+ 		int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+ 
+ 		if (lock_tlbie)
+@@ -321,7 +321,7 @@ void radix__flush_tlb_range_psize(struct mm_struct *mm, unsigned long start,
+ {
+ 	unsigned long pid;
+ 	unsigned long addr;
+-	int local = mm_is_core_local(mm);
++	int local = mm_is_thread_local(mm);
+ 	unsigned long ap = mmu_get_ap(psize);
+ 	int lock_tlbie = !mmu_has_feature(MMU_FTR_LOCKLESS_TLBIE);
+ 	unsigned long page_size = 1UL << mmu_psize_defs[psize].shift;
+diff --git a/arch/s390/kvm/sthyi.c b/arch/s390/kvm/sthyi.c
+index bd98b7d25200..05c98bb853cf 100644
+--- a/arch/s390/kvm/sthyi.c
++++ b/arch/s390/kvm/sthyi.c
+@@ -315,7 +315,7 @@ static void fill_diag(struct sthyi_sctns *sctns)
+ 	if (r < 0)
+ 		goto out;
+ 
+-	diag224_buf = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
++	diag224_buf = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
+ 	if (!diag224_buf || diag224(diag224_buf))
+ 		goto out;
+ 
+@@ -378,7 +378,7 @@ static void fill_diag(struct sthyi_sctns *sctns)
+ 	sctns->par.infpval1 |= PAR_WGHT_VLD;
+ 
+ out:
+-	kfree(diag224_buf);
++	free_page((unsigned long)diag224_buf);
+ 	vfree(diag204_buf);
+ }
+ 
+diff --git a/arch/x86/kernel/cpu/microcode/amd.c b/arch/x86/kernel/cpu/microcode/amd.c
+index 620ab06bcf45..017bda12caae 100644
+--- a/arch/x86/kernel/cpu/microcode/amd.c
++++ b/arch/x86/kernel/cpu/microcode/amd.c
+@@ -429,7 +429,7 @@ int __init save_microcode_in_initrd_amd(void)
+ 	 * We need the physical address of the container for both bitness since
+ 	 * boot_params.hdr.ramdisk_image is a physical address.
+ 	 */
+-	cont    = __pa(container);
++	cont    = __pa_nodebug(container);
+ 	cont_va = container;
+ #endif
+ 
+diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
+index 98c9cd6f3b5d..d5219b1c8775 100644
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -1222,11 +1222,16 @@ void __init setup_arch(char **cmdline_p)
+ 	if (smp_found_config)
+ 		get_smp_config();
+ 
++	/*
++	 * Systems w/o ACPI and mptables might not have it mapped the local
++	 * APIC yet, but prefill_possible_map() might need to access it.
++	 */
++	init_apic_mappings();
++
+ 	prefill_possible_map();
+ 
+ 	init_cpu_to_node();
+ 
+-	init_apic_mappings();
+ 	io_apic_init_mappings();
+ 
+ 	kvm_guest_init();
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index 4e95d3eb2955..cbd7b92585bb 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -5045,7 +5045,7 @@ done_prefixes:
+ 	/* Decode and fetch the destination operand: register or memory. */
+ 	rc = decode_operand(ctxt, &ctxt->dst, (ctxt->d >> DstShift) & OpMask);
+ 
+-	if (ctxt->rip_relative)
++	if (ctxt->rip_relative && likely(ctxt->memopp))
+ 		ctxt->memopp->addr.mem.ea = address_mask(ctxt,
+ 					ctxt->memopp->addr.mem.ea + ctxt->_eip);
+ 
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 699f8726539a..46f74d461f3f 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -7372,10 +7372,12 @@ void kvm_put_guest_fpu(struct kvm_vcpu *vcpu)
+ 
+ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
+ {
++	void *wbinvd_dirty_mask = vcpu->arch.wbinvd_dirty_mask;
++
+ 	kvmclock_reset(vcpu);
+ 
+-	free_cpumask_var(vcpu->arch.wbinvd_dirty_mask);
+ 	kvm_x86_ops->vcpu_free(vcpu);
++	free_cpumask_var(wbinvd_dirty_mask);
+ }
+ 
+ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm,
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c
+index 16288e777ec3..4b1e4eabeba4 100644
+--- a/drivers/android/binder.c
++++ b/drivers/android/binder.c
+@@ -1003,7 +1003,7 @@ static int binder_dec_node(struct binder_node *node, int strong, int internal)
+ 
+ 
+ static struct binder_ref *binder_get_ref(struct binder_proc *proc,
+-					 uint32_t desc)
++					 u32 desc, bool need_strong_ref)
+ {
+ 	struct rb_node *n = proc->refs_by_desc.rb_node;
+ 	struct binder_ref *ref;
+@@ -1011,12 +1011,16 @@ static struct binder_ref *binder_get_ref(struct binder_proc *proc,
+ 	while (n) {
+ 		ref = rb_entry(n, struct binder_ref, rb_node_desc);
+ 
+-		if (desc < ref->desc)
++		if (desc < ref->desc) {
+ 			n = n->rb_left;
+-		else if (desc > ref->desc)
++		} else if (desc > ref->desc) {
+ 			n = n->rb_right;
+-		else
++		} else if (need_strong_ref && !ref->strong) {
++			binder_user_error("tried to use weak ref as strong ref\n");
++			return NULL;
++		} else {
+ 			return ref;
++		}
+ 	}
+ 	return NULL;
+ }
+@@ -1286,7 +1290,10 @@ static void binder_transaction_buffer_release(struct binder_proc *proc,
+ 		} break;
+ 		case BINDER_TYPE_HANDLE:
+ 		case BINDER_TYPE_WEAK_HANDLE: {
+-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
++			struct binder_ref *ref;
++
++			ref = binder_get_ref(proc, fp->handle,
++					     fp->type == BINDER_TYPE_HANDLE);
+ 
+ 			if (ref == NULL) {
+ 				pr_err("transaction release %d bad handle %d\n",
+@@ -1381,7 +1388,7 @@ static void binder_transaction(struct binder_proc *proc,
+ 		if (tr->target.handle) {
+ 			struct binder_ref *ref;
+ 
+-			ref = binder_get_ref(proc, tr->target.handle);
++			ref = binder_get_ref(proc, tr->target.handle, true);
+ 			if (ref == NULL) {
+ 				binder_user_error("%d:%d got transaction to invalid handle\n",
+ 					proc->pid, thread->pid);
+@@ -1578,7 +1585,9 @@ static void binder_transaction(struct binder_proc *proc,
+ 				fp->type = BINDER_TYPE_HANDLE;
+ 			else
+ 				fp->type = BINDER_TYPE_WEAK_HANDLE;
++			fp->binder = 0;
+ 			fp->handle = ref->desc;
++			fp->cookie = 0;
+ 			binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
+ 				       &thread->todo);
+ 
+@@ -1590,7 +1599,10 @@ static void binder_transaction(struct binder_proc *proc,
+ 		} break;
+ 		case BINDER_TYPE_HANDLE:
+ 		case BINDER_TYPE_WEAK_HANDLE: {
+-			struct binder_ref *ref = binder_get_ref(proc, fp->handle);
++			struct binder_ref *ref;
++
++			ref = binder_get_ref(proc, fp->handle,
++					     fp->type == BINDER_TYPE_HANDLE);
+ 
+ 			if (ref == NULL) {
+ 				binder_user_error("%d:%d got transaction with invalid handle, %d\n",
+@@ -1625,7 +1637,9 @@ static void binder_transaction(struct binder_proc *proc,
+ 					return_error = BR_FAILED_REPLY;
+ 					goto err_binder_get_ref_for_node_failed;
+ 				}
++				fp->binder = 0;
+ 				fp->handle = new_ref->desc;
++				fp->cookie = 0;
+ 				binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+ 				trace_binder_transaction_ref_to_ref(t, ref,
+ 								    new_ref);
+@@ -1679,6 +1693,7 @@ static void binder_transaction(struct binder_proc *proc,
+ 			binder_debug(BINDER_DEBUG_TRANSACTION,
+ 				     "        fd %d -> %d\n", fp->handle, target_fd);
+ 			/* TODO: fput? */
++			fp->binder = 0;
+ 			fp->handle = target_fd;
+ 		} break;
+ 
+@@ -1801,7 +1816,9 @@ static int binder_thread_write(struct binder_proc *proc,
+ 						ref->desc);
+ 				}
+ 			} else
+-				ref = binder_get_ref(proc, target);
++				ref = binder_get_ref(proc, target,
++						     cmd == BC_ACQUIRE ||
++						     cmd == BC_RELEASE);
+ 			if (ref == NULL) {
+ 				binder_user_error("%d:%d refcount change on invalid ref %d\n",
+ 					proc->pid, thread->pid, target);
+@@ -1997,7 +2014,7 @@ static int binder_thread_write(struct binder_proc *proc,
+ 			if (get_user(cookie, (binder_uintptr_t __user *)ptr))
+ 				return -EFAULT;
+ 			ptr += sizeof(binder_uintptr_t);
+-			ref = binder_get_ref(proc, target);
++			ref = binder_get_ref(proc, target, false);
+ 			if (ref == NULL) {
+ 				binder_user_error("%d:%d %s invalid ref %d\n",
+ 					proc->pid, thread->pid,
+diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
+index 5da47e26a012..4aae0d27e382 100644
+--- a/drivers/char/virtio_console.c
++++ b/drivers/char/virtio_console.c
+@@ -1540,19 +1540,29 @@ static void remove_port_data(struct port *port)
+ 	spin_lock_irq(&port->inbuf_lock);
+ 	/* Remove unused data this port might have received. */
+ 	discard_port_data(port);
++	spin_unlock_irq(&port->inbuf_lock);
+ 
+ 	/* Remove buffers we queued up for the Host to send us data in. */
+-	while ((buf = virtqueue_detach_unused_buf(port->in_vq)))
+-		free_buf(buf, true);
+-	spin_unlock_irq(&port->inbuf_lock);
++	do {
++		spin_lock_irq(&port->inbuf_lock);
++		buf = virtqueue_detach_unused_buf(port->in_vq);
++		spin_unlock_irq(&port->inbuf_lock);
++		if (buf)
++			free_buf(buf, true);
++	} while (buf);
+ 
+ 	spin_lock_irq(&port->outvq_lock);
+ 	reclaim_consumed_buffers(port);
++	spin_unlock_irq(&port->outvq_lock);
+ 
+ 	/* Free pending buffers from the out-queue. */
+-	while ((buf = virtqueue_detach_unused_buf(port->out_vq)))
+-		free_buf(buf, true);
+-	spin_unlock_irq(&port->outvq_lock);
++	do {
++		spin_lock_irq(&port->outvq_lock);
++		buf = virtqueue_detach_unused_buf(port->out_vq);
++		spin_unlock_irq(&port->outvq_lock);
++		if (buf)
++			free_buf(buf, true);
++	} while (buf);
+ }
+ 
+ /*
+diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c
+index b46547e907be..8c347f5c2562 100644
+--- a/drivers/cpufreq/intel_pstate.c
++++ b/drivers/cpufreq/intel_pstate.c
+@@ -1133,10 +1133,8 @@ static void intel_pstate_get_min_max(struct cpudata *cpu, int *min, int *max)
+ 	*min = clamp_t(int, min_perf, cpu->pstate.min_pstate, max_perf);
+ }
+ 
+-static void intel_pstate_set_min_pstate(struct cpudata *cpu)
++static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate)
+ {
+-	int pstate = cpu->pstate.min_pstate;
+-
+ 	trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu);
+ 	cpu->pstate.current_pstate = pstate;
+ 	/*
+@@ -1148,6 +1146,20 @@ static void intel_pstate_set_min_pstate(struct cpudata *cpu)
+ 		      pstate_funcs.get_val(cpu, pstate));
+ }
+ 
++static void intel_pstate_set_min_pstate(struct cpudata *cpu)
++{
++	intel_pstate_set_pstate(cpu, cpu->pstate.min_pstate);
++}
++
++static void intel_pstate_max_within_limits(struct cpudata *cpu)
++{
++	int min_pstate, max_pstate;
++
++	update_turbo_state();
++	intel_pstate_get_min_max(cpu, &min_pstate, &max_pstate);
++	intel_pstate_set_pstate(cpu, max_pstate);
++}
++
+ static void intel_pstate_get_cpu_pstates(struct cpudata *cpu)
+ {
+ 	cpu->pstate.min_pstate = pstate_funcs.get_min();
+@@ -1465,7 +1477,7 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+ 	pr_debug("set_policy cpuinfo.max %u policy->max %u\n",
+ 		 policy->cpuinfo.max_freq, policy->max);
+ 
+-	cpu = all_cpu_data[0];
++	cpu = all_cpu_data[policy->cpu];
+ 	if (cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate &&
+ 	    policy->max < policy->cpuinfo.max_freq &&
+ 	    policy->max > cpu->pstate.max_pstate * cpu->pstate.scaling) {
+@@ -1509,6 +1521,15 @@ static int intel_pstate_set_policy(struct cpufreq_policy *policy)
+ 	limits->max_perf = round_up(limits->max_perf, FRAC_BITS);
+ 
+  out:
++	if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) {
++		/*
++		 * NOHZ_FULL CPUs need this as the governor callback may not
++		 * be invoked on them.
++		 */
++		intel_pstate_clear_update_util_hook(policy->cpu);
++		intel_pstate_max_within_limits(cpu);
++	}
++
+ 	intel_pstate_set_update_util_hook(policy->cpu);
+ 
+ 	intel_pstate_hwp_set_policy(policy);
+diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
+index 1f01e98c83c7..73ae849f5170 100644
+--- a/drivers/dax/pmem.c
++++ b/drivers/dax/pmem.c
+@@ -44,7 +44,6 @@ static void dax_pmem_percpu_exit(void *data)
+ 
+ 	dev_dbg(dax_pmem->dev, "%s\n", __func__);
+ 	percpu_ref_exit(ref);
+-	wait_for_completion(&dax_pmem->cmp);
+ }
+ 
+ static void dax_pmem_percpu_kill(void *data)
+@@ -54,6 +53,7 @@ static void dax_pmem_percpu_kill(void *data)
+ 
+ 	dev_dbg(dax_pmem->dev, "%s\n", __func__);
+ 	percpu_ref_kill(ref);
++	wait_for_completion(&dax_pmem->cmp);
+ }
+ 
+ static int dax_pmem_probe(struct device *dev)
+diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c
+index 309311b1faae..15475892af0c 100644
+--- a/drivers/firewire/net.c
++++ b/drivers/firewire/net.c
+@@ -73,13 +73,13 @@ struct rfc2734_header {
+ 
+ #define fwnet_get_hdr_lf(h)		(((h)->w0 & 0xc0000000) >> 30)
+ #define fwnet_get_hdr_ether_type(h)	(((h)->w0 & 0x0000ffff))
+-#define fwnet_get_hdr_dg_size(h)	(((h)->w0 & 0x0fff0000) >> 16)
++#define fwnet_get_hdr_dg_size(h)	((((h)->w0 & 0x0fff0000) >> 16) + 1)
+ #define fwnet_get_hdr_fg_off(h)		(((h)->w0 & 0x00000fff))
+ #define fwnet_get_hdr_dgl(h)		(((h)->w1 & 0xffff0000) >> 16)
+ 
+-#define fwnet_set_hdr_lf(lf)		((lf)  << 30)
++#define fwnet_set_hdr_lf(lf)		((lf) << 30)
+ #define fwnet_set_hdr_ether_type(et)	(et)
+-#define fwnet_set_hdr_dg_size(dgs)	((dgs) << 16)
++#define fwnet_set_hdr_dg_size(dgs)	(((dgs) - 1) << 16)
+ #define fwnet_set_hdr_fg_off(fgo)	(fgo)
+ 
+ #define fwnet_set_hdr_dgl(dgl)		((dgl) << 16)
+@@ -578,6 +578,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
+ 	int retval;
+ 	u16 ether_type;
+ 
++	if (len <= RFC2374_UNFRAG_HDR_SIZE)
++		return 0;
++
+ 	hdr.w0 = be32_to_cpu(buf[0]);
+ 	lf = fwnet_get_hdr_lf(&hdr);
+ 	if (lf == RFC2374_HDR_UNFRAG) {
+@@ -602,7 +605,12 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
+ 		return fwnet_finish_incoming_packet(net, skb, source_node_id,
+ 						    is_broadcast, ether_type);
+ 	}
++
+ 	/* A datagram fragment has been received, now the fun begins. */
++
++	if (len <= RFC2374_FRAG_HDR_SIZE)
++		return 0;
++
+ 	hdr.w1 = ntohl(buf[1]);
+ 	buf += 2;
+ 	len -= RFC2374_FRAG_HDR_SIZE;
+@@ -614,7 +622,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
+ 		fg_off = fwnet_get_hdr_fg_off(&hdr);
+ 	}
+ 	datagram_label = fwnet_get_hdr_dgl(&hdr);
+-	dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
++	dg_size = fwnet_get_hdr_dg_size(&hdr);
++
++	if (fg_off + len > dg_size)
++		return 0;
+ 
+ 	spin_lock_irqsave(&dev->lock, flags);
+ 
+@@ -722,6 +733,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,
+ 	fw_send_response(card, r, rcode);
+ }
+ 
++static int gasp_source_id(__be32 *p)
++{
++	return be32_to_cpu(p[0]) >> 16;
++}
++
++static u32 gasp_specifier_id(__be32 *p)
++{
++	return (be32_to_cpu(p[0]) & 0xffff) << 8 |
++	       (be32_to_cpu(p[1]) & 0xff000000) >> 24;
++}
++
++static u32 gasp_version(__be32 *p)
++{
++	return be32_to_cpu(p[1]) & 0xffffff;
++}
++
+ static void fwnet_receive_broadcast(struct fw_iso_context *context,
+ 		u32 cycle, size_t header_length, void *header, void *data)
+ {
+@@ -731,9 +758,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
+ 	__be32 *buf_ptr;
+ 	int retval;
+ 	u32 length;
+-	u16 source_node_id;
+-	u32 specifier_id;
+-	u32 ver;
+ 	unsigned long offset;
+ 	unsigned long flags;
+ 
+@@ -750,22 +774,17 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
+ 
+ 	spin_unlock_irqrestore(&dev->lock, flags);
+ 
+-	specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
+-			| (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
+-	ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
+-	source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
+-
+-	if (specifier_id == IANA_SPECIFIER_ID &&
+-	    (ver == RFC2734_SW_VERSION
++	if (length > IEEE1394_GASP_HDR_SIZE &&
++	    gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
++	    (gasp_version(buf_ptr) == RFC2734_SW_VERSION
+ #if IS_ENABLED(CONFIG_IPV6)
+-	     || ver == RFC3146_SW_VERSION
++	     || gasp_version(buf_ptr) == RFC3146_SW_VERSION
+ #endif
+-	    )) {
+-		buf_ptr += 2;
+-		length -= IEEE1394_GASP_HDR_SIZE;
+-		fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
++	    ))
++		fwnet_incoming_packet(dev, buf_ptr + 2,
++				      length - IEEE1394_GASP_HDR_SIZE,
++				      gasp_source_id(buf_ptr),
+ 				      context->card->generation, true);
+-	}
+ 
+ 	packet.payload_length = dev->rcv_buffer_size;
+ 	packet.interrupt = 1;
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
+index af514618d7fb..14f2d9835723 100644
+--- a/drivers/gpio/gpiolib-acpi.c
++++ b/drivers/gpio/gpiolib-acpi.c
+@@ -602,14 +602,17 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
+ {
+ 	int idx, i;
+ 	unsigned int irq_flags;
++	int ret = -ENOENT;
+ 
+ 	for (i = 0, idx = 0; idx <= index; i++) {
+ 		struct acpi_gpio_info info;
+ 		struct gpio_desc *desc;
+ 
+ 		desc = acpi_get_gpiod_by_index(adev, NULL, i, &info);
+-		if (IS_ERR(desc))
++		if (IS_ERR(desc)) {
++			ret = PTR_ERR(desc);
+ 			break;
++		}
+ 		if (info.gpioint && idx++ == index) {
+ 			int irq = gpiod_to_irq(desc);
+ 
+@@ -628,7 +631,7 @@ int acpi_dev_gpio_irq_get(struct acpi_device *adev, int index)
+ 		}
+ 
+ 	}
+-	return -ENOENT;
++	return ret;
+ }
+ EXPORT_SYMBOL_GPL(acpi_dev_gpio_irq_get);
+ 
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 53ff25ac66d8..b2dee1024166 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -21,6 +21,7 @@
+ #include <linux/uaccess.h>
+ #include <linux/compat.h>
+ #include <linux/anon_inodes.h>
++#include <linux/file.h>
+ #include <linux/kfifo.h>
+ #include <linux/poll.h>
+ #include <linux/timekeeping.h>
+@@ -331,6 +332,13 @@ struct linehandle_state {
+ 	u32 numdescs;
+ };
+ 
++#define GPIOHANDLE_REQUEST_VALID_FLAGS \
++	(GPIOHANDLE_REQUEST_INPUT | \
++	GPIOHANDLE_REQUEST_OUTPUT | \
++	GPIOHANDLE_REQUEST_ACTIVE_LOW | \
++	GPIOHANDLE_REQUEST_OPEN_DRAIN | \
++	GPIOHANDLE_REQUEST_OPEN_SOURCE)
++
+ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
+ 			     unsigned long arg)
+ {
+@@ -342,6 +350,8 @@ static long linehandle_ioctl(struct file *filep, unsigned int cmd,
+ 	if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
+ 		int val;
+ 
++		memset(&ghd, 0, sizeof(ghd));
++
+ 		/* TODO: check if descriptors are really input */
+ 		for (i = 0; i < lh->numdescs; i++) {
+ 			val = gpiod_get_value_cansleep(lh->descs[i]);
+@@ -412,6 +422,7 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
+ {
+ 	struct gpiohandle_request handlereq;
+ 	struct linehandle_state *lh;
++	struct file *file;
+ 	int fd, i, ret;
+ 
+ 	if (copy_from_user(&handlereq, ip, sizeof(handlereq)))
+@@ -442,6 +453,17 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
+ 		u32 lflags = handlereq.flags;
+ 		struct gpio_desc *desc;
+ 
++		if (offset >= gdev->ngpio) {
++			ret = -EINVAL;
++			goto out_free_descs;
++		}
++
++		/* Return an error if a unknown flag is set */
++		if (lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) {
++			ret = -EINVAL;
++			goto out_free_descs;
++		}
++
+ 		desc = &gdev->descs[offset];
+ 		ret = gpiod_request(desc, lh->label);
+ 		if (ret)
+@@ -477,26 +499,41 @@ static int linehandle_create(struct gpio_device *gdev, void __user *ip)
+ 	i--;
+ 	lh->numdescs = handlereq.lines;
+ 
+-	fd = anon_inode_getfd("gpio-linehandle",
+-			      &linehandle_fileops,
+-			      lh,
+-			      O_RDONLY | O_CLOEXEC);
++	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
+ 	if (fd < 0) {
+ 		ret = fd;
+ 		goto out_free_descs;
+ 	}
+ 
++	file = anon_inode_getfile("gpio-linehandle",
++				  &linehandle_fileops,
++				  lh,
++				  O_RDONLY | O_CLOEXEC);
++	if (IS_ERR(file)) {
++		ret = PTR_ERR(file);
++		goto out_put_unused_fd;
++	}
++
+ 	handlereq.fd = fd;
+ 	if (copy_to_user(ip, &handlereq, sizeof(handlereq))) {
+-		ret = -EFAULT;
+-		goto out_free_descs;
++		/*
++		 * fput() will trigger the release() callback, so do not go onto
++		 * the regular error cleanup path here.
++		 */
++		fput(file);
++		put_unused_fd(fd);
++		return -EFAULT;
+ 	}
+ 
++	fd_install(fd, file);
++
+ 	dev_dbg(&gdev->dev, "registered chardev handle for %d lines\n",
+ 		lh->numdescs);
+ 
+ 	return 0;
+ 
++out_put_unused_fd:
++	put_unused_fd(fd);
+ out_free_descs:
+ 	for (; i >= 0; i--)
+ 		gpiod_free(lh->descs[i]);
+@@ -534,6 +571,10 @@ struct lineevent_state {
+ 	struct mutex read_lock;
+ };
+ 
++#define GPIOEVENT_REQUEST_VALID_FLAGS \
++	(GPIOEVENT_REQUEST_RISING_EDGE | \
++	GPIOEVENT_REQUEST_FALLING_EDGE)
++
+ static unsigned int lineevent_poll(struct file *filep,
+ 				   struct poll_table_struct *wait)
+ {
+@@ -621,6 +662,8 @@ static long lineevent_ioctl(struct file *filep, unsigned int cmd,
+ 	if (cmd == GPIOHANDLE_GET_LINE_VALUES_IOCTL) {
+ 		int val;
+ 
++		memset(&ghd, 0, sizeof(ghd));
++
+ 		val = gpiod_get_value_cansleep(le->desc);
+ 		if (val < 0)
+ 			return val;
+@@ -693,6 +736,7 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
+ 	struct gpioevent_request eventreq;
+ 	struct lineevent_state *le;
+ 	struct gpio_desc *desc;
++	struct file *file;
+ 	u32 offset;
+ 	u32 lflags;
+ 	u32 eflags;
+@@ -724,6 +768,18 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
+ 	lflags = eventreq.handleflags;
+ 	eflags = eventreq.eventflags;
+ 
++	if (offset >= gdev->ngpio) {
++		ret = -EINVAL;
++		goto out_free_label;
++	}
++
++	/* Return an error if a unknown flag is set */
++	if ((lflags & ~GPIOHANDLE_REQUEST_VALID_FLAGS) ||
++	    (eflags & ~GPIOEVENT_REQUEST_VALID_FLAGS)) {
++		ret = -EINVAL;
++		goto out_free_label;
++	}
++
+ 	/* This is just wrong: we don't look for events on output lines */
+ 	if (lflags & GPIOHANDLE_REQUEST_OUTPUT) {
+ 		ret = -EINVAL;
+@@ -775,23 +831,38 @@ static int lineevent_create(struct gpio_device *gdev, void __user *ip)
+ 	if (ret)
+ 		goto out_free_desc;
+ 
+-	fd = anon_inode_getfd("gpio-event",
+-			      &lineevent_fileops,
+-			      le,
+-			      O_RDONLY | O_CLOEXEC);
++	fd = get_unused_fd_flags(O_RDONLY | O_CLOEXEC);
+ 	if (fd < 0) {
+ 		ret = fd;
+ 		goto out_free_irq;
+ 	}
+ 
++	file = anon_inode_getfile("gpio-event",
++				  &lineevent_fileops,
++				  le,
++				  O_RDONLY | O_CLOEXEC);
++	if (IS_ERR(file)) {
++		ret = PTR_ERR(file);
++		goto out_put_unused_fd;
++	}
++
+ 	eventreq.fd = fd;
+ 	if (copy_to_user(ip, &eventreq, sizeof(eventreq))) {
+-		ret = -EFAULT;
+-		goto out_free_irq;
++		/*
++		 * fput() will trigger the release() callback, so do not go onto
++		 * the regular error cleanup path here.
++		 */
++		fput(file);
++		put_unused_fd(fd);
++		return -EFAULT;
+ 	}
+ 
++	fd_install(fd, file);
++
+ 	return 0;
+ 
++out_put_unused_fd:
++	put_unused_fd(fd);
+ out_free_irq:
+ 	free_irq(le->irq, le);
+ out_free_desc:
+@@ -821,6 +892,8 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ 	if (cmd == GPIO_GET_CHIPINFO_IOCTL) {
+ 		struct gpiochip_info chipinfo;
+ 
++		memset(&chipinfo, 0, sizeof(chipinfo));
++
+ 		strncpy(chipinfo.name, dev_name(&gdev->dev),
+ 			sizeof(chipinfo.name));
+ 		chipinfo.name[sizeof(chipinfo.name)-1] = '\0';
+@@ -837,7 +910,7 @@ static long gpio_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+ 
+ 		if (copy_from_user(&lineinfo, ip, sizeof(lineinfo)))
+ 			return -EFAULT;
+-		if (lineinfo.line_offset > gdev->ngpio)
++		if (lineinfo.line_offset >= gdev->ngpio)
+ 			return -EINVAL;
+ 
+ 		desc = &gdev->descs[lineinfo.line_offset];
+diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
+index 2a3ded44cf2a..7c8c185c90ea 100644
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -420,18 +420,21 @@ drm_atomic_replace_property_blob_from_id(struct drm_crtc *crtc,
+ 					 ssize_t expected_size,
+ 					 bool *replaced)
+ {
+-	struct drm_device *dev = crtc->dev;
+ 	struct drm_property_blob *new_blob = NULL;
+ 
+ 	if (blob_id != 0) {
+-		new_blob = drm_property_lookup_blob(dev, blob_id);
++		new_blob = drm_property_lookup_blob(crtc->dev, blob_id);
+ 		if (new_blob == NULL)
+ 			return -EINVAL;
+-		if (expected_size > 0 && expected_size != new_blob->length)
++
++		if (expected_size > 0 && expected_size != new_blob->length) {
++			drm_property_unreference_blob(new_blob);
+ 			return -EINVAL;
++		}
+ 	}
+ 
+ 	drm_atomic_replace_property_blob(blob, new_blob, replaced);
++	drm_property_unreference_blob(new_blob);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
+index 04e457117980..aa644487749c 100644
+--- a/drivers/gpu/drm/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/drm_dp_mst_topology.c
+@@ -914,6 +914,7 @@ static void drm_dp_destroy_port(struct kref *kref)
+ 		/* no need to clean up vcpi
+ 		 * as if we have no connector we never setup a vcpi */
+ 		drm_dp_port_teardown_pdt(port, port->pdt);
++		port->pdt = DP_PEER_DEVICE_NONE;
+ 	}
+ 	kfree(port);
+ }
+@@ -1159,7 +1160,9 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
+ 			drm_dp_put_port(port);
+ 			goto out;
+ 		}
+-		if (port->port_num >= DP_MST_LOGICAL_PORT_0) {
++		if ((port->pdt == DP_PEER_DEVICE_DP_LEGACY_CONV ||
++		     port->pdt == DP_PEER_DEVICE_SST_SINK) &&
++		    port->port_num >= DP_MST_LOGICAL_PORT_0) {
+ 			port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
+ 			drm_mode_connector_set_tile_property(port->connector);
+ 		}
+@@ -2919,6 +2922,7 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
+ 		mgr->cbs->destroy_connector(mgr, port->connector);
+ 
+ 		drm_dp_port_teardown_pdt(port, port->pdt);
++		port->pdt = DP_PEER_DEVICE_NONE;
+ 
+ 		if (!port->input && port->vcpi.vcpi > 0) {
+ 			drm_dp_mst_reset_vcpi_slots(mgr, port);
+diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
+index 0a06f9120b5a..337c55597ccd 100644
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -129,7 +129,12 @@ int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
+ 	return 0;
+ fail:
+ 	for (i = 0; i < fb_helper->connector_count; i++) {
+-		kfree(fb_helper->connector_info[i]);
++		struct drm_fb_helper_connector *fb_helper_connector =
++			fb_helper->connector_info[i];
++
++		drm_connector_unreference(fb_helper_connector->connector);
++
++		kfree(fb_helper_connector);
+ 		fb_helper->connector_info[i] = NULL;
+ 	}
+ 	fb_helper->connector_count = 0;
+@@ -601,6 +606,24 @@ int drm_fb_helper_blank(int blank, struct fb_info *info)
+ }
+ EXPORT_SYMBOL(drm_fb_helper_blank);
+ 
++static void drm_fb_helper_modeset_release(struct drm_fb_helper *helper,
++					  struct drm_mode_set *modeset)
++{
++	int i;
++
++	for (i = 0; i < modeset->num_connectors; i++) {
++		drm_connector_unreference(modeset->connectors[i]);
++		modeset->connectors[i] = NULL;
++	}
++	modeset->num_connectors = 0;
++
++	drm_mode_destroy(helper->dev, modeset->mode);
++	modeset->mode = NULL;
++
++	/* FIXME should hold a ref? */
++	modeset->fb = NULL;
++}
++
+ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
+ {
+ 	int i;
+@@ -610,10 +633,12 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper)
+ 		kfree(helper->connector_info[i]);
+ 	}
+ 	kfree(helper->connector_info);
++
+ 	for (i = 0; i < helper->crtc_count; i++) {
+-		kfree(helper->crtc_info[i].mode_set.connectors);
+-		if (helper->crtc_info[i].mode_set.mode)
+-			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
++		struct drm_mode_set *modeset = &helper->crtc_info[i].mode_set;
++
++		drm_fb_helper_modeset_release(helper, modeset);
++		kfree(modeset->connectors);
+ 	}
+ 	kfree(helper->crtc_info);
+ }
+@@ -632,7 +657,9 @@ static void drm_fb_helper_dirty_work(struct work_struct *work)
+ 	clip->x2 = clip->y2 = 0;
+ 	spin_unlock_irqrestore(&helper->dirty_lock, flags);
+ 
+-	helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
++	/* call dirty callback only when it has been really touched */
++	if (clip_copy.x1 < clip_copy.x2 && clip_copy.y1 < clip_copy.y2)
++		helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, &clip_copy, 1);
+ }
+ 
+ /**
+@@ -2027,7 +2054,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
+ 	struct drm_fb_helper_crtc **crtcs;
+ 	struct drm_display_mode **modes;
+ 	struct drm_fb_offset *offsets;
+-	struct drm_mode_set *modeset;
+ 	bool *enabled;
+ 	int width, height;
+ 	int i;
+@@ -2075,45 +2101,35 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
+ 
+ 	/* need to set the modesets up here for use later */
+ 	/* fill out the connector<->crtc mappings into the modesets */
+-	for (i = 0; i < fb_helper->crtc_count; i++) {
+-		modeset = &fb_helper->crtc_info[i].mode_set;
+-		modeset->num_connectors = 0;
+-		modeset->fb = NULL;
+-	}
++	for (i = 0; i < fb_helper->crtc_count; i++)
++		drm_fb_helper_modeset_release(fb_helper,
++					      &fb_helper->crtc_info[i].mode_set);
+ 
+ 	for (i = 0; i < fb_helper->connector_count; i++) {
+ 		struct drm_display_mode *mode = modes[i];
+ 		struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
+ 		struct drm_fb_offset *offset = &offsets[i];
+-		modeset = &fb_crtc->mode_set;
++		struct drm_mode_set *modeset = &fb_crtc->mode_set;
+ 
+ 		if (mode && fb_crtc) {
++			struct drm_connector *connector =
++				fb_helper->connector_info[i]->connector;
++
+ 			DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
+ 				      mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
++
+ 			fb_crtc->desired_mode = mode;
+ 			fb_crtc->x = offset->x;
+ 			fb_crtc->y = offset->y;
+-			if (modeset->mode)
+-				drm_mode_destroy(dev, modeset->mode);
+ 			modeset->mode = drm_mode_duplicate(dev,
+ 							   fb_crtc->desired_mode);
+-			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
++			drm_connector_reference(connector);
++			modeset->connectors[modeset->num_connectors++] = connector;
+ 			modeset->fb = fb_helper->fb;
+ 			modeset->x = offset->x;
+ 			modeset->y = offset->y;
+ 		}
+ 	}
+-
+-	/* Clear out any old modes if there are no more connected outputs. */
+-	for (i = 0; i < fb_helper->crtc_count; i++) {
+-		modeset = &fb_helper->crtc_info[i].mode_set;
+-		if (modeset->num_connectors == 0) {
+-			BUG_ON(modeset->fb);
+-			if (modeset->mode)
+-				drm_mode_destroy(dev, modeset->mode);
+-			modeset->mode = NULL;
+-		}
+-	}
+ out:
+ 	kfree(crtcs);
+ 	kfree(modes);
+diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
+index c6e69e4cfa83..1f8af87c6294 100644
+--- a/drivers/gpu/drm/i915/intel_bios.c
++++ b/drivers/gpu/drm/i915/intel_bios.c
+@@ -1031,6 +1031,77 @@ static u8 translate_iboost(u8 val)
+ 	return mapping[val];
+ }
+ 
++static void sanitize_ddc_pin(struct drm_i915_private *dev_priv,
++			     enum port port)
++{
++	const struct ddi_vbt_port_info *info =
++		&dev_priv->vbt.ddi_port_info[port];
++	enum port p;
++
++	if (!info->alternate_ddc_pin)
++		return;
++
++	for_each_port_masked(p, (1 << port) - 1) {
++		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
++
++		if (info->alternate_ddc_pin != i->alternate_ddc_pin)
++			continue;
++
++		DRM_DEBUG_KMS("port %c trying to use the same DDC pin (0x%x) as port %c, "
++			      "disabling port %c DVI/HDMI support\n",
++			      port_name(p), i->alternate_ddc_pin,
++			      port_name(port), port_name(p));
++
++		/*
++		 * If we have multiple ports supposedly sharing the
++		 * pin, then dvi/hdmi couldn't exist on the shared
++		 * port. Otherwise they share the same ddc bin and
++		 * system couldn't communicate with them separately.
++		 *
++		 * Due to parsing the ports in alphabetical order,
++		 * a higher port will always clobber a lower one.
++		 */
++		i->supports_dvi = false;
++		i->supports_hdmi = false;
++		i->alternate_ddc_pin = 0;
++	}
++}
++
++static void sanitize_aux_ch(struct drm_i915_private *dev_priv,
++			    enum port port)
++{
++	const struct ddi_vbt_port_info *info =
++		&dev_priv->vbt.ddi_port_info[port];
++	enum port p;
++
++	if (!info->alternate_aux_channel)
++		return;
++
++	for_each_port_masked(p, (1 << port) - 1) {
++		struct ddi_vbt_port_info *i = &dev_priv->vbt.ddi_port_info[p];
++
++		if (info->alternate_aux_channel != i->alternate_aux_channel)
++			continue;
++
++		DRM_DEBUG_KMS("port %c trying to use the same AUX CH (0x%x) as port %c, "
++			      "disabling port %c DP support\n",
++			      port_name(p), i->alternate_aux_channel,
++			      port_name(port), port_name(p));
++
++		/*
++		 * If we have multiple ports supposedlt sharing the
++		 * aux channel, then DP couldn't exist on the shared
++		 * port. Otherwise they share the same aux channel
++		 * and system couldn't communicate with them separately.
++		 *
++		 * Due to parsing the ports in alphabetical order,
++		 * a higher port will always clobber a lower one.
++		 */
++		i->supports_dp = false;
++		i->alternate_aux_channel = 0;
++	}
++}
++
+ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
+ 			   const struct bdb_header *bdb)
+ {
+@@ -1105,54 +1176,15 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
+ 		DRM_DEBUG_KMS("Port %c is internal DP\n", port_name(port));
+ 
+ 	if (is_dvi) {
+-		if (port == PORT_E) {
+-			info->alternate_ddc_pin = ddc_pin;
+-			/* if DDIE share ddc pin with other port, then
+-			 * dvi/hdmi couldn't exist on the shared port.
+-			 * Otherwise they share the same ddc bin and system
+-			 * couldn't communicate with them seperately. */
+-			if (ddc_pin == DDC_PIN_B) {
+-				dev_priv->vbt.ddi_port_info[PORT_B].supports_dvi = 0;
+-				dev_priv->vbt.ddi_port_info[PORT_B].supports_hdmi = 0;
+-			} else if (ddc_pin == DDC_PIN_C) {
+-				dev_priv->vbt.ddi_port_info[PORT_C].supports_dvi = 0;
+-				dev_priv->vbt.ddi_port_info[PORT_C].supports_hdmi = 0;
+-			} else if (ddc_pin == DDC_PIN_D) {
+-				dev_priv->vbt.ddi_port_info[PORT_D].supports_dvi = 0;
+-				dev_priv->vbt.ddi_port_info[PORT_D].supports_hdmi = 0;
+-			}
+-		} else if (ddc_pin == DDC_PIN_B && port != PORT_B)
+-			DRM_DEBUG_KMS("Unexpected DDC pin for port B\n");
+-		else if (ddc_pin == DDC_PIN_C && port != PORT_C)
+-			DRM_DEBUG_KMS("Unexpected DDC pin for port C\n");
+-		else if (ddc_pin == DDC_PIN_D && port != PORT_D)
+-			DRM_DEBUG_KMS("Unexpected DDC pin for port D\n");
++		info->alternate_ddc_pin = ddc_pin;
++
++		sanitize_ddc_pin(dev_priv, port);
+ 	}
+ 
+ 	if (is_dp) {
+-		if (port == PORT_E) {
+-			info->alternate_aux_channel = aux_channel;
+-			/* if DDIE share aux channel with other port, then
+-			 * DP couldn't exist on the shared port. Otherwise
+-			 * they share the same aux channel and system
+-			 * couldn't communicate with them seperately. */
+-			if (aux_channel == DP_AUX_A)
+-				dev_priv->vbt.ddi_port_info[PORT_A].supports_dp = 0;
+-			else if (aux_channel == DP_AUX_B)
+-				dev_priv->vbt.ddi_port_info[PORT_B].supports_dp = 0;
+-			else if (aux_channel == DP_AUX_C)
+-				dev_priv->vbt.ddi_port_info[PORT_C].supports_dp = 0;
+-			else if (aux_channel == DP_AUX_D)
+-				dev_priv->vbt.ddi_port_info[PORT_D].supports_dp = 0;
+-		}
+-		else if (aux_channel == DP_AUX_A && port != PORT_A)
+-			DRM_DEBUG_KMS("Unexpected AUX channel for port A\n");
+-		else if (aux_channel == DP_AUX_B && port != PORT_B)
+-			DRM_DEBUG_KMS("Unexpected AUX channel for port B\n");
+-		else if (aux_channel == DP_AUX_C && port != PORT_C)
+-			DRM_DEBUG_KMS("Unexpected AUX channel for port C\n");
+-		else if (aux_channel == DP_AUX_D && port != PORT_D)
+-			DRM_DEBUG_KMS("Unexpected AUX channel for port D\n");
++		info->alternate_aux_channel = aux_channel;
++
++		sanitize_aux_ch(dev_priv, port);
+ 	}
+ 
+ 	if (bdb->version >= 158) {
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index e9a64fba6333..63462f279187 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13834,7 +13834,7 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
+ 
+ 	for_each_plane_in_state(state, plane, plane_state, i) {
+ 		struct intel_plane_state *intel_plane_state =
+-			to_intel_plane_state(plane_state);
++			to_intel_plane_state(plane->state);
+ 
+ 		if (!intel_plane_state->wait_req)
+ 			continue;
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 1ca155f4d368..3051182cf483 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -1090,6 +1090,44 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
+ 	return ret;
+ }
+ 
++static enum port intel_aux_port(struct drm_i915_private *dev_priv,
++				enum port port)
++{
++	const struct ddi_vbt_port_info *info =
++		&dev_priv->vbt.ddi_port_info[port];
++	enum port aux_port;
++
++	if (!info->alternate_aux_channel) {
++		DRM_DEBUG_KMS("using AUX %c for port %c (platform default)\n",
++			      port_name(port), port_name(port));
++		return port;
++	}
++
++	switch (info->alternate_aux_channel) {
++	case DP_AUX_A:
++		aux_port = PORT_A;
++		break;
++	case DP_AUX_B:
++		aux_port = PORT_B;
++		break;
++	case DP_AUX_C:
++		aux_port = PORT_C;
++		break;
++	case DP_AUX_D:
++		aux_port = PORT_D;
++		break;
++	default:
++		MISSING_CASE(info->alternate_aux_channel);
++		aux_port = PORT_A;
++		break;
++	}
++
++	DRM_DEBUG_KMS("using AUX %c for port %c (VBT)\n",
++		      port_name(aux_port), port_name(port));
++
++	return aux_port;
++}
++
+ static i915_reg_t g4x_aux_ctl_reg(struct drm_i915_private *dev_priv,
+ 				       enum port port)
+ {
+@@ -1150,36 +1188,9 @@ static i915_reg_t ilk_aux_data_reg(struct drm_i915_private *dev_priv,
+ 	}
+ }
+ 
+-/*
+- * On SKL we don't have Aux for port E so we rely
+- * on VBT to set a proper alternate aux channel.
+- */
+-static enum port skl_porte_aux_port(struct drm_i915_private *dev_priv)
+-{
+-	const struct ddi_vbt_port_info *info =
+-		&dev_priv->vbt.ddi_port_info[PORT_E];
+-
+-	switch (info->alternate_aux_channel) {
+-	case DP_AUX_A:
+-		return PORT_A;
+-	case DP_AUX_B:
+-		return PORT_B;
+-	case DP_AUX_C:
+-		return PORT_C;
+-	case DP_AUX_D:
+-		return PORT_D;
+-	default:
+-		MISSING_CASE(info->alternate_aux_channel);
+-		return PORT_A;
+-	}
+-}
+-
+ static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
+ 				       enum port port)
+ {
+-	if (port == PORT_E)
+-		port = skl_porte_aux_port(dev_priv);
+-
+ 	switch (port) {
+ 	case PORT_A:
+ 	case PORT_B:
+@@ -1195,9 +1206,6 @@ static i915_reg_t skl_aux_ctl_reg(struct drm_i915_private *dev_priv,
+ static i915_reg_t skl_aux_data_reg(struct drm_i915_private *dev_priv,
+ 					enum port port, int index)
+ {
+-	if (port == PORT_E)
+-		port = skl_porte_aux_port(dev_priv);
+-
+ 	switch (port) {
+ 	case PORT_A:
+ 	case PORT_B:
+@@ -1235,7 +1243,8 @@ static i915_reg_t intel_aux_data_reg(struct drm_i915_private *dev_priv,
+ static void intel_aux_reg_init(struct intel_dp *intel_dp)
+ {
+ 	struct drm_i915_private *dev_priv = to_i915(intel_dp_to_dev(intel_dp));
+-	enum port port = dp_to_dig_port(intel_dp)->port;
++	enum port port = intel_aux_port(dev_priv,
++					dp_to_dig_port(intel_dp)->port);
+ 	int i;
+ 
+ 	intel_dp->aux_ch_ctl_reg = intel_aux_ctl_reg(dev_priv, port);
+diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
+index 3836a1c79714..ad483376bdfa 100644
+--- a/drivers/gpu/drm/i915/intel_fbc.c
++++ b/drivers/gpu/drm/i915/intel_fbc.c
+@@ -104,8 +104,10 @@ static int intel_fbc_calculate_cfb_size(struct drm_i915_private *dev_priv,
+ 	int lines;
+ 
+ 	intel_fbc_get_plane_source_size(cache, NULL, &lines);
+-	if (INTEL_INFO(dev_priv)->gen >= 7)
++	if (INTEL_GEN(dev_priv) == 7)
+ 		lines = min(lines, 2048);
++	else if (INTEL_GEN(dev_priv) >= 8)
++		lines = min(lines, 2560);
+ 
+ 	/* Hardware needs the full buffer stride, not just the active area. */
+ 	return lines * cache->fb.stride;
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index e59a28cb3158..a69160568254 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3363,13 +3363,15 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ 	int num_active;
+ 	int id, i;
+ 
++	/* Clear the partitioning for disabled planes. */
++	memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
++	memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
++
+ 	if (WARN_ON(!state))
+ 		return 0;
+ 
+ 	if (!cstate->base.active) {
+ 		ddb->pipe[pipe].start = ddb->pipe[pipe].end = 0;
+-		memset(ddb->plane[pipe], 0, sizeof(ddb->plane[pipe]));
+-		memset(ddb->y_plane[pipe], 0, sizeof(ddb->y_plane[pipe]));
+ 		return 0;
+ 	}
+ 
+@@ -3469,12 +3471,6 @@ skl_allocate_pipe_ddb(struct intel_crtc_state *cstate,
+ 	return 0;
+ }
+ 
+-static uint32_t skl_pipe_pixel_rate(const struct intel_crtc_state *config)
+-{
+-	/* TODO: Take into account the scalers once we support them */
+-	return config->base.adjusted_mode.crtc_clock;
+-}
+-
+ /*
+  * The max latency should be 257 (max the punit can code is 255 and we add 2us
+  * for the read latency) and cpp should always be <= 8, so that
+@@ -3525,7 +3521,7 @@ static uint32_t skl_adjusted_plane_pixel_rate(const struct intel_crtc_state *cst
+ 	 * Adjusted plane pixel rate is just the pipe's adjusted pixel rate
+ 	 * with additional adjustments for plane-specific scaling.
+ 	 */
+-	adjusted_pixel_rate = skl_pipe_pixel_rate(cstate);
++	adjusted_pixel_rate = ilk_pipe_pixel_rate(cstate);
+ 	downscale_amount = skl_plane_downscale_amount(pstate);
+ 
+ 	pixel_rate = adjusted_pixel_rate * downscale_amount >> 16;
+@@ -3737,11 +3733,11 @@ skl_compute_linetime_wm(struct intel_crtc_state *cstate)
+ 	if (!cstate->base.active)
+ 		return 0;
+ 
+-	if (WARN_ON(skl_pipe_pixel_rate(cstate) == 0))
++	if (WARN_ON(ilk_pipe_pixel_rate(cstate) == 0))
+ 		return 0;
+ 
+ 	return DIV_ROUND_UP(8 * cstate->base.adjusted_mode.crtc_htotal * 1000,
+-			    skl_pipe_pixel_rate(cstate));
++			    ilk_pipe_pixel_rate(cstate));
+ }
+ 
+ static void skl_compute_transition_wm(struct intel_crtc_state *cstate,
+@@ -4051,6 +4047,12 @@ skl_compute_ddb(struct drm_atomic_state *state)
+ 		intel_state->wm_results.dirty_pipes = ~0;
+ 	}
+ 
++	/*
++	 * We're not recomputing for the pipes not included in the commit, so
++	 * make sure we start with the current state.
++	 */
++	memcpy(ddb, &dev_priv->wm.skl_hw.ddb, sizeof(*ddb));
++
+ 	for_each_intel_crtc_mask(dev, intel_crtc, realloc_pipes) {
+ 		struct intel_crtc_state *cstate;
+ 
+diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c
+index 29423e757d36..927c51e8abc6 100644
+--- a/drivers/gpu/drm/imx/ipuv3-plane.c
++++ b/drivers/gpu/drm/imx/ipuv3-plane.c
+@@ -108,6 +108,7 @@ static void ipu_plane_atomic_set_base(struct ipu_plane *ipu_plane,
+ {
+ 	struct drm_plane *plane = &ipu_plane->base;
+ 	struct drm_plane_state *state = plane->state;
++	struct drm_crtc_state *crtc_state = state->crtc->state;
+ 	struct drm_framebuffer *fb = state->fb;
+ 	unsigned long eba, ubo, vbo;
+ 	int active;
+@@ -149,7 +150,7 @@ static void ipu_plane_atomic_set_base(struct ipu_plane *ipu_plane,
+ 		break;
+ 	}
+ 
+-	if (old_state->fb) {
++	if (!drm_atomic_crtc_needs_modeset(crtc_state)) {
+ 		active = ipu_idmac_get_current_buffer(ipu_plane->ipu_ch);
+ 		ipu_cpmem_set_buffer(ipu_plane->ipu_ch, !active, eba);
+ 		ipu_idmac_select_buffer(ipu_plane->ipu_ch, !active);
+@@ -359,7 +360,9 @@ static int ipu_plane_atomic_check(struct drm_plane *plane,
+ 		if ((ubo > 0xfffff8) || (vbo > 0xfffff8))
+ 			return -EINVAL;
+ 
+-		if (old_fb) {
++		if (old_fb &&
++		    (old_fb->pixel_format == DRM_FORMAT_YUV420 ||
++		     old_fb->pixel_format == DRM_FORMAT_YVU420)) {
+ 			old_ubo = drm_plane_state_to_ubo(old_state);
+ 			old_vbo = drm_plane_state_to_vbo(old_state);
+ 			if (ubo != old_ubo || vbo != old_vbo)
+diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c
+index dc57b628e074..193573d191e5 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_acpi.c
++++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c
+@@ -240,7 +240,8 @@ static bool nouveau_pr3_present(struct pci_dev *pdev)
+ 	if (!parent_adev)
+ 		return false;
+ 
+-	return acpi_has_method(parent_adev->handle, "_PR3");
++	return parent_adev->power.flags.power_resources &&
++		acpi_has_method(parent_adev->handle, "_PR3");
+ }
+ 
+ static void nouveau_dsm_pci_probe(struct pci_dev *pdev, acpi_handle *dhandle_out,
+diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c
+index 4a3d7cab83f7..4b9c2d5ff6a1 100644
+--- a/drivers/gpu/drm/radeon/ni.c
++++ b/drivers/gpu/drm/radeon/ni.c
+@@ -1396,9 +1396,7 @@ static void cayman_pcie_gart_fini(struct radeon_device *rdev)
+ void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
+ 			      int ring, u32 cp_int_cntl)
+ {
+-	u32 srbm_gfx_cntl = RREG32(SRBM_GFX_CNTL) & ~3;
+-
+-	WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl | (ring & 3));
++	WREG32(SRBM_GFX_CNTL, RINGID(ring));
+ 	WREG32(CP_INT_CNTL, cp_int_cntl);
+ }
+ 
+diff --git a/drivers/gpu/drm/radeon/radeon_dp_auxch.c b/drivers/gpu/drm/radeon/radeon_dp_auxch.c
+index db64e0062689..3b0c229d7dcd 100644
+--- a/drivers/gpu/drm/radeon/radeon_dp_auxch.c
++++ b/drivers/gpu/drm/radeon/radeon_dp_auxch.c
+@@ -105,7 +105,7 @@ radeon_dp_aux_transfer_native(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg
+ 
+ 	tmp &= AUX_HPD_SEL(0x7);
+ 	tmp |= AUX_HPD_SEL(chan->rec.hpd);
+-	tmp |= AUX_EN | AUX_LS_READ_EN | AUX_HPD_DISCON(0x1);
++	tmp |= AUX_EN | AUX_LS_READ_EN;
+ 
+ 	WREG32(AUX_CONTROL + aux_offset[instance], tmp);
+ 
+diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
+index 89bdf20344ae..c49934527a87 100644
+--- a/drivers/gpu/drm/radeon/si_dpm.c
++++ b/drivers/gpu/drm/radeon/si_dpm.c
+@@ -2999,6 +2999,49 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
+ 	int i;
+ 	struct si_dpm_quirk *p = si_dpm_quirk_list;
+ 
++	/* limit all SI kickers */
++	if (rdev->family == CHIP_PITCAIRN) {
++		if ((rdev->pdev->revision == 0x81) ||
++		    (rdev->pdev->device == 0x6810) ||
++		    (rdev->pdev->device == 0x6811) ||
++		    (rdev->pdev->device == 0x6816) ||
++		    (rdev->pdev->device == 0x6817) ||
++		    (rdev->pdev->device == 0x6806))
++			max_mclk = 120000;
++	} else if (rdev->family == CHIP_VERDE) {
++		if ((rdev->pdev->revision == 0x81) ||
++		    (rdev->pdev->revision == 0x83) ||
++		    (rdev->pdev->revision == 0x87) ||
++		    (rdev->pdev->device == 0x6820) ||
++		    (rdev->pdev->device == 0x6821) ||
++		    (rdev->pdev->device == 0x6822) ||
++		    (rdev->pdev->device == 0x6823) ||
++		    (rdev->pdev->device == 0x682A) ||
++		    (rdev->pdev->device == 0x682B)) {
++			max_sclk = 75000;
++			max_mclk = 80000;
++		}
++	} else if (rdev->family == CHIP_OLAND) {
++		if ((rdev->pdev->revision == 0xC7) ||
++		    (rdev->pdev->revision == 0x80) ||
++		    (rdev->pdev->revision == 0x81) ||
++		    (rdev->pdev->revision == 0x83) ||
++		    (rdev->pdev->device == 0x6604) ||
++		    (rdev->pdev->device == 0x6605)) {
++			max_sclk = 75000;
++			max_mclk = 80000;
++		}
++	} else if (rdev->family == CHIP_HAINAN) {
++		if ((rdev->pdev->revision == 0x81) ||
++		    (rdev->pdev->revision == 0x83) ||
++		    (rdev->pdev->revision == 0xC3) ||
++		    (rdev->pdev->device == 0x6664) ||
++		    (rdev->pdev->device == 0x6665) ||
++		    (rdev->pdev->device == 0x6667)) {
++			max_sclk = 75000;
++			max_mclk = 80000;
++		}
++	}
+ 	/* Apply dpm quirks */
+ 	while (p && p->chip_device != 0) {
+ 		if (rdev->pdev->vendor == p->chip_vendor &&
+@@ -3011,16 +3054,6 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
+ 		}
+ 		++p;
+ 	}
+-	/* limit mclk on all R7 370 parts for stability */
+-	if (rdev->pdev->device == 0x6811 &&
+-	    rdev->pdev->revision == 0x81)
+-		max_mclk = 120000;
+-	/* limit sclk/mclk on Jet parts for stability */
+-	if (rdev->pdev->device == 0x6665 &&
+-	    rdev->pdev->revision == 0xc3) {
+-		max_sclk = 75000;
+-		max_mclk = 80000;
+-	}
+ 
+ 	if (rps->vce_active) {
+ 		rps->evclk = rdev->pm.dpm.vce_states[rdev->pm.dpm.vce_level].evclk;
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
+index e92b09d32605..9ab703c1042e 100644
+--- a/drivers/hid/hid-ids.h
++++ b/drivers/hid/hid-ids.h
+@@ -179,6 +179,7 @@
+ #define USB_DEVICE_ID_ATEN_4PORTKVM	0x2205
+ #define USB_DEVICE_ID_ATEN_4PORTKVMC	0x2208
+ #define USB_DEVICE_ID_ATEN_CS682	0x2213
++#define USB_DEVICE_ID_ATEN_CS692	0x8021
+ 
+ #define USB_VENDOR_ID_ATMEL		0x03eb
+ #define USB_DEVICE_ID_ATMEL_MULTITOUCH	0x211c
+diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c
+index bb400081efe4..85fcf60f3bba 100644
+--- a/drivers/hid/usbhid/hid-quirks.c
++++ b/drivers/hid/usbhid/hid-quirks.c
+@@ -63,6 +63,7 @@ static const struct hid_blacklist {
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVM, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_4PORTKVMC, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS682, HID_QUIRK_NOGET },
++	{ USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_CS692, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FIGHTERSTICK, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_COMBATSTICK, HID_QUIRK_NOGET },
+ 	{ USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_FLIGHT_SIM_ECLIPSE_YOKE, HID_QUIRK_NOGET },
+diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
+index d5acaa2d8e61..9dc63725363d 100644
+--- a/drivers/hv/hv_util.c
++++ b/drivers/hv/hv_util.c
+@@ -283,10 +283,14 @@ static void heartbeat_onchannelcallback(void *context)
+ 	u8 *hbeat_txf_buf = util_heartbeat.recv_buffer;
+ 	struct icmsg_negotiate *negop = NULL;
+ 
+-	vmbus_recvpacket(channel, hbeat_txf_buf,
+-			 PAGE_SIZE, &recvlen, &requestid);
++	while (1) {
++
++		vmbus_recvpacket(channel, hbeat_txf_buf,
++				 PAGE_SIZE, &recvlen, &requestid);
++
++		if (!recvlen)
++			break;
+ 
+-	if (recvlen > 0) {
+ 		icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[
+ 				sizeof(struct vmbuspipe_hdr)];
+ 
+diff --git a/drivers/i2c/busses/i2c-rk3x.c b/drivers/i2c/busses/i2c-rk3x.c
+index 5c5b7cada8be..dfae43523d34 100644
+--- a/drivers/i2c/busses/i2c-rk3x.c
++++ b/drivers/i2c/busses/i2c-rk3x.c
+@@ -694,6 +694,8 @@ static int rk3x_i2c_v0_calc_timings(unsigned long clk_rate,
+ 	t_calc->div_low--;
+ 	t_calc->div_high--;
+ 
++	/* Give the tuning value 0, that would not update con register */
++	t_calc->tuning = 0;
+ 	/* Maximum divider supported by hw is 0xffff */
+ 	if (t_calc->div_low > 0xffff) {
+ 		t_calc->div_low = 0xffff;
+diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c
+index 4233f5695352..3c38029e3fe9 100644
+--- a/drivers/i2c/busses/i2c-xgene-slimpro.c
++++ b/drivers/i2c/busses/i2c-xgene-slimpro.c
+@@ -105,7 +105,7 @@ struct slimpro_i2c_dev {
+ 	struct mbox_chan *mbox_chan;
+ 	struct mbox_client mbox_client;
+ 	struct completion rd_complete;
+-	u8 dma_buffer[I2C_SMBUS_BLOCK_MAX];
++	u8 dma_buffer[I2C_SMBUS_BLOCK_MAX + 1]; /* dma_buffer[0] is used for length */
+ 	u32 *resp_msg;
+ };
+ 
+diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c
+index da3a02ef4a31..a9a9f66947e8 100644
+--- a/drivers/i2c/i2c-core.c
++++ b/drivers/i2c/i2c-core.c
+@@ -1592,6 +1592,7 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
+ static void of_i2c_register_devices(struct i2c_adapter *adap)
+ {
+ 	struct device_node *node;
++	struct i2c_client *client;
+ 
+ 	/* Only register child devices if the adapter has a node pointer set */
+ 	if (!adap->dev.of_node)
+@@ -1602,7 +1603,14 @@ static void of_i2c_register_devices(struct i2c_adapter *adap)
+ 	for_each_available_child_of_node(adap->dev.of_node, node) {
+ 		if (of_node_test_and_set_flag(node, OF_POPULATED))
+ 			continue;
+-		of_i2c_register_device(adap, node);
++
++		client = of_i2c_register_device(adap, node);
++		if (IS_ERR(client)) {
++			dev_warn(&adap->dev,
++				 "Failed to create I2C device for %s\n",
++				 node->full_name);
++			of_node_clear_flag(node, OF_POPULATED);
++		}
+ 	}
+ }
+ 
+@@ -2073,6 +2081,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
+ 	/* add the driver to the list of i2c drivers in the driver core */
+ 	driver->driver.owner = owner;
+ 	driver->driver.bus = &i2c_bus_type;
++	INIT_LIST_HEAD(&driver->clients);
+ 
+ 	/* When registration returns, the driver core
+ 	 * will have called probe() for all matching-but-unbound devices.
+@@ -2083,7 +2092,6 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
+ 
+ 	pr_debug("driver [%s] registered\n", driver->driver.name);
+ 
+-	INIT_LIST_HEAD(&driver->clients);
+ 	/* Walk the adapters that are already present */
+ 	i2c_for_each_dev(driver, __process_new_driver);
+ 
+@@ -2201,6 +2209,7 @@ static int of_i2c_notify(struct notifier_block *nb, unsigned long action,
+ 		if (IS_ERR(client)) {
+ 			dev_err(&adap->dev, "failed to create client for '%s'\n",
+ 				 rd->dn->full_name);
++			of_node_clear_flag(rd->dn, OF_POPULATED);
+ 			return notifier_from_errno(PTR_ERR(client));
+ 		}
+ 		break;
+diff --git a/drivers/iio/chemical/atlas-ph-sensor.c b/drivers/iio/chemical/atlas-ph-sensor.c
+index 407f141a1eee..a3fbdb761b5f 100644
+--- a/drivers/iio/chemical/atlas-ph-sensor.c
++++ b/drivers/iio/chemical/atlas-ph-sensor.c
+@@ -207,13 +207,14 @@ static int atlas_check_ec_calibration(struct atlas_data *data)
+ 	struct device *dev = &data->client->dev;
+ 	int ret;
+ 	unsigned int val;
++	__be16	rval;
+ 
+-	ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &val, 2);
++	ret = regmap_bulk_read(data->regmap, ATLAS_REG_EC_PROBE, &rval, 2);
+ 	if (ret)
+ 		return ret;
+ 
+-	dev_info(dev, "probe set to K = %d.%.2d", be16_to_cpu(val) / 100,
+-						 be16_to_cpu(val) % 100);
++	val = be16_to_cpu(rval);
++	dev_info(dev, "probe set to K = %d.%.2d", val / 100, val % 100);
+ 
+ 	ret = regmap_read(data->regmap, ATLAS_REG_EC_CALIB_STATUS, &val);
+ 	if (ret)
+diff --git a/drivers/input/serio/i8042-x86ia64io.h b/drivers/input/serio/i8042-x86ia64io.h
+index f4bfb4b2d50a..073246c7d163 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -877,6 +877,13 @@ static const struct dmi_system_id __initconst i8042_dmi_kbdreset_table[] = {
+ 			DMI_MATCH(DMI_PRODUCT_NAME, "P34"),
+ 		},
+ 	},
++	{
++		/* Schenker XMG C504 - Elantech touchpad */
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "XMG"),
++			DMI_MATCH(DMI_PRODUCT_NAME, "C504"),
++		},
++	},
+ 	{ }
+ };
+ 
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 8abde6b8cedc..6d53810963f7 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -266,7 +266,7 @@ static struct raid_type {
+ 	{"raid10_offset", "raid10 offset (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_OFFSET},
+ 	{"raid10_near",	  "raid10 near (striped mirrors)",	    0, 2, 10, ALGORITHM_RAID10_NEAR},
+ 	{"raid10",	  "raid10 (striped mirrors)",		    0, 2, 10, ALGORITHM_RAID10_DEFAULT},
+-	{"raid4",	  "raid4 (dedicated last parity disk)",	    1, 2, 4,  ALGORITHM_PARITY_N}, /* raid4 layout = raid5_n */
++	{"raid4",	  "raid4 (dedicated first parity disk)",    1, 2, 5,  ALGORITHM_PARITY_0}, /* raid4 layout = raid5_0 */
+ 	{"raid5_n",	  "raid5 (dedicated last parity disk)",	    1, 2, 5,  ALGORITHM_PARITY_N},
+ 	{"raid5_ls",	  "raid5 (left symmetric)",		    1, 2, 5,  ALGORITHM_LEFT_SYMMETRIC},
+ 	{"raid5_rs",	  "raid5 (right symmetric)",		    1, 2, 5,  ALGORITHM_RIGHT_SYMMETRIC},
+@@ -2087,11 +2087,11 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev)
+ 		/*
+ 		 * No takeover/reshaping, because we don't have the extended v1.9.0 metadata
+ 		 */
+-		if (le32_to_cpu(sb->level) != mddev->level) {
++		if (le32_to_cpu(sb->level) != mddev->new_level) {
+ 			DMERR("Reshaping/takeover raid sets not yet supported. (raid level/stripes/size change)");
+ 			return -EINVAL;
+ 		}
+-		if (le32_to_cpu(sb->layout) != mddev->layout) {
++		if (le32_to_cpu(sb->layout) != mddev->new_layout) {
+ 			DMERR("Reshaping raid sets not yet supported. (raid layout change)");
+ 			DMERR("	 0x%X vs 0x%X", le32_to_cpu(sb->layout), mddev->layout);
+ 			DMERR("	 Old layout: %s w/ %d copies",
+@@ -2102,7 +2102,7 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev)
+ 			      raid10_md_layout_to_copies(mddev->layout));
+ 			return -EINVAL;
+ 		}
+-		if (le32_to_cpu(sb->stripe_sectors) != mddev->chunk_sectors) {
++		if (le32_to_cpu(sb->stripe_sectors) != mddev->new_chunk_sectors) {
+ 			DMERR("Reshaping raid sets not yet supported. (stripe sectors change)");
+ 			return -EINVAL;
+ 		}
+@@ -2115,6 +2115,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev)
+ 			return -EINVAL;
+ 		}
+ 
++		DMINFO("Discovered old metadata format; upgrading to extended metadata format");
++
+ 		/* Table line is checked vs. authoritative superblock */
+ 		rs_set_new(rs);
+ 	}
+@@ -2258,7 +2260,8 @@ static int super_validate(struct raid_set *rs, struct md_rdev *rdev)
+ 	if (!mddev->events && super_init_validation(rs, rdev))
+ 		return -EINVAL;
+ 
+-	if (le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) {
++	if (le32_to_cpu(sb->compat_features) &&
++	    le32_to_cpu(sb->compat_features) != FEATURE_FLAG_SUPPORTS_V190) {
+ 		rs->ti->error = "Unable to assemble array: Unknown flag(s) in compatible feature flags";
+ 		return -EINVAL;
+ 	}
+@@ -3646,7 +3649,7 @@ static void raid_resume(struct dm_target *ti)
+ 
+ static struct target_type raid_target = {
+ 	.name = "raid",
+-	.version = {1, 9, 0},
++	.version = {1, 9, 1},
+ 	.module = THIS_MODULE,
+ 	.ctr = raid_ctr,
+ 	.dtr = raid_dtr,
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index bdf1606f67bc..7a6254d54baf 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1292,6 +1292,7 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
+ 
+ 			dm_bio_restore(bd, bio);
+ 			bio_record->details.bi_bdev = NULL;
++			bio->bi_error = 0;
+ 
+ 			queue_bio(ms, bio, rw);
+ 			return DM_ENDIO_INCOMPLETE;
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 5da86c8b6545..2154596eedf3 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -835,8 +835,11 @@ int dm_old_init_request_queue(struct mapped_device *md)
+ 	init_kthread_worker(&md->kworker);
+ 	md->kworker_task = kthread_run(kthread_worker_fn, &md->kworker,
+ 				       "kdmwork-%s", dm_device_name(md));
+-	if (IS_ERR(md->kworker_task))
+-		return PTR_ERR(md->kworker_task);
++	if (IS_ERR(md->kworker_task)) {
++		int error = PTR_ERR(md->kworker_task);
++		md->kworker_task = NULL;
++		return error;
++	}
+ 
+ 	elv_register_queue(md->queue);
+ 
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index 3e407a9cde1f..c4b53b332607 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -695,37 +695,32 @@ int dm_table_add_target(struct dm_table *t, const char *type,
+ 
+ 	tgt->type = dm_get_target_type(type);
+ 	if (!tgt->type) {
+-		DMERR("%s: %s: unknown target type", dm_device_name(t->md),
+-		      type);
++		DMERR("%s: %s: unknown target type", dm_device_name(t->md), type);
+ 		return -EINVAL;
+ 	}
+ 
+ 	if (dm_target_needs_singleton(tgt->type)) {
+ 		if (t->num_targets) {
+-			DMERR("%s: target type %s must appear alone in table",
+-			      dm_device_name(t->md), type);
+-			return -EINVAL;
++			tgt->error = "singleton target type must appear alone in table";
++			goto bad;
+ 		}
+ 		t->singleton = true;
+ 	}
+ 
+ 	if (dm_target_always_writeable(tgt->type) && !(t->mode & FMODE_WRITE)) {
+-		DMERR("%s: target type %s may not be included in read-only tables",
+-		      dm_device_name(t->md), type);
+-		return -EINVAL;
++		tgt->error = "target type may not be included in a read-only table";
++		goto bad;
+ 	}
+ 
+ 	if (t->immutable_target_type) {
+ 		if (t->immutable_target_type != tgt->type) {
+-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
+-			      dm_device_name(t->md), t->immutable_target_type->name);
+-			return -EINVAL;
++			tgt->error = "immutable target type cannot be mixed with other target types";
++			goto bad;
+ 		}
+ 	} else if (dm_target_is_immutable(tgt->type)) {
+ 		if (t->num_targets) {
+-			DMERR("%s: immutable target type %s cannot be mixed with other target types",
+-			      dm_device_name(t->md), tgt->type->name);
+-			return -EINVAL;
++			tgt->error = "immutable target type cannot be mixed with other target types";
++			goto bad;
+ 		}
+ 		t->immutable_target_type = tgt->type;
+ 	}
+@@ -740,7 +735,6 @@ int dm_table_add_target(struct dm_table *t, const char *type,
+ 	 */
+ 	if (!adjoin(t, tgt)) {
+ 		tgt->error = "Gap in table";
+-		r = -EINVAL;
+ 		goto bad;
+ 	}
+ 
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c
+index 0f2928b3136b..eeef575fb54b 100644
+--- a/drivers/md/dm.c
++++ b/drivers/md/dm.c
+@@ -1423,8 +1423,6 @@ static void cleanup_mapped_device(struct mapped_device *md)
+ 	if (md->bs)
+ 		bioset_free(md->bs);
+ 
+-	cleanup_srcu_struct(&md->io_barrier);
+-
+ 	if (md->disk) {
+ 		spin_lock(&_minor_lock);
+ 		md->disk->private_data = NULL;
+@@ -1436,6 +1434,8 @@ static void cleanup_mapped_device(struct mapped_device *md)
+ 	if (md->queue)
+ 		blk_cleanup_queue(md->queue);
+ 
++	cleanup_srcu_struct(&md->io_barrier);
++
+ 	if (md->bdev) {
+ 		bdput(md->bdev);
+ 		md->bdev = NULL;
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 915e84d631a2..db0aa6c058e7 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -8120,14 +8120,14 @@ void md_do_sync(struct md_thread *thread)
+ 
+ 	if (!test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery) &&
+ 	    !test_bit(MD_RECOVERY_INTR, &mddev->recovery) &&
+-	    mddev->curr_resync > 2) {
++	    mddev->curr_resync > 3) {
+ 		mddev->curr_resync_completed = mddev->curr_resync;
+ 		sysfs_notify(&mddev->kobj, NULL, "sync_completed");
+ 	}
+ 	mddev->pers->sync_request(mddev, max_sectors, &skipped);
+ 
+ 	if (!test_bit(MD_RECOVERY_CHECK, &mddev->recovery) &&
+-	    mddev->curr_resync > 2) {
++	    mddev->curr_resync > 3) {
+ 		if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
+ 			if (test_bit(MD_RECOVERY_INTR, &mddev->recovery)) {
+ 				if (mddev->curr_resync >= mddev->recovery_cp) {
+diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
+index 21dc00eb1989..95bf4cd8fcc0 100644
+--- a/drivers/md/raid1.c
++++ b/drivers/md/raid1.c
+@@ -407,11 +407,14 @@ static void raid1_end_write_request(struct bio *bio)
+ 	struct bio *to_put = NULL;
+ 	int mirror = find_bio_disk(r1_bio, bio);
+ 	struct md_rdev *rdev = conf->mirrors[mirror].rdev;
++	bool discard_error;
++
++	discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD;
+ 
+ 	/*
+ 	 * 'one mirror IO has finished' event handler:
+ 	 */
+-	if (bio->bi_error) {
++	if (bio->bi_error && !discard_error) {
+ 		set_bit(WriteErrorSeen,	&rdev->flags);
+ 		if (!test_and_set_bit(WantReplacement, &rdev->flags))
+ 			set_bit(MD_RECOVERY_NEEDED, &
+@@ -448,7 +451,7 @@ static void raid1_end_write_request(struct bio *bio)
+ 
+ 		/* Maybe we can clear some bad blocks. */
+ 		if (is_badblock(rdev, r1_bio->sector, r1_bio->sectors,
+-				&first_bad, &bad_sectors)) {
++				&first_bad, &bad_sectors) && !discard_error) {
+ 			r1_bio->bios[mirror] = IO_MADE_GOOD;
+ 			set_bit(R1BIO_MadeGood, &r1_bio->state);
+ 		}
+diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
+index be1a9fca3b2d..39fddda2fef2 100644
+--- a/drivers/md/raid10.c
++++ b/drivers/md/raid10.c
+@@ -447,6 +447,9 @@ static void raid10_end_write_request(struct bio *bio)
+ 	struct r10conf *conf = r10_bio->mddev->private;
+ 	int slot, repl;
+ 	struct md_rdev *rdev = NULL;
++	bool discard_error;
++
++	discard_error = bio->bi_error && bio_op(bio) == REQ_OP_DISCARD;
+ 
+ 	dev = find_bio_disk(conf, r10_bio, bio, &slot, &repl);
+ 
+@@ -460,7 +463,7 @@ static void raid10_end_write_request(struct bio *bio)
+ 	/*
+ 	 * this branch is our 'one mirror IO has finished' event handler:
+ 	 */
+-	if (bio->bi_error) {
++	if (bio->bi_error && !discard_error) {
+ 		if (repl)
+ 			/* Never record new bad blocks to replacement,
+ 			 * just fail it.
+@@ -503,7 +506,7 @@ static void raid10_end_write_request(struct bio *bio)
+ 		if (is_badblock(rdev,
+ 				r10_bio->devs[slot].addr,
+ 				r10_bio->sectors,
+-				&first_bad, &bad_sectors)) {
++				&first_bad, &bad_sectors) && !discard_error) {
+ 			bio_put(bio);
+ 			if (repl)
+ 				r10_bio->devs[slot].repl_bio = IO_MADE_GOOD;
+diff --git a/drivers/media/platform/vsp1/vsp1_video.c b/drivers/media/platform/vsp1/vsp1_video.c
+index 9fb4fc26a359..ed9759e8a6fc 100644
+--- a/drivers/media/platform/vsp1/vsp1_video.c
++++ b/drivers/media/platform/vsp1/vsp1_video.c
+@@ -675,6 +675,13 @@ static void vsp1_video_stop_streaming(struct vb2_queue *vq)
+ 	unsigned long flags;
+ 	int ret;
+ 
++	/* Clear the buffers ready flag to make sure the device won't be started
++	 * by a QBUF on the video node on the other side of the pipeline.
++	 */
++	spin_lock_irqsave(&video->irqlock, flags);
++	pipe->buffers_ready &= ~(1 << video->pipe_index);
++	spin_unlock_irqrestore(&video->irqlock, flags);
++
+ 	mutex_lock(&pipe->lock);
+ 	if (--pipe->stream_count == pipe->num_inputs) {
+ 		/* Stop the pipeline. */
+diff --git a/drivers/misc/cxl/api.c b/drivers/misc/cxl/api.c
+index af23d7dfe752..2e5233b60971 100644
+--- a/drivers/misc/cxl/api.c
++++ b/drivers/misc/cxl/api.c
+@@ -247,7 +247,9 @@ int cxl_start_context(struct cxl_context *ctx, u64 wed,
+ 	cxl_ctx_get();
+ 
+ 	if ((rc = cxl_ops->attach_process(ctx, kernel, wed, 0))) {
++		put_pid(ctx->glpid);
+ 		put_pid(ctx->pid);
++		ctx->glpid = ctx->pid = NULL;
+ 		cxl_adapter_context_put(ctx->afu->adapter);
+ 		cxl_ctx_put();
+ 		goto out;
+diff --git a/drivers/misc/cxl/file.c b/drivers/misc/cxl/file.c
+index d0b421f49b39..77080cc5fa0a 100644
+--- a/drivers/misc/cxl/file.c
++++ b/drivers/misc/cxl/file.c
+@@ -194,6 +194,16 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
+ 	ctx->mmio_err_ff = !!(work.flags & CXL_START_WORK_ERR_FF);
+ 
+ 	/*
++	 * Increment the mapped context count for adapter. This also checks
++	 * if adapter_context_lock is taken.
++	 */
++	rc = cxl_adapter_context_get(ctx->afu->adapter);
++	if (rc) {
++		afu_release_irqs(ctx, ctx);
++		goto out;
++	}
++
++	/*
+ 	 * We grab the PID here and not in the file open to allow for the case
+ 	 * where a process (master, some daemon, etc) has opened the chardev on
+ 	 * behalf of another process, so the AFU's mm gets bound to the process
+@@ -205,15 +215,6 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
+ 	ctx->pid = get_task_pid(current, PIDTYPE_PID);
+ 	ctx->glpid = get_task_pid(current->group_leader, PIDTYPE_PID);
+ 
+-	/*
+-	 * Increment the mapped context count for adapter. This also checks
+-	 * if adapter_context_lock is taken.
+-	 */
+-	rc = cxl_adapter_context_get(ctx->afu->adapter);
+-	if (rc) {
+-		afu_release_irqs(ctx, ctx);
+-		goto out;
+-	}
+ 
+ 	trace_cxl_attach(ctx, work.work_element_descriptor, work.num_interrupts, amr);
+ 
+@@ -221,6 +222,9 @@ static long afu_ioctl_start_work(struct cxl_context *ctx,
+ 							amr))) {
+ 		afu_release_irqs(ctx, ctx);
+ 		cxl_adapter_context_put(ctx->afu->adapter);
++		put_pid(ctx->glpid);
++		put_pid(ctx->pid);
++		ctx->glpid = ctx->pid = NULL;
+ 		goto out;
+ 	}
+ 
+diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
+index 222367cc8c81..524660510599 100644
+--- a/drivers/misc/genwqe/card_utils.c
++++ b/drivers/misc/genwqe/card_utils.c
+@@ -352,17 +352,27 @@ int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ 		if (copy_from_user(sgl->lpage, user_addr + user_size -
+ 				   sgl->lpage_size, sgl->lpage_size)) {
+ 			rc = -EFAULT;
+-			goto err_out1;
++			goto err_out2;
+ 		}
+ 	}
+ 	return 0;
+ 
++ err_out2:
++	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
++				 sgl->lpage_dma_addr);
++	sgl->lpage = NULL;
++	sgl->lpage_dma_addr = 0;
+  err_out1:
+ 	__genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+ 				 sgl->fpage_dma_addr);
++	sgl->fpage = NULL;
++	sgl->fpage_dma_addr = 0;
+  err_out:
+ 	__genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+ 				 sgl->sgl_dma_addr);
++	sgl->sgl = NULL;
++	sgl->sgl_dma_addr = 0;
++	sgl->sgl_size = 0;
+ 	return -ENOMEM;
+ }
+ 
+diff --git a/drivers/misc/mei/hw-txe.c b/drivers/misc/mei/hw-txe.c
+index 4a6c1b85f11e..2d23cdf8a734 100644
+--- a/drivers/misc/mei/hw-txe.c
++++ b/drivers/misc/mei/hw-txe.c
+@@ -978,11 +978,13 @@ static bool mei_txe_check_and_ack_intrs(struct mei_device *dev, bool do_ack)
+ 	hisr = mei_txe_br_reg_read(hw, HISR_REG);
+ 
+ 	aliveness = mei_txe_aliveness_get(dev);
+-	if (hhisr & IPC_HHIER_SEC && aliveness)
++	if (hhisr & IPC_HHIER_SEC && aliveness) {
+ 		ipc_isr = mei_txe_sec_reg_read_silent(hw,
+ 				SEC_IPC_HOST_INT_STATUS_REG);
+-	else
++	} else {
+ 		ipc_isr = 0;
++		hhisr &= ~IPC_HHIER_SEC;
++	}
+ 
+ 	generated = generated ||
+ 		(hisr & HISR_INT_STS_MSK) ||
+diff --git a/drivers/mmc/host/dw_mmc-pltfm.c b/drivers/mmc/host/dw_mmc-pltfm.c
+index c0bb0c793e84..dbbc4303bdd0 100644
+--- a/drivers/mmc/host/dw_mmc-pltfm.c
++++ b/drivers/mmc/host/dw_mmc-pltfm.c
+@@ -46,12 +46,13 @@ int dw_mci_pltfm_register(struct platform_device *pdev,
+ 	host->pdata = pdev->dev.platform_data;
+ 
+ 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+-	/* Get registers' physical base address */
+-	host->phy_regs = regs->start;
+ 	host->regs = devm_ioremap_resource(&pdev->dev, regs);
+ 	if (IS_ERR(host->regs))
+ 		return PTR_ERR(host->regs);
+ 
++	/* Get registers' physical base address */
++	host->phy_regs = regs->start;
++
+ 	platform_set_drvdata(pdev, host);
+ 	return dw_mci_probe(host);
+ }
+diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
+index 48eb55f344eb..a01a70a8fd3b 100644
+--- a/drivers/mtd/ubi/fastmap.c
++++ b/drivers/mtd/ubi/fastmap.c
+@@ -515,10 +515,11 @@ static int scan_pool(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ 			unsigned long long ec = be64_to_cpu(ech->ec);
+ 			unmap_peb(ai, pnum);
+ 			dbg_bld("Adding PEB to free: %i", pnum);
++
+ 			if (err == UBI_IO_FF_BITFLIPS)
+-				add_aeb(ai, free, pnum, ec, 1);
+-			else
+-				add_aeb(ai, free, pnum, ec, 0);
++				scrub = 1;
++
++			add_aeb(ai, free, pnum, ec, scrub);
+ 			continue;
+ 		} else if (err == 0 || err == UBI_IO_BITFLIPS) {
+ 			dbg_bld("Found non empty PEB:%i in pool", pnum);
+@@ -750,11 +751,11 @@ static int ubi_attach_fastmap(struct ubi_device *ubi,
+ 			     fmvhdr->vol_type,
+ 			     be32_to_cpu(fmvhdr->last_eb_bytes));
+ 
+-		if (!av)
+-			goto fail_bad;
+-		if (PTR_ERR(av) == -EINVAL) {
+-			ubi_err(ubi, "volume (ID %i) already exists",
+-				fmvhdr->vol_id);
++		if (IS_ERR(av)) {
++			if (PTR_ERR(av) == -EEXIST)
++				ubi_err(ubi, "volume (ID %i) already exists",
++					fmvhdr->vol_id);
++
+ 			goto fail_bad;
+ 		}
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h
+index 30ae5bf81611..76ad825a823d 100644
+--- a/drivers/net/wireless/ath/ath10k/core.h
++++ b/drivers/net/wireless/ath/ath10k/core.h
+@@ -445,6 +445,7 @@ struct ath10k_debug {
+ 	u32 pktlog_filter;
+ 	u32 reg_addr;
+ 	u32 nf_cal_period;
++	void *cal_data;
+ 
+ 	struct ath10k_fw_crash_data *fw_crash_data;
+ };
+diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
+index 8f0fd41dfd4b..8c6a5dd7e178 100644
+--- a/drivers/net/wireless/ath/ath10k/debug.c
++++ b/drivers/net/wireless/ath/ath10k/debug.c
+@@ -30,6 +30,8 @@
+ /* ms */
+ #define ATH10K_DEBUG_HTT_STATS_INTERVAL 1000
+ 
++#define ATH10K_DEBUG_CAL_DATA_LEN 12064
++
+ #define ATH10K_FW_CRASH_DUMP_VERSION 1
+ 
+ /**
+@@ -1450,56 +1452,51 @@ static const struct file_operations fops_fw_dbglog = {
+ 	.llseek = default_llseek,
+ };
+ 
+-static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
++static int ath10k_debug_cal_data_fetch(struct ath10k *ar)
+ {
+-	struct ath10k *ar = inode->i_private;
+-	void *buf;
+ 	u32 hi_addr;
+ 	__le32 addr;
+ 	int ret;
+ 
+-	mutex_lock(&ar->conf_mutex);
+-
+-	if (ar->state != ATH10K_STATE_ON &&
+-	    ar->state != ATH10K_STATE_UTF) {
+-		ret = -ENETDOWN;
+-		goto err;
+-	}
++	lockdep_assert_held(&ar->conf_mutex);
+ 
+-	buf = vmalloc(ar->hw_params.cal_data_len);
+-	if (!buf) {
+-		ret = -ENOMEM;
+-		goto err;
+-	}
++	if (WARN_ON(ar->hw_params.cal_data_len > ATH10K_DEBUG_CAL_DATA_LEN))
++		return -EINVAL;
+ 
+ 	hi_addr = host_interest_item_address(HI_ITEM(hi_board_data));
+ 
+ 	ret = ath10k_hif_diag_read(ar, hi_addr, &addr, sizeof(addr));
+ 	if (ret) {
+-		ath10k_warn(ar, "failed to read hi_board_data address: %d\n", ret);
+-		goto err_vfree;
++		ath10k_warn(ar, "failed to read hi_board_data address: %d\n",
++			    ret);
++		return ret;
+ 	}
+ 
+-	ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), buf,
++	ret = ath10k_hif_diag_read(ar, le32_to_cpu(addr), ar->debug.cal_data,
+ 				   ar->hw_params.cal_data_len);
+ 	if (ret) {
+ 		ath10k_warn(ar, "failed to read calibration data: %d\n", ret);
+-		goto err_vfree;
++		return ret;
+ 	}
+ 
+-	file->private_data = buf;
++	return 0;
++}
+ 
+-	mutex_unlock(&ar->conf_mutex);
++static int ath10k_debug_cal_data_open(struct inode *inode, struct file *file)
++{
++	struct ath10k *ar = inode->i_private;
+ 
+-	return 0;
++	mutex_lock(&ar->conf_mutex);
+ 
+-err_vfree:
+-	vfree(buf);
++	if (ar->state == ATH10K_STATE_ON ||
++	    ar->state == ATH10K_STATE_UTF) {
++		ath10k_debug_cal_data_fetch(ar);
++	}
+ 
+-err:
++	file->private_data = ar;
+ 	mutex_unlock(&ar->conf_mutex);
+ 
+-	return ret;
++	return 0;
+ }
+ 
+ static ssize_t ath10k_debug_cal_data_read(struct file *file,
+@@ -1507,18 +1504,16 @@ static ssize_t ath10k_debug_cal_data_read(struct file *file,
+ 					  size_t count, loff_t *ppos)
+ {
+ 	struct ath10k *ar = file->private_data;
+-	void *buf = file->private_data;
+ 
+-	return simple_read_from_buffer(user_buf, count, ppos,
+-				       buf, ar->hw_params.cal_data_len);
+-}
++	mutex_lock(&ar->conf_mutex);
+ 
+-static int ath10k_debug_cal_data_release(struct inode *inode,
+-					 struct file *file)
+-{
+-	vfree(file->private_data);
++	count = simple_read_from_buffer(user_buf, count, ppos,
++					ar->debug.cal_data,
++					ar->hw_params.cal_data_len);
+ 
+-	return 0;
++	mutex_unlock(&ar->conf_mutex);
++
++	return count;
+ }
+ 
+ static ssize_t ath10k_write_ani_enable(struct file *file,
+@@ -1579,7 +1574,6 @@ static const struct file_operations fops_ani_enable = {
+ static const struct file_operations fops_cal_data = {
+ 	.open = ath10k_debug_cal_data_open,
+ 	.read = ath10k_debug_cal_data_read,
+-	.release = ath10k_debug_cal_data_release,
+ 	.owner = THIS_MODULE,
+ 	.llseek = default_llseek,
+ };
+@@ -1931,6 +1925,8 @@ void ath10k_debug_stop(struct ath10k *ar)
+ {
+ 	lockdep_assert_held(&ar->conf_mutex);
+ 
++	ath10k_debug_cal_data_fetch(ar);
++
+ 	/* Must not use _sync to avoid deadlock, we do that in
+ 	 * ath10k_debug_destroy(). The check for htt_stats_mask is to avoid
+ 	 * warning from del_timer(). */
+@@ -2343,6 +2339,10 @@ int ath10k_debug_create(struct ath10k *ar)
+ 	if (!ar->debug.fw_crash_data)
+ 		return -ENOMEM;
+ 
++	ar->debug.cal_data = vzalloc(ATH10K_DEBUG_CAL_DATA_LEN);
++	if (!ar->debug.cal_data)
++		return -ENOMEM;
++
+ 	INIT_LIST_HEAD(&ar->debug.fw_stats.pdevs);
+ 	INIT_LIST_HEAD(&ar->debug.fw_stats.vdevs);
+ 	INIT_LIST_HEAD(&ar->debug.fw_stats.peers);
+@@ -2356,6 +2356,9 @@ void ath10k_debug_destroy(struct ath10k *ar)
+ 	vfree(ar->debug.fw_crash_data);
+ 	ar->debug.fw_crash_data = NULL;
+ 
++	vfree(ar->debug.cal_data);
++	ar->debug.cal_data = NULL;
++
+ 	ath10k_debug_fw_stats_reset(ar);
+ 
+ 	kfree(ar->debug.tpc_stats);
+diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+index b6f064a8d264..7e27a06e5df1 100644
+--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
++++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+@@ -33,7 +33,6 @@ struct coeff {
+ 
+ enum ar9003_cal_types {
+ 	IQ_MISMATCH_CAL = BIT(0),
+-	TEMP_COMP_CAL = BIT(1),
+ };
+ 
+ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
+@@ -59,12 +58,6 @@ static void ar9003_hw_setup_calibration(struct ath_hw *ah,
+ 		/* Kick-off cal */
+ 		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
+ 		break;
+-	case TEMP_COMP_CAL:
+-		ath_dbg(common, CALIBRATE,
+-			"starting Temperature Compensation Calibration\n");
+-		REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_LOCAL);
+-		REG_SET_BIT(ah, AR_CH0_THERM, AR_CH0_THERM_START);
+-		break;
+ 	default:
+ 		ath_err(common, "Invalid calibration type\n");
+ 		break;
+@@ -93,8 +86,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
+ 		/*
+ 		* Accumulate cal measures for active chains
+ 		*/
+-		if (cur_caldata->calCollect)
+-			cur_caldata->calCollect(ah);
++		cur_caldata->calCollect(ah);
+ 		ah->cal_samples++;
+ 
+ 		if (ah->cal_samples >= cur_caldata->calNumSamples) {
+@@ -107,8 +99,7 @@ static bool ar9003_hw_per_calibration(struct ath_hw *ah,
+ 			/*
+ 			* Process accumulated data
+ 			*/
+-			if (cur_caldata->calPostProc)
+-				cur_caldata->calPostProc(ah, numChains);
++			cur_caldata->calPostProc(ah, numChains);
+ 
+ 			/* Calibration has finished. */
+ 			caldata->CalValid |= cur_caldata->calType;
+@@ -323,16 +314,9 @@ static const struct ath9k_percal_data iq_cal_single_sample = {
+ 	ar9003_hw_iqcalibrate
+ };
+ 
+-static const struct ath9k_percal_data temp_cal_single_sample = {
+-	TEMP_COMP_CAL,
+-	MIN_CAL_SAMPLES,
+-	PER_MAX_LOG_COUNT,
+-};
+-
+ static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
+ {
+ 	ah->iq_caldata.calData = &iq_cal_single_sample;
+-	ah->temp_caldata.calData = &temp_cal_single_sample;
+ 
+ 	if (AR_SREV_9300_20_OR_LATER(ah)) {
+ 		ah->enabled_cals |= TX_IQ_CAL;
+@@ -340,7 +324,7 @@ static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
+ 			ah->enabled_cals |= TX_IQ_ON_AGC_CAL;
+ 	}
+ 
+-	ah->supp_cals = IQ_MISMATCH_CAL | TEMP_COMP_CAL;
++	ah->supp_cals = IQ_MISMATCH_CAL;
+ }
+ 
+ #define OFF_UPPER_LT 24
+@@ -1399,9 +1383,6 @@ static void ar9003_hw_init_cal_common(struct ath_hw *ah)
+ 	INIT_CAL(&ah->iq_caldata);
+ 	INSERT_CAL(ah, &ah->iq_caldata);
+ 
+-	INIT_CAL(&ah->temp_caldata);
+-	INSERT_CAL(ah, &ah->temp_caldata);
+-
+ 	/* Initialize current pointer to first element in list */
+ 	ah->cal_list_curr = ah->cal_list;
+ 
+diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
+index 2a5d3ad1169c..9cbca1229bac 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.h
++++ b/drivers/net/wireless/ath/ath9k/hw.h
+@@ -830,7 +830,6 @@ struct ath_hw {
+ 	/* Calibration */
+ 	u32 supp_cals;
+ 	struct ath9k_cal_list iq_caldata;
+-	struct ath9k_cal_list temp_caldata;
+ 	struct ath9k_cal_list adcgain_caldata;
+ 	struct ath9k_cal_list adcdc_caldata;
+ 	struct ath9k_cal_list *cal_list;
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+index 4341d56805f8..a28093235ee0 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu.h
+@@ -231,7 +231,7 @@ struct rtl8xxxu_rxdesc16 {
+ 	u32 pattern1match:1;
+ 	u32 pattern0match:1;
+ #endif
+-	__le32 tsfl;
++	u32 tsfl;
+ #if 0
+ 	u32 bassn:12;
+ 	u32 bavld:1;
+@@ -361,7 +361,7 @@ struct rtl8xxxu_rxdesc24 {
+ 	u32 ldcp:1;
+ 	u32 splcp:1;
+ #endif
+-	__le32 tsfl;
++	u32 tsfl;
+ };
+ 
+ struct rtl8xxxu_txdesc32 {
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
+index 9d45afb0e3fd..c831a586766c 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_8723b.c
+@@ -1498,6 +1498,10 @@ static void rtl8723b_enable_rf(struct rtl8xxxu_priv *priv)
+ 	u32 val32;
+ 	u8 val8;
+ 
++	val32 = rtl8xxxu_read32(priv, REG_RX_WAIT_CCA);
++	val32 |= (BIT(22) | BIT(23));
++	rtl8xxxu_write32(priv, REG_RX_WAIT_CCA, val32);
++
+ 	/*
+ 	 * No indication anywhere as to what 0x0790 does. The 2 antenna
+ 	 * vendor code preserves bits 6-7 here.
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index 77048db3b32a..c6b246aa2419 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -5201,7 +5201,12 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
+ 		pkt_offset = roundup(pkt_len + drvinfo_sz + desc_shift +
+ 				     sizeof(struct rtl8xxxu_rxdesc16), 128);
+ 
+-		if (pkt_cnt > 1)
++		/*
++		 * Only clone the skb if there's enough data at the end to
++		 * at least cover the rx descriptor
++		 */
++		if (pkt_cnt > 1 &&
++		    urb_len > (pkt_offset + sizeof(struct rtl8xxxu_rxdesc16)))
+ 			next_skb = skb_clone(skb, GFP_ATOMIC);
+ 
+ 		rx_status = IEEE80211_SKB_RXCB(skb);
+@@ -5219,7 +5224,7 @@ int rtl8xxxu_parse_rxdesc16(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
+ 			rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
+ 						   rx_desc->rxmcs);
+ 
+-		rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
++		rx_status->mactime = rx_desc->tsfl;
+ 		rx_status->flag |= RX_FLAG_MACTIME_START;
+ 
+ 		if (!rx_desc->swdec)
+@@ -5289,7 +5294,7 @@ int rtl8xxxu_parse_rxdesc24(struct rtl8xxxu_priv *priv, struct sk_buff *skb)
+ 		rtl8xxxu_rx_parse_phystats(priv, rx_status, phy_stats,
+ 					   rx_desc->rxmcs);
+ 
+-	rx_status->mactime = le32_to_cpu(rx_desc->tsfl);
++	rx_status->mactime = rx_desc->tsfl;
+ 	rx_status->flag |= RX_FLAG_MACTIME_START;
+ 
+ 	if (!rx_desc->swdec)
+diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c
+index 0dbd29e287db..172ef8245811 100644
+--- a/drivers/pwm/core.c
++++ b/drivers/pwm/core.c
+@@ -339,6 +339,8 @@ int pwmchip_remove(struct pwm_chip *chip)
+ 	unsigned int i;
+ 	int ret = 0;
+ 
++	pwmchip_sysfs_unexport_children(chip);
++
+ 	mutex_lock(&pwm_lock);
+ 
+ 	for (i = 0; i < chip->npwm; i++) {
+diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
+index 18ed725594c3..0296d8178ae2 100644
+--- a/drivers/pwm/sysfs.c
++++ b/drivers/pwm/sysfs.c
+@@ -409,6 +409,24 @@ void pwmchip_sysfs_unexport(struct pwm_chip *chip)
+ 	}
+ }
+ 
++void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
++{
++	struct device *parent;
++	unsigned int i;
++
++	parent = class_find_device(&pwm_class, NULL, chip,
++				   pwmchip_sysfs_match);
++	if (!parent)
++		return;
++
++	for (i = 0; i < chip->npwm; i++) {
++		struct pwm_device *pwm = &chip->pwms[i];
++
++		if (test_bit(PWMF_EXPORTED, &pwm->flags))
++			pwm_unexport_child(parent, pwm);
++	}
++}
++
+ static int __init pwm_sysfs_init(void)
+ {
+ 	return class_register(&pwm_class);
+diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
+index 3d53d636b17b..f0cfb0451757 100644
+--- a/drivers/scsi/arcmsr/arcmsr_hba.c
++++ b/drivers/scsi/arcmsr/arcmsr_hba.c
+@@ -2636,18 +2636,9 @@ static int arcmsr_queue_command_lck(struct scsi_cmnd *cmd,
+ 	struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata;
+ 	struct CommandControlBlock *ccb;
+ 	int target = cmd->device->id;
+-	int lun = cmd->device->lun;
+-	uint8_t scsicmd = cmd->cmnd[0];
+ 	cmd->scsi_done = done;
+ 	cmd->host_scribble = NULL;
+ 	cmd->result = 0;
+-	if ((scsicmd == SYNCHRONIZE_CACHE) ||(scsicmd == SEND_DIAGNOSTIC)){
+-		if(acb->devstate[target][lun] == ARECA_RAID_GONE) {
+-    			cmd->result = (DID_NO_CONNECT << 16);
+-		}
+-		cmd->scsi_done(cmd);
+-		return 0;
+-	}
+ 	if (target == 16) {
+ 		/* virtual device for iop message transfer */
+ 		arcmsr_handle_virtual_command(acb, cmd);
+diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
+index 6a219a0844d3..05e892a231a5 100644
+--- a/drivers/scsi/scsi_debug.c
++++ b/drivers/scsi/scsi_debug.c
+@@ -5134,6 +5134,7 @@ static void __exit scsi_debug_exit(void)
+ 	bus_unregister(&pseudo_lld_bus);
+ 	root_device_unregister(pseudo_primary);
+ 
++	vfree(map_storep);
+ 	vfree(dif_storep);
+ 	vfree(fake_storep);
+ 	kfree(sdebug_q_arr);
+diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
+index 8d85a3c343da..3f3561371410 100644
+--- a/drivers/spi/spi-fsl-espi.c
++++ b/drivers/spi/spi-fsl-espi.c
+@@ -581,7 +581,7 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events)
+ 
+ 		mspi->len -= rx_nr_bytes;
+ 
+-		if (mspi->rx)
++		if (rx_nr_bytes && mspi->rx)
+ 			mspi->get_rx(rx_data, mspi);
+ 	}
+ 
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
+index 200ca228d885..935f1a511856 100644
+--- a/drivers/spi/spi.c
++++ b/drivers/spi/spi.c
+@@ -1607,9 +1607,11 @@ static void of_register_spi_devices(struct spi_master *master)
+ 		if (of_node_test_and_set_flag(nc, OF_POPULATED))
+ 			continue;
+ 		spi = of_register_spi_device(master, nc);
+-		if (IS_ERR(spi))
++		if (IS_ERR(spi)) {
+ 			dev_warn(&master->dev, "Failed to create SPI device for %s\n",
+ 				nc->full_name);
++			of_node_clear_flag(nc, OF_POPULATED);
++		}
+ 	}
+ }
+ #else
+@@ -3120,6 +3122,7 @@ static int of_spi_notify(struct notifier_block *nb, unsigned long action,
+ 		if (IS_ERR(spi)) {
+ 			pr_err("%s: failed to create for '%s'\n",
+ 					__func__, rd->dn->full_name);
++			of_node_clear_flag(rd->dn, OF_POPULATED);
+ 			return notifier_from_errno(PTR_ERR(spi));
+ 		}
+ 		break;
+diff --git a/drivers/staging/wilc1000/host_interface.c b/drivers/staging/wilc1000/host_interface.c
+index 78f524fcd214..f4dbcb19d7c5 100644
+--- a/drivers/staging/wilc1000/host_interface.c
++++ b/drivers/staging/wilc1000/host_interface.c
+@@ -3391,7 +3391,6 @@ int wilc_init(struct net_device *dev, struct host_if_drv **hif_drv_handler)
+ 
+ 	clients_count++;
+ 
+-	destroy_workqueue(hif_workqueue);
+ _fail_:
+ 	return result;
+ }
+diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
+index 0e4dc0afcfd2..7a223074df3d 100644
+--- a/drivers/thermal/intel_powerclamp.c
++++ b/drivers/thermal/intel_powerclamp.c
+@@ -669,20 +669,10 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = {
+ 	.set_cur_state = powerclamp_set_cur_state,
+ };
+ 
+-static const struct x86_cpu_id intel_powerclamp_ids[] __initconst = {
+-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_MWAIT },
+-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_ARAT },
+-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_NONSTOP_TSC },
+-	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_CONSTANT_TSC},
+-	{}
+-};
+-MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
+-
+ static int __init powerclamp_probe(void)
+ {
+-	if (!x86_match_cpu(intel_powerclamp_ids)) {
+-		pr_err("Intel powerclamp does not run on family %d model %d\n",
+-				boot_cpu_data.x86, boot_cpu_data.x86_model);
++	if (!boot_cpu_has(X86_FEATURE_MWAIT)) {
++		pr_err("CPU does not support MWAIT");
+ 		return -ENODEV;
+ 	}
+ 
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 2705ca960e92..fd375f15bbbd 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -870,10 +870,15 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
+ 	if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
+ 		return 0;
+ 
++	if (new_screen_size > (4 << 20))
++		return -EINVAL;
+ 	newscreen = kmalloc(new_screen_size, GFP_USER);
+ 	if (!newscreen)
+ 		return -ENOMEM;
+ 
++	if (vc == sel_cons)
++		clear_selection();
++
+ 	old_rows = vc->vc_rows;
+ 	old_row_size = vc->vc_size_row;
+ 
+@@ -1176,7 +1181,7 @@ static void csi_J(struct vc_data *vc, int vpar)
+ 			break;
+ 		case 3: /* erase scroll-back buffer (and whole display) */
+ 			scr_memsetw(vc->vc_screenbuf, vc->vc_video_erase_char,
+-				    vc->vc_screenbuf_size >> 1);
++				    vc->vc_screenbuf_size);
+ 			set_origin(vc);
+ 			if (con_is_visible(vc))
+ 				update_screen(vc);
+diff --git a/drivers/usb/chipidea/host.c b/drivers/usb/chipidea/host.c
+index 053bac9d983c..887be343fcd4 100644
+--- a/drivers/usb/chipidea/host.c
++++ b/drivers/usb/chipidea/host.c
+@@ -185,6 +185,8 @@ static void host_stop(struct ci_hdrc *ci)
+ 
+ 	if (hcd) {
+ 		usb_remove_hcd(hcd);
++		ci->role = CI_ROLE_END;
++		synchronize_irq(ci->irq);
+ 		usb_put_hcd(hcd);
+ 		if (ci->platdata->reg_vbus && !ci_otg_is_fsm_mode(ci) &&
+ 			(ci->platdata->flags & CI_HDRC_TURN_VBUS_EARLY_ON))
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 68544618982e..6443cfba7b55 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -3055,7 +3055,7 @@ err3:
+ 	kfree(dwc->setup_buf);
+ 
+ err2:
+-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
++	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+ 			dwc->ep0_trb, dwc->ep0_trb_addr);
+ 
+ err1:
+@@ -3080,7 +3080,7 @@ void dwc3_gadget_exit(struct dwc3 *dwc)
+ 	kfree(dwc->setup_buf);
+ 	kfree(dwc->zlp_buf);
+ 
+-	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb),
++	dma_free_coherent(dwc->dev, sizeof(*dwc->ep0_trb) * 2,
+ 			dwc->ep0_trb, dwc->ep0_trb_addr);
+ 
+ 	dma_free_coherent(dwc->dev, sizeof(*dwc->ctrl_req),
+diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
+index 5f562c1ec795..9b9e71f2c66e 100644
+--- a/drivers/usb/gadget/function/u_ether.c
++++ b/drivers/usb/gadget/function/u_ether.c
+@@ -587,8 +587,9 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
+ 
+ 	/* throttle high/super speed IRQ rate back slightly */
+ 	if (gadget_is_dualspeed(dev->gadget))
+-		req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH ||
+-				     dev->gadget->speed == USB_SPEED_SUPER)
++		req->no_interrupt = (((dev->gadget->speed == USB_SPEED_HIGH ||
++				       dev->gadget->speed == USB_SPEED_SUPER)) &&
++					!list_empty(&dev->tx_reqs))
+ 			? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
+ 			: 0;
+ 
+diff --git a/drivers/usb/gadget/udc/atmel_usba_udc.c b/drivers/usb/gadget/udc/atmel_usba_udc.c
+index bb1f6c8f0f01..45bc997d0711 100644
+--- a/drivers/usb/gadget/udc/atmel_usba_udc.c
++++ b/drivers/usb/gadget/udc/atmel_usba_udc.c
+@@ -1978,7 +1978,7 @@ static struct usba_ep * atmel_udc_of_init(struct platform_device *pdev,
+ 			dev_err(&pdev->dev, "of_probe: name error(%d)\n", ret);
+ 			goto err;
+ 		}
+-		ep->ep.name = name;
++		ep->ep.name = kasprintf(GFP_KERNEL, "ep%d", ep->index);
+ 
+ 		ep->ep_regs = udc->regs + USBA_EPT_BASE(i);
+ 		ep->dma_regs = udc->regs + USBA_DMA_BASE(i);
+diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
+index 1700908b84ef..86612ac3fda2 100644
+--- a/drivers/usb/host/ohci-hcd.c
++++ b/drivers/usb/host/ohci-hcd.c
+@@ -72,7 +72,7 @@
+ static const char	hcd_name [] = "ohci_hcd";
+ 
+ #define	STATECHANGE_DELAY	msecs_to_jiffies(300)
+-#define	IO_WATCHDOG_DELAY	msecs_to_jiffies(250)
++#define	IO_WATCHDOG_DELAY	msecs_to_jiffies(275)
+ 
+ #include "ohci.h"
+ #include "pci-quirks.h"
+diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
+index 730b9fd26685..0ef16900efed 100644
+--- a/drivers/usb/host/xhci-hub.c
++++ b/drivers/usb/host/xhci-hub.c
+@@ -1166,7 +1166,7 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
+ 				xhci_set_link_state(xhci, port_array, wIndex,
+ 							XDEV_RESUME);
+ 				spin_unlock_irqrestore(&xhci->lock, flags);
+-				msleep(20);
++				msleep(USB_RESUME_TIMEOUT);
+ 				spin_lock_irqsave(&xhci->lock, flags);
+ 				xhci_set_link_state(xhci, port_array, wIndex,
+ 							XDEV_U0);
+@@ -1355,6 +1355,35 @@ int xhci_bus_suspend(struct usb_hcd *hcd)
+ 	return 0;
+ }
+ 
++/*
++ * Workaround for missing Cold Attach Status (CAS) if device re-plugged in S3.
++ * warm reset a USB3 device stuck in polling or compliance mode after resume.
++ * See Intel 100/c230 series PCH specification update Doc #332692-006 Errata #8
++ */
++static bool xhci_port_missing_cas_quirk(int port_index,
++					     __le32 __iomem **port_array)
++{
++	u32 portsc;
++
++	portsc = readl(port_array[port_index]);
++
++	/* if any of these are set we are not stuck */
++	if (portsc & (PORT_CONNECT | PORT_CAS))
++		return false;
++
++	if (((portsc & PORT_PLS_MASK) != XDEV_POLLING) &&
++	    ((portsc & PORT_PLS_MASK) != XDEV_COMP_MODE))
++		return false;
++
++	/* clear wakeup/change bits, and do a warm port reset */
++	portsc &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
++	portsc |= PORT_WR;
++	writel(portsc, port_array[port_index]);
++	/* flush write */
++	readl(port_array[port_index]);
++	return true;
++}
++
+ int xhci_bus_resume(struct usb_hcd *hcd)
+ {
+ 	struct xhci_hcd	*xhci = hcd_to_xhci(hcd);
+@@ -1392,6 +1421,14 @@ int xhci_bus_resume(struct usb_hcd *hcd)
+ 		u32 temp;
+ 
+ 		temp = readl(port_array[port_index]);
++
++		/* warm reset CAS limited ports stuck in polling/compliance */
++		if ((xhci->quirks & XHCI_MISSING_CAS) &&
++		    (hcd->speed >= HCD_USB3) &&
++		    xhci_port_missing_cas_quirk(port_index, port_array)) {
++			xhci_dbg(xhci, "reset stuck port %d\n", port_index);
++			continue;
++		}
+ 		if (DEV_SUPERSPEED_ANY(temp))
+ 			temp &= ~(PORT_RWC_BITS | PORT_CEC | PORT_WAKE_BITS);
+ 		else
+@@ -1410,7 +1447,7 @@ int xhci_bus_resume(struct usb_hcd *hcd)
+ 
+ 	if (need_usb2_u3_exit) {
+ 		spin_unlock_irqrestore(&xhci->lock, flags);
+-		msleep(20);
++		msleep(USB_RESUME_TIMEOUT);
+ 		spin_lock_irqsave(&xhci->lock, flags);
+ 	}
+ 
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index d7b0f97abbad..e96ae80d107e 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -45,11 +45,13 @@
+ 
+ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_XHCI	0x8c31
+ #define PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI	0x9c31
++#define PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI	0x9cb1
+ #define PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI		0x22b5
+ #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_H_XHCI		0xa12f
+ #define PCI_DEVICE_ID_INTEL_SUNRISEPOINT_LP_XHCI	0x9d2f
+ #define PCI_DEVICE_ID_INTEL_BROXTON_M_XHCI		0x0aa8
+ #define PCI_DEVICE_ID_INTEL_BROXTON_B_XHCI		0x1aa8
++#define PCI_DEVICE_ID_INTEL_APL_XHCI			0x5aa8
+ 
+ static const char hcd_name[] = "xhci_hcd";
+ 
+@@ -153,7 +155,8 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
+ 	}
+ 	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
+-		pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI) {
++		(pdev->device == PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_XHCI ||
++		 pdev->device == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_XHCI)) {
+ 		xhci->quirks |= XHCI_SPURIOUS_REBOOT;
+ 		xhci->quirks |= XHCI_SPURIOUS_WAKEUP;
+ 	}
+@@ -169,6 +172,11 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 		 pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI) {
+ 		xhci->quirks |= XHCI_SSIC_PORT_UNUSED;
+ 	}
++	if (pdev->vendor == PCI_VENDOR_ID_INTEL &&
++	    (pdev->device == PCI_DEVICE_ID_INTEL_CHERRYVIEW_XHCI ||
++	     pdev->device == PCI_DEVICE_ID_INTEL_APL_XHCI))
++		xhci->quirks |= XHCI_MISSING_CAS;
++
+ 	if (pdev->vendor == PCI_VENDOR_ID_ETRON &&
+ 			pdev->device == PCI_DEVICE_ID_EJ168) {
+ 		xhci->quirks |= XHCI_RESET_ON_RESUME;
+diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
+index b2c1dc5dc0f3..f945380035d0 100644
+--- a/drivers/usb/host/xhci.h
++++ b/drivers/usb/host/xhci.h
+@@ -314,6 +314,8 @@ struct xhci_op_regs {
+ #define XDEV_U2		(0x2 << 5)
+ #define XDEV_U3		(0x3 << 5)
+ #define XDEV_INACTIVE	(0x6 << 5)
++#define XDEV_POLLING	(0x7 << 5)
++#define XDEV_COMP_MODE  (0xa << 5)
+ #define XDEV_RESUME	(0xf << 5)
+ /* true: port has power (see HCC_PPC) */
+ #define PORT_POWER	(1 << 9)
+@@ -1653,6 +1655,7 @@ struct xhci_hcd {
+ #define XHCI_MTK_HOST		(1 << 21)
+ #define XHCI_SSIC_PORT_UNUSED	(1 << 22)
+ #define XHCI_NO_64BIT_SUPPORT	(1 << 23)
++#define XHCI_MISSING_CAS	(1 << 24)
+ 	unsigned int		num_active_eps;
+ 	unsigned int		limit_active_eps;
+ 	/* There are two roothubs to keep track of bus suspend info for */
+diff --git a/drivers/usb/musb/omap2430.c b/drivers/usb/musb/omap2430.c
+index 0b4cec940386..dae92de92592 100644
+--- a/drivers/usb/musb/omap2430.c
++++ b/drivers/usb/musb/omap2430.c
+@@ -337,6 +337,7 @@ static int omap2430_musb_init(struct musb *musb)
+ 	}
+ 	musb->isr = omap2430_musb_interrupt;
+ 	phy_init(musb->phy);
++	phy_power_on(musb->phy);
+ 
+ 	l = musb_readl(musb->mregs, OTG_INTERFSEL);
+ 
+@@ -373,8 +374,6 @@ static void omap2430_musb_enable(struct musb *musb)
+ 	struct musb_hdrc_platform_data *pdata = dev_get_platdata(dev);
+ 	struct omap_musb_board_data *data = pdata->board_data;
+ 
+-	if (!WARN_ON(!musb->phy))
+-		phy_power_on(musb->phy);
+ 
+ 	omap2430_set_power(musb, true, glue->cable_connected);
+ 
+@@ -413,9 +412,6 @@ static void omap2430_musb_disable(struct musb *musb)
+ 	struct device *dev = musb->controller;
+ 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+ 
+-	if (!WARN_ON(!musb->phy))
+-		phy_power_off(musb->phy);
+-
+ 	if (glue->status != MUSB_UNKNOWN)
+ 		omap_control_usb_set_mode(glue->control_otghs,
+ 			USB_MODE_DISCONNECT);
+@@ -429,6 +425,7 @@ static int omap2430_musb_exit(struct musb *musb)
+ 	struct omap2430_glue *glue = dev_get_drvdata(dev->parent);
+ 
+ 	omap2430_low_level_exit(musb);
++	phy_power_off(musb->phy);
+ 	phy_exit(musb->phy);
+ 	musb->phy = NULL;
+ 	cancel_work_sync(&glue->omap_musb_mailbox_work);
+diff --git a/drivers/usb/renesas_usbhs/rcar3.c b/drivers/usb/renesas_usbhs/rcar3.c
+index 1d70add926f0..d544b331c9f2 100644
+--- a/drivers/usb/renesas_usbhs/rcar3.c
++++ b/drivers/usb/renesas_usbhs/rcar3.c
+@@ -9,6 +9,7 @@
+  *
+  */
+ 
++#include <linux/delay.h>
+ #include <linux/io.h>
+ #include "common.h"
+ #include "rcar3.h"
+@@ -35,10 +36,13 @@ static int usbhs_rcar3_power_ctrl(struct platform_device *pdev,
+ 
+ 	usbhs_write32(priv, UGCTRL2, UGCTRL2_RESERVED_3 | UGCTRL2_USB0SEL_OTG);
+ 
+-	if (enable)
++	if (enable) {
+ 		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, LPSTS_SUSPM);
+-	else
++		/* The controller on R-Car Gen3 needs to wait up to 45 usec */
++		udelay(45);
++	} else {
+ 		usbhs_bset(priv, LPSTS, LPSTS_SUSPM, 0);
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 54a4de0efdba..f61477bed3a8 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -1077,7 +1077,9 @@ static int cp210x_tiocmget(struct tty_struct *tty)
+ 	u8 control;
+ 	int result;
+ 
+-	cp210x_read_u8_reg(port, CP210X_GET_MDMSTS, &control);
++	result = cp210x_read_u8_reg(port, CP210X_GET_MDMSTS, &control);
++	if (result)
++		return result;
+ 
+ 	result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0)
+ 		|((control & CONTROL_RTS) ? TIOCM_RTS : 0)
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index b2d767e743fc..0ff7f38d7800 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -986,7 +986,8 @@ static const struct usb_device_id id_table_combined[] = {
+ 	/* ekey Devices */
+ 	{ USB_DEVICE(FTDI_VID, FTDI_EKEY_CONV_USB_PID) },
+ 	/* Infineon Devices */
+-	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_PID, 1) },
++	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC1798_PID, 1) },
++	{ USB_DEVICE_INTERFACE_NUMBER(INFINEON_VID, INFINEON_TRIBOARD_TC2X7_PID, 1) },
+ 	/* GE Healthcare devices */
+ 	{ USB_DEVICE(GE_HEALTHCARE_VID, GE_HEALTHCARE_NEMO_TRACKER_PID) },
+ 	/* Active Research (Actisense) devices */
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index f87a938cf005..21011c0a4c64 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -626,8 +626,9 @@
+ /*
+  * Infineon Technologies
+  */
+-#define INFINEON_VID		0x058b
+-#define INFINEON_TRIBOARD_PID	0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */
++#define INFINEON_VID		        0x058b
++#define INFINEON_TRIBOARD_TC1798_PID	0x0028 /* DAS JTAG TriBoard TC1798 V1.0 */
++#define INFINEON_TRIBOARD_TC2X7_PID	0x0043 /* DAS JTAG TriBoard TC2X7 V1.0 */
+ 
+ /*
+  * Acton Research Corp.
+diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
+index d213cf44a7e4..4a037b4a79cf 100644
+--- a/drivers/usb/serial/usb-serial.c
++++ b/drivers/usb/serial/usb-serial.c
+@@ -1078,7 +1078,8 @@ static int usb_serial_probe(struct usb_interface *interface,
+ 
+ 	serial->disconnected = 0;
+ 
+-	usb_serial_console_init(serial->port[0]->minor);
++	if (num_ports > 0)
++		usb_serial_console_init(serial->port[0]->minor);
+ exit:
+ 	module_put(type->driver.owner);
+ 	return 0;
+diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+index 9e4800a4e3d1..951dd93f89b2 100644
+--- a/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
++++ b/drivers/video/fbdev/omap2/omapfb/dss/dsi.c
+@@ -5348,7 +5348,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
+ 
+ 	dsi->phy_base = devm_ioremap(&dsidev->dev, res->start,
+ 		resource_size(res));
+-	if (!dsi->proto_base) {
++	if (!dsi->phy_base) {
+ 		DSSERR("can't ioremap DSI PHY\n");
+ 		return -ENOMEM;
+ 	}
+@@ -5368,7 +5368,7 @@ static int dsi_bind(struct device *dev, struct device *master, void *data)
+ 
+ 	dsi->pll_base = devm_ioremap(&dsidev->dev, res->start,
+ 		resource_size(res));
+-	if (!dsi->proto_base) {
++	if (!dsi->pll_base) {
+ 		DSSERR("can't ioremap DSI PLL\n");
+ 		return -ENOMEM;
+ 	}
+diff --git a/drivers/video/fbdev/pxafb.c b/drivers/video/fbdev/pxafb.c
+index 2c0487f4f805..ed41fdb42d13 100644
+--- a/drivers/video/fbdev/pxafb.c
++++ b/drivers/video/fbdev/pxafb.c
+@@ -2125,7 +2125,7 @@ static int of_get_pxafb_display(struct device *dev, struct device_node *disp,
+ 
+ 	timings = of_get_display_timings(disp);
+ 	if (!timings)
+-		goto out;
++		return -EINVAL;
+ 
+ 	ret = -ENOMEM;
+ 	info->modes = kmalloc_array(timings->num_timings,
+diff --git a/drivers/virtio/virtio_pci_legacy.c b/drivers/virtio/virtio_pci_legacy.c
+index 8c4e61783441..6d9e5173d5fa 100644
+--- a/drivers/virtio/virtio_pci_legacy.c
++++ b/drivers/virtio/virtio_pci_legacy.c
+@@ -212,10 +212,18 @@ int virtio_pci_legacy_probe(struct virtio_pci_device *vp_dev)
+ 		return -ENODEV;
+ 	}
+ 
+-	rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(64));
+-	if (rc)
+-		rc = dma_set_mask_and_coherent(&pci_dev->dev,
+-						DMA_BIT_MASK(32));
++	rc = dma_set_mask(&pci_dev->dev, DMA_BIT_MASK(64));
++	if (rc) {
++		rc = dma_set_mask_and_coherent(&pci_dev->dev, DMA_BIT_MASK(32));
++	} else {
++		/*
++		 * The virtio ring base address is expressed as a 32-bit PFN,
++		 * with a page size of 1 << VIRTIO_PCI_QUEUE_ADDR_SHIFT.
++		 */
++		dma_set_coherent_mask(&pci_dev->dev,
++				DMA_BIT_MASK(32 + VIRTIO_PCI_QUEUE_ADDR_SHIFT));
++	}
++
+ 	if (rc)
+ 		dev_warn(&pci_dev->dev, "Failed to enable 64-bit or 32-bit DMA.  Trying to continue, but this might not work.\n");
+ 
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
+index ed9c9eeedfe5..6b2cd922d322 100644
+--- a/drivers/virtio/virtio_ring.c
++++ b/drivers/virtio/virtio_ring.c
+@@ -732,7 +732,8 @@ void virtqueue_disable_cb(struct virtqueue *_vq)
+ 
+ 	if (!(vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT)) {
+ 		vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++		if (!vq->event)
++			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+ 	}
+ 
+ }
+@@ -764,7 +765,8 @@ unsigned virtqueue_enable_cb_prepare(struct virtqueue *_vq)
+ 	 * entry. Always do both to keep code simple. */
+ 	if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+ 		vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++		if (!vq->event)
++			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+ 	}
+ 	vring_used_event(&vq->vring) = cpu_to_virtio16(_vq->vdev, last_used_idx = vq->last_used_idx);
+ 	END_USE(vq);
+@@ -832,10 +834,11 @@ bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
+ 	 * more to do. */
+ 	/* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
+ 	 * either clear the flags bit or point the event index at the next
+-	 * entry. Always do both to keep code simple. */
++	 * entry. Always update the event index to keep code simple. */
+ 	if (vq->avail_flags_shadow & VRING_AVAIL_F_NO_INTERRUPT) {
+ 		vq->avail_flags_shadow &= ~VRING_AVAIL_F_NO_INTERRUPT;
+-		vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
++		if (!vq->event)
++			vq->vring.avail->flags = cpu_to_virtio16(_vq->vdev, vq->avail_flags_shadow);
+ 	}
+ 	/* TODO: tune this threshold */
+ 	bufs = (u16)(vq->avail_idx_shadow - vq->last_used_idx) * 3 / 4;
+@@ -953,7 +956,8 @@ struct virtqueue *__vring_new_virtqueue(unsigned int index,
+ 	/* No callback?  Tell other side not to bother us. */
+ 	if (!callback) {
+ 		vq->avail_flags_shadow |= VRING_AVAIL_F_NO_INTERRUPT;
+-		vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
++		if (!vq->event)
++			vq->vring.avail->flags = cpu_to_virtio16(vdev, vq->avail_flags_shadow);
+ 	}
+ 
+ 	/* Put everything in free lists. */
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index e6811c42e41e..bc1a004d4264 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -8915,9 +8915,14 @@ again:
+ 	 *    So even we call qgroup_free_data(), it won't decrease reserved
+ 	 *    space.
+ 	 * 2) Not written to disk
+-	 *    This means the reserved space should be freed here.
++	 *    This means the reserved space should be freed here. However,
++	 *    if a truncate invalidates the page (by clearing PageDirty)
++	 *    and the page is accounted for while allocating extent
++	 *    in btrfs_check_data_free_space() we let delayed_ref to
++	 *    free the entire extent.
+ 	 */
+-	btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
++	if (PageDirty(page))
++		btrfs_qgroup_free_data(inode, page_start, PAGE_SIZE);
+ 	if (!inode_evicting) {
+ 		clear_extent_bit(tree, page_start, page_end,
+ 				 EXTENT_LOCKED | EXTENT_DIRTY |
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index ef9c55bc7907..90e1198bc63d 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -2713,14 +2713,12 @@ static inline void btrfs_remove_all_log_ctxs(struct btrfs_root *root,
+ 					     int index, int error)
+ {
+ 	struct btrfs_log_ctx *ctx;
++	struct btrfs_log_ctx *safe;
+ 
+-	if (!error) {
+-		INIT_LIST_HEAD(&root->log_ctxs[index]);
+-		return;
+-	}
+-
+-	list_for_each_entry(ctx, &root->log_ctxs[index], list)
++	list_for_each_entry_safe(ctx, safe, &root->log_ctxs[index], list) {
++		list_del_init(&ctx->list);
+ 		ctx->log_ret = error;
++	}
+ 
+ 	INIT_LIST_HEAD(&root->log_ctxs[index]);
+ }
+@@ -2961,13 +2959,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
+ 	mutex_unlock(&root->log_mutex);
+ 
+ out_wake_log_root:
+-	/*
+-	 * We needn't get log_mutex here because we are sure all
+-	 * the other tasks are blocked.
+-	 */
++	mutex_lock(&log_root_tree->log_mutex);
+ 	btrfs_remove_all_log_ctxs(log_root_tree, index2, ret);
+ 
+-	mutex_lock(&log_root_tree->log_mutex);
+ 	log_root_tree->log_transid_committed++;
+ 	atomic_set(&log_root_tree->log_commit[index2], 0);
+ 	mutex_unlock(&log_root_tree->log_mutex);
+@@ -2978,10 +2972,8 @@ out_wake_log_root:
+ 	if (waitqueue_active(&log_root_tree->log_commit_wait[index2]))
+ 		wake_up(&log_root_tree->log_commit_wait[index2]);
+ out:
+-	/* See above. */
+-	btrfs_remove_all_log_ctxs(root, index1, ret);
+-
+ 	mutex_lock(&root->log_mutex);
++	btrfs_remove_all_log_ctxs(root, index1, ret);
+ 	root->log_transid_committed++;
+ 	atomic_set(&root->log_commit[index1], 0);
+ 	mutex_unlock(&root->log_mutex);
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index a204d7e109d4..0fe31b4b110d 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -1147,9 +1147,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);
+@@ -1158,12 +1156,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/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
+index abadbc30e013..767377e522c6 100644
+--- a/fs/overlayfs/copy_up.c
++++ b/fs/overlayfs/copy_up.c
+@@ -171,6 +171,8 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
+ 		len -= bytes;
+ 	}
+ 
++	if (!error)
++		error = vfs_fsync(new_file, 0);
+ 	fput(new_file);
+ out_fput:
+ 	fput(old_file);
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index c75625c1efa3..cf2bfeb1b385 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -294,9 +294,6 @@ struct posix_acl *ovl_get_acl(struct inode *inode, int type)
+ 	if (!IS_ENABLED(CONFIG_FS_POSIX_ACL) || !IS_POSIXACL(realinode))
+ 		return NULL;
+ 
+-	if (!realinode->i_op->get_acl)
+-		return NULL;
+-
+ 	old_cred = ovl_override_creds(inode->i_sb);
+ 	acl = get_acl(realinode, type);
+ 	revert_creds(old_cred);
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index e2a94a26767b..a78415d77434 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1026,6 +1026,21 @@ ovl_posix_acl_xattr_set(const struct xattr_handler *handler,
+ 
+ 	posix_acl_release(acl);
+ 
++	/*
++	 * Check if sgid bit needs to be cleared (actual setacl operation will
++	 * be done with mounter's capabilities and so that won't do it for us).
++	 */
++	if (unlikely(inode->i_mode & S_ISGID) &&
++	    handler->flags == ACL_TYPE_ACCESS &&
++	    !in_group_p(inode->i_gid) &&
++	    !capable_wrt_inode_uidgid(inode, CAP_FSETID)) {
++		struct iattr iattr = { .ia_valid = ATTR_KILL_SGID };
++
++		err = ovl_setattr(dentry, &iattr);
++		if (err)
++			return err;
++	}
++
+ 	err = ovl_xattr_set(dentry, handler->name, value, size, flags);
+ 	if (!err)
+ 		ovl_copyattr(ovl_inode_real(inode, NULL), inode);
+diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
+index 4b86d3a738e1..3b27145f985f 100644
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -350,7 +350,7 @@ static unsigned int vfs_dent_type(uint8_t type)
+  */
+ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
+ {
+-	int err;
++	int err = 0;
+ 	struct qstr nm;
+ 	union ubifs_key key;
+ 	struct ubifs_dent_node *dent;
+@@ -452,14 +452,20 @@ out:
+ 	kfree(file->private_data);
+ 	file->private_data = NULL;
+ 
+-	if (err != -ENOENT) {
++	if (err != -ENOENT)
+ 		ubifs_err(c, "cannot find next direntry, error %d", err);
+-		return err;
+-	}
++	else
++		/*
++		 * -ENOENT is a non-fatal error in this context, the TNC uses
++		 * it to indicate that the cursor moved past the current directory
++		 * and readdir() has to stop.
++		 */
++		err = 0;
++
+ 
+ 	/* 2 is a special value indicating that there are no more direntries */
+ 	ctx->pos = 2;
+-	return 0;
++	return err;
+ }
+ 
+ /* Free saved readdir() state when the directory is closed */
+diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
+index 3cc3cf767474..ac9a003dd29a 100644
+--- a/fs/xfs/libxfs/xfs_dquot_buf.c
++++ b/fs/xfs/libxfs/xfs_dquot_buf.c
+@@ -191,8 +191,7 @@ xfs_dquot_buf_verify_crc(
+ 	if (mp->m_quotainfo)
+ 		ndquots = mp->m_quotainfo->qi_dqperchunk;
+ 	else
+-		ndquots = xfs_calc_dquots_per_chunk(
+-					XFS_BB_TO_FSB(mp, bp->b_length));
++		ndquots = xfs_calc_dquots_per_chunk(bp->b_length);
+ 
+ 	for (i = 0; i < ndquots; i++, d++) {
+ 		if (!xfs_verify_cksum((char *)d, sizeof(struct xfs_dqblk),
+diff --git a/include/linux/pwm.h b/include/linux/pwm.h
+index f1bbae014889..2c6c5114c089 100644
+--- a/include/linux/pwm.h
++++ b/include/linux/pwm.h
+@@ -641,6 +641,7 @@ static inline void pwm_remove_table(struct pwm_lookup *table, size_t num)
+ #ifdef CONFIG_PWM_SYSFS
+ void pwmchip_sysfs_export(struct pwm_chip *chip);
+ void pwmchip_sysfs_unexport(struct pwm_chip *chip);
++void pwmchip_sysfs_unexport_children(struct pwm_chip *chip);
+ #else
+ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
+ {
+@@ -649,6 +650,10 @@ static inline void pwmchip_sysfs_export(struct pwm_chip *chip)
+ static inline void pwmchip_sysfs_unexport(struct pwm_chip *chip)
+ {
+ }
++
++static inline void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
++{
++}
+ #endif /* CONFIG_PWM_SYSFS */
+ 
+ #endif /* __LINUX_PWM_H */
+diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
+index 185f8ea2702f..407ca0d7a938 100644
+--- a/include/uapi/linux/Kbuild
++++ b/include/uapi/linux/Kbuild
+@@ -396,6 +396,7 @@ header-y += string.h
+ header-y += suspend_ioctls.h
+ header-y += swab.h
+ header-y += synclink.h
++header-y += sync_file.h
+ header-y += sysctl.h
+ header-y += sysinfo.h
+ header-y += target_core_user.h
+diff --git a/kernel/time/timer.c b/kernel/time/timer.c
+index 32bf6f75a8fe..96db64bdedbb 100644
+--- a/kernel/time/timer.c
++++ b/kernel/time/timer.c
+@@ -878,7 +878,7 @@ static inline struct timer_base *get_timer_base(u32 tflags)
+ 
+ #ifdef CONFIG_NO_HZ_COMMON
+ static inline struct timer_base *
+-__get_target_base(struct timer_base *base, unsigned tflags)
++get_target_base(struct timer_base *base, unsigned tflags)
+ {
+ #ifdef CONFIG_SMP
+ 	if ((tflags & TIMER_PINNED) || !base->migration_enabled)
+@@ -891,25 +891,27 @@ __get_target_base(struct timer_base *base, unsigned tflags)
+ 
+ static inline void forward_timer_base(struct timer_base *base)
+ {
++	unsigned long jnow = READ_ONCE(jiffies);
++
+ 	/*
+ 	 * We only forward the base when it's idle and we have a delta between
+ 	 * base clock and jiffies.
+ 	 */
+-	if (!base->is_idle || (long) (jiffies - base->clk) < 2)
++	if (!base->is_idle || (long) (jnow - base->clk) < 2)
+ 		return;
+ 
+ 	/*
+ 	 * If the next expiry value is > jiffies, then we fast forward to
+ 	 * jiffies otherwise we forward to the next expiry value.
+ 	 */
+-	if (time_after(base->next_expiry, jiffies))
+-		base->clk = jiffies;
++	if (time_after(base->next_expiry, jnow))
++		base->clk = jnow;
+ 	else
+ 		base->clk = base->next_expiry;
+ }
+ #else
+ static inline struct timer_base *
+-__get_target_base(struct timer_base *base, unsigned tflags)
++get_target_base(struct timer_base *base, unsigned tflags)
+ {
+ 	return get_timer_this_cpu_base(tflags);
+ }
+@@ -917,14 +919,6 @@ __get_target_base(struct timer_base *base, unsigned tflags)
+ static inline void forward_timer_base(struct timer_base *base) { }
+ #endif
+ 
+-static inline struct timer_base *
+-get_target_base(struct timer_base *base, unsigned tflags)
+-{
+-	struct timer_base *target = __get_target_base(base, tflags);
+-
+-	forward_timer_base(target);
+-	return target;
+-}
+ 
+ /*
+  * We are using hashed locking: Holding per_cpu(timer_bases[x]).lock means
+@@ -943,7 +937,14 @@ static struct timer_base *lock_timer_base(struct timer_list *timer,
+ {
+ 	for (;;) {
+ 		struct timer_base *base;
+-		u32 tf = timer->flags;
++		u32 tf;
++
++		/*
++		 * We need to use READ_ONCE() here, otherwise the compiler
++		 * might re-read @tf between the check for TIMER_MIGRATING
++		 * and spin_lock().
++		 */
++		tf = READ_ONCE(timer->flags);
+ 
+ 		if (!(tf & TIMER_MIGRATING)) {
+ 			base = get_timer_base(tf);
+@@ -964,6 +965,8 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
+ 	unsigned long clk = 0, flags;
+ 	int ret = 0;
+ 
++	BUG_ON(!timer->function);
++
+ 	/*
+ 	 * This is a common optimization triggered by the networking code - if
+ 	 * the timer is re-modified to have the same timeout or ends up in the
+@@ -972,13 +975,16 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
+ 	if (timer_pending(timer)) {
+ 		if (timer->expires == expires)
+ 			return 1;
++
+ 		/*
+-		 * Take the current timer_jiffies of base, but without holding
+-		 * the lock!
++		 * We lock timer base and calculate the bucket index right
++		 * here. If the timer ends up in the same bucket, then we
++		 * just update the expiry time and avoid the whole
++		 * dequeue/enqueue dance.
+ 		 */
+-		base = get_timer_base(timer->flags);
+-		clk = base->clk;
++		base = lock_timer_base(timer, &flags);
+ 
++		clk = base->clk;
+ 		idx = calc_wheel_index(expires, clk);
+ 
+ 		/*
+@@ -988,14 +994,14 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
+ 		 */
+ 		if (idx == timer_get_idx(timer)) {
+ 			timer->expires = expires;
+-			return 1;
++			ret = 1;
++			goto out_unlock;
+ 		}
++	} else {
++		base = lock_timer_base(timer, &flags);
+ 	}
+ 
+ 	timer_stats_timer_set_start_info(timer);
+-	BUG_ON(!timer->function);
+-
+-	base = lock_timer_base(timer, &flags);
+ 
+ 	ret = detach_if_pending(timer, base, false);
+ 	if (!ret && pending_only)
+@@ -1025,12 +1031,16 @@ __mod_timer(struct timer_list *timer, unsigned long expires, bool pending_only)
+ 		}
+ 	}
+ 
++	/* Try to forward a stale timer base clock */
++	forward_timer_base(base);
++
+ 	timer->expires = expires;
+ 	/*
+ 	 * If 'idx' was calculated above and the base time did not advance
+-	 * between calculating 'idx' and taking the lock, only enqueue_timer()
+-	 * and trigger_dyntick_cpu() is required. Otherwise we need to
+-	 * (re)calculate the wheel index via internal_add_timer().
++	 * between calculating 'idx' and possibly switching the base, only
++	 * enqueue_timer() and trigger_dyntick_cpu() is required. Otherwise
++	 * we need to (re)calculate the wheel index via
++	 * internal_add_timer().
+ 	 */
+ 	if (idx != UINT_MAX && clk == base->clk) {
+ 		enqueue_timer(base, timer, idx);
+@@ -1510,12 +1520,16 @@ u64 get_next_timer_interrupt(unsigned long basej, u64 basem)
+ 	is_max_delta = (nextevt == base->clk + NEXT_TIMER_MAX_DELTA);
+ 	base->next_expiry = nextevt;
+ 	/*
+-	 * We have a fresh next event. Check whether we can forward the base:
++	 * We have a fresh next event. Check whether we can forward the
++	 * base. We can only do that when @basej is past base->clk
++	 * otherwise we might rewind base->clk.
+ 	 */
+-	if (time_after(nextevt, jiffies))
+-		base->clk = jiffies;
+-	else if (time_after(nextevt, base->clk))
+-		base->clk = nextevt;
++	if (time_after(basej, base->clk)) {
++		if (time_after(nextevt, basej))
++			base->clk = basej;
++		else if (time_after(nextevt, base->clk))
++			base->clk = nextevt;
++	}
+ 
+ 	if (time_before_eq(nextevt, basej)) {
+ 		expires = basem;
+diff --git a/mm/list_lru.c b/mm/list_lru.c
+index 1d05cb9d363d..234676e31edd 100644
+--- a/mm/list_lru.c
++++ b/mm/list_lru.c
+@@ -554,6 +554,8 @@ int __list_lru_init(struct list_lru *lru, bool memcg_aware,
+ 	err = memcg_init_list_lru(lru, memcg_aware);
+ 	if (err) {
+ 		kfree(lru->node);
++		/* Do this so a list_lru_destroy() doesn't crash: */
++		lru->node = NULL;
+ 		goto out;
+ 	}
+ 
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index 4be518d4e68a..dddead146459 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -1947,6 +1947,15 @@ retry:
+ 		     current->flags & PF_EXITING))
+ 		goto force;
+ 
++	/*
++	 * Prevent unbounded recursion when reclaim operations need to
++	 * allocate memory. This might exceed the limits temporarily,
++	 * but we prefer facilitating memory reclaim and getting back
++	 * under the limit over triggering OOM kills in these cases.
++	 */
++	if (unlikely(current->flags & PF_MEMALLOC))
++		goto force;
++
+ 	if (unlikely(task_in_memcg_oom(current)))
+ 		goto nomem;
+ 
+diff --git a/mm/slab.c b/mm/slab.c
+index b67271024135..525a911985a2 100644
+--- a/mm/slab.c
++++ b/mm/slab.c
+@@ -964,7 +964,7 @@ static int setup_kmem_cache_node(struct kmem_cache *cachep,
+ 	 * guaranteed to be valid until irq is re-enabled, because it will be
+ 	 * freed after synchronize_sched().
+ 	 */
+-	if (force_change)
++	if (old_shared && force_change)
+ 		synchronize_sched();
+ 
+ fail:
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index 0fe8b7113868..ba0fad78e5d4 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -3048,7 +3048,9 @@ unsigned long try_to_free_mem_cgroup_pages(struct mem_cgroup *memcg,
+ 					    sc.gfp_mask,
+ 					    sc.reclaim_idx);
+ 
++	current->flags |= PF_MEMALLOC;
+ 	nr_reclaimed = do_try_to_free_pages(zonelist, &sc);
++	current->flags &= ~PF_MEMALLOC;
+ 
+ 	trace_mm_vmscan_memcg_reclaim_end(nr_reclaimed);
+ 
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
+index 9dce3b157908..59a96034979b 100644
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2253,16 +2253,22 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx_data *rx)
+ 	if (!(status->rx_flags & IEEE80211_RX_AMSDU))
+ 		return RX_CONTINUE;
+ 
+-	if (ieee80211_has_a4(hdr->frame_control) &&
+-	    rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+-	    !rx->sdata->u.vlan.sta)
+-		return RX_DROP_UNUSABLE;
++	if (unlikely(ieee80211_has_a4(hdr->frame_control))) {
++		switch (rx->sdata->vif.type) {
++		case NL80211_IFTYPE_AP_VLAN:
++			if (!rx->sdata->u.vlan.sta)
++				return RX_DROP_UNUSABLE;
++			break;
++		case NL80211_IFTYPE_STATION:
++			if (!rx->sdata->u.mgd.use_4addr)
++				return RX_DROP_UNUSABLE;
++			break;
++		default:
++			return RX_DROP_UNUSABLE;
++		}
++	}
+ 
+-	if (is_multicast_ether_addr(hdr->addr1) &&
+-	    ((rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+-	      rx->sdata->u.vlan.sta) ||
+-	     (rx->sdata->vif.type == NL80211_IFTYPE_STATION &&
+-	      rx->sdata->u.mgd.use_4addr)))
++	if (is_multicast_ether_addr(hdr->addr1))
+ 		return RX_DROP_UNUSABLE;
+ 
+ 	skb->dev = dev;
+diff --git a/net/netfilter/xt_NFLOG.c b/net/netfilter/xt_NFLOG.c
+index 018eed7e1ff1..8668a5c18dc3 100644
+--- a/net/netfilter/xt_NFLOG.c
++++ b/net/netfilter/xt_NFLOG.c
+@@ -32,6 +32,7 @@ nflog_tg(struct sk_buff *skb, const struct xt_action_param *par)
+ 	li.u.ulog.copy_len   = info->len;
+ 	li.u.ulog.group	     = info->group;
+ 	li.u.ulog.qthreshold = info->threshold;
++	li.u.ulog.flags	     = 0;
+ 
+ 	if (info->flags & XT_NFLOG_F_COPY_LEN)
+ 		li.u.ulog.flags |= NF_LOG_F_COPY_LEN;
+diff --git a/security/keys/Kconfig b/security/keys/Kconfig
+index f826e8739023..d942c7c2bc0a 100644
+--- a/security/keys/Kconfig
++++ b/security/keys/Kconfig
+@@ -41,7 +41,7 @@ config BIG_KEYS
+ 	bool "Large payload keys"
+ 	depends on KEYS
+ 	depends on TMPFS
+-	select CRYPTO
++	depends on (CRYPTO_ANSI_CPRNG = y || CRYPTO_DRBG = y)
+ 	select CRYPTO_AES
+ 	select CRYPTO_ECB
+ 	select CRYPTO_RNG
+diff --git a/security/keys/big_key.c b/security/keys/big_key.c
+index c0b3030b5634..835c1ab30d01 100644
+--- a/security/keys/big_key.c
++++ b/security/keys/big_key.c
+@@ -9,6 +9,7 @@
+  * 2 of the Licence, or (at your option) any later version.
+  */
+ 
++#define pr_fmt(fmt) "big_key: "fmt
+ #include <linux/init.h>
+ #include <linux/seq_file.h>
+ #include <linux/file.h>
+@@ -341,44 +342,48 @@ error:
+  */
+ static int __init big_key_init(void)
+ {
+-	return register_key_type(&key_type_big_key);
+-}
+-
+-/*
+- * Initialize big_key crypto and RNG algorithms
+- */
+-static int __init big_key_crypto_init(void)
+-{
+-	int ret = -EINVAL;
++	struct crypto_skcipher *cipher;
++	struct crypto_rng *rng;
++	int ret;
+ 
+-	/* init RNG */
+-	big_key_rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
+-	if (IS_ERR(big_key_rng)) {
+-		big_key_rng = NULL;
+-		return -EFAULT;
++	rng = crypto_alloc_rng(big_key_rng_name, 0, 0);
++	if (IS_ERR(rng)) {
++		pr_err("Can't alloc rng: %ld\n", PTR_ERR(rng));
++		return PTR_ERR(rng);
+ 	}
+ 
++	big_key_rng = rng;
++
+ 	/* seed RNG */
+-	ret = crypto_rng_reset(big_key_rng, NULL, crypto_rng_seedsize(big_key_rng));
+-	if (ret)
+-		goto error;
++	ret = crypto_rng_reset(rng, NULL, crypto_rng_seedsize(rng));
++	if (ret) {
++		pr_err("Can't reset rng: %d\n", ret);
++		goto error_rng;
++	}
+ 
+ 	/* init block cipher */
+-	big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name,
+-						 0, CRYPTO_ALG_ASYNC);
+-	if (IS_ERR(big_key_skcipher)) {
+-		big_key_skcipher = NULL;
+-		ret = -EFAULT;
+-		goto error;
++	cipher = crypto_alloc_skcipher(big_key_alg_name, 0, CRYPTO_ALG_ASYNC);
++	if (IS_ERR(cipher)) {
++		ret = PTR_ERR(cipher);
++		pr_err("Can't alloc crypto: %d\n", ret);
++		goto error_rng;
++	}
++
++	big_key_skcipher = cipher;
++
++	ret = register_key_type(&key_type_big_key);
++	if (ret < 0) {
++		pr_err("Can't register type: %d\n", ret);
++		goto error_cipher;
+ 	}
+ 
+ 	return 0;
+ 
+-error:
++error_cipher:
++	crypto_free_skcipher(big_key_skcipher);
++error_rng:
+ 	crypto_free_rng(big_key_rng);
+-	big_key_rng = NULL;
+ 	return ret;
+ }
+ 
+-device_initcall(big_key_init);
+-late_initcall(big_key_crypto_init);
++late_initcall(big_key_init);
+diff --git a/security/keys/proc.c b/security/keys/proc.c
+index f0611a6368cd..b9f531c9e4fa 100644
+--- a/security/keys/proc.c
++++ b/security/keys/proc.c
+@@ -181,7 +181,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
+ 	struct timespec now;
+ 	unsigned long timo;
+ 	key_ref_t key_ref, skey_ref;
+-	char xbuf[12];
++	char xbuf[16];
+ 	int rc;
+ 
+ 	struct keyring_search_context ctx = {
+diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c
+index dcc102813aef..37d9cfbc29f9 100644
+--- a/sound/core/seq/seq_timer.c
++++ b/sound/core/seq/seq_timer.c
+@@ -448,8 +448,8 @@ snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr)
+ 
+ 		ktime_get_ts64(&tm);
+ 		tm = timespec64_sub(tm, tmr->last_update);
+-		cur_time.tv_nsec = tm.tv_nsec;
+-		cur_time.tv_sec = tm.tv_sec;
++		cur_time.tv_nsec += tm.tv_nsec;
++		cur_time.tv_sec += tm.tv_sec;
+ 		snd_seq_sanity_real_time(&cur_time);
+ 	}
+ 	spin_unlock_irqrestore(&tmr->lock, flags);
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 160c7f713722..487fcbf9473e 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -340,8 +340,7 @@ enum {
+ 
+ /* quirks for Nvidia */
+ #define AZX_DCAPS_PRESET_NVIDIA \
+-	(AZX_DCAPS_NO_MSI | /*AZX_DCAPS_ALIGN_BUFSIZE |*/ \
+-	 AZX_DCAPS_NO_64BIT | AZX_DCAPS_CORBRP_SELF_CLEAR |\
++	(AZX_DCAPS_NO_MSI | AZX_DCAPS_CORBRP_SELF_CLEAR |\
+ 	 AZX_DCAPS_SNOOP_TYPE(NVIDIA))
+ 
+ #define AZX_DCAPS_PRESET_CTHDA \
+@@ -1699,6 +1698,10 @@ static int azx_first_init(struct azx *chip)
+ 		}
+ 	}
+ 
++	/* NVidia hardware normally only supports up to 40 bits of DMA */
++	if (chip->pci->vendor == PCI_VENDOR_ID_NVIDIA)
++		dma_bits = 40;
++
+ 	/* disable 64bit DMA address on some devices */
+ 	if (chip->driver_caps & AZX_DCAPS_NO_64BIT) {
+ 		dev_dbg(card->dev, "Disabling 64bit DMA\n");
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index bd481ac23faf..26e866f65314 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5809,8 +5809,6 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ #define ALC295_STANDARD_PINS \
+ 	{0x12, 0xb7a60130}, \
+ 	{0x14, 0x90170110}, \
+-	{0x17, 0x21014020}, \
+-	{0x18, 0x21a19030}, \
+ 	{0x21, 0x04211020}
+ 
+ #define ALC298_STANDARD_PINS \
+@@ -5857,11 +5855,19 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x1b, 0x02011020},
+ 		{0x21, 0x0221101f}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x14, 0x90170110},
++		{0x1b, 0x01011020},
++		{0x21, 0x0221101f}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x14, 0x90170130},
+ 		{0x1b, 0x01014020},
+ 		{0x21, 0x0221103f}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x14, 0x90170130},
++		{0x1b, 0x01011020},
++		{0x21, 0x0221103f}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x14, 0x90170130},
+ 		{0x1b, 0x02011020},
+ 		{0x21, 0x0221103f}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+@@ -6037,7 +6043,13 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		ALC292_STANDARD_PINS,
+ 		{0x13, 0x90a60140}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
+-		ALC295_STANDARD_PINS),
++		ALC295_STANDARD_PINS,
++		{0x17, 0x21014020},
++		{0x18, 0x21a19030}),
++	SND_HDA_PIN_QUIRK(0x10ec0295, 0x1028, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE,
++		ALC295_STANDARD_PINS,
++		{0x17, 0x21014040},
++		{0x18, 0x21a19050}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0298, 0x1028, "Dell", ALC298_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC298_STANDARD_PINS,
+ 		{0x17, 0x90170110}),
+@@ -6611,6 +6623,7 @@ enum {
+ 	ALC891_FIXUP_HEADSET_MODE,
+ 	ALC891_FIXUP_DELL_MIC_NO_PRESENCE,
+ 	ALC662_FIXUP_ACER_VERITON,
++	ALC892_FIXUP_ASROCK_MOBO,
+ };
+ 
+ static const struct hda_fixup alc662_fixups[] = {
+@@ -6887,6 +6900,16 @@ static const struct hda_fixup alc662_fixups[] = {
+ 			{ }
+ 		}
+ 	},
++	[ALC892_FIXUP_ASROCK_MOBO] = {
++		.type = HDA_FIXUP_PINS,
++		.v.pins = (const struct hda_pintbl[]) {
++			{ 0x15, 0x40f000f0 }, /* disabled */
++			{ 0x16, 0x40f000f0 }, /* disabled */
++			{ 0x18, 0x01014011 }, /* LO */
++			{ 0x1a, 0x01014012 }, /* LO */
++			{ }
++		}
++	},
+ };
+ 
+ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+@@ -6924,6 +6947,7 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD),
+ 	SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD),
+ 	SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD),
++	SND_PCI_QUIRK(0x1849, 0x5892, "ASRock B150M", ALC892_FIXUP_ASROCK_MOBO),
+ 	SND_PCI_QUIRK(0x19da, 0xa130, "Zotac Z68", ALC662_FIXUP_ZOTAC_Z68),
+ 	SND_PCI_QUIRK(0x1b0a, 0x01b8, "ACER Veriton", ALC662_FIXUP_ACER_VERITON),
+ 	SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T),
+diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h
+index c60a776e815d..8a59d4782a0f 100644
+--- a/sound/usb/quirks-table.h
++++ b/sound/usb/quirks-table.h
+@@ -2907,6 +2907,23 @@ AU0828_DEVICE(0x2040, 0x7260, "Hauppauge", "HVR-950Q"),
+ AU0828_DEVICE(0x2040, 0x7213, "Hauppauge", "HVR-950Q"),
+ AU0828_DEVICE(0x2040, 0x7270, "Hauppauge", "HVR-950Q"),
+ 
++/* Syntek STK1160 */
++{
++	.match_flags = USB_DEVICE_ID_MATCH_DEVICE |
++		       USB_DEVICE_ID_MATCH_INT_CLASS |
++		       USB_DEVICE_ID_MATCH_INT_SUBCLASS,
++	.idVendor = 0x05e1,
++	.idProduct = 0x0408,
++	.bInterfaceClass = USB_CLASS_AUDIO,
++	.bInterfaceSubClass = USB_SUBCLASS_AUDIOCONTROL,
++	.driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) {
++		.vendor_name = "Syntek",
++		.product_name = "STK1160",
++		.ifnum = QUIRK_ANY_INTERFACE,
++		.type = QUIRK_AUDIO_ALIGN_TRANSFER
++	}
++},
++
+ /* Digidesign Mbox */
+ {
+ 	/* Thanks to Clemens Ladisch <clemens@ladisch.de> */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-15  7:59 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-11-15  7:59 UTC (permalink / raw
  To: gentoo-commits

commit:     215deabf1be5d79b5db37aee287bca795cf0805d
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 15 07:58:39 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Tue Nov 15 07:58:39 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=215deabf

Linux patch 4.8.8

 0000_README            |    4 +
 1007_linux-4.8.8.patch | 1846 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1850 insertions(+)

diff --git a/0000_README b/0000_README
index 9cd8633..236529a 100644
--- a/0000_README
+++ b/0000_README
@@ -71,6 +71,10 @@ Patch:  1006_linux-4.8.7.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.7
 
+Patch:  1007_linux-4.8.8.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.8
+
 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/1007_linux-4.8.8.patch b/1007_linux-4.8.8.patch
new file mode 100644
index 0000000..7f46629
--- /dev/null
+++ b/1007_linux-4.8.8.patch
@@ -0,0 +1,1846 @@
+diff --git a/Makefile b/Makefile
+index 4d0f28cb481d..8f18daa2c76a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 7
++SUBLEVEL = 8
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/powerpc/include/asm/checksum.h b/arch/powerpc/include/asm/checksum.h
+index ee655ed1ff1b..1e8fceb308a5 100644
+--- a/arch/powerpc/include/asm/checksum.h
++++ b/arch/powerpc/include/asm/checksum.h
+@@ -53,10 +53,8 @@ static inline __sum16 csum_fold(__wsum sum)
+ 	return (__force __sum16)(~((__force u32)sum + tmp) >> 16);
+ }
+ 
+-static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+-                                     unsigned short len,
+-                                     unsigned short proto,
+-                                     __wsum sum)
++static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
++					__u8 proto, __wsum sum)
+ {
+ #ifdef __powerpc64__
+ 	unsigned long s = (__force u32)sum;
+@@ -83,10 +81,8 @@ static inline __wsum csum_tcpudp_nofold(__be32 saddr, __be32 daddr,
+  * computes the checksum of the TCP/UDP pseudo-header
+  * returns a 16-bit checksum, already complemented
+  */
+-static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr,
+-					unsigned short len,
+-					unsigned short proto,
+-					__wsum sum)
++static inline __sum16 csum_tcpudp_magic(__be32 saddr, __be32 daddr, __u32 len,
++					__u8 proto, __wsum sum)
+ {
+ 	return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
+ }
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h
+index 9dbfcc0ab577..5ff64afd69f9 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib.h
++++ b/drivers/infiniband/ulp/ipoib/ipoib.h
+@@ -63,6 +63,8 @@ enum ipoib_flush_level {
+ 
+ enum {
+ 	IPOIB_ENCAP_LEN		  = 4,
++	IPOIB_PSEUDO_LEN	  = 20,
++	IPOIB_HARD_LEN		  = IPOIB_ENCAP_LEN + IPOIB_PSEUDO_LEN,
+ 
+ 	IPOIB_UD_HEAD_SIZE	  = IB_GRH_BYTES + IPOIB_ENCAP_LEN,
+ 	IPOIB_UD_RX_SG		  = 2, /* max buffer needed for 4K mtu */
+@@ -134,15 +136,21 @@ struct ipoib_header {
+ 	u16	reserved;
+ };
+ 
+-struct ipoib_cb {
+-	struct qdisc_skb_cb	qdisc_cb;
+-	u8			hwaddr[INFINIBAND_ALEN];
++struct ipoib_pseudo_header {
++	u8	hwaddr[INFINIBAND_ALEN];
+ };
+ 
+-static inline struct ipoib_cb *ipoib_skb_cb(const struct sk_buff *skb)
++static inline void skb_add_pseudo_hdr(struct sk_buff *skb)
+ {
+-	BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct ipoib_cb));
+-	return (struct ipoib_cb *)skb->cb;
++	char *data = skb_push(skb, IPOIB_PSEUDO_LEN);
++
++	/*
++	 * only the ipoib header is present now, make room for a dummy
++	 * pseudo header and set skb field accordingly
++	 */
++	memset(data, 0, IPOIB_PSEUDO_LEN);
++	skb_reset_mac_header(skb);
++	skb_pull(skb, IPOIB_HARD_LEN);
+ }
+ 
+ /* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+index 4ad297d3de89..339a1eecdfe3 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -63,6 +63,8 @@ MODULE_PARM_DESC(cm_data_debug_level,
+ #define IPOIB_CM_RX_DELAY       (3 * 256 * HZ)
+ #define IPOIB_CM_RX_UPDATE_MASK (0x3)
+ 
++#define IPOIB_CM_RX_RESERVE     (ALIGN(IPOIB_HARD_LEN, 16) - IPOIB_ENCAP_LEN)
++
+ static struct ib_qp_attr ipoib_cm_err_attr = {
+ 	.qp_state = IB_QPS_ERR
+ };
+@@ -146,15 +148,15 @@ static struct sk_buff *ipoib_cm_alloc_rx_skb(struct net_device *dev,
+ 	struct sk_buff *skb;
+ 	int i;
+ 
+-	skb = dev_alloc_skb(IPOIB_CM_HEAD_SIZE + 12);
++	skb = dev_alloc_skb(ALIGN(IPOIB_CM_HEAD_SIZE + IPOIB_PSEUDO_LEN, 16));
+ 	if (unlikely(!skb))
+ 		return NULL;
+ 
+ 	/*
+-	 * IPoIB adds a 4 byte header. So we need 12 more bytes to align the
++	 * IPoIB adds a IPOIB_ENCAP_LEN byte header, this will align the
+ 	 * IP header to a multiple of 16.
+ 	 */
+-	skb_reserve(skb, 12);
++	skb_reserve(skb, IPOIB_CM_RX_RESERVE);
+ 
+ 	mapping[0] = ib_dma_map_single(priv->ca, skb->data, IPOIB_CM_HEAD_SIZE,
+ 				       DMA_FROM_DEVICE);
+@@ -624,9 +626,9 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
+ 	if (wc->byte_len < IPOIB_CM_COPYBREAK) {
+ 		int dlen = wc->byte_len;
+ 
+-		small_skb = dev_alloc_skb(dlen + 12);
++		small_skb = dev_alloc_skb(dlen + IPOIB_CM_RX_RESERVE);
+ 		if (small_skb) {
+-			skb_reserve(small_skb, 12);
++			skb_reserve(small_skb, IPOIB_CM_RX_RESERVE);
+ 			ib_dma_sync_single_for_cpu(priv->ca, rx_ring[wr_id].mapping[0],
+ 						   dlen, DMA_FROM_DEVICE);
+ 			skb_copy_from_linear_data(skb, small_skb->data, dlen);
+@@ -663,8 +665,7 @@ void ipoib_cm_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
+ 
+ copied:
+ 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
+-	skb_reset_mac_header(skb);
+-	skb_pull(skb, IPOIB_ENCAP_LEN);
++	skb_add_pseudo_hdr(skb);
+ 
+ 	++dev->stats.rx_packets;
+ 	dev->stats.rx_bytes += skb->len;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_ib.c b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+index be11d5d5b8c1..830fecb6934c 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c
+@@ -128,16 +128,15 @@ static struct sk_buff *ipoib_alloc_rx_skb(struct net_device *dev, int id)
+ 
+ 	buf_size = IPOIB_UD_BUF_SIZE(priv->max_ib_mtu);
+ 
+-	skb = dev_alloc_skb(buf_size + IPOIB_ENCAP_LEN);
++	skb = dev_alloc_skb(buf_size + IPOIB_HARD_LEN);
+ 	if (unlikely(!skb))
+ 		return NULL;
+ 
+ 	/*
+-	 * IB will leave a 40 byte gap for a GRH and IPoIB adds a 4 byte
+-	 * header.  So we need 4 more bytes to get to 48 and align the
+-	 * IP header to a multiple of 16.
++	 * the IP header will be at IPOIP_HARD_LEN + IB_GRH_BYTES, that is
++	 * 64 bytes aligned
+ 	 */
+-	skb_reserve(skb, 4);
++	skb_reserve(skb, sizeof(struct ipoib_pseudo_header));
+ 
+ 	mapping = priv->rx_ring[id].mapping;
+ 	mapping[0] = ib_dma_map_single(priv->ca, skb->data, buf_size,
+@@ -253,8 +252,7 @@ static void ipoib_ib_handle_rx_wc(struct net_device *dev, struct ib_wc *wc)
+ 	skb_pull(skb, IB_GRH_BYTES);
+ 
+ 	skb->protocol = ((struct ipoib_header *) skb->data)->proto;
+-	skb_reset_mac_header(skb);
+-	skb_pull(skb, IPOIB_ENCAP_LEN);
++	skb_add_pseudo_hdr(skb);
+ 
+ 	++dev->stats.rx_packets;
+ 	dev->stats.rx_bytes += skb->len;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+index cc1c1b062ea5..823a528ef4eb 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -925,9 +925,12 @@ static void neigh_add_path(struct sk_buff *skb, u8 *daddr,
+ 				ipoib_neigh_free(neigh);
+ 				goto err_drop;
+ 			}
+-			if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE)
++			if (skb_queue_len(&neigh->queue) <
++			    IPOIB_MAX_PATH_REC_QUEUE) {
++				/* put pseudoheader back on for next time */
++				skb_push(skb, IPOIB_PSEUDO_LEN);
+ 				__skb_queue_tail(&neigh->queue, skb);
+-			else {
++			} else {
+ 				ipoib_warn(priv, "queue length limit %d. Packet drop.\n",
+ 					   skb_queue_len(&neigh->queue));
+ 				goto err_drop;
+@@ -964,7 +967,7 @@ err_drop:
+ }
+ 
+ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+-			     struct ipoib_cb *cb)
++			     struct ipoib_pseudo_header *phdr)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	struct ipoib_path *path;
+@@ -972,16 +975,18 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+ 
+ 	spin_lock_irqsave(&priv->lock, flags);
+ 
+-	path = __path_find(dev, cb->hwaddr + 4);
++	path = __path_find(dev, phdr->hwaddr + 4);
+ 	if (!path || !path->valid) {
+ 		int new_path = 0;
+ 
+ 		if (!path) {
+-			path = path_rec_create(dev, cb->hwaddr + 4);
++			path = path_rec_create(dev, phdr->hwaddr + 4);
+ 			new_path = 1;
+ 		}
+ 		if (path) {
+ 			if (skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
++				/* put pseudoheader back on for next time */
++				skb_push(skb, IPOIB_PSEUDO_LEN);
+ 				__skb_queue_tail(&path->queue, skb);
+ 			} else {
+ 				++dev->stats.tx_dropped;
+@@ -1009,10 +1014,12 @@ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+ 			  be16_to_cpu(path->pathrec.dlid));
+ 
+ 		spin_unlock_irqrestore(&priv->lock, flags);
+-		ipoib_send(dev, skb, path->ah, IPOIB_QPN(cb->hwaddr));
++		ipoib_send(dev, skb, path->ah, IPOIB_QPN(phdr->hwaddr));
+ 		return;
+ 	} else if ((path->query || !path_rec_start(dev, path)) &&
+ 		   skb_queue_len(&path->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
++		/* put pseudoheader back on for next time */
++		skb_push(skb, IPOIB_PSEUDO_LEN);
+ 		__skb_queue_tail(&path->queue, skb);
+ 	} else {
+ 		++dev->stats.tx_dropped;
+@@ -1026,13 +1033,15 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	struct ipoib_neigh *neigh;
+-	struct ipoib_cb *cb = ipoib_skb_cb(skb);
++	struct ipoib_pseudo_header *phdr;
+ 	struct ipoib_header *header;
+ 	unsigned long flags;
+ 
++	phdr = (struct ipoib_pseudo_header *) skb->data;
++	skb_pull(skb, sizeof(*phdr));
+ 	header = (struct ipoib_header *) skb->data;
+ 
+-	if (unlikely(cb->hwaddr[4] == 0xff)) {
++	if (unlikely(phdr->hwaddr[4] == 0xff)) {
+ 		/* multicast, arrange "if" according to probability */
+ 		if ((header->proto != htons(ETH_P_IP)) &&
+ 		    (header->proto != htons(ETH_P_IPV6)) &&
+@@ -1045,13 +1054,13 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 			return NETDEV_TX_OK;
+ 		}
+ 		/* Add in the P_Key for multicast*/
+-		cb->hwaddr[8] = (priv->pkey >> 8) & 0xff;
+-		cb->hwaddr[9] = priv->pkey & 0xff;
++		phdr->hwaddr[8] = (priv->pkey >> 8) & 0xff;
++		phdr->hwaddr[9] = priv->pkey & 0xff;
+ 
+-		neigh = ipoib_neigh_get(dev, cb->hwaddr);
++		neigh = ipoib_neigh_get(dev, phdr->hwaddr);
+ 		if (likely(neigh))
+ 			goto send_using_neigh;
+-		ipoib_mcast_send(dev, cb->hwaddr, skb);
++		ipoib_mcast_send(dev, phdr->hwaddr, skb);
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+@@ -1060,16 +1069,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	case htons(ETH_P_IP):
+ 	case htons(ETH_P_IPV6):
+ 	case htons(ETH_P_TIPC):
+-		neigh = ipoib_neigh_get(dev, cb->hwaddr);
++		neigh = ipoib_neigh_get(dev, phdr->hwaddr);
+ 		if (unlikely(!neigh)) {
+-			neigh_add_path(skb, cb->hwaddr, dev);
++			neigh_add_path(skb, phdr->hwaddr, dev);
+ 			return NETDEV_TX_OK;
+ 		}
+ 		break;
+ 	case htons(ETH_P_ARP):
+ 	case htons(ETH_P_RARP):
+ 		/* for unicast ARP and RARP should always perform path find */
+-		unicast_arp_send(skb, dev, cb);
++		unicast_arp_send(skb, dev, phdr);
+ 		return NETDEV_TX_OK;
+ 	default:
+ 		/* ethertype not supported by IPoIB */
+@@ -1086,11 +1095,13 @@ send_using_neigh:
+ 			goto unref;
+ 		}
+ 	} else if (neigh->ah) {
+-		ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(cb->hwaddr));
++		ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(phdr->hwaddr));
+ 		goto unref;
+ 	}
+ 
+ 	if (skb_queue_len(&neigh->queue) < IPOIB_MAX_PATH_REC_QUEUE) {
++		/* put pseudoheader back on for next time */
++		skb_push(skb, sizeof(*phdr));
+ 		spin_lock_irqsave(&priv->lock, flags);
+ 		__skb_queue_tail(&neigh->queue, skb);
+ 		spin_unlock_irqrestore(&priv->lock, flags);
+@@ -1122,8 +1133,8 @@ static int ipoib_hard_header(struct sk_buff *skb,
+ 			     unsigned short type,
+ 			     const void *daddr, const void *saddr, unsigned len)
+ {
++	struct ipoib_pseudo_header *phdr;
+ 	struct ipoib_header *header;
+-	struct ipoib_cb *cb = ipoib_skb_cb(skb);
+ 
+ 	header = (struct ipoib_header *) skb_push(skb, sizeof *header);
+ 
+@@ -1132,12 +1143,13 @@ static int ipoib_hard_header(struct sk_buff *skb,
+ 
+ 	/*
+ 	 * we don't rely on dst_entry structure,  always stuff the
+-	 * destination address into skb->cb so we can figure out where
++	 * destination address into skb hard header so we can figure out where
+ 	 * to send the packet later.
+ 	 */
+-	memcpy(cb->hwaddr, daddr, INFINIBAND_ALEN);
++	phdr = (struct ipoib_pseudo_header *) skb_push(skb, sizeof(*phdr));
++	memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
+ 
+-	return sizeof *header;
++	return IPOIB_HARD_LEN;
+ }
+ 
+ static void ipoib_set_mcast_list(struct net_device *dev)
+@@ -1759,7 +1771,7 @@ void ipoib_setup(struct net_device *dev)
+ 
+ 	dev->flags		|= IFF_BROADCAST | IFF_MULTICAST;
+ 
+-	dev->hard_header_len	 = IPOIB_ENCAP_LEN;
++	dev->hard_header_len	 = IPOIB_HARD_LEN;
+ 	dev->addr_len		 = INFINIBAND_ALEN;
+ 	dev->type		 = ARPHRD_INFINIBAND;
+ 	dev->tx_queue_len	 = ipoib_sendq_size * 2;
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+index d3394b6add24..1909dd252c94 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -796,9 +796,11 @@ void ipoib_mcast_send(struct net_device *dev, u8 *daddr, struct sk_buff *skb)
+ 			__ipoib_mcast_add(dev, mcast);
+ 			list_add_tail(&mcast->list, &priv->multicast_list);
+ 		}
+-		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE)
++		if (skb_queue_len(&mcast->pkt_queue) < IPOIB_MAX_MCAST_QUEUE) {
++			/* put pseudoheader back on for next time */
++			skb_push(skb, sizeof(struct ipoib_pseudo_header));
+ 			skb_queue_tail(&mcast->pkt_queue, skb);
+-		else {
++		} else {
+ 			++dev->stats.tx_dropped;
+ 			dev_kfree_skb_any(skb);
+ 		}
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 692ee248e486..3474de576dde 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -913,13 +913,11 @@ fec_restart(struct net_device *ndev)
+ 	 * enet-mac reset will reset mac address registers too,
+ 	 * so need to reconfigure it.
+ 	 */
+-	if (fep->quirks & FEC_QUIRK_ENET_MAC) {
+-		memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
+-		writel((__force u32)cpu_to_be32(temp_mac[0]),
+-		       fep->hwp + FEC_ADDR_LOW);
+-		writel((__force u32)cpu_to_be32(temp_mac[1]),
+-		       fep->hwp + FEC_ADDR_HIGH);
+-	}
++	memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
++	writel((__force u32)cpu_to_be32(temp_mac[0]),
++	       fep->hwp + FEC_ADDR_LOW);
++	writel((__force u32)cpu_to_be32(temp_mac[1]),
++	       fep->hwp + FEC_ADDR_HIGH);
+ 
+ 	/* Clear any outstanding interrupt. */
+ 	writel(0xffffffff, fep->hwp + FEC_IEVENT);
+@@ -1432,14 +1430,14 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+ 		skb_put(skb, pkt_len - 4);
+ 		data = skb->data;
+ 
++		if (!is_copybreak && need_swap)
++			swap_buffer(data, pkt_len);
++
+ #if !defined(CONFIG_M5272)
+ 		if (fep->quirks & FEC_QUIRK_HAS_RACC)
+ 			data = skb_pull_inline(skb, 2);
+ #endif
+ 
+-		if (!is_copybreak && need_swap)
+-			swap_buffer(data, pkt_len);
+-
+ 		/* Extract the enhanced buffer descriptor */
+ 		ebdp = NULL;
+ 		if (fep->bufdesc_ex)
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_cq.c b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+index 132cea655920..e3be7e44ff51 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_cq.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_cq.c
+@@ -127,7 +127,15 @@ int mlx4_en_activate_cq(struct mlx4_en_priv *priv, struct mlx4_en_cq *cq,
+ 		/* For TX we use the same irq per
+ 		ring we assigned for the RX    */
+ 		struct mlx4_en_cq *rx_cq;
+-
++		int xdp_index;
++
++		/* The xdp tx irq must align with the rx ring that forwards to
++		 * it, so reindex these from 0. This should only happen when
++		 * tx_ring_num is not a multiple of rx_ring_num.
++		 */
++		xdp_index = (priv->xdp_ring_num - priv->tx_ring_num) + cq_idx;
++		if (xdp_index >= 0)
++			cq_idx = xdp_index;
+ 		cq_idx = cq_idx % priv->rx_ring_num;
+ 		rx_cq = priv->rx_cq[cq_idx];
+ 		cq->vector = rx_cq->vector;
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 3c20e87bb761..16af1ce99233 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -453,7 +453,7 @@ static struct sk_buff **geneve_gro_receive(struct sock *sk,
+ 
+ 	skb_gro_pull(skb, gh_len);
+ 	skb_gro_postpull_rcsum(skb, gh, gh_len);
+-	pp = ptype->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+ 	flush = 0;
+ 
+ out_unlock:
+diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
+index 3ba29fc80d05..c4d9653cae66 100644
+--- a/drivers/net/hyperv/netvsc_drv.c
++++ b/drivers/net/hyperv/netvsc_drv.c
+@@ -624,15 +624,18 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net,
+ 	       packet->total_data_buflen);
+ 
+ 	skb->protocol = eth_type_trans(skb, net);
+-	if (csum_info) {
+-		/* We only look at the IP checksum here.
+-		 * Should we be dropping the packet if checksum
+-		 * failed? How do we deal with other checksums - TCP/UDP?
+-		 */
+-		if (csum_info->receive.ip_checksum_succeeded)
++
++	/* skb is already created with CHECKSUM_NONE */
++	skb_checksum_none_assert(skb);
++
++	/*
++	 * In Linux, the IP checksum is always checked.
++	 * Do L4 checksum offload if enabled and present.
++	 */
++	if (csum_info && (net->features & NETIF_F_RXCSUM)) {
++		if (csum_info->receive.tcp_checksum_succeeded ||
++		    csum_info->receive.udp_checksum_succeeded)
+ 			skb->ip_summed = CHECKSUM_UNNECESSARY;
+-		else
+-			skb->ip_summed = CHECKSUM_NONE;
+ 	}
+ 
+ 	if (vlan_tci & VLAN_TAG_PRESENT)
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 351e701eb043..b72ddc61eff8 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -397,6 +397,14 @@ static struct macsec_cb *macsec_skb_cb(struct sk_buff *skb)
+ #define DEFAULT_ENCRYPT false
+ #define DEFAULT_ENCODING_SA 0
+ 
++static bool send_sci(const struct macsec_secy *secy)
++{
++	const struct macsec_tx_sc *tx_sc = &secy->tx_sc;
++
++	return tx_sc->send_sci ||
++		(secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb);
++}
++
+ static sci_t make_sci(u8 *addr, __be16 port)
+ {
+ 	sci_t sci;
+@@ -437,15 +445,15 @@ static unsigned int macsec_extra_len(bool sci_present)
+ 
+ /* Fill SecTAG according to IEEE 802.1AE-2006 10.5.3 */
+ static void macsec_fill_sectag(struct macsec_eth_header *h,
+-			       const struct macsec_secy *secy, u32 pn)
++			       const struct macsec_secy *secy, u32 pn,
++			       bool sci_present)
+ {
+ 	const struct macsec_tx_sc *tx_sc = &secy->tx_sc;
+ 
+-	memset(&h->tci_an, 0, macsec_sectag_len(tx_sc->send_sci));
++	memset(&h->tci_an, 0, macsec_sectag_len(sci_present));
+ 	h->eth.h_proto = htons(ETH_P_MACSEC);
+ 
+-	if (tx_sc->send_sci ||
+-	    (secy->n_rx_sc > 1 && !tx_sc->end_station && !tx_sc->scb)) {
++	if (sci_present) {
+ 		h->tci_an |= MACSEC_TCI_SC;
+ 		memcpy(&h->secure_channel_id, &secy->sci,
+ 		       sizeof(h->secure_channel_id));
+@@ -650,6 +658,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ 	struct macsec_tx_sc *tx_sc;
+ 	struct macsec_tx_sa *tx_sa;
+ 	struct macsec_dev *macsec = macsec_priv(dev);
++	bool sci_present;
+ 	u32 pn;
+ 
+ 	secy = &macsec->secy;
+@@ -687,7 +696,8 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ 
+ 	unprotected_len = skb->len;
+ 	eth = eth_hdr(skb);
+-	hh = (struct macsec_eth_header *)skb_push(skb, macsec_extra_len(tx_sc->send_sci));
++	sci_present = send_sci(secy);
++	hh = (struct macsec_eth_header *)skb_push(skb, macsec_extra_len(sci_present));
+ 	memmove(hh, eth, 2 * ETH_ALEN);
+ 
+ 	pn = tx_sa_update_pn(tx_sa, secy);
+@@ -696,7 +706,7 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ 		kfree_skb(skb);
+ 		return ERR_PTR(-ENOLINK);
+ 	}
+-	macsec_fill_sectag(hh, secy, pn);
++	macsec_fill_sectag(hh, secy, pn, sci_present);
+ 	macsec_set_shortlen(hh, unprotected_len - 2 * ETH_ALEN);
+ 
+ 	skb_put(skb, secy->icv_len);
+@@ -726,10 +736,10 @@ static struct sk_buff *macsec_encrypt(struct sk_buff *skb,
+ 	skb_to_sgvec(skb, sg, 0, skb->len);
+ 
+ 	if (tx_sc->encrypt) {
+-		int len = skb->len - macsec_hdr_len(tx_sc->send_sci) -
++		int len = skb->len - macsec_hdr_len(sci_present) -
+ 			  secy->icv_len;
+ 		aead_request_set_crypt(req, sg, sg, len, iv);
+-		aead_request_set_ad(req, macsec_hdr_len(tx_sc->send_sci));
++		aead_request_set_ad(req, macsec_hdr_len(sci_present));
+ 	} else {
+ 		aead_request_set_crypt(req, sg, sg, 0, iv);
+ 		aead_request_set_ad(req, skb->len - secy->icv_len);
+diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
+index c6f66832a1a6..f424b867f73e 100644
+--- a/drivers/net/phy/phy.c
++++ b/drivers/net/phy/phy.c
+@@ -608,6 +608,21 @@ void phy_start_machine(struct phy_device *phydev)
+ }
+ 
+ /**
++ * phy_trigger_machine - trigger the state machine to run
++ *
++ * @phydev: the phy_device struct
++ *
++ * Description: There has been a change in state which requires that the
++ *   state machine runs.
++ */
++
++static void phy_trigger_machine(struct phy_device *phydev)
++{
++	cancel_delayed_work_sync(&phydev->state_queue);
++	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
++}
++
++/**
+  * phy_stop_machine - stop the PHY state machine tracking
+  * @phydev: target phy_device struct
+  *
+@@ -639,6 +654,8 @@ static void phy_error(struct phy_device *phydev)
+ 	mutex_lock(&phydev->lock);
+ 	phydev->state = PHY_HALTED;
+ 	mutex_unlock(&phydev->lock);
++
++	phy_trigger_machine(phydev);
+ }
+ 
+ /**
+@@ -800,8 +817,7 @@ void phy_change(struct work_struct *work)
+ 	}
+ 
+ 	/* reschedule state queue work to run as soon as possible */
+-	cancel_delayed_work_sync(&phydev->state_queue);
+-	queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, 0);
++	phy_trigger_machine(phydev);
+ 	return;
+ 
+ ignore:
+@@ -890,6 +906,8 @@ void phy_start(struct phy_device *phydev)
+ 	/* if phy was suspended, bring the physical link up again */
+ 	if (do_resume)
+ 		phy_resume(phydev);
++
++	phy_trigger_machine(phydev);
+ }
+ EXPORT_SYMBOL(phy_start);
+ 
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 6e65832051d6..5ae664c02528 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -584,7 +584,7 @@ static struct sk_buff **vxlan_gro_receive(struct sock *sk,
+ 		}
+ 	}
+ 
+-	pp = eth_gro_receive(head, skb);
++	pp = call_gro_receive(eth_gro_receive, head, skb);
+ 	flush = 0;
+ 
+ out:
+diff --git a/drivers/ptp/ptp_chardev.c b/drivers/ptp/ptp_chardev.c
+index d637c933c8a9..58a97d420572 100644
+--- a/drivers/ptp/ptp_chardev.c
++++ b/drivers/ptp/ptp_chardev.c
+@@ -193,6 +193,7 @@ long ptp_ioctl(struct posix_clock *pc, unsigned int cmd, unsigned long arg)
+ 		if (err)
+ 			break;
+ 
++		memset(&precise_offset, 0, sizeof(precise_offset));
+ 		ts = ktime_to_timespec64(xtstamp.device);
+ 		precise_offset.device.sec = ts.tv_sec;
+ 		precise_offset.device.nsec = ts.tv_nsec;
+diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index ca86c885dfaa..3aaea713bf37 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -2233,7 +2233,7 @@ struct megasas_instance_template {
+ };
+ 
+ #define MEGASAS_IS_LOGICAL(scp)						\
+-	(scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1
++	((scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1)
+ 
+ #define MEGASAS_DEV_INDEX(scp)						\
+ 	(((scp->device->channel % 2) * MEGASAS_MAX_DEV_PER_CHANNEL) +	\
+diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
+index c1ed25adb17e..71e489937c6f 100644
+--- a/drivers/scsi/megaraid/megaraid_sas_base.c
++++ b/drivers/scsi/megaraid/megaraid_sas_base.c
+@@ -1713,16 +1713,13 @@ megasas_queue_command(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
+ 		goto out_done;
+ 	}
+ 
+-	switch (scmd->cmnd[0]) {
+-	case SYNCHRONIZE_CACHE:
+-		/*
+-		 * FW takes care of flush cache on its own
+-		 * No need to send it down
+-		 */
++	/*
++	 * FW takes care of flush cache on its own for Virtual Disk.
++	 * No need to send it down for VD. For JBOD send SYNCHRONIZE_CACHE to FW.
++	 */
++	if ((scmd->cmnd[0] == SYNCHRONIZE_CACHE) && MEGASAS_IS_LOGICAL(scmd)) {
+ 		scmd->result = DID_OK << 16;
+ 		goto out_done;
+-	default:
+-		break;
+ 	}
+ 
+ 	return instance->instancet->build_and_issue_cmd(instance, scmd);
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index 6443cfba7b55..dc3b5962d087 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -789,6 +789,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 		req->trb = trb;
+ 		req->trb_dma = dwc3_trb_dma_offset(dep, trb);
+ 		req->first_trb_index = dep->trb_enqueue;
++		dep->queued_requests++;
+ 	}
+ 
+ 	dwc3_ep_inc_enq(dep);
+@@ -841,8 +842,6 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 
+ 	trb->ctrl |= DWC3_TRB_CTRL_HWO;
+ 
+-	dep->queued_requests++;
+-
+ 	trace_dwc3_prepare_trb(dep, trb);
+ }
+ 
+@@ -1963,7 +1962,9 @@ static int __dwc3_cleanup_done_trbs(struct dwc3 *dwc, struct dwc3_ep *dep,
+ 	unsigned int		s_pkt = 0;
+ 	unsigned int		trb_status;
+ 
+-	dep->queued_requests--;
++	if (req->trb == trb)
++		dep->queued_requests--;
++
+ 	trace_dwc3_complete_trb(dep, trb);
+ 
+ 	/*
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index e8d79d4ebcfe..e942c67ea230 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -2154,7 +2154,10 @@ struct napi_gro_cb {
+ 	/* Used to determine if flush_id can be ignored */
+ 	u8	is_atomic:1;
+ 
+-	/* 5 bit hole */
++	/* Number of gro_receive callbacks this packet already went through */
++	u8 recursion_counter:4;
++
++	/* 1 bit hole */
+ 
+ 	/* used to support CHECKSUM_COMPLETE for tunneling protocols */
+ 	__wsum	csum;
+@@ -2165,6 +2168,40 @@ struct napi_gro_cb {
+ 
+ #define NAPI_GRO_CB(skb) ((struct napi_gro_cb *)(skb)->cb)
+ 
++#define GRO_RECURSION_LIMIT 15
++static inline int gro_recursion_inc_test(struct sk_buff *skb)
++{
++	return ++NAPI_GRO_CB(skb)->recursion_counter == GRO_RECURSION_LIMIT;
++}
++
++typedef struct sk_buff **(*gro_receive_t)(struct sk_buff **, struct sk_buff *);
++static inline struct sk_buff **call_gro_receive(gro_receive_t cb,
++						struct sk_buff **head,
++						struct sk_buff *skb)
++{
++	if (unlikely(gro_recursion_inc_test(skb))) {
++		NAPI_GRO_CB(skb)->flush |= 1;
++		return NULL;
++	}
++
++	return cb(head, skb);
++}
++
++typedef struct sk_buff **(*gro_receive_sk_t)(struct sock *, struct sk_buff **,
++					     struct sk_buff *);
++static inline struct sk_buff **call_gro_receive_sk(gro_receive_sk_t cb,
++						   struct sock *sk,
++						   struct sk_buff **head,
++						   struct sk_buff *skb)
++{
++	if (unlikely(gro_recursion_inc_test(skb))) {
++		NAPI_GRO_CB(skb)->flush |= 1;
++		return NULL;
++	}
++
++	return cb(sk, head, skb);
++}
++
+ struct packet_type {
+ 	__be16			type;	/* This is really htons(ether_type). */
+ 	struct net_device	*dev;	/* NULL is wildcarded here	     */
+@@ -3862,7 +3899,7 @@ struct net_device *netdev_all_lower_get_next_rcu(struct net_device *dev,
+ 	     ldev = netdev_all_lower_get_next(dev, &(iter)))
+ 
+ #define netdev_for_each_all_lower_dev_rcu(dev, ldev, iter) \
+-	for (iter = (dev)->all_adj_list.lower.next, \
++	for (iter = &(dev)->all_adj_list.lower, \
+ 	     ldev = netdev_all_lower_get_next_rcu(dev, &(iter)); \
+ 	     ldev; \
+ 	     ldev = netdev_all_lower_get_next_rcu(dev, &(iter)))
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 9742b92dc933..156b0c11b524 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -549,7 +549,7 @@ int ip_options_rcv_srr(struct sk_buff *skb);
+  */
+ 
+ void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb);
+-void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb, int offset);
++void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb, int tlen, int offset);
+ int ip_cmsg_send(struct sock *sk, struct msghdr *msg,
+ 		 struct ipcm_cookie *ipc, bool allow_ipv6);
+ int ip_setsockopt(struct sock *sk, int level, int optname, char __user *optval,
+@@ -571,7 +571,7 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 dport,
+ 
+ static inline void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb)
+ {
+-	ip_cmsg_recv_offset(msg, skb, 0);
++	ip_cmsg_recv_offset(msg, skb, 0, 0);
+ }
+ 
+ bool icmp_global_allow(void);
+diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
+index d97305d0e71f..0a2d2701285d 100644
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -32,6 +32,7 @@ struct route_info {
+ #define RT6_LOOKUP_F_SRCPREF_TMP	0x00000008
+ #define RT6_LOOKUP_F_SRCPREF_PUBLIC	0x00000010
+ #define RT6_LOOKUP_F_SRCPREF_COA	0x00000020
++#define RT6_LOOKUP_F_IGNORE_LINKSTATE	0x00000040
+ 
+ /* We do not (yet ?) support IPv6 jumbograms (RFC 2675)
+  * Unlike IPv4, hdr->seg_len doesn't include the IPv6 header
+diff --git a/include/uapi/linux/rtnetlink.h b/include/uapi/linux/rtnetlink.h
+index 262f0379d83a..5a78be518101 100644
+--- a/include/uapi/linux/rtnetlink.h
++++ b/include/uapi/linux/rtnetlink.h
+@@ -350,7 +350,7 @@ struct rtnexthop {
+ #define RTNH_F_OFFLOAD		8	/* offloaded route */
+ #define RTNH_F_LINKDOWN		16	/* carrier-down on nexthop */
+ 
+-#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN)
++#define RTNH_COMPARE_MASK	(RTNH_F_DEAD | RTNH_F_LINKDOWN | RTNH_F_OFFLOAD)
+ 
+ /* Macros to handle hexthops */
+ 
+diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
+index 8de138d3306b..f2531ad66b68 100644
+--- a/net/8021q/vlan.c
++++ b/net/8021q/vlan.c
+@@ -664,7 +664,7 @@ static struct sk_buff **vlan_gro_receive(struct sk_buff **head,
+ 
+ 	skb_gro_pull(skb, sizeof(*vhdr));
+ 	skb_gro_postpull_rcsum(skb, vhdr, sizeof(*vhdr));
+-	pp = ptype->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index c5fea9393946..2136e45f5277 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -972,13 +972,12 @@ static void br_multicast_enable(struct bridge_mcast_own_query *query)
+ 		mod_timer(&query->timer, jiffies);
+ }
+ 
+-void br_multicast_enable_port(struct net_bridge_port *port)
++static void __br_multicast_enable_port(struct net_bridge_port *port)
+ {
+ 	struct net_bridge *br = port->br;
+ 
+-	spin_lock(&br->multicast_lock);
+ 	if (br->multicast_disabled || !netif_running(br->dev))
+-		goto out;
++		return;
+ 
+ 	br_multicast_enable(&port->ip4_own_query);
+ #if IS_ENABLED(CONFIG_IPV6)
+@@ -987,8 +986,14 @@ void br_multicast_enable_port(struct net_bridge_port *port)
+ 	if (port->multicast_router == MDB_RTR_TYPE_PERM &&
+ 	    hlist_unhashed(&port->rlist))
+ 		br_multicast_add_router(br, port);
++}
+ 
+-out:
++void br_multicast_enable_port(struct net_bridge_port *port)
++{
++	struct net_bridge *br = port->br;
++
++	spin_lock(&br->multicast_lock);
++	__br_multicast_enable_port(port);
+ 	spin_unlock(&br->multicast_lock);
+ }
+ 
+@@ -1994,8 +1999,9 @@ static void br_multicast_start_querier(struct net_bridge *br,
+ 
+ int br_multicast_toggle(struct net_bridge *br, unsigned long val)
+ {
+-	int err = 0;
+ 	struct net_bridge_mdb_htable *mdb;
++	struct net_bridge_port *port;
++	int err = 0;
+ 
+ 	spin_lock_bh(&br->multicast_lock);
+ 	if (br->multicast_disabled == !val)
+@@ -2023,10 +2029,9 @@ rollback:
+ 			goto rollback;
+ 	}
+ 
+-	br_multicast_start_querier(br, &br->ip4_own_query);
+-#if IS_ENABLED(CONFIG_IPV6)
+-	br_multicast_start_querier(br, &br->ip6_own_query);
+-#endif
++	br_multicast_open(br);
++	list_for_each_entry(port, &br->port_list, list)
++		__br_multicast_enable_port(port);
+ 
+ unlock:
+ 	spin_unlock_bh(&br->multicast_lock);
+diff --git a/net/core/dev.c b/net/core/dev.c
+index ea6312057a71..44b3ba462ba1 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -3035,6 +3035,7 @@ struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *d
+ 	}
+ 	return head;
+ }
++EXPORT_SYMBOL_GPL(validate_xmit_skb_list);
+ 
+ static void qdisc_pkt_len_init(struct sk_buff *skb)
+ {
+@@ -4496,6 +4497,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
+ 		NAPI_GRO_CB(skb)->flush = 0;
+ 		NAPI_GRO_CB(skb)->free = 0;
+ 		NAPI_GRO_CB(skb)->encap_mark = 0;
++		NAPI_GRO_CB(skb)->recursion_counter = 0;
+ 		NAPI_GRO_CB(skb)->is_fou = 0;
+ 		NAPI_GRO_CB(skb)->is_atomic = 1;
+ 		NAPI_GRO_CB(skb)->gro_remcsum_start = 0;
+@@ -5500,10 +5502,14 @@ struct net_device *netdev_all_lower_get_next_rcu(struct net_device *dev,
+ {
+ 	struct netdev_adjacent *lower;
+ 
+-	lower = list_first_or_null_rcu(&dev->all_adj_list.lower,
+-				       struct netdev_adjacent, list);
++	lower = list_entry_rcu((*iter)->next, struct netdev_adjacent, list);
++
++	if (&lower->list == &dev->all_adj_list.lower)
++		return NULL;
++
++	*iter = &lower->list;
+ 
+-	return lower ? lower->dev : NULL;
++	return lower->dev;
+ }
+ EXPORT_SYMBOL(netdev_all_lower_get_next_rcu);
+ 
+@@ -5578,6 +5584,7 @@ static inline bool netdev_adjacent_is_neigh_list(struct net_device *dev,
+ 
+ static int __netdev_adjacent_dev_insert(struct net_device *dev,
+ 					struct net_device *adj_dev,
++					u16 ref_nr,
+ 					struct list_head *dev_list,
+ 					void *private, bool master)
+ {
+@@ -5587,7 +5594,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
+ 	adj = __netdev_find_adj(adj_dev, dev_list);
+ 
+ 	if (adj) {
+-		adj->ref_nr++;
++		adj->ref_nr += ref_nr;
+ 		return 0;
+ 	}
+ 
+@@ -5597,7 +5604,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
+ 
+ 	adj->dev = adj_dev;
+ 	adj->master = master;
+-	adj->ref_nr = 1;
++	adj->ref_nr = ref_nr;
+ 	adj->private = private;
+ 	dev_hold(adj_dev);
+ 
+@@ -5636,6 +5643,7 @@ free_adj:
+ 
+ static void __netdev_adjacent_dev_remove(struct net_device *dev,
+ 					 struct net_device *adj_dev,
++					 u16 ref_nr,
+ 					 struct list_head *dev_list)
+ {
+ 	struct netdev_adjacent *adj;
+@@ -5648,10 +5656,10 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,
+ 		BUG();
+ 	}
+ 
+-	if (adj->ref_nr > 1) {
+-		pr_debug("%s to %s ref_nr-- = %d\n", dev->name, adj_dev->name,
+-			 adj->ref_nr-1);
+-		adj->ref_nr--;
++	if (adj->ref_nr > ref_nr) {
++		pr_debug("%s to %s ref_nr-%d = %d\n", dev->name, adj_dev->name,
++			 ref_nr, adj->ref_nr-ref_nr);
++		adj->ref_nr -= ref_nr;
+ 		return;
+ 	}
+ 
+@@ -5670,21 +5678,22 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,
+ 
+ static int __netdev_adjacent_dev_link_lists(struct net_device *dev,
+ 					    struct net_device *upper_dev,
++					    u16 ref_nr,
+ 					    struct list_head *up_list,
+ 					    struct list_head *down_list,
+ 					    void *private, bool master)
+ {
+ 	int ret;
+ 
+-	ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private,
+-					   master);
++	ret = __netdev_adjacent_dev_insert(dev, upper_dev, ref_nr, up_list,
++					   private, master);
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private,
+-					   false);
++	ret = __netdev_adjacent_dev_insert(upper_dev, dev, ref_nr, down_list,
++					   private, false);
+ 	if (ret) {
+-		__netdev_adjacent_dev_remove(dev, upper_dev, up_list);
++		__netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list);
+ 		return ret;
+ 	}
+ 
+@@ -5692,9 +5701,10 @@ static int __netdev_adjacent_dev_link_lists(struct net_device *dev,
+ }
+ 
+ static int __netdev_adjacent_dev_link(struct net_device *dev,
+-				      struct net_device *upper_dev)
++				      struct net_device *upper_dev,
++				      u16 ref_nr)
+ {
+-	return __netdev_adjacent_dev_link_lists(dev, upper_dev,
++	return __netdev_adjacent_dev_link_lists(dev, upper_dev, ref_nr,
+ 						&dev->all_adj_list.upper,
+ 						&upper_dev->all_adj_list.lower,
+ 						NULL, false);
+@@ -5702,17 +5712,19 @@ static int __netdev_adjacent_dev_link(struct net_device *dev,
+ 
+ static void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
+ 					       struct net_device *upper_dev,
++					       u16 ref_nr,
+ 					       struct list_head *up_list,
+ 					       struct list_head *down_list)
+ {
+-	__netdev_adjacent_dev_remove(dev, upper_dev, up_list);
+-	__netdev_adjacent_dev_remove(upper_dev, dev, down_list);
++	__netdev_adjacent_dev_remove(dev, upper_dev, ref_nr, up_list);
++	__netdev_adjacent_dev_remove(upper_dev, dev, ref_nr, down_list);
+ }
+ 
+ static void __netdev_adjacent_dev_unlink(struct net_device *dev,
+-					 struct net_device *upper_dev)
++					 struct net_device *upper_dev,
++					 u16 ref_nr)
+ {
+-	__netdev_adjacent_dev_unlink_lists(dev, upper_dev,
++	__netdev_adjacent_dev_unlink_lists(dev, upper_dev, ref_nr,
+ 					   &dev->all_adj_list.upper,
+ 					   &upper_dev->all_adj_list.lower);
+ }
+@@ -5721,17 +5733,17 @@ static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
+ 						struct net_device *upper_dev,
+ 						void *private, bool master)
+ {
+-	int ret = __netdev_adjacent_dev_link(dev, upper_dev);
++	int ret = __netdev_adjacent_dev_link(dev, upper_dev, 1);
+ 
+ 	if (ret)
+ 		return ret;
+ 
+-	ret = __netdev_adjacent_dev_link_lists(dev, upper_dev,
++	ret = __netdev_adjacent_dev_link_lists(dev, upper_dev, 1,
+ 					       &dev->adj_list.upper,
+ 					       &upper_dev->adj_list.lower,
+ 					       private, master);
+ 	if (ret) {
+-		__netdev_adjacent_dev_unlink(dev, upper_dev);
++		__netdev_adjacent_dev_unlink(dev, upper_dev, 1);
+ 		return ret;
+ 	}
+ 
+@@ -5741,8 +5753,8 @@ static int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
+ static void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
+ 						   struct net_device *upper_dev)
+ {
+-	__netdev_adjacent_dev_unlink(dev, upper_dev);
+-	__netdev_adjacent_dev_unlink_lists(dev, upper_dev,
++	__netdev_adjacent_dev_unlink(dev, upper_dev, 1);
++	__netdev_adjacent_dev_unlink_lists(dev, upper_dev, 1,
+ 					   &dev->adj_list.upper,
+ 					   &upper_dev->adj_list.lower);
+ }
+@@ -5795,7 +5807,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
+ 		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) {
+ 			pr_debug("Interlinking %s with %s, non-neighbour\n",
+ 				 i->dev->name, j->dev->name);
+-			ret = __netdev_adjacent_dev_link(i->dev, j->dev);
++			ret = __netdev_adjacent_dev_link(i->dev, j->dev, i->ref_nr);
+ 			if (ret)
+ 				goto rollback_mesh;
+ 		}
+@@ -5805,7 +5817,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
+ 	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) {
+ 		pr_debug("linking %s's upper device %s with %s\n",
+ 			 upper_dev->name, i->dev->name, dev->name);
+-		ret = __netdev_adjacent_dev_link(dev, i->dev);
++		ret = __netdev_adjacent_dev_link(dev, i->dev, i->ref_nr);
+ 		if (ret)
+ 			goto rollback_upper_mesh;
+ 	}
+@@ -5814,7 +5826,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
+ 	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
+ 		pr_debug("linking %s's lower device %s with %s\n", dev->name,
+ 			 i->dev->name, upper_dev->name);
+-		ret = __netdev_adjacent_dev_link(i->dev, upper_dev);
++		ret = __netdev_adjacent_dev_link(i->dev, upper_dev, i->ref_nr);
+ 		if (ret)
+ 			goto rollback_lower_mesh;
+ 	}
+@@ -5832,7 +5844,7 @@ rollback_lower_mesh:
+ 	list_for_each_entry(i, &dev->all_adj_list.lower, list) {
+ 		if (i == to_i)
+ 			break;
+-		__netdev_adjacent_dev_unlink(i->dev, upper_dev);
++		__netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr);
+ 	}
+ 
+ 	i = NULL;
+@@ -5842,7 +5854,7 @@ rollback_upper_mesh:
+ 	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list) {
+ 		if (i == to_i)
+ 			break;
+-		__netdev_adjacent_dev_unlink(dev, i->dev);
++		__netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr);
+ 	}
+ 
+ 	i = j = NULL;
+@@ -5854,7 +5866,7 @@ rollback_mesh:
+ 		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list) {
+ 			if (i == to_i && j == to_j)
+ 				break;
+-			__netdev_adjacent_dev_unlink(i->dev, j->dev);
++			__netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr);
+ 		}
+ 		if (i == to_i)
+ 			break;
+@@ -5934,16 +5946,16 @@ void netdev_upper_dev_unlink(struct net_device *dev,
+ 	 */
+ 	list_for_each_entry(i, &dev->all_adj_list.lower, list)
+ 		list_for_each_entry(j, &upper_dev->all_adj_list.upper, list)
+-			__netdev_adjacent_dev_unlink(i->dev, j->dev);
++			__netdev_adjacent_dev_unlink(i->dev, j->dev, i->ref_nr);
+ 
+ 	/* remove also the devices itself from lower/upper device
+ 	 * list
+ 	 */
+ 	list_for_each_entry(i, &dev->all_adj_list.lower, list)
+-		__netdev_adjacent_dev_unlink(i->dev, upper_dev);
++		__netdev_adjacent_dev_unlink(i->dev, upper_dev, i->ref_nr);
+ 
+ 	list_for_each_entry(i, &upper_dev->all_adj_list.upper, list)
+-		__netdev_adjacent_dev_unlink(dev, i->dev);
++		__netdev_adjacent_dev_unlink(dev, i->dev, i->ref_nr);
+ 
+ 	call_netdevice_notifiers_info(NETDEV_CHANGEUPPER, dev,
+ 				      &changeupper_info.info);
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index bbd118b19aef..306b8f0e03c1 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -216,8 +216,8 @@
+ #define M_QUEUE_XMIT		2	/* Inject packet into qdisc */
+ 
+ /* If lock -- protects updating of if_list */
+-#define   if_lock(t)           spin_lock(&(t->if_lock));
+-#define   if_unlock(t)           spin_unlock(&(t->if_lock));
++#define   if_lock(t)           mutex_lock(&(t->if_lock));
++#define   if_unlock(t)           mutex_unlock(&(t->if_lock));
+ 
+ /* Used to help with determining the pkts on receive */
+ #define PKTGEN_MAGIC 0xbe9be955
+@@ -423,7 +423,7 @@ struct pktgen_net {
+ };
+ 
+ struct pktgen_thread {
+-	spinlock_t if_lock;		/* for list of devices */
++	struct mutex if_lock;		/* for list of devices */
+ 	struct list_head if_list;	/* All device here */
+ 	struct list_head th_list;
+ 	struct task_struct *tsk;
+@@ -2010,11 +2010,13 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d
+ {
+ 	struct pktgen_thread *t;
+ 
++	mutex_lock(&pktgen_thread_lock);
++
+ 	list_for_each_entry(t, &pn->pktgen_threads, th_list) {
+ 		struct pktgen_dev *pkt_dev;
+ 
+-		rcu_read_lock();
+-		list_for_each_entry_rcu(pkt_dev, &t->if_list, list) {
++		if_lock(t);
++		list_for_each_entry(pkt_dev, &t->if_list, list) {
+ 			if (pkt_dev->odev != dev)
+ 				continue;
+ 
+@@ -2029,8 +2031,9 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d
+ 				       dev->name);
+ 			break;
+ 		}
+-		rcu_read_unlock();
++		if_unlock(t);
+ 	}
++	mutex_unlock(&pktgen_thread_lock);
+ }
+ 
+ static int pktgen_device_event(struct notifier_block *unused,
+@@ -2286,7 +2289,7 @@ out:
+ 
+ static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev)
+ {
+-	pkt_dev->pkt_overhead = LL_RESERVED_SPACE(pkt_dev->odev);
++	pkt_dev->pkt_overhead = 0;
+ 	pkt_dev->pkt_overhead += pkt_dev->nr_labels*sizeof(u32);
+ 	pkt_dev->pkt_overhead += VLAN_TAG_SIZE(pkt_dev);
+ 	pkt_dev->pkt_overhead += SVLAN_TAG_SIZE(pkt_dev);
+@@ -2777,13 +2780,13 @@ static void pktgen_finalize_skb(struct pktgen_dev *pkt_dev, struct sk_buff *skb,
+ }
+ 
+ static struct sk_buff *pktgen_alloc_skb(struct net_device *dev,
+-					struct pktgen_dev *pkt_dev,
+-					unsigned int extralen)
++					struct pktgen_dev *pkt_dev)
+ {
++	unsigned int extralen = LL_RESERVED_SPACE(dev);
+ 	struct sk_buff *skb = NULL;
+-	unsigned int size = pkt_dev->cur_pkt_size + 64 + extralen +
+-			    pkt_dev->pkt_overhead;
++	unsigned int size;
+ 
++	size = pkt_dev->cur_pkt_size + 64 + extralen + pkt_dev->pkt_overhead;
+ 	if (pkt_dev->flags & F_NODE) {
+ 		int node = pkt_dev->node >= 0 ? pkt_dev->node : numa_node_id();
+ 
+@@ -2796,8 +2799,9 @@ static struct sk_buff *pktgen_alloc_skb(struct net_device *dev,
+ 		 skb = __netdev_alloc_skb(dev, size, GFP_NOWAIT);
+ 	}
+ 
++	/* the caller pre-fetches from skb->data and reserves for the mac hdr */
+ 	if (likely(skb))
+-		skb_reserve(skb, LL_RESERVED_SPACE(dev));
++		skb_reserve(skb, extralen - 16);
+ 
+ 	return skb;
+ }
+@@ -2830,16 +2834,14 @@ static struct sk_buff *fill_packet_ipv4(struct net_device *odev,
+ 	mod_cur_headers(pkt_dev);
+ 	queue_map = pkt_dev->cur_queue_map;
+ 
+-	datalen = (odev->hard_header_len + 16) & ~0xf;
+-
+-	skb = pktgen_alloc_skb(odev, pkt_dev, datalen);
++	skb = pktgen_alloc_skb(odev, pkt_dev);
+ 	if (!skb) {
+ 		sprintf(pkt_dev->result, "No memory");
+ 		return NULL;
+ 	}
+ 
+ 	prefetchw(skb->data);
+-	skb_reserve(skb, datalen);
++	skb_reserve(skb, 16);
+ 
+ 	/*  Reserve for ethernet and IP header  */
+ 	eth = (__u8 *) skb_push(skb, 14);
+@@ -2959,7 +2961,7 @@ static struct sk_buff *fill_packet_ipv6(struct net_device *odev,
+ 	mod_cur_headers(pkt_dev);
+ 	queue_map = pkt_dev->cur_queue_map;
+ 
+-	skb = pktgen_alloc_skb(odev, pkt_dev, 16);
++	skb = pktgen_alloc_skb(odev, pkt_dev);
+ 	if (!skb) {
+ 		sprintf(pkt_dev->result, "No memory");
+ 		return NULL;
+@@ -3763,7 +3765,7 @@ static int __net_init pktgen_create_thread(int cpu, struct pktgen_net *pn)
+ 		return -ENOMEM;
+ 	}
+ 
+-	spin_lock_init(&t->if_lock);
++	mutex_init(&t->if_lock);
+ 	t->cpu = cpu;
+ 
+ 	INIT_LIST_HEAD(&t->if_list);
+diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
+index 66dff5e3d772..02acfff36028 100644
+--- a/net/ethernet/eth.c
++++ b/net/ethernet/eth.c
+@@ -439,7 +439,7 @@ struct sk_buff **eth_gro_receive(struct sk_buff **head,
+ 
+ 	skb_gro_pull(skb, sizeof(*eh));
+ 	skb_gro_postpull_rcsum(skb, eh, sizeof(*eh));
+-	pp = ptype->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 55513e654d79..eebbc0f2baa8 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1388,7 +1388,7 @@ struct sk_buff **inet_gro_receive(struct sk_buff **head, struct sk_buff *skb)
+ 	skb_gro_pull(skb, sizeof(*iph));
+ 	skb_set_transport_header(skb, skb_gro_offset(skb));
+ 
+-	pp = ops->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
+index 321d57f825ce..5351b61ab8d3 100644
+--- a/net/ipv4/fou.c
++++ b/net/ipv4/fou.c
+@@ -249,7 +249,7 @@ static struct sk_buff **fou_gro_receive(struct sock *sk,
+ 	if (!ops || !ops->callbacks.gro_receive)
+ 		goto out_unlock;
+ 
+-	pp = ops->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+@@ -441,7 +441,7 @@ next_proto:
+ 	if (WARN_ON_ONCE(!ops || !ops->callbacks.gro_receive))
+ 		goto out_unlock;
+ 
+-	pp = ops->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ 	flush = 0;
+ 
+ out_unlock:
+diff --git a/net/ipv4/gre_offload.c b/net/ipv4/gre_offload.c
+index ecd1e09dbbf1..6871f59cd0c0 100644
+--- a/net/ipv4/gre_offload.c
++++ b/net/ipv4/gre_offload.c
+@@ -227,7 +227,7 @@ static struct sk_buff **gre_gro_receive(struct sk_buff **head,
+ 	/* Adjusted NAPI_GRO_CB(skb)->csum after skb_gro_pull()*/
+ 	skb_gro_postpull_rcsum(skb, greh, grehlen);
+ 
+-	pp = ptype->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ptype->callbacks.gro_receive, head, skb);
+ 	flush = 0;
+ 
+ out_unlock:
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index 71a52f4d4cff..11ef96e2147a 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -98,7 +98,7 @@ static void ip_cmsg_recv_retopts(struct msghdr *msg, struct sk_buff *skb)
+ }
+ 
+ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
+-				  int offset)
++				  int tlen, int offset)
+ {
+ 	__wsum csum = skb->csum;
+ 
+@@ -106,8 +106,9 @@ static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
+ 		return;
+ 
+ 	if (offset != 0)
+-		csum = csum_sub(csum, csum_partial(skb_transport_header(skb),
+-						   offset, 0));
++		csum = csum_sub(csum,
++				csum_partial(skb_transport_header(skb) + tlen,
++					     offset, 0));
+ 
+ 	put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
+ }
+@@ -153,7 +154,7 @@ static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
+ }
+ 
+ void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb,
+-			 int offset)
++			 int tlen, int offset)
+ {
+ 	struct inet_sock *inet = inet_sk(skb->sk);
+ 	unsigned int flags = inet->cmsg_flags;
+@@ -216,7 +217,7 @@ void ip_cmsg_recv_offset(struct msghdr *msg, struct sk_buff *skb,
+ 	}
+ 
+ 	if (flags & IP_CMSG_CHECKSUM)
+-		ip_cmsg_recv_checksum(msg, skb, offset);
++		ip_cmsg_recv_checksum(msg, skb, tlen, offset);
+ }
+ EXPORT_SYMBOL(ip_cmsg_recv_offset);
+ 
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 1cb67de106fe..80bc36b25de2 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -96,11 +96,11 @@ static void inet_get_ping_group_range_table(struct ctl_table *table, kgid_t *low
+ 		container_of(table->data, struct net, ipv4.ping_group_range.range);
+ 	unsigned int seq;
+ 	do {
+-		seq = read_seqbegin(&net->ipv4.ip_local_ports.lock);
++		seq = read_seqbegin(&net->ipv4.ping_group_range.lock);
+ 
+ 		*low = data[0];
+ 		*high = data[1];
+-	} while (read_seqretry(&net->ipv4.ip_local_ports.lock, seq));
++	} while (read_seqretry(&net->ipv4.ping_group_range.lock, seq));
+ }
+ 
+ /* Update system visible IP port range */
+@@ -109,10 +109,10 @@ static void set_ping_group_range(struct ctl_table *table, kgid_t low, kgid_t hig
+ 	kgid_t *data = table->data;
+ 	struct net *net =
+ 		container_of(table->data, struct net, ipv4.ping_group_range.range);
+-	write_seqlock(&net->ipv4.ip_local_ports.lock);
++	write_seqlock(&net->ipv4.ping_group_range.lock);
+ 	data[0] = low;
+ 	data[1] = high;
+-	write_sequnlock(&net->ipv4.ip_local_ports.lock);
++	write_sequnlock(&net->ipv4.ping_group_range.lock);
+ }
+ 
+ /* Validate changes from /proc interface. */
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 5fdcb8d108d4..c0d71e7d663e 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1327,7 +1327,7 @@ try_again:
+ 		*addr_len = sizeof(*sin);
+ 	}
+ 	if (inet->cmsg_flags)
+-		ip_cmsg_recv_offset(msg, skb, sizeof(struct udphdr) + off);
++		ip_cmsg_recv_offset(msg, skb, sizeof(struct udphdr), off);
+ 
+ 	err = copied;
+ 	if (flags & MSG_TRUNC)
+diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c
+index 81f253b6ff36..6de9f977356e 100644
+--- a/net/ipv4/udp_offload.c
++++ b/net/ipv4/udp_offload.c
+@@ -293,7 +293,7 @@ unflush:
+ 
+ 	skb_gro_pull(skb, sizeof(struct udphdr)); /* pull encapsulating udp header */
+ 	skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr));
+-	pp = udp_sk(sk)->gro_receive(sk, head, skb);
++	pp = call_gro_receive_sk(udp_sk(sk)->gro_receive, sk, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 2f1f5d439788..f5432d65e6bf 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -2995,7 +2995,7 @@ static void init_loopback(struct net_device *dev)
+ 				 * lo device down, release this obsolete dst and
+ 				 * reallocate a new router for ifa.
+ 				 */
+-				if (sp_ifa->rt->dst.obsolete > 0) {
++				if (!atomic_read(&sp_ifa->rt->rt6i_ref)) {
+ 					ip6_rt_put(sp_ifa->rt);
+ 					sp_ifa->rt = NULL;
+ 				} else {
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
+index 22e90e56b5a9..a09418bda1f8 100644
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -243,7 +243,7 @@ static struct sk_buff **ipv6_gro_receive(struct sk_buff **head,
+ 
+ 	skb_gro_postpull_rcsum(skb, iph, nlen);
+ 
+-	pp = ops->callbacks.gro_receive(head, skb);
++	pp = call_gro_receive(ops->callbacks.gro_receive, head, skb);
+ 
+ out_unlock:
+ 	rcu_read_unlock();
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 888543debe4e..41489f39c456 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -155,6 +155,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
+ 	hash = HASH(&any, local);
+ 	for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ 		if (ipv6_addr_equal(local, &t->parms.laddr) &&
++		    ipv6_addr_any(&t->parms.raddr) &&
+ 		    (t->dev->flags & IFF_UP))
+ 			return t;
+ 	}
+@@ -162,6 +163,7 @@ ip6_tnl_lookup(struct net *net, const struct in6_addr *remote, const struct in6_
+ 	hash = HASH(remote, &any);
+ 	for_each_ip6_tunnel_rcu(ip6n->tnls_r_l[hash]) {
+ 		if (ipv6_addr_equal(remote, &t->parms.raddr) &&
++		    ipv6_addr_any(&t->parms.laddr) &&
+ 		    (t->dev->flags & IFF_UP))
+ 			return t;
+ 	}
+@@ -1132,6 +1134,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ 	if (err)
+ 		return err;
+ 
++	skb->protocol = htons(ETH_P_IPV6);
+ 	skb_push(skb, sizeof(struct ipv6hdr));
+ 	skb_reset_network_header(skb);
+ 	ipv6h = ipv6_hdr(skb);
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index 269218aacbea..23153ac6c9b9 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -656,7 +656,8 @@ static struct rt6_info *find_match(struct rt6_info *rt, int oif, int strict,
+ 	struct net_device *dev = rt->dst.dev;
+ 
+ 	if (dev && !netif_carrier_ok(dev) &&
+-	    idev->cnf.ignore_routes_with_linkdown)
++	    idev->cnf.ignore_routes_with_linkdown &&
++	    !(strict & RT6_LOOKUP_F_IGNORE_LINKSTATE))
+ 		goto out;
+ 
+ 	if (rt6_check_expired(rt))
+@@ -1050,6 +1051,7 @@ struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
+ 	int strict = 0;
+ 
+ 	strict |= flags & RT6_LOOKUP_F_IFACE;
++	strict |= flags & RT6_LOOKUP_F_IGNORE_LINKSTATE;
+ 	if (net->ipv6.devconf_all->forwarding == 0)
+ 		strict |= RT6_LOOKUP_F_REACHABLE;
+ 
+@@ -1783,7 +1785,7 @@ static struct rt6_info *ip6_nh_lookup_table(struct net *net,
+ 	};
+ 	struct fib6_table *table;
+ 	struct rt6_info *rt;
+-	int flags = RT6_LOOKUP_F_IFACE;
++	int flags = RT6_LOOKUP_F_IFACE | RT6_LOOKUP_F_IGNORE_LINKSTATE;
+ 
+ 	table = fib6_get_table(net, cfg->fc_table);
+ 	if (!table)
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index 94f4f89d73e7..fc67822c42e0 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1193,6 +1193,16 @@ out:
+ 	return NULL;
+ }
+ 
++static void tcp_v6_restore_cb(struct sk_buff *skb)
++{
++	/* We need to move header back to the beginning if xfrm6_policy_check()
++	 * and tcp_v6_fill_cb() are going to be called again.
++	 * ip6_datagram_recv_specific_ctl() also expects IP6CB to be there.
++	 */
++	memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
++		sizeof(struct inet6_skb_parm));
++}
++
+ /* The socket must have it's spinlock held when we get
+  * here, unless it is a TCP_LISTEN socket.
+  *
+@@ -1322,6 +1332,7 @@ ipv6_pktoptions:
+ 			np->flow_label = ip6_flowlabel(ipv6_hdr(opt_skb));
+ 		if (ipv6_opt_accepted(sk, opt_skb, &TCP_SKB_CB(opt_skb)->header.h6)) {
+ 			skb_set_owner_r(opt_skb, sk);
++			tcp_v6_restore_cb(opt_skb);
+ 			opt_skb = xchg(&np->pktoptions, opt_skb);
+ 		} else {
+ 			__kfree_skb(opt_skb);
+@@ -1355,15 +1366,6 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr,
+ 	TCP_SKB_CB(skb)->sacked = 0;
+ }
+ 
+-static void tcp_v6_restore_cb(struct sk_buff *skb)
+-{
+-	/* We need to move header back to the beginning if xfrm6_policy_check()
+-	 * and tcp_v6_fill_cb() are going to be called again.
+-	 */
+-	memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6,
+-		sizeof(struct inet6_skb_parm));
+-}
+-
+ static int tcp_v6_rcv(struct sk_buff *skb)
+ {
+ 	const struct tcphdr *th;
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 19ac3a1c308d..c2a8656c22eb 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -427,7 +427,8 @@ try_again:
+ 
+ 	if (is_udp4) {
+ 		if (inet->cmsg_flags)
+-			ip_cmsg_recv(msg, skb);
++			ip_cmsg_recv_offset(msg, skb,
++					    sizeof(struct udphdr), off);
+ 	} else {
+ 		if (np->rxopt.all)
+ 			ip6_datagram_recv_specific_ctl(sk, msg, skb);
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 627f898c05b9..62bea4591054 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -1832,7 +1832,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,
+ 	/* Record the max length of recvmsg() calls for future allocations */
+ 	nlk->max_recvmsg_len = max(nlk->max_recvmsg_len, len);
+ 	nlk->max_recvmsg_len = min_t(size_t, nlk->max_recvmsg_len,
+-				     16384);
++				     SKB_WITH_OVERHEAD(32768));
+ 
+ 	copied = data_skb->len;
+ 	if (len < copied) {
+@@ -2083,8 +2083,9 @@ static int netlink_dump(struct sock *sk)
+ 
+ 	if (alloc_min_size < nlk->max_recvmsg_len) {
+ 		alloc_size = nlk->max_recvmsg_len;
+-		skb = alloc_skb(alloc_size, GFP_KERNEL |
+-					    __GFP_NOWARN | __GFP_NORETRY);
++		skb = alloc_skb(alloc_size,
++				(GFP_KERNEL & ~__GFP_DIRECT_RECLAIM) |
++				__GFP_NOWARN | __GFP_NORETRY);
+ 	}
+ 	if (!skb) {
+ 		alloc_size = alloc_min_size;
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 33a4697d5539..d2238b204691 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -250,7 +250,7 @@ static void __fanout_link(struct sock *sk, struct packet_sock *po);
+ static int packet_direct_xmit(struct sk_buff *skb)
+ {
+ 	struct net_device *dev = skb->dev;
+-	netdev_features_t features;
++	struct sk_buff *orig_skb = skb;
+ 	struct netdev_queue *txq;
+ 	int ret = NETDEV_TX_BUSY;
+ 
+@@ -258,9 +258,8 @@ static int packet_direct_xmit(struct sk_buff *skb)
+ 		     !netif_carrier_ok(dev)))
+ 		goto drop;
+ 
+-	features = netif_skb_features(skb);
+-	if (skb_needs_linearize(skb, features) &&
+-	    __skb_linearize(skb))
++	skb = validate_xmit_skb_list(skb, dev);
++	if (skb != orig_skb)
+ 		goto drop;
+ 
+ 	txq = skb_get_tx_queue(dev, skb);
+@@ -280,7 +279,7 @@ static int packet_direct_xmit(struct sk_buff *skb)
+ 	return ret;
+ drop:
+ 	atomic_long_inc(&dev->tx_dropped);
+-	kfree_skb(skb);
++	kfree_skb_list(skb);
+ 	return NET_XMIT_DROP;
+ }
+ 
+@@ -3952,6 +3951,7 @@ static int packet_notifier(struct notifier_block *this,
+ 				}
+ 				if (msg == NETDEV_UNREGISTER) {
+ 					packet_cached_dev_reset(po);
++					fanout_release(sk);
+ 					po->ifindex = -1;
+ 					if (po->prot_hook.dev)
+ 						dev_put(po->prot_hook.dev);
+diff --git a/net/sched/act_api.c b/net/sched/act_api.c
+index d09d0687594b..027ddf412c40 100644
+--- a/net/sched/act_api.c
++++ b/net/sched/act_api.c
+@@ -341,22 +341,25 @@ int tcf_register_action(struct tc_action_ops *act,
+ 	if (!act->act || !act->dump || !act->init || !act->walk || !act->lookup)
+ 		return -EINVAL;
+ 
++	/* We have to register pernet ops before making the action ops visible,
++	 * otherwise tcf_action_init_1() could get a partially initialized
++	 * netns.
++	 */
++	ret = register_pernet_subsys(ops);
++	if (ret)
++		return ret;
++
+ 	write_lock(&act_mod_lock);
+ 	list_for_each_entry(a, &act_base, head) {
+ 		if (act->type == a->type || (strcmp(act->kind, a->kind) == 0)) {
+ 			write_unlock(&act_mod_lock);
++			unregister_pernet_subsys(ops);
+ 			return -EEXIST;
+ 		}
+ 	}
+ 	list_add_tail(&act->head, &act_base);
+ 	write_unlock(&act_mod_lock);
+ 
+-	ret = register_pernet_subsys(ops);
+-	if (ret) {
+-		tcf_unregister_action(act, ops);
+-		return ret;
+-	}
+-
+ 	return 0;
+ }
+ EXPORT_SYMBOL(tcf_register_action);
+@@ -367,8 +370,6 @@ int tcf_unregister_action(struct tc_action_ops *act,
+ 	struct tc_action_ops *a;
+ 	int err = -ENOENT;
+ 
+-	unregister_pernet_subsys(ops);
+-
+ 	write_lock(&act_mod_lock);
+ 	list_for_each_entry(a, &act_base, head) {
+ 		if (a == act) {
+@@ -378,6 +379,8 @@ int tcf_unregister_action(struct tc_action_ops *act,
+ 		}
+ 	}
+ 	write_unlock(&act_mod_lock);
++	if (!err)
++		unregister_pernet_subsys(ops);
+ 	return err;
+ }
+ EXPORT_SYMBOL(tcf_unregister_action);
+diff --git a/net/sched/act_vlan.c b/net/sched/act_vlan.c
+index 691409de3e1a..4ffc6c13a566 100644
+--- a/net/sched/act_vlan.c
++++ b/net/sched/act_vlan.c
+@@ -36,6 +36,12 @@ static int tcf_vlan(struct sk_buff *skb, const struct tc_action *a,
+ 	bstats_update(&v->tcf_bstats, skb);
+ 	action = v->tcf_action;
+ 
++	/* Ensure 'data' points at mac_header prior calling vlan manipulating
++	 * functions.
++	 */
++	if (skb_at_tc_ingress(skb))
++		skb_push_rcsum(skb, skb->mac_len);
++
+ 	switch (v->tcfv_action) {
+ 	case TCA_VLAN_ACT_POP:
+ 		err = skb_vlan_pop(skb);
+@@ -57,6 +63,9 @@ drop:
+ 	action = TC_ACT_SHOT;
+ 	v->tcf_qstats.drops++;
+ unlock:
++	if (skb_at_tc_ingress(skb))
++		skb_pull_rcsum(skb, skb->mac_len);
++
+ 	spin_unlock(&v->tcf_lock);
+ 	return action;
+ }
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
+index a7c5645373af..74bed5e9bb89 100644
+--- a/net/sched/cls_api.c
++++ b/net/sched/cls_api.c
+@@ -344,7 +344,8 @@ replay:
+ 			if (err == 0) {
+ 				struct tcf_proto *next = rtnl_dereference(tp->next);
+ 
+-				tfilter_notify(net, skb, n, tp, fh, RTM_DELTFILTER);
++				tfilter_notify(net, skb, n, tp,
++					       t->tcm_handle, RTM_DELTFILTER);
+ 				if (tcf_destroy(tp, false))
+ 					RCU_INIT_POINTER(*back, next);
+ 			}
+diff --git a/net/sctp/output.c b/net/sctp/output.c
+index 31b7bc35895d..81929907a365 100644
+--- a/net/sctp/output.c
++++ b/net/sctp/output.c
+@@ -417,6 +417,7 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
+ 	__u8 has_data = 0;
+ 	int gso = 0;
+ 	int pktcount = 0;
++	int auth_len = 0;
+ 	struct dst_entry *dst;
+ 	unsigned char *auth = NULL;	/* pointer to auth in skb data */
+ 
+@@ -505,7 +506,12 @@ int sctp_packet_transmit(struct sctp_packet *packet, gfp_t gfp)
+ 			list_for_each_entry(chunk, &packet->chunk_list, list) {
+ 				int padded = WORD_ROUND(chunk->skb->len);
+ 
+-				if (pkt_size + padded > tp->pathmtu)
++				if (chunk == packet->auth)
++					auth_len = padded;
++				else if (auth_len + padded + packet->overhead >
++					 tp->pathmtu)
++					goto nomem;
++				else if (pkt_size + padded > tp->pathmtu)
+ 					break;
+ 				pkt_size += padded;
+ 			}
+diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
+index d88bb2b0b699..920469e7b0ef 100644
+--- a/net/sctp/sm_statefuns.c
++++ b/net/sctp/sm_statefuns.c
+@@ -3422,6 +3422,12 @@ sctp_disposition_t sctp_sf_ootb(struct net *net,
+ 			return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+ 						  commands);
+ 
++		/* Report violation if chunk len overflows */
++		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
++		if (ch_end > skb_tail_pointer(skb))
++			return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
++						  commands);
++
+ 		/* Now that we know we at least have a chunk header,
+ 		 * do things that are type appropriate.
+ 		 */
+@@ -3453,12 +3459,6 @@ sctp_disposition_t sctp_sf_ootb(struct net *net,
+ 			}
+ 		}
+ 
+-		/* Report violation if chunk len overflows */
+-		ch_end = ((__u8 *)ch) + WORD_ROUND(ntohs(ch->length));
+-		if (ch_end > skb_tail_pointer(skb))
+-			return sctp_sf_violation_chunklen(net, ep, asoc, type, arg,
+-						  commands);
+-
+ 		ch = (sctp_chunkhdr_t *) ch_end;
+ 	} while (ch_end < skb_tail_pointer(skb));
+ 
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 8ed2d99bde6d..baccbf3c1c60 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -4683,7 +4683,7 @@ static int sctp_getsockopt_disable_fragments(struct sock *sk, int len,
+ static int sctp_getsockopt_events(struct sock *sk, int len, char __user *optval,
+ 				  int __user *optlen)
+ {
+-	if (len <= 0)
++	if (len == 0)
+ 		return -EINVAL;
+ 	if (len > sizeof(struct sctp_event_subscribe))
+ 		len = sizeof(struct sctp_event_subscribe);
+@@ -6426,6 +6426,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
+ 	if (get_user(len, optlen))
+ 		return -EFAULT;
+ 
++	if (len < 0)
++		return -EINVAL;
++
+ 	lock_sock(sk);
+ 
+ 	switch (optname) {
+diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
+index a5fc9dd24aa9..a56c5e6f4498 100644
+--- a/net/switchdev/switchdev.c
++++ b/net/switchdev/switchdev.c
+@@ -774,6 +774,9 @@ int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ 	u32 mask = BR_LEARNING | BR_LEARNING_SYNC | BR_FLOOD;
+ 	int err;
+ 
++	if (!netif_is_bridge_port(dev))
++		return -EOPNOTSUPP;
++
+ 	err = switchdev_port_attr_get(dev, &attr);
+ 	if (err && err != -EOPNOTSUPP)
+ 		return err;
+@@ -929,6 +932,9 @@ int switchdev_port_bridge_setlink(struct net_device *dev,
+ 	struct nlattr *afspec;
+ 	int err = 0;
+ 
++	if (!netif_is_bridge_port(dev))
++		return -EOPNOTSUPP;
++
+ 	protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
+ 				   IFLA_PROTINFO);
+ 	if (protinfo) {
+@@ -962,6 +968,9 @@ int switchdev_port_bridge_dellink(struct net_device *dev,
+ {
+ 	struct nlattr *afspec;
+ 
++	if (!netif_is_bridge_port(dev))
++		return -EOPNOTSUPP;
++
+ 	afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
+ 				 IFLA_AF_SPEC);
+ 	if (afspec)


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-19 11:05 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-11-19 11:05 UTC (permalink / raw
  To: gentoo-commits

commit:     f13a81bef4970bd4993d84ad318bfe4990d92536
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 19 11:05:07 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Nov 19 11:05:07 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=f13a81be

Linux patch 4.8.9

 0000_README            |    4 +
 1008_linux-4.8.9.patch | 3120 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3124 insertions(+)

diff --git a/0000_README b/0000_README
index 236529a..d5af994 100644
--- a/0000_README
+++ b/0000_README
@@ -75,6 +75,10 @@ Patch:  1007_linux-4.8.8.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.8
 
+Patch:  1008_linux-4.8.9.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.9
+
 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/1008_linux-4.8.9.patch b/1008_linux-4.8.9.patch
new file mode 100644
index 0000000..6b106d5
--- /dev/null
+++ b/1008_linux-4.8.9.patch
@@ -0,0 +1,3120 @@
+diff --git a/Makefile b/Makefile
+index 8f18daa2c76a..c1519ab85258 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 8
++SUBLEVEL = 9
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arc/kernel/time.c b/arch/arc/kernel/time.c
+index f927b8dc6edd..c10390d1ddb6 100644
+--- a/arch/arc/kernel/time.c
++++ b/arch/arc/kernel/time.c
+@@ -152,14 +152,17 @@ static cycle_t arc_read_rtc(struct clocksource *cs)
+ 		cycle_t  full;
+ 	} stamp;
+ 
+-
+-	__asm__ __volatile(
+-	"1:						\n"
+-	"	lr		%0, [AUX_RTC_LOW]	\n"
+-	"	lr		%1, [AUX_RTC_HIGH]	\n"
+-	"	lr		%2, [AUX_RTC_CTRL]	\n"
+-	"	bbit0.nt	%2, 31, 1b		\n"
+-	: "=r" (stamp.low), "=r" (stamp.high), "=r" (status));
++	/*
++	 * hardware has an internal state machine which tracks readout of
++	 * low/high and updates the CTRL.status if
++	 *  - interrupt/exception taken between the two reads
++	 *  - high increments after low has been read
++	 */
++	do {
++		stamp.low = read_aux_reg(AUX_RTC_LOW);
++		stamp.high = read_aux_reg(AUX_RTC_HIGH);
++		status = read_aux_reg(AUX_RTC_CTRL);
++	} while (!(status & _BITUL(31)));
+ 
+ 	return stamp.full;
+ }
+diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c
+index 20afc65e22dc..9288851d43a0 100644
+--- a/arch/arc/mm/dma.c
++++ b/arch/arc/mm/dma.c
+@@ -105,6 +105,31 @@ static void arc_dma_free(struct device *dev, size_t size, void *vaddr,
+ 	__free_pages(page, get_order(size));
+ }
+ 
++static int arc_dma_mmap(struct device *dev, struct vm_area_struct *vma,
++			void *cpu_addr, dma_addr_t dma_addr, size_t size,
++			unsigned long attrs)
++{
++	unsigned long user_count = vma_pages(vma);
++	unsigned long count = PAGE_ALIGN(size) >> PAGE_SHIFT;
++	unsigned long pfn = __phys_to_pfn(plat_dma_to_phys(dev, dma_addr));
++	unsigned long off = vma->vm_pgoff;
++	int ret = -ENXIO;
++
++	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
++
++	if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
++		return ret;
++
++	if (off < count && user_count <= (count - off)) {
++		ret = remap_pfn_range(vma, vma->vm_start,
++				      pfn + off,
++				      user_count << PAGE_SHIFT,
++				      vma->vm_page_prot);
++	}
++
++	return ret;
++}
++
+ /*
+  * streaming DMA Mapping API...
+  * CPU accesses page via normal paddr, thus needs to explicitly made
+@@ -193,6 +218,7 @@ static int arc_dma_supported(struct device *dev, u64 dma_mask)
+ struct dma_map_ops arc_dma_ops = {
+ 	.alloc			= arc_dma_alloc,
+ 	.free			= arc_dma_free,
++	.mmap			= arc_dma_mmap,
+ 	.map_page		= arc_dma_map_page,
+ 	.map_sg			= arc_dma_map_sg,
+ 	.sync_single_for_device	= arc_dma_sync_single_for_device,
+diff --git a/arch/s390/hypfs/hypfs_diag.c b/arch/s390/hypfs/hypfs_diag.c
+index 28f03ca60100..794bebb43d23 100644
+--- a/arch/s390/hypfs/hypfs_diag.c
++++ b/arch/s390/hypfs/hypfs_diag.c
+@@ -363,11 +363,11 @@ out:
+ static int diag224_get_name_table(void)
+ {
+ 	/* memory must be below 2GB */
+-	diag224_cpu_names = kmalloc(PAGE_SIZE, GFP_KERNEL | GFP_DMA);
++	diag224_cpu_names = (char *) __get_free_page(GFP_KERNEL | GFP_DMA);
+ 	if (!diag224_cpu_names)
+ 		return -ENOMEM;
+ 	if (diag224(diag224_cpu_names)) {
+-		kfree(diag224_cpu_names);
++		free_page((unsigned long) diag224_cpu_names);
+ 		return -EOPNOTSUPP;
+ 	}
+ 	EBCASC(diag224_cpu_names + 16, (*diag224_cpu_names + 1) * 16);
+@@ -376,7 +376,7 @@ static int diag224_get_name_table(void)
+ 
+ static void diag224_delete_name_table(void)
+ {
+-	kfree(diag224_cpu_names);
++	free_page((unsigned long) diag224_cpu_names);
+ }
+ 
+ static int diag224_idx2name(int index, char *name)
+diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
+index 03323175de30..602af692efdc 100644
+--- a/arch/s390/include/asm/processor.h
++++ b/arch/s390/include/asm/processor.h
+@@ -192,7 +192,7 @@ struct task_struct;
+ struct mm_struct;
+ struct seq_file;
+ 
+-typedef int (*dump_trace_func_t)(void *data, unsigned long address);
++typedef int (*dump_trace_func_t)(void *data, unsigned long address, int reliable);
+ void dump_trace(dump_trace_func_t func, void *data,
+ 		struct task_struct *task, unsigned long sp);
+ 
+diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
+index 6693383bc01b..518f615ad0a2 100644
+--- a/arch/s390/kernel/dumpstack.c
++++ b/arch/s390/kernel/dumpstack.c
+@@ -38,10 +38,10 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
+ 		if (sp < low || sp > high - sizeof(*sf))
+ 			return sp;
+ 		sf = (struct stack_frame *) sp;
++		if (func(data, sf->gprs[8], 0))
++			return sp;
+ 		/* Follow the backchain. */
+ 		while (1) {
+-			if (func(data, sf->gprs[8]))
+-				return sp;
+ 			low = sp;
+ 			sp = sf->back_chain;
+ 			if (!sp)
+@@ -49,6 +49,8 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
+ 			if (sp <= low || sp > high - sizeof(*sf))
+ 				return sp;
+ 			sf = (struct stack_frame *) sp;
++			if (func(data, sf->gprs[8], 1))
++				return sp;
+ 		}
+ 		/* Zero backchain detected, check for interrupt frame. */
+ 		sp = (unsigned long) (sf + 1);
+@@ -56,7 +58,7 @@ __dump_trace(dump_trace_func_t func, void *data, unsigned long sp,
+ 			return sp;
+ 		regs = (struct pt_regs *) sp;
+ 		if (!user_mode(regs)) {
+-			if (func(data, regs->psw.addr))
++			if (func(data, regs->psw.addr, 1))
+ 				return sp;
+ 		}
+ 		low = sp;
+@@ -90,7 +92,7 @@ struct return_address_data {
+ 	int depth;
+ };
+ 
+-static int __return_address(void *data, unsigned long address)
++static int __return_address(void *data, unsigned long address, int reliable)
+ {
+ 	struct return_address_data *rd = data;
+ 
+@@ -109,9 +111,12 @@ unsigned long return_address(int depth)
+ }
+ EXPORT_SYMBOL_GPL(return_address);
+ 
+-static int show_address(void *data, unsigned long address)
++static int show_address(void *data, unsigned long address, int reliable)
+ {
+-	printk("([<%016lx>] %pSR)\n", address, (void *)address);
++	if (reliable)
++		printk(" [<%016lx>] %pSR \n", address, (void *)address);
++	else
++		printk("([<%016lx>] %pSR)\n", address, (void *)address);
+ 	return 0;
+ }
+ 
+diff --git a/arch/s390/kernel/perf_event.c b/arch/s390/kernel/perf_event.c
+index 17431f63de00..955a7b6fa0a4 100644
+--- a/arch/s390/kernel/perf_event.c
++++ b/arch/s390/kernel/perf_event.c
+@@ -222,7 +222,7 @@ static int __init service_level_perf_register(void)
+ }
+ arch_initcall(service_level_perf_register);
+ 
+-static int __perf_callchain_kernel(void *data, unsigned long address)
++static int __perf_callchain_kernel(void *data, unsigned long address, int reliable)
+ {
+ 	struct perf_callchain_entry_ctx *entry = data;
+ 
+diff --git a/arch/s390/kernel/stacktrace.c b/arch/s390/kernel/stacktrace.c
+index 44f84b23d4e5..355db9db8210 100644
+--- a/arch/s390/kernel/stacktrace.c
++++ b/arch/s390/kernel/stacktrace.c
+@@ -27,12 +27,12 @@ static int __save_address(void *data, unsigned long address, int nosched)
+ 	return 1;
+ }
+ 
+-static int save_address(void *data, unsigned long address)
++static int save_address(void *data, unsigned long address, int reliable)
+ {
+ 	return __save_address(data, address, 0);
+ }
+ 
+-static int save_address_nosched(void *data, unsigned long address)
++static int save_address_nosched(void *data, unsigned long address, int reliable)
+ {
+ 	return __save_address(data, address, 1);
+ }
+diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c
+index 16f4c3960b87..9a4de4599c7b 100644
+--- a/arch/s390/oprofile/init.c
++++ b/arch/s390/oprofile/init.c
+@@ -13,7 +13,7 @@
+ #include <linux/init.h>
+ #include <asm/processor.h>
+ 
+-static int __s390_backtrace(void *data, unsigned long address)
++static int __s390_backtrace(void *data, unsigned long address, int reliable)
+ {
+ 	unsigned int *depth = data;
+ 
+diff --git a/arch/x86/entry/Makefile b/arch/x86/entry/Makefile
+index 77f28ce9c646..9976fcecd17e 100644
+--- a/arch/x86/entry/Makefile
++++ b/arch/x86/entry/Makefile
+@@ -5,8 +5,8 @@
+ OBJECT_FILES_NON_STANDARD_entry_$(BITS).o   := y
+ OBJECT_FILES_NON_STANDARD_entry_64_compat.o := y
+ 
+-CFLAGS_syscall_64.o		+= -Wno-override-init
+-CFLAGS_syscall_32.o		+= -Wno-override-init
++CFLAGS_syscall_64.o		+= $(call cc-option,-Wno-override-init,)
++CFLAGS_syscall_32.o		+= $(call cc-option,-Wno-override-init,)
+ obj-y				:= entry_$(BITS).o thunk_$(BITS).o syscall_$(BITS).o
+ obj-y				+= common.o
+ 
+diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
+index fbd19444403f..d99ca57cbf60 100644
+--- a/arch/x86/kernel/acpi/boot.c
++++ b/arch/x86/kernel/acpi/boot.c
+@@ -453,6 +453,7 @@ static void __init acpi_sci_ioapic_setup(u8 bus_irq, u16 polarity, u16 trigger,
+ 		polarity = acpi_sci_flags & ACPI_MADT_POLARITY_MASK;
+ 
+ 	mp_override_legacy_irq(bus_irq, polarity, trigger, gsi);
++	acpi_penalize_sci_irq(bus_irq, trigger, polarity);
+ 
+ 	/*
+ 	 * stash over-ride to indicate we've been here
+diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c
+index 60746ef904e4..caea575f25f8 100644
+--- a/drivers/acpi/apei/ghes.c
++++ b/drivers/acpi/apei/ghes.c
+@@ -662,7 +662,7 @@ static int ghes_proc(struct ghes *ghes)
+ 	ghes_do_proc(ghes, ghes->estatus);
+ out:
+ 	ghes_clear_estatus(ghes);
+-	return 0;
++	return rc;
+ }
+ 
+ static void ghes_add_timer(struct ghes *ghes)
+diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
+index c983bf733ad3..bc3d914dfc3e 100644
+--- a/drivers/acpi/pci_link.c
++++ b/drivers/acpi/pci_link.c
+@@ -87,6 +87,7 @@ struct acpi_pci_link {
+ 
+ static LIST_HEAD(acpi_link_list);
+ static DEFINE_MUTEX(acpi_link_lock);
++static int sci_irq = -1, sci_penalty;
+ 
+ /* --------------------------------------------------------------------------
+                             PCI Link Device Management
+@@ -496,25 +497,13 @@ static int acpi_irq_get_penalty(int irq)
+ {
+ 	int penalty = 0;
+ 
+-	/*
+-	* Penalize IRQ used by ACPI SCI. If ACPI SCI pin attributes conflict
+-	* with PCI IRQ attributes, mark ACPI SCI as ISA_ALWAYS so it won't be
+-	* use for PCI IRQs.
+-	*/
+-	if (irq == acpi_gbl_FADT.sci_interrupt) {
+-		u32 type = irq_get_trigger_type(irq) & IRQ_TYPE_SENSE_MASK;
+-
+-		if (type != IRQ_TYPE_LEVEL_LOW)
+-			penalty += PIRQ_PENALTY_ISA_ALWAYS;
+-		else
+-			penalty += PIRQ_PENALTY_PCI_USING;
+-	}
++	if (irq == sci_irq)
++		penalty += sci_penalty;
+ 
+ 	if (irq < ACPI_MAX_ISA_IRQS)
+ 		return penalty + acpi_isa_irq_penalty[irq];
+ 
+-	penalty += acpi_irq_pci_sharing_penalty(irq);
+-	return penalty;
++	return penalty + acpi_irq_pci_sharing_penalty(irq);
+ }
+ 
+ int __init acpi_irq_penalty_init(void)
+@@ -619,6 +608,10 @@ static int acpi_pci_link_allocate(struct acpi_pci_link *link)
+ 			    acpi_device_bid(link->device));
+ 		return -ENODEV;
+ 	} else {
++		if (link->irq.active < ACPI_MAX_ISA_IRQS)
++			acpi_isa_irq_penalty[link->irq.active] +=
++				PIRQ_PENALTY_PCI_USING;
++
+ 		printk(KERN_WARNING PREFIX "%s [%s] enabled at IRQ %d\n",
+ 		       acpi_device_name(link->device),
+ 		       acpi_device_bid(link->device), link->irq.active);
+@@ -849,7 +842,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)
+ 			continue;
+ 
+ 		if (used)
+-			new_penalty = acpi_irq_get_penalty(irq) +
++			new_penalty = acpi_isa_irq_penalty[irq] +
+ 					PIRQ_PENALTY_ISA_USED;
+ 		else
+ 			new_penalty = 0;
+@@ -871,7 +864,7 @@ static int __init acpi_irq_penalty_update(char *str, int used)
+ void acpi_penalize_isa_irq(int irq, int active)
+ {
+ 	if ((irq >= 0) && (irq < ARRAY_SIZE(acpi_isa_irq_penalty)))
+-		acpi_isa_irq_penalty[irq] = acpi_irq_get_penalty(irq) +
++		acpi_isa_irq_penalty[irq] +=
+ 		  (active ? PIRQ_PENALTY_ISA_USED : PIRQ_PENALTY_PCI_USING);
+ }
+ 
+@@ -881,6 +874,17 @@ bool acpi_isa_irq_available(int irq)
+ 		    acpi_irq_get_penalty(irq) < PIRQ_PENALTY_ISA_ALWAYS);
+ }
+ 
++void acpi_penalize_sci_irq(int irq, int trigger, int polarity)
++{
++	sci_irq = irq;
++
++	if (trigger == ACPI_MADT_TRIGGER_LEVEL &&
++	    polarity == ACPI_MADT_POLARITY_ACTIVE_LOW)
++		sci_penalty = PIRQ_PENALTY_PCI_USING;
++	else
++		sci_penalty = PIRQ_PENALTY_ISA_ALWAYS;
++}
++
+ /*
+  * Over-ride default table to reserve additional IRQs for use by ISA
+  * e.g. acpi_irq_isa=5
+diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
+index 100be556e613..83482721bc01 100644
+--- a/drivers/block/drbd/drbd_main.c
++++ b/drivers/block/drbd/drbd_main.c
+@@ -1871,7 +1871,7 @@ int drbd_send(struct drbd_connection *connection, struct socket *sock,
+ 		drbd_update_congested(connection);
+ 	}
+ 	do {
+-		rv = kernel_sendmsg(sock, &msg, &iov, 1, size);
++		rv = kernel_sendmsg(sock, &msg, &iov, 1, iov.iov_len);
+ 		if (rv == -EAGAIN) {
+ 			if (we_should_drop_the_connection(connection, sock))
+ 				break;
+diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c
+index 44311296ec02..0f7d28a98b9a 100644
+--- a/drivers/char/agp/intel-gtt.c
++++ b/drivers/char/agp/intel-gtt.c
+@@ -845,6 +845,8 @@ void intel_gtt_insert_page(dma_addr_t addr,
+ 			   unsigned int flags)
+ {
+ 	intel_private.driver->write_entry(addr, pg, flags);
++	if (intel_private.driver->chipset_flush)
++		intel_private.driver->chipset_flush();
+ }
+ EXPORT_SYMBOL(intel_gtt_insert_page);
+ 
+diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
+index 9203f2d130c0..340f96e44642 100644
+--- a/drivers/char/hw_random/core.c
++++ b/drivers/char/hw_random/core.c
+@@ -84,14 +84,14 @@ static size_t rng_buffer_size(void)
+ 
+ static void add_early_randomness(struct hwrng *rng)
+ {
+-	unsigned char bytes[16];
+ 	int bytes_read;
++	size_t size = min_t(size_t, 16, rng_buffer_size());
+ 
+ 	mutex_lock(&reading_mutex);
+-	bytes_read = rng_get_data(rng, bytes, sizeof(bytes), 1);
++	bytes_read = rng_get_data(rng, rng_buffer, size, 1);
+ 	mutex_unlock(&reading_mutex);
+ 	if (bytes_read > 0)
+-		add_device_randomness(bytes, bytes_read);
++		add_device_randomness(rng_buffer, bytes_read);
+ }
+ 
+ static inline void cleanup_rng(struct kref *kref)
+diff --git a/drivers/clk/clk-qoriq.c b/drivers/clk/clk-qoriq.c
+index 20b105584f82..80ae2a51452d 100644
+--- a/drivers/clk/clk-qoriq.c
++++ b/drivers/clk/clk-qoriq.c
+@@ -700,6 +700,7 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
+ 					     struct mux_hwclock *hwc,
+ 					     const struct clk_ops *ops,
+ 					     unsigned long min_rate,
++					     unsigned long max_rate,
+ 					     unsigned long pct80_rate,
+ 					     const char *fmt, int idx)
+ {
+@@ -728,6 +729,8 @@ static struct clk * __init create_mux_common(struct clockgen *cg,
+ 			continue;
+ 		if (rate < min_rate)
+ 			continue;
++		if (rate > max_rate)
++			continue;
+ 
+ 		parent_names[j] = div->name;
+ 		hwc->parent_to_clksel[j] = i;
+@@ -759,7 +762,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
+ 	struct mux_hwclock *hwc;
+ 	const struct clockgen_pll_div *div;
+ 	unsigned long plat_rate, min_rate;
+-	u64 pct80_rate;
++	u64 max_rate, pct80_rate;
+ 	u32 clksel;
+ 
+ 	hwc = kzalloc(sizeof(*hwc), GFP_KERNEL);
+@@ -787,8 +790,8 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
+ 		return NULL;
+ 	}
+ 
+-	pct80_rate = clk_get_rate(div->clk);
+-	pct80_rate *= 8;
++	max_rate = clk_get_rate(div->clk);
++	pct80_rate = max_rate * 8;
+ 	do_div(pct80_rate, 10);
+ 
+ 	plat_rate = clk_get_rate(cg->pll[PLATFORM_PLL].div[PLL_DIV1].clk);
+@@ -798,7 +801,7 @@ static struct clk * __init create_one_cmux(struct clockgen *cg, int idx)
+ 	else
+ 		min_rate = plat_rate / 2;
+ 
+-	return create_mux_common(cg, hwc, &cmux_ops, min_rate,
++	return create_mux_common(cg, hwc, &cmux_ops, min_rate, max_rate,
+ 				 pct80_rate, "cg-cmux%d", idx);
+ }
+ 
+@@ -813,7 +816,7 @@ static struct clk * __init create_one_hwaccel(struct clockgen *cg, int idx)
+ 	hwc->reg = cg->regs + 0x20 * idx + 0x10;
+ 	hwc->info = cg->info.hwaccel[idx];
+ 
+-	return create_mux_common(cg, hwc, &hwaccel_ops, 0, 0,
++	return create_mux_common(cg, hwc, &hwaccel_ops, 0, ULONG_MAX, 0,
+ 				 "cg-hwaccel%d", idx);
+ }
+ 
+diff --git a/drivers/clk/samsung/clk-exynos-audss.c b/drivers/clk/samsung/clk-exynos-audss.c
+index bdf8b971f332..0fa91f37879b 100644
+--- a/drivers/clk/samsung/clk-exynos-audss.c
++++ b/drivers/clk/samsung/clk-exynos-audss.c
+@@ -82,6 +82,7 @@ static const struct of_device_id exynos_audss_clk_of_match[] = {
+ 	  .data = (void *)TYPE_EXYNOS5420, },
+ 	{},
+ };
++MODULE_DEVICE_TABLE(of, exynos_audss_clk_of_match);
+ 
+ static void exynos_audss_clk_teardown(void)
+ {
+diff --git a/drivers/clocksource/timer-sun5i.c b/drivers/clocksource/timer-sun5i.c
+index c184eb84101e..4f87f3e76d83 100644
+--- a/drivers/clocksource/timer-sun5i.c
++++ b/drivers/clocksource/timer-sun5i.c
+@@ -152,6 +152,13 @@ static irqreturn_t sun5i_timer_interrupt(int irq, void *dev_id)
+ 	return IRQ_HANDLED;
+ }
+ 
++static cycle_t sun5i_clksrc_read(struct clocksource *clksrc)
++{
++	struct sun5i_timer_clksrc *cs = to_sun5i_timer_clksrc(clksrc);
++
++	return ~readl(cs->timer.base + TIMER_CNTVAL_LO_REG(1));
++}
++
+ static int sun5i_rate_cb_clksrc(struct notifier_block *nb,
+ 				unsigned long event, void *data)
+ {
+@@ -210,8 +217,13 @@ static int __init sun5i_setup_clocksource(struct device_node *node,
+ 	writel(TIMER_CTL_ENABLE | TIMER_CTL_RELOAD,
+ 	       base + TIMER_CTL_REG(1));
+ 
+-	ret = clocksource_mmio_init(base + TIMER_CNTVAL_LO_REG(1), node->name,
+-				    rate, 340, 32, clocksource_mmio_readl_down);
++	cs->clksrc.name = node->name;
++	cs->clksrc.rating = 340;
++	cs->clksrc.read = sun5i_clksrc_read;
++	cs->clksrc.mask = CLOCKSOURCE_MASK(32);
++	cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
++
++	ret = clocksource_register_hz(&cs->clksrc, rate);
+ 	if (ret) {
+ 		pr_err("Couldn't register clock source.\n");
+ 		goto err_remove_notifier;
+diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c
+index cd5dc27320a2..1ed6132b993c 100644
+--- a/drivers/gpio/gpio-mvebu.c
++++ b/drivers/gpio/gpio-mvebu.c
+@@ -293,10 +293,10 @@ static void mvebu_gpio_irq_ack(struct irq_data *d)
+ {
+ 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ 	struct mvebu_gpio_chip *mvchip = gc->private;
+-	u32 mask = ~(1 << (d->irq - gc->irq_base));
++	u32 mask = d->mask;
+ 
+ 	irq_gc_lock(gc);
+-	writel_relaxed(mask, mvebu_gpioreg_edge_cause(mvchip));
++	writel_relaxed(~mask, mvebu_gpioreg_edge_cause(mvchip));
+ 	irq_gc_unlock(gc);
+ }
+ 
+@@ -305,7 +305,7 @@ static void mvebu_gpio_edge_irq_mask(struct irq_data *d)
+ 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ 	struct mvebu_gpio_chip *mvchip = gc->private;
+ 	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+-	u32 mask = 1 << (d->irq - gc->irq_base);
++	u32 mask = d->mask;
+ 
+ 	irq_gc_lock(gc);
+ 	ct->mask_cache_priv &= ~mask;
+@@ -319,8 +319,7 @@ static void mvebu_gpio_edge_irq_unmask(struct irq_data *d)
+ 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ 	struct mvebu_gpio_chip *mvchip = gc->private;
+ 	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+-
+-	u32 mask = 1 << (d->irq - gc->irq_base);
++	u32 mask = d->mask;
+ 
+ 	irq_gc_lock(gc);
+ 	ct->mask_cache_priv |= mask;
+@@ -333,8 +332,7 @@ static void mvebu_gpio_level_irq_mask(struct irq_data *d)
+ 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ 	struct mvebu_gpio_chip *mvchip = gc->private;
+ 	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+-
+-	u32 mask = 1 << (d->irq - gc->irq_base);
++	u32 mask = d->mask;
+ 
+ 	irq_gc_lock(gc);
+ 	ct->mask_cache_priv &= ~mask;
+@@ -347,8 +345,7 @@ static void mvebu_gpio_level_irq_unmask(struct irq_data *d)
+ 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ 	struct mvebu_gpio_chip *mvchip = gc->private;
+ 	struct irq_chip_type *ct = irq_data_get_chip_type(d);
+-
+-	u32 mask = 1 << (d->irq - gc->irq_base);
++	u32 mask = d->mask;
+ 
+ 	irq_gc_lock(gc);
+ 	ct->mask_cache_priv |= mask;
+@@ -462,7 +459,7 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc)
+ 	for (i = 0; i < mvchip->chip.ngpio; i++) {
+ 		int irq;
+ 
+-		irq = mvchip->irqbase + i;
++		irq = irq_find_mapping(mvchip->domain, i);
+ 
+ 		if (!(cause & (1 << i)))
+ 			continue;
+@@ -655,6 +652,7 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ 	struct irq_chip_type *ct;
+ 	struct clk *clk;
+ 	unsigned int ngpios;
++	bool have_irqs;
+ 	int soc_variant;
+ 	int i, cpu, id;
+ 	int err;
+@@ -665,6 +663,9 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ 	else
+ 		soc_variant = MVEBU_GPIO_SOC_VARIANT_ORION;
+ 
++	/* Some gpio controllers do not provide irq support */
++	have_irqs = of_irq_count(np) != 0;
++
+ 	mvchip = devm_kzalloc(&pdev->dev, sizeof(struct mvebu_gpio_chip),
+ 			      GFP_KERNEL);
+ 	if (!mvchip)
+@@ -697,7 +698,8 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ 	mvchip->chip.get = mvebu_gpio_get;
+ 	mvchip->chip.direction_output = mvebu_gpio_direction_output;
+ 	mvchip->chip.set = mvebu_gpio_set;
+-	mvchip->chip.to_irq = mvebu_gpio_to_irq;
++	if (have_irqs)
++		mvchip->chip.to_irq = mvebu_gpio_to_irq;
+ 	mvchip->chip.base = id * MVEBU_MAX_GPIO_PER_BANK;
+ 	mvchip->chip.ngpio = ngpios;
+ 	mvchip->chip.can_sleep = false;
+@@ -758,34 +760,30 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ 	devm_gpiochip_add_data(&pdev->dev, &mvchip->chip, mvchip);
+ 
+ 	/* Some gpio controllers do not provide irq support */
+-	if (!of_irq_count(np))
++	if (!have_irqs)
+ 		return 0;
+ 
+-	/* Setup the interrupt handlers. Each chip can have up to 4
+-	 * interrupt handlers, with each handler dealing with 8 GPIO
+-	 * pins. */
+-	for (i = 0; i < 4; i++) {
+-		int irq = platform_get_irq(pdev, i);
+-
+-		if (irq < 0)
+-			continue;
+-		irq_set_chained_handler_and_data(irq, mvebu_gpio_irq_handler,
+-						 mvchip);
+-	}
+-
+-	mvchip->irqbase = irq_alloc_descs(-1, 0, ngpios, -1);
+-	if (mvchip->irqbase < 0) {
+-		dev_err(&pdev->dev, "no irqs\n");
+-		return mvchip->irqbase;
++	mvchip->domain =
++	    irq_domain_add_linear(np, ngpios, &irq_generic_chip_ops, NULL);
++	if (!mvchip->domain) {
++		dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
++			mvchip->chip.label);
++		return -ENODEV;
+ 	}
+ 
+-	gc = irq_alloc_generic_chip("mvebu_gpio_irq", 2, mvchip->irqbase,
+-				    mvchip->membase, handle_level_irq);
+-	if (!gc) {
+-		dev_err(&pdev->dev, "Cannot allocate generic irq_chip\n");
+-		return -ENOMEM;
++	err = irq_alloc_domain_generic_chips(
++	    mvchip->domain, ngpios, 2, np->name, handle_level_irq,
++	    IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_LEVEL, 0, 0);
++	if (err) {
++		dev_err(&pdev->dev, "couldn't allocate irq chips %s (DT).\n",
++			mvchip->chip.label);
++		goto err_domain;
+ 	}
+ 
++	/* NOTE: The common accessors cannot be used because of the percpu
++	 * access to the mask registers
++	 */
++	gc = irq_get_domain_generic_chip(mvchip->domain, 0);
+ 	gc->private = mvchip;
+ 	ct = &gc->chip_types[0];
+ 	ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW;
+@@ -803,27 +801,23 @@ static int mvebu_gpio_probe(struct platform_device *pdev)
+ 	ct->handler = handle_edge_irq;
+ 	ct->chip.name = mvchip->chip.label;
+ 
+-	irq_setup_generic_chip(gc, IRQ_MSK(ngpios), 0,
+-			       IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE);
++	/* Setup the interrupt handlers. Each chip can have up to 4
++	 * interrupt handlers, with each handler dealing with 8 GPIO
++	 * pins.
++	 */
++	for (i = 0; i < 4; i++) {
++		int irq = platform_get_irq(pdev, i);
+ 
+-	/* Setup irq domain on top of the generic chip. */
+-	mvchip->domain = irq_domain_add_simple(np, mvchip->chip.ngpio,
+-					       mvchip->irqbase,
+-					       &irq_domain_simple_ops,
+-					       mvchip);
+-	if (!mvchip->domain) {
+-		dev_err(&pdev->dev, "couldn't allocate irq domain %s (DT).\n",
+-			mvchip->chip.label);
+-		err = -ENODEV;
+-		goto err_generic_chip;
++		if (irq < 0)
++			continue;
++		irq_set_chained_handler_and_data(irq, mvebu_gpio_irq_handler,
++						 mvchip);
+ 	}
+ 
+ 	return 0;
+ 
+-err_generic_chip:
+-	irq_remove_generic_chip(gc, IRQ_MSK(ngpios), IRQ_NOREQUEST,
+-				IRQ_LEVEL | IRQ_NOPROBE);
+-	kfree(gc);
++err_domain:
++	irq_domain_remove(mvchip->domain);
+ 
+ 	return err;
+ }
+diff --git a/drivers/gpio/gpiolib-of.c b/drivers/gpio/gpiolib-of.c
+index a28feb3edf33..e3fc90130855 100644
+--- a/drivers/gpio/gpiolib-of.c
++++ b/drivers/gpio/gpiolib-of.c
+@@ -26,14 +26,18 @@
+ 
+ #include "gpiolib.h"
+ 
+-static int of_gpiochip_match_node(struct gpio_chip *chip, void *data)
++static int of_gpiochip_match_node_and_xlate(struct gpio_chip *chip, void *data)
+ {
+-	return chip->gpiodev->dev.of_node == data;
++	struct of_phandle_args *gpiospec = data;
++
++	return chip->gpiodev->dev.of_node == gpiospec->np &&
++				chip->of_xlate(chip, gpiospec, NULL) >= 0;
+ }
+ 
+-static struct gpio_chip *of_find_gpiochip_by_node(struct device_node *np)
++static struct gpio_chip *of_find_gpiochip_by_xlate(
++					struct of_phandle_args *gpiospec)
+ {
+-	return gpiochip_find(np, of_gpiochip_match_node);
++	return gpiochip_find(gpiospec, of_gpiochip_match_node_and_xlate);
+ }
+ 
+ static struct gpio_desc *of_xlate_and_get_gpiod_flags(struct gpio_chip *chip,
+@@ -79,7 +83,7 @@ struct gpio_desc *of_get_named_gpiod_flags(struct device_node *np,
+ 		return ERR_PTR(ret);
+ 	}
+ 
+-	chip = of_find_gpiochip_by_node(gpiospec.np);
++	chip = of_find_gpiochip_by_xlate(&gpiospec);
+ 	if (!chip) {
+ 		desc = ERR_PTR(-EPROBE_DEFER);
+ 		goto out;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+index 892d60fb225b..2057683f7b59 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
+@@ -395,9 +395,12 @@ static int acp_hw_fini(void *handle)
+ {
+ 	int i, ret;
+ 	struct device *dev;
+-
+ 	struct amdgpu_device *adev = (struct amdgpu_device *)handle;
+ 
++	/* return early if no ACP */
++	if (!adev->acp.acp_genpd)
++		return 0;
++
+ 	for (i = 0; i < ACP_DEVS ; i++) {
+ 		dev = get_mfd_cell_dev(adev->acp.acp_cell[i].name, i);
+ 		ret = pm_genpd_remove_device(&adev->acp.acp_genpd->gpd, dev);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+index 9aa533cf4ad1..414a1600da54 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+@@ -605,6 +605,7 @@ static int __init amdgpu_init(void)
+ {
+ 	amdgpu_sync_init();
+ 	amdgpu_fence_slab_init();
++	amd_sched_fence_slab_init();
+ 	if (vgacon_text_force()) {
+ 		DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n");
+ 		return -EINVAL;
+@@ -624,6 +625,7 @@ static void __exit amdgpu_exit(void)
+ 	drm_pci_exit(driver, pdriver);
+ 	amdgpu_unregister_atpx_handler();
+ 	amdgpu_sync_fini();
++	amd_sched_fence_slab_fini();
+ 	amdgpu_fence_slab_fini();
+ }
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+index 0b109aebfec6..c82b95b838d0 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
+@@ -68,6 +68,7 @@ int amdgpu_fence_slab_init(void)
+ 
+ void amdgpu_fence_slab_fini(void)
+ {
++	rcu_barrier();
+ 	kmem_cache_destroy(amdgpu_fence_slab);
+ }
+ /*
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index e24a8af72d90..1ed64aedb2fe 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -99,6 +99,8 @@ int amdgpu_driver_load_kms(struct drm_device *dev, unsigned long flags)
+ 
+ 	if ((amdgpu_runtime_pm != 0) &&
+ 	    amdgpu_has_atpx() &&
++	    (amdgpu_is_atpx_hybrid() ||
++	     amdgpu_has_atpx_dgpu_power_cntl()) &&
+ 	    ((flags & AMD_IS_APU) == 0))
+ 		flags |= AMD_IS_PX;
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+index 80120fa4092c..e86ca392a08c 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
+@@ -1654,5 +1654,6 @@ void amdgpu_vm_manager_fini(struct amdgpu_device *adev)
+ 		fence_put(adev->vm_manager.ids[i].first);
+ 		amdgpu_sync_free(&adev->vm_manager.ids[i].active);
+ 		fence_put(id->flushed_updates);
++		fence_put(id->last_flush);
+ 	}
+ }
+diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+index 963a24d46a93..ffe1f85ce300 100644
+--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
++++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.c
+@@ -34,9 +34,6 @@ static bool amd_sched_entity_is_ready(struct amd_sched_entity *entity);
+ static void amd_sched_wakeup(struct amd_gpu_scheduler *sched);
+ static void amd_sched_process_job(struct fence *f, struct fence_cb *cb);
+ 
+-struct kmem_cache *sched_fence_slab;
+-atomic_t sched_fence_slab_ref = ATOMIC_INIT(0);
+-
+ /* Initialize a given run queue struct */
+ static void amd_sched_rq_init(struct amd_sched_rq *rq)
+ {
+@@ -618,13 +615,6 @@ int amd_sched_init(struct amd_gpu_scheduler *sched,
+ 	INIT_LIST_HEAD(&sched->ring_mirror_list);
+ 	spin_lock_init(&sched->job_list_lock);
+ 	atomic_set(&sched->hw_rq_count, 0);
+-	if (atomic_inc_return(&sched_fence_slab_ref) == 1) {
+-		sched_fence_slab = kmem_cache_create(
+-			"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
+-			SLAB_HWCACHE_ALIGN, NULL);
+-		if (!sched_fence_slab)
+-			return -ENOMEM;
+-	}
+ 
+ 	/* Each scheduler will run on a seperate kernel thread */
+ 	sched->thread = kthread_run(amd_sched_main, sched, sched->name);
+@@ -645,6 +635,4 @@ void amd_sched_fini(struct amd_gpu_scheduler *sched)
+ {
+ 	if (sched->thread)
+ 		kthread_stop(sched->thread);
+-	if (atomic_dec_and_test(&sched_fence_slab_ref))
+-		kmem_cache_destroy(sched_fence_slab);
+ }
+diff --git a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+index 7cbbbfb502ef..51068e6c3d9a 100644
+--- a/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
++++ b/drivers/gpu/drm/amd/scheduler/gpu_scheduler.h
+@@ -30,9 +30,6 @@
+ struct amd_gpu_scheduler;
+ struct amd_sched_rq;
+ 
+-extern struct kmem_cache *sched_fence_slab;
+-extern atomic_t sched_fence_slab_ref;
+-
+ /**
+  * A scheduler entity is a wrapper around a job queue or a group
+  * of other entities. Entities take turns emitting jobs from their
+@@ -145,6 +142,9 @@ void amd_sched_entity_fini(struct amd_gpu_scheduler *sched,
+ 			   struct amd_sched_entity *entity);
+ void amd_sched_entity_push_job(struct amd_sched_job *sched_job);
+ 
++int amd_sched_fence_slab_init(void);
++void amd_sched_fence_slab_fini(void);
++
+ struct amd_sched_fence *amd_sched_fence_create(
+ 	struct amd_sched_entity *s_entity, void *owner);
+ void amd_sched_fence_scheduled(struct amd_sched_fence *fence);
+diff --git a/drivers/gpu/drm/amd/scheduler/sched_fence.c b/drivers/gpu/drm/amd/scheduler/sched_fence.c
+index 6b63beaf7574..93ad2e1f8f57 100644
+--- a/drivers/gpu/drm/amd/scheduler/sched_fence.c
++++ b/drivers/gpu/drm/amd/scheduler/sched_fence.c
+@@ -27,6 +27,25 @@
+ #include <drm/drmP.h>
+ #include "gpu_scheduler.h"
+ 
++static struct kmem_cache *sched_fence_slab;
++
++int amd_sched_fence_slab_init(void)
++{
++	sched_fence_slab = kmem_cache_create(
++		"amd_sched_fence", sizeof(struct amd_sched_fence), 0,
++		SLAB_HWCACHE_ALIGN, NULL);
++	if (!sched_fence_slab)
++		return -ENOMEM;
++
++	return 0;
++}
++
++void amd_sched_fence_slab_fini(void)
++{
++	rcu_barrier();
++	kmem_cache_destroy(sched_fence_slab);
++}
++
+ struct amd_sched_fence *amd_sched_fence_create(struct amd_sched_entity *entity,
+ 					       void *owner)
+ {
+diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
+index 5de36d8dcc68..d46fa2206722 100644
+--- a/drivers/gpu/drm/i915/i915_drv.c
++++ b/drivers/gpu/drm/i915/i915_drv.c
+@@ -1490,8 +1490,6 @@ static int i915_drm_suspend(struct drm_device *dev)
+ 
+ 	dev_priv->suspend_count++;
+ 
+-	intel_display_set_init_power(dev_priv, false);
+-
+ 	intel_csr_ucode_suspend(dev_priv);
+ 
+ out:
+@@ -1508,6 +1506,8 @@ static int i915_drm_suspend_late(struct drm_device *drm_dev, bool hibernation)
+ 
+ 	disable_rpm_wakeref_asserts(dev_priv);
+ 
++	intel_display_set_init_power(dev_priv, false);
++
+ 	fw_csr = !IS_BROXTON(dev_priv) &&
+ 		suspend_to_idle(dev_priv) && dev_priv->csr.dmc_payload;
+ 	/*
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 63462f279187..e26f88965c58 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -9737,6 +9737,29 @@ static void bxt_modeset_commit_cdclk(struct drm_atomic_state *old_state)
+ 	bxt_set_cdclk(to_i915(dev), req_cdclk);
+ }
+ 
++static int bdw_adjust_min_pipe_pixel_rate(struct intel_crtc_state *crtc_state,
++					  int pixel_rate)
++{
++	struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
++
++	/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
++	if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
++		pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
++
++	/* BSpec says "Do not use DisplayPort with CDCLK less than
++	 * 432 MHz, audio enabled, port width x4, and link rate
++	 * HBR2 (5.4 GHz), or else there may be audio corruption or
++	 * screen corruption."
++	 */
++	if (intel_crtc_has_dp_encoder(crtc_state) &&
++	    crtc_state->has_audio &&
++	    crtc_state->port_clock >= 540000 &&
++	    crtc_state->lane_count == 4)
++		pixel_rate = max(432000, pixel_rate);
++
++	return pixel_rate;
++}
++
+ /* compute the max rate for new configuration */
+ static int ilk_max_pixel_rate(struct drm_atomic_state *state)
+ {
+@@ -9762,9 +9785,9 @@ static int ilk_max_pixel_rate(struct drm_atomic_state *state)
+ 
+ 		pixel_rate = ilk_pipe_pixel_rate(crtc_state);
+ 
+-		/* pixel rate mustn't exceed 95% of cdclk with IPS on BDW */
+-		if (IS_BROADWELL(dev_priv) && crtc_state->ips_enabled)
+-			pixel_rate = DIV_ROUND_UP(pixel_rate * 100, 95);
++		if (IS_BROADWELL(dev_priv) || IS_GEN9(dev_priv))
++			pixel_rate = bdw_adjust_min_pipe_pixel_rate(crtc_state,
++								    pixel_rate);
+ 
+ 		intel_state->min_pixclk[i] = pixel_rate;
+ 	}
+diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
+index c3aa9e670d15..1421270071d2 100644
+--- a/drivers/gpu/drm/i915/intel_hdmi.c
++++ b/drivers/gpu/drm/i915/intel_hdmi.c
+@@ -1759,6 +1759,50 @@ intel_hdmi_add_properties(struct intel_hdmi *intel_hdmi, struct drm_connector *c
+ 	intel_hdmi->aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+ }
+ 
++static u8 intel_hdmi_ddc_pin(struct drm_i915_private *dev_priv,
++			     enum port port)
++{
++	const struct ddi_vbt_port_info *info =
++		&dev_priv->vbt.ddi_port_info[port];
++	u8 ddc_pin;
++
++	if (info->alternate_ddc_pin) {
++		DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (VBT)\n",
++			      info->alternate_ddc_pin, port_name(port));
++		return info->alternate_ddc_pin;
++	}
++
++	switch (port) {
++	case PORT_B:
++		if (IS_BROXTON(dev_priv))
++			ddc_pin = GMBUS_PIN_1_BXT;
++		else
++			ddc_pin = GMBUS_PIN_DPB;
++		break;
++	case PORT_C:
++		if (IS_BROXTON(dev_priv))
++			ddc_pin = GMBUS_PIN_2_BXT;
++		else
++			ddc_pin = GMBUS_PIN_DPC;
++		break;
++	case PORT_D:
++		if (IS_CHERRYVIEW(dev_priv))
++			ddc_pin = GMBUS_PIN_DPD_CHV;
++		else
++			ddc_pin = GMBUS_PIN_DPD;
++		break;
++	default:
++		MISSING_CASE(port);
++		ddc_pin = GMBUS_PIN_DPB;
++		break;
++	}
++
++	DRM_DEBUG_KMS("Using DDC pin 0x%x for port %c (platform default)\n",
++		      ddc_pin, port_name(port));
++
++	return ddc_pin;
++}
++
+ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ 			       struct intel_connector *intel_connector)
+ {
+@@ -1768,7 +1812,6 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ 	struct drm_device *dev = intel_encoder->base.dev;
+ 	struct drm_i915_private *dev_priv = to_i915(dev);
+ 	enum port port = intel_dig_port->port;
+-	uint8_t alternate_ddc_pin;
+ 
+ 	DRM_DEBUG_KMS("Adding HDMI connector on port %c\n",
+ 		      port_name(port));
+@@ -1786,12 +1829,10 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ 	connector->doublescan_allowed = 0;
+ 	connector->stereo_allowed = 1;
+ 
++	intel_hdmi->ddc_bus = intel_hdmi_ddc_pin(dev_priv, port);
++
+ 	switch (port) {
+ 	case PORT_B:
+-		if (IS_BROXTON(dev_priv))
+-			intel_hdmi->ddc_bus = GMBUS_PIN_1_BXT;
+-		else
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
+ 		/*
+ 		 * On BXT A0/A1, sw needs to activate DDIA HPD logic and
+ 		 * interrupts to check the external panel connection.
+@@ -1802,46 +1843,17 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ 			intel_encoder->hpd_pin = HPD_PORT_B;
+ 		break;
+ 	case PORT_C:
+-		if (IS_BROXTON(dev_priv))
+-			intel_hdmi->ddc_bus = GMBUS_PIN_2_BXT;
+-		else
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
+ 		intel_encoder->hpd_pin = HPD_PORT_C;
+ 		break;
+ 	case PORT_D:
+-		if (WARN_ON(IS_BROXTON(dev_priv)))
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DISABLED;
+-		else if (IS_CHERRYVIEW(dev_priv))
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPD_CHV;
+-		else
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
+ 		intel_encoder->hpd_pin = HPD_PORT_D;
+ 		break;
+ 	case PORT_E:
+-		/* On SKL PORT E doesn't have seperate GMBUS pin
+-		 *  We rely on VBT to set a proper alternate GMBUS pin. */
+-		alternate_ddc_pin =
+-			dev_priv->vbt.ddi_port_info[PORT_E].alternate_ddc_pin;
+-		switch (alternate_ddc_pin) {
+-		case DDC_PIN_B:
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPB;
+-			break;
+-		case DDC_PIN_C:
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPC;
+-			break;
+-		case DDC_PIN_D:
+-			intel_hdmi->ddc_bus = GMBUS_PIN_DPD;
+-			break;
+-		default:
+-			MISSING_CASE(alternate_ddc_pin);
+-		}
+ 		intel_encoder->hpd_pin = HPD_PORT_E;
+ 		break;
+-	case PORT_A:
+-		intel_encoder->hpd_pin = HPD_PORT_A;
+-		/* Internal port only for eDP. */
+ 	default:
+-		BUG();
++		MISSING_CASE(port);
++		return;
+ 	}
+ 
+ 	if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index 554ca7115f98..edd2d0396290 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -104,6 +104,14 @@ static const char radeon_family_name[][16] = {
+ 	"LAST",
+ };
+ 
++#if defined(CONFIG_VGA_SWITCHEROO)
++bool radeon_has_atpx_dgpu_power_cntl(void);
++bool radeon_is_atpx_hybrid(void);
++#else
++static inline bool radeon_has_atpx_dgpu_power_cntl(void) { return false; }
++static inline bool radeon_is_atpx_hybrid(void) { return false; }
++#endif
++
+ #define RADEON_PX_QUIRK_DISABLE_PX  (1 << 0)
+ #define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1)
+ 
+@@ -160,6 +168,11 @@ static void radeon_device_handle_px_quirks(struct radeon_device *rdev)
+ 
+ 	if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX)
+ 		rdev->flags &= ~RADEON_IS_PX;
++
++	/* disable PX is the system doesn't support dGPU power control or hybrid gfx */
++	if (!radeon_is_atpx_hybrid() &&
++	    !radeon_has_atpx_dgpu_power_cntl())
++		rdev->flags &= ~RADEON_IS_PX;
+ }
+ 
+ /**
+diff --git a/drivers/iio/accel/st_accel_core.c b/drivers/iio/accel/st_accel_core.c
+index da3fb069ec5c..ce69048c88e9 100644
+--- a/drivers/iio/accel/st_accel_core.c
++++ b/drivers/iio/accel/st_accel_core.c
+@@ -743,8 +743,8 @@ static int st_accel_read_raw(struct iio_dev *indio_dev,
+ 
+ 		return IIO_VAL_INT;
+ 	case IIO_CHAN_INFO_SCALE:
+-		*val = 0;
+-		*val2 = adata->current_fullscale->gain;
++		*val = adata->current_fullscale->gain / 1000000;
++		*val2 = adata->current_fullscale->gain % 1000000;
+ 		return IIO_VAL_INT_PLUS_MICRO;
+ 	case IIO_CHAN_INFO_SAMP_FREQ:
+ 		*val = adata->odr;
+@@ -763,9 +763,13 @@ static int st_accel_write_raw(struct iio_dev *indio_dev,
+ 	int err;
+ 
+ 	switch (mask) {
+-	case IIO_CHAN_INFO_SCALE:
+-		err = st_sensors_set_fullscale_by_gain(indio_dev, val2);
++	case IIO_CHAN_INFO_SCALE: {
++		int gain;
++
++		gain = val * 1000000 + val2;
++		err = st_sensors_set_fullscale_by_gain(indio_dev, gain);
+ 		break;
++	}
+ 	case IIO_CHAN_INFO_SAMP_FREQ:
+ 		if (val2)
+ 			return -EINVAL;
+diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+index dc33c1dd5191..b5beea53d6f6 100644
+--- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
++++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c
+@@ -30,26 +30,26 @@ static struct {
+ 	u32 usage_id;
+ 	int unit; /* 0 for default others from HID sensor spec */
+ 	int scale_val0; /* scale, whole number */
+-	int scale_val1; /* scale, fraction in micros */
++	int scale_val1; /* scale, fraction in nanos */
+ } unit_conversion[] = {
+-	{HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650},
++	{HID_USAGE_SENSOR_ACCEL_3D, 0, 9, 806650000},
+ 	{HID_USAGE_SENSOR_ACCEL_3D,
+ 		HID_USAGE_SENSOR_UNITS_METERS_PER_SEC_SQRD, 1, 0},
+ 	{HID_USAGE_SENSOR_ACCEL_3D,
+-		HID_USAGE_SENSOR_UNITS_G, 9, 806650},
++		HID_USAGE_SENSOR_UNITS_G, 9, 806650000},
+ 
+-	{HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453},
++	{HID_USAGE_SENSOR_GYRO_3D, 0, 0, 17453293},
+ 	{HID_USAGE_SENSOR_GYRO_3D,
+ 		HID_USAGE_SENSOR_UNITS_RADIANS_PER_SECOND, 1, 0},
+ 	{HID_USAGE_SENSOR_GYRO_3D,
+-		HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453},
++		HID_USAGE_SENSOR_UNITS_DEGREES_PER_SECOND, 0, 17453293},
+ 
+-	{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000},
++	{HID_USAGE_SENSOR_COMPASS_3D, 0, 0, 1000000},
+ 	{HID_USAGE_SENSOR_COMPASS_3D, HID_USAGE_SENSOR_UNITS_GAUSS, 1, 0},
+ 
+-	{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453},
++	{HID_USAGE_SENSOR_INCLINOMETER_3D, 0, 0, 17453293},
+ 	{HID_USAGE_SENSOR_INCLINOMETER_3D,
+-		HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453},
++		HID_USAGE_SENSOR_UNITS_DEGREES, 0, 17453293},
+ 	{HID_USAGE_SENSOR_INCLINOMETER_3D,
+ 		HID_USAGE_SENSOR_UNITS_RADIANS, 1, 0},
+ 
+@@ -57,7 +57,7 @@ static struct {
+ 	{HID_USAGE_SENSOR_ALS, HID_USAGE_SENSOR_UNITS_LUX, 1, 0},
+ 
+ 	{HID_USAGE_SENSOR_PRESSURE, 0, 100, 0},
+-	{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000},
++	{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, 0, 1000000},
+ };
+ 
+ static int pow_10(unsigned power)
+@@ -266,15 +266,15 @@ EXPORT_SYMBOL(hid_sensor_write_raw_hyst_value);
+ /*
+  * This fuction applies the unit exponent to the scale.
+  * For example:
+- * 9.806650 ->exp:2-> val0[980]val1[665000]
+- * 9.000806 ->exp:2-> val0[900]val1[80600]
+- * 0.174535 ->exp:2-> val0[17]val1[453500]
+- * 1.001745 ->exp:0-> val0[1]val1[1745]
+- * 1.001745 ->exp:2-> val0[100]val1[174500]
+- * 1.001745 ->exp:4-> val0[10017]val1[450000]
+- * 9.806650 ->exp:-2-> val0[0]val1[98066]
++ * 9.806650000 ->exp:2-> val0[980]val1[665000000]
++ * 9.000806000 ->exp:2-> val0[900]val1[80600000]
++ * 0.174535293 ->exp:2-> val0[17]val1[453529300]
++ * 1.001745329 ->exp:0-> val0[1]val1[1745329]
++ * 1.001745329 ->exp:2-> val0[100]val1[174532900]
++ * 1.001745329 ->exp:4-> val0[10017]val1[453290000]
++ * 9.806650000 ->exp:-2-> val0[0]val1[98066500]
+  */
+-static void adjust_exponent_micro(int *val0, int *val1, int scale0,
++static void adjust_exponent_nano(int *val0, int *val1, int scale0,
+ 				  int scale1, int exp)
+ {
+ 	int i;
+@@ -285,32 +285,32 @@ static void adjust_exponent_micro(int *val0, int *val1, int scale0,
+ 	if (exp > 0) {
+ 		*val0 = scale0 * pow_10(exp);
+ 		res = 0;
+-		if (exp > 6) {
++		if (exp > 9) {
+ 			*val1 = 0;
+ 			return;
+ 		}
+ 		for (i = 0; i < exp; ++i) {
+-			x = scale1 / pow_10(5 - i);
++			x = scale1 / pow_10(8 - i);
+ 			res += (pow_10(exp - 1 - i) * x);
+-			scale1 = scale1 % pow_10(5 - i);
++			scale1 = scale1 % pow_10(8 - i);
+ 		}
+ 		*val0 += res;
+ 			*val1 = scale1 * pow_10(exp);
+ 	} else if (exp < 0) {
+ 		exp = abs(exp);
+-		if (exp > 6) {
++		if (exp > 9) {
+ 			*val0 = *val1 = 0;
+ 			return;
+ 		}
+ 		*val0 = scale0 / pow_10(exp);
+ 		rem = scale0 % pow_10(exp);
+ 		res = 0;
+-		for (i = 0; i < (6 - exp); ++i) {
+-			x = scale1 / pow_10(5 - i);
+-			res += (pow_10(5 - exp - i) * x);
+-			scale1 = scale1 % pow_10(5 - i);
++		for (i = 0; i < (9 - exp); ++i) {
++			x = scale1 / pow_10(8 - i);
++			res += (pow_10(8 - exp - i) * x);
++			scale1 = scale1 % pow_10(8 - i);
+ 		}
+-		*val1 = rem * pow_10(6 - exp) + res;
++		*val1 = rem * pow_10(9 - exp) + res;
+ 	} else {
+ 		*val0 = scale0;
+ 		*val1 = scale1;
+@@ -332,14 +332,14 @@ int hid_sensor_format_scale(u32 usage_id,
+ 			unit_conversion[i].unit == attr_info->units) {
+ 			exp  = hid_sensor_convert_exponent(
+ 						attr_info->unit_expo);
+-			adjust_exponent_micro(val0, val1,
++			adjust_exponent_nano(val0, val1,
+ 					unit_conversion[i].scale_val0,
+ 					unit_conversion[i].scale_val1, exp);
+ 			break;
+ 		}
+ 	}
+ 
+-	return IIO_VAL_INT_PLUS_MICRO;
++	return IIO_VAL_INT_PLUS_NANO;
+ }
+ EXPORT_SYMBOL(hid_sensor_format_scale);
+ 
+diff --git a/drivers/iio/common/st_sensors/st_sensors_core.c b/drivers/iio/common/st_sensors/st_sensors_core.c
+index 2d5282e05482..32a594675a54 100644
+--- a/drivers/iio/common/st_sensors/st_sensors_core.c
++++ b/drivers/iio/common/st_sensors/st_sensors_core.c
+@@ -619,7 +619,7 @@ EXPORT_SYMBOL(st_sensors_sysfs_sampling_frequency_avail);
+ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
+ 				struct device_attribute *attr, char *buf)
+ {
+-	int i, len = 0;
++	int i, len = 0, q, r;
+ 	struct iio_dev *indio_dev = dev_get_drvdata(dev);
+ 	struct st_sensor_data *sdata = iio_priv(indio_dev);
+ 
+@@ -628,8 +628,10 @@ ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
+ 		if (sdata->sensor_settings->fs.fs_avl[i].num == 0)
+ 			break;
+ 
+-		len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06u ",
+-				sdata->sensor_settings->fs.fs_avl[i].gain);
++		q = sdata->sensor_settings->fs.fs_avl[i].gain / 1000000;
++		r = sdata->sensor_settings->fs.fs_avl[i].gain % 1000000;
++
++		len += scnprintf(buf + len, PAGE_SIZE - len, "%u.%06u ", q, r);
+ 	}
+ 	mutex_unlock(&indio_dev->mlock);
+ 	buf[len - 1] = '\n';
+diff --git a/drivers/iio/orientation/hid-sensor-rotation.c b/drivers/iio/orientation/hid-sensor-rotation.c
+index b98b9d94d184..a97e802ca523 100644
+--- a/drivers/iio/orientation/hid-sensor-rotation.c
++++ b/drivers/iio/orientation/hid-sensor-rotation.c
+@@ -335,6 +335,7 @@ static struct platform_driver hid_dev_rot_platform_driver = {
+ 	.id_table = hid_dev_rot_ids,
+ 	.driver = {
+ 		.name	= KBUILD_MODNAME,
++		.pm     = &hid_sensor_pm_ops,
+ 	},
+ 	.probe		= hid_dev_rot_probe,
+ 	.remove		= hid_dev_rot_remove,
+diff --git a/drivers/input/rmi4/rmi_i2c.c b/drivers/input/rmi4/rmi_i2c.c
+index 6f2e0e4f0296..1ebc2c1debae 100644
+--- a/drivers/input/rmi4/rmi_i2c.c
++++ b/drivers/input/rmi4/rmi_i2c.c
+@@ -221,6 +221,21 @@ static const struct of_device_id rmi_i2c_of_match[] = {
+ MODULE_DEVICE_TABLE(of, rmi_i2c_of_match);
+ #endif
+ 
++static void rmi_i2c_regulator_bulk_disable(void *data)
++{
++	struct rmi_i2c_xport *rmi_i2c = data;
++
++	regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
++			       rmi_i2c->supplies);
++}
++
++static void rmi_i2c_unregister_transport(void *data)
++{
++	struct rmi_i2c_xport *rmi_i2c = data;
++
++	rmi_unregister_transport_device(&rmi_i2c->xport);
++}
++
+ static int rmi_i2c_probe(struct i2c_client *client,
+ 			 const struct i2c_device_id *id)
+ {
+@@ -264,6 +279,12 @@ static int rmi_i2c_probe(struct i2c_client *client,
+ 	if (retval < 0)
+ 		return retval;
+ 
++	retval = devm_add_action_or_reset(&client->dev,
++					  rmi_i2c_regulator_bulk_disable,
++					  rmi_i2c);
++	if (retval)
++		return retval;
++
+ 	of_property_read_u32(client->dev.of_node, "syna,startup-delay-ms",
+ 			     &rmi_i2c->startup_delay);
+ 
+@@ -294,6 +315,11 @@ static int rmi_i2c_probe(struct i2c_client *client,
+ 			client->addr);
+ 		return retval;
+ 	}
++	retval = devm_add_action_or_reset(&client->dev,
++					  rmi_i2c_unregister_transport,
++					  rmi_i2c);
++	if (retval)
++		return retval;
+ 
+ 	retval = rmi_i2c_init_irq(client);
+ 	if (retval < 0)
+@@ -304,17 +330,6 @@ static int rmi_i2c_probe(struct i2c_client *client,
+ 	return 0;
+ }
+ 
+-static int rmi_i2c_remove(struct i2c_client *client)
+-{
+-	struct rmi_i2c_xport *rmi_i2c = i2c_get_clientdata(client);
+-
+-	rmi_unregister_transport_device(&rmi_i2c->xport);
+-	regulator_bulk_disable(ARRAY_SIZE(rmi_i2c->supplies),
+-			       rmi_i2c->supplies);
+-
+-	return 0;
+-}
+-
+ #ifdef CONFIG_PM_SLEEP
+ static int rmi_i2c_suspend(struct device *dev)
+ {
+@@ -431,7 +446,6 @@ static struct i2c_driver rmi_i2c_driver = {
+ 	},
+ 	.id_table	= rmi_id,
+ 	.probe		= rmi_i2c_probe,
+-	.remove		= rmi_i2c_remove,
+ };
+ 
+ module_i2c_driver(rmi_i2c_driver);
+diff --git a/drivers/input/rmi4/rmi_spi.c b/drivers/input/rmi4/rmi_spi.c
+index 55bd1b34970c..4ebef607e214 100644
+--- a/drivers/input/rmi4/rmi_spi.c
++++ b/drivers/input/rmi4/rmi_spi.c
+@@ -396,6 +396,13 @@ static inline int rmi_spi_of_probe(struct spi_device *spi,
+ }
+ #endif
+ 
++static void rmi_spi_unregister_transport(void *data)
++{
++	struct rmi_spi_xport *rmi_spi = data;
++
++	rmi_unregister_transport_device(&rmi_spi->xport);
++}
++
+ static int rmi_spi_probe(struct spi_device *spi)
+ {
+ 	struct rmi_spi_xport *rmi_spi;
+@@ -464,6 +471,11 @@ static int rmi_spi_probe(struct spi_device *spi)
+ 		dev_err(&spi->dev, "failed to register transport.\n");
+ 		return retval;
+ 	}
++	retval = devm_add_action_or_reset(&spi->dev,
++					  rmi_spi_unregister_transport,
++					  rmi_spi);
++	if (retval)
++		return retval;
+ 
+ 	retval = rmi_spi_init_irq(spi);
+ 	if (retval < 0)
+@@ -473,15 +485,6 @@ static int rmi_spi_probe(struct spi_device *spi)
+ 	return 0;
+ }
+ 
+-static int rmi_spi_remove(struct spi_device *spi)
+-{
+-	struct rmi_spi_xport *rmi_spi = spi_get_drvdata(spi);
+-
+-	rmi_unregister_transport_device(&rmi_spi->xport);
+-
+-	return 0;
+-}
+-
+ #ifdef CONFIG_PM_SLEEP
+ static int rmi_spi_suspend(struct device *dev)
+ {
+@@ -577,7 +580,6 @@ static struct spi_driver rmi_spi_driver = {
+ 	},
+ 	.id_table	= rmi_id,
+ 	.probe		= rmi_spi_probe,
+-	.remove		= rmi_spi_remove,
+ };
+ 
+ module_spi_driver(rmi_spi_driver);
+diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c
+index 96de97a46079..822fc4afad3c 100644
+--- a/drivers/iommu/amd_iommu.c
++++ b/drivers/iommu/amd_iommu.c
+@@ -1654,6 +1654,9 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom)
+ 
+ 	free_pagetable(&dom->domain);
+ 
++	if (dom->domain.id)
++		domain_id_free(dom->domain.id);
++
+ 	kfree(dom);
+ }
+ 
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index ebb5bf3ddbd9..1257b0b80296 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -1711,6 +1711,7 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
+ 	if (!iommu->domains || !iommu->domain_ids)
+ 		return;
+ 
++again:
+ 	spin_lock_irqsave(&device_domain_lock, flags);
+ 	list_for_each_entry_safe(info, tmp, &device_domain_list, global) {
+ 		struct dmar_domain *domain;
+@@ -1723,10 +1724,19 @@ static void disable_dmar_iommu(struct intel_iommu *iommu)
+ 
+ 		domain = info->domain;
+ 
+-		dmar_remove_one_dev_info(domain, info->dev);
++		__dmar_remove_one_dev_info(info);
+ 
+-		if (!domain_type_is_vm_or_si(domain))
++		if (!domain_type_is_vm_or_si(domain)) {
++			/*
++			 * The domain_exit() function  can't be called under
++			 * device_domain_lock, as it takes this lock itself.
++			 * So release the lock here and re-run the loop
++			 * afterwards.
++			 */
++			spin_unlock_irqrestore(&device_domain_lock, flags);
+ 			domain_exit(domain);
++			goto again;
++		}
+ 	}
+ 	spin_unlock_irqrestore(&device_domain_lock, flags);
+ 
+diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c
+index def8ca1c982d..f50e51c1a9c8 100644
+--- a/drivers/iommu/io-pgtable-arm-v7s.c
++++ b/drivers/iommu/io-pgtable-arm-v7s.c
+@@ -633,6 +633,10 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
+ {
+ 	struct arm_v7s_io_pgtable *data;
+ 
++#ifdef PHYS_OFFSET
++	if (upper_32_bits(PHYS_OFFSET))
++		return NULL;
++#endif
+ 	if (cfg->ias > ARM_V7S_ADDR_BITS || cfg->oas > ARM_V7S_ADDR_BITS)
+ 		return NULL;
+ 
+diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c
+index bf890c3d9cda..f73e108dc980 100644
+--- a/drivers/media/usb/dvb-usb/dib0700_core.c
++++ b/drivers/media/usb/dvb-usb/dib0700_core.c
+@@ -677,7 +677,7 @@ static void dib0700_rc_urb_completion(struct urb *purb)
+ 	struct dvb_usb_device *d = purb->context;
+ 	struct dib0700_rc_response *poll_reply;
+ 	enum rc_type protocol;
+-	u32 uninitialized_var(keycode);
++	u32 keycode;
+ 	u8 toggle;
+ 
+ 	deb_info("%s()\n", __func__);
+@@ -719,7 +719,8 @@ static void dib0700_rc_urb_completion(struct urb *purb)
+ 		    poll_reply->nec.data       == 0x00 &&
+ 		    poll_reply->nec.not_data   == 0xff) {
+ 			poll_reply->data_state = 2;
+-			break;
++			rc_repeat(d->rc_dev);
++			goto resubmit;
+ 		}
+ 
+ 		if ((poll_reply->nec.data ^ poll_reply->nec.not_data) != 0xff) {
+diff --git a/drivers/misc/mei/bus-fixup.c b/drivers/misc/mei/bus-fixup.c
+index e9e6ea3ab73c..75b9d4ac8b1e 100644
+--- a/drivers/misc/mei/bus-fixup.c
++++ b/drivers/misc/mei/bus-fixup.c
+@@ -178,7 +178,7 @@ static int mei_nfc_if_version(struct mei_cl *cl,
+ 
+ 	ret = 0;
+ 	bytes_recv = __mei_cl_recv(cl, (u8 *)reply, if_version_length);
+-	if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) {
++	if (bytes_recv < if_version_length) {
+ 		dev_err(bus->dev, "Could not read IF version\n");
+ 		ret = -EIO;
+ 		goto err;
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index c57eb32dc075..6ef1e3c731f8 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -26,6 +26,8 @@
+ #include "mmc_ops.h"
+ #include "sd_ops.h"
+ 
++#define DEFAULT_CMD6_TIMEOUT_MS	500
++
+ static const unsigned int tran_exp[] = {
+ 	10000,		100000,		1000000,	10000000,
+ 	0,		0,		0,		0
+@@ -571,6 +573,7 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
+ 		card->erased_byte = 0x0;
+ 
+ 	/* eMMC v4.5 or later */
++	card->ext_csd.generic_cmd6_time = DEFAULT_CMD6_TIMEOUT_MS;
+ 	if (card->ext_csd.rev >= 6) {
+ 		card->ext_csd.feature_support |= MMC_DISCARD_FEATURE;
+ 
+diff --git a/drivers/mmc/host/mxs-mmc.c b/drivers/mmc/host/mxs-mmc.c
+index d839147e591d..44ecebd1ea8c 100644
+--- a/drivers/mmc/host/mxs-mmc.c
++++ b/drivers/mmc/host/mxs-mmc.c
+@@ -661,13 +661,13 @@ static int mxs_mmc_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, mmc);
+ 
++	spin_lock_init(&host->lock);
++
+ 	ret = devm_request_irq(&pdev->dev, irq_err, mxs_mmc_irq_handler, 0,
+ 			       dev_name(&pdev->dev), host);
+ 	if (ret)
+ 		goto out_free_dma;
+ 
+-	spin_lock_init(&host->lock);
+-
+ 	ret = mmc_add_host(mmc);
+ 	if (ret)
+ 		goto out_free_dma;
+diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c
+index 8ef44a2a2fd9..90ed2e12d345 100644
+--- a/drivers/mmc/host/sdhci-msm.c
++++ b/drivers/mmc/host/sdhci-msm.c
+@@ -647,6 +647,7 @@ static int sdhci_msm_probe(struct platform_device *pdev)
+ 	if (msm_host->pwr_irq < 0) {
+ 		dev_err(&pdev->dev, "Get pwr_irq failed (%d)\n",
+ 			msm_host->pwr_irq);
++		ret = msm_host->pwr_irq;
+ 		goto clk_disable;
+ 	}
+ 
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index a8a022a7358f..6eb8f0705c65 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -2269,10 +2269,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ 
+ 	for (i = 0; i < SDHCI_MAX_MRQS; i++) {
+ 		mrq = host->mrqs_done[i];
+-		if (mrq) {
+-			host->mrqs_done[i] = NULL;
++		if (mrq)
+ 			break;
+-		}
+ 	}
+ 
+ 	if (!mrq) {
+@@ -2303,6 +2301,17 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ 	 * upon error conditions.
+ 	 */
+ 	if (sdhci_needs_reset(host, mrq)) {
++		/*
++		 * Do not finish until command and data lines are available for
++		 * reset. Note there can only be one other mrq, so it cannot
++		 * also be in mrqs_done, otherwise host->cmd and host->data_cmd
++		 * would both be null.
++		 */
++		if (host->cmd || host->data_cmd) {
++			spin_unlock_irqrestore(&host->lock, flags);
++			return true;
++		}
++
+ 		/* Some controllers need this kick or reset won't work here */
+ 		if (host->quirks & SDHCI_QUIRK_CLOCK_BEFORE_RESET)
+ 			/* This is to force an update */
+@@ -2310,10 +2319,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ 
+ 		/* Spec says we should do both at the same time, but Ricoh
+ 		   controllers do not like that. */
+-		if (!host->cmd)
+-			sdhci_do_reset(host, SDHCI_RESET_CMD);
+-		if (!host->data_cmd)
+-			sdhci_do_reset(host, SDHCI_RESET_DATA);
++		sdhci_do_reset(host, SDHCI_RESET_CMD);
++		sdhci_do_reset(host, SDHCI_RESET_DATA);
+ 
+ 		host->pending_reset = false;
+ 	}
+@@ -2321,6 +2328,8 @@ static bool sdhci_request_done(struct sdhci_host *host)
+ 	if (!sdhci_has_requests(host))
+ 		sdhci_led_deactivate(host);
+ 
++	host->mrqs_done[i] = NULL;
++
+ 	mmiowb();
+ 	spin_unlock_irqrestore(&host->lock, flags);
+ 
+@@ -2500,9 +2509,6 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ 	if (!host->data) {
+ 		struct mmc_command *data_cmd = host->data_cmd;
+ 
+-		if (data_cmd)
+-			host->data_cmd = NULL;
+-
+ 		/*
+ 		 * The "data complete" interrupt is also used to
+ 		 * indicate that a busy state has ended. See comment
+@@ -2510,11 +2516,13 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask)
+ 		 */
+ 		if (data_cmd && (data_cmd->flags & MMC_RSP_BUSY)) {
+ 			if (intmask & SDHCI_INT_DATA_TIMEOUT) {
++				host->data_cmd = NULL;
+ 				data_cmd->error = -ETIMEDOUT;
+ 				sdhci_finish_mrq(host, data_cmd->mrq);
+ 				return;
+ 			}
+ 			if (intmask & SDHCI_INT_DATA_END) {
++				host->data_cmd = NULL;
+ 				/*
+ 				 * Some cards handle busy-end interrupt
+ 				 * before the command completed, so make
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index c74d16409941..6b46a37ba139 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -9001,7 +9001,7 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
+ 		return 0;
+ 
+ 	return ndo_dflt_bridge_getlink(skb, pid, seq, dev, veb->bridge_mode,
+-				       nlflags, 0, 0, filter_mask, NULL);
++				       0, 0, nlflags, filter_mask, NULL);
+ }
+ 
+ /* Hardware supports L4 tunnel length of 128B (=2^7) which includes
+diff --git a/drivers/nfc/mei_phy.c b/drivers/nfc/mei_phy.c
+index 83deda4bb4d6..6f9563a96488 100644
+--- a/drivers/nfc/mei_phy.c
++++ b/drivers/nfc/mei_phy.c
+@@ -133,7 +133,7 @@ static int mei_nfc_if_version(struct nfc_mei_phy *phy)
+ 		return -ENOMEM;
+ 
+ 	bytes_recv = mei_cldev_recv(phy->cldev, (u8 *)reply, if_version_length);
+-	if (bytes_recv < 0 || bytes_recv < sizeof(struct mei_nfc_reply)) {
++	if (bytes_recv < 0 || bytes_recv < if_version_length) {
+ 		pr_err("Could not read IF version\n");
+ 		r = -EIO;
+ 		goto err;
+diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
+index 60f7eab11865..da134a0df7d8 100644
+--- a/drivers/nvme/host/pci.c
++++ b/drivers/nvme/host/pci.c
+@@ -1531,9 +1531,9 @@ static int nvme_delete_queue(struct nvme_queue *nvmeq, u8 opcode)
+ 	return 0;
+ }
+ 
+-static void nvme_disable_io_queues(struct nvme_dev *dev)
++static void nvme_disable_io_queues(struct nvme_dev *dev, int queues)
+ {
+-	int pass, queues = dev->online_queues - 1;
++	int pass;
+ 	unsigned long timeout;
+ 	u8 opcode = nvme_admin_delete_sq;
+ 
+@@ -1678,7 +1678,7 @@ static void nvme_pci_disable(struct nvme_dev *dev)
+ 
+ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
+ {
+-	int i;
++	int i, queues;
+ 	u32 csts = -1;
+ 
+ 	del_timer_sync(&dev->watchdog_timer);
+@@ -1689,6 +1689,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
+ 		csts = readl(dev->bar + NVME_REG_CSTS);
+ 	}
+ 
++	queues = dev->online_queues - 1;
+ 	for (i = dev->queue_count - 1; i > 0; i--)
+ 		nvme_suspend_queue(dev->queues[i]);
+ 
+@@ -1700,7 +1701,7 @@ static void nvme_dev_disable(struct nvme_dev *dev, bool shutdown)
+ 		if (dev->queue_count)
+ 			nvme_suspend_queue(dev->queues[0]);
+ 	} else {
+-		nvme_disable_io_queues(dev);
++		nvme_disable_io_queues(dev, queues);
+ 		nvme_disable_admin_queue(dev, shutdown);
+ 	}
+ 	nvme_pci_disable(dev);
+diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
+index 66c4d8f42233..9526e341988b 100644
+--- a/drivers/pci/setup-res.c
++++ b/drivers/pci/setup-res.c
+@@ -121,6 +121,14 @@ int pci_claim_resource(struct pci_dev *dev, int resource)
+ 		return -EINVAL;
+ 	}
+ 
++	/*
++	 * If we have a shadow copy in RAM, the PCI device doesn't respond
++	 * to the shadow range, so we don't need to claim it, and upstream
++	 * bridges don't need to route the range to the device.
++	 */
++	if (res->flags & IORESOURCE_ROM_SHADOW)
++		return 0;
++
+ 	root = pci_find_parent_resource(dev, res);
+ 	if (!root) {
+ 		dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n",
+diff --git a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+index 7f7700716398..5d1e505c3c63 100644
+--- a/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
++++ b/drivers/pinctrl/bcm/pinctrl-iproc-gpio.c
+@@ -844,6 +844,6 @@ static struct platform_driver iproc_gpio_driver = {
+ 
+ static int __init iproc_gpio_init(void)
+ {
+-	return platform_driver_probe(&iproc_gpio_driver, iproc_gpio_probe);
++	return platform_driver_register(&iproc_gpio_driver);
+ }
+ arch_initcall_sync(iproc_gpio_init);
+diff --git a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+index 35783db1c10b..c8deb8be1da7 100644
+--- a/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
++++ b/drivers/pinctrl/bcm/pinctrl-nsp-gpio.c
+@@ -741,6 +741,6 @@ static struct platform_driver nsp_gpio_driver = {
+ 
+ static int __init nsp_gpio_init(void)
+ {
+-	return platform_driver_probe(&nsp_gpio_driver, nsp_gpio_probe);
++	return platform_driver_register(&nsp_gpio_driver);
+ }
+ arch_initcall_sync(nsp_gpio_init);
+diff --git a/drivers/pinctrl/intel/pinctrl-cherryview.c b/drivers/pinctrl/intel/pinctrl-cherryview.c
+index 0fe8fad25e4d..bc3150428d89 100644
+--- a/drivers/pinctrl/intel/pinctrl-cherryview.c
++++ b/drivers/pinctrl/intel/pinctrl-cherryview.c
+@@ -1634,12 +1634,15 @@ static int chv_pinctrl_remove(struct platform_device *pdev)
+ }
+ 
+ #ifdef CONFIG_PM_SLEEP
+-static int chv_pinctrl_suspend(struct device *dev)
++static int chv_pinctrl_suspend_noirq(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+ 	struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
++	unsigned long flags;
+ 	int i;
+ 
++	raw_spin_lock_irqsave(&chv_lock, flags);
++
+ 	pctrl->saved_intmask = readl(pctrl->regs + CHV_INTMASK);
+ 
+ 	for (i = 0; i < pctrl->community->npins; i++) {
+@@ -1660,15 +1663,20 @@ static int chv_pinctrl_suspend(struct device *dev)
+ 		ctx->padctrl1 = readl(reg);
+ 	}
+ 
++	raw_spin_unlock_irqrestore(&chv_lock, flags);
++
+ 	return 0;
+ }
+ 
+-static int chv_pinctrl_resume(struct device *dev)
++static int chv_pinctrl_resume_noirq(struct device *dev)
+ {
+ 	struct platform_device *pdev = to_platform_device(dev);
+ 	struct chv_pinctrl *pctrl = platform_get_drvdata(pdev);
++	unsigned long flags;
+ 	int i;
+ 
++	raw_spin_lock_irqsave(&chv_lock, flags);
++
+ 	/*
+ 	 * Mask all interrupts before restoring per-pin configuration
+ 	 * registers because we don't know in which state BIOS left them
+@@ -1713,12 +1721,15 @@ static int chv_pinctrl_resume(struct device *dev)
+ 	chv_writel(0xffff, pctrl->regs + CHV_INTSTAT);
+ 	chv_writel(pctrl->saved_intmask, pctrl->regs + CHV_INTMASK);
+ 
++	raw_spin_unlock_irqrestore(&chv_lock, flags);
++
+ 	return 0;
+ }
+ #endif
+ 
+ static const struct dev_pm_ops chv_pinctrl_pm_ops = {
+-	SET_LATE_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend, chv_pinctrl_resume)
++	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(chv_pinctrl_suspend_noirq,
++				      chv_pinctrl_resume_noirq)
+ };
+ 
+ static const struct acpi_device_id chv_pinctrl_acpi_match[] = {
+diff --git a/drivers/platform/x86/toshiba-wmi.c b/drivers/platform/x86/toshiba-wmi.c
+index feac4576b837..2df07ee8f3c3 100644
+--- a/drivers/platform/x86/toshiba-wmi.c
++++ b/drivers/platform/x86/toshiba-wmi.c
+@@ -24,14 +24,15 @@
+ #include <linux/acpi.h>
+ #include <linux/input.h>
+ #include <linux/input/sparse-keymap.h>
++#include <linux/dmi.h>
+ 
+ MODULE_AUTHOR("Azael Avalos");
+ MODULE_DESCRIPTION("Toshiba WMI Hotkey Driver");
+ MODULE_LICENSE("GPL");
+ 
+-#define TOSHIBA_WMI_EVENT_GUID	"59142400-C6A3-40FA-BADB-8A2652834100"
++#define WMI_EVENT_GUID	"59142400-C6A3-40FA-BADB-8A2652834100"
+ 
+-MODULE_ALIAS("wmi:"TOSHIBA_WMI_EVENT_GUID);
++MODULE_ALIAS("wmi:"WMI_EVENT_GUID);
+ 
+ static struct input_dev *toshiba_wmi_input_dev;
+ 
+@@ -63,6 +64,16 @@ static void toshiba_wmi_notify(u32 value, void *context)
+ 	kfree(response.pointer);
+ }
+ 
++static struct dmi_system_id toshiba_wmi_dmi_table[] __initdata = {
++	{
++		.ident = "Toshiba laptop",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"),
++		},
++	},
++	{}
++};
++
+ static int __init toshiba_wmi_input_setup(void)
+ {
+ 	acpi_status status;
+@@ -81,7 +92,7 @@ static int __init toshiba_wmi_input_setup(void)
+ 	if (err)
+ 		goto err_free_dev;
+ 
+-	status = wmi_install_notify_handler(TOSHIBA_WMI_EVENT_GUID,
++	status = wmi_install_notify_handler(WMI_EVENT_GUID,
+ 					    toshiba_wmi_notify, NULL);
+ 	if (ACPI_FAILURE(status)) {
+ 		err = -EIO;
+@@ -95,7 +106,7 @@ static int __init toshiba_wmi_input_setup(void)
+ 	return 0;
+ 
+  err_remove_notifier:
+-	wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID);
++	wmi_remove_notify_handler(WMI_EVENT_GUID);
+  err_free_keymap:
+ 	sparse_keymap_free(toshiba_wmi_input_dev);
+  err_free_dev:
+@@ -105,7 +116,7 @@ static int __init toshiba_wmi_input_setup(void)
+ 
+ static void toshiba_wmi_input_destroy(void)
+ {
+-	wmi_remove_notify_handler(TOSHIBA_WMI_EVENT_GUID);
++	wmi_remove_notify_handler(WMI_EVENT_GUID);
+ 	sparse_keymap_free(toshiba_wmi_input_dev);
+ 	input_unregister_device(toshiba_wmi_input_dev);
+ }
+@@ -114,7 +125,8 @@ static int __init toshiba_wmi_init(void)
+ {
+ 	int ret;
+ 
+-	if (!wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
++	if (!wmi_has_guid(WMI_EVENT_GUID) ||
++	    !dmi_check_system(toshiba_wmi_dmi_table))
+ 		return -ENODEV;
+ 
+ 	ret = toshiba_wmi_input_setup();
+@@ -130,7 +142,7 @@ static int __init toshiba_wmi_init(void)
+ 
+ static void __exit toshiba_wmi_exit(void)
+ {
+-	if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID))
++	if (wmi_has_guid(WMI_EVENT_GUID))
+ 		toshiba_wmi_input_destroy();
+ }
+ 
+diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c
+index b4478cc92b55..8895f77726e8 100644
+--- a/drivers/rtc/rtc-pcf2123.c
++++ b/drivers/rtc/rtc-pcf2123.c
+@@ -182,7 +182,8 @@ static ssize_t pcf2123_show(struct device *dev, struct device_attribute *attr,
+ }
+ 
+ static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
+-			     const char *buffer, size_t count) {
++			     const char *buffer, size_t count)
++{
+ 	struct pcf2123_sysfs_reg *r;
+ 	unsigned long reg;
+ 	unsigned long val;
+@@ -199,7 +200,7 @@ static ssize_t pcf2123_store(struct device *dev, struct device_attribute *attr,
+ 	if (ret)
+ 		return ret;
+ 
+-	pcf2123_write_reg(dev, reg, val);
++	ret = pcf2123_write_reg(dev, reg, val);
+ 	if (ret < 0)
+ 		return -EIO;
+ 	return count;
+diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
+index 752b5c9d1ab2..920c42151e92 100644
+--- a/drivers/scsi/device_handler/scsi_dh_alua.c
++++ b/drivers/scsi/device_handler/scsi_dh_alua.c
+@@ -792,6 +792,7 @@ static void alua_rtpg_work(struct work_struct *work)
+ 		WARN_ON(pg->flags & ALUA_PG_RUN_RTPG);
+ 		WARN_ON(pg->flags & ALUA_PG_RUN_STPG);
+ 		spin_unlock_irqrestore(&pg->lock, flags);
++		kref_put(&pg->kref, release_port_group);
+ 		return;
+ 	}
+ 	if (pg->flags & ALUA_SYNC_STPG)
+@@ -889,6 +890,7 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
+ 		/* Do not queue if the worker is already running */
+ 		if (!(pg->flags & ALUA_PG_RUNNING)) {
+ 			kref_get(&pg->kref);
++			sdev = NULL;
+ 			start_queue = 1;
+ 		}
+ 	}
+@@ -900,7 +902,8 @@ static void alua_rtpg_queue(struct alua_port_group *pg,
+ 	if (start_queue &&
+ 	    !queue_delayed_work(alua_wq, &pg->rtpg_work,
+ 				msecs_to_jiffies(ALUA_RTPG_DELAY_MSECS))) {
+-		scsi_device_put(sdev);
++		if (sdev)
++			scsi_device_put(sdev);
+ 		kref_put(&pg->kref, release_port_group);
+ 	}
+ }
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index 4cb79902e7a8..46c0f5ecd99d 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -1273,9 +1273,9 @@ scsih_target_alloc(struct scsi_target *starget)
+ 			sas_target_priv_data->handle = raid_device->handle;
+ 			sas_target_priv_data->sas_address = raid_device->wwid;
+ 			sas_target_priv_data->flags |= MPT_TARGET_FLAGS_VOLUME;
+-			sas_target_priv_data->raid_device = raid_device;
+ 			if (ioc->is_warpdrive)
+-				raid_device->starget = starget;
++				sas_target_priv_data->raid_device = raid_device;
++			raid_device->starget = starget;
+ 		}
+ 		spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
+ 		return 0;
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 2674f4c16bc3..e46e2c53871a 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -2341,6 +2341,8 @@ qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time)
+ {
+ 	scsi_qla_host_t *vha = shost_priv(shost);
+ 
++	if (test_bit(UNLOADING, &vha->dpc_flags))
++		return 1;
+ 	if (!vha->host)
+ 		return 1;
+ 	if (time > vha->hw->loop_reset_delay * HZ)
+diff --git a/drivers/staging/comedi/drivers/ni_tio.c b/drivers/staging/comedi/drivers/ni_tio.c
+index 7043eb0543f6..5ab49a798164 100644
+--- a/drivers/staging/comedi/drivers/ni_tio.c
++++ b/drivers/staging/comedi/drivers/ni_tio.c
+@@ -207,7 +207,8 @@ static int ni_tio_clock_period_ps(const struct ni_gpct *counter,
+ 		 * clock period is specified by user with prescaling
+ 		 * already taken into account.
+ 		 */
+-		return counter->clock_period_ps;
++		*period_ps = counter->clock_period_ps;
++		return 0;
+ 	}
+ 
+ 	switch (generic_clock_source & NI_GPCT_PRESCALE_MODE_CLOCK_SRC_MASK) {
+diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c
+index 24c348d2f5bb..98d947338e01 100644
+--- a/drivers/staging/iio/impedance-analyzer/ad5933.c
++++ b/drivers/staging/iio/impedance-analyzer/ad5933.c
+@@ -655,6 +655,7 @@ static void ad5933_work(struct work_struct *work)
+ 	__be16 buf[2];
+ 	int val[2];
+ 	unsigned char status;
++	int ret;
+ 
+ 	mutex_lock(&indio_dev->mlock);
+ 	if (st->state == AD5933_CTRL_INIT_START_FREQ) {
+@@ -662,19 +663,22 @@ static void ad5933_work(struct work_struct *work)
+ 		ad5933_cmd(st, AD5933_CTRL_START_SWEEP);
+ 		st->state = AD5933_CTRL_START_SWEEP;
+ 		schedule_delayed_work(&st->work, st->poll_time_jiffies);
+-		mutex_unlock(&indio_dev->mlock);
+-		return;
++		goto out;
+ 	}
+ 
+-	ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
++	ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status);
++	if (ret)
++		goto out;
+ 
+ 	if (status & AD5933_STAT_DATA_VALID) {
+ 		int scan_count = bitmap_weight(indio_dev->active_scan_mask,
+ 					       indio_dev->masklength);
+-		ad5933_i2c_read(st->client,
++		ret = ad5933_i2c_read(st->client,
+ 				test_bit(1, indio_dev->active_scan_mask) ?
+ 				AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA,
+ 				scan_count * 2, (u8 *)buf);
++		if (ret)
++			goto out;
+ 
+ 		if (scan_count == 2) {
+ 			val[0] = be16_to_cpu(buf[0]);
+@@ -686,8 +690,7 @@ static void ad5933_work(struct work_struct *work)
+ 	} else {
+ 		/* no data available - try again later */
+ 		schedule_delayed_work(&st->work, st->poll_time_jiffies);
+-		mutex_unlock(&indio_dev->mlock);
+-		return;
++		goto out;
+ 	}
+ 
+ 	if (status & AD5933_STAT_SWEEP_DONE) {
+@@ -700,7 +703,7 @@ static void ad5933_work(struct work_struct *work)
+ 		ad5933_cmd(st, AD5933_CTRL_INC_FREQ);
+ 		schedule_delayed_work(&st->work, st->poll_time_jiffies);
+ 	}
+-
++out:
+ 	mutex_unlock(&indio_dev->mlock);
+ }
+ 
+diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c
+index a324322ee0ad..499952c8ef39 100644
+--- a/drivers/staging/nvec/nvec_ps2.c
++++ b/drivers/staging/nvec/nvec_ps2.c
+@@ -106,13 +106,12 @@ static int nvec_mouse_probe(struct platform_device *pdev)
+ {
+ 	struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent);
+ 	struct serio *ser_dev;
+-	char mouse_reset[] = { NVEC_PS2, SEND_COMMAND, PSMOUSE_RST, 3 };
+ 
+-	ser_dev = devm_kzalloc(&pdev->dev, sizeof(struct serio), GFP_KERNEL);
++	ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL);
+ 	if (!ser_dev)
+ 		return -ENOMEM;
+ 
+-	ser_dev->id.type = SERIO_PS_PSTHRU;
++	ser_dev->id.type = SERIO_8042;
+ 	ser_dev->write = ps2_sendcommand;
+ 	ser_dev->start = ps2_startstreaming;
+ 	ser_dev->stop = ps2_stopstreaming;
+@@ -127,9 +126,6 @@ static int nvec_mouse_probe(struct platform_device *pdev)
+ 
+ 	serio_register_port(ser_dev);
+ 
+-	/* mouse reset */
+-	nvec_write_async(nvec, mouse_reset, sizeof(mouse_reset));
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/staging/sm750fb/ddk750_reg.h b/drivers/staging/sm750fb/ddk750_reg.h
+index 955247979aaa..4ed6d8d7712a 100644
+--- a/drivers/staging/sm750fb/ddk750_reg.h
++++ b/drivers/staging/sm750fb/ddk750_reg.h
+@@ -601,13 +601,13 @@
+ 
+ #define PANEL_PLANE_TL                                0x08001C
+ #define PANEL_PLANE_TL_TOP_SHIFT                      16
+-#define PANEL_PLANE_TL_TOP_MASK                       (0xeff << 16)
+-#define PANEL_PLANE_TL_LEFT_MASK                      0xeff
++#define PANEL_PLANE_TL_TOP_MASK                       (0x7ff << 16)
++#define PANEL_PLANE_TL_LEFT_MASK                      0x7ff
+ 
+ #define PANEL_PLANE_BR                                0x080020
+ #define PANEL_PLANE_BR_BOTTOM_SHIFT                   16
+-#define PANEL_PLANE_BR_BOTTOM_MASK                    (0xeff << 16)
+-#define PANEL_PLANE_BR_RIGHT_MASK                     0xeff
++#define PANEL_PLANE_BR_BOTTOM_MASK                    (0x7ff << 16)
++#define PANEL_PLANE_BR_RIGHT_MASK                     0x7ff
+ 
+ #define PANEL_HORIZONTAL_TOTAL                        0x080024
+ #define PANEL_HORIZONTAL_TOTAL_TOTAL_SHIFT            16
+diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
+index 8bbde52db376..21aeac59df48 100644
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -2026,6 +2026,7 @@ static void atmel_serial_pm(struct uart_port *port, unsigned int state,
+ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
+ 			      struct ktermios *old)
+ {
++	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+ 	unsigned long flags;
+ 	unsigned int old_mode, mode, imr, quot, baud;
+ 
+@@ -2129,11 +2130,29 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
+ 		mode |= ATMEL_US_USMODE_RS485;
+ 	} else if (termios->c_cflag & CRTSCTS) {
+ 		/* RS232 with hardware handshake (RTS/CTS) */
+-		if (atmel_use_dma_rx(port) && !atmel_use_fifo(port)) {
+-			dev_info(port->dev, "not enabling hardware flow control because DMA is used");
+-			termios->c_cflag &= ~CRTSCTS;
+-		} else {
++		if (atmel_use_fifo(port) &&
++		    !mctrl_gpio_to_gpiod(atmel_port->gpios, UART_GPIO_CTS)) {
++			/*
++			 * with ATMEL_US_USMODE_HWHS set, the controller will
++			 * be able to drive the RTS pin high/low when the RX
++			 * FIFO is above RXFTHRES/below RXFTHRES2.
++			 * It will also disable the transmitter when the CTS
++			 * pin is high.
++			 * This mode is not activated if CTS pin is a GPIO
++			 * because in this case, the transmitter is always
++			 * disabled (there must be an internal pull-up
++			 * responsible for this behaviour).
++			 * If the RTS pin is a GPIO, the controller won't be
++			 * able to drive it according to the FIFO thresholds,
++			 * but it will be handled by the driver.
++			 */
+ 			mode |= ATMEL_US_USMODE_HWHS;
++		} else {
++			/*
++			 * For platforms without FIFO, the flow control is
++			 * handled by the driver.
++			 */
++			mode |= ATMEL_US_USMODE_NORMAL;
+ 		}
+ 	} else {
+ 		/* RS232 without hadware handshake */
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 0f3f62e81e5b..3ca9fdb0a271 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -946,8 +946,6 @@ static int wait_serial_change(struct acm *acm, unsigned long arg)
+ 	DECLARE_WAITQUEUE(wait, current);
+ 	struct async_icount old, new;
+ 
+-	if (arg & (TIOCM_DSR | TIOCM_RI | TIOCM_CD))
+-		return -EINVAL;
+ 	do {
+ 		spin_lock_irq(&acm->read_lock);
+ 		old = acm->oldcount;
+@@ -1175,6 +1173,8 @@ static int acm_probe(struct usb_interface *intf,
+ 	if (quirks == IGNORE_DEVICE)
+ 		return -ENODEV;
+ 
++	memset(&h, 0x00, sizeof(struct usb_cdc_parsed_header));
++
+ 	num_rx_buf = (quirks == SINGLE_RX_URB) ? 1 : ACM_NR;
+ 
+ 	/* handle quirks deadly to normal probing*/
+diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
+index 35d092456bec..2d47010e55af 100644
+--- a/drivers/usb/dwc3/core.c
++++ b/drivers/usb/dwc3/core.c
+@@ -669,15 +669,14 @@ static int dwc3_core_init(struct dwc3 *dwc)
+ 	return 0;
+ 
+ err4:
+-	phy_power_off(dwc->usb2_generic_phy);
++	phy_power_off(dwc->usb3_generic_phy);
+ 
+ err3:
+-	phy_power_off(dwc->usb3_generic_phy);
++	phy_power_off(dwc->usb2_generic_phy);
+ 
+ err2:
+ 	usb_phy_set_suspend(dwc->usb2_phy, 1);
+ 	usb_phy_set_suspend(dwc->usb3_phy, 1);
+-	dwc3_core_exit(dwc);
+ 
+ err1:
+ 	usb_phy_shutdown(dwc->usb2_phy);
+diff --git a/drivers/usb/gadget/function/u_ether.c b/drivers/usb/gadget/function/u_ether.c
+index 9b9e71f2c66e..f590adaaba8e 100644
+--- a/drivers/usb/gadget/function/u_ether.c
++++ b/drivers/usb/gadget/function/u_ether.c
+@@ -585,14 +585,6 @@ static netdev_tx_t eth_start_xmit(struct sk_buff *skb,
+ 
+ 	req->length = length;
+ 
+-	/* throttle high/super speed IRQ rate back slightly */
+-	if (gadget_is_dualspeed(dev->gadget))
+-		req->no_interrupt = (((dev->gadget->speed == USB_SPEED_HIGH ||
+-				       dev->gadget->speed == USB_SPEED_SUPER)) &&
+-					!list_empty(&dev->tx_reqs))
+-			? ((atomic_read(&dev->tx_qlen) % dev->qmult) != 0)
+-			: 0;
+-
+ 	retval = usb_ep_queue(in, req, GFP_ATOMIC);
+ 	switch (retval) {
+ 	default:
+diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c
+index 6abb83cd7681..74265b2f806c 100644
+--- a/drivers/watchdog/watchdog_core.c
++++ b/drivers/watchdog/watchdog_core.c
+@@ -349,7 +349,7 @@ int devm_watchdog_register_device(struct device *dev,
+ 	struct watchdog_device **rcwdd;
+ 	int ret;
+ 
+-	rcwdd = devres_alloc(devm_watchdog_unregister_device, sizeof(*wdd),
++	rcwdd = devres_alloc(devm_watchdog_unregister_device, sizeof(*rcwdd),
+ 			     GFP_KERNEL);
+ 	if (!rcwdd)
+ 		return -ENOMEM;
+diff --git a/fs/coredump.c b/fs/coredump.c
+index 281b768000e6..eb9c92c9b20f 100644
+--- a/fs/coredump.c
++++ b/fs/coredump.c
+@@ -1,6 +1,7 @@
+ #include <linux/slab.h>
+ #include <linux/file.h>
+ #include <linux/fdtable.h>
++#include <linux/freezer.h>
+ #include <linux/mm.h>
+ #include <linux/stat.h>
+ #include <linux/fcntl.h>
+@@ -423,7 +424,9 @@ static int coredump_wait(int exit_code, struct core_state *core_state)
+ 	if (core_waiters > 0) {
+ 		struct core_thread *ptr;
+ 
++		freezer_do_not_count();
+ 		wait_for_completion(&core_state->startup);
++		freezer_count();
+ 		/*
+ 		 * Wait for all the threads to become inactive, so that
+ 		 * all the thread context (extended register state, like
+diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
+index b62973045a3e..150c5a1879bf 100644
+--- a/fs/nfs/nfs4session.c
++++ b/fs/nfs/nfs4session.c
+@@ -178,12 +178,14 @@ static int nfs4_slot_get_seqid(struct nfs4_slot_table  *tbl, u32 slotid,
+ 	__must_hold(&tbl->slot_tbl_lock)
+ {
+ 	struct nfs4_slot *slot;
++	int ret;
+ 
+ 	slot = nfs4_lookup_slot(tbl, slotid);
+-	if (IS_ERR(slot))
+-		return PTR_ERR(slot);
+-	*seq_nr = slot->seq_nr;
+-	return 0;
++	ret = PTR_ERR_OR_ZERO(slot);
++	if (!ret)
++		*seq_nr = slot->seq_nr;
++
++	return ret;
+ }
+ 
+ /*
+diff --git a/include/linux/acpi.h b/include/linux/acpi.h
+index c5eaf2f80a4c..67d1d3ebb4b2 100644
+--- a/include/linux/acpi.h
++++ b/include/linux/acpi.h
+@@ -318,6 +318,7 @@ struct pci_dev;
+ int acpi_pci_irq_enable (struct pci_dev *dev);
+ void acpi_penalize_isa_irq(int irq, int active);
+ bool acpi_isa_irq_available(int irq);
++void acpi_penalize_sci_irq(int irq, int trigger, int polarity);
+ void acpi_pci_irq_disable (struct pci_dev *dev);
+ 
+ extern int ec_read(u8 addr, u8 *val);
+diff --git a/include/linux/frontswap.h b/include/linux/frontswap.h
+index c46d2aa16d81..1d18af034554 100644
+--- a/include/linux/frontswap.h
++++ b/include/linux/frontswap.h
+@@ -106,8 +106,9 @@ static inline void frontswap_invalidate_area(unsigned type)
+ 
+ static inline void frontswap_init(unsigned type, unsigned long *map)
+ {
+-	if (frontswap_enabled())
+-		__frontswap_init(type, map);
++#ifdef CONFIG_FRONTSWAP
++	__frontswap_init(type, map);
++#endif
+ }
+ 
+ #endif /* _LINUX_FRONTSWAP_H */
+diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h
+index d6917b896d3a..3584bc8864c4 100644
+--- a/include/linux/sunrpc/svc_rdma.h
++++ b/include/linux/sunrpc/svc_rdma.h
+@@ -86,6 +86,7 @@ struct svc_rdma_op_ctxt {
+ 	unsigned long flags;
+ 	enum dma_data_direction direction;
+ 	int count;
++	unsigned int mapped_sges;
+ 	struct ib_sge sge[RPCSVC_MAXPAGES];
+ 	struct page *pages[RPCSVC_MAXPAGES];
+ };
+@@ -193,6 +194,14 @@ struct svcxprt_rdma {
+ 
+ #define RPCSVC_MAXPAYLOAD_RDMA	RPCSVC_MAXPAYLOAD
+ 
++/* Track DMA maps for this transport and context */
++static inline void svc_rdma_count_mappings(struct svcxprt_rdma *rdma,
++					   struct svc_rdma_op_ctxt *ctxt)
++{
++	ctxt->mapped_sges++;
++	atomic_inc(&rdma->sc_dma_used);
++}
++
+ /* svc_rdma_backchannel.c */
+ extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt,
+ 				    struct rpcrdma_msg *rmsgp,
+diff --git a/lib/genalloc.c b/lib/genalloc.c
+index 0a1139644d32..144fe6b1a03e 100644
+--- a/lib/genalloc.c
++++ b/lib/genalloc.c
+@@ -292,7 +292,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
+ 	struct gen_pool_chunk *chunk;
+ 	unsigned long addr = 0;
+ 	int order = pool->min_alloc_order;
+-	int nbits, start_bit = 0, end_bit, remain;
++	int nbits, start_bit, end_bit, remain;
+ 
+ #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
+ 	BUG_ON(in_nmi());
+@@ -307,6 +307,7 @@ unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
+ 		if (size > atomic_read(&chunk->avail))
+ 			continue;
+ 
++		start_bit = 0;
+ 		end_bit = chunk_size(chunk) >> order;
+ retry:
+ 		start_bit = algo(chunk->bits, end_bit, start_bit,
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 770d83eb3f48..0ddce6a1cdf7 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1826,11 +1826,17 @@ static void return_unused_surplus_pages(struct hstate *h,
+  * is not the case is if a reserve map was changed between calls.  It
+  * is the responsibility of the caller to notice the difference and
+  * take appropriate action.
++ *
++ * vma_add_reservation is used in error paths where a reservation must
++ * be restored when a newly allocated huge page must be freed.  It is
++ * to be called after calling vma_needs_reservation to determine if a
++ * reservation exists.
+  */
+ enum vma_resv_mode {
+ 	VMA_NEEDS_RESV,
+ 	VMA_COMMIT_RESV,
+ 	VMA_END_RESV,
++	VMA_ADD_RESV,
+ };
+ static long __vma_reservation_common(struct hstate *h,
+ 				struct vm_area_struct *vma, unsigned long addr,
+@@ -1856,6 +1862,14 @@ static long __vma_reservation_common(struct hstate *h,
+ 		region_abort(resv, idx, idx + 1);
+ 		ret = 0;
+ 		break;
++	case VMA_ADD_RESV:
++		if (vma->vm_flags & VM_MAYSHARE)
++			ret = region_add(resv, idx, idx + 1);
++		else {
++			region_abort(resv, idx, idx + 1);
++			ret = region_del(resv, idx, idx + 1);
++		}
++		break;
+ 	default:
+ 		BUG();
+ 	}
+@@ -1903,6 +1917,56 @@ static void vma_end_reservation(struct hstate *h,
+ 	(void)__vma_reservation_common(h, vma, addr, VMA_END_RESV);
+ }
+ 
++static long vma_add_reservation(struct hstate *h,
++			struct vm_area_struct *vma, unsigned long addr)
++{
++	return __vma_reservation_common(h, vma, addr, VMA_ADD_RESV);
++}
++
++/*
++ * This routine is called to restore a reservation on error paths.  In the
++ * specific error paths, a huge page was allocated (via alloc_huge_page)
++ * and is about to be freed.  If a reservation for the page existed,
++ * alloc_huge_page would have consumed the reservation and set PagePrivate
++ * in the newly allocated page.  When the page is freed via free_huge_page,
++ * the global reservation count will be incremented if PagePrivate is set.
++ * However, free_huge_page can not adjust the reserve map.  Adjust the
++ * reserve map here to be consistent with global reserve count adjustments
++ * to be made by free_huge_page.
++ */
++static void restore_reserve_on_error(struct hstate *h,
++			struct vm_area_struct *vma, unsigned long address,
++			struct page *page)
++{
++	if (unlikely(PagePrivate(page))) {
++		long rc = vma_needs_reservation(h, vma, address);
++
++		if (unlikely(rc < 0)) {
++			/*
++			 * Rare out of memory condition in reserve map
++			 * manipulation.  Clear PagePrivate so that
++			 * global reserve count will not be incremented
++			 * by free_huge_page.  This will make it appear
++			 * as though the reservation for this page was
++			 * consumed.  This may prevent the task from
++			 * faulting in the page at a later time.  This
++			 * is better than inconsistent global huge page
++			 * accounting of reserve counts.
++			 */
++			ClearPagePrivate(page);
++		} else if (rc) {
++			rc = vma_add_reservation(h, vma, address);
++			if (unlikely(rc < 0))
++				/*
++				 * See above comment about rare out of
++				 * memory condition.
++				 */
++				ClearPagePrivate(page);
++		} else
++			vma_end_reservation(h, vma, address);
++	}
++}
++
+ struct page *alloc_huge_page(struct vm_area_struct *vma,
+ 				    unsigned long addr, int avoid_reserve)
+ {
+@@ -3498,6 +3562,7 @@ retry_avoidcopy:
+ 	spin_unlock(ptl);
+ 	mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
+ out_release_all:
++	restore_reserve_on_error(h, vma, address, new_page);
+ 	put_page(new_page);
+ out_release_old:
+ 	put_page(old_page);
+@@ -3680,6 +3745,7 @@ backout:
+ 	spin_unlock(ptl);
+ backout_unlocked:
+ 	unlock_page(page);
++	restore_reserve_on_error(h, vma, address, page);
+ 	put_page(page);
+ 	goto out;
+ }
+diff --git a/mm/memory-failure.c b/mm/memory-failure.c
+index de88f33519c0..19e796d36a62 100644
+--- a/mm/memory-failure.c
++++ b/mm/memory-failure.c
+@@ -1112,10 +1112,10 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
+ 	}
+ 
+ 	if (!PageHuge(p) && PageTransHuge(hpage)) {
+-		lock_page(hpage);
+-		if (!PageAnon(hpage) || unlikely(split_huge_page(hpage))) {
+-			unlock_page(hpage);
+-			if (!PageAnon(hpage))
++		lock_page(p);
++		if (!PageAnon(p) || unlikely(split_huge_page(p))) {
++			unlock_page(p);
++			if (!PageAnon(p))
+ 				pr_err("Memory failure: %#lx: non anonymous thp\n",
+ 					pfn);
+ 			else
+@@ -1126,9 +1126,7 @@ int memory_failure(unsigned long pfn, int trapno, int flags)
+ 			put_hwpoison_page(p);
+ 			return -EBUSY;
+ 		}
+-		unlock_page(hpage);
+-		get_hwpoison_page(p);
+-		put_hwpoison_page(hpage);
++		unlock_page(p);
+ 		VM_BUG_ON_PAGE(!page_count(p), p);
+ 		hpage = compound_head(p);
+ 	}
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 971fc83e6402..38aa5e0a955f 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -1483,6 +1483,8 @@ static int shmem_replace_page(struct page **pagep, gfp_t gfp,
+ 	copy_highpage(newpage, oldpage);
+ 	flush_dcache_page(newpage);
+ 
++	__SetPageLocked(newpage);
++	__SetPageSwapBacked(newpage);
+ 	SetPageUptodate(newpage);
+ 	set_page_private(newpage, swap_index);
+ 	SetPageSwapCache(newpage);
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index 71f0b28a1bec..329b03843863 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -533,8 +533,8 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg,
+ 
+ 	s = create_cache(cache_name, root_cache->object_size,
+ 			 root_cache->size, root_cache->align,
+-			 root_cache->flags, root_cache->ctor,
+-			 memcg, root_cache);
++			 root_cache->flags & CACHE_CREATE_MASK,
++			 root_cache->ctor, memcg, root_cache);
+ 	/*
+ 	 * If we could not create a memcg cache, do not complain, because
+ 	 * that's not critical at all as we can always proceed with the root
+diff --git a/mm/swapfile.c b/mm/swapfile.c
+index 2657accc6e2b..bf262e494f68 100644
+--- a/mm/swapfile.c
++++ b/mm/swapfile.c
+@@ -2218,6 +2218,8 @@ static unsigned long read_swap_header(struct swap_info_struct *p,
+ 		swab32s(&swap_header->info.version);
+ 		swab32s(&swap_header->info.last_page);
+ 		swab32s(&swap_header->info.nr_badpages);
++		if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES)
++			return 0;
+ 		for (i = 0; i < swap_header->info.nr_badpages; i++)
+ 			swab32s(&swap_header->info.badpages[i]);
+ 	}
+diff --git a/net/batman-adv/originator.c b/net/batman-adv/originator.c
+index 3940b5d24421..3e9667e467c3 100644
+--- a/net/batman-adv/originator.c
++++ b/net/batman-adv/originator.c
+@@ -537,7 +537,7 @@ batadv_hardif_neigh_create(struct batadv_hard_iface *hard_iface,
+ 	if (bat_priv->algo_ops->neigh.hardif_init)
+ 		bat_priv->algo_ops->neigh.hardif_init(hardif_neigh);
+ 
+-	hlist_add_head(&hardif_neigh->list, &hard_iface->neigh_list);
++	hlist_add_head_rcu(&hardif_neigh->list, &hard_iface->neigh_list);
+ 
+ out:
+ 	spin_unlock_bh(&hard_iface->neigh_list_lock);
+diff --git a/net/ceph/ceph_fs.c b/net/ceph/ceph_fs.c
+index 7d54e944de5e..dcbe67ff3e2b 100644
+--- a/net/ceph/ceph_fs.c
++++ b/net/ceph/ceph_fs.c
+@@ -34,7 +34,8 @@ void ceph_file_layout_from_legacy(struct ceph_file_layout *fl,
+ 	fl->stripe_count = le32_to_cpu(legacy->fl_stripe_count);
+ 	fl->object_size = le32_to_cpu(legacy->fl_object_size);
+ 	fl->pool_id = le32_to_cpu(legacy->fl_pg_pool);
+-	if (fl->pool_id == 0)
++	if (fl->pool_id == 0 && fl->stripe_unit == 0 &&
++	    fl->stripe_count == 0 && fl->object_size == 0)
+ 		fl->pool_id = -1;
+ }
+ EXPORT_SYMBOL(ceph_file_layout_from_legacy);
+diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
+index aa5847a16713..1df2c8dac7c5 100644
+--- a/net/netfilter/nf_log.c
++++ b/net/netfilter/nf_log.c
+@@ -420,7 +420,7 @@ static int nf_log_proc_dostring(struct ctl_table *table, int write,
+ 	char buf[NFLOGGER_NAME_LEN];
+ 	int r = 0;
+ 	int tindex = (unsigned long)table->extra1;
+-	struct net *net = current->nsproxy->net_ns;
++	struct net *net = table->extra2;
+ 
+ 	if (write) {
+ 		struct ctl_table tmp = *table;
+@@ -474,7 +474,6 @@ static int netfilter_log_sysctl_init(struct net *net)
+ 				 3, "%d", i);
+ 			nf_log_sysctl_table[i].procname	=
+ 				nf_log_sysctl_fnames[i];
+-			nf_log_sysctl_table[i].data = NULL;
+ 			nf_log_sysctl_table[i].maxlen = NFLOGGER_NAME_LEN;
+ 			nf_log_sysctl_table[i].mode = 0644;
+ 			nf_log_sysctl_table[i].proc_handler =
+@@ -484,6 +483,9 @@ static int netfilter_log_sysctl_init(struct net *net)
+ 		}
+ 	}
+ 
++	for (i = NFPROTO_UNSPEC; i < NFPROTO_NUMPROTO; i++)
++		table[i].extra2 = net;
++
+ 	net->nf.nf_log_dir_header = register_net_sysctl(net,
+ 						"net/netfilter/nf_log",
+ 						table);
+diff --git a/net/sunrpc/xprtrdma/frwr_ops.c b/net/sunrpc/xprtrdma/frwr_ops.c
+index 892b5e1d9b09..2761377dcc17 100644
+--- a/net/sunrpc/xprtrdma/frwr_ops.c
++++ b/net/sunrpc/xprtrdma/frwr_ops.c
+@@ -44,18 +44,20 @@
+  * being done.
+  *
+  * When the underlying transport disconnects, MRs are left in one of
+- * three states:
++ * four states:
+  *
+  * INVALID:	The MR was not in use before the QP entered ERROR state.
+- *		(Or, the LOCAL_INV WR has not completed or flushed yet).
+- *
+- * STALE:	The MR was being registered or unregistered when the QP
+- *		entered ERROR state, and the pending WR was flushed.
+  *
+  * VALID:	The MR was registered before the QP entered ERROR state.
+  *
+- * When frwr_op_map encounters STALE and VALID MRs, they are recovered
+- * with ib_dereg_mr and then are re-initialized. Beause MR recovery
++ * FLUSHED_FR:	The MR was being registered when the QP entered ERROR
++ *		state, and the pending WR was flushed.
++ *
++ * FLUSHED_LI:	The MR was being invalidated when the QP entered ERROR
++ *		state, and the pending WR was flushed.
++ *
++ * When frwr_op_map encounters FLUSHED and VALID MRs, they are recovered
++ * with ib_dereg_mr and then are re-initialized. Because MR recovery
+  * allocates fresh resources, it is deferred to a workqueue, and the
+  * recovered MRs are placed back on the rb_mws list when recovery is
+  * complete. frwr_op_map allocates another MR for the current RPC while
+@@ -175,12 +177,15 @@ __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r)
+ static void
+ frwr_op_recover_mr(struct rpcrdma_mw *mw)
+ {
++	enum rpcrdma_frmr_state state = mw->frmr.fr_state;
+ 	struct rpcrdma_xprt *r_xprt = mw->mw_xprt;
+ 	struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+ 	int rc;
+ 
+ 	rc = __frwr_reset_mr(ia, mw);
+-	ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir);
++	if (state != FRMR_FLUSHED_LI)
++		ib_dma_unmap_sg(ia->ri_device,
++				mw->mw_sg, mw->mw_nents, mw->mw_dir);
+ 	if (rc)
+ 		goto out_release;
+ 
+@@ -261,10 +266,8 @@ frwr_op_maxpages(struct rpcrdma_xprt *r_xprt)
+ }
+ 
+ static void
+-__frwr_sendcompletion_flush(struct ib_wc *wc, struct rpcrdma_frmr *frmr,
+-			    const char *wr)
++__frwr_sendcompletion_flush(struct ib_wc *wc, const char *wr)
+ {
+-	frmr->fr_state = FRMR_IS_STALE;
+ 	if (wc->status != IB_WC_WR_FLUSH_ERR)
+ 		pr_err("rpcrdma: %s: %s (%u/0x%x)\n",
+ 		       wr, ib_wc_status_msg(wc->status),
+@@ -287,7 +290,8 @@ frwr_wc_fastreg(struct ib_cq *cq, struct ib_wc *wc)
+ 	if (wc->status != IB_WC_SUCCESS) {
+ 		cqe = wc->wr_cqe;
+ 		frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe);
+-		__frwr_sendcompletion_flush(wc, frmr, "fastreg");
++		frmr->fr_state = FRMR_FLUSHED_FR;
++		__frwr_sendcompletion_flush(wc, "fastreg");
+ 	}
+ }
+ 
+@@ -307,7 +311,8 @@ frwr_wc_localinv(struct ib_cq *cq, struct ib_wc *wc)
+ 	if (wc->status != IB_WC_SUCCESS) {
+ 		cqe = wc->wr_cqe;
+ 		frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe);
+-		__frwr_sendcompletion_flush(wc, frmr, "localinv");
++		frmr->fr_state = FRMR_FLUSHED_LI;
++		__frwr_sendcompletion_flush(wc, "localinv");
+ 	}
+ }
+ 
+@@ -327,9 +332,11 @@ frwr_wc_localinv_wake(struct ib_cq *cq, struct ib_wc *wc)
+ 	/* WARNING: Only wr_cqe and status are reliable at this point */
+ 	cqe = wc->wr_cqe;
+ 	frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe);
+-	if (wc->status != IB_WC_SUCCESS)
+-		__frwr_sendcompletion_flush(wc, frmr, "localinv");
+-	complete_all(&frmr->fr_linv_done);
++	if (wc->status != IB_WC_SUCCESS) {
++		frmr->fr_state = FRMR_FLUSHED_LI;
++		__frwr_sendcompletion_flush(wc, "localinv");
++	}
++	complete(&frmr->fr_linv_done);
+ }
+ 
+ /* Post a REG_MR Work Request to register a memory region
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+index a2a7519b0f23..cd0c5581498c 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_backchannel.c
+@@ -129,7 +129,7 @@ static int svc_rdma_bc_sendto(struct svcxprt_rdma *rdma,
+ 		ret = -EIO;
+ 		goto out_unmap;
+ 	}
+-	atomic_inc(&rdma->sc_dma_used);
++	svc_rdma_count_mappings(rdma, ctxt);
+ 
+ 	memset(&send_wr, 0, sizeof(send_wr));
+ 	ctxt->cqe.done = svc_rdma_wc_send;
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+index 2c25606f2561..ad1df979b3f0 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+@@ -159,7 +159,7 @@ int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt,
+ 					   ctxt->sge[pno].addr);
+ 		if (ret)
+ 			goto err;
+-		atomic_inc(&xprt->sc_dma_used);
++		svc_rdma_count_mappings(xprt, ctxt);
+ 
+ 		ctxt->sge[pno].lkey = xprt->sc_pd->local_dma_lkey;
+ 		ctxt->sge[pno].length = len;
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+index 54d533300620..3b95b19fcf72 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+@@ -280,7 +280,7 @@ static int send_write(struct svcxprt_rdma *xprt, struct svc_rqst *rqstp,
+ 		if (ib_dma_mapping_error(xprt->sc_cm_id->device,
+ 					 sge[sge_no].addr))
+ 			goto err;
+-		atomic_inc(&xprt->sc_dma_used);
++		svc_rdma_count_mappings(xprt, ctxt);
+ 		sge[sge_no].lkey = xprt->sc_pd->local_dma_lkey;
+ 		ctxt->count++;
+ 		sge_off = 0;
+@@ -489,7 +489,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
+ 			    ctxt->sge[0].length, DMA_TO_DEVICE);
+ 	if (ib_dma_mapping_error(rdma->sc_cm_id->device, ctxt->sge[0].addr))
+ 		goto err;
+-	atomic_inc(&rdma->sc_dma_used);
++	svc_rdma_count_mappings(rdma, ctxt);
+ 
+ 	ctxt->direction = DMA_TO_DEVICE;
+ 
+@@ -505,7 +505,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
+ 		if (ib_dma_mapping_error(rdma->sc_cm_id->device,
+ 					 ctxt->sge[sge_no].addr))
+ 			goto err;
+-		atomic_inc(&rdma->sc_dma_used);
++		svc_rdma_count_mappings(rdma, ctxt);
+ 		ctxt->sge[sge_no].lkey = rdma->sc_pd->local_dma_lkey;
+ 		ctxt->sge[sge_no].length = sge_bytes;
+ 	}
+@@ -523,23 +523,9 @@ static int send_reply(struct svcxprt_rdma *rdma,
+ 		ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
+ 		ctxt->count++;
+ 		rqstp->rq_respages[page_no] = NULL;
+-		/*
+-		 * If there are more pages than SGE, terminate SGE
+-		 * list so that svc_rdma_unmap_dma doesn't attempt to
+-		 * unmap garbage.
+-		 */
+-		if (page_no+1 >= sge_no)
+-			ctxt->sge[page_no+1].length = 0;
+ 	}
+ 	rqstp->rq_next_page = rqstp->rq_respages + 1;
+ 
+-	/* The loop above bumps sc_dma_used for each sge. The
+-	 * xdr_buf.tail gets a separate sge, but resides in the
+-	 * same page as xdr_buf.head. Don't count it twice.
+-	 */
+-	if (sge_no > ctxt->count)
+-		atomic_dec(&rdma->sc_dma_used);
+-
+ 	if (sge_no > rdma->sc_max_sge) {
+ 		pr_err("svcrdma: Too many sges (%d)\n", sge_no);
+ 		goto err;
+@@ -635,7 +621,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp)
+ 	ret = send_reply(rdma, rqstp, res_page, rdma_resp, vec,
+ 			 inline_bytes);
+ 	if (ret < 0)
+-		goto err1;
++		goto err0;
+ 
+ 	svc_rdma_put_req_map(rdma, vec);
+ 	dprintk("svcrdma: send_reply returns %d\n", ret);
+@@ -692,7 +678,7 @@ void svc_rdma_send_error(struct svcxprt_rdma *xprt, struct rpcrdma_msg *rmsgp,
+ 		svc_rdma_put_context(ctxt, 1);
+ 		return;
+ 	}
+-	atomic_inc(&xprt->sc_dma_used);
++	svc_rdma_count_mappings(xprt, ctxt);
+ 
+ 	/* Prepare SEND WR */
+ 	memset(&err_wr, 0, sizeof(err_wr));
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+index dd9440137834..924271c9ef3e 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -198,6 +198,7 @@ struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
+ 
+ out:
+ 	ctxt->count = 0;
++	ctxt->mapped_sges = 0;
+ 	ctxt->frmr = NULL;
+ 	return ctxt;
+ 
+@@ -221,22 +222,27 @@ out_empty:
+ void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt)
+ {
+ 	struct svcxprt_rdma *xprt = ctxt->xprt;
+-	int i;
+-	for (i = 0; i < ctxt->count && ctxt->sge[i].length; i++) {
++	struct ib_device *device = xprt->sc_cm_id->device;
++	u32 lkey = xprt->sc_pd->local_dma_lkey;
++	unsigned int i, count;
++
++	for (count = 0, i = 0; i < ctxt->mapped_sges; i++) {
+ 		/*
+ 		 * Unmap the DMA addr in the SGE if the lkey matches
+ 		 * the local_dma_lkey, otherwise, ignore it since it is
+ 		 * an FRMR lkey and will be unmapped later when the
+ 		 * last WR that uses it completes.
+ 		 */
+-		if (ctxt->sge[i].lkey == xprt->sc_pd->local_dma_lkey) {
+-			atomic_dec(&xprt->sc_dma_used);
+-			ib_dma_unmap_page(xprt->sc_cm_id->device,
++		if (ctxt->sge[i].lkey == lkey) {
++			count++;
++			ib_dma_unmap_page(device,
+ 					    ctxt->sge[i].addr,
+ 					    ctxt->sge[i].length,
+ 					    ctxt->direction);
+ 		}
+ 	}
++	ctxt->mapped_sges = 0;
++	atomic_sub(count, &xprt->sc_dma_used);
+ }
+ 
+ void svc_rdma_put_context(struct svc_rdma_op_ctxt *ctxt, int free_pages)
+@@ -600,7 +606,7 @@ int svc_rdma_post_recv(struct svcxprt_rdma *xprt, gfp_t flags)
+ 				     DMA_FROM_DEVICE);
+ 		if (ib_dma_mapping_error(xprt->sc_cm_id->device, pa))
+ 			goto err_put_ctxt;
+-		atomic_inc(&xprt->sc_dma_used);
++		svc_rdma_count_mappings(xprt, ctxt);
+ 		ctxt->sge[sge_no].addr = pa;
+ 		ctxt->sge[sge_no].length = PAGE_SIZE;
+ 		ctxt->sge[sge_no].lkey = xprt->sc_pd->local_dma_lkey;
+diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h
+index a71b0f5897d8..edc03445beed 100644
+--- a/net/sunrpc/xprtrdma/xprt_rdma.h
++++ b/net/sunrpc/xprtrdma/xprt_rdma.h
+@@ -207,7 +207,8 @@ struct rpcrdma_rep {
+ enum rpcrdma_frmr_state {
+ 	FRMR_IS_INVALID,	/* ready to be used */
+ 	FRMR_IS_VALID,		/* in use */
+-	FRMR_IS_STALE,		/* failed completion */
++	FRMR_FLUSHED_FR,	/* flushed FASTREG WR */
++	FRMR_FLUSHED_LI,	/* flushed LOCALINV WR */
+ };
+ 
+ struct rpcrdma_frmr {
+diff --git a/sound/core/info.c b/sound/core/info.c
+index 895362a696c9..8ab72e0f5932 100644
+--- a/sound/core/info.c
++++ b/sound/core/info.c
+@@ -325,10 +325,15 @@ static ssize_t snd_info_text_entry_write(struct file *file,
+ 	size_t next;
+ 	int err = 0;
+ 
++	if (!entry->c.text.write)
++		return -EIO;
+ 	pos = *offset;
+ 	if (!valid_pos(pos, count))
+ 		return -EIO;
+ 	next = pos + count;
++	/* don't handle too large text inputs */
++	if (next > 16 * 1024)
++		return -EIO;
+ 	mutex_lock(&entry->access);
+ 	buf = data->wbuffer;
+ 	if (!buf) {
+@@ -366,7 +371,9 @@ static int snd_info_seq_show(struct seq_file *seq, void *p)
+ 	struct snd_info_private_data *data = seq->private;
+ 	struct snd_info_entry *entry = data->entry;
+ 
+-	if (entry->c.text.read) {
++	if (!entry->c.text.read) {
++		return -EIO;
++	} else {
+ 		data->rbuffer->buffer = (char *)seq; /* XXX hack! */
+ 		entry->c.text.read(entry, data->rbuffer);
+ 	}
+diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c
+index e07807d96b68..3670086b9227 100644
+--- a/sound/soc/codecs/cs4270.c
++++ b/sound/soc/codecs/cs4270.c
+@@ -148,11 +148,11 @@ SND_SOC_DAPM_OUTPUT("AOUTR"),
+ };
+ 
+ static const struct snd_soc_dapm_route cs4270_dapm_routes[] = {
+-	{ "Capture", NULL, "AINA" },
+-	{ "Capture", NULL, "AINB" },
++	{ "Capture", NULL, "AINL" },
++	{ "Capture", NULL, "AINR" },
+ 
+-	{ "AOUTA", NULL, "Playback" },
+-	{ "AOUTB", NULL, "Playback" },
++	{ "AOUTL", NULL, "Playback" },
++	{ "AOUTR", NULL, "Playback" },
+ };
+ 
+ /**
+diff --git a/sound/soc/intel/skylake/skl.c b/sound/soc/intel/skylake/skl.c
+index e3e764167765..7b7a380b1245 100644
+--- a/sound/soc/intel/skylake/skl.c
++++ b/sound/soc/intel/skylake/skl.c
+@@ -785,8 +785,7 @@ static void skl_remove(struct pci_dev *pci)
+ 
+ 	release_firmware(skl->tplg);
+ 
+-	if (pci_dev_run_wake(pci))
+-		pm_runtime_get_noresume(&pci->dev);
++	pm_runtime_get_noresume(&pci->dev);
+ 
+ 	/* codec removal, invoke bus_device_remove */
+ 	snd_hdac_ext_bus_device_remove(ebus);
+diff --git a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
+index 44f170c73b06..03c18db96741 100644
+--- a/sound/soc/sunxi/sun4i-codec.c
++++ b/sound/soc/sunxi/sun4i-codec.c
+@@ -738,11 +738,11 @@ static struct snd_soc_card *sun4i_codec_create_card(struct device *dev)
+ 
+ 	card = devm_kzalloc(dev, sizeof(*card), GFP_KERNEL);
+ 	if (!card)
+-		return NULL;
++		return ERR_PTR(-ENOMEM);
+ 
+ 	card->dai_link = sun4i_codec_create_link(dev, &card->num_links);
+ 	if (!card->dai_link)
+-		return NULL;
++		return ERR_PTR(-ENOMEM);
+ 
+ 	card->dev		= dev;
+ 	card->name		= "sun4i-codec";
+@@ -842,7 +842,8 @@ static int sun4i_codec_probe(struct platform_device *pdev)
+ 	}
+ 
+ 	card = sun4i_codec_create_card(&pdev->dev);
+-	if (!card) {
++	if (IS_ERR(card)) {
++		ret = PTR_ERR(card);
+ 		dev_err(&pdev->dev, "Failed to create our card\n");
+ 		goto err_unregister_codec;
+ 	}
+diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
+index 7aee954b307f..4ad1eac23f66 100644
+--- a/tools/perf/ui/browsers/hists.c
++++ b/tools/perf/ui/browsers/hists.c
+@@ -595,7 +595,8 @@ int hist_browser__run(struct hist_browser *browser, const char *help)
+ 			u64 nr_entries;
+ 			hbt->timer(hbt->arg);
+ 
+-			if (hist_browser__has_filter(browser))
++			if (hist_browser__has_filter(browser) ||
++			    symbol_conf.report_hierarchy)
+ 				hist_browser__update_nr_entries(browser);
+ 
+ 			nr_entries = hist_browser__nr_entries(browser);
+diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c
+index b4bf76971dc9..1eef0aed6423 100644
+--- a/tools/power/cpupower/utils/cpufreq-set.c
++++ b/tools/power/cpupower/utils/cpufreq-set.c
+@@ -296,7 +296,7 @@ int cmd_freq_set(int argc, char **argv)
+ 			struct cpufreq_affected_cpus *cpus;
+ 
+ 			if (!bitmask_isbitset(cpus_chosen, cpu) ||
+-			    cpupower_is_cpu_online(cpu))
++			    cpupower_is_cpu_online(cpu) != 1)
+ 				continue;
+ 
+ 			cpus = cpufreq_get_related_cpus(cpu);
+@@ -316,10 +316,7 @@ int cmd_freq_set(int argc, char **argv)
+ 	     cpu <= bitmask_last(cpus_chosen); cpu++) {
+ 
+ 		if (!bitmask_isbitset(cpus_chosen, cpu) ||
+-		    cpupower_is_cpu_online(cpu))
+-			continue;
+-
+-		if (cpupower_is_cpu_online(cpu) != 1)
++		    cpupower_is_cpu_online(cpu) != 1)
+ 			continue;
+ 
+ 		printf(_("Setting cpu: %d\n"), cpu);
+diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
+index 3bad3c5ed431..d1b080ca8dc9 100644
+--- a/virt/kvm/arm/vgic/vgic-mmio.c
++++ b/virt/kvm/arm/vgic/vgic-mmio.c
+@@ -453,17 +453,33 @@ struct vgic_io_device *kvm_to_vgic_iodev(const struct kvm_io_device *dev)
+ 	return container_of(dev, struct vgic_io_device, dev);
+ }
+ 
+-static bool check_region(const struct vgic_register_region *region,
++static bool check_region(const struct kvm *kvm,
++			 const struct vgic_register_region *region,
+ 			 gpa_t addr, int len)
+ {
+-	if ((region->access_flags & VGIC_ACCESS_8bit) && len == 1)
+-		return true;
+-	if ((region->access_flags & VGIC_ACCESS_32bit) &&
+-	    len == sizeof(u32) && !(addr & 3))
+-		return true;
+-	if ((region->access_flags & VGIC_ACCESS_64bit) &&
+-	    len == sizeof(u64) && !(addr & 7))
+-		return true;
++	int flags, nr_irqs = kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS;
++
++	switch (len) {
++	case sizeof(u8):
++		flags = VGIC_ACCESS_8bit;
++		break;
++	case sizeof(u32):
++		flags = VGIC_ACCESS_32bit;
++		break;
++	case sizeof(u64):
++		flags = VGIC_ACCESS_64bit;
++		break;
++	default:
++		return false;
++	}
++
++	if ((region->access_flags & flags) && IS_ALIGNED(addr, len)) {
++		if (!region->bits_per_irq)
++			return true;
++
++		/* Do we access a non-allocated IRQ? */
++		return VGIC_ADDR_TO_INTID(addr, region->bits_per_irq) < nr_irqs;
++	}
+ 
+ 	return false;
+ }
+@@ -477,7 +493,7 @@ static int dispatch_mmio_read(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
+ 
+ 	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
+ 				       addr - iodev->base_addr);
+-	if (!region || !check_region(region, addr, len)) {
++	if (!region || !check_region(vcpu->kvm, region, addr, len)) {
+ 		memset(val, 0, len);
+ 		return 0;
+ 	}
+@@ -510,10 +526,7 @@ static int dispatch_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *dev,
+ 
+ 	region = vgic_find_mmio_region(iodev->regions, iodev->nr_regions,
+ 				       addr - iodev->base_addr);
+-	if (!region)
+-		return 0;
+-
+-	if (!check_region(region, addr, len))
++	if (!region || !check_region(vcpu->kvm, region, addr, len))
+ 		return 0;
+ 
+ 	switch (iodev->iodev_type) {
+diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
+index 0b3ecf9d100e..ba63d91d2619 100644
+--- a/virt/kvm/arm/vgic/vgic-mmio.h
++++ b/virt/kvm/arm/vgic/vgic-mmio.h
+@@ -50,15 +50,15 @@ extern struct kvm_io_device_ops kvm_io_gic_ops;
+ #define VGIC_ADDR_IRQ_MASK(bits) (((bits) * 1024 / 8) - 1)
+ 
+ /*
+- * (addr & mask) gives us the byte offset for the INT ID, so we want to
+- * divide this with 'bytes per irq' to get the INT ID, which is given
+- * by '(bits) / 8'.  But we do this with fixed-point-arithmetic and
+- * take advantage of the fact that division by a fraction equals
+- * multiplication with the inverted fraction, and scale up both the
+- * numerator and denominator with 8 to support at most 64 bits per IRQ:
++ * (addr & mask) gives us the _byte_ offset for the INT ID.
++ * We multiply this by 8 the get the _bit_ offset, then divide this by
++ * the number of bits to learn the actual INT ID.
++ * But instead of a division (which requires a "long long div" implementation),
++ * we shift by the binary logarithm of <bits>.
++ * This assumes that <bits> is a power of two.
+  */
+ #define VGIC_ADDR_TO_INTID(addr, bits)  (((addr) & VGIC_ADDR_IRQ_MASK(bits)) * \
+-					64 / (bits) / 8)
++					8 >> ilog2(bits))
+ 
+ /*
+  * Some VGIC registers store per-IRQ information, with a different number


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-21 14:50 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-11-21 14:50 UTC (permalink / raw
  To: gentoo-commits

commit:     c8c8fca074336deefaa5af1dbf8bf3b62839878e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Nov 21 14:50:13 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Nov 21 14:50:13 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c8c8fca0

Linux patch 4.8.10

 0000_README             |    4 +
 1009_linux-4.8.10.patch | 4759 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4763 insertions(+)

diff --git a/0000_README b/0000_README
index d5af994..13976e7 100644
--- a/0000_README
+++ b/0000_README
@@ -79,6 +79,10 @@ Patch:  1008_linux-4.8.9.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.9
 
+Patch:  1009_linux-4.8.10.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.10
+
 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/1009_linux-4.8.10.patch b/1009_linux-4.8.10.patch
new file mode 100644
index 0000000..7b1d9cf
--- /dev/null
+++ b/1009_linux-4.8.10.patch
@@ -0,0 +1,4759 @@
+diff --git a/Makefile b/Makefile
+index c1519ab85258..7cf2b4985703 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 9
++SUBLEVEL = 10
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/sparc/include/asm/uaccess_64.h b/arch/sparc/include/asm/uaccess_64.h
+index 37a315d0ddd4..a6847fc05a6d 100644
+--- a/arch/sparc/include/asm/uaccess_64.h
++++ b/arch/sparc/include/asm/uaccess_64.h
+@@ -98,7 +98,6 @@ struct exception_table_entry {
+         unsigned int insn, fixup;
+ };
+ 
+-void __ret_efault(void);
+ void __retl_efault(void);
+ 
+ /* Uh, these should become the main single-value transfer routines..
+@@ -205,55 +204,34 @@ int __get_user_bad(void);
+ unsigned long __must_check ___copy_from_user(void *to,
+ 					     const void __user *from,
+ 					     unsigned long size);
+-unsigned long copy_from_user_fixup(void *to, const void __user *from,
+-				   unsigned long size);
+ static inline unsigned long __must_check
+ copy_from_user(void *to, const void __user *from, unsigned long size)
+ {
+-	unsigned long ret;
+-
+ 	check_object_size(to, size, false);
+ 
+-	ret = ___copy_from_user(to, from, size);
+-	if (unlikely(ret))
+-		ret = copy_from_user_fixup(to, from, size);
+-
+-	return ret;
++	return ___copy_from_user(to, from, size);
+ }
+ #define __copy_from_user copy_from_user
+ 
+ unsigned long __must_check ___copy_to_user(void __user *to,
+ 					   const void *from,
+ 					   unsigned long size);
+-unsigned long copy_to_user_fixup(void __user *to, const void *from,
+-				 unsigned long size);
+ static inline unsigned long __must_check
+ copy_to_user(void __user *to, const void *from, unsigned long size)
+ {
+-	unsigned long ret;
+-
+ 	check_object_size(from, size, true);
+ 
+-	ret = ___copy_to_user(to, from, size);
+-	if (unlikely(ret))
+-		ret = copy_to_user_fixup(to, from, size);
+-	return ret;
++	return ___copy_to_user(to, from, size);
+ }
+ #define __copy_to_user copy_to_user
+ 
+ unsigned long __must_check ___copy_in_user(void __user *to,
+ 					   const void __user *from,
+ 					   unsigned long size);
+-unsigned long copy_in_user_fixup(void __user *to, void __user *from,
+-				 unsigned long size);
+ static inline unsigned long __must_check
+ copy_in_user(void __user *to, void __user *from, unsigned long size)
+ {
+-	unsigned long ret = ___copy_in_user(to, from, size);
+-
+-	if (unlikely(ret))
+-		ret = copy_in_user_fixup(to, from, size);
+-	return ret;
++	return ___copy_in_user(to, from, size);
+ }
+ #define __copy_in_user copy_in_user
+ 
+diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S
+index a076b4249e62..5f1f3ae21657 100644
+--- a/arch/sparc/kernel/head_64.S
++++ b/arch/sparc/kernel/head_64.S
+@@ -922,47 +922,11 @@ prom_tba:	.xword	0
+ tlb_type:	.word	0	/* Must NOT end up in BSS */
+ 	.section	".fixup",#alloc,#execinstr
+ 
+-	.globl	__ret_efault, __retl_efault, __ret_one, __retl_one
+-ENTRY(__ret_efault)
+-	ret
+-	 restore %g0, -EFAULT, %o0
+-ENDPROC(__ret_efault)
+-
+ ENTRY(__retl_efault)
+ 	retl
+ 	 mov	-EFAULT, %o0
+ ENDPROC(__retl_efault)
+ 
+-ENTRY(__retl_one)
+-	retl
+-	 mov	1, %o0
+-ENDPROC(__retl_one)
+-
+-ENTRY(__retl_one_fp)
+-	VISExitHalf
+-	retl
+-	 mov	1, %o0
+-ENDPROC(__retl_one_fp)
+-
+-ENTRY(__ret_one_asi)
+-	wr	%g0, ASI_AIUS, %asi
+-	ret
+-	 restore %g0, 1, %o0
+-ENDPROC(__ret_one_asi)
+-
+-ENTRY(__retl_one_asi)
+-	wr	%g0, ASI_AIUS, %asi
+-	retl
+-	 mov	1, %o0
+-ENDPROC(__retl_one_asi)
+-
+-ENTRY(__retl_one_asi_fp)
+-	wr	%g0, ASI_AIUS, %asi
+-	VISExitHalf
+-	retl
+-	 mov	1, %o0
+-ENDPROC(__retl_one_asi_fp)
+-
+ ENTRY(__retl_o1)
+ 	retl
+ 	 mov	%o1, %o0
+diff --git a/arch/sparc/kernel/jump_label.c b/arch/sparc/kernel/jump_label.c
+index 59bbeff55024..07933b9e9ce0 100644
+--- a/arch/sparc/kernel/jump_label.c
++++ b/arch/sparc/kernel/jump_label.c
+@@ -13,19 +13,30 @@
+ void arch_jump_label_transform(struct jump_entry *entry,
+ 			       enum jump_label_type type)
+ {
+-	u32 val;
+ 	u32 *insn = (u32 *) (unsigned long) entry->code;
++	u32 val;
+ 
+ 	if (type == JUMP_LABEL_JMP) {
+ 		s32 off = (s32)entry->target - (s32)entry->code;
++		bool use_v9_branch = false;
++
++		BUG_ON(off & 3);
+ 
+ #ifdef CONFIG_SPARC64
+-		/* ba,pt %xcc, . + (off << 2) */
+-		val = 0x10680000 | ((u32) off >> 2);
+-#else
+-		/* ba . + (off << 2) */
+-		val = 0x10800000 | ((u32) off >> 2);
++		if (off <= 0xfffff && off >= -0x100000)
++			use_v9_branch = true;
+ #endif
++		if (use_v9_branch) {
++			/* WDISP19 - target is . + immed << 2 */
++			/* ba,pt %xcc, . + off */
++			val = 0x10680000 | (((u32) off >> 2) & 0x7ffff);
++		} else {
++			/* WDISP22 - target is . + immed << 2 */
++			BUG_ON(off > 0x7fffff);
++			BUG_ON(off < -0x800000);
++			/* ba . + off */
++			val = 0x10800000 | (((u32) off >> 2) & 0x3fffff);
++		}
+ 	} else {
+ 		val = 0x01000000;
+ 	}
+diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c
+index 9e034f29dcc5..20ffb052fe38 100644
+--- a/arch/sparc/kernel/sparc_ksyms_64.c
++++ b/arch/sparc/kernel/sparc_ksyms_64.c
+@@ -27,7 +27,6 @@ EXPORT_SYMBOL(__flushw_user);
+ EXPORT_SYMBOL_GPL(real_hard_smp_processor_id);
+ 
+ /* from head_64.S */
+-EXPORT_SYMBOL(__ret_efault);
+ EXPORT_SYMBOL(tlb_type);
+ EXPORT_SYMBOL(sun4v_chip_type);
+ EXPORT_SYMBOL(prom_root_node);
+diff --git a/arch/sparc/lib/GENcopy_from_user.S b/arch/sparc/lib/GENcopy_from_user.S
+index b7d0bd6b1406..69a439fa2fc1 100644
+--- a/arch/sparc/lib/GENcopy_from_user.S
++++ b/arch/sparc/lib/GENcopy_from_user.S
+@@ -3,11 +3,11 @@
+  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/GENcopy_to_user.S b/arch/sparc/lib/GENcopy_to_user.S
+index 780550e1afc7..9947427ce354 100644
+--- a/arch/sparc/lib/GENcopy_to_user.S
++++ b/arch/sparc/lib/GENcopy_to_user.S
+@@ -3,11 +3,11 @@
+  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/GENmemcpy.S b/arch/sparc/lib/GENmemcpy.S
+index 89358ee94851..059ea24ad73d 100644
+--- a/arch/sparc/lib/GENmemcpy.S
++++ b/arch/sparc/lib/GENmemcpy.S
+@@ -4,21 +4,18 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #define GLOBAL_SPARE	%g7
+ #else
+ #define GLOBAL_SPARE	%g5
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
+-#endif
+-
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ 
+ #ifndef LOAD
+@@ -45,6 +42,29 @@
+ 	.register	%g3,#scratch
+ 
+ 	.text
++
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++ENTRY(GEN_retl_o4_1)
++	add	%o4, %o2, %o4
++	retl
++	 add	%o4, 1, %o0
++ENDPROC(GEN_retl_o4_1)
++ENTRY(GEN_retl_g1_8)
++	add	%g1, %o2, %g1
++	retl
++	 add	%g1, 8, %o0
++ENDPROC(GEN_retl_g1_8)
++ENTRY(GEN_retl_o2_4)
++	retl
++	 add	%o2, 4, %o0
++ENDPROC(GEN_retl_o2_4)
++ENTRY(GEN_retl_o2_1)
++	retl
++	 add	%o2, 1, %o0
++ENDPROC(GEN_retl_o2_1)
++#endif
++
+ 	.align		64
+ 
+ 	.globl	FUNC_NAME
+@@ -73,8 +93,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	sub		%g0, %o4, %o4
+ 	sub		%o2, %o4, %o2
+ 1:	subcc		%o4, 1, %o4
+-	EX_LD(LOAD(ldub, %o1, %g1))
+-	EX_ST(STORE(stb, %g1, %o0))
++	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o4_1)
++	EX_ST(STORE(stb, %g1, %o0),GEN_retl_o4_1)
+ 	add		%o1, 1, %o1
+ 	bne,pt		%XCC, 1b
+ 	add		%o0, 1, %o0
+@@ -82,8 +102,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	andn		%o2, 0x7, %g1
+ 	sub		%o2, %g1, %o2
+ 1:	subcc		%g1, 0x8, %g1
+-	EX_LD(LOAD(ldx, %o1, %g2))
+-	EX_ST(STORE(stx, %g2, %o0))
++	EX_LD(LOAD(ldx, %o1, %g2),GEN_retl_g1_8)
++	EX_ST(STORE(stx, %g2, %o0),GEN_retl_g1_8)
+ 	add		%o1, 0x8, %o1
+ 	bne,pt		%XCC, 1b
+ 	 add		%o0, 0x8, %o0
+@@ -100,8 +120,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 1:
+ 	subcc		%o2, 4, %o2
+-	EX_LD(LOAD(lduw, %o1, %g1))
+-	EX_ST(STORE(stw, %g1, %o1 + %o3))
++	EX_LD(LOAD(lduw, %o1, %g1),GEN_retl_o2_4)
++	EX_ST(STORE(stw, %g1, %o1 + %o3),GEN_retl_o2_4)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 4, %o1
+ 
+@@ -111,8 +131,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	.align		32
+ 90:
+ 	subcc		%o2, 1, %o2
+-	EX_LD(LOAD(ldub, %o1, %g1))
+-	EX_ST(STORE(stb, %g1, %o1 + %o3))
++	EX_LD(LOAD(ldub, %o1, %g1),GEN_retl_o2_1)
++	EX_ST(STORE(stb, %g1, %o1 + %o3),GEN_retl_o2_1)
+ 	bgu,pt		%XCC, 90b
+ 	 add		%o1, 1, %o1
+ 	retl
+diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
+index 3269b0234093..4f2384a4286a 100644
+--- a/arch/sparc/lib/Makefile
++++ b/arch/sparc/lib/Makefile
+@@ -38,7 +38,7 @@ lib-$(CONFIG_SPARC64) +=  NG4patch.o NG4copy_page.o NG4clear_page.o NG4memset.o
+ lib-$(CONFIG_SPARC64) += GENmemcpy.o GENcopy_from_user.o GENcopy_to_user.o
+ lib-$(CONFIG_SPARC64) += GENpatch.o GENpage.o GENbzero.o
+ 
+-lib-$(CONFIG_SPARC64) += copy_in_user.o user_fixup.o memmove.o
++lib-$(CONFIG_SPARC64) += copy_in_user.o memmove.o
+ lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o hweight.o ffs.o
+ 
+ obj-$(CONFIG_SPARC64) += iomap.o
+diff --git a/arch/sparc/lib/NG2copy_from_user.S b/arch/sparc/lib/NG2copy_from_user.S
+index d5242b8c4f94..b79a6998d87c 100644
+--- a/arch/sparc/lib/NG2copy_from_user.S
++++ b/arch/sparc/lib/NG2copy_from_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_LD_FP(x)		\
++#define EX_LD_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NG2copy_to_user.S b/arch/sparc/lib/NG2copy_to_user.S
+index 4e962d993b10..dcec55f254ab 100644
+--- a/arch/sparc/lib/NG2copy_to_user.S
++++ b/arch/sparc/lib/NG2copy_to_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_ST_FP(x)		\
++#define EX_ST_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NG2memcpy.S b/arch/sparc/lib/NG2memcpy.S
+index d5f585df2f3f..c629dbd121b6 100644
+--- a/arch/sparc/lib/NG2memcpy.S
++++ b/arch/sparc/lib/NG2memcpy.S
+@@ -4,6 +4,7 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #include <asm/visasm.h>
+ #include <asm/asi.h>
+ #define GLOBAL_SPARE	%g7
+@@ -32,21 +33,17 @@
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ #ifndef EX_LD_FP
+-#define EX_LD_FP(x)	x
++#define EX_LD_FP(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ #ifndef EX_ST_FP
+-#define EX_ST_FP(x)	x
+-#endif
+-
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
++#define EX_ST_FP(x,y)	x
+ #endif
+ 
+ #ifndef LOAD
+@@ -140,45 +137,110 @@
+ 	fsrc2		%x6, %f12; \
+ 	fsrc2		%x7, %f14;
+ #define FREG_LOAD_1(base, x0) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0))
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1)
+ #define FREG_LOAD_2(base, x0, x1) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1);
+ #define FREG_LOAD_3(base, x0, x1, x2) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x10, %x2));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1);
+ #define FREG_LOAD_4(base, x0, x1, x2, x3) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x18, %x3));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1);
+ #define FREG_LOAD_5(base, x0, x1, x2, x3, x4) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x20, %x4));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1);
+ #define FREG_LOAD_6(base, x0, x1, x2, x3, x4, x5) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x28, %x5));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x28, %x5), NG2_retl_o2_plus_g1);
+ #define FREG_LOAD_7(base, x0, x1, x2, x3, x4, x5, x6) \
+-	EX_LD_FP(LOAD(ldd, base + 0x00, %x0)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x08, %x1)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x10, %x2)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x18, %x3)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x20, %x4)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x28, %x5)); \
+-	EX_LD_FP(LOAD(ldd, base + 0x30, %x6));
++	EX_LD_FP(LOAD(ldd, base + 0x00, %x0), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x08, %x1), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x10, %x2), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x18, %x3), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x20, %x4), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x28, %x5), NG2_retl_o2_plus_g1); \
++	EX_LD_FP(LOAD(ldd, base + 0x30, %x6), NG2_retl_o2_plus_g1);
+ 
+ 	.register	%g2,#scratch
+ 	.register	%g3,#scratch
+ 
+ 	.text
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++__restore_fp:
++	VISExitHalf
++__restore_asi:
++	retl
++	 wr	%g0, ASI_AIUS, %asi
++ENTRY(NG2_retl_o2)
++	ba,pt	%xcc, __restore_asi
++	 mov	%o2, %o0
++ENDPROC(NG2_retl_o2)
++ENTRY(NG2_retl_o2_plus_1)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, 1, %o0
++ENDPROC(NG2_retl_o2_plus_1)
++ENTRY(NG2_retl_o2_plus_4)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, 4, %o0
++ENDPROC(NG2_retl_o2_plus_4)
++ENTRY(NG2_retl_o2_plus_8)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, 8, %o0
++ENDPROC(NG2_retl_o2_plus_8)
++ENTRY(NG2_retl_o2_plus_o4_plus_1)
++	add	%o4, 1, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG2_retl_o2_plus_o4_plus_1)
++ENTRY(NG2_retl_o2_plus_o4_plus_8)
++	add	%o4, 8, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG2_retl_o2_plus_o4_plus_8)
++ENTRY(NG2_retl_o2_plus_o4_plus_16)
++	add	%o4, 16, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG2_retl_o2_plus_o4_plus_16)
++ENTRY(NG2_retl_o2_plus_g1_fp)
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %g1, %o0
++ENDPROC(NG2_retl_o2_plus_g1_fp)
++ENTRY(NG2_retl_o2_plus_g1_plus_64_fp)
++	add	%g1, 64, %g1
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %g1, %o0
++ENDPROC(NG2_retl_o2_plus_g1_plus_64_fp)
++ENTRY(NG2_retl_o2_plus_g1_plus_1)
++	add	%g1, 1, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %g1, %o0
++ENDPROC(NG2_retl_o2_plus_g1_plus_1)
++ENTRY(NG2_retl_o2_and_7_plus_o4)
++	and	%o2, 7, %o2
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG2_retl_o2_and_7_plus_o4)
++ENTRY(NG2_retl_o2_and_7_plus_o4_plus_8)
++	and	%o2, 7, %o2
++	add	%o4, 8, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG2_retl_o2_and_7_plus_o4_plus_8)
++#endif
++
+ 	.align		64
+ 
+ 	.globl	FUNC_NAME
+@@ -230,8 +292,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	sub		%g0, %o4, %o4	! bytes to align dst
+ 	sub		%o2, %o4, %o2
+ 1:	subcc		%o4, 1, %o4
+-	EX_LD(LOAD(ldub, %o1, %g1))
+-	EX_ST(STORE(stb, %g1, %o0))
++	EX_LD(LOAD(ldub, %o1, %g1), NG2_retl_o2_plus_o4_plus_1)
++	EX_ST(STORE(stb, %g1, %o0), NG2_retl_o2_plus_o4_plus_1)
+ 	add		%o1, 1, %o1
+ 	bne,pt		%XCC, 1b
+ 	add		%o0, 1, %o0
+@@ -281,11 +343,11 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	 nop
+ 	/* fall through for 0 < low bits < 8 */
+ 110:	sub		%o4, 64, %g2
+-	EX_LD_FP(LOAD_BLK(%g2, %f0))
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++	EX_LD_FP(LOAD_BLK(%g2, %f0), NG2_retl_o2_plus_g1)
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f14, f16)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_8(f16, f18, f20, f22, f24, f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -296,10 +358,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 120:	sub		%o4, 56, %g2
+ 	FREG_LOAD_7(%g2, f0, f2, f4, f6, f8, f10, f12)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f6, f8, f10, f12, f16, f18)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_7(f18, f20, f22, f24, f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -310,10 +372,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 130:	sub		%o4, 48, %g2
+ 	FREG_LOAD_6(%g2, f0, f2, f4, f6, f8, f10)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f6, f8, f10, f16, f18, f20)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_6(f20, f22, f24, f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -324,10 +386,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 140:	sub		%o4, 40, %g2
+ 	FREG_LOAD_5(%g2, f0, f2, f4, f6, f8)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f6, f8, f16, f18, f20, f22)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_5(f22, f24, f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -338,10 +400,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 150:	sub		%o4, 32, %g2
+ 	FREG_LOAD_4(%g2, f0, f2, f4, f6)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f6, f16, f18, f20, f22, f24)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_4(f24, f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -352,10 +414,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 160:	sub		%o4, 24, %g2
+ 	FREG_LOAD_3(%g2, f0, f2, f4)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f4, f16, f18, f20, f22, f24, f26)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_3(f26, f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -366,10 +428,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 170:	sub		%o4, 16, %g2
+ 	FREG_LOAD_2(%g2, f0, f2)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f2, f16, f18, f20, f22, f24, f26, f28)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_2(f28, f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -380,10 +442,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 180:	sub		%o4, 8, %g2
+ 	FREG_LOAD_1(%g2, f0)
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
+-	EX_LD_FP(LOAD_BLK(%o4, %f16))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
++	EX_LD_FP(LOAD_BLK(%o4, %f16), NG2_retl_o2_plus_g1)
+ 	FREG_FROB(f0, f16, f18, f20, f22, f24, f26, f28, f30)
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	FREG_MOVE_1(f30)
+ 	subcc		%g1, 64, %g1
+ 	add		%o4, 64, %o4
+@@ -393,10 +455,10 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	 nop
+ 
+ 190:
+-1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3))
++1:	EX_ST_FP(STORE_INIT(%g0, %o4 + %g3), NG2_retl_o2_plus_g1)
+ 	subcc		%g1, 64, %g1
+-	EX_LD_FP(LOAD_BLK(%o4, %f0))
+-	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3))
++	EX_LD_FP(LOAD_BLK(%o4, %f0), NG2_retl_o2_plus_g1_plus_64)
++	EX_ST_FP(STORE_BLK(%f0, %o4 + %g3), NG2_retl_o2_plus_g1_plus_64)
+ 	add		%o4, 64, %o4
+ 	bne,pt		%xcc, 1b
+ 	 LOAD(prefetch, %o4 + 64, #one_read)
+@@ -423,28 +485,28 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	andn		%o2, 0xf, %o4
+ 	and		%o2, 0xf, %o2
+ 1:	subcc		%o4, 0x10, %o4
+-	EX_LD(LOAD(ldx, %o1, %o5))
++	EX_LD(LOAD(ldx, %o1, %o5), NG2_retl_o2_plus_o4_plus_16)
+ 	add		%o1, 0x08, %o1
+-	EX_LD(LOAD(ldx, %o1, %g1))
++	EX_LD(LOAD(ldx, %o1, %g1), NG2_retl_o2_plus_o4_plus_16)
+ 	sub		%o1, 0x08, %o1
+-	EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE))
++	EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_o4_plus_16)
+ 	add		%o1, 0x8, %o1
+-	EX_ST(STORE(stx, %g1, %o1 + GLOBAL_SPARE))
++	EX_ST(STORE(stx, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_o4_plus_8)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 0x8, %o1
+ 73:	andcc		%o2, 0x8, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%o2, 0x8, %o2
+-	EX_LD(LOAD(ldx, %o1, %o5))
+-	EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE))
++	EX_LD(LOAD(ldx, %o1, %o5), NG2_retl_o2_plus_8)
++	EX_ST(STORE(stx, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_8)
+ 	add		%o1, 0x8, %o1
+ 1:	andcc		%o2, 0x4, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%o2, 0x4, %o2
+-	EX_LD(LOAD(lduw, %o1, %o5))
+-	EX_ST(STORE(stw, %o5, %o1 + GLOBAL_SPARE))
++	EX_LD(LOAD(lduw, %o1, %o5), NG2_retl_o2_plus_4)
++	EX_ST(STORE(stw, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_4)
+ 	add		%o1, 0x4, %o1
+ 1:	cmp		%o2, 0
+ 	be,pt		%XCC, 85f
+@@ -460,8 +522,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	sub		%o2, %g1, %o2
+ 
+ 1:	subcc		%g1, 1, %g1
+-	EX_LD(LOAD(ldub, %o1, %o5))
+-	EX_ST(STORE(stb, %o5, %o1 + GLOBAL_SPARE))
++	EX_LD(LOAD(ldub, %o1, %o5), NG2_retl_o2_plus_g1_plus_1)
++	EX_ST(STORE(stb, %o5, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_g1_plus_1)
+ 	bgu,pt		%icc, 1b
+ 	 add		%o1, 1, %o1
+ 
+@@ -477,16 +539,16 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 8:	mov		64, GLOBAL_SPARE
+ 	andn		%o1, 0x7, %o1
+-	EX_LD(LOAD(ldx, %o1, %g2))
++	EX_LD(LOAD(ldx, %o1, %g2), NG2_retl_o2)
+ 	sub		GLOBAL_SPARE, %g1, GLOBAL_SPARE
+ 	andn		%o2, 0x7, %o4
+ 	sllx		%g2, %g1, %g2
+ 1:	add		%o1, 0x8, %o1
+-	EX_LD(LOAD(ldx, %o1, %g3))
++	EX_LD(LOAD(ldx, %o1, %g3), NG2_retl_o2_and_7_plus_o4)
+ 	subcc		%o4, 0x8, %o4
+ 	srlx		%g3, GLOBAL_SPARE, %o5
+ 	or		%o5, %g2, %o5
+-	EX_ST(STORE(stx, %o5, %o0))
++	EX_ST(STORE(stx, %o5, %o0), NG2_retl_o2_and_7_plus_o4_plus_8)
+ 	add		%o0, 0x8, %o0
+ 	bgu,pt		%icc, 1b
+ 	 sllx		%g3, %g1, %g2
+@@ -506,8 +568,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 1:
+ 	subcc		%o2, 4, %o2
+-	EX_LD(LOAD(lduw, %o1, %g1))
+-	EX_ST(STORE(stw, %g1, %o1 + GLOBAL_SPARE))
++	EX_LD(LOAD(lduw, %o1, %g1), NG2_retl_o2_plus_4)
++	EX_ST(STORE(stw, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_4)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 4, %o1
+ 
+@@ -517,8 +579,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	.align		32
+ 90:
+ 	subcc		%o2, 1, %o2
+-	EX_LD(LOAD(ldub, %o1, %g1))
+-	EX_ST(STORE(stb, %g1, %o1 + GLOBAL_SPARE))
++	EX_LD(LOAD(ldub, %o1, %g1), NG2_retl_o2_plus_1)
++	EX_ST(STORE(stb, %g1, %o1 + GLOBAL_SPARE), NG2_retl_o2_plus_1)
+ 	bgu,pt		%XCC, 90b
+ 	 add		%o1, 1, %o1
+ 	retl
+diff --git a/arch/sparc/lib/NG4copy_from_user.S b/arch/sparc/lib/NG4copy_from_user.S
+index 2e8ee7ad07a9..16a286c1a528 100644
+--- a/arch/sparc/lib/NG4copy_from_user.S
++++ b/arch/sparc/lib/NG4copy_from_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x, y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_LD_FP(x)		\
++#define EX_LD_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NG4copy_to_user.S b/arch/sparc/lib/NG4copy_to_user.S
+index be0bf4590df8..6b0276ffc858 100644
+--- a/arch/sparc/lib/NG4copy_to_user.S
++++ b/arch/sparc/lib/NG4copy_to_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 2012 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_ST_FP(x)		\
++#define EX_ST_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_asi_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NG4memcpy.S b/arch/sparc/lib/NG4memcpy.S
+index 8e13ee1f4454..75bb93b1437f 100644
+--- a/arch/sparc/lib/NG4memcpy.S
++++ b/arch/sparc/lib/NG4memcpy.S
+@@ -4,6 +4,7 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #include <asm/visasm.h>
+ #include <asm/asi.h>
+ #define GLOBAL_SPARE	%g7
+@@ -46,22 +47,19 @@
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ #ifndef EX_LD_FP
+-#define EX_LD_FP(x)	x
++#define EX_LD_FP(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ #ifndef EX_ST_FP
+-#define EX_ST_FP(x)	x
++#define EX_ST_FP(x,y)	x
+ #endif
+ 
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
+-#endif
+ 
+ #ifndef LOAD
+ #define LOAD(type,addr,dest)	type [addr], dest
+@@ -94,6 +92,158 @@
+ 	.register	%g3,#scratch
+ 
+ 	.text
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++__restore_asi_fp:
++	VISExitHalf
++__restore_asi:
++	retl
++	 wr	%g0, ASI_AIUS, %asi
++
++ENTRY(NG4_retl_o2)
++	ba,pt	%xcc, __restore_asi
++	 mov	%o2, %o0
++ENDPROC(NG4_retl_o2)
++ENTRY(NG4_retl_o2_plus_1)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, 1, %o0
++ENDPROC(NG4_retl_o2_plus_1)
++ENTRY(NG4_retl_o2_plus_4)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, 4, %o0
++ENDPROC(NG4_retl_o2_plus_4)
++ENTRY(NG4_retl_o2_plus_o5)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5)
++ENTRY(NG4_retl_o2_plus_o5_plus_4)
++	add	%o5, 4, %o5
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5_plus_4)
++ENTRY(NG4_retl_o2_plus_o5_plus_8)
++	add	%o5, 8, %o5
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5_plus_8)
++ENTRY(NG4_retl_o2_plus_o5_plus_16)
++	add	%o5, 16, %o5
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5_plus_16)
++ENTRY(NG4_retl_o2_plus_o5_plus_24)
++	add	%o5, 24, %o5
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5_plus_24)
++ENTRY(NG4_retl_o2_plus_o5_plus_32)
++	add	%o5, 32, %o5
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o5, %o0
++ENDPROC(NG4_retl_o2_plus_o5_plus_32)
++ENTRY(NG4_retl_o2_plus_g1)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %g1, %o0
++ENDPROC(NG4_retl_o2_plus_g1)
++ENTRY(NG4_retl_o2_plus_g1_plus_1)
++	add	%g1, 1, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %g1, %o0
++ENDPROC(NG4_retl_o2_plus_g1_plus_1)
++ENTRY(NG4_retl_o2_plus_g1_plus_8)
++	add	%g1, 8, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %g1, %o0
++ENDPROC(NG4_retl_o2_plus_g1_plus_8)
++ENTRY(NG4_retl_o2_plus_o4)
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4)
++ENTRY(NG4_retl_o2_plus_o4_plus_8)
++	add	%o4, 8, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_8)
++ENTRY(NG4_retl_o2_plus_o4_plus_16)
++	add	%o4, 16, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_16)
++ENTRY(NG4_retl_o2_plus_o4_plus_24)
++	add	%o4, 24, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_24)
++ENTRY(NG4_retl_o2_plus_o4_plus_32)
++	add	%o4, 32, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_32)
++ENTRY(NG4_retl_o2_plus_o4_plus_40)
++	add	%o4, 40, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_40)
++ENTRY(NG4_retl_o2_plus_o4_plus_48)
++	add	%o4, 48, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_48)
++ENTRY(NG4_retl_o2_plus_o4_plus_56)
++	add	%o4, 56, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_56)
++ENTRY(NG4_retl_o2_plus_o4_plus_64)
++	add	%o4, 64, %o4
++	ba,pt	%xcc, __restore_asi
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_64)
++ENTRY(NG4_retl_o2_plus_o4_fp)
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_8_fp)
++	add	%o4, 8, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_8_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_16_fp)
++	add	%o4, 16, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_16_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_24_fp)
++	add	%o4, 24, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_24_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_32_fp)
++	add	%o4, 32, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_32_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_40_fp)
++	add	%o4, 40, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_40_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_48_fp)
++	add	%o4, 48, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_48_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_56_fp)
++	add	%o4, 56, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_56_fp)
++ENTRY(NG4_retl_o2_plus_o4_plus_64_fp)
++	add	%o4, 64, %o4
++	ba,pt	%xcc, __restore_asi_fp
++	 add	%o2, %o4, %o0
++ENDPROC(NG4_retl_o2_plus_o4_plus_64_fp)
++#endif
+ 	.align		64
+ 
+ 	.globl	FUNC_NAME
+@@ -124,12 +274,13 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	brz,pt		%g1, 51f
+ 	 sub		%o2, %g1, %o2
+ 
+-1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2))
++
++1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
+ 	add		%o1, 1, %o1
+ 	subcc		%g1, 1, %g1
+ 	add		%o0, 1, %o0
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stb, %g2, %o0 - 0x01))
++	 EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
+ 
+ 51:	LOAD(prefetch, %o1 + 0x040, #n_reads_strong)
+ 	LOAD(prefetch, %o1 + 0x080, #n_reads_strong)
+@@ -154,43 +305,43 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	brz,pt		%g1, .Llarge_aligned
+ 	 sub		%o2, %g1, %o2
+ 
+-1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g2))
++1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
+ 	add		%o1, 8, %o1
+ 	subcc		%g1, 8, %g1
+ 	add		%o0, 8, %o0
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stx, %g2, %o0 - 0x08))
++	 EX_ST(STORE(stx, %g2, %o0 - 0x08), NG4_retl_o2_plus_g1_plus_8)
+ 
+ .Llarge_aligned:
+ 	/* len >= 0x80 && src 8-byte aligned && dest 8-byte aligned */
+ 	andn		%o2, 0x3f, %o4
+ 	sub		%o2, %o4, %o2
+ 
+-1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
++1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o4)
+ 	add		%o1, 0x40, %o1
+-	EX_LD(LOAD(ldx, %o1 - 0x38, %g2))
++	EX_LD(LOAD(ldx, %o1 - 0x38, %g2), NG4_retl_o2_plus_o4)
+ 	subcc		%o4, 0x40, %o4
+-	EX_LD(LOAD(ldx, %o1 - 0x30, %g3))
+-	EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE))
+-	EX_LD(LOAD(ldx, %o1 - 0x20, %o5))
+-	EX_ST(STORE_INIT(%g1, %o0))
++	EX_LD(LOAD(ldx, %o1 - 0x30, %g3), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD(LOAD(ldx, %o1 - 0x28, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD(LOAD(ldx, %o1 - 0x20, %o5), NG4_retl_o2_plus_o4_plus_64)
++	EX_ST(STORE_INIT(%g1, %o0), NG4_retl_o2_plus_o4_plus_64)
+ 	add		%o0, 0x08, %o0
+-	EX_ST(STORE_INIT(%g2, %o0))
++	EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_56)
+ 	add		%o0, 0x08, %o0
+-	EX_LD(LOAD(ldx, %o1 - 0x18, %g2))
+-	EX_ST(STORE_INIT(%g3, %o0))
++	EX_LD(LOAD(ldx, %o1 - 0x18, %g2), NG4_retl_o2_plus_o4_plus_48)
++	EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_48)
+ 	add		%o0, 0x08, %o0
+-	EX_LD(LOAD(ldx, %o1 - 0x10, %g3))
+-	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0))
++	EX_LD(LOAD(ldx, %o1 - 0x10, %g3), NG4_retl_o2_plus_o4_plus_40)
++	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_40)
+ 	add		%o0, 0x08, %o0
+-	EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE))
+-	EX_ST(STORE_INIT(%o5, %o0))
++	EX_LD(LOAD(ldx, %o1 - 0x08, GLOBAL_SPARE), NG4_retl_o2_plus_o4_plus_32)
++	EX_ST(STORE_INIT(%o5, %o0), NG4_retl_o2_plus_o4_plus_32)
+ 	add		%o0, 0x08, %o0
+-	EX_ST(STORE_INIT(%g2, %o0))
++	EX_ST(STORE_INIT(%g2, %o0), NG4_retl_o2_plus_o4_plus_24)
+ 	add		%o0, 0x08, %o0
+-	EX_ST(STORE_INIT(%g3, %o0))
++	EX_ST(STORE_INIT(%g3, %o0), NG4_retl_o2_plus_o4_plus_16)
+ 	add		%o0, 0x08, %o0
+-	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0))
++	EX_ST(STORE_INIT(GLOBAL_SPARE, %o0), NG4_retl_o2_plus_o4_plus_8)
+ 	add		%o0, 0x08, %o0
+ 	bne,pt		%icc, 1b
+ 	 LOAD(prefetch, %o1 + 0x200, #n_reads_strong)
+@@ -216,17 +367,17 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	sub		%o2, %o4, %o2
+ 	alignaddr	%o1, %g0, %g1
+ 	add		%o1, %o4, %o1
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0))
+-1:	EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2))
++	EX_LD_FP(LOAD(ldd, %g1 + 0x00, %f0), NG4_retl_o2_plus_o4)
++1:	EX_LD_FP(LOAD(ldd, %g1 + 0x08, %f2), NG4_retl_o2_plus_o4)
+ 	subcc		%o4, 0x40, %o4
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4))
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6))
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8))
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10))
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12))
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14))
++	EX_LD_FP(LOAD(ldd, %g1 + 0x10, %f4), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD_FP(LOAD(ldd, %g1 + 0x18, %f6), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD_FP(LOAD(ldd, %g1 + 0x20, %f8), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD_FP(LOAD(ldd, %g1 + 0x28, %f10), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD_FP(LOAD(ldd, %g1 + 0x30, %f12), NG4_retl_o2_plus_o4_plus_64)
++	EX_LD_FP(LOAD(ldd, %g1 + 0x38, %f14), NG4_retl_o2_plus_o4_plus_64)
+ 	faligndata	%f0, %f2, %f16
+-	EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0))
++	EX_LD_FP(LOAD(ldd, %g1 + 0x40, %f0), NG4_retl_o2_plus_o4_plus_64)
+ 	faligndata	%f2, %f4, %f18
+ 	add		%g1, 0x40, %g1
+ 	faligndata	%f4, %f6, %f20
+@@ -235,14 +386,14 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	faligndata	%f10, %f12, %f26
+ 	faligndata	%f12, %f14, %f28
+ 	faligndata	%f14, %f0, %f30
+-	EX_ST_FP(STORE(std, %f16, %o0 + 0x00))
+-	EX_ST_FP(STORE(std, %f18, %o0 + 0x08))
+-	EX_ST_FP(STORE(std, %f20, %o0 + 0x10))
+-	EX_ST_FP(STORE(std, %f22, %o0 + 0x18))
+-	EX_ST_FP(STORE(std, %f24, %o0 + 0x20))
+-	EX_ST_FP(STORE(std, %f26, %o0 + 0x28))
+-	EX_ST_FP(STORE(std, %f28, %o0 + 0x30))
+-	EX_ST_FP(STORE(std, %f30, %o0 + 0x38))
++	EX_ST_FP(STORE(std, %f16, %o0 + 0x00), NG4_retl_o2_plus_o4_plus_64)
++	EX_ST_FP(STORE(std, %f18, %o0 + 0x08), NG4_retl_o2_plus_o4_plus_56)
++	EX_ST_FP(STORE(std, %f20, %o0 + 0x10), NG4_retl_o2_plus_o4_plus_48)
++	EX_ST_FP(STORE(std, %f22, %o0 + 0x18), NG4_retl_o2_plus_o4_plus_40)
++	EX_ST_FP(STORE(std, %f24, %o0 + 0x20), NG4_retl_o2_plus_o4_plus_32)
++	EX_ST_FP(STORE(std, %f26, %o0 + 0x28), NG4_retl_o2_plus_o4_plus_24)
++	EX_ST_FP(STORE(std, %f28, %o0 + 0x30), NG4_retl_o2_plus_o4_plus_16)
++	EX_ST_FP(STORE(std, %f30, %o0 + 0x38), NG4_retl_o2_plus_o4_plus_8)
+ 	add		%o0, 0x40, %o0
+ 	bne,pt		%icc, 1b
+ 	 LOAD(prefetch, %g1 + 0x200, #n_reads_strong)
+@@ -270,37 +421,38 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	andncc		%o2, 0x20 - 1, %o5
+ 	be,pn		%icc, 2f
+ 	 sub		%o2, %o5, %o2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
+-	EX_LD(LOAD(ldx, %o1 + 0x08, %g2))
+-	EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE))
+-	EX_LD(LOAD(ldx, %o1 + 0x18, %o4))
++1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
++	EX_LD(LOAD(ldx, %o1 + 0x08, %g2), NG4_retl_o2_plus_o5)
++	EX_LD(LOAD(ldx, %o1 + 0x10, GLOBAL_SPARE), NG4_retl_o2_plus_o5)
++	EX_LD(LOAD(ldx, %o1 + 0x18, %o4), NG4_retl_o2_plus_o5)
+ 	add		%o1, 0x20, %o1
+ 	subcc		%o5, 0x20, %o5
+-	EX_ST(STORE(stx, %g1, %o0 + 0x00))
+-	EX_ST(STORE(stx, %g2, %o0 + 0x08))
+-	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10))
+-	EX_ST(STORE(stx, %o4, %o0 + 0x18))
++	EX_ST(STORE(stx, %g1, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_32)
++	EX_ST(STORE(stx, %g2, %o0 + 0x08), NG4_retl_o2_plus_o5_plus_24)
++	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x10), NG4_retl_o2_plus_o5_plus_24)
++	EX_ST(STORE(stx, %o4, %o0 + 0x18), NG4_retl_o2_plus_o5_plus_8)
+ 	bne,pt		%icc, 1b
+ 	 add		%o0, 0x20, %o0
+ 2:	andcc		%o2, 0x18, %o5
+ 	be,pt		%icc, 3f
+ 	 sub		%o2, %o5, %o2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1))
++
++1:	EX_LD(LOAD(ldx, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
+ 	add		%o1, 0x08, %o1
+ 	add		%o0, 0x08, %o0
+ 	subcc		%o5, 0x08, %o5
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stx, %g1, %o0 - 0x08))
++	 EX_ST(STORE(stx, %g1, %o0 - 0x08), NG4_retl_o2_plus_o5_plus_8)
+ 3:	brz,pt		%o2, .Lexit
+ 	 cmp		%o2, 0x04
+ 	bl,pn		%icc, .Ltiny
+ 	 nop
+-	EX_LD(LOAD(lduw, %o1 + 0x00, %g1))
++	EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2)
+ 	add		%o1, 0x04, %o1
+ 	add		%o0, 0x04, %o0
+ 	subcc		%o2, 0x04, %o2
+ 	bne,pn		%icc, .Ltiny
+-	 EX_ST(STORE(stw, %g1, %o0 - 0x04))
++	 EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_4)
+ 	ba,a,pt		%icc, .Lexit
+ .Lmedium_unaligned:
+ 	/* First get dest 8 byte aligned.  */
+@@ -309,12 +461,12 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	brz,pt		%g1, 2f
+ 	 sub		%o2, %g1, %o2
+ 
+-1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2))
++1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g2), NG4_retl_o2_plus_g1)
+ 	add		%o1, 1, %o1
+ 	subcc		%g1, 1, %g1
+ 	add		%o0, 1, %o0
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stb, %g2, %o0 - 0x01))
++	 EX_ST(STORE(stb, %g2, %o0 - 0x01), NG4_retl_o2_plus_g1_plus_1)
+ 2:
+ 	and		%o1, 0x7, %g1
+ 	brz,pn		%g1, .Lmedium_noprefetch
+@@ -322,16 +474,16 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	mov		64, %g2
+ 	sub		%g2, %g1, %g2
+ 	andn		%o1, 0x7, %o1
+-	EX_LD(LOAD(ldx, %o1 + 0x00, %o4))
++	EX_LD(LOAD(ldx, %o1 + 0x00, %o4), NG4_retl_o2)
+ 	sllx		%o4, %g1, %o4
+ 	andn		%o2, 0x08 - 1, %o5
+ 	sub		%o2, %o5, %o2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x08, %g3))
++1:	EX_LD(LOAD(ldx, %o1 + 0x08, %g3), NG4_retl_o2_plus_o5)
+ 	add		%o1, 0x08, %o1
+ 	subcc		%o5, 0x08, %o5
+ 	srlx		%g3, %g2, GLOBAL_SPARE
+ 	or		GLOBAL_SPARE, %o4, GLOBAL_SPARE
+-	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00))
++	EX_ST(STORE(stx, GLOBAL_SPARE, %o0 + 0x00), NG4_retl_o2_plus_o5_plus_8)
+ 	add		%o0, 0x08, %o0
+ 	bne,pt		%icc, 1b
+ 	 sllx		%g3, %g1, %o4
+@@ -342,17 +494,17 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	ba,pt		%icc, .Lsmall_unaligned
+ 
+ .Ltiny:
+-	EX_LD(LOAD(ldub, %o1 + 0x00, %g1))
++	EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
+ 	subcc		%o2, 1, %o2
+ 	be,pn		%icc, .Lexit
+-	 EX_ST(STORE(stb, %g1, %o0 + 0x00))
+-	EX_LD(LOAD(ldub, %o1 + 0x01, %g1))
++	 EX_ST(STORE(stb, %g1, %o0 + 0x00), NG4_retl_o2_plus_1)
++	EX_LD(LOAD(ldub, %o1 + 0x01, %g1), NG4_retl_o2)
+ 	subcc		%o2, 1, %o2
+ 	be,pn		%icc, .Lexit
+-	 EX_ST(STORE(stb, %g1, %o0 + 0x01))
+-	EX_LD(LOAD(ldub, %o1 + 0x02, %g1))
++	 EX_ST(STORE(stb, %g1, %o0 + 0x01), NG4_retl_o2_plus_1)
++	EX_LD(LOAD(ldub, %o1 + 0x02, %g1), NG4_retl_o2)
+ 	ba,pt		%icc, .Lexit
+-	 EX_ST(STORE(stb, %g1, %o0 + 0x02))
++	 EX_ST(STORE(stb, %g1, %o0 + 0x02), NG4_retl_o2)
+ 
+ .Lsmall:
+ 	andcc		%g2, 0x3, %g0
+@@ -360,22 +512,22 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	 andn		%o2, 0x4 - 1, %o5
+ 	sub		%o2, %o5, %o2
+ 1:
+-	EX_LD(LOAD(lduw, %o1 + 0x00, %g1))
++	EX_LD(LOAD(lduw, %o1 + 0x00, %g1), NG4_retl_o2_plus_o5)
+ 	add		%o1, 0x04, %o1
+ 	subcc		%o5, 0x04, %o5
+ 	add		%o0, 0x04, %o0
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stw, %g1, %o0 - 0x04))
++	 EX_ST(STORE(stw, %g1, %o0 - 0x04), NG4_retl_o2_plus_o5_plus_4)
+ 	brz,pt		%o2, .Lexit
+ 	 nop
+ 	ba,a,pt		%icc, .Ltiny
+ 
+ .Lsmall_unaligned:
+-1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g1))
++1:	EX_LD(LOAD(ldub, %o1 + 0x00, %g1), NG4_retl_o2)
+ 	add		%o1, 1, %o1
+ 	add		%o0, 1, %o0
+ 	subcc		%o2, 1, %o2
+ 	bne,pt		%icc, 1b
+-	 EX_ST(STORE(stb, %g1, %o0 - 0x01))
++	 EX_ST(STORE(stb, %g1, %o0 - 0x01), NG4_retl_o2_plus_1)
+ 	ba,a,pt		%icc, .Lexit
+ 	.size		FUNC_NAME, .-FUNC_NAME
+diff --git a/arch/sparc/lib/NGcopy_from_user.S b/arch/sparc/lib/NGcopy_from_user.S
+index 5d1e4d1ac21e..9cd42fcbc781 100644
+--- a/arch/sparc/lib/NGcopy_from_user.S
++++ b/arch/sparc/lib/NGcopy_from_user.S
+@@ -3,11 +3,11 @@
+  * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __ret_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NGcopy_to_user.S b/arch/sparc/lib/NGcopy_to_user.S
+index ff630dcb273c..5c358afd464e 100644
+--- a/arch/sparc/lib/NGcopy_to_user.S
++++ b/arch/sparc/lib/NGcopy_to_user.S
+@@ -3,11 +3,11 @@
+  * Copyright (C) 2006, 2007 David S. Miller (davem@davemloft.net)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __ret_one_asi;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/NGmemcpy.S b/arch/sparc/lib/NGmemcpy.S
+index 96a14caf6966..d88c4ed50a00 100644
+--- a/arch/sparc/lib/NGmemcpy.S
++++ b/arch/sparc/lib/NGmemcpy.S
+@@ -4,6 +4,7 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #include <asm/asi.h>
+ #include <asm/thread_info.h>
+ #define GLOBAL_SPARE	%g7
+@@ -27,15 +28,11 @@
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
+-#endif
+-
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ 
+ #ifndef LOAD
+@@ -79,6 +76,92 @@
+ 	.register	%g3,#scratch
+ 
+ 	.text
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++__restore_asi:
++	ret
++	wr	%g0, ASI_AIUS, %asi
++	 restore
++ENTRY(NG_ret_i2_plus_i4_plus_1)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %i5, %i0
++ENDPROC(NG_ret_i2_plus_i4_plus_1)
++ENTRY(NG_ret_i2_plus_g1)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1)
++ENTRY(NG_ret_i2_plus_g1_minus_8)
++	sub	%g1, 8, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_8)
++ENTRY(NG_ret_i2_plus_g1_minus_16)
++	sub	%g1, 16, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_16)
++ENTRY(NG_ret_i2_plus_g1_minus_24)
++	sub	%g1, 24, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_24)
++ENTRY(NG_ret_i2_plus_g1_minus_32)
++	sub	%g1, 32, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_32)
++ENTRY(NG_ret_i2_plus_g1_minus_40)
++	sub	%g1, 40, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_40)
++ENTRY(NG_ret_i2_plus_g1_minus_48)
++	sub	%g1, 48, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_48)
++ENTRY(NG_ret_i2_plus_g1_minus_56)
++	sub	%g1, 56, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_minus_56)
++ENTRY(NG_ret_i2_plus_i4)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %i4, %i0
++ENDPROC(NG_ret_i2_plus_i4)
++ENTRY(NG_ret_i2_plus_i4_minus_8)
++	sub	%i4, 8, %i4
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %i4, %i0
++ENDPROC(NG_ret_i2_plus_i4_minus_8)
++ENTRY(NG_ret_i2_plus_8)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, 8, %i0
++ENDPROC(NG_ret_i2_plus_8)
++ENTRY(NG_ret_i2_plus_4)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, 4, %i0
++ENDPROC(NG_ret_i2_plus_4)
++ENTRY(NG_ret_i2_plus_1)
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, 1, %i0
++ENDPROC(NG_ret_i2_plus_1)
++ENTRY(NG_ret_i2_plus_g1_plus_1)
++	add	%g1, 1, %g1
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %g1, %i0
++ENDPROC(NG_ret_i2_plus_g1_plus_1)
++ENTRY(NG_ret_i2)
++	ba,pt	%xcc, __restore_asi
++	 mov	%i2, %i0
++ENDPROC(NG_ret_i2)
++ENTRY(NG_ret_i2_and_7_plus_i4)
++	and	%i2, 7, %i2
++	ba,pt	%xcc, __restore_asi
++	 add	%i2, %i4, %i0
++ENDPROC(NG_ret_i2_and_7_plus_i4)
++#endif
++
+ 	.align		64
+ 
+ 	.globl	FUNC_NAME
+@@ -126,8 +209,8 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	sub		%g0, %i4, %i4	! bytes to align dst
+ 	sub		%i2, %i4, %i2
+ 1:	subcc		%i4, 1, %i4
+-	EX_LD(LOAD(ldub, %i1, %g1))
+-	EX_ST(STORE(stb, %g1, %o0))
++	EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_i4_plus_1)
++	EX_ST(STORE(stb, %g1, %o0), NG_ret_i2_plus_i4_plus_1)
+ 	add		%i1, 1, %i1
+ 	bne,pt		%XCC, 1b
+ 	add		%o0, 1, %o0
+@@ -160,7 +243,7 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	and		%i4, 0x7, GLOBAL_SPARE
+ 	sll		GLOBAL_SPARE, 3, GLOBAL_SPARE
+ 	mov		64, %i5
+-	EX_LD(LOAD_TWIN(%i1, %g2, %g3))
++	EX_LD(LOAD_TWIN(%i1, %g2, %g3), NG_ret_i2_plus_g1)
+ 	sub		%i5, GLOBAL_SPARE, %i5
+ 	mov		16, %o4
+ 	mov		32, %o5
+@@ -178,31 +261,31 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	srlx		WORD3, PRE_SHIFT, TMP; \
+ 	or		WORD2, TMP, WORD2;
+ 
+-8:	EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3))
++8:	EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1)
+ 	MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
+ 	LOAD(prefetch, %i1 + %i3, #one_read)
+ 
+-	EX_ST(STORE_INIT(%g2, %o0 + 0x00))
+-	EX_ST(STORE_INIT(%g3, %o0 + 0x08))
++	EX_ST(STORE_INIT(%g2, %o0 + 0x00), NG_ret_i2_plus_g1)
++	EX_ST(STORE_INIT(%g3, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3))
++	EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16)
+ 	MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x10))
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x18))
++	EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
++	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
+ 	MIX_THREE_WORDS(%g2, %g3, %o2, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%g2, %o0 + 0x20))
+-	EX_ST(STORE_INIT(%g3, %o0 + 0x28))
++	EX_ST(STORE_INIT(%g2, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
++	EX_ST(STORE_INIT(%g3, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3))
++	EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48)
+ 	add		%i1, 64, %i1
+ 	MIX_THREE_WORDS(%o2, %o3, %g2, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x30))
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x38))
++	EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
++	EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
+ 
+ 	subcc		%g1, 64, %g1
+ 	bne,pt		%XCC, 8b
+@@ -211,31 +294,31 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	ba,pt		%XCC, 60f
+ 	 add		%i1, %i4, %i1
+ 
+-9:	EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3))
++9:	EX_LD(LOAD_TWIN(%i1 + %o4, %o2, %o3), NG_ret_i2_plus_g1)
+ 	MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
+ 	LOAD(prefetch, %i1 + %i3, #one_read)
+ 
+-	EX_ST(STORE_INIT(%g3, %o0 + 0x00))
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x08))
++	EX_ST(STORE_INIT(%g3, %o0 + 0x00), NG_ret_i2_plus_g1)
++	EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3))
++	EX_LD(LOAD_TWIN(%i1 + %o5, %g2, %g3), NG_ret_i2_plus_g1_minus_16)
+ 	MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x10))
+-	EX_ST(STORE_INIT(%g2, %o0 + 0x18))
++	EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%g2, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
++	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
+ 	MIX_THREE_WORDS(%g3, %o2, %o3, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%g3, %o0 + 0x20))
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x28))
++	EX_ST(STORE_INIT(%g3, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
++	EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
+ 
+-	EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3))
++	EX_LD(LOAD_TWIN(%i1 + %i3, %g2, %g3), NG_ret_i2_plus_g1_minus_48)
+ 	add		%i1, 64, %i1
+ 	MIX_THREE_WORDS(%o3, %g2, %g3, %i5, GLOBAL_SPARE, %o1)
+ 
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x30))
+-	EX_ST(STORE_INIT(%g2, %o0 + 0x38))
++	EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
++	EX_ST(STORE_INIT(%g2, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
+ 
+ 	subcc		%g1, 64, %g1
+ 	bne,pt		%XCC, 9b
+@@ -249,25 +332,25 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	 * one twin load ahead, then add 8 back into source when
+ 	 * we finish the loop.
+ 	 */
+-	EX_LD(LOAD_TWIN(%i1, %o4, %o5))
++	EX_LD(LOAD_TWIN(%i1, %o4, %o5), NG_ret_i2_plus_g1)
+ 	mov	16, %o7
+ 	mov	32, %g2
+ 	mov	48, %g3
+ 	mov	64, %o1
+-1:	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
++1:	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1)
+ 	LOAD(prefetch, %i1 + %o1, #one_read)
+-	EX_ST(STORE_INIT(%o5, %o0 + 0x00))	! initializes cache line
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x08))
+-	EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5))
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x10))
+-	EX_ST(STORE_INIT(%o4, %o0 + 0x18))
+-	EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3))
+-	EX_ST(STORE_INIT(%o5, %o0 + 0x20))
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x28))
+-	EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5))
++	EX_ST(STORE_INIT(%o5, %o0 + 0x00), NG_ret_i2_plus_g1)	! initializes cache line
++	EX_ST(STORE_INIT(%o2, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
++	EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%o3, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%o4, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
++	EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
++	EX_ST(STORE_INIT(%o5, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
++	EX_ST(STORE_INIT(%o2, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
++	EX_LD(LOAD_TWIN(%i1 + %o1, %o4, %o5), NG_ret_i2_plus_g1_minus_48)
+ 	add		%i1, 64, %i1
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x30))
+-	EX_ST(STORE_INIT(%o4, %o0 + 0x38))
++	EX_ST(STORE_INIT(%o3, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
++	EX_ST(STORE_INIT(%o4, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
+ 	subcc		%g1, 64, %g1
+ 	bne,pt		%XCC, 1b
+ 	 add		%o0, 64, %o0
+@@ -282,20 +365,20 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	mov	32, %g2
+ 	mov	48, %g3
+ 	mov	64, %o1
+-1:	EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5))
+-	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3))
++1:	EX_LD(LOAD_TWIN(%i1 + %g0, %o4, %o5), NG_ret_i2_plus_g1)
++	EX_LD(LOAD_TWIN(%i1 + %o7, %o2, %o3), NG_ret_i2_plus_g1)
+ 	LOAD(prefetch, %i1 + %o1, #one_read)
+-	EX_ST(STORE_INIT(%o4, %o0 + 0x00))	! initializes cache line
+-	EX_ST(STORE_INIT(%o5, %o0 + 0x08))
+-	EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5))
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x10))
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x18))
+-	EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3))
++	EX_ST(STORE_INIT(%o4, %o0 + 0x00), NG_ret_i2_plus_g1)	! initializes cache line
++	EX_ST(STORE_INIT(%o5, %o0 + 0x08), NG_ret_i2_plus_g1_minus_8)
++	EX_LD(LOAD_TWIN(%i1 + %g2, %o4, %o5), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%o2, %o0 + 0x10), NG_ret_i2_plus_g1_minus_16)
++	EX_ST(STORE_INIT(%o3, %o0 + 0x18), NG_ret_i2_plus_g1_minus_24)
++	EX_LD(LOAD_TWIN(%i1 + %g3, %o2, %o3), NG_ret_i2_plus_g1_minus_32)
+ 	add	%i1, 64, %i1
+-	EX_ST(STORE_INIT(%o4, %o0 + 0x20))
+-	EX_ST(STORE_INIT(%o5, %o0 + 0x28))
+-	EX_ST(STORE_INIT(%o2, %o0 + 0x30))
+-	EX_ST(STORE_INIT(%o3, %o0 + 0x38))
++	EX_ST(STORE_INIT(%o4, %o0 + 0x20), NG_ret_i2_plus_g1_minus_32)
++	EX_ST(STORE_INIT(%o5, %o0 + 0x28), NG_ret_i2_plus_g1_minus_40)
++	EX_ST(STORE_INIT(%o2, %o0 + 0x30), NG_ret_i2_plus_g1_minus_48)
++	EX_ST(STORE_INIT(%o3, %o0 + 0x38), NG_ret_i2_plus_g1_minus_56)
+ 	subcc	%g1, 64, %g1
+ 	bne,pt	%XCC, 1b
+ 	 add	%o0, 64, %o0
+@@ -321,28 +404,28 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	andn		%i2, 0xf, %i4
+ 	and		%i2, 0xf, %i2
+ 1:	subcc		%i4, 0x10, %i4
+-	EX_LD(LOAD(ldx, %i1, %o4))
++	EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_i4)
+ 	add		%i1, 0x08, %i1
+-	EX_LD(LOAD(ldx, %i1, %g1))
++	EX_LD(LOAD(ldx, %i1, %g1), NG_ret_i2_plus_i4)
+ 	sub		%i1, 0x08, %i1
+-	EX_ST(STORE(stx, %o4, %i1 + %i3))
++	EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_i4)
+ 	add		%i1, 0x8, %i1
+-	EX_ST(STORE(stx, %g1, %i1 + %i3))
++	EX_ST(STORE(stx, %g1, %i1 + %i3), NG_ret_i2_plus_i4_minus_8)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%i1, 0x8, %i1
+ 73:	andcc		%i2, 0x8, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%i2, 0x8, %i2
+-	EX_LD(LOAD(ldx, %i1, %o4))
+-	EX_ST(STORE(stx, %o4, %i1 + %i3))
++	EX_LD(LOAD(ldx, %i1, %o4), NG_ret_i2_plus_8)
++	EX_ST(STORE(stx, %o4, %i1 + %i3), NG_ret_i2_plus_8)
+ 	add		%i1, 0x8, %i1
+ 1:	andcc		%i2, 0x4, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%i2, 0x4, %i2
+-	EX_LD(LOAD(lduw, %i1, %i5))
+-	EX_ST(STORE(stw, %i5, %i1 + %i3))
++	EX_LD(LOAD(lduw, %i1, %i5), NG_ret_i2_plus_4)
++	EX_ST(STORE(stw, %i5, %i1 + %i3), NG_ret_i2_plus_4)
+ 	add		%i1, 0x4, %i1
+ 1:	cmp		%i2, 0
+ 	be,pt		%XCC, 85f
+@@ -358,8 +441,8 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	sub		%i2, %g1, %i2
+ 
+ 1:	subcc		%g1, 1, %g1
+-	EX_LD(LOAD(ldub, %i1, %i5))
+-	EX_ST(STORE(stb, %i5, %i1 + %i3))
++	EX_LD(LOAD(ldub, %i1, %i5), NG_ret_i2_plus_g1_plus_1)
++	EX_ST(STORE(stb, %i5, %i1 + %i3), NG_ret_i2_plus_g1_plus_1)
+ 	bgu,pt		%icc, 1b
+ 	 add		%i1, 1, %i1
+ 
+@@ -375,16 +458,16 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 
+ 8:	mov		64, %i3
+ 	andn		%i1, 0x7, %i1
+-	EX_LD(LOAD(ldx, %i1, %g2))
++	EX_LD(LOAD(ldx, %i1, %g2), NG_ret_i2)
+ 	sub		%i3, %g1, %i3
+ 	andn		%i2, 0x7, %i4
+ 	sllx		%g2, %g1, %g2
+ 1:	add		%i1, 0x8, %i1
+-	EX_LD(LOAD(ldx, %i1, %g3))
++	EX_LD(LOAD(ldx, %i1, %g3), NG_ret_i2_and_7_plus_i4)
+ 	subcc		%i4, 0x8, %i4
+ 	srlx		%g3, %i3, %i5
+ 	or		%i5, %g2, %i5
+-	EX_ST(STORE(stx, %i5, %o0))
++	EX_ST(STORE(stx, %i5, %o0), NG_ret_i2_and_7_plus_i4)
+ 	add		%o0, 0x8, %o0
+ 	bgu,pt		%icc, 1b
+ 	 sllx		%g3, %g1, %g2
+@@ -404,8 +487,8 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 
+ 1:
+ 	subcc		%i2, 4, %i2
+-	EX_LD(LOAD(lduw, %i1, %g1))
+-	EX_ST(STORE(stw, %g1, %i1 + %i3))
++	EX_LD(LOAD(lduw, %i1, %g1), NG_ret_i2_plus_4)
++	EX_ST(STORE(stw, %g1, %i1 + %i3), NG_ret_i2_plus_4)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%i1, 4, %i1
+ 
+@@ -415,8 +498,8 @@ FUNC_NAME:	/* %i0=dst, %i1=src, %i2=len */
+ 	.align		32
+ 90:
+ 	subcc		%i2, 1, %i2
+-	EX_LD(LOAD(ldub, %i1, %g1))
+-	EX_ST(STORE(stb, %g1, %i1 + %i3))
++	EX_LD(LOAD(ldub, %i1, %g1), NG_ret_i2_plus_1)
++	EX_ST(STORE(stb, %g1, %i1 + %i3), NG_ret_i2_plus_1)
+ 	bgu,pt		%XCC, 90b
+ 	 add		%i1, 1, %i1
+ 	ret
+diff --git a/arch/sparc/lib/U1copy_from_user.S b/arch/sparc/lib/U1copy_from_user.S
+index ecc5692fa2b4..bb6ff73229e3 100644
+--- a/arch/sparc/lib/U1copy_from_user.S
++++ b/arch/sparc/lib/U1copy_from_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_LD_FP(x)		\
++#define EX_LD_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_fp;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/U1copy_to_user.S b/arch/sparc/lib/U1copy_to_user.S
+index 9eea392e44d4..ed92ce739558 100644
+--- a/arch/sparc/lib/U1copy_to_user.S
++++ b/arch/sparc/lib/U1copy_to_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_ST_FP(x)		\
++#define EX_ST_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_fp;\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/U1memcpy.S b/arch/sparc/lib/U1memcpy.S
+index 3e6209ebb7d7..f30d2ab2c371 100644
+--- a/arch/sparc/lib/U1memcpy.S
++++ b/arch/sparc/lib/U1memcpy.S
+@@ -5,6 +5,7 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #include <asm/visasm.h>
+ #include <asm/asi.h>
+ #define GLOBAL_SPARE	g7
+@@ -23,21 +24,17 @@
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ #ifndef EX_LD_FP
+-#define EX_LD_FP(x)	x
++#define EX_LD_FP(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ #ifndef EX_ST_FP
+-#define EX_ST_FP(x)	x
+-#endif
+-
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
++#define EX_ST_FP(x,y)	x
+ #endif
+ 
+ #ifndef LOAD
+@@ -78,53 +75,169 @@
+ 	faligndata		%f7, %f8, %f60;			\
+ 	faligndata		%f8, %f9, %f62;
+ 
+-#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, len, jmptgt)	\
+-	EX_LD_FP(LOAD_BLK(%src, %fdest));				\
+-	EX_ST_FP(STORE_BLK(%fsrc, %dest));				\
+-	add			%src, 0x40, %src;		\
+-	subcc			%len, 0x40, %len;		\
+-	be,pn			%xcc, jmptgt;			\
+-	 add			%dest, 0x40, %dest;		\
+-
+-#define LOOP_CHUNK1(src, dest, len, branch_dest)		\
+-	MAIN_LOOP_CHUNK(src, dest, f0,  f48, len, branch_dest)
+-#define LOOP_CHUNK2(src, dest, len, branch_dest)		\
+-	MAIN_LOOP_CHUNK(src, dest, f16, f48, len, branch_dest)
+-#define LOOP_CHUNK3(src, dest, len, branch_dest)		\
+-	MAIN_LOOP_CHUNK(src, dest, f32, f48, len, branch_dest)
++#define MAIN_LOOP_CHUNK(src, dest, fdest, fsrc, jmptgt)			\
++	EX_LD_FP(LOAD_BLK(%src, %fdest), U1_gs_80_fp);			\
++	EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_80_fp);			\
++	add			%src, 0x40, %src;			\
++	subcc			%GLOBAL_SPARE, 0x40, %GLOBAL_SPARE;	\
++	be,pn			%xcc, jmptgt;				\
++	 add			%dest, 0x40, %dest;			\
++
++#define LOOP_CHUNK1(src, dest, branch_dest)		\
++	MAIN_LOOP_CHUNK(src, dest, f0,  f48, branch_dest)
++#define LOOP_CHUNK2(src, dest, branch_dest)		\
++	MAIN_LOOP_CHUNK(src, dest, f16, f48, branch_dest)
++#define LOOP_CHUNK3(src, dest, branch_dest)		\
++	MAIN_LOOP_CHUNK(src, dest, f32, f48, branch_dest)
+ 
+ #define DO_SYNC			membar	#Sync;
+ #define STORE_SYNC(dest, fsrc)				\
+-	EX_ST_FP(STORE_BLK(%fsrc, %dest));			\
++	EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_80_fp);	\
+ 	add			%dest, 0x40, %dest;	\
+ 	DO_SYNC
+ 
+ #define STORE_JUMP(dest, fsrc, target)			\
+-	EX_ST_FP(STORE_BLK(%fsrc, %dest));			\
++	EX_ST_FP(STORE_BLK(%fsrc, %dest), U1_gs_40_fp);	\
+ 	add			%dest, 0x40, %dest;	\
+ 	ba,pt			%xcc, target;		\
+ 	 nop;
+ 
+-#define FINISH_VISCHUNK(dest, f0, f1, left)	\
+-	subcc			%left, 8, %left;\
+-	bl,pn			%xcc, 95f;	\
+-	 faligndata		%f0, %f1, %f48;	\
+-	EX_ST_FP(STORE(std, %f48, %dest));		\
++#define FINISH_VISCHUNK(dest, f0, f1)			\
++	subcc			%g3, 8, %g3;		\
++	bl,pn			%xcc, 95f;		\
++	 faligndata		%f0, %f1, %f48;		\
++	EX_ST_FP(STORE(std, %f48, %dest), U1_g3_8_fp);	\
+ 	add			%dest, 8, %dest;
+ 
+-#define UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)	\
+-	subcc			%left, 8, %left;	\
+-	bl,pn			%xcc, 95f;		\
++#define UNEVEN_VISCHUNK_LAST(dest, f0, f1)	\
++	subcc			%g3, 8, %g3;	\
++	bl,pn			%xcc, 95f;	\
+ 	 fsrc2			%f0, %f1;
+ 
+-#define UNEVEN_VISCHUNK(dest, f0, f1, left)		\
+-	UNEVEN_VISCHUNK_LAST(dest, f0, f1, left)	\
++#define UNEVEN_VISCHUNK(dest, f0, f1)		\
++	UNEVEN_VISCHUNK_LAST(dest, f0, f1)	\
+ 	ba,a,pt			%xcc, 93f;
+ 
+ 	.register	%g2,#scratch
+ 	.register	%g3,#scratch
+ 
+ 	.text
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++ENTRY(U1_g1_1_fp)
++	VISExitHalf
++	add		%g1, 1, %g1
++	add		%g1, %g2, %g1
++	retl
++	 add		%g1, %o2, %o0
++ENDPROC(U1_g1_1_fp)
++ENTRY(U1_g2_0_fp)
++	VISExitHalf
++	retl
++	 add		%g2, %o2, %o0
++ENDPROC(U1_g2_0_fp)
++ENTRY(U1_g2_8_fp)
++	VISExitHalf
++	add		%g2, 8, %g2
++	retl
++	 add		%g2, %o2, %o0
++ENDPROC(U1_g2_8_fp)
++ENTRY(U1_gs_0_fp)
++	VISExitHalf
++	add		%GLOBAL_SPARE, %g3, %o0
++	retl
++	 add		%o0, %o2, %o0
++ENDPROC(U1_gs_0_fp)
++ENTRY(U1_gs_80_fp)
++	VISExitHalf
++	add		%GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
++	add		%GLOBAL_SPARE, %g3, %o0
++	retl
++	 add		%o0, %o2, %o0
++ENDPROC(U1_gs_80_fp)
++ENTRY(U1_gs_40_fp)
++	VISExitHalf
++	add		%GLOBAL_SPARE, 0x40, %GLOBAL_SPARE
++	add		%GLOBAL_SPARE, %g3, %o0
++	retl
++	 add		%o0, %o2, %o0
++ENDPROC(U1_gs_40_fp)
++ENTRY(U1_g3_0_fp)
++	VISExitHalf
++	retl
++	 add		%g3, %o2, %o0
++ENDPROC(U1_g3_0_fp)
++ENTRY(U1_g3_8_fp)
++	VISExitHalf
++	add		%g3, 8, %g3
++	retl
++	 add		%g3, %o2, %o0
++ENDPROC(U1_g3_8_fp)
++ENTRY(U1_o2_0_fp)
++	VISExitHalf
++	retl
++	 mov		%o2, %o0
++ENDPROC(U1_o2_0_fp)
++ENTRY(U1_o2_1_fp)
++	VISExitHalf
++	retl
++	 add		%o2, 1, %o0
++ENDPROC(U1_o2_1_fp)
++ENTRY(U1_gs_0)
++	VISExitHalf
++	retl
++	 add		%GLOBAL_SPARE, %o2, %o0
++ENDPROC(U1_gs_0)
++ENTRY(U1_gs_8)
++	VISExitHalf
++	add		%GLOBAL_SPARE, %o2, %GLOBAL_SPARE
++	retl
++	 add		%GLOBAL_SPARE, 0x8, %o0
++ENDPROC(U1_gs_8)
++ENTRY(U1_gs_10)
++	VISExitHalf
++	add		%GLOBAL_SPARE, %o2, %GLOBAL_SPARE
++	retl
++	 add		%GLOBAL_SPARE, 0x10, %o0
++ENDPROC(U1_gs_10)
++ENTRY(U1_o2_0)
++	retl
++	 mov		%o2, %o0
++ENDPROC(U1_o2_0)
++ENTRY(U1_o2_8)
++	retl
++	 add		%o2, 8, %o0
++ENDPROC(U1_o2_8)
++ENTRY(U1_o2_4)
++	retl
++	 add		%o2, 4, %o0
++ENDPROC(U1_o2_4)
++ENTRY(U1_o2_1)
++	retl
++	 add		%o2, 1, %o0
++ENDPROC(U1_o2_1)
++ENTRY(U1_g1_0)
++	retl
++	 add		%g1, %o2, %o0
++ENDPROC(U1_g1_0)
++ENTRY(U1_g1_1)
++	add		%g1, 1, %g1
++	retl
++	 add		%g1, %o2, %o0
++ENDPROC(U1_g1_1)
++ENTRY(U1_gs_0_o2_adj)
++	and		%o2, 7, %o2
++	retl
++	 add		%GLOBAL_SPARE, %o2, %o0
++ENDPROC(U1_gs_0_o2_adj)
++ENTRY(U1_gs_8_o2_adj)
++	and		%o2, 7, %o2
++	add		%GLOBAL_SPARE, 8, %GLOBAL_SPARE
++	retl
++	 add		%GLOBAL_SPARE, %o2, %o0
++ENDPROC(U1_gs_8_o2_adj)
++#endif
++
+ 	.align		64
+ 
+ 	.globl		FUNC_NAME
+@@ -166,8 +279,8 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	 and		%g2, 0x38, %g2
+ 
+ 1:	subcc		%g1, 0x1, %g1
+-	EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+-	EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE))
++	EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3), U1_g1_1_fp)
++	EX_ST_FP(STORE(stb, %o3, %o1 + %GLOBAL_SPARE), U1_g1_1_fp)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 0x1, %o1
+ 
+@@ -178,20 +291,20 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	be,pt		%icc, 3f
+ 	 alignaddr	%o1, %g0, %o1
+ 
+-	EX_LD_FP(LOAD(ldd, %o1, %f4))
+-1:	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
++	EX_LD_FP(LOAD(ldd, %o1, %f4), U1_g2_0_fp)
++1:	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6), U1_g2_0_fp)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f4, %f6, %f0
+-	EX_ST_FP(STORE(std, %f0, %o0))
++	EX_ST_FP(STORE(std, %f0, %o0), U1_g2_8_fp)
+ 	be,pn		%icc, 3f
+ 	 add		%o0, 0x8, %o0
+ 
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4), U1_g2_0_fp)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f6, %f4, %f0
+-	EX_ST_FP(STORE(std, %f0, %o0))
++	EX_ST_FP(STORE(std, %f0, %o0), U1_g2_8_fp)
+ 	bne,pt		%icc, 1b
+ 	 add		%o0, 0x8, %o0
+ 
+@@ -214,13 +327,13 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	add		%g1, %GLOBAL_SPARE, %g1
+ 	subcc		%o2, %g3, %o2
+ 
+-	EX_LD_FP(LOAD_BLK(%o1, %f0))
++	EX_LD_FP(LOAD_BLK(%o1, %f0), U1_gs_0_fp)
+ 	add		%o1, 0x40, %o1
+ 	add		%g1, %g3, %g1
+-	EX_LD_FP(LOAD_BLK(%o1, %f16))
++	EX_LD_FP(LOAD_BLK(%o1, %f16), U1_gs_0_fp)
+ 	add		%o1, 0x40, %o1
+ 	sub		%GLOBAL_SPARE, 0x80, %GLOBAL_SPARE
+-	EX_LD_FP(LOAD_BLK(%o1, %f32))
++	EX_LD_FP(LOAD_BLK(%o1, %f32), U1_gs_80_fp)
+ 	add		%o1, 0x40, %o1
+ 
+ 	/* There are 8 instances of the unrolled loop,
+@@ -240,11 +353,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 
+ 	.align		64
+ 1:	FREG_FROB(f0, f2, f4, f6, f8, f10,f12,f14,f16)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f32,f34,f36,f38,f40,f42,f44,f46,f0)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f0, %f2, %f48
+ 1:	FREG_FROB(f16,f18,f20,f22,f24,f26,f28,f30,f32)
+@@ -261,11 +374,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 56f)
+ 
+ 1:	FREG_FROB(f2, f4, f6, f8, f10,f12,f14,f16,f18)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f34,f36,f38,f40,f42,f44,f46,f0, f2)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f2, %f4, %f48
+ 1:	FREG_FROB(f18,f20,f22,f24,f26,f28,f30,f32,f34)
+@@ -282,11 +395,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 57f)
+ 
+ 1:	FREG_FROB(f4, f6, f8, f10,f12,f14,f16,f18,f20)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f36,f38,f40,f42,f44,f46,f0, f2, f4)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f4, %f6, %f48
+ 1:	FREG_FROB(f20,f22,f24,f26,f28,f30,f32,f34,f36)
+@@ -303,11 +416,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 58f)
+ 
+ 1:	FREG_FROB(f6, f8, f10,f12,f14,f16,f18,f20,f22)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f38,f40,f42,f44,f46,f0, f2, f4, f6) 
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f6, %f8, %f48
+ 1:	FREG_FROB(f22,f24,f26,f28,f30,f32,f34,f36,f38)
+@@ -324,11 +437,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 59f)
+ 
+ 1:	FREG_FROB(f8, f10,f12,f14,f16,f18,f20,f22,f24)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f40,f42,f44,f46,f0, f2, f4, f6, f8)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f8, %f10, %f48
+ 1:	FREG_FROB(f24,f26,f28,f30,f32,f34,f36,f38,f40)
+@@ -345,11 +458,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 60f)
+ 
+ 1:	FREG_FROB(f10,f12,f14,f16,f18,f20,f22,f24,f26)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f42,f44,f46,f0, f2, f4, f6, f8, f10)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f10, %f12, %f48
+ 1:	FREG_FROB(f26,f28,f30,f32,f34,f36,f38,f40,f42)
+@@ -366,11 +479,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 61f)
+ 
+ 1:	FREG_FROB(f12,f14,f16,f18,f20,f22,f24,f26,f28)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f44,f46,f0, f2, f4, f6, f8, f10,f12)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f12, %f14, %f48
+ 1:	FREG_FROB(f28,f30,f32,f34,f36,f38,f40,f42,f44)
+@@ -387,11 +500,11 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	STORE_JUMP(o0, f48, 62f)
+ 
+ 1:	FREG_FROB(f14,f16,f18,f20,f22,f24,f26,f28,f30)
+-	LOOP_CHUNK1(o1, o0, GLOBAL_SPARE, 1f)
++	LOOP_CHUNK1(o1, o0, 1f)
+ 	FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
+-	LOOP_CHUNK2(o1, o0, GLOBAL_SPARE, 2f)
++	LOOP_CHUNK2(o1, o0, 2f)
+ 	FREG_FROB(f46,f0, f2, f4, f6, f8, f10,f12,f14)
+-	LOOP_CHUNK3(o1, o0, GLOBAL_SPARE, 3f)
++	LOOP_CHUNK3(o1, o0, 3f)
+ 	ba,pt		%xcc, 1b+4
+ 	 faligndata	%f14, %f16, %f48
+ 1:	FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
+@@ -407,53 +520,53 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	FREG_FROB(f30,f32,f34,f36,f38,f40,f42,f44,f46)
+ 	STORE_JUMP(o0, f48, 63f)
+ 
+-40:	FINISH_VISCHUNK(o0, f0,  f2,  g3)
+-41:	FINISH_VISCHUNK(o0, f2,  f4,  g3)
+-42:	FINISH_VISCHUNK(o0, f4,  f6,  g3)
+-43:	FINISH_VISCHUNK(o0, f6,  f8,  g3)
+-44:	FINISH_VISCHUNK(o0, f8,  f10, g3)
+-45:	FINISH_VISCHUNK(o0, f10, f12, g3)
+-46:	FINISH_VISCHUNK(o0, f12, f14, g3)
+-47:	UNEVEN_VISCHUNK(o0, f14, f0,  g3)
+-48:	FINISH_VISCHUNK(o0, f16, f18, g3)
+-49:	FINISH_VISCHUNK(o0, f18, f20, g3)
+-50:	FINISH_VISCHUNK(o0, f20, f22, g3)
+-51:	FINISH_VISCHUNK(o0, f22, f24, g3)
+-52:	FINISH_VISCHUNK(o0, f24, f26, g3)
+-53:	FINISH_VISCHUNK(o0, f26, f28, g3)
+-54:	FINISH_VISCHUNK(o0, f28, f30, g3)
+-55:	UNEVEN_VISCHUNK(o0, f30, f0,  g3)
+-56:	FINISH_VISCHUNK(o0, f32, f34, g3)
+-57:	FINISH_VISCHUNK(o0, f34, f36, g3)
+-58:	FINISH_VISCHUNK(o0, f36, f38, g3)
+-59:	FINISH_VISCHUNK(o0, f38, f40, g3)
+-60:	FINISH_VISCHUNK(o0, f40, f42, g3)
+-61:	FINISH_VISCHUNK(o0, f42, f44, g3)
+-62:	FINISH_VISCHUNK(o0, f44, f46, g3)
+-63:	UNEVEN_VISCHUNK_LAST(o0, f46, f0,  g3)
+-
+-93:	EX_LD_FP(LOAD(ldd, %o1, %f2))
++40:	FINISH_VISCHUNK(o0, f0,  f2)
++41:	FINISH_VISCHUNK(o0, f2,  f4)
++42:	FINISH_VISCHUNK(o0, f4,  f6)
++43:	FINISH_VISCHUNK(o0, f6,  f8)
++44:	FINISH_VISCHUNK(o0, f8,  f10)
++45:	FINISH_VISCHUNK(o0, f10, f12)
++46:	FINISH_VISCHUNK(o0, f12, f14)
++47:	UNEVEN_VISCHUNK(o0, f14, f0)
++48:	FINISH_VISCHUNK(o0, f16, f18)
++49:	FINISH_VISCHUNK(o0, f18, f20)
++50:	FINISH_VISCHUNK(o0, f20, f22)
++51:	FINISH_VISCHUNK(o0, f22, f24)
++52:	FINISH_VISCHUNK(o0, f24, f26)
++53:	FINISH_VISCHUNK(o0, f26, f28)
++54:	FINISH_VISCHUNK(o0, f28, f30)
++55:	UNEVEN_VISCHUNK(o0, f30, f0)
++56:	FINISH_VISCHUNK(o0, f32, f34)
++57:	FINISH_VISCHUNK(o0, f34, f36)
++58:	FINISH_VISCHUNK(o0, f36, f38)
++59:	FINISH_VISCHUNK(o0, f38, f40)
++60:	FINISH_VISCHUNK(o0, f40, f42)
++61:	FINISH_VISCHUNK(o0, f42, f44)
++62:	FINISH_VISCHUNK(o0, f44, f46)
++63:	UNEVEN_VISCHUNK_LAST(o0, f46, f0)
++
++93:	EX_LD_FP(LOAD(ldd, %o1, %f2), U1_g3_0_fp)
+ 	add		%o1, 8, %o1
+ 	subcc		%g3, 8, %g3
+ 	faligndata	%f0, %f2, %f8
+-	EX_ST_FP(STORE(std, %f8, %o0))
++	EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp)
+ 	bl,pn		%xcc, 95f
+ 	 add		%o0, 8, %o0
+-	EX_LD_FP(LOAD(ldd, %o1, %f0))
++	EX_LD_FP(LOAD(ldd, %o1, %f0), U1_g3_0_fp)
+ 	add		%o1, 8, %o1
+ 	subcc		%g3, 8, %g3
+ 	faligndata	%f2, %f0, %f8
+-	EX_ST_FP(STORE(std, %f8, %o0))
++	EX_ST_FP(STORE(std, %f8, %o0), U1_g3_8_fp)
+ 	bge,pt		%xcc, 93b
+ 	 add		%o0, 8, %o0
+ 
+ 95:	brz,pt		%o2, 2f
+ 	 mov		%g1, %o1
+ 
+-1:	EX_LD_FP(LOAD(ldub, %o1, %o3))
++1:	EX_LD_FP(LOAD(ldub, %o1, %o3), U1_o2_0_fp)
+ 	add		%o1, 1, %o1
+ 	subcc		%o2, 1, %o2
+-	EX_ST_FP(STORE(stb, %o3, %o0))
++	EX_ST_FP(STORE(stb, %o3, %o0), U1_o2_1_fp)
+ 	bne,pt		%xcc, 1b
+ 	 add		%o0, 1, %o0
+ 
+@@ -469,27 +582,27 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 
+ 72:	andn		%o2, 0xf, %GLOBAL_SPARE
+ 	and		%o2, 0xf, %o2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x00, %o5))
+-	EX_LD(LOAD(ldx, %o1 + 0x08, %g1))
++1:	EX_LD(LOAD(ldx, %o1 + 0x00, %o5), U1_gs_0)
++	EX_LD(LOAD(ldx, %o1 + 0x08, %g1), U1_gs_0)
+ 	subcc		%GLOBAL_SPARE, 0x10, %GLOBAL_SPARE
+-	EX_ST(STORE(stx, %o5, %o1 + %o3))
++	EX_ST(STORE(stx, %o5, %o1 + %o3), U1_gs_10)
+ 	add		%o1, 0x8, %o1
+-	EX_ST(STORE(stx, %g1, %o1 + %o3))
++	EX_ST(STORE(stx, %g1, %o1 + %o3), U1_gs_8)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 0x8, %o1
+ 73:	andcc		%o2, 0x8, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+-	EX_LD(LOAD(ldx, %o1, %o5))
++	EX_LD(LOAD(ldx, %o1, %o5), U1_o2_0)
+ 	sub		%o2, 0x8, %o2
+-	EX_ST(STORE(stx, %o5, %o1 + %o3))
++	EX_ST(STORE(stx, %o5, %o1 + %o3), U1_o2_8)
+ 	add		%o1, 0x8, %o1
+ 1:	andcc		%o2, 0x4, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+-	EX_LD(LOAD(lduw, %o1, %o5))
++	EX_LD(LOAD(lduw, %o1, %o5), U1_o2_0)
+ 	sub		%o2, 0x4, %o2
+-	EX_ST(STORE(stw, %o5, %o1 + %o3))
++	EX_ST(STORE(stw, %o5, %o1 + %o3), U1_o2_4)
+ 	add		%o1, 0x4, %o1
+ 1:	cmp		%o2, 0
+ 	be,pt		%XCC, 85f
+@@ -503,9 +616,9 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	 sub		%g0, %g1, %g1
+ 	sub		%o2, %g1, %o2
+ 
+-1:	EX_LD(LOAD(ldub, %o1, %o5))
++1:	EX_LD(LOAD(ldub, %o1, %o5), U1_g1_0)
+ 	subcc		%g1, 1, %g1
+-	EX_ST(STORE(stb, %o5, %o1 + %o3))
++	EX_ST(STORE(stb, %o5, %o1 + %o3), U1_g1_1)
+ 	bgu,pt		%icc, 1b
+ 	 add		%o1, 1, %o1
+ 
+@@ -521,16 +634,16 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 
+ 8:	mov		64, %o3
+ 	andn		%o1, 0x7, %o1
+-	EX_LD(LOAD(ldx, %o1, %g2))
++	EX_LD(LOAD(ldx, %o1, %g2), U1_o2_0)
+ 	sub		%o3, %g1, %o3
+ 	andn		%o2, 0x7, %GLOBAL_SPARE
+ 	sllx		%g2, %g1, %g2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x8, %g3))
++1:	EX_LD(LOAD(ldx, %o1 + 0x8, %g3), U1_gs_0_o2_adj)
+ 	subcc		%GLOBAL_SPARE, 0x8, %GLOBAL_SPARE
+ 	add		%o1, 0x8, %o1
+ 	srlx		%g3, %o3, %o5
+ 	or		%o5, %g2, %o5
+-	EX_ST(STORE(stx, %o5, %o0))
++	EX_ST(STORE(stx, %o5, %o0), U1_gs_8_o2_adj)
+ 	add		%o0, 0x8, %o0
+ 	bgu,pt		%icc, 1b
+ 	 sllx		%g3, %g1, %g2
+@@ -548,9 +661,9 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	bne,pn		%XCC, 90f
+ 	 sub		%o0, %o1, %o3
+ 
+-1:	EX_LD(LOAD(lduw, %o1, %g1))
++1:	EX_LD(LOAD(lduw, %o1, %g1), U1_o2_0)
+ 	subcc		%o2, 4, %o2
+-	EX_ST(STORE(stw, %g1, %o1 + %o3))
++	EX_ST(STORE(stw, %g1, %o1 + %o3), U1_o2_4)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 4, %o1
+ 
+@@ -558,9 +671,9 @@ FUNC_NAME:		/* %o0=dst, %o1=src, %o2=len */
+ 	 mov		EX_RETVAL(%o4), %o0
+ 
+ 	.align		32
+-90:	EX_LD(LOAD(ldub, %o1, %g1))
++90:	EX_LD(LOAD(ldub, %o1, %g1), U1_o2_0)
+ 	subcc		%o2, 1, %o2
+-	EX_ST(STORE(stb, %g1, %o1 + %o3))
++	EX_ST(STORE(stb, %g1, %o1 + %o3), U1_o2_1)
+ 	bgu,pt		%XCC, 90b
+ 	 add		%o1, 1, %o1
+ 	retl
+diff --git a/arch/sparc/lib/U3copy_from_user.S b/arch/sparc/lib/U3copy_from_user.S
+index 88ad73d86fe4..db73010a1af8 100644
+--- a/arch/sparc/lib/U3copy_from_user.S
++++ b/arch/sparc/lib/U3copy_from_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
+  */
+ 
+-#define EX_LD(x)		\
++#define EX_LD(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_LD_FP(x)		\
++#define EX_LD_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/U3copy_to_user.S b/arch/sparc/lib/U3copy_to_user.S
+index 845139d75537..c4ee858e352a 100644
+--- a/arch/sparc/lib/U3copy_to_user.S
++++ b/arch/sparc/lib/U3copy_to_user.S
+@@ -3,19 +3,19 @@
+  * Copyright (C) 1999, 2000, 2004 David S. Miller (davem@redhat.com)
+  */
+ 
+-#define EX_ST(x)		\
++#define EX_ST(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, y;		\
+ 	.text;			\
+ 	.align 4;
+ 
+-#define EX_ST_FP(x)		\
++#define EX_ST_FP(x,y)		\
+ 98:	x;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one_fp;\
++	.word 98b, y##_fp;	\
+ 	.text;			\
+ 	.align 4;
+ 
+diff --git a/arch/sparc/lib/U3memcpy.S b/arch/sparc/lib/U3memcpy.S
+index 491ee69e4995..54f98706b03b 100644
+--- a/arch/sparc/lib/U3memcpy.S
++++ b/arch/sparc/lib/U3memcpy.S
+@@ -4,6 +4,7 @@
+  */
+ 
+ #ifdef __KERNEL__
++#include <linux/linkage.h>
+ #include <asm/visasm.h>
+ #include <asm/asi.h>
+ #define GLOBAL_SPARE	%g7
+@@ -22,21 +23,17 @@
+ #endif
+ 
+ #ifndef EX_LD
+-#define EX_LD(x)	x
++#define EX_LD(x,y)	x
+ #endif
+ #ifndef EX_LD_FP
+-#define EX_LD_FP(x)	x
++#define EX_LD_FP(x,y)	x
+ #endif
+ 
+ #ifndef EX_ST
+-#define EX_ST(x)	x
++#define EX_ST(x,y)	x
+ #endif
+ #ifndef EX_ST_FP
+-#define EX_ST_FP(x)	x
+-#endif
+-
+-#ifndef EX_RETVAL
+-#define EX_RETVAL(x)	x
++#define EX_ST_FP(x,y)	x
+ #endif
+ 
+ #ifndef LOAD
+@@ -77,6 +74,87 @@
+ 	 */
+ 
+ 	.text
++#ifndef EX_RETVAL
++#define EX_RETVAL(x)	x
++__restore_fp:
++	VISExitHalf
++	retl
++	 nop
++ENTRY(U3_retl_o2_plus_g2_plus_g1_plus_1_fp)
++	add	%g1, 1, %g1
++	add	%g2, %g1, %g2
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %g2, %o0
++ENDPROC(U3_retl_o2_plus_g2_plus_g1_plus_1_fp)
++ENTRY(U3_retl_o2_plus_g2_fp)
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %g2, %o0
++ENDPROC(U3_retl_o2_plus_g2_fp)
++ENTRY(U3_retl_o2_plus_g2_plus_8_fp)
++	add	%g2, 8, %g2
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %g2, %o0
++ENDPROC(U3_retl_o2_plus_g2_plus_8_fp)
++ENTRY(U3_retl_o2)
++	retl
++	 mov	%o2, %o0
++ENDPROC(U3_retl_o2)
++ENTRY(U3_retl_o2_plus_1)
++	retl
++	 add	%o2, 1, %o0
++ENDPROC(U3_retl_o2_plus_1)
++ENTRY(U3_retl_o2_plus_4)
++	retl
++	 add	%o2, 4, %o0
++ENDPROC(U3_retl_o2_plus_4)
++ENTRY(U3_retl_o2_plus_8)
++	retl
++	 add	%o2, 8, %o0
++ENDPROC(U3_retl_o2_plus_8)
++ENTRY(U3_retl_o2_plus_g1_plus_1)
++	add	%g1, 1, %g1
++	retl
++	 add	%o2, %g1, %o0
++ENDPROC(U3_retl_o2_plus_g1_plus_1)
++ENTRY(U3_retl_o2_fp)
++	ba,pt	%xcc, __restore_fp
++	 mov	%o2, %o0
++ENDPROC(U3_retl_o2_fp)
++ENTRY(U3_retl_o2_plus_o3_sll_6_plus_0x80_fp)
++	sll	%o3, 6, %o3
++	add	%o3, 0x80, %o3
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %o3, %o0
++ENDPROC(U3_retl_o2_plus_o3_sll_6_plus_0x80_fp)
++ENTRY(U3_retl_o2_plus_o3_sll_6_plus_0x40_fp)
++	sll	%o3, 6, %o3
++	add	%o3, 0x40, %o3
++	ba,pt	%xcc, __restore_fp
++	 add	%o2, %o3, %o0
++ENDPROC(U3_retl_o2_plus_o3_sll_6_plus_0x40_fp)
++ENTRY(U3_retl_o2_plus_GS_plus_0x10)
++	add	GLOBAL_SPARE, 0x10, GLOBAL_SPARE
++	retl
++	 add	%o2, GLOBAL_SPARE, %o0
++ENDPROC(U3_retl_o2_plus_GS_plus_0x10)
++ENTRY(U3_retl_o2_plus_GS_plus_0x08)
++	add	GLOBAL_SPARE, 0x08, GLOBAL_SPARE
++	retl
++	 add	%o2, GLOBAL_SPARE, %o0
++ENDPROC(U3_retl_o2_plus_GS_plus_0x08)
++ENTRY(U3_retl_o2_and_7_plus_GS)
++	and	%o2, 7, %o2
++	retl
++	 add	%o2, GLOBAL_SPARE, %o2
++ENDPROC(U3_retl_o2_and_7_plus_GS)
++ENTRY(U3_retl_o2_and_7_plus_GS_plus_8)
++	add	GLOBAL_SPARE, 8, GLOBAL_SPARE
++	and	%o2, 7, %o2
++	retl
++	 add	%o2, GLOBAL_SPARE, %o2
++ENDPROC(U3_retl_o2_and_7_plus_GS_plus_8)
++#endif
++
+ 	.align		64
+ 
+ 	/* The cheetah's flexible spine, oversized liver, enlarged heart,
+@@ -126,8 +204,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	 and		%g2, 0x38, %g2
+ 
+ 1:	subcc		%g1, 0x1, %g1
+-	EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3))
+-	EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE))
++	EX_LD_FP(LOAD(ldub, %o1 + 0x00, %o3), U3_retl_o2_plus_g2_plus_g1_plus_1)
++	EX_ST_FP(STORE(stb, %o3, %o1 + GLOBAL_SPARE), U3_retl_o2_plus_g2_plus_g1_plus_1)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 0x1, %o1
+ 
+@@ -138,20 +216,20 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	be,pt		%icc, 3f
+ 	 alignaddr	%o1, %g0, %o1
+ 
+-	EX_LD_FP(LOAD(ldd, %o1, %f4))
+-1:	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6))
++	EX_LD_FP(LOAD(ldd, %o1, %f4), U3_retl_o2_plus_g2)
++1:	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f6), U3_retl_o2_plus_g2)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f4, %f6, %f0
+-	EX_ST_FP(STORE(std, %f0, %o0))
++	EX_ST_FP(STORE(std, %f0, %o0), U3_retl_o2_plus_g2_plus_8)
+ 	be,pn		%icc, 3f
+ 	 add		%o0, 0x8, %o0
+ 
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x8, %f4), U3_retl_o2_plus_g2)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f6, %f4, %f2
+-	EX_ST_FP(STORE(std, %f2, %o0))
++	EX_ST_FP(STORE(std, %f2, %o0), U3_retl_o2_plus_g2_plus_8)
+ 	bne,pt		%icc, 1b
+ 	 add		%o0, 0x8, %o0
+ 
+@@ -161,25 +239,25 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	LOAD(prefetch, %o1 + 0x080, #one_read)
+ 	LOAD(prefetch, %o1 + 0x0c0, #one_read)
+ 	LOAD(prefetch, %o1 + 0x100, #one_read)
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x000, %f0), U3_retl_o2)
+ 	LOAD(prefetch, %o1 + 0x140, #one_read)
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2)
+ 	LOAD(prefetch, %o1 + 0x180, #one_read)
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2)
+ 	LOAD(prefetch, %o1 + 0x1c0, #one_read)
+ 	faligndata	%f0, %f2, %f16
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2)
+ 	faligndata	%f2, %f4, %f18
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2)
+ 	faligndata	%f4, %f6, %f20
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2)
+ 	faligndata	%f6, %f8, %f22
+ 
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2)
+ 	faligndata	%f8, %f10, %f24
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2)
+ 	faligndata	%f10, %f12, %f26
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2)
+ 
+ 	subcc		GLOBAL_SPARE, 0x80, GLOBAL_SPARE
+ 	add		%o1, 0x40, %o1
+@@ -190,26 +268,26 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 	.align		64
+ 1:
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 	faligndata	%f12, %f14, %f28
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 	faligndata	%f14, %f0, %f30
+-	EX_ST_FP(STORE_BLK(%f16, %o0))
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
++	EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
++	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f0, %f2, %f16
+ 	add		%o0, 0x40, %o0
+ 
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f2, %f4, %f18
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f4, %f6, %f20
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	subcc		%o3, 0x01, %o3
+ 	faligndata	%f6, %f8, %f22
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 
+ 	faligndata	%f8, %f10, %f24
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 	LOAD(prefetch, %o1 + 0x1c0, #one_read)
+ 	faligndata	%f10, %f12, %f26
+ 	bg,pt		%XCC, 1b
+@@ -217,29 +295,29 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 	/* Finally we copy the last full 64-byte block. */
+ 2:
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x008, %f2), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 	faligndata	%f12, %f14, %f28
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x010, %f4), U3_retl_o2_plus_o3_sll_6_plus_0x80)
+ 	faligndata	%f14, %f0, %f30
+-	EX_ST_FP(STORE_BLK(%f16, %o0))
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6))
++	EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x80)
++	EX_LD_FP(LOAD(ldd, %o1 + 0x018, %f6), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f0, %f2, %f16
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x020, %f8), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f2, %f4, %f18
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x028, %f10), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f4, %f6, %f20
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x030, %f12), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f6, %f8, %f22
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x038, %f14), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	faligndata	%f8, %f10, %f24
+ 	cmp		%g1, 0
+ 	be,pt		%XCC, 1f
+ 	 add		%o0, 0x40, %o0
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x040, %f0), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 1:	faligndata	%f10, %f12, %f26
+ 	faligndata	%f12, %f14, %f28
+ 	faligndata	%f14, %f0, %f30
+-	EX_ST_FP(STORE_BLK(%f16, %o0))
++	EX_ST_FP(STORE_BLK(%f16, %o0), U3_retl_o2_plus_o3_sll_6_plus_0x40)
+ 	add		%o0, 0x40, %o0
+ 	add		%o1, 0x40, %o1
+ 	membar		#Sync
+@@ -259,20 +337,20 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 	sub		%o2, %g2, %o2
+ 	be,a,pt		%XCC, 1f
+-	 EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0))
++	 EX_LD_FP(LOAD(ldd, %o1 + 0x00, %f0), U3_retl_o2_plus_g2)
+ 
+-1:	EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2))
++1:	EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f2), U3_retl_o2_plus_g2)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f0, %f2, %f8
+-	EX_ST_FP(STORE(std, %f8, %o0))
++	EX_ST_FP(STORE(std, %f8, %o0), U3_retl_o2_plus_g2_plus_8)
+ 	be,pn		%XCC, 2f
+ 	 add		%o0, 0x8, %o0
+-	EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0))
++	EX_LD_FP(LOAD(ldd, %o1 + 0x08, %f0), U3_retl_o2_plus_g2)
+ 	add		%o1, 0x8, %o1
+ 	subcc		%g2, 0x8, %g2
+ 	faligndata	%f2, %f0, %f8
+-	EX_ST_FP(STORE(std, %f8, %o0))
++	EX_ST_FP(STORE(std, %f8, %o0), U3_retl_o2_plus_g2_plus_8)
+ 	bne,pn		%XCC, 1b
+ 	 add		%o0, 0x8, %o0
+ 
+@@ -292,30 +370,33 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	 andcc		%o2, 0x8, %g0
+ 	be,pt		%icc, 1f
+ 	 nop
+-	EX_LD(LOAD(ldx, %o1, %o5))
+-	EX_ST(STORE(stx, %o5, %o1 + %o3))
++	EX_LD(LOAD(ldx, %o1, %o5), U3_retl_o2)
++	EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2)
+ 	add		%o1, 0x8, %o1
++	sub		%o2, 8, %o2
+ 
+ 1:	andcc		%o2, 0x4, %g0
+ 	be,pt		%icc, 1f
+ 	 nop
+-	EX_LD(LOAD(lduw, %o1, %o5))
+-	EX_ST(STORE(stw, %o5, %o1 + %o3))
++	EX_LD(LOAD(lduw, %o1, %o5), U3_retl_o2)
++	EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2)
+ 	add		%o1, 0x4, %o1
++	sub		%o2, 4, %o2
+ 
+ 1:	andcc		%o2, 0x2, %g0
+ 	be,pt		%icc, 1f
+ 	 nop
+-	EX_LD(LOAD(lduh, %o1, %o5))
+-	EX_ST(STORE(sth, %o5, %o1 + %o3))
++	EX_LD(LOAD(lduh, %o1, %o5), U3_retl_o2)
++	EX_ST(STORE(sth, %o5, %o1 + %o3), U3_retl_o2)
+ 	add		%o1, 0x2, %o1
++	sub		%o2, 2, %o2
+ 
+ 1:	andcc		%o2, 0x1, %g0
+ 	be,pt		%icc, 85f
+ 	 nop
+-	EX_LD(LOAD(ldub, %o1, %o5))
++	EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2)
+ 	ba,pt		%xcc, 85f
+-	 EX_ST(STORE(stb, %o5, %o1 + %o3))
++	 EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2)
+ 
+ 	.align		64
+ 70: /* 16 < len <= 64 */
+@@ -326,26 +407,26 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	andn		%o2, 0xf, GLOBAL_SPARE
+ 	and		%o2, 0xf, %o2
+ 1:	subcc		GLOBAL_SPARE, 0x10, GLOBAL_SPARE
+-	EX_LD(LOAD(ldx, %o1 + 0x00, %o5))
+-	EX_LD(LOAD(ldx, %o1 + 0x08, %g1))
+-	EX_ST(STORE(stx, %o5, %o1 + %o3))
++	EX_LD(LOAD(ldx, %o1 + 0x00, %o5), U3_retl_o2_plus_GS_plus_0x10)
++	EX_LD(LOAD(ldx, %o1 + 0x08, %g1), U3_retl_o2_plus_GS_plus_0x10)
++	EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2_plus_GS_plus_0x10)
+ 	add		%o1, 0x8, %o1
+-	EX_ST(STORE(stx, %g1, %o1 + %o3))
++	EX_ST(STORE(stx, %g1, %o1 + %o3), U3_retl_o2_plus_GS_plus_0x08)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 0x8, %o1
+ 73:	andcc		%o2, 0x8, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%o2, 0x8, %o2
+-	EX_LD(LOAD(ldx, %o1, %o5))
+-	EX_ST(STORE(stx, %o5, %o1 + %o3))
++	EX_LD(LOAD(ldx, %o1, %o5), U3_retl_o2_plus_8)
++	EX_ST(STORE(stx, %o5, %o1 + %o3), U3_retl_o2_plus_8)
+ 	add		%o1, 0x8, %o1
+ 1:	andcc		%o2, 0x4, %g0
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%o2, 0x4, %o2
+-	EX_LD(LOAD(lduw, %o1, %o5))
+-	EX_ST(STORE(stw, %o5, %o1 + %o3))
++	EX_LD(LOAD(lduw, %o1, %o5), U3_retl_o2_plus_4)
++	EX_ST(STORE(stw, %o5, %o1 + %o3), U3_retl_o2_plus_4)
+ 	add		%o1, 0x4, %o1
+ 1:	cmp		%o2, 0
+ 	be,pt		%XCC, 85f
+@@ -361,8 +442,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	sub		%o2, %g1, %o2
+ 
+ 1:	subcc		%g1, 1, %g1
+-	EX_LD(LOAD(ldub, %o1, %o5))
+-	EX_ST(STORE(stb, %o5, %o1 + %o3))
++	EX_LD(LOAD(ldub, %o1, %o5), U3_retl_o2_plus_g1_plus_1)
++	EX_ST(STORE(stb, %o5, %o1 + %o3), U3_retl_o2_plus_g1_plus_1)
+ 	bgu,pt		%icc, 1b
+ 	 add		%o1, 1, %o1
+ 
+@@ -378,16 +459,16 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 8:	mov		64, %o3
+ 	andn		%o1, 0x7, %o1
+-	EX_LD(LOAD(ldx, %o1, %g2))
++	EX_LD(LOAD(ldx, %o1, %g2), U3_retl_o2)
+ 	sub		%o3, %g1, %o3
+ 	andn		%o2, 0x7, GLOBAL_SPARE
+ 	sllx		%g2, %g1, %g2
+-1:	EX_LD(LOAD(ldx, %o1 + 0x8, %g3))
++1:	EX_LD(LOAD(ldx, %o1 + 0x8, %g3), U3_retl_o2_and_7_plus_GS)
+ 	subcc		GLOBAL_SPARE, 0x8, GLOBAL_SPARE
+ 	add		%o1, 0x8, %o1
+ 	srlx		%g3, %o3, %o5
+ 	or		%o5, %g2, %o5
+-	EX_ST(STORE(stx, %o5, %o0))
++	EX_ST(STORE(stx, %o5, %o0), U3_retl_o2_and_7_plus_GS_plus_8)
+ 	add		%o0, 0x8, %o0
+ 	bgu,pt		%icc, 1b
+ 	 sllx		%g3, %g1, %g2
+@@ -407,8 +488,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 1:
+ 	subcc		%o2, 4, %o2
+-	EX_LD(LOAD(lduw, %o1, %g1))
+-	EX_ST(STORE(stw, %g1, %o1 + %o3))
++	EX_LD(LOAD(lduw, %o1, %g1), U3_retl_o2_plus_4)
++	EX_ST(STORE(stw, %g1, %o1 + %o3), U3_retl_o2_plus_4)
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o1, 4, %o1
+ 
+@@ -418,8 +499,8 @@ FUNC_NAME:	/* %o0=dst, %o1=src, %o2=len */
+ 	.align		32
+ 90:
+ 	subcc		%o2, 1, %o2
+-	EX_LD(LOAD(ldub, %o1, %g1))
+-	EX_ST(STORE(stb, %g1, %o1 + %o3))
++	EX_LD(LOAD(ldub, %o1, %g1), U3_retl_o2_plus_1)
++	EX_ST(STORE(stb, %g1, %o1 + %o3), U3_retl_o2_plus_1)
+ 	bgu,pt		%XCC, 90b
+ 	 add		%o1, 1, %o1
+ 	retl
+diff --git a/arch/sparc/lib/copy_in_user.S b/arch/sparc/lib/copy_in_user.S
+index 302c0e60dc2c..4c89b486fa0d 100644
+--- a/arch/sparc/lib/copy_in_user.S
++++ b/arch/sparc/lib/copy_in_user.S
+@@ -8,18 +8,33 @@
+ 
+ #define XCC xcc
+ 
+-#define EX(x,y)			\
++#define EX(x,y,z)		\
+ 98:	x,y;			\
+ 	.section __ex_table,"a";\
+ 	.align 4;		\
+-	.word 98b, __retl_one;	\
++	.word 98b, z;		\
+ 	.text;			\
+ 	.align 4;
+ 
++#define EX_O4(x,y) EX(x,y,__retl_o4_plus_8)
++#define EX_O2_4(x,y) EX(x,y,__retl_o2_plus_4)
++#define EX_O2_1(x,y) EX(x,y,__retl_o2_plus_1)
++
+ 	.register	%g2,#scratch
+ 	.register	%g3,#scratch
+ 
+ 	.text
++__retl_o4_plus_8:
++	add	%o4, %o2, %o4
++	retl
++	 add	%o4, 8, %o0
++__retl_o2_plus_4:
++	retl
++	 add	%o2, 4, %o0
++__retl_o2_plus_1:
++	retl
++	 add	%o2, 1, %o0
++
+ 	.align	32
+ 
+ 	/* Don't try to get too fancy here, just nice and
+@@ -44,8 +59,8 @@ ENTRY(___copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
+ 	andn		%o2, 0x7, %o4
+ 	and		%o2, 0x7, %o2
+ 1:	subcc		%o4, 0x8, %o4
+-	EX(ldxa [%o1] %asi, %o5)
+-	EX(stxa %o5, [%o0] %asi)
++	EX_O4(ldxa [%o1] %asi, %o5)
++	EX_O4(stxa %o5, [%o0] %asi)
+ 	add		%o1, 0x8, %o1
+ 	bgu,pt		%XCC, 1b
+ 	 add		%o0, 0x8, %o0
+@@ -53,8 +68,8 @@ ENTRY(___copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
+ 	be,pt		%XCC, 1f
+ 	 nop
+ 	sub		%o2, 0x4, %o2
+-	EX(lduwa [%o1] %asi, %o5)
+-	EX(stwa %o5, [%o0] %asi)
++	EX_O2_4(lduwa [%o1] %asi, %o5)
++	EX_O2_4(stwa %o5, [%o0] %asi)
+ 	add		%o1, 0x4, %o1
+ 	add		%o0, 0x4, %o0
+ 1:	cmp		%o2, 0
+@@ -70,8 +85,8 @@ ENTRY(___copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
+ 
+ 82:
+ 	subcc		%o2, 4, %o2
+-	EX(lduwa [%o1] %asi, %g1)
+-	EX(stwa %g1, [%o0] %asi)
++	EX_O2_4(lduwa [%o1] %asi, %g1)
++	EX_O2_4(stwa %g1, [%o0] %asi)
+ 	add		%o1, 4, %o1
+ 	bgu,pt		%XCC, 82b
+ 	 add		%o0, 4, %o0
+@@ -82,8 +97,8 @@ ENTRY(___copy_in_user)	/* %o0=dst, %o1=src, %o2=len */
+ 	.align	32
+ 90:
+ 	subcc		%o2, 1, %o2
+-	EX(lduba [%o1] %asi, %g1)
+-	EX(stba %g1, [%o0] %asi)
++	EX_O2_1(lduba [%o1] %asi, %g1)
++	EX_O2_1(stba %g1, [%o0] %asi)
+ 	add		%o1, 1, %o1
+ 	bgu,pt		%XCC, 90b
+ 	 add		%o0, 1, %o0
+diff --git a/arch/sparc/lib/user_fixup.c b/arch/sparc/lib/user_fixup.c
+deleted file mode 100644
+index ac96ae236709..000000000000
+--- a/arch/sparc/lib/user_fixup.c
++++ /dev/null
+@@ -1,71 +0,0 @@
+-/* user_fixup.c: Fix up user copy faults.
+- *
+- * Copyright (C) 2004 David S. Miller <davem@redhat.com>
+- */
+-
+-#include <linux/compiler.h>
+-#include <linux/kernel.h>
+-#include <linux/string.h>
+-#include <linux/errno.h>
+-#include <linux/module.h>
+-
+-#include <asm/uaccess.h>
+-
+-/* Calculating the exact fault address when using
+- * block loads and stores can be very complicated.
+- *
+- * Instead of trying to be clever and handling all
+- * of the cases, just fix things up simply here.
+- */
+-
+-static unsigned long compute_size(unsigned long start, unsigned long size, unsigned long *offset)
+-{
+-	unsigned long fault_addr = current_thread_info()->fault_address;
+-	unsigned long end = start + size;
+-
+-	if (fault_addr < start || fault_addr >= end) {
+-		*offset = 0;
+-	} else {
+-		*offset = fault_addr - start;
+-		size = end - fault_addr;
+-	}
+-	return size;
+-}
+-
+-unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned long size)
+-{
+-	unsigned long offset;
+-
+-	size = compute_size((unsigned long) from, size, &offset);
+-	if (likely(size))
+-		memset(to + offset, 0, size);
+-
+-	return size;
+-}
+-EXPORT_SYMBOL(copy_from_user_fixup);
+-
+-unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
+-{
+-	unsigned long offset;
+-
+-	return compute_size((unsigned long) to, size, &offset);
+-}
+-EXPORT_SYMBOL(copy_to_user_fixup);
+-
+-unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
+-{
+-	unsigned long fault_addr = current_thread_info()->fault_address;
+-	unsigned long start = (unsigned long) to;
+-	unsigned long end = start + size;
+-
+-	if (fault_addr >= start && fault_addr < end)
+-		return end - fault_addr;
+-
+-	start = (unsigned long) from;
+-	end = start + size;
+-	if (fault_addr >= start && fault_addr < end)
+-		return end - fault_addr;
+-
+-	return size;
+-}
+-EXPORT_SYMBOL(copy_in_user_fixup);
+diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
+index f2b77112e9d8..e20fbbafb0b0 100644
+--- a/arch/sparc/mm/tsb.c
++++ b/arch/sparc/mm/tsb.c
+@@ -27,6 +27,20 @@ static inline int tag_compare(unsigned long tag, unsigned long vaddr)
+ 	return (tag == (vaddr >> 22));
+ }
+ 
++static void flush_tsb_kernel_range_scan(unsigned long start, unsigned long end)
++{
++	unsigned long idx;
++
++	for (idx = 0; idx < KERNEL_TSB_NENTRIES; idx++) {
++		struct tsb *ent = &swapper_tsb[idx];
++		unsigned long match = idx << 13;
++
++		match |= (ent->tag << 22);
++		if (match >= start && match < end)
++			ent->tag = (1UL << TSB_TAG_INVALID_BIT);
++	}
++}
++
+ /* TSB flushes need only occur on the processor initiating the address
+  * space modification, not on each cpu the address space has run on.
+  * Only the TLB flush needs that treatment.
+@@ -36,6 +50,9 @@ void flush_tsb_kernel_range(unsigned long start, unsigned long end)
+ {
+ 	unsigned long v;
+ 
++	if ((end - start) >> PAGE_SHIFT >= 2 * KERNEL_TSB_NENTRIES)
++		return flush_tsb_kernel_range_scan(start, end);
++
+ 	for (v = start; v < end; v += PAGE_SIZE) {
+ 		unsigned long hash = tsb_hash(v, PAGE_SHIFT,
+ 					      KERNEL_TSB_NENTRIES);
+diff --git a/arch/sparc/mm/ultra.S b/arch/sparc/mm/ultra.S
+index b4f4733abc6e..5d2fd6cd3189 100644
+--- a/arch/sparc/mm/ultra.S
++++ b/arch/sparc/mm/ultra.S
+@@ -30,7 +30,7 @@
+ 	.text
+ 	.align		32
+ 	.globl		__flush_tlb_mm
+-__flush_tlb_mm:		/* 18 insns */
++__flush_tlb_mm:		/* 19 insns */
+ 	/* %o0=(ctx & TAG_CONTEXT_BITS), %o1=SECONDARY_CONTEXT */
+ 	ldxa		[%o1] ASI_DMMU, %g2
+ 	cmp		%g2, %o0
+@@ -81,7 +81,7 @@ __flush_tlb_page:	/* 22 insns */
+ 
+ 	.align		32
+ 	.globl		__flush_tlb_pending
+-__flush_tlb_pending:	/* 26 insns */
++__flush_tlb_pending:	/* 27 insns */
+ 	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
+ 	rdpr		%pstate, %g7
+ 	sllx		%o1, 3, %o1
+@@ -113,12 +113,14 @@ __flush_tlb_pending:	/* 26 insns */
+ 
+ 	.align		32
+ 	.globl		__flush_tlb_kernel_range
+-__flush_tlb_kernel_range:	/* 16 insns */
++__flush_tlb_kernel_range:	/* 31 insns */
+ 	/* %o0=start, %o1=end */
+ 	cmp		%o0, %o1
+ 	be,pn		%xcc, 2f
++	 sub		%o1, %o0, %o3
++	srlx		%o3, 18, %o4
++	brnz,pn		%o4, __spitfire_flush_tlb_kernel_range_slow
+ 	 sethi		%hi(PAGE_SIZE), %o4
+-	sub		%o1, %o0, %o3
+ 	sub		%o3, %o4, %o3
+ 	or		%o0, 0x20, %o0		! Nucleus
+ 1:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
+@@ -131,6 +133,41 @@ __flush_tlb_kernel_range:	/* 16 insns */
+ 	retl
+ 	 nop
+ 	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++
++__spitfire_flush_tlb_kernel_range_slow:
++	mov		63 * 8, %o4
++1:	ldxa		[%o4] ASI_ITLB_DATA_ACCESS, %o3
++	andcc		%o3, 0x40, %g0			/* _PAGE_L_4U */
++	bne,pn		%xcc, 2f
++	 mov		TLB_TAG_ACCESS, %o3
++	stxa		%g0, [%o3] ASI_IMMU
++	stxa		%g0, [%o4] ASI_ITLB_DATA_ACCESS
++	membar		#Sync
++2:	ldxa		[%o4] ASI_DTLB_DATA_ACCESS, %o3
++	andcc		%o3, 0x40, %g0
++	bne,pn		%xcc, 2f
++	 mov		TLB_TAG_ACCESS, %o3
++	stxa		%g0, [%o3] ASI_DMMU
++	stxa		%g0, [%o4] ASI_DTLB_DATA_ACCESS
++	membar		#Sync
++2:	sub		%o4, 8, %o4
++	brgez,pt	%o4, 1b
++	 nop
++	retl
++	 nop
+ 
+ __spitfire_flush_tlb_mm_slow:
+ 	rdpr		%pstate, %g1
+@@ -285,6 +322,40 @@ __cheetah_flush_tlb_pending:	/* 27 insns */
+ 	retl
+ 	 wrpr		%g7, 0x0, %pstate
+ 
++__cheetah_flush_tlb_kernel_range:	/* 31 insns */
++	/* %o0=start, %o1=end */
++	cmp		%o0, %o1
++	be,pn		%xcc, 2f
++	 sub		%o1, %o0, %o3
++	srlx		%o3, 18, %o4
++	brnz,pn		%o4, 3f
++	 sethi		%hi(PAGE_SIZE), %o4
++	sub		%o3, %o4, %o3
++	or		%o0, 0x20, %o0		! Nucleus
++1:	stxa		%g0, [%o0 + %o3] ASI_DMMU_DEMAP
++	stxa		%g0, [%o0 + %o3] ASI_IMMU_DEMAP
++	membar		#Sync
++	brnz,pt		%o3, 1b
++	 sub		%o3, %o4, %o3
++2:	sethi		%hi(KERNBASE), %o3
++	flush		%o3
++	retl
++	 nop
++3:	mov		0x80, %o4
++	stxa		%g0, [%o4] ASI_DMMU_DEMAP
++	membar		#Sync
++	stxa		%g0, [%o4] ASI_IMMU_DEMAP
++	membar		#Sync
++	retl
++	 nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++
+ #ifdef DCACHE_ALIASING_POSSIBLE
+ __cheetah_flush_dcache_page: /* 11 insns */
+ 	sethi		%hi(PAGE_OFFSET), %g1
+@@ -309,19 +380,28 @@ __hypervisor_tlb_tl0_error:
+ 	ret
+ 	 restore
+ 
+-__hypervisor_flush_tlb_mm: /* 10 insns */
++__hypervisor_flush_tlb_mm: /* 19 insns */
+ 	mov		%o0, %o2	/* ARG2: mmu context */
+ 	mov		0, %o0		/* ARG0: CPU lists unimplemented */
+ 	mov		0, %o1		/* ARG1: CPU lists unimplemented */
+ 	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
+ 	mov		HV_FAST_MMU_DEMAP_CTX, %o5
+ 	ta		HV_FAST_TRAP
+-	brnz,pn		%o0, __hypervisor_tlb_tl0_error
++	brnz,pn		%o0, 1f
+ 	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
+ 	retl
+ 	 nop
++1:	sethi		%hi(__hypervisor_tlb_tl0_error), %o5
++	jmpl		%o5 + %lo(__hypervisor_tlb_tl0_error), %g0
++	 nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
+ 
+-__hypervisor_flush_tlb_page: /* 11 insns */
++__hypervisor_flush_tlb_page: /* 22 insns */
+ 	/* %o0 = context, %o1 = vaddr */
+ 	mov		%o0, %g2
+ 	mov		%o1, %o0              /* ARG0: vaddr + IMMU-bit */
+@@ -330,12 +410,23 @@ __hypervisor_flush_tlb_page: /* 11 insns */
+ 	srlx		%o0, PAGE_SHIFT, %o0
+ 	sllx		%o0, PAGE_SHIFT, %o0
+ 	ta		HV_MMU_UNMAP_ADDR_TRAP
+-	brnz,pn		%o0, __hypervisor_tlb_tl0_error
++	brnz,pn		%o0, 1f
+ 	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
+ 	retl
+ 	 nop
++1:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
++	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
++	 nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
+ 
+-__hypervisor_flush_tlb_pending: /* 16 insns */
++__hypervisor_flush_tlb_pending: /* 27 insns */
+ 	/* %o0 = context, %o1 = nr, %o2 = vaddrs[] */
+ 	sllx		%o1, 3, %g1
+ 	mov		%o2, %g2
+@@ -347,31 +438,57 @@ __hypervisor_flush_tlb_pending: /* 16 insns */
+ 	srlx		%o0, PAGE_SHIFT, %o0
+ 	sllx		%o0, PAGE_SHIFT, %o0
+ 	ta		HV_MMU_UNMAP_ADDR_TRAP
+-	brnz,pn		%o0, __hypervisor_tlb_tl0_error
++	brnz,pn		%o0, 1f
+ 	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
+ 	brnz,pt		%g1, 1b
+ 	 nop
+ 	retl
+ 	 nop
++1:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
++	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
++	 nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
+ 
+-__hypervisor_flush_tlb_kernel_range: /* 16 insns */
++__hypervisor_flush_tlb_kernel_range: /* 31 insns */
+ 	/* %o0=start, %o1=end */
+ 	cmp		%o0, %o1
+ 	be,pn		%xcc, 2f
+-	 sethi		%hi(PAGE_SIZE), %g3
+-	mov		%o0, %g1
+-	sub		%o1, %g1, %g2
++	 sub		%o1, %o0, %g2
++	srlx		%g2, 18, %g3
++	brnz,pn		%g3, 4f
++	 mov		%o0, %g1
++	sethi		%hi(PAGE_SIZE), %g3
+ 	sub		%g2, %g3, %g2
+ 1:	add		%g1, %g2, %o0	/* ARG0: virtual address */
+ 	mov		0, %o1		/* ARG1: mmu context */
+ 	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
+ 	ta		HV_MMU_UNMAP_ADDR_TRAP
+-	brnz,pn		%o0, __hypervisor_tlb_tl0_error
++	brnz,pn		%o0, 3f
+ 	 mov		HV_MMU_UNMAP_ADDR_TRAP, %o1
+ 	brnz,pt		%g2, 1b
+ 	 sub		%g2, %g3, %g2
+ 2:	retl
+ 	 nop
++3:	sethi		%hi(__hypervisor_tlb_tl0_error), %o2
++	jmpl		%o2 + %lo(__hypervisor_tlb_tl0_error), %g0
++	 nop
++4:	mov		0, %o0		/* ARG0: CPU lists unimplemented */
++	mov		0, %o1		/* ARG1: CPU lists unimplemented */
++	mov		0, %o2		/* ARG2: mmu context == nucleus */
++	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
++	mov		HV_FAST_MMU_DEMAP_CTX, %o5
++	ta		HV_FAST_TRAP
++	brnz,pn		%o0, 3b
++	 mov		HV_FAST_MMU_DEMAP_CTX, %o1
++	retl
++	 nop
+ 
+ #ifdef DCACHE_ALIASING_POSSIBLE
+ 	/* XXX Niagara and friends have an 8K cache, so no aliasing is
+@@ -394,43 +511,6 @@ tlb_patch_one:
+ 	retl
+ 	 nop
+ 
+-	.globl		cheetah_patch_cachetlbops
+-cheetah_patch_cachetlbops:
+-	save		%sp, -128, %sp
+-
+-	sethi		%hi(__flush_tlb_mm), %o0
+-	or		%o0, %lo(__flush_tlb_mm), %o0
+-	sethi		%hi(__cheetah_flush_tlb_mm), %o1
+-	or		%o1, %lo(__cheetah_flush_tlb_mm), %o1
+-	call		tlb_patch_one
+-	 mov		19, %o2
+-
+-	sethi		%hi(__flush_tlb_page), %o0
+-	or		%o0, %lo(__flush_tlb_page), %o0
+-	sethi		%hi(__cheetah_flush_tlb_page), %o1
+-	or		%o1, %lo(__cheetah_flush_tlb_page), %o1
+-	call		tlb_patch_one
+-	 mov		22, %o2
+-
+-	sethi		%hi(__flush_tlb_pending), %o0
+-	or		%o0, %lo(__flush_tlb_pending), %o0
+-	sethi		%hi(__cheetah_flush_tlb_pending), %o1
+-	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
+-	call		tlb_patch_one
+-	 mov		27, %o2
+-
+-#ifdef DCACHE_ALIASING_POSSIBLE
+-	sethi		%hi(__flush_dcache_page), %o0
+-	or		%o0, %lo(__flush_dcache_page), %o0
+-	sethi		%hi(__cheetah_flush_dcache_page), %o1
+-	or		%o1, %lo(__cheetah_flush_dcache_page), %o1
+-	call		tlb_patch_one
+-	 mov		11, %o2
+-#endif /* DCACHE_ALIASING_POSSIBLE */
+-
+-	ret
+-	 restore
+-
+ #ifdef CONFIG_SMP
+ 	/* These are all called by the slaves of a cross call, at
+ 	 * trap level 1, with interrupts fully disabled.
+@@ -447,7 +527,7 @@ cheetah_patch_cachetlbops:
+ 	 */
+ 	.align		32
+ 	.globl		xcall_flush_tlb_mm
+-xcall_flush_tlb_mm:	/* 21 insns */
++xcall_flush_tlb_mm:	/* 24 insns */
+ 	mov		PRIMARY_CONTEXT, %g2
+ 	ldxa		[%g2] ASI_DMMU, %g3
+ 	srlx		%g3, CTX_PGSZ1_NUC_SHIFT, %g4
+@@ -469,9 +549,12 @@ xcall_flush_tlb_mm:	/* 21 insns */
+ 	nop
+ 	nop
+ 	nop
++	nop
++	nop
++	nop
+ 
+ 	.globl		xcall_flush_tlb_page
+-xcall_flush_tlb_page:	/* 17 insns */
++xcall_flush_tlb_page:	/* 20 insns */
+ 	/* %g5=context, %g1=vaddr */
+ 	mov		PRIMARY_CONTEXT, %g4
+ 	ldxa		[%g4] ASI_DMMU, %g2
+@@ -490,15 +573,20 @@ xcall_flush_tlb_page:	/* 17 insns */
+ 	retry
+ 	nop
+ 	nop
++	nop
++	nop
++	nop
+ 
+ 	.globl		xcall_flush_tlb_kernel_range
+-xcall_flush_tlb_kernel_range:	/* 25 insns */
++xcall_flush_tlb_kernel_range:	/* 44 insns */
+ 	sethi		%hi(PAGE_SIZE - 1), %g2
+ 	or		%g2, %lo(PAGE_SIZE - 1), %g2
+ 	andn		%g1, %g2, %g1
+ 	andn		%g7, %g2, %g7
+ 	sub		%g7, %g1, %g3
+-	add		%g2, 1, %g2
++	srlx		%g3, 18, %g2
++	brnz,pn		%g2, 2f
++	 add		%g2, 1, %g2
+ 	sub		%g3, %g2, %g3
+ 	or		%g1, 0x20, %g1		! Nucleus
+ 1:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
+@@ -507,8 +595,25 @@ xcall_flush_tlb_kernel_range:	/* 25 insns */
+ 	brnz,pt		%g3, 1b
+ 	 sub		%g3, %g2, %g3
+ 	retry
+-	nop
+-	nop
++2:	mov		63 * 8, %g1
++1:	ldxa		[%g1] ASI_ITLB_DATA_ACCESS, %g2
++	andcc		%g2, 0x40, %g0			/* _PAGE_L_4U */
++	bne,pn		%xcc, 2f
++	 mov		TLB_TAG_ACCESS, %g2
++	stxa		%g0, [%g2] ASI_IMMU
++	stxa		%g0, [%g1] ASI_ITLB_DATA_ACCESS
++	membar		#Sync
++2:	ldxa		[%g1] ASI_DTLB_DATA_ACCESS, %g2
++	andcc		%g2, 0x40, %g0
++	bne,pn		%xcc, 2f
++	 mov		TLB_TAG_ACCESS, %g2
++	stxa		%g0, [%g2] ASI_DMMU
++	stxa		%g0, [%g1] ASI_DTLB_DATA_ACCESS
++	membar		#Sync
++2:	sub		%g1, 8, %g1
++	brgez,pt	%g1, 1b
++	 nop
++	retry
+ 	nop
+ 	nop
+ 	nop
+@@ -637,6 +742,52 @@ xcall_fetch_glob_pmu_n4:
+ 
+ 	retry
+ 
++__cheetah_xcall_flush_tlb_kernel_range:	/* 44 insns */
++	sethi		%hi(PAGE_SIZE - 1), %g2
++	or		%g2, %lo(PAGE_SIZE - 1), %g2
++	andn		%g1, %g2, %g1
++	andn		%g7, %g2, %g7
++	sub		%g7, %g1, %g3
++	srlx		%g3, 18, %g2
++	brnz,pn		%g2, 2f
++	 add		%g2, 1, %g2
++	sub		%g3, %g2, %g3
++	or		%g1, 0x20, %g1		! Nucleus
++1:	stxa		%g0, [%g1 + %g3] ASI_DMMU_DEMAP
++	stxa		%g0, [%g1 + %g3] ASI_IMMU_DEMAP
++	membar		#Sync
++	brnz,pt		%g3, 1b
++	 sub		%g3, %g2, %g3
++	retry
++2:	mov		0x80, %g2
++	stxa		%g0, [%g2] ASI_DMMU_DEMAP
++	membar		#Sync
++	stxa		%g0, [%g2] ASI_IMMU_DEMAP
++	membar		#Sync
++	retry
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++	nop
++
+ #ifdef DCACHE_ALIASING_POSSIBLE
+ 	.align		32
+ 	.globl		xcall_flush_dcache_page_cheetah
+@@ -700,7 +851,7 @@ __hypervisor_tlb_xcall_error:
+ 	ba,a,pt	%xcc, rtrap
+ 
+ 	.globl		__hypervisor_xcall_flush_tlb_mm
+-__hypervisor_xcall_flush_tlb_mm: /* 21 insns */
++__hypervisor_xcall_flush_tlb_mm: /* 24 insns */
+ 	/* %g5=ctx, g1,g2,g3,g4,g7=scratch, %g6=unusable */
+ 	mov		%o0, %g2
+ 	mov		%o1, %g3
+@@ -714,7 +865,7 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */
+ 	mov		HV_FAST_MMU_DEMAP_CTX, %o5
+ 	ta		HV_FAST_TRAP
+ 	mov		HV_FAST_MMU_DEMAP_CTX, %g6
+-	brnz,pn		%o0, __hypervisor_tlb_xcall_error
++	brnz,pn		%o0, 1f
+ 	 mov		%o0, %g5
+ 	mov		%g2, %o0
+ 	mov		%g3, %o1
+@@ -723,9 +874,12 @@ __hypervisor_xcall_flush_tlb_mm: /* 21 insns */
+ 	mov		%g7, %o5
+ 	membar		#Sync
+ 	retry
++1:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
++	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
++	 nop
+ 
+ 	.globl		__hypervisor_xcall_flush_tlb_page
+-__hypervisor_xcall_flush_tlb_page: /* 17 insns */
++__hypervisor_xcall_flush_tlb_page: /* 20 insns */
+ 	/* %g5=ctx, %g1=vaddr */
+ 	mov		%o0, %g2
+ 	mov		%o1, %g3
+@@ -737,42 +891,64 @@ __hypervisor_xcall_flush_tlb_page: /* 17 insns */
+ 	sllx		%o0, PAGE_SHIFT, %o0
+ 	ta		HV_MMU_UNMAP_ADDR_TRAP
+ 	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
+-	brnz,a,pn	%o0, __hypervisor_tlb_xcall_error
++	brnz,a,pn	%o0, 1f
+ 	 mov		%o0, %g5
+ 	mov		%g2, %o0
+ 	mov		%g3, %o1
+ 	mov		%g4, %o2
+ 	membar		#Sync
+ 	retry
++1:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
++	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
++	 nop
+ 
+ 	.globl		__hypervisor_xcall_flush_tlb_kernel_range
+-__hypervisor_xcall_flush_tlb_kernel_range: /* 25 insns */
++__hypervisor_xcall_flush_tlb_kernel_range: /* 44 insns */
+ 	/* %g1=start, %g7=end, g2,g3,g4,g5,g6=scratch */
+ 	sethi		%hi(PAGE_SIZE - 1), %g2
+ 	or		%g2, %lo(PAGE_SIZE - 1), %g2
+ 	andn		%g1, %g2, %g1
+ 	andn		%g7, %g2, %g7
+ 	sub		%g7, %g1, %g3
++	srlx		%g3, 18, %g7
+ 	add		%g2, 1, %g2
+ 	sub		%g3, %g2, %g3
+ 	mov		%o0, %g2
+ 	mov		%o1, %g4
+-	mov		%o2, %g7
++	brnz,pn		%g7, 2f
++	 mov		%o2, %g7
+ 1:	add		%g1, %g3, %o0	/* ARG0: virtual address */
+ 	mov		0, %o1		/* ARG1: mmu context */
+ 	mov		HV_MMU_ALL, %o2	/* ARG2: flags */
+ 	ta		HV_MMU_UNMAP_ADDR_TRAP
+ 	mov		HV_MMU_UNMAP_ADDR_TRAP, %g6
+-	brnz,pn		%o0, __hypervisor_tlb_xcall_error
++	brnz,pn		%o0, 1f
+ 	 mov		%o0, %g5
+ 	sethi		%hi(PAGE_SIZE), %o2
+ 	brnz,pt		%g3, 1b
+ 	 sub		%g3, %o2, %g3
+-	mov		%g2, %o0
++5:	mov		%g2, %o0
+ 	mov		%g4, %o1
+ 	mov		%g7, %o2
+ 	membar		#Sync
+ 	retry
++1:	sethi		%hi(__hypervisor_tlb_xcall_error), %g4
++	jmpl		%g4 + %lo(__hypervisor_tlb_xcall_error), %g0
++	 nop
++2:	mov		%o3, %g1
++	mov		%o5, %g3
++	mov		0, %o0		/* ARG0: CPU lists unimplemented */
++	mov		0, %o1		/* ARG1: CPU lists unimplemented */
++	mov		0, %o2		/* ARG2: mmu context == nucleus */
++	mov		HV_MMU_ALL, %o3	/* ARG3: flags */
++	mov		HV_FAST_MMU_DEMAP_CTX, %o5
++	ta		HV_FAST_TRAP
++	mov		%g1, %o3
++	brz,pt		%o0, 5b
++	 mov		%g3, %o5
++	mov		HV_FAST_MMU_DEMAP_CTX, %g6
++	ba,pt		%xcc, 1b
++	 clr		%g5
+ 
+ 	/* These just get rescheduled to PIL vectors. */
+ 	.globl		xcall_call_function
+@@ -809,6 +985,58 @@ xcall_kgdb_capture:
+ 
+ #endif /* CONFIG_SMP */
+ 
++	.globl		cheetah_patch_cachetlbops
++cheetah_patch_cachetlbops:
++	save		%sp, -128, %sp
++
++	sethi		%hi(__flush_tlb_mm), %o0
++	or		%o0, %lo(__flush_tlb_mm), %o0
++	sethi		%hi(__cheetah_flush_tlb_mm), %o1
++	or		%o1, %lo(__cheetah_flush_tlb_mm), %o1
++	call		tlb_patch_one
++	 mov		19, %o2
++
++	sethi		%hi(__flush_tlb_page), %o0
++	or		%o0, %lo(__flush_tlb_page), %o0
++	sethi		%hi(__cheetah_flush_tlb_page), %o1
++	or		%o1, %lo(__cheetah_flush_tlb_page), %o1
++	call		tlb_patch_one
++	 mov		22, %o2
++
++	sethi		%hi(__flush_tlb_pending), %o0
++	or		%o0, %lo(__flush_tlb_pending), %o0
++	sethi		%hi(__cheetah_flush_tlb_pending), %o1
++	or		%o1, %lo(__cheetah_flush_tlb_pending), %o1
++	call		tlb_patch_one
++	 mov		27, %o2
++
++	sethi		%hi(__flush_tlb_kernel_range), %o0
++	or		%o0, %lo(__flush_tlb_kernel_range), %o0
++	sethi		%hi(__cheetah_flush_tlb_kernel_range), %o1
++	or		%o1, %lo(__cheetah_flush_tlb_kernel_range), %o1
++	call		tlb_patch_one
++	 mov		31, %o2
++
++#ifdef DCACHE_ALIASING_POSSIBLE
++	sethi		%hi(__flush_dcache_page), %o0
++	or		%o0, %lo(__flush_dcache_page), %o0
++	sethi		%hi(__cheetah_flush_dcache_page), %o1
++	or		%o1, %lo(__cheetah_flush_dcache_page), %o1
++	call		tlb_patch_one
++	 mov		11, %o2
++#endif /* DCACHE_ALIASING_POSSIBLE */
++
++#ifdef CONFIG_SMP
++	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
++	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
++	sethi		%hi(__cheetah_xcall_flush_tlb_kernel_range), %o1
++	or		%o1, %lo(__cheetah_xcall_flush_tlb_kernel_range), %o1
++	call		tlb_patch_one
++	 mov		44, %o2
++#endif /* CONFIG_SMP */
++
++	ret
++	 restore
+ 
+ 	.globl		hypervisor_patch_cachetlbops
+ hypervisor_patch_cachetlbops:
+@@ -819,28 +1047,28 @@ hypervisor_patch_cachetlbops:
+ 	sethi		%hi(__hypervisor_flush_tlb_mm), %o1
+ 	or		%o1, %lo(__hypervisor_flush_tlb_mm), %o1
+ 	call		tlb_patch_one
+-	 mov		10, %o2
++	 mov		19, %o2
+ 
+ 	sethi		%hi(__flush_tlb_page), %o0
+ 	or		%o0, %lo(__flush_tlb_page), %o0
+ 	sethi		%hi(__hypervisor_flush_tlb_page), %o1
+ 	or		%o1, %lo(__hypervisor_flush_tlb_page), %o1
+ 	call		tlb_patch_one
+-	 mov		11, %o2
++	 mov		22, %o2
+ 
+ 	sethi		%hi(__flush_tlb_pending), %o0
+ 	or		%o0, %lo(__flush_tlb_pending), %o0
+ 	sethi		%hi(__hypervisor_flush_tlb_pending), %o1
+ 	or		%o1, %lo(__hypervisor_flush_tlb_pending), %o1
+ 	call		tlb_patch_one
+-	 mov		16, %o2
++	 mov		27, %o2
+ 
+ 	sethi		%hi(__flush_tlb_kernel_range), %o0
+ 	or		%o0, %lo(__flush_tlb_kernel_range), %o0
+ 	sethi		%hi(__hypervisor_flush_tlb_kernel_range), %o1
+ 	or		%o1, %lo(__hypervisor_flush_tlb_kernel_range), %o1
+ 	call		tlb_patch_one
+-	 mov		16, %o2
++	 mov		31, %o2
+ 
+ #ifdef DCACHE_ALIASING_POSSIBLE
+ 	sethi		%hi(__flush_dcache_page), %o0
+@@ -857,21 +1085,21 @@ hypervisor_patch_cachetlbops:
+ 	sethi		%hi(__hypervisor_xcall_flush_tlb_mm), %o1
+ 	or		%o1, %lo(__hypervisor_xcall_flush_tlb_mm), %o1
+ 	call		tlb_patch_one
+-	 mov		21, %o2
++	 mov		24, %o2
+ 
+ 	sethi		%hi(xcall_flush_tlb_page), %o0
+ 	or		%o0, %lo(xcall_flush_tlb_page), %o0
+ 	sethi		%hi(__hypervisor_xcall_flush_tlb_page), %o1
+ 	or		%o1, %lo(__hypervisor_xcall_flush_tlb_page), %o1
+ 	call		tlb_patch_one
+-	 mov		17, %o2
++	 mov		20, %o2
+ 
+ 	sethi		%hi(xcall_flush_tlb_kernel_range), %o0
+ 	or		%o0, %lo(xcall_flush_tlb_kernel_range), %o0
+ 	sethi		%hi(__hypervisor_xcall_flush_tlb_kernel_range), %o1
+ 	or		%o1, %lo(__hypervisor_xcall_flush_tlb_kernel_range), %o1
+ 	call		tlb_patch_one
+-	 mov		25, %o2
++	 mov		44, %o2
+ #endif /* CONFIG_SMP */
+ 
+ 	ret
+diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
+index c4751ece76f6..45e87c9cc828 100644
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -307,6 +307,10 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,
+ 	u32 ctl;
+ 
+ 	ctl = bgmac_read(bgmac, ring->mmio_base + BGMAC_DMA_RX_CTL);
++
++	/* preserve ONLY bits 16-17 from current hardware value */
++	ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
++
+ 	if (bgmac->feature_flags & BGMAC_FEAT_RX_MASK_SETUP) {
+ 		ctl &= ~BGMAC_DMA_RX_BL_MASK;
+ 		ctl |= BGMAC_DMA_RX_BL_128 << BGMAC_DMA_RX_BL_SHIFT;
+@@ -317,7 +321,6 @@ static void bgmac_dma_rx_enable(struct bgmac *bgmac,
+ 		ctl &= ~BGMAC_DMA_RX_PT_MASK;
+ 		ctl |= BGMAC_DMA_RX_PT_1 << BGMAC_DMA_RX_PT_SHIFT;
+ 	}
+-	ctl &= BGMAC_DMA_RX_ADDREXT_MASK;
+ 	ctl |= BGMAC_DMA_RX_ENABLE;
+ 	ctl |= BGMAC_DMA_RX_PARITY_DISABLE;
+ 	ctl |= BGMAC_DMA_RX_OVERFLOW_CONT;
+diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
+index 505ceaf451e2..2c850a92ab15 100644
+--- a/drivers/net/ethernet/broadcom/bnx2.c
++++ b/drivers/net/ethernet/broadcom/bnx2.c
+@@ -49,6 +49,7 @@
+ #include <linux/firmware.h>
+ #include <linux/log2.h>
+ #include <linux/aer.h>
++#include <linux/crash_dump.h>
+ 
+ #if defined(CONFIG_CNIC) || defined(CONFIG_CNIC_MODULE)
+ #define BCM_CNIC 1
+@@ -4759,15 +4760,16 @@ bnx2_setup_msix_tbl(struct bnx2 *bp)
+ 	BNX2_WR(bp, BNX2_PCI_GRC_WINDOW3_ADDR, BNX2_MSIX_PBA_ADDR);
+ }
+ 
+-static int
+-bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
++static void
++bnx2_wait_dma_complete(struct bnx2 *bp)
+ {
+ 	u32 val;
+-	int i, rc = 0;
+-	u8 old_port;
++	int i;
+ 
+-	/* Wait for the current PCI transaction to complete before
+-	 * issuing a reset. */
++	/*
++	 * Wait for the current PCI transaction to complete before
++	 * issuing a reset.
++	 */
+ 	if ((BNX2_CHIP(bp) == BNX2_CHIP_5706) ||
+ 	    (BNX2_CHIP(bp) == BNX2_CHIP_5708)) {
+ 		BNX2_WR(bp, BNX2_MISC_ENABLE_CLR_BITS,
+@@ -4791,6 +4793,21 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
+ 		}
+ 	}
+ 
++	return;
++}
++
++
++static int
++bnx2_reset_chip(struct bnx2 *bp, u32 reset_code)
++{
++	u32 val;
++	int i, rc = 0;
++	u8 old_port;
++
++	/* Wait for the current PCI transaction to complete before
++	 * issuing a reset. */
++	bnx2_wait_dma_complete(bp);
++
+ 	/* Wait for the firmware to tell us it is ok to issue a reset. */
+ 	bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1);
+ 
+@@ -6356,6 +6373,10 @@ bnx2_open(struct net_device *dev)
+ 	struct bnx2 *bp = netdev_priv(dev);
+ 	int rc;
+ 
++	rc = bnx2_request_firmware(bp);
++	if (rc < 0)
++		goto out;
++
+ 	netif_carrier_off(dev);
+ 
+ 	bnx2_disable_int(bp);
+@@ -6424,6 +6445,7 @@ open_err:
+ 	bnx2_free_irq(bp);
+ 	bnx2_free_mem(bp);
+ 	bnx2_del_napi(bp);
++	bnx2_release_firmware(bp);
+ 	goto out;
+ }
+ 
+@@ -8570,12 +8592,15 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 
+ 	pci_set_drvdata(pdev, dev);
+ 
+-	rc = bnx2_request_firmware(bp);
+-	if (rc < 0)
+-		goto error;
+-
++	/*
++	 * In-flight DMA from 1st kernel could continue going in kdump kernel.
++	 * New io-page table has been created before bnx2 does reset at open stage.
++	 * We have to wait for the in-flight DMA to complete to avoid it look up
++	 * into the newly created io-page table.
++	 */
++	if (is_kdump_kernel())
++		bnx2_wait_dma_complete(bp);
+ 
+-	bnx2_reset_chip(bp, BNX2_DRV_MSG_CODE_RESET);
+ 	memcpy(dev->dev_addr, bp->mac_addr, ETH_ALEN);
+ 
+ 	dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_SG |
+@@ -8608,7 +8633,6 @@ bnx2_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+ 	return 0;
+ 
+ error:
+-	bnx2_release_firmware(bp);
+ 	pci_iounmap(pdev, bp->regview);
+ 	pci_release_regions(pdev);
+ 	pci_disable_device(pdev);
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+index d48873bcbddf..5cdc96bdd444 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+@@ -231,7 +231,7 @@ mlxsw_sp_span_entry_create(struct mlxsw_sp_port *port)
+ 
+ 	span_entry->used = true;
+ 	span_entry->id = index;
+-	span_entry->ref_count = 0;
++	span_entry->ref_count = 1;
+ 	span_entry->local_port = local_port;
+ 	return span_entry;
+ }
+@@ -268,6 +268,7 @@ struct mlxsw_sp_span_entry *mlxsw_sp_span_entry_get(struct mlxsw_sp_port *port)
+ 
+ 	span_entry = mlxsw_sp_span_entry_find(port);
+ 	if (span_entry) {
++		/* Already exists, just take a reference */
+ 		span_entry->ref_count++;
+ 		return span_entry;
+ 	}
+@@ -278,6 +279,7 @@ struct mlxsw_sp_span_entry *mlxsw_sp_span_entry_get(struct mlxsw_sp_port *port)
+ static int mlxsw_sp_span_entry_put(struct mlxsw_sp *mlxsw_sp,
+ 				   struct mlxsw_sp_span_entry *span_entry)
+ {
++	WARN_ON(!span_entry->ref_count);
+ 	if (--span_entry->ref_count == 0)
+ 		mlxsw_sp_span_entry_destroy(mlxsw_sp, span_entry);
+ 	return 0;
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+index 3f5c51da6d3e..62514b9bf988 100644
+--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
++++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+@@ -777,6 +777,26 @@ static void mlxsw_sp_router_neigh_rec_process(struct mlxsw_sp *mlxsw_sp,
+ 	}
+ }
+ 
++static bool mlxsw_sp_router_rauhtd_is_full(char *rauhtd_pl)
++{
++	u8 num_rec, last_rec_index, num_entries;
++
++	num_rec = mlxsw_reg_rauhtd_num_rec_get(rauhtd_pl);
++	last_rec_index = num_rec - 1;
++
++	if (num_rec < MLXSW_REG_RAUHTD_REC_MAX_NUM)
++		return false;
++	if (mlxsw_reg_rauhtd_rec_type_get(rauhtd_pl, last_rec_index) ==
++	    MLXSW_REG_RAUHTD_TYPE_IPV6)
++		return true;
++
++	num_entries = mlxsw_reg_rauhtd_ipv4_rec_num_entries_get(rauhtd_pl,
++								last_rec_index);
++	if (++num_entries == MLXSW_REG_RAUHTD_IPV4_ENT_PER_REC)
++		return true;
++	return false;
++}
++
+ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
+ {
+ 	char *rauhtd_pl;
+@@ -803,7 +823,7 @@ static int mlxsw_sp_router_neighs_update_rauhtd(struct mlxsw_sp *mlxsw_sp)
+ 		for (i = 0; i < num_rec; i++)
+ 			mlxsw_sp_router_neigh_rec_process(mlxsw_sp, rauhtd_pl,
+ 							  i);
+-	} while (num_rec);
++	} while (mlxsw_sp_router_rauhtd_is_full(rauhtd_pl));
+ 	rtnl_unlock();
+ 
+ 	kfree(rauhtd_pl);
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+index 4c8c60af7985..fe9e7b1979b8 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+@@ -871,6 +871,13 @@ static int stmmac_init_phy(struct net_device *dev)
+ 		return -ENODEV;
+ 	}
+ 
++	/* stmmac_adjust_link will change this to PHY_IGNORE_INTERRUPT to avoid
++	 * subsequent PHY polling, make sure we force a link transition if
++	 * we have a UP/DOWN/UP transition
++	 */
++	if (phydev->is_pseudo_fixed_link)
++		phydev->irq = PHY_POLL;
++
+ 	pr_debug("stmmac_init_phy:  %s: attached to PHY (UID 0x%x)"
+ 		 " Link = %d\n", dev->name, phydev->phy_id, phydev->link);
+ 
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index 5c8429f23a89..3a5530d0511b 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -133,8 +133,60 @@ struct ffs_epfile {
+ 	/*
+ 	 * Buffer for holding data from partial reads which may happen since
+ 	 * we’re rounding user read requests to a multiple of a max packet size.
++	 *
++	 * The pointer is initialised with NULL value and may be set by
++	 * __ffs_epfile_read_data function to point to a temporary buffer.
++	 *
++	 * In normal operation, calls to __ffs_epfile_read_buffered will consume
++	 * data from said buffer and eventually free it.  Importantly, while the
++	 * function is using the buffer, it sets the pointer to NULL.  This is
++	 * all right since __ffs_epfile_read_data and __ffs_epfile_read_buffered
++	 * can never run concurrently (they are synchronised by epfile->mutex)
++	 * so the latter will not assign a new value to the pointer.
++	 *
++	 * Meanwhile ffs_func_eps_disable frees the buffer (if the pointer is
++	 * valid) and sets the pointer to READ_BUFFER_DROP value.  This special
++	 * value is crux of the synchronisation between ffs_func_eps_disable and
++	 * __ffs_epfile_read_data.
++	 *
++	 * Once __ffs_epfile_read_data is about to finish it will try to set the
++	 * pointer back to its old value (as described above), but seeing as the
++	 * pointer is not-NULL (namely READ_BUFFER_DROP) it will instead free
++	 * the buffer.
++	 *
++	 * == State transitions ==
++	 *
++	 * • ptr == NULL:  (initial state)
++	 *   ◦ __ffs_epfile_read_buffer_free: go to ptr == DROP
++	 *   ◦ __ffs_epfile_read_buffered:    nop
++	 *   ◦ __ffs_epfile_read_data allocates temp buffer: go to ptr == buf
++	 *   ◦ reading finishes:              n/a, not in ‘and reading’ state
++	 * • ptr == DROP:
++	 *   ◦ __ffs_epfile_read_buffer_free: nop
++	 *   ◦ __ffs_epfile_read_buffered:    go to ptr == NULL
++	 *   ◦ __ffs_epfile_read_data allocates temp buffer: free buf, nop
++	 *   ◦ reading finishes:              n/a, not in ‘and reading’ state
++	 * • ptr == buf:
++	 *   ◦ __ffs_epfile_read_buffer_free: free buf, go to ptr == DROP
++	 *   ◦ __ffs_epfile_read_buffered:    go to ptr == NULL and reading
++	 *   ◦ __ffs_epfile_read_data:        n/a, __ffs_epfile_read_buffered
++	 *                                    is always called first
++	 *   ◦ reading finishes:              n/a, not in ‘and reading’ state
++	 * • ptr == NULL and reading:
++	 *   ◦ __ffs_epfile_read_buffer_free: go to ptr == DROP and reading
++	 *   ◦ __ffs_epfile_read_buffered:    n/a, mutex is held
++	 *   ◦ __ffs_epfile_read_data:        n/a, mutex is held
++	 *   ◦ reading finishes and …
++	 *     … all data read:               free buf, go to ptr == NULL
++	 *     … otherwise:                   go to ptr == buf and reading
++	 * • ptr == DROP and reading:
++	 *   ◦ __ffs_epfile_read_buffer_free: nop
++	 *   ◦ __ffs_epfile_read_buffered:    n/a, mutex is held
++	 *   ◦ __ffs_epfile_read_data:        n/a, mutex is held
++	 *   ◦ reading finishes:              free buf, go to ptr == DROP
+ 	 */
+-	struct ffs_buffer		*read_buffer;	/* P: epfile->mutex */
++	struct ffs_buffer		*read_buffer;
++#define READ_BUFFER_DROP ((struct ffs_buffer *)ERR_PTR(-ESHUTDOWN))
+ 
+ 	char				name[5];
+ 
+@@ -733,25 +785,47 @@ static void ffs_epfile_async_io_complete(struct usb_ep *_ep,
+ 	schedule_work(&io_data->work);
+ }
+ 
++static void __ffs_epfile_read_buffer_free(struct ffs_epfile *epfile)
++{
++	/*
++	 * See comment in struct ffs_epfile for full read_buffer pointer
++	 * synchronisation story.
++	 */
++	struct ffs_buffer *buf = xchg(&epfile->read_buffer, READ_BUFFER_DROP);
++	if (buf && buf != READ_BUFFER_DROP)
++		kfree(buf);
++}
++
+ /* Assumes epfile->mutex is held. */
+ static ssize_t __ffs_epfile_read_buffered(struct ffs_epfile *epfile,
+ 					  struct iov_iter *iter)
+ {
+-	struct ffs_buffer *buf = epfile->read_buffer;
++	/*
++	 * Null out epfile->read_buffer so ffs_func_eps_disable does not free
++	 * the buffer while we are using it.  See comment in struct ffs_epfile
++	 * for full read_buffer pointer synchronisation story.
++	 */
++	struct ffs_buffer *buf = xchg(&epfile->read_buffer, NULL);
+ 	ssize_t ret;
+-	if (!buf)
++	if (!buf || buf == READ_BUFFER_DROP)
+ 		return 0;
+ 
+ 	ret = copy_to_iter(buf->data, buf->length, iter);
+ 	if (buf->length == ret) {
+ 		kfree(buf);
+-		epfile->read_buffer = NULL;
+-	} else if (unlikely(iov_iter_count(iter))) {
++		return ret;
++	}
++
++	if (unlikely(iov_iter_count(iter))) {
+ 		ret = -EFAULT;
+ 	} else {
+ 		buf->length -= ret;
+ 		buf->data += ret;
+ 	}
++
++	if (cmpxchg(&epfile->read_buffer, NULL, buf))
++		kfree(buf);
++
+ 	return ret;
+ }
+ 
+@@ -780,7 +854,15 @@ static ssize_t __ffs_epfile_read_data(struct ffs_epfile *epfile,
+ 	buf->length = data_len;
+ 	buf->data = buf->storage;
+ 	memcpy(buf->storage, data + ret, data_len);
+-	epfile->read_buffer = buf;
++
++	/*
++	 * At this point read_buffer is NULL or READ_BUFFER_DROP (if
++	 * ffs_func_eps_disable has been called in the meanwhile).  See comment
++	 * in struct ffs_epfile for full read_buffer pointer synchronisation
++	 * story.
++	 */
++	if (unlikely(cmpxchg(&epfile->read_buffer, NULL, buf)))
++		kfree(buf);
+ 
+ 	return ret;
+ }
+@@ -1094,8 +1176,7 @@ ffs_epfile_release(struct inode *inode, struct file *file)
+ 
+ 	ENTER();
+ 
+-	kfree(epfile->read_buffer);
+-	epfile->read_buffer = NULL;
++	__ffs_epfile_read_buffer_free(epfile);
+ 	ffs_data_closed(epfile->ffs);
+ 
+ 	return 0;
+@@ -1721,24 +1802,20 @@ static void ffs_func_eps_disable(struct ffs_function *func)
+ 	unsigned count            = func->ffs->eps_count;
+ 	unsigned long flags;
+ 
++	spin_lock_irqsave(&func->ffs->eps_lock, flags);
+ 	do {
+-		if (epfile)
+-			mutex_lock(&epfile->mutex);
+-		spin_lock_irqsave(&func->ffs->eps_lock, flags);
+ 		/* pending requests get nuked */
+ 		if (likely(ep->ep))
+ 			usb_ep_disable(ep->ep);
+ 		++ep;
+-		spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
+ 
+ 		if (epfile) {
+ 			epfile->ep = NULL;
+-			kfree(epfile->read_buffer);
+-			epfile->read_buffer = NULL;
+-			mutex_unlock(&epfile->mutex);
++			__ffs_epfile_read_buffer_free(epfile);
+ 			++epfile;
+ 		}
+ 	} while (--count);
++	spin_unlock_irqrestore(&func->ffs->eps_lock, flags);
+ }
+ 
+ static int ffs_func_eps_enable(struct ffs_function *func)
+diff --git a/include/net/ip.h b/include/net/ip.h
+index 156b0c11b524..0ccf6daf6f56 100644
+--- a/include/net/ip.h
++++ b/include/net/ip.h
+@@ -47,7 +47,6 @@ struct inet_skb_parm {
+ #define IPSKB_REROUTED		BIT(4)
+ #define IPSKB_DOREDIRECT	BIT(5)
+ #define IPSKB_FRAG_PMTU		BIT(6)
+-#define IPSKB_FRAG_SEGS		BIT(7)
+ 
+ 	u16			frag_max_size;
+ };
+diff --git a/include/net/ip6_tunnel.h b/include/net/ip6_tunnel.h
+index 43a5a0e4524c..b01d5d1d7439 100644
+--- a/include/net/ip6_tunnel.h
++++ b/include/net/ip6_tunnel.h
+@@ -145,6 +145,7 @@ static inline void ip6tunnel_xmit(struct sock *sk, struct sk_buff *skb,
+ {
+ 	int pkt_len, err;
+ 
++	memset(skb->cb, 0, sizeof(struct inet6_skb_parm));
+ 	pkt_len = skb->len - skb_inner_network_offset(skb);
+ 	err = ip6_local_out(dev_net(skb_dst(skb)->dev), sk, skb);
+ 	if (unlikely(net_xmit_eval(err)))
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 8741988e6880..c26eab962ec7 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1587,11 +1587,11 @@ static inline void sock_put(struct sock *sk)
+ void sock_gen_put(struct sock *sk);
+ 
+ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb, const int nested,
+-		     unsigned int trim_cap);
++		     unsigned int trim_cap, bool refcounted);
+ static inline int sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+ 				 const int nested)
+ {
+-	return __sk_receive_skb(sk, skb, nested, 1);
++	return __sk_receive_skb(sk, skb, nested, 1, true);
+ }
+ 
+ static inline void sk_tx_queue_set(struct sock *sk, int tx_queue)
+diff --git a/include/net/tcp.h b/include/net/tcp.h
+index 7717302cab91..0de698940793 100644
+--- a/include/net/tcp.h
++++ b/include/net/tcp.h
+@@ -1164,6 +1164,7 @@ static inline void tcp_prequeue_init(struct tcp_sock *tp)
+ }
+ 
+ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb);
++int tcp_filter(struct sock *sk, struct sk_buff *skb);
+ 
+ #undef STATE_TRACE
+ 
+diff --git a/include/uapi/linux/atm_zatm.h b/include/uapi/linux/atm_zatm.h
+index 5cd4d4d2dd1d..9c9c6ad55f14 100644
+--- a/include/uapi/linux/atm_zatm.h
++++ b/include/uapi/linux/atm_zatm.h
+@@ -14,7 +14,6 @@
+ 
+ #include <linux/atmapi.h>
+ #include <linux/atmioc.h>
+-#include <linux/time.h>
+ 
+ #define ZATM_GETPOOL	_IOW('a',ATMIOC_SARPRV+1,struct atmif_sioc)
+ 						/* get pool statistics */
+diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
+index 570eeca7bdfa..ad1bc67aff1b 100644
+--- a/kernel/bpf/hashtab.c
++++ b/kernel/bpf/hashtab.c
+@@ -687,7 +687,8 @@ static void delete_all_elements(struct bpf_htab *htab)
+ 
+ 		hlist_for_each_entry_safe(l, n, head, hash_node) {
+ 			hlist_del_rcu(&l->hash_node);
+-			htab_elem_free(htab, l);
++			if (l->state != HTAB_EXTRA_ELEM_USED)
++				htab_elem_free(htab, l);
+ 		}
+ 	}
+ }
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 44b3ba462ba1..9ce9d7284ea7 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2484,7 +2484,7 @@ int skb_checksum_help(struct sk_buff *skb)
+ 			goto out;
+ 	}
+ 
+-	*(__sum16 *)(skb->data + offset) = csum_fold(csum);
++	*(__sum16 *)(skb->data + offset) = csum_fold(csum) ?: CSUM_MANGLED_0;
+ out_set_summed:
+ 	skb->ip_summed = CHECKSUM_NONE;
+ out:
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 52742a02814f..5550a86f7264 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -118,7 +118,7 @@ bool __skb_flow_dissect(const struct sk_buff *skb,
+ 	struct flow_dissector_key_tags *key_tags;
+ 	struct flow_dissector_key_keyid *key_keyid;
+ 	u8 ip_proto = 0;
+-	bool ret = false;
++	bool ret;
+ 
+ 	if (!data) {
+ 		data = skb->data;
+@@ -481,12 +481,17 @@ ip_proto_again:
+ out_good:
+ 	ret = true;
+ 
+-out_bad:
++	key_control->thoff = (u16)nhoff;
++out:
+ 	key_basic->n_proto = proto;
+ 	key_basic->ip_proto = ip_proto;
+-	key_control->thoff = (u16)nhoff;
+ 
+ 	return ret;
++
++out_bad:
++	ret = false;
++	key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen);
++	goto out;
+ }
+ EXPORT_SYMBOL(__skb_flow_dissect);
+ 
+diff --git a/net/core/sock.c b/net/core/sock.c
+index fd7b41edf1ce..10acaccca5c8 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -453,7 +453,7 @@ int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ EXPORT_SYMBOL(sock_queue_rcv_skb);
+ 
+ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+-		     const int nested, unsigned int trim_cap)
++		     const int nested, unsigned int trim_cap, bool refcounted)
+ {
+ 	int rc = NET_RX_SUCCESS;
+ 
+@@ -487,7 +487,8 @@ int __sk_receive_skb(struct sock *sk, struct sk_buff *skb,
+ 
+ 	bh_unlock_sock(sk);
+ out:
+-	sock_put(sk);
++	if (refcounted)
++		sock_put(sk);
+ 	return rc;
+ discard_and_relse:
+ 	kfree_skb(skb);
+@@ -1563,6 +1564,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
+ 		RCU_INIT_POINTER(newsk->sk_reuseport_cb, NULL);
+ 
+ 		newsk->sk_err	   = 0;
++		newsk->sk_err_soft = 0;
+ 		newsk->sk_priority = 0;
+ 		newsk->sk_incoming_cpu = raw_smp_processor_id();
+ 		atomic64_set(&newsk->sk_cookie, 0);
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index 345a3aeb8c7e..b567c8725aea 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -235,7 +235,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
+ {
+ 	const struct iphdr *iph = (struct iphdr *)skb->data;
+ 	const u8 offset = iph->ihl << 2;
+-	const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
++	const struct dccp_hdr *dh;
+ 	struct dccp_sock *dp;
+ 	struct inet_sock *inet;
+ 	const int type = icmp_hdr(skb)->type;
+@@ -245,11 +245,13 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
+ 	int err;
+ 	struct net *net = dev_net(skb->dev);
+ 
+-	if (skb->len < offset + sizeof(*dh) ||
+-	    skb->len < offset + __dccp_basic_hdr_len(dh)) {
+-		__ICMP_INC_STATS(net, ICMP_MIB_INERRORS);
+-		return;
+-	}
++	/* Only need dccph_dport & dccph_sport which are the first
++	 * 4 bytes in dccp header.
++	 * Our caller (icmp_socket_deliver()) already pulled 8 bytes for us.
++	 */
++	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
++	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
++	dh = (struct dccp_hdr *)(skb->data + offset);
+ 
+ 	sk = __inet_lookup_established(net, &dccp_hashinfo,
+ 				       iph->daddr, dh->dccph_dport,
+@@ -868,7 +870,7 @@ lookup:
+ 		goto discard_and_relse;
+ 	nf_reset(skb);
+ 
+-	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4);
++	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4, refcounted);
+ 
+ no_dccp_socket:
+ 	if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
+diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
+index 3828f94b234c..715e5d1dc107 100644
+--- a/net/dccp/ipv6.c
++++ b/net/dccp/ipv6.c
+@@ -70,7 +70,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ 			u8 type, u8 code, int offset, __be32 info)
+ {
+ 	const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data;
+-	const struct dccp_hdr *dh = (struct dccp_hdr *)(skb->data + offset);
++	const struct dccp_hdr *dh;
+ 	struct dccp_sock *dp;
+ 	struct ipv6_pinfo *np;
+ 	struct sock *sk;
+@@ -78,12 +78,13 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
+ 	__u64 seq;
+ 	struct net *net = dev_net(skb->dev);
+ 
+-	if (skb->len < offset + sizeof(*dh) ||
+-	    skb->len < offset + __dccp_basic_hdr_len(dh)) {
+-		__ICMP6_INC_STATS(net, __in6_dev_get(skb->dev),
+-				  ICMP6_MIB_INERRORS);
+-		return;
+-	}
++	/* Only need dccph_dport & dccph_sport which are the first
++	 * 4 bytes in dccp header.
++	 * Our caller (icmpv6_notify()) already pulled 8 bytes for us.
++	 */
++	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_sport) > 8);
++	BUILD_BUG_ON(offsetofend(struct dccp_hdr, dccph_dport) > 8);
++	dh = (struct dccp_hdr *)(skb->data + offset);
+ 
+ 	sk = __inet6_lookup_established(net, &dccp_hashinfo,
+ 					&hdr->daddr, dh->dccph_dport,
+@@ -738,7 +739,8 @@ lookup:
+ 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
+ 		goto discard_and_relse;
+ 
+-	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4) ? -1 : 0;
++	return __sk_receive_skb(sk, skb, 1, dh->dccph_doff * 4,
++				refcounted) ? -1 : 0;
+ 
+ no_dccp_socket:
+ 	if (!xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb))
+@@ -956,6 +958,7 @@ static const struct inet_connection_sock_af_ops dccp_ipv6_mapped = {
+ 	.getsockopt	   = ipv6_getsockopt,
+ 	.addr2sockaddr	   = inet6_csk_addr2sockaddr,
+ 	.sockaddr_len	   = sizeof(struct sockaddr_in6),
++	.bind_conflict	   = inet6_csk_bind_conflict,
+ #ifdef CONFIG_COMPAT
+ 	.compat_setsockopt = compat_ipv6_setsockopt,
+ 	.compat_getsockopt = compat_ipv6_getsockopt,
+diff --git a/net/dccp/proto.c b/net/dccp/proto.c
+index 41e65804ddf5..9fe25bf63296 100644
+--- a/net/dccp/proto.c
++++ b/net/dccp/proto.c
+@@ -1009,6 +1009,10 @@ void dccp_close(struct sock *sk, long timeout)
+ 		__kfree_skb(skb);
+ 	}
+ 
++	/* If socket has been already reset kill it. */
++	if (sk->sk_state == DCCP_CLOSED)
++		goto adjudge_to_death;
++
+ 	if (data_was_unread) {
+ 		/* Unread data was tossed, send an appropriate Reset Code */
+ 		DCCP_WARN("ABORT with %u bytes unread\n", data_was_unread);
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index e2ffc2a5c7db..7ef703102dca 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -2455,22 +2455,19 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
+ 	struct key_vector *l, **tp = &iter->tnode;
+ 	t_key key;
+ 
+-	/* use cache location of next-to-find key */
++	/* use cached location of previously found key */
+ 	if (iter->pos > 0 && pos >= iter->pos) {
+-		pos -= iter->pos;
+ 		key = iter->key;
+ 	} else {
+-		iter->pos = 0;
++		iter->pos = 1;
+ 		key = 0;
+ 	}
+ 
+-	while ((l = leaf_walk_rcu(tp, key)) != NULL) {
++	pos -= iter->pos;
++
++	while ((l = leaf_walk_rcu(tp, key)) && (pos-- > 0)) {
+ 		key = l->key + 1;
+ 		iter->pos++;
+-
+-		if (--pos <= 0)
+-			break;
+-
+ 		l = NULL;
+ 
+ 		/* handle unlikely case of a key wrap */
+@@ -2479,7 +2476,7 @@ static struct key_vector *fib_route_get_idx(struct fib_route_iter *iter,
+ 	}
+ 
+ 	if (l)
+-		iter->key = key;	/* remember it */
++		iter->key = l->key;	/* remember it */
+ 	else
+ 		iter->pos = 0;		/* forget it */
+ 
+@@ -2507,7 +2504,7 @@ static void *fib_route_seq_start(struct seq_file *seq, loff_t *pos)
+ 		return fib_route_get_idx(iter, *pos);
+ 
+ 	iter->pos = 0;
+-	iter->key = 0;
++	iter->key = KEY_MAX;
+ 
+ 	return SEQ_START_TOKEN;
+ }
+@@ -2516,7 +2513,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ {
+ 	struct fib_route_iter *iter = seq->private;
+ 	struct key_vector *l = NULL;
+-	t_key key = iter->key;
++	t_key key = iter->key + 1;
+ 
+ 	++*pos;
+ 
+@@ -2525,7 +2522,7 @@ static void *fib_route_seq_next(struct seq_file *seq, void *v, loff_t *pos)
+ 		l = leaf_walk_rcu(&iter->tnode, key);
+ 
+ 	if (l) {
+-		iter->key = l->key + 1;
++		iter->key = l->key;
+ 		iter->pos++;
+ 	} else {
+ 		iter->pos = 0;
+diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
+index 38abe70e595f..48734ee6293f 100644
+--- a/net/ipv4/icmp.c
++++ b/net/ipv4/icmp.c
+@@ -477,7 +477,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
+ 	fl4->flowi4_proto = IPPROTO_ICMP;
+ 	fl4->fl4_icmp_type = type;
+ 	fl4->fl4_icmp_code = code;
+-	fl4->flowi4_oif = l3mdev_master_ifindex(skb_in->dev);
++	fl4->flowi4_oif = l3mdev_master_ifindex(skb_dst(skb_in)->dev);
+ 
+ 	security_skb_classify_flow(skb_in, flowi4_to_flowi(fl4));
+ 	rt = __ip_route_output_key_hash(net, fl4,
+@@ -502,7 +502,7 @@ static struct rtable *icmp_route_lookup(struct net *net,
+ 	if (err)
+ 		goto relookup_failed;
+ 
+-	if (inet_addr_type_dev_table(net, skb_in->dev,
++	if (inet_addr_type_dev_table(net, skb_dst(skb_in)->dev,
+ 				     fl4_dec.saddr) == RTN_LOCAL) {
+ 		rt2 = __ip_route_output_key(net, &fl4_dec);
+ 		if (IS_ERR(rt2))
+diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
+index 8b4ffd216839..9f0a7b96646f 100644
+--- a/net/ipv4/ip_forward.c
++++ b/net/ipv4/ip_forward.c
+@@ -117,7 +117,7 @@ int ip_forward(struct sk_buff *skb)
+ 	if (opt->is_strictroute && rt->rt_uses_gateway)
+ 		goto sr_failed;
+ 
+-	IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
++	IPCB(skb)->flags |= IPSKB_FORWARDED;
+ 	mtu = ip_dst_mtu_maybe_forward(&rt->dst, true);
+ 	if (ip_exceeds_mtu(skb, mtu)) {
+ 		IP_INC_STATS(net, IPSTATS_MIB_FRAGFAILS);
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index dde37fb340bf..307daed9a4b9 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -223,11 +223,9 @@ static int ip_finish_output_gso(struct net *net, struct sock *sk,
+ 	struct sk_buff *segs;
+ 	int ret = 0;
+ 
+-	/* common case: fragmentation of segments is not allowed,
+-	 * or seglen is <= mtu
++	/* common case: seglen is <= mtu
+ 	 */
+-	if (((IPCB(skb)->flags & IPSKB_FRAG_SEGS) == 0) ||
+-	      skb_gso_validate_mtu(skb, mtu))
++	if (skb_gso_validate_mtu(skb, mtu))
+ 		return ip_finish_output2(net, sk, skb);
+ 
+ 	/* Slowpath -  GSO segment length is exceeding the dst MTU.
+diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
+index 0f227db0e9ac..afd6b5968caf 100644
+--- a/net/ipv4/ip_tunnel_core.c
++++ b/net/ipv4/ip_tunnel_core.c
+@@ -63,7 +63,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
+ 	int pkt_len = skb->len - skb_inner_network_offset(skb);
+ 	struct net *net = dev_net(rt->dst.dev);
+ 	struct net_device *dev = skb->dev;
+-	int skb_iif = skb->skb_iif;
+ 	struct iphdr *iph;
+ 	int err;
+ 
+@@ -73,16 +72,6 @@ void iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
+ 	skb_dst_set(skb, &rt->dst);
+ 	memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+ 
+-	if (skb_iif && !(df & htons(IP_DF))) {
+-		/* Arrived from an ingress interface, got encapsulated, with
+-		 * fragmentation of encapulating frames allowed.
+-		 * If skb is gso, the resulting encapsulated network segments
+-		 * may exceed dst mtu.
+-		 * Allow IP Fragmentation of segments.
+-		 */
+-		IPCB(skb)->flags |= IPSKB_FRAG_SEGS;
+-	}
+-
+ 	/* Push down and install the IP header. */
+ 	skb_push(skb, sizeof(struct iphdr));
+ 	skb_reset_network_header(skb);
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 5f006e13de56..27089f5ebbb1 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -1749,7 +1749,7 @@ static void ipmr_queue_xmit(struct net *net, struct mr_table *mrt,
+ 		vif->dev->stats.tx_bytes += skb->len;
+ 	}
+ 
+-	IPCB(skb)->flags |= IPSKB_FORWARDED | IPSKB_FRAG_SEGS;
++	IPCB(skb)->flags |= IPSKB_FORWARDED;
+ 
+ 	/* RFC1584 teaches, that DVMRP/PIM router must deliver packets locally
+ 	 * not only before forwarding, but after forwarding on all output
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index 62c3ed0b7556..2f23ef1a8486 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -753,7 +753,9 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
+ 			goto reject_redirect;
+ 	}
+ 
+-	n = ipv4_neigh_lookup(&rt->dst, NULL, &new_gw);
++	n = __ipv4_neigh_lookup(rt->dst.dev, new_gw);
++	if (!n)
++		n = neigh_create(&arp_tbl, &new_gw, rt->dst.dev);
+ 	if (!IS_ERR(n)) {
+ 		if (!(n->nud_state & NUD_VALID)) {
+ 			neigh_event_send(n, NULL);
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index ffbb218de520..c876f5ddc86c 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -1145,7 +1145,7 @@ restart:
+ 
+ 	err = -EPIPE;
+ 	if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN))
+-		goto out_err;
++		goto do_error;
+ 
+ 	sg = !!(sk->sk_route_caps & NETIF_F_SG);
+ 
+@@ -1219,7 +1219,7 @@ new_segment:
+ 
+ 			if (!skb_can_coalesce(skb, i, pfrag->page,
+ 					      pfrag->offset)) {
+-				if (i == sysctl_max_skb_frags || !sg) {
++				if (i >= sysctl_max_skb_frags || !sg) {
+ 					tcp_mark_push(tp, skb);
+ 					goto new_segment;
+ 				}
+diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c
+index 10d728b6804c..ab37c6775630 100644
+--- a/net/ipv4/tcp_dctcp.c
++++ b/net/ipv4/tcp_dctcp.c
+@@ -56,6 +56,7 @@ struct dctcp {
+ 	u32 next_seq;
+ 	u32 ce_state;
+ 	u32 delayed_ack_reserved;
++	u32 loss_cwnd;
+ };
+ 
+ static unsigned int dctcp_shift_g __read_mostly = 4; /* g = 1/2^4 */
+@@ -96,6 +97,7 @@ static void dctcp_init(struct sock *sk)
+ 		ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA);
+ 
+ 		ca->delayed_ack_reserved = 0;
++		ca->loss_cwnd = 0;
+ 		ca->ce_state = 0;
+ 
+ 		dctcp_reset(tp, ca);
+@@ -111,9 +113,10 @@ static void dctcp_init(struct sock *sk)
+ 
+ static u32 dctcp_ssthresh(struct sock *sk)
+ {
+-	const struct dctcp *ca = inet_csk_ca(sk);
++	struct dctcp *ca = inet_csk_ca(sk);
+ 	struct tcp_sock *tp = tcp_sk(sk);
+ 
++	ca->loss_cwnd = tp->snd_cwnd;
+ 	return max(tp->snd_cwnd - ((tp->snd_cwnd * ca->dctcp_alpha) >> 11U), 2U);
+ }
+ 
+@@ -308,12 +311,20 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr,
+ 	return 0;
+ }
+ 
++static u32 dctcp_cwnd_undo(struct sock *sk)
++{
++	const struct dctcp *ca = inet_csk_ca(sk);
++
++	return max(tcp_sk(sk)->snd_cwnd, ca->loss_cwnd);
++}
++
+ static struct tcp_congestion_ops dctcp __read_mostly = {
+ 	.init		= dctcp_init,
+ 	.in_ack_event   = dctcp_update_alpha,
+ 	.cwnd_event	= dctcp_cwnd_event,
+ 	.ssthresh	= dctcp_ssthresh,
+ 	.cong_avoid	= tcp_reno_cong_avoid,
++	.undo_cwnd	= dctcp_cwnd_undo,
+ 	.set_state	= dctcp_state,
+ 	.get_info	= dctcp_get_info,
+ 	.flags		= TCP_CONG_NEEDS_ECN,
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index 7158d4f8dae4..7b235fa12903 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -1537,6 +1537,21 @@ bool tcp_prequeue(struct sock *sk, struct sk_buff *skb)
+ }
+ EXPORT_SYMBOL(tcp_prequeue);
+ 
++int tcp_filter(struct sock *sk, struct sk_buff *skb)
++{
++	struct tcphdr *th = (struct tcphdr *)skb->data;
++	unsigned int eaten = skb->len;
++	int err;
++
++	err = sk_filter_trim_cap(sk, skb, th->doff * 4);
++	if (!err) {
++		eaten -= skb->len;
++		TCP_SKB_CB(skb)->end_seq -= eaten;
++	}
++	return err;
++}
++EXPORT_SYMBOL(tcp_filter);
++
+ /*
+  *	From tcp_input.c
+  */
+@@ -1648,8 +1663,10 @@ process:
+ 
+ 	nf_reset(skb);
+ 
+-	if (sk_filter(sk, skb))
++	if (tcp_filter(sk, skb))
+ 		goto discard_and_relse;
++	th = (const struct tcphdr *)skb->data;
++	iph = ip_hdr(skb);
+ 
+ 	skb->dev = NULL;
+ 
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
+index bd59c343d35f..7370ad2e693a 100644
+--- a/net/ipv6/icmp.c
++++ b/net/ipv6/icmp.c
+@@ -448,7 +448,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info,
+ 	if (__ipv6_addr_needs_scope_id(addr_type))
+ 		iif = skb->dev->ifindex;
+ 	else
+-		iif = l3mdev_master_ifindex(skb->dev);
++		iif = l3mdev_master_ifindex(skb_dst(skb)->dev);
+ 
+ 	/*
+ 	 *	Must not send error if the source does not uniquely
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index fc67822c42e0..af6a09efad5b 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1228,7 +1228,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
+ 	if (skb->protocol == htons(ETH_P_IP))
+ 		return tcp_v4_do_rcv(sk, skb);
+ 
+-	if (sk_filter(sk, skb))
++	if (tcp_filter(sk, skb))
+ 		goto discard;
+ 
+ 	/*
+@@ -1455,8 +1455,10 @@ process:
+ 	if (tcp_v6_inbound_md5_hash(sk, skb))
+ 		goto discard_and_relse;
+ 
+-	if (sk_filter(sk, skb))
++	if (tcp_filter(sk, skb))
+ 		goto discard_and_relse;
++	th = (const struct tcphdr *)skb->data;
++	hdr = ipv6_hdr(skb);
+ 
+ 	skb->dev = NULL;
+ 
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index baccbf3c1c60..7b0e059bf13b 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -1214,9 +1214,12 @@ static int __sctp_connect(struct sock *sk,
+ 
+ 	timeo = sock_sndtimeo(sk, f_flags & O_NONBLOCK);
+ 
+-	err = sctp_wait_for_connect(asoc, &timeo);
+-	if ((err == 0 || err == -EINPROGRESS) && assoc_id)
++	if (assoc_id)
+ 		*assoc_id = asoc->assoc_id;
++	err = sctp_wait_for_connect(asoc, &timeo);
++	/* Note: the asoc may be freed after the return of
++	 * sctp_wait_for_connect.
++	 */
+ 
+ 	/* Don't free association on exit. */
+ 	asoc = NULL;
+@@ -4278,19 +4281,18 @@ static void sctp_shutdown(struct sock *sk, int how)
+ {
+ 	struct net *net = sock_net(sk);
+ 	struct sctp_endpoint *ep;
+-	struct sctp_association *asoc;
+ 
+ 	if (!sctp_style(sk, TCP))
+ 		return;
+ 
+-	if (how & SEND_SHUTDOWN) {
++	ep = sctp_sk(sk)->ep;
++	if (how & SEND_SHUTDOWN && !list_empty(&ep->asocs)) {
++		struct sctp_association *asoc;
++
+ 		sk->sk_state = SCTP_SS_CLOSING;
+-		ep = sctp_sk(sk)->ep;
+-		if (!list_empty(&ep->asocs)) {
+-			asoc = list_entry(ep->asocs.next,
+-					  struct sctp_association, asocs);
+-			sctp_primitive_SHUTDOWN(net, asoc, NULL);
+-		}
++		asoc = list_entry(ep->asocs.next,
++				  struct sctp_association, asocs);
++		sctp_primitive_SHUTDOWN(net, asoc, NULL);
+ 	}
+ }
+ 
+diff --git a/net/socket.c b/net/socket.c
+index a1bd16106625..03bc2c289c94 100644
+--- a/net/socket.c
++++ b/net/socket.c
+@@ -2041,6 +2041,8 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen,
+ 		if (err)
+ 			break;
+ 		++datagrams;
++		if (msg_data_left(&msg_sys))
++			break;
+ 		cond_resched();
+ 	}
+ 
+diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c
+index f3825b676e38..f046b77cfefe 100644
+--- a/tools/spi/spidev_test.c
++++ b/tools/spi/spidev_test.c
+@@ -19,6 +19,7 @@
+ #include <getopt.h>
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
++#include <linux/ioctl.h>
+ #include <sys/stat.h>
+ #include <linux/types.h>
+ #include <linux/spi/spidev.h>


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-21 14:55 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-11-21 14:55 UTC (permalink / raw
  To: gentoo-commits

commit:     da402fa940145d444f70632399df6fdbdbb40162
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Nov 21 14:54:55 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Nov 21 14:54:55 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=da402fa9

Update gentoo kconfig patch adding CHECKPOINT_RESTORE for GENTOO_LINUX_INIT_SYSTEMD. See bug #598623

 4567_distro-Gentoo-Kconfig.patch | 26 ++++++++++++++++++--------
 1 file changed, 18 insertions(+), 8 deletions(-)

diff --git a/4567_distro-Gentoo-Kconfig.patch b/4567_distro-Gentoo-Kconfig.patch
index cf5a20c..acb0972 100644
--- a/4567_distro-Gentoo-Kconfig.patch
+++ b/4567_distro-Gentoo-Kconfig.patch
@@ -1,14 +1,15 @@
---- a/Kconfig	2016-08-30 14:30:48.508361013 -0400
-+++ b/Kconfig	2016-08-30 14:31:40.718683061 -0400
-@@ -9,3 +9,5 @@ config SRCARCH
+--- a/Kconfig	2016-07-01 19:22:17.117439707 -0400
++++ b/Kconfig	2016-07-01 19:21:54.371440596 -0400
+@@ -8,4 +8,6 @@ config SRCARCH
+ 	string
  	option env="SRCARCH"
  
- source "arch/$SRCARCH/Kconfig"
-+
 +source "distro/Kconfig"
---- /dev/null	2016-08-30 01:47:09.760073185 -0400
-+++ b/distro/Kconfig	2016-08-30 14:32:21.378933599 -0400
-@@ -0,0 +1,133 @@
++
+ source "arch/$SRCARCH/Kconfig"
+--- /dev/null	2016-11-15 00:56:18.320838834 -0500
++++ b/distro/Kconfig	2016-11-16 06:24:29.457357409 -0500
+@@ -0,0 +1,142 @@
 +menu "Gentoo Linux"
 +
 +config GENTOO_LINUX
@@ -32,6 +33,7 @@
 +
 +	select DEVTMPFS
 +	select TMPFS
++	select UNIX
 +
 +	select MMU
 +	select SHMEM
@@ -111,16 +113,24 @@
 +	select AUTOFS4_FS
 +	select BLK_DEV_BSG
 +	select CGROUPS
++	select CHECKPOINT_RESTORE
++	select DEVPTS_MULTIPLE_INSTANCES
++	select DMIID
 +	select EPOLL
 +	select FANOTIFY
 +	select FHANDLE
 +	select INOTIFY_USER
++	select IPV6
 +	select NET
 +	select NET_NS
 +	select PROC_FS
++	select SECCOMP
++	select SECCOMP_FILTER
 +	select SIGNALFD
 +	select SYSFS
 +	select TIMERFD
++	select TMPFS_POSIX_ACL
++	select TMPFS_XATTR
 +
 +	select ANON_INODES
 +	select BLOCK


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-11-26 14:21 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-11-26 14:21 UTC (permalink / raw
  To: gentoo-commits

commit:     323a66be9ef3d4a7514e055204c780958716758d
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Sat Nov 26 14:19:40 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Sat Nov 26 14:19:40 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=323a66be

Linux patch 4.8.11

 0000_README             |    4 +
 1010_linux-4.8.11.patch | 2351 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2355 insertions(+)

diff --git a/0000_README b/0000_README
index 13976e7..4aa1baf 100644
--- a/0000_README
+++ b/0000_README
@@ -83,6 +83,10 @@ Patch:  1009_linux-4.8.10.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.10
 
+Patch:  1010_linux-4.8.11.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.11
+
 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/1010_linux-4.8.11.patch b/1010_linux-4.8.11.patch
new file mode 100644
index 0000000..49be830
--- /dev/null
+++ b/1010_linux-4.8.11.patch
@@ -0,0 +1,2351 @@
+diff --git a/Makefile b/Makefile
+index 7cf2b4985703..2b1bcbacebcd 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 10
++SUBLEVEL = 11
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+@@ -399,11 +399,12 @@ KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
+ 		   -fno-strict-aliasing -fno-common \
+ 		   -Werror-implicit-function-declaration \
+ 		   -Wno-format-security \
+-		   -std=gnu89
++		   -std=gnu89 $(call cc-option,-fno-PIE)
++
+ 
+ KBUILD_AFLAGS_KERNEL :=
+ KBUILD_CFLAGS_KERNEL :=
+-KBUILD_AFLAGS   := -D__ASSEMBLY__
++KBUILD_AFLAGS   := -D__ASSEMBLY__ $(call cc-option,-fno-PIE)
+ KBUILD_AFLAGS_MODULE  := -DMODULE
+ KBUILD_CFLAGS_MODULE  := -DMODULE
+ KBUILD_LDFLAGS_MODULE := -T $(srctree)/scripts/module-common.lds
+@@ -621,6 +622,7 @@ include arch/$(SRCARCH)/Makefile
+ 
+ KBUILD_CFLAGS	+= $(call cc-option,-fno-delete-null-pointer-checks,)
+ KBUILD_CFLAGS	+= $(call cc-disable-warning,maybe-uninitialized,)
++KBUILD_CFLAGS	+= $(call cc-disable-warning,frame-address,)
+ 
+ ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
+ KBUILD_CFLAGS	+= -Os
+diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts
+index dec4b073ceb1..379939699164 100644
+--- a/arch/arm/boot/dts/imx53-qsb.dts
++++ b/arch/arm/boot/dts/imx53-qsb.dts
+@@ -64,8 +64,8 @@
+ 			};
+ 
+ 			ldo3_reg: ldo3 {
+-				regulator-min-microvolt = <600000>;
+-				regulator-max-microvolt = <1800000>;
++				regulator-min-microvolt = <1725000>;
++				regulator-max-microvolt = <3300000>;
+ 				regulator-always-on;
+ 			};
+ 
+@@ -76,8 +76,8 @@
+ 			};
+ 
+ 			ldo5_reg: ldo5 {
+-				regulator-min-microvolt = <1725000>;
+-				regulator-max-microvolt = <3300000>;
++				regulator-min-microvolt = <1200000>;
++				regulator-max-microvolt = <3600000>;
+ 				regulator-always-on;
+ 			};
+ 
+@@ -100,14 +100,14 @@
+ 			};
+ 
+ 			ldo9_reg: ldo9 {
+-				regulator-min-microvolt = <1200000>;
++				regulator-min-microvolt = <1250000>;
+ 				regulator-max-microvolt = <3600000>;
+ 				regulator-always-on;
+ 			};
+ 
+ 			ldo10_reg: ldo10 {
+-				regulator-min-microvolt = <1250000>;
+-				regulator-max-microvolt = <3650000>;
++				regulator-min-microvolt = <1200000>;
++				regulator-max-microvolt = <3600000>;
+ 				regulator-always-on;
+ 			};
+ 		};
+diff --git a/arch/arm64/include/asm/perf_event.h b/arch/arm64/include/asm/perf_event.h
+index 2065f46fa740..38b6a2b49d68 100644
+--- a/arch/arm64/include/asm/perf_event.h
++++ b/arch/arm64/include/asm/perf_event.h
+@@ -46,7 +46,15 @@
+ #define	ARMV8_PMU_EVTYPE_MASK	0xc800ffff	/* Mask for writable bits */
+ #define	ARMV8_PMU_EVTYPE_EVENT	0xffff		/* Mask for EVENT bits */
+ 
+-#define ARMV8_PMU_EVTYPE_EVENT_SW_INCR	0	/* Software increment event */
++/*
++ * PMUv3 event types: required events
++ */
++#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
++#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
++#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
++#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
++#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
++#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
+ 
+ /*
+  * Event filters for PMUv3
+diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
+index 838ccf123307..2c4df1520c45 100644
+--- a/arch/arm64/kernel/perf_event.c
++++ b/arch/arm64/kernel/perf_event.c
+@@ -30,17 +30,9 @@
+ 
+ /*
+  * ARMv8 PMUv3 Performance Events handling code.
+- * Common event types.
++ * Common event types (some are defined in asm/perf_event.h).
+  */
+ 
+-/* Required events. */
+-#define ARMV8_PMUV3_PERFCTR_SW_INCR				0x00
+-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE_REFILL			0x03
+-#define ARMV8_PMUV3_PERFCTR_L1D_CACHE				0x04
+-#define ARMV8_PMUV3_PERFCTR_BR_MIS_PRED				0x10
+-#define ARMV8_PMUV3_PERFCTR_CPU_CYCLES				0x11
+-#define ARMV8_PMUV3_PERFCTR_BR_PRED				0x12
+-
+ /* At least one of the following is required. */
+ #define ARMV8_PMUV3_PERFCTR_INST_RETIRED			0x08
+ #define ARMV8_PMUV3_PERFCTR_INST_SPEC				0x1B
+diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c
+index e51367d159d0..31c144f7339a 100644
+--- a/arch/arm64/kvm/sys_regs.c
++++ b/arch/arm64/kvm/sys_regs.c
+@@ -602,8 +602,14 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
+ 
+ 			idx = ARMV8_PMU_CYCLE_IDX;
+ 		} else {
+-			BUG();
++			return false;
+ 		}
++	} else if (r->CRn == 0 && r->CRm == 9) {
++		/* PMCCNTR */
++		if (pmu_access_event_counter_el0_disabled(vcpu))
++			return false;
++
++		idx = ARMV8_PMU_CYCLE_IDX;
+ 	} else if (r->CRn == 14 && (r->CRm & 12) == 8) {
+ 		/* PMEVCNTRn_EL0 */
+ 		if (pmu_access_event_counter_el0_disabled(vcpu))
+@@ -611,7 +617,7 @@ static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
+ 
+ 		idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
+ 	} else {
+-		BUG();
++		return false;
+ 	}
+ 
+ 	if (!pmu_counter_idx_valid(vcpu, idx))
+diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
+index 7ac8e6eaab5b..8d586cff8a41 100644
+--- a/arch/powerpc/kernel/setup_64.c
++++ b/arch/powerpc/kernel/setup_64.c
+@@ -226,17 +226,25 @@ static void __init configure_exceptions(void)
+ 		if (firmware_has_feature(FW_FEATURE_OPAL))
+ 			opal_configure_cores();
+ 
+-		/* Enable AIL if supported, and we are in hypervisor mode */
+-		if (early_cpu_has_feature(CPU_FTR_HVMODE) &&
+-		    early_cpu_has_feature(CPU_FTR_ARCH_207S)) {
+-			unsigned long lpcr = mfspr(SPRN_LPCR);
+-			mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
+-		}
++		/* AIL on native is done in cpu_ready_for_interrupts() */
+ 	}
+ }
+ 
+ static void cpu_ready_for_interrupts(void)
+ {
++	/*
++	 * Enable AIL if supported, and we are in hypervisor mode. This
++	 * is called once for every processor.
++	 *
++	 * If we are not in hypervisor mode the job is done once for
++	 * the whole partition in configure_exceptions().
++	 */
++	if (early_cpu_has_feature(CPU_FTR_HVMODE) &&
++	    early_cpu_has_feature(CPU_FTR_ARCH_207S)) {
++		unsigned long lpcr = mfspr(SPRN_LPCR);
++		mtspr(SPRN_LPCR, lpcr | LPCR_AIL_3);
++	}
++
+ 	/* Set IR and DR in PACA MSR */
+ 	get_paca()->kernel_msr = MSR_KERNEL;
+ }
+diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c
+index b81fe2d63e15..1e81a37c034e 100644
+--- a/arch/x86/kernel/cpu/amd.c
++++ b/arch/x86/kernel/cpu/amd.c
+@@ -347,7 +347,6 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
+ #ifdef CONFIG_SMP
+ 	unsigned bits;
+ 	int cpu = smp_processor_id();
+-	unsigned int socket_id, core_complex_id;
+ 
+ 	bits = c->x86_coreid_bits;
+ 	/* Low order bits define the core id (index of core in socket) */
+@@ -365,10 +364,7 @@ static void amd_detect_cmp(struct cpuinfo_x86 *c)
+ 	 if (c->x86 != 0x17 || !cpuid_edx(0x80000006))
+ 		return;
+ 
+-	socket_id	= (c->apicid >> bits) - 1;
+-	core_complex_id	= (c->apicid & ((1 << bits) - 1)) >> 3;
+-
+-	per_cpu(cpu_llc_id, cpu) = (socket_id << 3) | core_complex_id;
++	per_cpu(cpu_llc_id, cpu) = c->apicid >> 3;
+ #endif
+ }
+ 
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 46f74d461f3f..2fff65794f46 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -210,7 +210,18 @@ static void kvm_on_user_return(struct user_return_notifier *urn)
+ 	struct kvm_shared_msrs *locals
+ 		= container_of(urn, struct kvm_shared_msrs, urn);
+ 	struct kvm_shared_msr_values *values;
++	unsigned long flags;
+ 
++	/*
++	 * Disabling irqs at this point since the following code could be
++	 * interrupted and executed through kvm_arch_hardware_disable()
++	 */
++	local_irq_save(flags);
++	if (locals->registered) {
++		locals->registered = false;
++		user_return_notifier_unregister(urn);
++	}
++	local_irq_restore(flags);
+ 	for (slot = 0; slot < shared_msrs_global.nr; ++slot) {
+ 		values = &locals->values[slot];
+ 		if (values->host != values->curr) {
+@@ -218,8 +229,6 @@ static void kvm_on_user_return(struct user_return_notifier *urn)
+ 			values->curr = values->host;
+ 		}
+ 	}
+-	locals->registered = false;
+-	user_return_notifier_unregister(urn);
+ }
+ 
+ static void shared_msr_update(unsigned slot, u32 msr)
+@@ -3372,6 +3381,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
+ 	};
+ 	case KVM_SET_VAPIC_ADDR: {
+ 		struct kvm_vapic_addr va;
++		int idx;
+ 
+ 		r = -EINVAL;
+ 		if (!lapic_in_kernel(vcpu))
+@@ -3379,7 +3389,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
+ 		r = -EFAULT;
+ 		if (copy_from_user(&va, argp, sizeof va))
+ 			goto out;
++		idx = srcu_read_lock(&vcpu->kvm->srcu);
+ 		r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr);
++		srcu_read_unlock(&vcpu->kvm->srcu, idx);
+ 		break;
+ 	}
+ 	case KVM_X86_SETUP_MCE: {
+diff --git a/arch/x86/purgatory/Makefile b/arch/x86/purgatory/Makefile
+index ac58c1616408..555b9fa0ad43 100644
+--- a/arch/x86/purgatory/Makefile
++++ b/arch/x86/purgatory/Makefile
+@@ -16,6 +16,7 @@ KCOV_INSTRUMENT := n
+ 
+ KBUILD_CFLAGS := -fno-strict-aliasing -Wall -Wstrict-prototypes -fno-zero-initialized-in-bss -fno-builtin -ffreestanding -c -MD -Os -mcmodel=large
+ KBUILD_CFLAGS += -m$(BITS)
++KBUILD_CFLAGS += $(call cc-option,-fno-PIE)
+ 
+ $(obj)/purgatory.ro: $(PURGATORY_OBJS) FORCE
+ 		$(call if_changed,ld)
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+index e44944f4be77..2932a5bd892f 100644
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -1027,6 +1027,8 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
+ 	TRACE_DEVICE(dev);
+ 	TRACE_SUSPEND(0);
+ 
++	dpm_wait_for_children(dev, async);
++
+ 	if (async_error)
+ 		goto Complete;
+ 
+@@ -1038,8 +1040,6 @@ static int __device_suspend_noirq(struct device *dev, pm_message_t state, bool a
+ 	if (dev->power.syscore || dev->power.direct_complete)
+ 		goto Complete;
+ 
+-	dpm_wait_for_children(dev, async);
+-
+ 	if (dev->pm_domain) {
+ 		info = "noirq power domain ";
+ 		callback = pm_noirq_op(&dev->pm_domain->ops, state);
+@@ -1174,6 +1174,8 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
+ 
+ 	__pm_runtime_disable(dev, false);
+ 
++	dpm_wait_for_children(dev, async);
++
+ 	if (async_error)
+ 		goto Complete;
+ 
+@@ -1185,8 +1187,6 @@ static int __device_suspend_late(struct device *dev, pm_message_t state, bool as
+ 	if (dev->power.syscore || dev->power.direct_complete)
+ 		goto Complete;
+ 
+-	dpm_wait_for_children(dev, async);
+-
+ 	if (dev->pm_domain) {
+ 		info = "late power domain ";
+ 		callback = pm_late_early_op(&dev->pm_domain->ops, state);
+diff --git a/drivers/clk/imx/clk-pllv3.c b/drivers/clk/imx/clk-pllv3.c
+index 19f9b622981a..7a6acc3e4a92 100644
+--- a/drivers/clk/imx/clk-pllv3.c
++++ b/drivers/clk/imx/clk-pllv3.c
+@@ -223,7 +223,7 @@ static unsigned long clk_pllv3_av_recalc_rate(struct clk_hw *hw,
+ 	temp64 *= mfn;
+ 	do_div(temp64, mfd);
+ 
+-	return (parent_rate * div) + (u32)temp64;
++	return parent_rate * div + (unsigned long)temp64;
+ }
+ 
+ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+@@ -247,7 +247,11 @@ static long clk_pllv3_av_round_rate(struct clk_hw *hw, unsigned long rate,
+ 	do_div(temp64, parent_rate);
+ 	mfn = temp64;
+ 
+-	return parent_rate * div + parent_rate * mfn / mfd;
++	temp64 = (u64)parent_rate;
++	temp64 *= mfn;
++	do_div(temp64, mfd);
++
++	return parent_rate * div + (unsigned long)temp64;
+ }
+ 
+ static int clk_pllv3_av_set_rate(struct clk_hw *hw, unsigned long rate,
+diff --git a/drivers/clk/mmp/clk-of-mmp2.c b/drivers/clk/mmp/clk-of-mmp2.c
+index 3a51fff1b0e7..9adaf48aea23 100644
+--- a/drivers/clk/mmp/clk-of-mmp2.c
++++ b/drivers/clk/mmp/clk-of-mmp2.c
+@@ -313,7 +313,7 @@ static void __init mmp2_clk_init(struct device_node *np)
+ 	}
+ 
+ 	pxa_unit->apmu_base = of_iomap(np, 1);
+-	if (!pxa_unit->mpmu_base) {
++	if (!pxa_unit->apmu_base) {
+ 		pr_err("failed to map apmu registers\n");
+ 		return;
+ 	}
+diff --git a/drivers/clk/mmp/clk-of-pxa168.c b/drivers/clk/mmp/clk-of-pxa168.c
+index 87f2317b2a00..f110c02e83cb 100644
+--- a/drivers/clk/mmp/clk-of-pxa168.c
++++ b/drivers/clk/mmp/clk-of-pxa168.c
+@@ -262,7 +262,7 @@ static void __init pxa168_clk_init(struct device_node *np)
+ 	}
+ 
+ 	pxa_unit->apmu_base = of_iomap(np, 1);
+-	if (!pxa_unit->mpmu_base) {
++	if (!pxa_unit->apmu_base) {
+ 		pr_err("failed to map apmu registers\n");
+ 		return;
+ 	}
+diff --git a/drivers/clk/mmp/clk-of-pxa910.c b/drivers/clk/mmp/clk-of-pxa910.c
+index e22a67f76d93..64d1ef49caeb 100644
+--- a/drivers/clk/mmp/clk-of-pxa910.c
++++ b/drivers/clk/mmp/clk-of-pxa910.c
+@@ -282,7 +282,7 @@ static void __init pxa910_clk_init(struct device_node *np)
+ 	}
+ 
+ 	pxa_unit->apmu_base = of_iomap(np, 1);
+-	if (!pxa_unit->mpmu_base) {
++	if (!pxa_unit->apmu_base) {
+ 		pr_err("failed to map apmu registers\n");
+ 		return;
+ 	}
+@@ -294,7 +294,7 @@ static void __init pxa910_clk_init(struct device_node *np)
+ 	}
+ 
+ 	pxa_unit->apbcp_base = of_iomap(np, 3);
+-	if (!pxa_unit->mpmu_base) {
++	if (!pxa_unit->apbcp_base) {
+ 		pr_err("failed to map apbcp registers\n");
+ 		return;
+ 	}
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
+index b3044219772c..2cde3796cb82 100644
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -4542,6 +4542,15 @@ static int __init caam_algapi_init(void)
+ 		if (!aes_inst && (alg_sel == OP_ALG_ALGSEL_AES))
+ 				continue;
+ 
++		/*
++		 * Check support for AES modes not available
++		 * on LP devices.
++		 */
++		if ((cha_vid & CHA_ID_LS_AES_MASK) == CHA_ID_LS_AES_LP)
++			if ((alg->class1_alg_type & OP_ALG_AAI_MASK) ==
++			     OP_ALG_AAI_XTS)
++				continue;
++
+ 		t_alg = caam_alg_alloc(alg);
+ 		if (IS_ERR(t_alg)) {
+ 			err = PTR_ERR(t_alg);
+diff --git a/drivers/gpio/gpio-pca953x.c b/drivers/gpio/gpio-pca953x.c
+index 02f2a5621bb0..47d08b9da60d 100644
+--- a/drivers/gpio/gpio-pca953x.c
++++ b/drivers/gpio/gpio-pca953x.c
+@@ -372,14 +372,15 @@ static void pca953x_gpio_set_multiple(struct gpio_chip *gc,
+ 		break;
+ 	}
+ 
+-	memcpy(reg_val, chip->reg_output, NBANK(chip));
+ 	mutex_lock(&chip->i2c_lock);
++	memcpy(reg_val, chip->reg_output, NBANK(chip));
+ 	for(bank=0; bank<NBANK(chip); bank++) {
+ 		unsigned bankmask = mask[bank / sizeof(*mask)] >>
+ 				    ((bank % sizeof(*mask)) * 8);
+ 		if(bankmask) {
+ 			unsigned bankval  = bits[bank / sizeof(*bits)] >>
+ 					    ((bank % sizeof(*bits)) * 8);
++			bankval &= bankmask;
+ 			reg_val[bank] = (reg_val[bank] & ~bankmask) | bankval;
+ 		}
+ 	}
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index b2dee1024166..15704aaf9e4e 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -2667,8 +2667,11 @@ int gpiochip_lock_as_irq(struct gpio_chip *chip, unsigned int offset)
+ 	if (IS_ERR(desc))
+ 		return PTR_ERR(desc);
+ 
+-	/* Flush direction if something changed behind our back */
+-	if (chip->get_direction) {
++	/*
++	 * If it's fast: flush the direction setting if something changed
++	 * behind our back
++	 */
++	if (!chip->can_sleep && chip->get_direction) {
+ 		int dir = chip->get_direction(chip, offset);
+ 
+ 		if (dir)
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+index 700c56baf2de..e443073f6ece 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+@@ -492,6 +492,7 @@ struct amdgpu_bo {
+ 	u64				metadata_flags;
+ 	void				*metadata;
+ 	u32				metadata_size;
++	unsigned			prime_shared_count;
+ 	/* list of all virtual address to which this bo
+ 	 * is associated to
+ 	 */
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+index 651115dcce12..c02db01f6583 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c
+@@ -132,7 +132,7 @@ static int amdgpu_bo_list_set(struct amdgpu_device *adev,
+ 		entry->priority = min(info[i].bo_priority,
+ 				      AMDGPU_BO_LIST_MAX_PRIORITY);
+ 		entry->tv.bo = &entry->robj->tbo;
+-		entry->tv.shared = true;
++		entry->tv.shared = !entry->robj->prime_shared_count;
+ 
+ 		if (entry->robj->prefered_domains == AMDGPU_GEM_DOMAIN_GDS)
+ 			gds_obj = entry->robj;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+index 7700dc22f243..3826d5aea0a6 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_prime.c
+@@ -74,20 +74,36 @@ amdgpu_gem_prime_import_sg_table(struct drm_device *dev,
+ 	if (ret)
+ 		return ERR_PTR(ret);
+ 
++	bo->prime_shared_count = 1;
+ 	return &bo->gem_base;
+ }
+ 
+ int amdgpu_gem_prime_pin(struct drm_gem_object *obj)
+ {
+ 	struct amdgpu_bo *bo = gem_to_amdgpu_bo(obj);
+-	int ret = 0;
++	long ret = 0;
+ 
+ 	ret = amdgpu_bo_reserve(bo, false);
+ 	if (unlikely(ret != 0))
+ 		return ret;
+ 
++	/*
++	 * Wait for all shared fences to complete before we switch to future
++	 * use of exclusive fence on this prime shared bo.
++	 */
++	ret = reservation_object_wait_timeout_rcu(bo->tbo.resv, true, false,
++						  MAX_SCHEDULE_TIMEOUT);
++	if (unlikely(ret < 0)) {
++		DRM_DEBUG_PRIME("Fence wait failed: %li\n", ret);
++		amdgpu_bo_unreserve(bo);
++		return ret;
++	}
++
+ 	/* pin buffer into GTT */
+ 	ret = amdgpu_bo_pin(bo, AMDGPU_GEM_DOMAIN_GTT, NULL);
++	if (likely(ret == 0))
++		bo->prime_shared_count++;
++
+ 	amdgpu_bo_unreserve(bo);
+ 	return ret;
+ }
+@@ -102,6 +118,8 @@ void amdgpu_gem_prime_unpin(struct drm_gem_object *obj)
+ 		return;
+ 
+ 	amdgpu_bo_unpin(bo);
++	if (bo->prime_shared_count)
++		bo->prime_shared_count--;
+ 	amdgpu_bo_unreserve(bo);
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
+index 1f8af87c6294..cf2560708e03 100644
+--- a/drivers/gpu/drm/i915/intel_bios.c
++++ b/drivers/gpu/drm/i915/intel_bios.c
+@@ -1143,7 +1143,7 @@ static void parse_ddi_port(struct drm_i915_private *dev_priv, enum port port,
+ 	if (!child)
+ 		return;
+ 
+-	aux_channel = child->raw[25];
++	aux_channel = child->common.aux_channel;
+ 	ddc_pin = child->common.ddc_pin;
+ 
+ 	is_dvi = child->common.device_type & DEVICE_TYPE_TMDS_DVI_SIGNALING;
+@@ -1673,7 +1673,8 @@ bool intel_bios_is_port_edp(struct drm_i915_private *dev_priv, enum port port)
+ 	return false;
+ }
+ 
+-bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum port port)
++static bool child_dev_is_dp_dual_mode(const union child_device_config *p_child,
++				      enum port port)
+ {
+ 	static const struct {
+ 		u16 dp, hdmi;
+@@ -1687,22 +1688,35 @@ bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv, enum por
+ 		[PORT_D] = { DVO_PORT_DPD, DVO_PORT_HDMID, },
+ 		[PORT_E] = { DVO_PORT_DPE, DVO_PORT_HDMIE, },
+ 	};
+-	int i;
+ 
+ 	if (port == PORT_A || port >= ARRAY_SIZE(port_mapping))
+ 		return false;
+ 
+-	if (!dev_priv->vbt.child_dev_num)
++	if ((p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) !=
++	    (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
+ 		return false;
+ 
++	if (p_child->common.dvo_port == port_mapping[port].dp)
++		return true;
++
++	/* Only accept a HDMI dvo_port as DP++ if it has an AUX channel */
++	if (p_child->common.dvo_port == port_mapping[port].hdmi &&
++	    p_child->common.aux_channel != 0)
++		return true;
++
++	return false;
++}
++
++bool intel_bios_is_port_dp_dual_mode(struct drm_i915_private *dev_priv,
++				     enum port port)
++{
++	int i;
++
+ 	for (i = 0; i < dev_priv->vbt.child_dev_num; i++) {
+ 		const union child_device_config *p_child =
+ 			&dev_priv->vbt.child_dev[i];
+ 
+-		if ((p_child->common.dvo_port == port_mapping[port].dp ||
+-		     p_child->common.dvo_port == port_mapping[port].hdmi) &&
+-		    (p_child->common.device_type & DEVICE_TYPE_DP_DUAL_MODE_BITS) ==
+-		    (DEVICE_TYPE_DP_DUAL_MODE & DEVICE_TYPE_DP_DUAL_MODE_BITS))
++		if (child_dev_is_dp_dual_mode(p_child, port))
+ 			return true;
+ 	}
+ 
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 3051182cf483..b8aeb28e14d7 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -4323,21 +4323,11 @@ static enum drm_connector_status
+ intel_dp_detect(struct drm_connector *connector, bool force)
+ {
+ 	struct intel_dp *intel_dp = intel_attached_dp(connector);
+-	struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
+-	struct intel_encoder *intel_encoder = &intel_dig_port->base;
+ 	enum drm_connector_status status = connector->status;
+ 
+ 	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
+ 		      connector->base.id, connector->name);
+ 
+-	if (intel_dp->is_mst) {
+-		/* MST devices are disconnected from a monitor POV */
+-		intel_dp_unset_edid(intel_dp);
+-		if (intel_encoder->type != INTEL_OUTPUT_EDP)
+-			intel_encoder->type = INTEL_OUTPUT_DP;
+-		return connector_status_disconnected;
+-	}
+-
+ 	/* If full detect is not performed yet, do a full detect */
+ 	if (!intel_dp->detect_done)
+ 		status = intel_dp_long_pulse(intel_dp->attached_connector);
+diff --git a/drivers/gpu/drm/i915/intel_vbt_defs.h b/drivers/gpu/drm/i915/intel_vbt_defs.h
+index 68db9621f1f0..8886cab19f98 100644
+--- a/drivers/gpu/drm/i915/intel_vbt_defs.h
++++ b/drivers/gpu/drm/i915/intel_vbt_defs.h
+@@ -280,7 +280,8 @@ struct common_child_dev_config {
+ 	u8 dp_support:1;
+ 	u8 tmds_support:1;
+ 	u8 support_reserved:5;
+-	u8 not_common3[12];
++	u8 aux_channel;
++	u8 not_common3[11];
+ 	u8 iboost_level;
+ } __packed;
+ 
+diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
+index d223650a97e4..11edabf425ae 100644
+--- a/drivers/i2c/Kconfig
++++ b/drivers/i2c/Kconfig
+@@ -59,7 +59,6 @@ config I2C_CHARDEV
+ 
+ config I2C_MUX
+ 	tristate "I2C bus multiplexing support"
+-	depends on HAS_IOMEM
+ 	help
+ 	  Say Y here if you want the I2C core to support the ability to
+ 	  handle multiplexed I2C bus topologies, by presenting each
+diff --git a/drivers/i2c/muxes/Kconfig b/drivers/i2c/muxes/Kconfig
+index e280c8ecc0b5..96de9ce5669b 100644
+--- a/drivers/i2c/muxes/Kconfig
++++ b/drivers/i2c/muxes/Kconfig
+@@ -63,6 +63,7 @@ config I2C_MUX_PINCTRL
+ 
+ config I2C_MUX_REG
+ 	tristate "Register-based I2C multiplexer"
++	depends on HAS_IOMEM
+ 	help
+ 	  If you say yes to this option, support will be included for a
+ 	  register based I2C multiplexer. This driver provides access to
+diff --git a/drivers/i2c/muxes/i2c-mux-pca954x.c b/drivers/i2c/muxes/i2c-mux-pca954x.c
+index 3278ebf1cc5c..7e6f300009c5 100644
+--- a/drivers/i2c/muxes/i2c-mux-pca954x.c
++++ b/drivers/i2c/muxes/i2c-mux-pca954x.c
+@@ -247,9 +247,9 @@ static int pca954x_probe(struct i2c_client *client,
+ 				/* discard unconfigured channels */
+ 				break;
+ 			idle_disconnect_pd = pdata->modes[num].deselect_on_exit;
+-			data->deselect |= (idle_disconnect_pd
+-					   || idle_disconnect_dt) << num;
+ 		}
++		data->deselect |= (idle_disconnect_pd ||
++				   idle_disconnect_dt) << num;
+ 
+ 		ret = i2c_mux_add_adapter(muxc, force, num, class);
+ 
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index c99525512b34..71c7c4c328ef 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -80,6 +80,8 @@ static struct ib_cm {
+ 	__be32 random_id_operand;
+ 	struct list_head timewait_list;
+ 	struct workqueue_struct *wq;
++	/* Sync on cm change port state */
++	spinlock_t state_lock;
+ } cm;
+ 
+ /* Counter indexes ordered by attribute ID */
+@@ -161,6 +163,8 @@ struct cm_port {
+ 	struct ib_mad_agent *mad_agent;
+ 	struct kobject port_obj;
+ 	u8 port_num;
++	struct list_head cm_priv_prim_list;
++	struct list_head cm_priv_altr_list;
+ 	struct cm_counter_group counter_group[CM_COUNTER_GROUPS];
+ };
+ 
+@@ -241,6 +245,12 @@ struct cm_id_private {
+ 	u8 service_timeout;
+ 	u8 target_ack_delay;
+ 
++	struct list_head prim_list;
++	struct list_head altr_list;
++	/* Indicates that the send port mad is registered and av is set */
++	int prim_send_port_not_ready;
++	int altr_send_port_not_ready;
++
+ 	struct list_head work_list;
+ 	atomic_t work_count;
+ };
+@@ -259,20 +269,47 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
+ 	struct ib_mad_agent *mad_agent;
+ 	struct ib_mad_send_buf *m;
+ 	struct ib_ah *ah;
++	struct cm_av *av;
++	unsigned long flags, flags2;
++	int ret = 0;
+ 
++	/* don't let the port to be released till the agent is down */
++	spin_lock_irqsave(&cm.state_lock, flags2);
++	spin_lock_irqsave(&cm.lock, flags);
++	if (!cm_id_priv->prim_send_port_not_ready)
++		av = &cm_id_priv->av;
++	else if (!cm_id_priv->altr_send_port_not_ready &&
++		 (cm_id_priv->alt_av.port))
++		av = &cm_id_priv->alt_av;
++	else {
++		pr_info("%s: not valid CM id\n", __func__);
++		ret = -ENODEV;
++		spin_unlock_irqrestore(&cm.lock, flags);
++		goto out;
++	}
++	spin_unlock_irqrestore(&cm.lock, flags);
++	/* Make sure the port haven't released the mad yet */
+ 	mad_agent = cm_id_priv->av.port->mad_agent;
+-	ah = ib_create_ah(mad_agent->qp->pd, &cm_id_priv->av.ah_attr);
+-	if (IS_ERR(ah))
+-		return PTR_ERR(ah);
++	if (!mad_agent) {
++		pr_info("%s: not a valid MAD agent\n", __func__);
++		ret = -ENODEV;
++		goto out;
++	}
++	ah = ib_create_ah(mad_agent->qp->pd, &av->ah_attr);
++	if (IS_ERR(ah)) {
++		ret = PTR_ERR(ah);
++		goto out;
++	}
+ 
+ 	m = ib_create_send_mad(mad_agent, cm_id_priv->id.remote_cm_qpn,
+-			       cm_id_priv->av.pkey_index,
++			       av->pkey_index,
+ 			       0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA,
+ 			       GFP_ATOMIC,
+ 			       IB_MGMT_BASE_VERSION);
+ 	if (IS_ERR(m)) {
+ 		ib_destroy_ah(ah);
+-		return PTR_ERR(m);
++		ret = PTR_ERR(m);
++		goto out;
+ 	}
+ 
+ 	/* Timeout set by caller if response is expected. */
+@@ -282,7 +319,10 @@ static int cm_alloc_msg(struct cm_id_private *cm_id_priv,
+ 	atomic_inc(&cm_id_priv->refcount);
+ 	m->context[0] = cm_id_priv;
+ 	*msg = m;
+-	return 0;
++
++out:
++	spin_unlock_irqrestore(&cm.state_lock, flags2);
++	return ret;
+ }
+ 
+ static int cm_alloc_response_msg(struct cm_port *port,
+@@ -352,7 +392,8 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
+ 			   grh, &av->ah_attr);
+ }
+ 
+-static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
++static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av,
++			      struct cm_id_private *cm_id_priv)
+ {
+ 	struct cm_device *cm_dev;
+ 	struct cm_port *port = NULL;
+@@ -387,7 +428,17 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
+ 			     &av->ah_attr);
+ 	av->timeout = path->packet_life_time + 1;
+ 
+-	return 0;
++	spin_lock_irqsave(&cm.lock, flags);
++	if (&cm_id_priv->av == av)
++		list_add_tail(&cm_id_priv->prim_list, &port->cm_priv_prim_list);
++	else if (&cm_id_priv->alt_av == av)
++		list_add_tail(&cm_id_priv->altr_list, &port->cm_priv_altr_list);
++	else
++		ret = -EINVAL;
++
++	spin_unlock_irqrestore(&cm.lock, flags);
++
++	return ret;
+ }
+ 
+ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
+@@ -677,6 +728,8 @@ struct ib_cm_id *ib_create_cm_id(struct ib_device *device,
+ 	spin_lock_init(&cm_id_priv->lock);
+ 	init_completion(&cm_id_priv->comp);
+ 	INIT_LIST_HEAD(&cm_id_priv->work_list);
++	INIT_LIST_HEAD(&cm_id_priv->prim_list);
++	INIT_LIST_HEAD(&cm_id_priv->altr_list);
+ 	atomic_set(&cm_id_priv->work_count, -1);
+ 	atomic_set(&cm_id_priv->refcount, 1);
+ 	return &cm_id_priv->id;
+@@ -892,6 +945,15 @@ retest:
+ 		break;
+ 	}
+ 
++	spin_lock_irq(&cm.lock);
++	if (!list_empty(&cm_id_priv->altr_list) &&
++	    (!cm_id_priv->altr_send_port_not_ready))
++		list_del(&cm_id_priv->altr_list);
++	if (!list_empty(&cm_id_priv->prim_list) &&
++	    (!cm_id_priv->prim_send_port_not_ready))
++		list_del(&cm_id_priv->prim_list);
++	spin_unlock_irq(&cm.lock);
++
+ 	cm_free_id(cm_id->local_id);
+ 	cm_deref_id(cm_id_priv);
+ 	wait_for_completion(&cm_id_priv->comp);
+@@ -1192,12 +1254,13 @@ int ib_send_cm_req(struct ib_cm_id *cm_id,
+ 		goto out;
+ 	}
+ 
+-	ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av);
++	ret = cm_init_av_by_path(param->primary_path, &cm_id_priv->av,
++				 cm_id_priv);
+ 	if (ret)
+ 		goto error1;
+ 	if (param->alternate_path) {
+ 		ret = cm_init_av_by_path(param->alternate_path,
+-					 &cm_id_priv->alt_av);
++					 &cm_id_priv->alt_av, cm_id_priv);
+ 		if (ret)
+ 			goto error1;
+ 	}
+@@ -1653,7 +1716,8 @@ static int cm_req_handler(struct cm_work *work)
+ 			dev_put(gid_attr.ndev);
+ 		}
+ 		work->path[0].gid_type = gid_attr.gid_type;
+-		ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
++		ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av,
++					 cm_id_priv);
+ 	}
+ 	if (ret) {
+ 		int err = ib_get_cached_gid(work->port->cm_dev->ib_device,
+@@ -1672,7 +1736,8 @@ static int cm_req_handler(struct cm_work *work)
+ 		goto rejected;
+ 	}
+ 	if (req_msg->alt_local_lid) {
+-		ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av);
++		ret = cm_init_av_by_path(&work->path[1], &cm_id_priv->alt_av,
++					 cm_id_priv);
+ 		if (ret) {
+ 			ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_ALT_GID,
+ 				       &work->path[0].sgid,
+@@ -2727,7 +2792,8 @@ int ib_send_cm_lap(struct ib_cm_id *cm_id,
+ 		goto out;
+ 	}
+ 
+-	ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av);
++	ret = cm_init_av_by_path(alternate_path, &cm_id_priv->alt_av,
++				 cm_id_priv);
+ 	if (ret)
+ 		goto out;
+ 	cm_id_priv->alt_av.timeout =
+@@ -2839,7 +2905,8 @@ static int cm_lap_handler(struct cm_work *work)
+ 	cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+ 				work->mad_recv_wc->recv_buf.grh,
+ 				&cm_id_priv->av);
+-	cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av);
++	cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av,
++			   cm_id_priv);
+ 	ret = atomic_inc_and_test(&cm_id_priv->work_count);
+ 	if (!ret)
+ 		list_add_tail(&work->list, &cm_id_priv->work_list);
+@@ -3031,7 +3098,7 @@ int ib_send_cm_sidr_req(struct ib_cm_id *cm_id,
+ 		return -EINVAL;
+ 
+ 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+-	ret = cm_init_av_by_path(param->path, &cm_id_priv->av);
++	ret = cm_init_av_by_path(param->path, &cm_id_priv->av, cm_id_priv);
+ 	if (ret)
+ 		goto out;
+ 
+@@ -3468,7 +3535,9 @@ out:
+ static int cm_migrate(struct ib_cm_id *cm_id)
+ {
+ 	struct cm_id_private *cm_id_priv;
++	struct cm_av tmp_av;
+ 	unsigned long flags;
++	int tmp_send_port_not_ready;
+ 	int ret = 0;
+ 
+ 	cm_id_priv = container_of(cm_id, struct cm_id_private, id);
+@@ -3477,7 +3546,14 @@ static int cm_migrate(struct ib_cm_id *cm_id)
+ 	    (cm_id->lap_state == IB_CM_LAP_UNINIT ||
+ 	     cm_id->lap_state == IB_CM_LAP_IDLE)) {
+ 		cm_id->lap_state = IB_CM_LAP_IDLE;
++		/* Swap address vector */
++		tmp_av = cm_id_priv->av;
+ 		cm_id_priv->av = cm_id_priv->alt_av;
++		cm_id_priv->alt_av = tmp_av;
++		/* Swap port send ready state */
++		tmp_send_port_not_ready = cm_id_priv->prim_send_port_not_ready;
++		cm_id_priv->prim_send_port_not_ready = cm_id_priv->altr_send_port_not_ready;
++		cm_id_priv->altr_send_port_not_ready = tmp_send_port_not_ready;
+ 	} else
+ 		ret = -EINVAL;
+ 	spin_unlock_irqrestore(&cm_id_priv->lock, flags);
+@@ -3888,6 +3964,9 @@ static void cm_add_one(struct ib_device *ib_device)
+ 		port->cm_dev = cm_dev;
+ 		port->port_num = i;
+ 
++		INIT_LIST_HEAD(&port->cm_priv_prim_list);
++		INIT_LIST_HEAD(&port->cm_priv_altr_list);
++
+ 		ret = cm_create_port_fs(port);
+ 		if (ret)
+ 			goto error1;
+@@ -3945,6 +4024,8 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
+ {
+ 	struct cm_device *cm_dev = client_data;
+ 	struct cm_port *port;
++	struct cm_id_private *cm_id_priv;
++	struct ib_mad_agent *cur_mad_agent;
+ 	struct ib_port_modify port_modify = {
+ 		.clr_port_cap_mask = IB_PORT_CM_SUP
+ 	};
+@@ -3968,15 +4049,27 @@ static void cm_remove_one(struct ib_device *ib_device, void *client_data)
+ 
+ 		port = cm_dev->port[i-1];
+ 		ib_modify_port(ib_device, port->port_num, 0, &port_modify);
++		/* Mark all the cm_id's as not valid */
++		spin_lock_irq(&cm.lock);
++		list_for_each_entry(cm_id_priv, &port->cm_priv_altr_list, altr_list)
++			cm_id_priv->altr_send_port_not_ready = 1;
++		list_for_each_entry(cm_id_priv, &port->cm_priv_prim_list, prim_list)
++			cm_id_priv->prim_send_port_not_ready = 1;
++		spin_unlock_irq(&cm.lock);
+ 		/*
+ 		 * We flush the queue here after the going_down set, this
+ 		 * verify that no new works will be queued in the recv handler,
+ 		 * after that we can call the unregister_mad_agent
+ 		 */
+ 		flush_workqueue(cm.wq);
+-		ib_unregister_mad_agent(port->mad_agent);
++		spin_lock_irq(&cm.state_lock);
++		cur_mad_agent = port->mad_agent;
++		port->mad_agent = NULL;
++		spin_unlock_irq(&cm.state_lock);
++		ib_unregister_mad_agent(cur_mad_agent);
+ 		cm_remove_port_fs(port);
+ 	}
++
+ 	device_unregister(cm_dev->device);
+ 	kfree(cm_dev);
+ }
+@@ -3989,6 +4082,7 @@ static int __init ib_cm_init(void)
+ 	INIT_LIST_HEAD(&cm.device_list);
+ 	rwlock_init(&cm.device_lock);
+ 	spin_lock_init(&cm.lock);
++	spin_lock_init(&cm.state_lock);
+ 	cm.listen_service_table = RB_ROOT;
+ 	cm.listen_service_id = be64_to_cpu(IB_CM_ASSIGN_SERVICE_ID);
+ 	cm.remote_id_table = RB_ROOT;
+diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
+index c68746ce6624..bdab61d9103c 100644
+--- a/drivers/infiniband/core/umem.c
++++ b/drivers/infiniband/core/umem.c
+@@ -174,7 +174,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
+ 
+ 	cur_base = addr & PAGE_MASK;
+ 
+-	if (npages == 0) {
++	if (npages == 0 || npages > UINT_MAX) {
+ 		ret = -EINVAL;
+ 		goto out;
+ 	}
+diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
+index 0012fa58c105..44b1104eb168 100644
+--- a/drivers/infiniband/core/uverbs_main.c
++++ b/drivers/infiniband/core/uverbs_main.c
+@@ -262,12 +262,9 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file,
+ 			container_of(uobj, struct ib_uqp_object, uevent.uobject);
+ 
+ 		idr_remove_uobj(&ib_uverbs_qp_idr, uobj);
+-		if (qp != qp->real_qp) {
+-			ib_close_qp(qp);
+-		} else {
++		if (qp == qp->real_qp)
+ 			ib_uverbs_detach_umcast(qp, uqp);
+-			ib_destroy_qp(qp);
+-		}
++		ib_destroy_qp(qp);
+ 		ib_uverbs_release_uevent(file, &uqp->uevent);
+ 		kfree(uqp);
+ 	}
+diff --git a/drivers/infiniband/hw/hfi1/rc.c b/drivers/infiniband/hw/hfi1/rc.c
+index bcf76c33726b..e3629983f1bf 100644
+--- a/drivers/infiniband/hw/hfi1/rc.c
++++ b/drivers/infiniband/hw/hfi1/rc.c
+@@ -87,7 +87,7 @@ void hfi1_add_rnr_timer(struct rvt_qp *qp, u32 to)
+ 	struct hfi1_qp_priv *priv = qp->priv;
+ 
+ 	qp->s_flags |= RVT_S_WAIT_RNR;
+-	qp->s_timer.expires = jiffies + usecs_to_jiffies(to);
++	priv->s_rnr_timer.expires = jiffies + usecs_to_jiffies(to);
+ 	add_timer(&priv->s_rnr_timer);
+ }
+ 
+diff --git a/drivers/infiniband/hw/hfi1/user_sdma.c b/drivers/infiniband/hw/hfi1/user_sdma.c
+index 1694037d1eee..8f59a4fded93 100644
+--- a/drivers/infiniband/hw/hfi1/user_sdma.c
++++ b/drivers/infiniband/hw/hfi1/user_sdma.c
+@@ -1152,7 +1152,7 @@ static int pin_vector_pages(struct user_sdma_request *req,
+ 	rb_node = hfi1_mmu_rb_extract(pq->handler,
+ 				      (unsigned long)iovec->iov.iov_base,
+ 				      iovec->iov.iov_len);
+-	if (rb_node && !IS_ERR(rb_node))
++	if (rb_node)
+ 		node = container_of(rb_node, struct sdma_mmu_node, rb);
+ 	else
+ 		rb_node = NULL;
+diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
+index 5fc623362731..b9bf0759f10a 100644
+--- a/drivers/infiniband/hw/mlx4/ah.c
++++ b/drivers/infiniband/hw/mlx4/ah.c
+@@ -102,7 +102,10 @@ static struct ib_ah *create_iboe_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr
+ 	if (vlan_tag < 0x1000)
+ 		vlan_tag |= (ah_attr->sl & 7) << 13;
+ 	ah->av.eth.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
+-	ah->av.eth.gid_index = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
++	ret = mlx4_ib_gid_index_to_real_index(ibdev, ah_attr->port_num, ah_attr->grh.sgid_index);
++	if (ret < 0)
++		return ERR_PTR(ret);
++	ah->av.eth.gid_index = ret;
+ 	ah->av.eth.vlan = cpu_to_be16(vlan_tag);
+ 	ah->av.eth.hop_limit = ah_attr->grh.hop_limit;
+ 	if (ah_attr->static_rate) {
+diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c
+index 5df63dacaaa3..efb6414cc5e4 100644
+--- a/drivers/infiniband/hw/mlx4/cq.c
++++ b/drivers/infiniband/hw/mlx4/cq.c
+@@ -253,11 +253,14 @@ struct ib_cq *mlx4_ib_create_cq(struct ib_device *ibdev,
+ 	if (context)
+ 		if (ib_copy_to_udata(udata, &cq->mcq.cqn, sizeof (__u32))) {
+ 			err = -EFAULT;
+-			goto err_dbmap;
++			goto err_cq_free;
+ 		}
+ 
+ 	return &cq->ibcq;
+ 
++err_cq_free:
++	mlx4_cq_free(dev->dev, &cq->mcq);
++
+ err_dbmap:
+ 	if (context)
+ 		mlx4_ib_db_unmap_user(to_mucontext(context), &cq->db);
+diff --git a/drivers/infiniband/hw/mlx5/cq.c b/drivers/infiniband/hw/mlx5/cq.c
+index e4fac9292e4a..ebe43cb7d06b 100644
+--- a/drivers/infiniband/hw/mlx5/cq.c
++++ b/drivers/infiniband/hw/mlx5/cq.c
+@@ -917,8 +917,7 @@ struct ib_cq *mlx5_ib_create_cq(struct ib_device *ibdev,
+ 		if (err)
+ 			goto err_create;
+ 	} else {
+-		/* for now choose 64 bytes till we have a proper interface */
+-		cqe_size = 64;
++		cqe_size = cache_line_size() == 128 ? 128 : 64;
+ 		err = create_cq_kernel(dev, cq, entries, cqe_size, &cqb,
+ 				       &index, &inlen);
+ 		if (err)
+diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
+index bff8707a2f1f..19f8820b4e92 100644
+--- a/drivers/infiniband/hw/mlx5/main.c
++++ b/drivers/infiniband/hw/mlx5/main.c
+@@ -2100,14 +2100,14 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
+ {
+ 	struct mlx5_ib_dev *ibdev = (struct mlx5_ib_dev *)context;
+ 	struct ib_event ibev;
+-
++	bool fatal = false;
+ 	u8 port = 0;
+ 
+ 	switch (event) {
+ 	case MLX5_DEV_EVENT_SYS_ERROR:
+-		ibdev->ib_active = false;
+ 		ibev.event = IB_EVENT_DEVICE_FATAL;
+ 		mlx5_ib_handle_internal_error(ibdev);
++		fatal = true;
+ 		break;
+ 
+ 	case MLX5_DEV_EVENT_PORT_UP:
+@@ -2154,6 +2154,9 @@ static void mlx5_ib_event(struct mlx5_core_dev *dev, void *context,
+ 
+ 	if (ibdev->ib_active)
+ 		ib_dispatch_event(&ibev);
++
++	if (fatal)
++		ibdev->ib_active = false;
+ }
+ 
+ static void get_ext_port_caps(struct mlx5_ib_dev *dev)
+@@ -2835,7 +2838,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
+ 	}
+ 	err = init_node_data(dev);
+ 	if (err)
+-		goto err_dealloc;
++		goto err_free_port;
+ 
+ 	mutex_init(&dev->flow_db.lock);
+ 	mutex_init(&dev->cap_mask_mutex);
+@@ -2845,7 +2848,7 @@ static void *mlx5_ib_add(struct mlx5_core_dev *mdev)
+ 	if (ll == IB_LINK_LAYER_ETHERNET) {
+ 		err = mlx5_enable_roce(dev);
+ 		if (err)
+-			goto err_dealloc;
++			goto err_free_port;
+ 	}
+ 
+ 	err = create_dev_resources(&dev->devr);
+diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
+index affc3f6598ca..19d590d39484 100644
+--- a/drivers/infiniband/hw/mlx5/qp.c
++++ b/drivers/infiniband/hw/mlx5/qp.c
+@@ -2037,8 +2037,8 @@ struct ib_qp *mlx5_ib_create_qp(struct ib_pd *pd,
+ 
+ 		mlx5_ib_dbg(dev, "ib qpnum 0x%x, mlx qpn 0x%x, rcqn 0x%x, scqn 0x%x\n",
+ 			    qp->ibqp.qp_num, qp->trans_qp.base.mqp.qpn,
+-			    to_mcq(init_attr->recv_cq)->mcq.cqn,
+-			    to_mcq(init_attr->send_cq)->mcq.cqn);
++			    init_attr->recv_cq ? to_mcq(init_attr->recv_cq)->mcq.cqn : -1,
++			    init_attr->send_cq ? to_mcq(init_attr->send_cq)->mcq.cqn : -1);
+ 
+ 		qp->trans_qp.xrcdn = xrcdn;
+ 
+@@ -4702,6 +4702,14 @@ struct ib_rwq_ind_table *mlx5_ib_create_rwq_ind_table(struct ib_device *device,
+ 				 udata->inlen))
+ 		return ERR_PTR(-EOPNOTSUPP);
+ 
++	if (init_attr->log_ind_tbl_size >
++	    MLX5_CAP_GEN(dev->mdev, log_max_rqt_size)) {
++		mlx5_ib_dbg(dev, "log_ind_tbl_size = %d is bigger than supported = %d\n",
++			    init_attr->log_ind_tbl_size,
++			    MLX5_CAP_GEN(dev->mdev, log_max_rqt_size));
++		return ERR_PTR(-EINVAL);
++	}
++
+ 	min_resp_len = offsetof(typeof(resp), reserved) + sizeof(resp.reserved);
+ 	if (udata->outlen && udata->outlen < min_resp_len)
+ 		return ERR_PTR(-EINVAL);
+diff --git a/drivers/infiniband/sw/rdmavt/dma.c b/drivers/infiniband/sw/rdmavt/dma.c
+index 33076a5eee2f..04ebbb576385 100644
+--- a/drivers/infiniband/sw/rdmavt/dma.c
++++ b/drivers/infiniband/sw/rdmavt/dma.c
+@@ -90,9 +90,6 @@ static u64 rvt_dma_map_page(struct ib_device *dev, struct page *page,
+ 	if (WARN_ON(!valid_dma_direction(direction)))
+ 		return BAD_DMA_ADDRESS;
+ 
+-	if (offset + size > PAGE_SIZE)
+-		return BAD_DMA_ADDRESS;
+-
+ 	addr = (u64)page_address(page);
+ 	if (addr)
+ 		addr += offset;
+diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
+index eedf2f1cafdf..7f5d7358c99e 100644
+--- a/drivers/infiniband/sw/rxe/rxe_net.c
++++ b/drivers/infiniband/sw/rxe/rxe_net.c
+@@ -243,10 +243,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
+ {
+ 	int err;
+ 	struct socket *sock;
+-	struct udp_port_cfg udp_cfg;
+-	struct udp_tunnel_sock_cfg tnl_cfg;
+-
+-	memset(&udp_cfg, 0, sizeof(udp_cfg));
++	struct udp_port_cfg udp_cfg = {0};
++	struct udp_tunnel_sock_cfg tnl_cfg = {0};
+ 
+ 	if (ipv6) {
+ 		udp_cfg.family = AF_INET6;
+@@ -264,10 +262,8 @@ static struct socket *rxe_setup_udp_tunnel(struct net *net, __be16 port,
+ 		return ERR_PTR(err);
+ 	}
+ 
+-	tnl_cfg.sk_user_data = NULL;
+ 	tnl_cfg.encap_type = 1;
+ 	tnl_cfg.encap_rcv = rxe_udp_encap_recv;
+-	tnl_cfg.encap_destroy = NULL;
+ 
+ 	/* Setup UDP tunnel */
+ 	setup_udp_tunnel_sock(net, sock, &tnl_cfg);
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index 22ba24f2a2c1..f724a7ef9b67 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -522,6 +522,7 @@ static void rxe_qp_reset(struct rxe_qp *qp)
+ 	if (qp->sq.queue) {
+ 		__rxe_do_task(&qp->comp.task);
+ 		__rxe_do_task(&qp->req.task);
++		rxe_queue_reset(qp->sq.queue);
+ 	}
+ 
+ 	/* cleanup attributes */
+@@ -573,6 +574,7 @@ void rxe_qp_error(struct rxe_qp *qp)
+ {
+ 	qp->req.state = QP_STATE_ERROR;
+ 	qp->resp.state = QP_STATE_ERROR;
++	qp->attr.qp_state = IB_QPS_ERR;
+ 
+ 	/* drain work and packet queues */
+ 	rxe_run_task(&qp->resp.task, 1);
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.c b/drivers/infiniband/sw/rxe/rxe_queue.c
+index 08274254eb88..d14bf496d62d 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.c
++++ b/drivers/infiniband/sw/rxe/rxe_queue.c
+@@ -84,6 +84,15 @@ err1:
+ 	return -EINVAL;
+ }
+ 
++inline void rxe_queue_reset(struct rxe_queue *q)
++{
++	/* queue is comprised from header and the memory
++	 * of the actual queue. See "struct rxe_queue_buf" in rxe_queue.h
++	 * reset only the queue itself and not the management header
++	 */
++	memset(q->buf->data, 0, q->buf_size - sizeof(struct rxe_queue_buf));
++}
++
+ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe,
+ 				 int *num_elem,
+ 				 unsigned int elem_size)
+diff --git a/drivers/infiniband/sw/rxe/rxe_queue.h b/drivers/infiniband/sw/rxe/rxe_queue.h
+index 239fd609c31e..8c8641c87817 100644
+--- a/drivers/infiniband/sw/rxe/rxe_queue.h
++++ b/drivers/infiniband/sw/rxe/rxe_queue.h
+@@ -84,6 +84,8 @@ int do_mmap_info(struct rxe_dev *rxe,
+ 		 size_t buf_size,
+ 		 struct rxe_mmap_info **ip_p);
+ 
++void rxe_queue_reset(struct rxe_queue *q);
++
+ struct rxe_queue *rxe_queue_init(struct rxe_dev *rxe,
+ 				 int *num_elem,
+ 				 unsigned int elem_size);
+diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c
+index 13a848a518e8..43bb16649e44 100644
+--- a/drivers/infiniband/sw/rxe/rxe_req.c
++++ b/drivers/infiniband/sw/rxe/rxe_req.c
+@@ -695,7 +695,8 @@ next_wqe:
+ 						       qp->req.wqe_index);
+ 			wqe->state = wqe_state_done;
+ 			wqe->status = IB_WC_SUCCESS;
+-			goto complete;
++			__rxe_do_task(&qp->comp.task);
++			return 0;
+ 		}
+ 		payload = mtu;
+ 	}
+@@ -744,13 +745,17 @@ err:
+ 	wqe->status = IB_WC_LOC_PROT_ERR;
+ 	wqe->state = wqe_state_error;
+ 
+-complete:
+-	if (qp_type(qp) != IB_QPT_RC) {
+-		while (rxe_completer(qp) == 0)
+-			;
+-	}
+-
+-	return 0;
++	/*
++	 * IBA Spec. Section 10.7.3.1 SIGNALED COMPLETIONS
++	 * ---------8<---------8<-------------
++	 * ...Note that if a completion error occurs, a Work Completion
++	 * will always be generated, even if the signaling
++	 * indicator requests an Unsignaled Completion.
++	 * ---------8<---------8<-------------
++	 */
++	wqe->wr.send_flags |= IB_SEND_SIGNALED;
++	__rxe_do_task(&qp->comp.task);
++	return -EAGAIN;
+ 
+ exit:
+ 	return -EAGAIN;
+diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
+index 41b113875d64..70c646b0097d 100644
+--- a/drivers/mfd/intel-lpss.c
++++ b/drivers/mfd/intel-lpss.c
+@@ -502,9 +502,6 @@ int intel_lpss_suspend(struct device *dev)
+ 	for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
+ 		lpss->priv_ctx[i] = readl(lpss->priv + i * 4);
+ 
+-	/* Put the device into reset state */
+-	writel(0, lpss->priv + LPSS_PRIV_RESETS);
+-
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(intel_lpss_suspend);
+diff --git a/drivers/mfd/mfd-core.c b/drivers/mfd/mfd-core.c
+index 3ac486a597f3..c57e407020f1 100644
+--- a/drivers/mfd/mfd-core.c
++++ b/drivers/mfd/mfd-core.c
+@@ -399,6 +399,8 @@ int mfd_clone_cell(const char *cell, const char **clones, size_t n_clones)
+ 					clones[i]);
+ 	}
+ 
++	put_device(dev);
++
+ 	return 0;
+ }
+ EXPORT_SYMBOL(mfd_clone_cell);
+diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
+index 94c7cc02fdab..00dd7ff70e01 100644
+--- a/drivers/mfd/stmpe.c
++++ b/drivers/mfd/stmpe.c
+@@ -761,6 +761,8 @@ static int stmpe1801_reset(struct stmpe *stmpe)
+ 	if (ret < 0)
+ 		return ret;
+ 
++	msleep(10);
++
+ 	timeout = jiffies + msecs_to_jiffies(100);
+ 	while (time_before(jiffies, timeout)) {
+ 		ret = __stmpe_reg_read(stmpe, STMPE1801_REG_SYS_CTRL);
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index 1b5f531eeb25..bf3fd34924bd 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -2010,23 +2010,33 @@ static struct virtio_device_id id_table[] = {
+ 	{ 0 },
+ };
+ 
++#define VIRTNET_FEATURES \
++	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM, \
++	VIRTIO_NET_F_MAC, \
++	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6, \
++	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, \
++	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO, \
++	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ, \
++	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN, \
++	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ, \
++	VIRTIO_NET_F_CTRL_MAC_ADDR, \
++	VIRTIO_NET_F_MTU
++
+ static unsigned int features[] = {
+-	VIRTIO_NET_F_CSUM, VIRTIO_NET_F_GUEST_CSUM,
+-	VIRTIO_NET_F_GSO, VIRTIO_NET_F_MAC,
+-	VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_UFO, VIRTIO_NET_F_HOST_TSO6,
+-	VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6,
+-	VIRTIO_NET_F_GUEST_ECN, VIRTIO_NET_F_GUEST_UFO,
+-	VIRTIO_NET_F_MRG_RXBUF, VIRTIO_NET_F_STATUS, VIRTIO_NET_F_CTRL_VQ,
+-	VIRTIO_NET_F_CTRL_RX, VIRTIO_NET_F_CTRL_VLAN,
+-	VIRTIO_NET_F_GUEST_ANNOUNCE, VIRTIO_NET_F_MQ,
+-	VIRTIO_NET_F_CTRL_MAC_ADDR,
++	VIRTNET_FEATURES,
++};
++
++static unsigned int features_legacy[] = {
++	VIRTNET_FEATURES,
++	VIRTIO_NET_F_GSO,
+ 	VIRTIO_F_ANY_LAYOUT,
+-	VIRTIO_NET_F_MTU,
+ };
+ 
+ static struct virtio_driver virtio_net_driver = {
+ 	.feature_table = features,
+ 	.feature_table_size = ARRAY_SIZE(features),
++	.feature_table_legacy = features_legacy,
++	.feature_table_size_legacy = ARRAY_SIZE(features_legacy),
+ 	.driver.name =	KBUILD_MODNAME,
+ 	.driver.owner =	THIS_MODULE,
+ 	.id_table =	id_table,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+index 4fdc3dad3e85..ea67ae9c87a0 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/d3.c
+@@ -1087,6 +1087,15 @@ iwl_mvm_netdetect_config(struct iwl_mvm *mvm,
+ 		ret = iwl_mvm_switch_to_d3(mvm);
+ 		if (ret)
+ 			return ret;
++	} else {
++		/* In theory, we wouldn't have to stop a running sched
++		 * scan in order to start another one (for
++		 * net-detect).  But in practice this doesn't seem to
++		 * work properly, so stop any running sched_scan now.
++		 */
++		ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED, true);
++		if (ret)
++			return ret;
+ 	}
+ 
+ 	/* rfkill release can be either for wowlan or netdetect */
+@@ -2088,6 +2097,16 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
+ 	iwl_mvm_update_changed_regdom(mvm);
+ 
+ 	if (mvm->net_detect) {
++		/* If this is a non-unified image, we restart the FW,
++		 * so no need to stop the netdetect scan.  If that
++		 * fails, continue and try to get the wake-up reasons,
++		 * but trigger a HW restart by keeping a failure code
++		 * in ret.
++		 */
++		if (unified_image)
++			ret = iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_NETDETECT,
++						false);
++
+ 		iwl_mvm_query_netdetect_reasons(mvm, vif);
+ 		/* has unlocked the mutex, so skip that */
+ 		goto out;
+@@ -2271,7 +2290,8 @@ static void iwl_mvm_d3_test_disconn_work_iter(void *_data, u8 *mac,
+ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
+ {
+ 	struct iwl_mvm *mvm = inode->i_private;
+-	int remaining_time = 10;
++	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
++					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
+ 
+ 	mvm->d3_test_active = false;
+ 
+@@ -2282,17 +2302,21 @@ static int iwl_mvm_d3_test_release(struct inode *inode, struct file *file)
+ 	mvm->trans->system_pm_mode = IWL_PLAT_PM_MODE_DISABLED;
+ 
+ 	iwl_abort_notification_waits(&mvm->notif_wait);
+-	ieee80211_restart_hw(mvm->hw);
++	if (!unified_image) {
++		int remaining_time = 10;
+ 
+-	/* wait for restart and disconnect all interfaces */
+-	while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
+-	       remaining_time > 0) {
+-		remaining_time--;
+-		msleep(1000);
+-	}
++		ieee80211_restart_hw(mvm->hw);
+ 
+-	if (remaining_time == 0)
+-		IWL_ERR(mvm, "Timed out waiting for HW restart to finish!\n");
++		/* wait for restart and disconnect all interfaces */
++		while (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
++		       remaining_time > 0) {
++			remaining_time--;
++			msleep(1000);
++		}
++
++		if (remaining_time == 0)
++			IWL_ERR(mvm, "Timed out waiting for HW restart!\n");
++	}
+ 
+ 	ieee80211_iterate_active_interfaces_atomic(
+ 		mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+index 5dd77e336617..90a1f4a06ba1 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+@@ -4097,7 +4097,6 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ 				     struct iwl_mvm_internal_rxq_notif *notif,
+ 				     u32 size)
+ {
+-	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(notif_waitq);
+ 	u32 qmask = BIT(mvm->trans->num_rx_queues) - 1;
+ 	int ret;
+ 
+@@ -4119,7 +4118,7 @@ void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
+ 	}
+ 
+ 	if (notif->sync)
+-		ret = wait_event_timeout(notif_waitq,
++		ret = wait_event_timeout(mvm->rx_sync_waitq,
+ 					 atomic_read(&mvm->queue_sync_counter) == 0,
+ 					 HZ);
+ 	WARN_ON_ONCE(!ret);
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+index 6a615bb73042..e9cb970139c7 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+@@ -932,6 +932,7 @@ struct iwl_mvm {
+ 	/* sync d0i3_tx queue and IWL_MVM_STATUS_IN_D0I3 status flag */
+ 	spinlock_t d0i3_tx_lock;
+ 	wait_queue_head_t d0i3_exit_waitq;
++	wait_queue_head_t rx_sync_waitq;
+ 
+ 	/* BT-Coex */
+ 	struct iwl_bt_coex_profile_notif last_bt_notif;
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+index 55d9096da68c..30bbdec97d03 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c
+@@ -618,6 +618,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
+ 	spin_lock_init(&mvm->refs_lock);
+ 	skb_queue_head_init(&mvm->d0i3_tx);
+ 	init_waitqueue_head(&mvm->d0i3_exit_waitq);
++	init_waitqueue_head(&mvm->rx_sync_waitq);
+ 
+ 	atomic_set(&mvm->queue_sync_counter, 0);
+ 
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+index afb7eb60e454..2b994be10b42 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+@@ -545,7 +545,8 @@ void iwl_mvm_rx_queue_notif(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb,
+ 				  "Received expired RX queue sync message\n");
+ 			return;
+ 		}
+-		atomic_dec(&mvm->queue_sync_counter);
++		if (!atomic_dec_return(&mvm->queue_sync_counter))
++			wake_up(&mvm->rx_sync_waitq);
+ 	}
+ 
+ 	switch (internal_notif->type) {
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+index dac120f8861b..3707ec60b575 100644
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c
+@@ -1185,6 +1185,9 @@ static int iwl_mvm_num_scans(struct iwl_mvm *mvm)
+ 
+ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
+ {
++	bool unified_image = fw_has_capa(&mvm->fw->ucode_capa,
++					 IWL_UCODE_TLV_CAPA_CNSLDTD_D3_D0_IMG);
++
+ 	/* This looks a bit arbitrary, but the idea is that if we run
+ 	 * out of possible simultaneous scans and the userspace is
+ 	 * trying to run a scan type that is already running, we
+@@ -1211,12 +1214,30 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type)
+ 			return -EBUSY;
+ 		return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR, true);
+ 	case IWL_MVM_SCAN_NETDETECT:
+-		/* No need to stop anything for net-detect since the
+-		 * firmware is restarted anyway.  This way, any sched
+-		 * scans that were running will be restarted when we
+-		 * resume.
+-		*/
+-		return 0;
++		/* For non-unified images, there's no need to stop
++		 * anything for net-detect since the firmware is
++		 * restarted anyway.  This way, any sched scans that
++		 * were running will be restarted when we resume.
++		 */
++		if (!unified_image)
++			return 0;
++
++		/* If this is a unified image and we ran out of scans,
++		 * we need to stop something.  Prefer stopping regular
++		 * scans, because the results are useless at this
++		 * point, and we should be able to keep running
++		 * another scheduled scan while suspended.
++		 */
++		if (mvm->scan_status & IWL_MVM_SCAN_REGULAR_MASK)
++			return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_REGULAR,
++						 true);
++		if (mvm->scan_status & IWL_MVM_SCAN_SCHED_MASK)
++			return iwl_mvm_scan_stop(mvm, IWL_MVM_SCAN_SCHED,
++						 true);
++
++		/* fall through, something is wrong if no scan was
++		 * running but we ran out of scans.
++		 */
+ 	default:
+ 		WARN_ON(1);
+ 		break;
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+index 78cf9a7f3eac..13842ca124ab 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/drv.c
+@@ -526,48 +526,64 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
+ MODULE_DEVICE_TABLE(pci, iwl_hw_card_ids);
+ 
+ #ifdef CONFIG_ACPI
+-#define SPL_METHOD		"SPLC"
+-#define SPL_DOMAINTYPE_MODULE	BIT(0)
+-#define SPL_DOMAINTYPE_WIFI	BIT(1)
+-#define SPL_DOMAINTYPE_WIGIG	BIT(2)
+-#define SPL_DOMAINTYPE_RFEM	BIT(3)
++#define ACPI_SPLC_METHOD	"SPLC"
++#define ACPI_SPLC_DOMAIN_WIFI	(0x07)
+ 
+-static u64 splx_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splx)
++static u64 splc_get_pwr_limit(struct iwl_trans *trans, union acpi_object *splc)
+ {
+-	union acpi_object *limits, *domain_type, *power_limit;
+-
+-	if (splx->type != ACPI_TYPE_PACKAGE ||
+-	    splx->package.count != 2 ||
+-	    splx->package.elements[0].type != ACPI_TYPE_INTEGER ||
+-	    splx->package.elements[0].integer.value != 0) {
+-		IWL_ERR(trans, "Unsupported splx structure\n");
++	union acpi_object *data_pkg, *dflt_pwr_limit;
++	int i;
++
++	/* We need at least two elements, one for the revision and one
++	 * for the data itself.  Also check that the revision is
++	 * supported (currently only revision 0).
++	*/
++	if (splc->type != ACPI_TYPE_PACKAGE ||
++	    splc->package.count < 2 ||
++	    splc->package.elements[0].type != ACPI_TYPE_INTEGER ||
++	    splc->package.elements[0].integer.value != 0) {
++		IWL_DEBUG_INFO(trans,
++			       "Unsupported structure returned by the SPLC method.  Ignoring.\n");
+ 		return 0;
+ 	}
+ 
+-	limits = &splx->package.elements[1];
+-	if (limits->type != ACPI_TYPE_PACKAGE ||
+-	    limits->package.count < 2 ||
+-	    limits->package.elements[0].type != ACPI_TYPE_INTEGER ||
+-	    limits->package.elements[1].type != ACPI_TYPE_INTEGER) {
+-		IWL_ERR(trans, "Invalid limits element\n");
+-		return 0;
++	/* loop through all the packages to find the one for WiFi */
++	for (i = 1; i < splc->package.count; i++) {
++		union acpi_object *domain;
++
++		data_pkg = &splc->package.elements[i];
++
++		/* Skip anything that is not a package with the right
++		 * amount of elements (i.e. at least 2 integers).
++		 */
++		if (data_pkg->type != ACPI_TYPE_PACKAGE ||
++		    data_pkg->package.count < 2 ||
++		    data_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
++		    data_pkg->package.elements[1].type != ACPI_TYPE_INTEGER)
++			continue;
++
++		domain = &data_pkg->package.elements[0];
++		if (domain->integer.value == ACPI_SPLC_DOMAIN_WIFI)
++			break;
++
++		data_pkg = NULL;
+ 	}
+ 
+-	domain_type = &limits->package.elements[0];
+-	power_limit = &limits->package.elements[1];
+-	if (!(domain_type->integer.value & SPL_DOMAINTYPE_WIFI)) {
+-		IWL_DEBUG_INFO(trans, "WiFi power is not limited\n");
++	if (!data_pkg) {
++		IWL_DEBUG_INFO(trans,
++			       "No element for the WiFi domain returned by the SPLC method.\n");
+ 		return 0;
+ 	}
+ 
+-	return power_limit->integer.value;
++	dflt_pwr_limit = &data_pkg->package.elements[1];
++	return dflt_pwr_limit->integer.value;
+ }
+ 
+ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
+ {
+ 	acpi_handle pxsx_handle;
+ 	acpi_handle handle;
+-	struct acpi_buffer splx = {ACPI_ALLOCATE_BUFFER, NULL};
++	struct acpi_buffer splc = {ACPI_ALLOCATE_BUFFER, NULL};
+ 	acpi_status status;
+ 
+ 	pxsx_handle = ACPI_HANDLE(&pdev->dev);
+@@ -578,23 +594,24 @@ static void set_dflt_pwr_limit(struct iwl_trans *trans, struct pci_dev *pdev)
+ 	}
+ 
+ 	/* Get the method's handle */
+-	status = acpi_get_handle(pxsx_handle, (acpi_string)SPL_METHOD, &handle);
++	status = acpi_get_handle(pxsx_handle, (acpi_string)ACPI_SPLC_METHOD,
++				 &handle);
+ 	if (ACPI_FAILURE(status)) {
+-		IWL_DEBUG_INFO(trans, "SPL method not found\n");
++		IWL_DEBUG_INFO(trans, "SPLC method not found\n");
+ 		return;
+ 	}
+ 
+ 	/* Call SPLC with no arguments */
+-	status = acpi_evaluate_object(handle, NULL, NULL, &splx);
++	status = acpi_evaluate_object(handle, NULL, NULL, &splc);
+ 	if (ACPI_FAILURE(status)) {
+ 		IWL_ERR(trans, "SPLC invocation failed (0x%x)\n", status);
+ 		return;
+ 	}
+ 
+-	trans->dflt_pwr_limit = splx_get_pwr_limit(trans, splx.pointer);
++	trans->dflt_pwr_limit = splc_get_pwr_limit(trans, splc.pointer);
+ 	IWL_DEBUG_INFO(trans, "Default power limit set to %lld\n",
+ 		       trans->dflt_pwr_limit);
+-	kfree(splx.pointer);
++	kfree(splc.pointer);
+ }
+ 
+ #else /* CONFIG_ACPI */
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+index 18650dccdb58..478bba527977 100644
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/tx.c
+@@ -522,6 +522,7 @@ error:
+ static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
+ 			      int slots_num, u32 txq_id)
+ {
++	struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ 	int ret;
+ 
+ 	txq->need_update = false;
+@@ -536,6 +537,13 @@ static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
+ 		return ret;
+ 
+ 	spin_lock_init(&txq->lock);
++
++	if (txq_id == trans_pcie->cmd_queue) {
++		static struct lock_class_key iwl_pcie_cmd_queue_lock_class;
++
++		lockdep_set_class(&txq->lock, &iwl_pcie_cmd_queue_lock_class);
++	}
++
+ 	__skb_queue_head_init(&txq->overflow_q);
+ 
+ 	/*
+diff --git a/drivers/rtc/rtc-omap.c b/drivers/rtc/rtc-omap.c
+index ec2e9c5fb993..22394fe30579 100644
+--- a/drivers/rtc/rtc-omap.c
++++ b/drivers/rtc/rtc-omap.c
+@@ -109,6 +109,7 @@
+ /* OMAP_RTC_OSC_REG bit fields: */
+ #define OMAP_RTC_OSC_32KCLK_EN		BIT(6)
+ #define OMAP_RTC_OSC_SEL_32KCLK_SRC	BIT(3)
++#define OMAP_RTC_OSC_OSC32K_GZ_DISABLE	BIT(4)
+ 
+ /* OMAP_RTC_IRQWAKEEN bit fields: */
+ #define OMAP_RTC_IRQWAKEEN_ALARM_WAKEEN	BIT(1)
+@@ -646,8 +647,9 @@ static int omap_rtc_probe(struct platform_device *pdev)
+ 	 */
+ 	if (rtc->has_ext_clk) {
+ 		reg = rtc_read(rtc, OMAP_RTC_OSC_REG);
+-		rtc_write(rtc, OMAP_RTC_OSC_REG,
+-			  reg | OMAP_RTC_OSC_SEL_32KCLK_SRC);
++		reg &= ~OMAP_RTC_OSC_OSC32K_GZ_DISABLE;
++		reg |= OMAP_RTC_OSC_32KCLK_EN | OMAP_RTC_OSC_SEL_32KCLK_SRC;
++		rtc_writel(rtc, OMAP_RTC_OSC_REG, reg);
+ 	}
+ 
+ 	rtc->type->lock(rtc);
+diff --git a/drivers/uwb/lc-rc.c b/drivers/uwb/lc-rc.c
+index d059ad4d0dbd..97ee1b46db69 100644
+--- a/drivers/uwb/lc-rc.c
++++ b/drivers/uwb/lc-rc.c
+@@ -56,8 +56,11 @@ static struct uwb_rc *uwb_rc_find_by_index(int index)
+ 	struct uwb_rc *rc = NULL;
+ 
+ 	dev = class_find_device(&uwb_rc_class, NULL, &index, uwb_rc_index_match);
+-	if (dev)
++	if (dev) {
+ 		rc = dev_get_drvdata(dev);
++		put_device(dev);
++	}
++
+ 	return rc;
+ }
+ 
+@@ -467,7 +470,9 @@ struct uwb_rc *__uwb_rc_try_get(struct uwb_rc *target_rc)
+ 	if (dev) {
+ 		rc = dev_get_drvdata(dev);
+ 		__uwb_rc_get(rc);
++		put_device(dev);
+ 	}
++
+ 	return rc;
+ }
+ EXPORT_SYMBOL_GPL(__uwb_rc_try_get);
+@@ -520,8 +525,11 @@ struct uwb_rc *uwb_rc_get_by_grandpa(const struct device *grandpa_dev)
+ 
+ 	dev = class_find_device(&uwb_rc_class, NULL, grandpa_dev,
+ 				find_rc_grandpa);
+-	if (dev)
++	if (dev) {
+ 		rc = dev_get_drvdata(dev);
++		put_device(dev);
++	}
++
+ 	return rc;
+ }
+ EXPORT_SYMBOL_GPL(uwb_rc_get_by_grandpa);
+@@ -553,8 +561,10 @@ struct uwb_rc *uwb_rc_get_by_dev(const struct uwb_dev_addr *addr)
+ 	struct uwb_rc *rc = NULL;
+ 
+ 	dev = class_find_device(&uwb_rc_class, NULL, addr, find_rc_dev);
+-	if (dev)
++	if (dev) {
+ 		rc = dev_get_drvdata(dev);
++		put_device(dev);
++	}
+ 
+ 	return rc;
+ }
+diff --git a/drivers/uwb/pal.c b/drivers/uwb/pal.c
+index c1304b8d4985..678e93741ae1 100644
+--- a/drivers/uwb/pal.c
++++ b/drivers/uwb/pal.c
+@@ -97,6 +97,8 @@ static bool uwb_rc_class_device_exists(struct uwb_rc *target_rc)
+ 
+ 	dev = class_find_device(&uwb_rc_class, NULL, target_rc,	find_rc);
+ 
++	put_device(dev);
++
+ 	return (dev != NULL);
+ }
+ 
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
+index ea31931386ec..7bd21aaedaaf 100644
+--- a/fs/ext4/ext4.h
++++ b/fs/ext4/ext4.h
+@@ -235,6 +235,7 @@ struct ext4_io_submit {
+ #define	EXT4_MAX_BLOCK_SIZE		65536
+ #define EXT4_MIN_BLOCK_LOG_SIZE		10
+ #define EXT4_MAX_BLOCK_LOG_SIZE		16
++#define EXT4_MAX_CLUSTER_LOG_SIZE	30
+ #ifdef __KERNEL__
+ # define EXT4_BLOCK_SIZE(s)		((s)->s_blocksize)
+ #else
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 3ec8708989ca..ec89f5005c2d 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3518,7 +3518,15 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	if (blocksize < EXT4_MIN_BLOCK_SIZE ||
+ 	    blocksize > EXT4_MAX_BLOCK_SIZE) {
+ 		ext4_msg(sb, KERN_ERR,
+-		       "Unsupported filesystem blocksize %d", blocksize);
++		       "Unsupported filesystem blocksize %d (%d log_block_size)",
++			 blocksize, le32_to_cpu(es->s_log_block_size));
++		goto failed_mount;
++	}
++	if (le32_to_cpu(es->s_log_block_size) >
++	    (EXT4_MAX_BLOCK_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
++		ext4_msg(sb, KERN_ERR,
++			 "Invalid log block size: %u",
++			 le32_to_cpu(es->s_log_block_size));
+ 		goto failed_mount;
+ 	}
+ 
+@@ -3650,6 +3658,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 				 "block size (%d)", clustersize, blocksize);
+ 			goto failed_mount;
+ 		}
++		if (le32_to_cpu(es->s_log_cluster_size) >
++		    (EXT4_MAX_CLUSTER_LOG_SIZE - EXT4_MIN_BLOCK_LOG_SIZE)) {
++			ext4_msg(sb, KERN_ERR,
++				 "Invalid log cluster size: %u",
++				 le32_to_cpu(es->s_log_cluster_size));
++			goto failed_mount;
++		}
+ 		sbi->s_cluster_bits = le32_to_cpu(es->s_log_cluster_size) -
+ 			le32_to_cpu(es->s_log_block_size);
+ 		sbi->s_clusters_per_group =
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index 3988b43c2f5a..a621dd98a865 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -1985,6 +1985,10 @@ static int fuse_write_end(struct file *file, struct address_space *mapping,
+ {
+ 	struct inode *inode = page->mapping->host;
+ 
++	/* Haven't copied anything?  Skip zeroing, size extending, dirtying. */
++	if (!copied)
++		goto unlock;
++
+ 	if (!PageUptodate(page)) {
+ 		/* Zero any unwritten bytes at the end of the page */
+ 		size_t endoff = (pos + copied) & ~PAGE_MASK;
+@@ -1995,6 +1999,8 @@ static int fuse_write_end(struct file *file, struct address_space *mapping,
+ 
+ 	fuse_write_update_size(inode, pos + copied);
+ 	set_page_dirty(page);
++
++unlock:
+ 	unlock_page(page);
+ 	put_page(page);
+ 
+diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
+index ab02a457da1f..e5d193440374 100644
+--- a/include/linux/sunrpc/svc_xprt.h
++++ b/include/linux/sunrpc/svc_xprt.h
+@@ -25,6 +25,7 @@ struct svc_xprt_ops {
+ 	void		(*xpo_detach)(struct svc_xprt *);
+ 	void		(*xpo_free)(struct svc_xprt *);
+ 	int		(*xpo_secure_port)(struct svc_rqst *);
++	void		(*xpo_kill_temp_xprt)(struct svc_xprt *);
+ };
+ 
+ struct svc_xprt_class {
+diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
+index 9530fcd27704..9d592c66f754 100644
+--- a/kernel/irq/manage.c
++++ b/kernel/irq/manage.c
+@@ -1341,12 +1341,12 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
+ 
+ 	} else if (new->flags & IRQF_TRIGGER_MASK) {
+ 		unsigned int nmsk = new->flags & IRQF_TRIGGER_MASK;
+-		unsigned int omsk = irq_settings_get_trigger_mask(desc);
++		unsigned int omsk = irqd_get_trigger_type(&desc->irq_data);
+ 
+ 		if (nmsk != omsk)
+ 			/* hope the handler works with current  trigger mode */
+ 			pr_warn("irq %d uses trigger mode %u; requested %u\n",
+-				irq, nmsk, omsk);
++				irq, omsk, nmsk);
+ 	}
+ 
+ 	*old_ptr = new;
+diff --git a/kernel/power/suspend_test.c b/kernel/power/suspend_test.c
+index 084452e34a12..bdff5ed57f10 100644
+--- a/kernel/power/suspend_test.c
++++ b/kernel/power/suspend_test.c
+@@ -203,8 +203,10 @@ static int __init test_suspend(void)
+ 
+ 	/* RTCs have initialized by now too ... can we use one? */
+ 	dev = class_find_device(rtc_class, NULL, NULL, has_wakealarm);
+-	if (dev)
++	if (dev) {
+ 		rtc = rtc_class_open(dev_name(dev));
++		put_device(dev);
++	}
+ 	if (!rtc) {
+ 		printk(warn_no_rtc);
+ 		return 0;
+diff --git a/kernel/trace/Makefile b/kernel/trace/Makefile
+index d0a1617b52b4..979e7bfbde7a 100644
+--- a/kernel/trace/Makefile
++++ b/kernel/trace/Makefile
+@@ -1,8 +1,4 @@
+ 
+-# We are fully aware of the dangers of __builtin_return_address()
+-FRAME_CFLAGS := $(call cc-disable-warning,frame-address)
+-KBUILD_CFLAGS += $(FRAME_CFLAGS)
+-
+ # Do not instrument the tracer itself:
+ 
+ ifdef CONFIG_FUNCTION_TRACER
+diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
+index 84752c8e28b5..b1d7f1b5e791 100644
+--- a/kernel/trace/ftrace.c
++++ b/kernel/trace/ftrace.c
+@@ -1856,6 +1856,10 @@ static int __ftrace_hash_update_ipmodify(struct ftrace_ops *ops,
+ 
+ 	/* Update rec->flags */
+ 	do_for_each_ftrace_rec(pg, rec) {
++
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		/* We need to update only differences of filter_hash */
+ 		in_old = !!ftrace_lookup_ip(old_hash, rec->ip);
+ 		in_new = !!ftrace_lookup_ip(new_hash, rec->ip);
+@@ -1878,6 +1882,10 @@ rollback:
+ 
+ 	/* Roll back what we did above */
+ 	do_for_each_ftrace_rec(pg, rec) {
++
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		if (rec == end)
+ 			goto err_out;
+ 
+@@ -2391,6 +2399,10 @@ void __weak ftrace_replace_code(int enable)
+ 		return;
+ 
+ 	do_for_each_ftrace_rec(pg, rec) {
++
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		failed = __ftrace_replace_code(rec, enable);
+ 		if (failed) {
+ 			ftrace_bug(failed, rec);
+@@ -2757,7 +2769,7 @@ static int ftrace_shutdown(struct ftrace_ops *ops, int command)
+ 		struct dyn_ftrace *rec;
+ 
+ 		do_for_each_ftrace_rec(pg, rec) {
+-			if (FTRACE_WARN_ON_ONCE(rec->flags))
++			if (FTRACE_WARN_ON_ONCE(rec->flags & ~FTRACE_FL_DISABLED))
+ 				pr_warn("  %pS flags:%lx\n",
+ 					(void *)rec->ip, rec->flags);
+ 		} while_for_each_ftrace_rec();
+@@ -3592,6 +3604,10 @@ match_records(struct ftrace_hash *hash, char *func, int len, char *mod)
+ 		goto out_unlock;
+ 
+ 	do_for_each_ftrace_rec(pg, rec) {
++
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		if (ftrace_match_record(rec, &func_g, mod_match, exclude_mod)) {
+ 			ret = enter_record(hash, rec, clear_filter);
+ 			if (ret < 0) {
+@@ -3787,6 +3803,9 @@ register_ftrace_function_probe(char *glob, struct ftrace_probe_ops *ops,
+ 
+ 	do_for_each_ftrace_rec(pg, rec) {
+ 
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		if (!ftrace_match_record(rec, &func_g, NULL, 0))
+ 			continue;
+ 
+@@ -4679,6 +4698,9 @@ ftrace_set_func(unsigned long *array, int *idx, int size, char *buffer)
+ 
+ 	do_for_each_ftrace_rec(pg, rec) {
+ 
++		if (rec->flags & FTRACE_FL_DISABLED)
++			continue;
++
+ 		if (ftrace_match_record(rec, &func_g, NULL, 0)) {
+ 			/* if it is in the array */
+ 			exists = false;
+diff --git a/mm/Makefile b/mm/Makefile
+index 2ca1faf3fa09..295bd7a9f76b 100644
+--- a/mm/Makefile
++++ b/mm/Makefile
+@@ -21,9 +21,6 @@ KCOV_INSTRUMENT_memcontrol.o := n
+ KCOV_INSTRUMENT_mmzone.o := n
+ KCOV_INSTRUMENT_vmstat.o := n
+ 
+-# Since __builtin_frame_address does work as used, disable the warning.
+-CFLAGS_usercopy.o += $(call cc-disable-warning, frame-address)
+-
+ mmu-y			:= nommu.o
+ mmu-$(CONFIG_MMU)	:= gup.o highmem.o memory.o mincore.o \
+ 			   mlock.o mmap.o mprotect.o mremap.o msync.o rmap.o \
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index 8e999ffdf28b..8af9d25ff988 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -1549,24 +1549,31 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
+ 	struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
+ 	struct sock *sk = sock->sk;
+ 	struct bcm_sock *bo = bcm_sk(sk);
++	int ret = 0;
+ 
+ 	if (len < sizeof(*addr))
+ 		return -EINVAL;
+ 
+-	if (bo->bound)
+-		return -EISCONN;
++	lock_sock(sk);
++
++	if (bo->bound) {
++		ret = -EISCONN;
++		goto fail;
++	}
+ 
+ 	/* bind a device to this socket */
+ 	if (addr->can_ifindex) {
+ 		struct net_device *dev;
+ 
+ 		dev = dev_get_by_index(&init_net, addr->can_ifindex);
+-		if (!dev)
+-			return -ENODEV;
+-
++		if (!dev) {
++			ret = -ENODEV;
++			goto fail;
++		}
+ 		if (dev->type != ARPHRD_CAN) {
+ 			dev_put(dev);
+-			return -ENODEV;
++			ret = -ENODEV;
++			goto fail;
+ 		}
+ 
+ 		bo->ifindex = dev->ifindex;
+@@ -1577,17 +1584,24 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len,
+ 		bo->ifindex = 0;
+ 	}
+ 
+-	bo->bound = 1;
+-
+ 	if (proc_dir) {
+ 		/* unique socket address as filename */
+ 		sprintf(bo->procname, "%lu", sock_i_ino(sk));
+ 		bo->bcm_proc_read = proc_create_data(bo->procname, 0644,
+ 						     proc_dir,
+ 						     &bcm_proc_fops, sk);
++		if (!bo->bcm_proc_read) {
++			ret = -ENOMEM;
++			goto fail;
++		}
+ 	}
+ 
+-	return 0;
++	bo->bound = 1;
++
++fail:
++	release_sock(sk);
++
++	return ret;
+ }
+ 
+ static int bcm_recvmsg(struct socket *sock, struct msghdr *msg, size_t size,
+diff --git a/net/netfilter/nft_dynset.c b/net/netfilter/nft_dynset.c
+index 0af26699bf04..584ac76ec555 100644
+--- a/net/netfilter/nft_dynset.c
++++ b/net/netfilter/nft_dynset.c
+@@ -143,7 +143,8 @@ static int nft_dynset_init(const struct nft_ctx *ctx,
+ 	if (tb[NFTA_DYNSET_TIMEOUT] != NULL) {
+ 		if (!(set->flags & NFT_SET_TIMEOUT))
+ 			return -EINVAL;
+-		timeout = be64_to_cpu(nla_get_be64(tb[NFTA_DYNSET_TIMEOUT]));
++		timeout = msecs_to_jiffies(be64_to_cpu(nla_get_be64(
++						tb[NFTA_DYNSET_TIMEOUT])));
+ 	}
+ 
+ 	priv->sreg_key = nft_parse_register(tb[NFTA_DYNSET_SREG_KEY]);
+@@ -230,7 +231,8 @@ static int nft_dynset_dump(struct sk_buff *skb, const struct nft_expr *expr)
+ 		goto nla_put_failure;
+ 	if (nla_put_string(skb, NFTA_DYNSET_SET_NAME, priv->set->name))
+ 		goto nla_put_failure;
+-	if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT, cpu_to_be64(priv->timeout),
++	if (nla_put_be64(skb, NFTA_DYNSET_TIMEOUT,
++			 cpu_to_be64(jiffies_to_msecs(priv->timeout)),
+ 			 NFTA_DYNSET_PAD))
+ 		goto nla_put_failure;
+ 	if (priv->expr && nft_expr_dump(skb, NFTA_DYNSET_EXPR, priv->expr))
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index c3f652395a80..3bc1d61694cb 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -1002,14 +1002,8 @@ static void svc_age_temp_xprts(unsigned long closure)
+ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
+ {
+ 	struct svc_xprt *xprt;
+-	struct svc_sock *svsk;
+-	struct socket *sock;
+ 	struct list_head *le, *next;
+ 	LIST_HEAD(to_be_closed);
+-	struct linger no_linger = {
+-		.l_onoff = 1,
+-		.l_linger = 0,
+-	};
+ 
+ 	spin_lock_bh(&serv->sv_lock);
+ 	list_for_each_safe(le, next, &serv->sv_tempsocks) {
+@@ -1027,10 +1021,7 @@ void svc_age_temp_xprts_now(struct svc_serv *serv, struct sockaddr *server_addr)
+ 		list_del_init(le);
+ 		xprt = list_entry(le, struct svc_xprt, xpt_list);
+ 		dprintk("svc_age_temp_xprts_now: closing %p\n", xprt);
+-		svsk = container_of(xprt, struct svc_sock, sk_xprt);
+-		sock = svsk->sk_sock;
+-		kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
+-				  (char *)&no_linger, sizeof(no_linger));
++		xprt->xpt_ops->xpo_kill_temp_xprt(xprt);
+ 		svc_close_xprt(xprt);
+ 	}
+ }
+diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
+index 57625f64efd5..a4bc98265d88 100644
+--- a/net/sunrpc/svcsock.c
++++ b/net/sunrpc/svcsock.c
+@@ -438,6 +438,21 @@ static int svc_tcp_has_wspace(struct svc_xprt *xprt)
+ 	return !test_bit(SOCK_NOSPACE, &svsk->sk_sock->flags);
+ }
+ 
++static void svc_tcp_kill_temp_xprt(struct svc_xprt *xprt)
++{
++	struct svc_sock *svsk;
++	struct socket *sock;
++	struct linger no_linger = {
++		.l_onoff = 1,
++		.l_linger = 0,
++	};
++
++	svsk = container_of(xprt, struct svc_sock, sk_xprt);
++	sock = svsk->sk_sock;
++	kernel_setsockopt(sock, SOL_SOCKET, SO_LINGER,
++			  (char *)&no_linger, sizeof(no_linger));
++}
++
+ /*
+  * See net/ipv6/ip_sockglue.c : ip_cmsg_recv_pktinfo
+  */
+@@ -648,6 +663,10 @@ static struct svc_xprt *svc_udp_accept(struct svc_xprt *xprt)
+ 	return NULL;
+ }
+ 
++static void svc_udp_kill_temp_xprt(struct svc_xprt *xprt)
++{
++}
++
+ static struct svc_xprt *svc_udp_create(struct svc_serv *serv,
+ 				       struct net *net,
+ 				       struct sockaddr *sa, int salen,
+@@ -667,6 +686,7 @@ static struct svc_xprt_ops svc_udp_ops = {
+ 	.xpo_has_wspace = svc_udp_has_wspace,
+ 	.xpo_accept = svc_udp_accept,
+ 	.xpo_secure_port = svc_sock_secure_port,
++	.xpo_kill_temp_xprt = svc_udp_kill_temp_xprt,
+ };
+ 
+ static struct svc_xprt_class svc_udp_class = {
+@@ -1242,6 +1262,7 @@ static struct svc_xprt_ops svc_tcp_ops = {
+ 	.xpo_has_wspace = svc_tcp_has_wspace,
+ 	.xpo_accept = svc_tcp_accept,
+ 	.xpo_secure_port = svc_sock_secure_port,
++	.xpo_kill_temp_xprt = svc_tcp_kill_temp_xprt,
+ };
+ 
+ static struct svc_xprt_class svc_tcp_class = {
+diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+index 924271c9ef3e..a55b8093a7f9 100644
+--- a/net/sunrpc/xprtrdma/svc_rdma_transport.c
++++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c
+@@ -67,6 +67,7 @@ static void svc_rdma_detach(struct svc_xprt *xprt);
+ static void svc_rdma_free(struct svc_xprt *xprt);
+ static int svc_rdma_has_wspace(struct svc_xprt *xprt);
+ static int svc_rdma_secure_port(struct svc_rqst *);
++static void svc_rdma_kill_temp_xprt(struct svc_xprt *);
+ 
+ static struct svc_xprt_ops svc_rdma_ops = {
+ 	.xpo_create = svc_rdma_create,
+@@ -79,6 +80,7 @@ static struct svc_xprt_ops svc_rdma_ops = {
+ 	.xpo_has_wspace = svc_rdma_has_wspace,
+ 	.xpo_accept = svc_rdma_accept,
+ 	.xpo_secure_port = svc_rdma_secure_port,
++	.xpo_kill_temp_xprt = svc_rdma_kill_temp_xprt,
+ };
+ 
+ struct svc_xprt_class svc_rdma_class = {
+@@ -1285,6 +1287,10 @@ static int svc_rdma_secure_port(struct svc_rqst *rqstp)
+ 	return 1;
+ }
+ 
++static void svc_rdma_kill_temp_xprt(struct svc_xprt *xprt)
++{
++}
++
+ int svc_rdma_send(struct svcxprt_rdma *xprt, struct ib_send_wr *wr)
+ {
+ 	struct ib_send_wr *bad_wr, *n_wr;
+diff --git a/scripts/gcc-x86_64-has-stack-protector.sh b/scripts/gcc-x86_64-has-stack-protector.sh
+index 973e8c141567..17867e723a51 100755
+--- a/scripts/gcc-x86_64-has-stack-protector.sh
++++ b/scripts/gcc-x86_64-has-stack-protector.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ 
+-echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
++echo "int foo(void) { char X[200]; return 3; }" | $* -S -x c -c -O0 -mcmodel=kernel -fno-PIE -fstack-protector - -o - 2> /dev/null | grep -q "%gs"
+ if [ "$?" -eq "0" ] ; then
+ 	echo y
+ else
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 26e866f65314..162818058a5d 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -6905,8 +6905,6 @@ static const struct hda_fixup alc662_fixups[] = {
+ 		.v.pins = (const struct hda_pintbl[]) {
+ 			{ 0x15, 0x40f000f0 }, /* disabled */
+ 			{ 0x16, 0x40f000f0 }, /* disabled */
+-			{ 0x18, 0x01014011 }, /* LO */
+-			{ 0x1a, 0x01014012 }, /* LO */
+ 			{ }
+ 		}
+ 	},
+diff --git a/sound/pci/hda/thinkpad_helper.c b/sound/pci/hda/thinkpad_helper.c
+index 6a23302297c9..4d9d320a7971 100644
+--- a/sound/pci/hda/thinkpad_helper.c
++++ b/sound/pci/hda/thinkpad_helper.c
+@@ -13,7 +13,8 @@ static void (*old_vmaster_hook)(void *, int);
+ static bool is_thinkpad(struct hda_codec *codec)
+ {
+ 	return (codec->core.subsystem_id >> 16 == 0x17aa) &&
+-	       (acpi_dev_found("LEN0068") || acpi_dev_found("IBM0068"));
++	       (acpi_dev_found("LEN0068") || acpi_dev_found("LEN0268") ||
++		acpi_dev_found("IBM0068"));
+ }
+ 
+ static void update_tpacpi_mute_led(void *private_data, int enabled)
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index 9e5276d6dda0..2ddc034673a8 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -315,7 +315,8 @@ static int snd_usb_audio_free(struct snd_usb_audio *chip)
+ 		snd_usb_endpoint_free(ep);
+ 
+ 	mutex_destroy(&chip->mutex);
+-	dev_set_drvdata(&chip->dev->dev, NULL);
++	if (!atomic_read(&chip->shutdown))
++		dev_set_drvdata(&chip->dev->dev, NULL);
+ 	kfree(chip);
+ 	return 0;
+ }
+diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
+index de15dbcdcecf..7214913861cf 100644
+--- a/tools/perf/util/hist.c
++++ b/tools/perf/util/hist.c
+@@ -1596,18 +1596,18 @@ static void hists__hierarchy_output_resort(struct hists *hists,
+ 		if (prog)
+ 			ui_progress__update(prog, 1);
+ 
++		hists->nr_entries++;
++		if (!he->filtered) {
++			hists->nr_non_filtered_entries++;
++			hists__calc_col_len(hists, he);
++		}
++
+ 		if (!he->leaf) {
+ 			hists__hierarchy_output_resort(hists, prog,
+ 						       &he->hroot_in,
+ 						       &he->hroot_out,
+ 						       min_callchain_hits,
+ 						       use_callchain);
+-			hists->nr_entries++;
+-			if (!he->filtered) {
+-				hists->nr_non_filtered_entries++;
+-				hists__calc_col_len(hists, he);
+-			}
+-
+ 			continue;
+ 		}
+ 
+diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c
+index 6e9c40eea208..69ccce308458 100644
+--- a/virt/kvm/arm/pmu.c
++++ b/virt/kvm/arm/pmu.c
+@@ -305,7 +305,7 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val)
+ 			continue;
+ 		type = vcpu_sys_reg(vcpu, PMEVTYPER0_EL0 + i)
+ 		       & ARMV8_PMU_EVTYPE_EVENT;
+-		if ((type == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
++		if ((type == ARMV8_PMUV3_PERFCTR_SW_INCR)
+ 		    && (enable & BIT(i))) {
+ 			reg = vcpu_sys_reg(vcpu, PMEVCNTR0_EL0 + i) + 1;
+ 			reg = lower_32_bits(reg);
+@@ -379,7 +379,8 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
+ 	eventsel = data & ARMV8_PMU_EVTYPE_EVENT;
+ 
+ 	/* Software increment event does't need to be backed by a perf event */
+-	if (eventsel == ARMV8_PMU_EVTYPE_EVENT_SW_INCR)
++	if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR &&
++	    select_idx != ARMV8_PMU_CYCLE_IDX)
+ 		return;
+ 
+ 	memset(&attr, 0, sizeof(struct perf_event_attr));
+@@ -391,7 +392,8 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data,
+ 	attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0;
+ 	attr.exclude_hv = 1; /* Don't count EL2 events */
+ 	attr.exclude_host = 1; /* Don't count host events */
+-	attr.config = eventsel;
++	attr.config = (select_idx == ARMV8_PMU_CYCLE_IDX) ?
++		ARMV8_PMUV3_PERFCTR_CPU_CYCLES : eventsel;
+ 
+ 	counter = kvm_pmu_get_counter_value(vcpu, select_idx);
+ 	/* The initial sample period (overflow count) of an event. */


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-12-02 16:23 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-12-02 16:23 UTC (permalink / raw
  To: gentoo-commits

commit:     27ab52c49dea953256202d19c96202f5cf703bbe
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Fri Dec  2 16:22:48 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Fri Dec  2 16:22:48 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=27ab52c4

Linux patch 4.8.12

 0000_README             |    4 +
 1011_linux-4.8.12.patch | 1563 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1567 insertions(+)

diff --git a/0000_README b/0000_README
index 4aa1baf..cd56013 100644
--- a/0000_README
+++ b/0000_README
@@ -87,6 +87,10 @@ Patch:  1010_linux-4.8.11.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.11
 
+Patch:  1011_linux-4.8.12.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.12
+
 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/1011_linux-4.8.12.patch b/1011_linux-4.8.12.patch
new file mode 100644
index 0000000..9855afb
--- /dev/null
+++ b/1011_linux-4.8.12.patch
@@ -0,0 +1,1563 @@
+diff --git a/Makefile b/Makefile
+index 2b1bcbacebcd..7b0c92f53169 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 11
++SUBLEVEL = 12
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
+index af12c2db9bb8..81c11a62b1fa 100644
+--- a/arch/parisc/Kconfig
++++ b/arch/parisc/Kconfig
+@@ -33,7 +33,9 @@ config PARISC
+ 	select HAVE_ARCH_HASH
+ 	select HAVE_ARCH_SECCOMP_FILTER
+ 	select HAVE_ARCH_TRACEHOOK
+-	select HAVE_UNSTABLE_SCHED_CLOCK if (SMP || !64BIT)
++	select GENERIC_SCHED_CLOCK
++	select HAVE_UNSTABLE_SCHED_CLOCK if SMP
++	select GENERIC_CLOCKEVENTS
+ 	select ARCH_NO_COHERENT_DMA_MMAP
+ 	select CPU_NO_EFFICIENT_FFS
+ 
+diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
+index 67001277256c..c2259d4a3c33 100644
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -369,6 +369,7 @@ void __init parisc_setup_cache_timing(void)
+ {
+ 	unsigned long rangetime, alltime;
+ 	unsigned long size, start;
++	unsigned long threshold;
+ 
+ 	alltime = mfctl(16);
+ 	flush_data_cache();
+@@ -382,17 +383,12 @@ void __init parisc_setup_cache_timing(void)
+ 	printk(KERN_DEBUG "Whole cache flush %lu cycles, flushing %lu bytes %lu cycles\n",
+ 		alltime, size, rangetime);
+ 
+-	/* Racy, but if we see an intermediate value, it's ok too... */
+-	parisc_cache_flush_threshold = size * alltime / rangetime;
+-
+-	parisc_cache_flush_threshold = L1_CACHE_ALIGN(parisc_cache_flush_threshold);
+-	if (!parisc_cache_flush_threshold)
+-		parisc_cache_flush_threshold = FLUSH_THRESHOLD;
+-
+-	if (parisc_cache_flush_threshold > cache_info.dc_size)
+-		parisc_cache_flush_threshold = cache_info.dc_size;
+-
+-	printk(KERN_INFO "Setting cache flush threshold to %lu kB\n",
++	threshold = L1_CACHE_ALIGN(size * alltime / rangetime);
++	if (threshold > cache_info.dc_size)
++		threshold = cache_info.dc_size;
++	if (threshold)
++		parisc_cache_flush_threshold = threshold;
++	printk(KERN_INFO "Cache flush threshold set to %lu KiB\n",
+ 		parisc_cache_flush_threshold/1024);
+ 
+ 	/* calculate TLB flush threshold */
+@@ -401,7 +397,7 @@ void __init parisc_setup_cache_timing(void)
+ 	flush_tlb_all();
+ 	alltime = mfctl(16) - alltime;
+ 
+-	size = PAGE_SIZE;
++	size = 0;
+ 	start = (unsigned long) _text;
+ 	rangetime = mfctl(16);
+ 	while (start < (unsigned long) _end) {
+@@ -414,13 +410,10 @@ void __init parisc_setup_cache_timing(void)
+ 	printk(KERN_DEBUG "Whole TLB flush %lu cycles, flushing %lu bytes %lu cycles\n",
+ 		alltime, size, rangetime);
+ 
+-	parisc_tlb_flush_threshold = size * alltime / rangetime;
+-	parisc_tlb_flush_threshold *= num_online_cpus();
+-	parisc_tlb_flush_threshold = PAGE_ALIGN(parisc_tlb_flush_threshold);
+-	if (!parisc_tlb_flush_threshold)
+-		parisc_tlb_flush_threshold = FLUSH_TLB_THRESHOLD;
+-
+-	printk(KERN_INFO "Setting TLB flush threshold to %lu kB\n",
++	threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
++	if (threshold)
++		parisc_tlb_flush_threshold = threshold;
++	printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
+ 		parisc_tlb_flush_threshold/1024);
+ }
+ 
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+index b743a80eaba0..675521919229 100644
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -96,7 +96,7 @@ fitmanyloop:					/* Loop if LOOP >= 2 */
+ 
+ fitmanymiddle:					/* Loop if LOOP >= 2 */
+ 	addib,COND(>)		-1, %r31, fitmanymiddle	/* Adjusted inner loop decr */
+-	pitlbe		0(%sr1, %r28)
++	pitlbe		%r0(%sr1, %r28)
+ 	pitlbe,m	%arg1(%sr1, %r28)	/* Last pitlbe and addr adjust */
+ 	addib,COND(>)		-1, %r29, fitmanymiddle	/* Middle loop decr */
+ 	copy		%arg3, %r31		/* Re-init inner loop count */
+@@ -139,7 +139,7 @@ fdtmanyloop:					/* Loop if LOOP >= 2 */
+ 
+ fdtmanymiddle:					/* Loop if LOOP >= 2 */
+ 	addib,COND(>)		-1, %r31, fdtmanymiddle	/* Adjusted inner loop decr */
+-	pdtlbe		0(%sr1, %r28)
++	pdtlbe		%r0(%sr1, %r28)
+ 	pdtlbe,m	%arg1(%sr1, %r28)	/* Last pdtlbe and addr adjust */
+ 	addib,COND(>)		-1, %r29, fdtmanymiddle	/* Middle loop decr */
+ 	copy		%arg3, %r31		/* Re-init inner loop count */
+@@ -620,12 +620,12 @@ ENTRY(copy_user_page_asm)
+ 	/* Purge any old translations */
+ 
+ #ifdef CONFIG_PA20
+-	pdtlb,l		0(%r28)
+-	pdtlb,l		0(%r29)
++	pdtlb,l		%r0(%r28)
++	pdtlb,l		%r0(%r29)
+ #else
+ 	tlb_lock	%r20,%r21,%r22
+-	pdtlb		0(%r28)
+-	pdtlb		0(%r29)
++	pdtlb		%r0(%r28)
++	pdtlb		%r0(%r29)
+ 	tlb_unlock	%r20,%r21,%r22
+ #endif
+ 
+@@ -768,10 +768,10 @@ ENTRY(clear_user_page_asm)
+ 	/* Purge any old translation */
+ 
+ #ifdef CONFIG_PA20
+-	pdtlb,l		0(%r28)
++	pdtlb,l		%r0(%r28)
+ #else
+ 	tlb_lock	%r20,%r21,%r22
+-	pdtlb		0(%r28)
++	pdtlb		%r0(%r28)
+ 	tlb_unlock	%r20,%r21,%r22
+ #endif
+ 
+@@ -852,10 +852,10 @@ ENTRY(flush_dcache_page_asm)
+ 	/* Purge any old translation */
+ 
+ #ifdef CONFIG_PA20
+-	pdtlb,l		0(%r28)
++	pdtlb,l		%r0(%r28)
+ #else
+ 	tlb_lock	%r20,%r21,%r22
+-	pdtlb		0(%r28)
++	pdtlb		%r0(%r28)
+ 	tlb_unlock	%r20,%r21,%r22
+ #endif
+ 
+@@ -892,10 +892,10 @@ ENTRY(flush_dcache_page_asm)
+ 	sync
+ 
+ #ifdef CONFIG_PA20
+-	pdtlb,l		0(%r25)
++	pdtlb,l		%r0(%r25)
+ #else
+ 	tlb_lock	%r20,%r21,%r22
+-	pdtlb		0(%r25)
++	pdtlb		%r0(%r25)
+ 	tlb_unlock	%r20,%r21,%r22
+ #endif
+ 
+@@ -925,13 +925,18 @@ ENTRY(flush_icache_page_asm)
+ 	depwi		0, 31,PAGE_SHIFT, %r28	/* Clear any offset bits */
+ #endif
+ 
+-	/* Purge any old translation */
++	/* Purge any old translation.  Note that the FIC instruction
++	 * may use either the instruction or data TLB.  Given that we
++	 * have a flat address space, it's not clear which TLB will be
++	 * used.  So, we purge both entries.  */
+ 
+ #ifdef CONFIG_PA20
++	pdtlb,l		%r0(%r28)
+ 	pitlb,l         %r0(%sr4,%r28)
+ #else
+ 	tlb_lock        %r20,%r21,%r22
+-	pitlb           (%sr4,%r28)
++	pdtlb		%r0(%r28)
++	pitlb           %r0(%sr4,%r28)
+ 	tlb_unlock      %r20,%r21,%r22
+ #endif
+ 
+@@ -970,10 +975,12 @@ ENTRY(flush_icache_page_asm)
+ 	sync
+ 
+ #ifdef CONFIG_PA20
++	pdtlb,l		%r0(%r28)
+ 	pitlb,l         %r0(%sr4,%r25)
+ #else
+ 	tlb_lock        %r20,%r21,%r22
+-	pitlb           (%sr4,%r25)
++	pdtlb		%r0(%r28)
++	pitlb           %r0(%sr4,%r25)
+ 	tlb_unlock      %r20,%r21,%r22
+ #endif
+ 
+diff --git a/arch/parisc/kernel/pci-dma.c b/arch/parisc/kernel/pci-dma.c
+index 02d9ed0f3949..494ff6e8c88a 100644
+--- a/arch/parisc/kernel/pci-dma.c
++++ b/arch/parisc/kernel/pci-dma.c
+@@ -95,8 +95,8 @@ static inline int map_pte_uncached(pte_t * pte,
+ 
+ 		if (!pte_none(*pte))
+ 			printk(KERN_ERR "map_pte_uncached: page already exists\n");
+-		set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
+ 		purge_tlb_start(flags);
++		set_pte(pte, __mk_pte(*paddr_ptr, PAGE_KERNEL_UNC));
+ 		pdtlb_kernel(orig_vaddr);
+ 		purge_tlb_end(flags);
+ 		vaddr += PAGE_SIZE;
+diff --git a/arch/parisc/kernel/setup.c b/arch/parisc/kernel/setup.c
+index 81d6f6391944..2e66a887788e 100644
+--- a/arch/parisc/kernel/setup.c
++++ b/arch/parisc/kernel/setup.c
+@@ -334,6 +334,10 @@ static int __init parisc_init(void)
+ 	/* tell PDC we're Linux. Nevermind failure. */
+ 	pdc_stable_write(0x40, &osid, sizeof(osid));
+ 	
++	/* start with known state */
++	flush_cache_all_local();
++	flush_tlb_all_local(NULL);
++
+ 	processor_init();
+ #ifdef CONFIG_SMP
+ 	pr_info("CPU(s): %d out of %d %s at %d.%06d MHz online\n",
+diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c
+index 9b63b876a13a..325f30d82b64 100644
+--- a/arch/parisc/kernel/time.c
++++ b/arch/parisc/kernel/time.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/rtc.h>
+ #include <linux/sched.h>
++#include <linux/sched_clock.h>
+ #include <linux/kernel.h>
+ #include <linux/param.h>
+ #include <linux/string.h>
+@@ -39,18 +40,6 @@
+ 
+ static unsigned long clocktick __read_mostly;	/* timer cycles per tick */
+ 
+-#ifndef CONFIG_64BIT
+-/*
+- * The processor-internal cycle counter (Control Register 16) is used as time
+- * source for the sched_clock() function.  This register is 64bit wide on a
+- * 64-bit kernel and 32bit on a 32-bit kernel. Since sched_clock() always
+- * requires a 64bit counter we emulate on the 32-bit kernel the higher 32bits
+- * with a per-cpu variable which we increase every time the counter
+- * wraps-around (which happens every ~4 secounds).
+- */
+-static DEFINE_PER_CPU(unsigned long, cr16_high_32_bits);
+-#endif
+-
+ /*
+  * We keep time on PA-RISC Linux by using the Interval Timer which is
+  * a pair of registers; one is read-only and one is write-only; both
+@@ -121,12 +110,6 @@ irqreturn_t __irq_entry timer_interrupt(int irq, void *dev_id)
+ 	 */
+ 	mtctl(next_tick, 16);
+ 
+-#if !defined(CONFIG_64BIT)
+-	/* check for overflow on a 32bit kernel (every ~4 seconds). */
+-	if (unlikely(next_tick < now))
+-		this_cpu_inc(cr16_high_32_bits);
+-#endif
+-
+ 	/* Skip one clocktick on purpose if we missed next_tick.
+ 	 * The new CR16 must be "later" than current CR16 otherwise
+ 	 * itimer would not fire until CR16 wrapped - e.g 4 seconds
+@@ -208,7 +191,7 @@ EXPORT_SYMBOL(profile_pc);
+ 
+ /* clock source code */
+ 
+-static cycle_t read_cr16(struct clocksource *cs)
++static cycle_t notrace read_cr16(struct clocksource *cs)
+ {
+ 	return get_cycles();
+ }
+@@ -287,26 +270,9 @@ void read_persistent_clock(struct timespec *ts)
+ }
+ 
+ 
+-/*
+- * sched_clock() framework
+- */
+-
+-static u32 cyc2ns_mul __read_mostly;
+-static u32 cyc2ns_shift __read_mostly;
+-
+-u64 sched_clock(void)
++static u64 notrace read_cr16_sched_clock(void)
+ {
+-	u64 now;
+-
+-	/* Get current cycle counter (Control Register 16). */
+-#ifdef CONFIG_64BIT
+-	now = mfctl(16);
+-#else
+-	now = mfctl(16) + (((u64) this_cpu_read(cr16_high_32_bits)) << 32);
+-#endif
+-
+-	/* return the value in ns (cycles_2_ns) */
+-	return mul_u64_u32_shr(now, cyc2ns_mul, cyc2ns_shift);
++	return get_cycles();
+ }
+ 
+ 
+@@ -316,17 +282,16 @@ u64 sched_clock(void)
+ 
+ void __init time_init(void)
+ {
+-	unsigned long current_cr16_khz;
++	unsigned long cr16_hz;
+ 
+-	current_cr16_khz = PAGE0->mem_10msec/10;  /* kHz */
+ 	clocktick = (100 * PAGE0->mem_10msec) / HZ;
+-
+-	/* calculate mult/shift values for cr16 */
+-	clocks_calc_mult_shift(&cyc2ns_mul, &cyc2ns_shift, current_cr16_khz,
+-				NSEC_PER_MSEC, 0);
+-
+ 	start_cpu_itimer();	/* get CPU 0 started */
+ 
++	cr16_hz = 100 * PAGE0->mem_10msec;  /* Hz */
++
+ 	/* register at clocksource framework */
+-	clocksource_register_khz(&clocksource_cr16, current_cr16_khz);
++	clocksource_register_hz(&clocksource_cr16, cr16_hz);
++
++	/* register as sched_clock source */
++	sched_clock_register(read_cr16_sched_clock, BITS_PER_LONG, cr16_hz);
+ }
+diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
+index d80161b633f4..60522d22a428 100644
+--- a/arch/powerpc/boot/main.c
++++ b/arch/powerpc/boot/main.c
+@@ -217,8 +217,12 @@ void start(void)
+ 		console_ops.close();
+ 
+ 	kentry = (kernel_entry_t) vmlinux.addr;
+-	if (ft_addr)
+-		kentry(ft_addr, 0, NULL);
++	if (ft_addr) {
++		if(platform_ops.kentry)
++			platform_ops.kentry(ft_addr, vmlinux.addr);
++		else
++			kentry(ft_addr, 0, NULL);
++	}
+ 	else
+ 		kentry((unsigned long)initrd.addr, initrd.size,
+ 		       loader_info.promptr);
+diff --git a/arch/powerpc/boot/opal-calls.S b/arch/powerpc/boot/opal-calls.S
+index ff2f1b97bc53..2a99fc9a3ccf 100644
+--- a/arch/powerpc/boot/opal-calls.S
++++ b/arch/powerpc/boot/opal-calls.S
+@@ -12,6 +12,19 @@
+ 
+ 	.text
+ 
++	.globl opal_kentry
++opal_kentry:
++	/* r3 is the fdt ptr */
++	mtctr r4
++	li	r4, 0
++	li	r5, 0
++	li	r6, 0
++	li	r7, 0
++	ld	r11,opal@got(r2)
++	ld	r8,0(r11)
++	ld	r9,8(r11)
++	bctr
++
+ #define OPAL_CALL(name, token)				\
+ 	.globl name;					\
+ name:							\
+diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
+index 1f37e1c1d6d8..d7b4fd47eb44 100644
+--- a/arch/powerpc/boot/opal.c
++++ b/arch/powerpc/boot/opal.c
+@@ -23,14 +23,25 @@ struct opal {
+ 
+ static u32 opal_con_id;
+ 
++/* see opal-wrappers.S */
+ int64_t opal_console_write(int64_t term_number, u64 *length, const u8 *buffer);
+ int64_t opal_console_read(int64_t term_number, uint64_t *length, u8 *buffer);
+ int64_t opal_console_write_buffer_space(uint64_t term_number, uint64_t *length);
+ int64_t opal_console_flush(uint64_t term_number);
+ int64_t opal_poll_events(uint64_t *outstanding_event_mask);
+ 
++void opal_kentry(unsigned long fdt_addr, void *vmlinux_addr);
++
+ static int opal_con_open(void)
+ {
++	/*
++	 * When OPAL loads the boot kernel it stashes the OPAL base and entry
++	 * address in r8 and r9 so the kernel can use the OPAL console
++	 * before unflattening the devicetree. While executing the wrapper will
++	 * probably trash r8 and r9 so this kentry hook restores them before
++	 * entering the decompressed kernel.
++	 */
++	platform_ops.kentry = opal_kentry;
+ 	return 0;
+ }
+ 
+diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
+index e19b64ef977a..deeae6f6ba9c 100644
+--- a/arch/powerpc/boot/ops.h
++++ b/arch/powerpc/boot/ops.h
+@@ -30,6 +30,7 @@ struct platform_ops {
+ 	void *	(*realloc)(void *ptr, unsigned long size);
+ 	void	(*exit)(void);
+ 	void *	(*vmlinux_alloc)(unsigned long size);
++	void  	(*kentry)(unsigned long fdt_addr, void *vmlinux_addr);
+ };
+ extern struct platform_ops platform_ops;
+ 
+diff --git a/arch/powerpc/include/asm/mmu.h b/arch/powerpc/include/asm/mmu.h
+index e2fb408f8398..fd10b582fb2d 100644
+--- a/arch/powerpc/include/asm/mmu.h
++++ b/arch/powerpc/include/asm/mmu.h
+@@ -29,6 +29,12 @@
+  */
+ 
+ /*
++ * Kernel read only support.
++ * We added the ppp value 0b110 in ISA 2.04.
++ */
++#define MMU_FTR_KERNEL_RO		ASM_CONST(0x00004000)
++
++/*
+  * We need to clear top 16bits of va (from the remaining 64 bits )in
+  * tlbie* instructions
+  */
+@@ -103,10 +109,10 @@
+ #define MMU_FTRS_POWER4		MMU_FTRS_DEFAULT_HPTE_ARCH_V2
+ #define MMU_FTRS_PPC970		MMU_FTRS_POWER4 | MMU_FTR_TLBIE_CROP_VA
+ #define MMU_FTRS_POWER5		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+-#define MMU_FTRS_POWER6		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+-#define MMU_FTRS_POWER7		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+-#define MMU_FTRS_POWER8		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
+-#define MMU_FTRS_POWER9		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE
++#define MMU_FTRS_POWER6		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
++#define MMU_FTRS_POWER7		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
++#define MMU_FTRS_POWER8		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
++#define MMU_FTRS_POWER9		MMU_FTRS_POWER4 | MMU_FTR_LOCKLESS_TLBIE | MMU_FTR_KERNEL_RO
+ #define MMU_FTRS_CELL		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
+ 				MMU_FTR_CI_LARGE_PAGE
+ #define MMU_FTRS_PA6T		MMU_FTRS_DEFAULT_HPTE_ARCH_V2 | \
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index 978dada662ae..52cbf043e960 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -355,6 +355,7 @@
+ #define     LPCR_PECE0		ASM_CONST(0x0000000000004000)	/* ext. exceptions can cause exit */
+ #define     LPCR_PECE1		ASM_CONST(0x0000000000002000)	/* decrementer can cause exit */
+ #define     LPCR_PECE2		ASM_CONST(0x0000000000001000)	/* machine check etc can cause exit */
++#define     LPCR_PECE_HVEE	ASM_CONST(0x0000400000000000)	/* P9 Wakeup on HV interrupts */
+ #define   LPCR_MER		ASM_CONST(0x0000000000000800)	/* Mediated External Exception */
+ #define   LPCR_MER_SH		11
+ #define   LPCR_TC		ASM_CONST(0x0000000000000200)	/* Translation control */
+diff --git a/arch/powerpc/kernel/cpu_setup_power.S b/arch/powerpc/kernel/cpu_setup_power.S
+index 52ff3f025437..37c027ca83b2 100644
+--- a/arch/powerpc/kernel/cpu_setup_power.S
++++ b/arch/powerpc/kernel/cpu_setup_power.S
+@@ -98,8 +98,8 @@ _GLOBAL(__setup_cpu_power9)
+ 	li	r0,0
+ 	mtspr	SPRN_LPID,r0
+ 	mfspr	r3,SPRN_LPCR
+-	ori	r3, r3, LPCR_PECEDH
+-	ori	r3, r3, LPCR_HVICE
++	LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
++	or	r3, r3, r4
+ 	bl	__init_LPCR
+ 	bl	__init_HFSCR
+ 	bl	__init_tlb_power9
+@@ -118,8 +118,8 @@ _GLOBAL(__restore_cpu_power9)
+ 	li	r0,0
+ 	mtspr	SPRN_LPID,r0
+ 	mfspr   r3,SPRN_LPCR
+-	ori	r3, r3, LPCR_PECEDH
+-	ori	r3, r3, LPCR_HVICE
++	LOAD_REG_IMMEDIATE(r4, LPCR_PECEDH | LPCR_PECE_HVEE | LPCR_HVICE)
++	or	r3, r3, r4
+ 	bl	__init_LPCR
+ 	bl	__init_HFSCR
+ 	bl	__init_tlb_power9
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+index 28923b2e2df1..8dff9ce6fbc1 100644
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -190,8 +190,12 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
+ 		/*
+ 		 * Kernel read only mapped with ppp bits 0b110
+ 		 */
+-		if (!(pteflags & _PAGE_WRITE))
+-			rflags |= (HPTE_R_PP0 | 0x2);
++		if (!(pteflags & _PAGE_WRITE)) {
++			if (mmu_has_feature(MMU_FTR_KERNEL_RO))
++				rflags |= (HPTE_R_PP0 | 0x2);
++			else
++				rflags |= 0x3;
++		}
+ 	} else {
+ 		if (pteflags & _PAGE_RWX)
+ 			rflags |= 0x2;
+diff --git a/arch/tile/kernel/time.c b/arch/tile/kernel/time.c
+index 178989e6d3e3..ea960d660917 100644
+--- a/arch/tile/kernel/time.c
++++ b/arch/tile/kernel/time.c
+@@ -218,8 +218,8 @@ void do_timer_interrupt(struct pt_regs *regs, int fault_num)
+  */
+ unsigned long long sched_clock(void)
+ {
+-	return clocksource_cyc2ns(get_cycles(),
+-				  sched_clock_mult, SCHED_CLOCK_SHIFT);
++	return mult_frac(get_cycles(),
++			 sched_clock_mult, 1ULL << SCHED_CLOCK_SHIFT);
+ }
+ 
+ int setup_profiling_timer(unsigned int multiplier)
+diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
+index 9b983a474253..8fc714b4f18a 100644
+--- a/arch/x86/events/intel/ds.c
++++ b/arch/x86/events/intel/ds.c
+@@ -1070,20 +1070,20 @@ static void setup_pebs_sample_data(struct perf_event *event,
+ 	}
+ 
+ 	/*
+-	 * We use the interrupt regs as a base because the PEBS record
+-	 * does not contain a full regs set, specifically it seems to
+-	 * lack segment descriptors, which get used by things like
+-	 * user_mode().
++	 * We use the interrupt regs as a base because the PEBS record does not
++	 * contain a full regs set, specifically it seems to lack segment
++	 * descriptors, which get used by things like user_mode().
+ 	 *
+-	 * In the simple case fix up only the IP and BP,SP regs, for
+-	 * PERF_SAMPLE_IP and PERF_SAMPLE_CALLCHAIN to function properly.
+-	 * A possible PERF_SAMPLE_REGS will have to transfer all regs.
++	 * In the simple case fix up only the IP for PERF_SAMPLE_IP.
++	 *
++	 * We must however always use BP,SP from iregs for the unwinder to stay
++	 * sane; the record BP,SP can point into thin air when the record is
++	 * from a previous PMI context or an (I)RET happend between the record
++	 * and PMI.
+ 	 */
+ 	*regs = *iregs;
+ 	regs->flags = pebs->flags;
+ 	set_linear_ip(regs, pebs->ip);
+-	regs->bp = pebs->bp;
+-	regs->sp = pebs->sp;
+ 
+ 	if (sample_type & PERF_SAMPLE_REGS_INTR) {
+ 		regs->ax = pebs->ax;
+@@ -1092,10 +1092,21 @@ static void setup_pebs_sample_data(struct perf_event *event,
+ 		regs->dx = pebs->dx;
+ 		regs->si = pebs->si;
+ 		regs->di = pebs->di;
+-		regs->bp = pebs->bp;
+-		regs->sp = pebs->sp;
+ 
+-		regs->flags = pebs->flags;
++		/*
++		 * Per the above; only set BP,SP if we don't need callchains.
++		 *
++		 * XXX: does this make sense?
++		 */
++		if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) {
++			regs->bp = pebs->bp;
++			regs->sp = pebs->sp;
++		}
++
++		/*
++		 * Preserve PERF_EFLAGS_VM from set_linear_ip().
++		 */
++		regs->flags = pebs->flags | (regs->flags & PERF_EFLAGS_VM);
+ #ifndef CONFIG_X86_32
+ 		regs->r8 = pebs->r8;
+ 		regs->r9 = pebs->r9;
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index 8c4a47706296..181c238d4df9 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -113,7 +113,7 @@ struct debug_store {
+  * Per register state.
+  */
+ struct er_account {
+-	raw_spinlock_t		lock;	/* per-core: protect structure */
++	raw_spinlock_t      lock;	/* per-core: protect structure */
+ 	u64                 config;	/* extra MSR config */
+ 	u64                 reg;	/* extra MSR number */
+ 	atomic_t            ref;	/* reference count */
+diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
+index 3fc03a09a93b..c289e2f4a6e5 100644
+--- a/arch/x86/kernel/fpu/core.c
++++ b/arch/x86/kernel/fpu/core.c
+@@ -517,14 +517,14 @@ void fpu__clear(struct fpu *fpu)
+ {
+ 	WARN_ON_FPU(fpu != &current->thread.fpu); /* Almost certainly an anomaly */
+ 
+-	if (!use_eager_fpu() || !static_cpu_has(X86_FEATURE_FPU)) {
+-		/* FPU state will be reallocated lazily at the first use. */
+-		fpu__drop(fpu);
+-	} else {
+-		if (!fpu->fpstate_active) {
+-			fpu__activate_curr(fpu);
+-			user_fpu_begin();
+-		}
++	fpu__drop(fpu);
++
++	/*
++	 * Make sure fpstate is cleared and initialized.
++	 */
++	if (static_cpu_has(X86_FEATURE_FPU)) {
++		fpu__activate_curr(fpu);
++		user_fpu_begin();
+ 		copy_init_fpstate_to_fpregs();
+ 	}
+ }
+diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
+index cbd7b92585bb..a3ce9d260d68 100644
+--- a/arch/x86/kvm/emulate.c
++++ b/arch/x86/kvm/emulate.c
+@@ -2105,16 +2105,10 @@ static int em_iret(struct x86_emulate_ctxt *ctxt)
+ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
+ {
+ 	int rc;
+-	unsigned short sel, old_sel;
+-	struct desc_struct old_desc, new_desc;
+-	const struct x86_emulate_ops *ops = ctxt->ops;
++	unsigned short sel;
++	struct desc_struct new_desc;
+ 	u8 cpl = ctxt->ops->cpl(ctxt);
+ 
+-	/* Assignment of RIP may only fail in 64-bit mode */
+-	if (ctxt->mode == X86EMUL_MODE_PROT64)
+-		ops->get_segment(ctxt, &old_sel, &old_desc, NULL,
+-				 VCPU_SREG_CS);
+-
+ 	memcpy(&sel, ctxt->src.valptr + ctxt->op_bytes, 2);
+ 
+ 	rc = __load_segment_descriptor(ctxt, sel, VCPU_SREG_CS, cpl,
+@@ -2124,12 +2118,10 @@ static int em_jmp_far(struct x86_emulate_ctxt *ctxt)
+ 		return rc;
+ 
+ 	rc = assign_eip_far(ctxt, ctxt->src.val, &new_desc);
+-	if (rc != X86EMUL_CONTINUE) {
+-		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
+-		/* assigning eip failed; restore the old cs */
+-		ops->set_segment(ctxt, old_sel, &old_desc, 0, VCPU_SREG_CS);
+-		return rc;
+-	}
++	/* Error handling is not implemented. */
++	if (rc != X86EMUL_CONTINUE)
++		return X86EMUL_UNHANDLEABLE;
++
+ 	return rc;
+ }
+ 
+@@ -2189,14 +2181,8 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
+ {
+ 	int rc;
+ 	unsigned long eip, cs;
+-	u16 old_cs;
+ 	int cpl = ctxt->ops->cpl(ctxt);
+-	struct desc_struct old_desc, new_desc;
+-	const struct x86_emulate_ops *ops = ctxt->ops;
+-
+-	if (ctxt->mode == X86EMUL_MODE_PROT64)
+-		ops->get_segment(ctxt, &old_cs, &old_desc, NULL,
+-				 VCPU_SREG_CS);
++	struct desc_struct new_desc;
+ 
+ 	rc = emulate_pop(ctxt, &eip, ctxt->op_bytes);
+ 	if (rc != X86EMUL_CONTINUE)
+@@ -2213,10 +2199,10 @@ static int em_ret_far(struct x86_emulate_ctxt *ctxt)
+ 	if (rc != X86EMUL_CONTINUE)
+ 		return rc;
+ 	rc = assign_eip_far(ctxt, eip, &new_desc);
+-	if (rc != X86EMUL_CONTINUE) {
+-		WARN_ON(ctxt->mode != X86EMUL_MODE_PROT64);
+-		ops->set_segment(ctxt, old_cs, &old_desc, 0, VCPU_SREG_CS);
+-	}
++	/* Error handling is not implemented. */
++	if (rc != X86EMUL_CONTINUE)
++		return X86EMUL_UNHANDLEABLE;
++
+ 	return rc;
+ }
+ 
+diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c
+index 1a22de70f7f7..6e219e5c07d2 100644
+--- a/arch/x86/kvm/ioapic.c
++++ b/arch/x86/kvm/ioapic.c
+@@ -94,7 +94,7 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
+ static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
+ {
+ 	ioapic->rtc_status.pending_eoi = 0;
+-	bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPUS);
++	bitmap_zero(ioapic->rtc_status.dest_map.map, KVM_MAX_VCPU_ID);
+ }
+ 
+ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
+diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h
+index 7d2692a49657..1cc6e54436db 100644
+--- a/arch/x86/kvm/ioapic.h
++++ b/arch/x86/kvm/ioapic.h
+@@ -42,13 +42,13 @@ struct kvm_vcpu;
+ 
+ struct dest_map {
+ 	/* vcpu bitmap where IRQ has been sent */
+-	DECLARE_BITMAP(map, KVM_MAX_VCPUS);
++	DECLARE_BITMAP(map, KVM_MAX_VCPU_ID);
+ 
+ 	/*
+ 	 * Vector sent to a given vcpu, only valid when
+ 	 * the vcpu's bit in map is set
+ 	 */
+-	u8 vectors[KVM_MAX_VCPUS];
++	u8 vectors[KVM_MAX_VCPU_ID];
+ };
+ 
+ 
+diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c
+index 25810b144b58..e7a112ac51a8 100644
+--- a/arch/x86/kvm/irq_comm.c
++++ b/arch/x86/kvm/irq_comm.c
+@@ -41,6 +41,15 @@ static int kvm_set_pic_irq(struct kvm_kernel_irq_routing_entry *e,
+ 			   bool line_status)
+ {
+ 	struct kvm_pic *pic = pic_irqchip(kvm);
++
++	/*
++	 * XXX: rejecting pic routes when pic isn't in use would be better,
++	 * but the default routing table is installed while kvm->arch.vpic is
++	 * NULL and KVM_CREATE_IRQCHIP can race with KVM_IRQ_LINE.
++	 */
++	if (!pic)
++		return -1;
++
+ 	return kvm_pic_set_irq(pic, e->irqchip.pin, irq_source_id, level);
+ }
+ 
+@@ -49,6 +58,10 @@ static int kvm_set_ioapic_irq(struct kvm_kernel_irq_routing_entry *e,
+ 			      bool line_status)
+ {
+ 	struct kvm_ioapic *ioapic = kvm->arch.vioapic;
++
++	if (!ioapic)
++		return -1;
++
+ 	return kvm_ioapic_set_irq(ioapic, e->irqchip.pin, irq_source_id, level,
+ 				line_status);
+ }
+diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
+index b62c85229711..d2255e4f9589 100644
+--- a/arch/x86/kvm/lapic.c
++++ b/arch/x86/kvm/lapic.c
+@@ -138,7 +138,7 @@ static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map,
+ 		*mask = dest_id & 0xff;
+ 		return true;
+ 	case KVM_APIC_MODE_XAPIC_CLUSTER:
+-		*cluster = map->xapic_cluster_map[dest_id >> 4];
++		*cluster = map->xapic_cluster_map[(dest_id >> 4) & 0xf];
+ 		*mask = dest_id & 0xf;
+ 		return true;
+ 	default:
+diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c
+index 832b98f822be..a3a983fd4248 100644
+--- a/arch/x86/mm/extable.c
++++ b/arch/x86/mm/extable.c
+@@ -135,7 +135,12 @@ void __init early_fixup_exception(struct pt_regs *regs, int trapnr)
+ 	if (early_recursion_flag > 2)
+ 		goto halt_loop;
+ 
+-	if (regs->cs != __KERNEL_CS)
++	/*
++	 * Old CPUs leave the high bits of CS on the stack
++	 * undefined.  I'm not sure which CPUs do this, but at least
++	 * the 486 DX works this way.
++	 */
++	if ((regs->cs & 0xFFFF) != __KERNEL_CS)
+ 		goto fail;
+ 
+ 	/*
+diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
+index 865f46ea724f..c80765b211cf 100644
+--- a/crypto/asymmetric_keys/x509_cert_parser.c
++++ b/crypto/asymmetric_keys/x509_cert_parser.c
+@@ -133,7 +133,6 @@ struct x509_certificate *x509_cert_parse(const void *data, size_t datalen)
+ 	return cert;
+ 
+ error_decode:
+-	kfree(cert->pub->key);
+ 	kfree(ctx);
+ error_no_ctx:
+ 	x509_free_certificate(cert);
+diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c
+index 29f600f2c447..ff64313770bd 100644
+--- a/drivers/dax/dax.c
++++ b/drivers/dax/dax.c
+@@ -323,8 +323,8 @@ static int check_vma(struct dax_dev *dax_dev, struct vm_area_struct *vma,
+ 	if (!dax_dev->alive)
+ 		return -ENXIO;
+ 
+-	/* prevent private / writable mappings from being established */
+-	if ((vma->vm_flags & (VM_NORESERVE|VM_SHARED|VM_WRITE)) == VM_WRITE) {
++	/* prevent private mappings from being established */
++	if ((vma->vm_flags & VM_SHARED) != VM_SHARED) {
+ 		dev_info(dev, "%s: %s: fail, attempted private mapping\n",
+ 				current->comm, func);
+ 		return -EINVAL;
+diff --git a/drivers/dax/pmem.c b/drivers/dax/pmem.c
+index 73ae849f5170..76dd42dd7088 100644
+--- a/drivers/dax/pmem.c
++++ b/drivers/dax/pmem.c
+@@ -77,7 +77,9 @@ static int dax_pmem_probe(struct device *dev)
+ 	nsio = to_nd_namespace_io(&ndns->dev);
+ 
+ 	/* parse the 'pfn' info block via ->rw_bytes */
+-	devm_nsio_enable(dev, nsio);
++	rc = devm_nsio_enable(dev, nsio);
++	if (rc)
++		return rc;
+ 	altmap = nvdimm_setup_pfn(nd_pfn, &res, &__altmap);
+ 	if (IS_ERR(altmap))
+ 		return PTR_ERR(altmap);
+diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
+index 58470f5ced04..8c53748a769d 100644
+--- a/drivers/iommu/dmar.c
++++ b/drivers/iommu/dmar.c
+@@ -338,7 +338,9 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
+ 	struct pci_dev *pdev = to_pci_dev(data);
+ 	struct dmar_pci_notify_info *info;
+ 
+-	/* Only care about add/remove events for physical functions */
++	/* Only care about add/remove events for physical functions.
++	 * For VFs we actually do the lookup based on the corresponding
++	 * PF in device_to_iommu() anyway. */
+ 	if (pdev->is_virtfn)
+ 		return NOTIFY_DONE;
+ 	if (action != BUS_NOTIFY_ADD_DEVICE &&
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index 1257b0b80296..7fb538708cec 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -892,7 +892,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
+ 		return NULL;
+ 
+ 	if (dev_is_pci(dev)) {
++		struct pci_dev *pf_pdev;
++
+ 		pdev = to_pci_dev(dev);
++		/* VFs aren't listed in scope tables; we need to look up
++		 * the PF instead to find the IOMMU. */
++		pf_pdev = pci_physfn(pdev);
++		dev = &pf_pdev->dev;
+ 		segment = pci_domain_nr(pdev->bus);
+ 	} else if (has_acpi_companion(dev))
+ 		dev = &ACPI_COMPANION(dev)->dev;
+@@ -905,6 +911,13 @@ static struct intel_iommu *device_to_iommu(struct device *dev, u8 *bus, u8 *devf
+ 		for_each_active_dev_scope(drhd->devices,
+ 					  drhd->devices_cnt, i, tmp) {
+ 			if (tmp == dev) {
++				/* For a VF use its original BDF# not that of the PF
++				 * which we used for the IOMMU lookup. Strictly speaking
++				 * we could do this for all PCI devices; we only need to
++				 * get the BDF# from the scope table for ACPI matches. */
++				if (pdev->is_virtfn)
++					goto got_pdev;
++
+ 				*bus = drhd->devices[i].bus;
+ 				*devfn = drhd->devices[i].devfn;
+ 				goto out;
+diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c
+index 8ebb3530afa7..cb72e0011310 100644
+--- a/drivers/iommu/intel-svm.c
++++ b/drivers/iommu/intel-svm.c
+@@ -39,10 +39,18 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+ 	struct page *pages;
+ 	int order;
+ 
+-	order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+-	if (order < 0)
+-		order = 0;
+-
++	/* Start at 2 because it's defined as 2^(1+PSS) */
++	iommu->pasid_max = 2 << ecap_pss(iommu->ecap);
++
++	/* Eventually I'm promised we will get a multi-level PASID table
++	 * and it won't have to be physically contiguous. Until then,
++	 * limit the size because 8MiB contiguous allocations can be hard
++	 * to come by. The limit of 0x20000, which is 1MiB for each of
++	 * the PASID and PASID-state tables, is somewhat arbitrary. */
++	if (iommu->pasid_max > 0x20000)
++		iommu->pasid_max = 0x20000;
++
++	order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max);
+ 	pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+ 	if (!pages) {
+ 		pr_warn("IOMMU: %s: Failed to allocate PASID table\n",
+@@ -53,6 +61,8 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+ 	pr_info("%s: Allocated order %d PASID table.\n", iommu->name, order);
+ 
+ 	if (ecap_dis(iommu->ecap)) {
++		/* Just making it explicit... */
++		BUILD_BUG_ON(sizeof(struct pasid_entry) != sizeof(struct pasid_state_entry));
+ 		pages = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+ 		if (pages)
+ 			iommu->pasid_state_table = page_address(pages);
+@@ -68,11 +78,7 @@ int intel_svm_alloc_pasid_tables(struct intel_iommu *iommu)
+ 
+ int intel_svm_free_pasid_tables(struct intel_iommu *iommu)
+ {
+-	int order;
+-
+-	order = ecap_pss(iommu->ecap) + 7 - PAGE_SHIFT;
+-	if (order < 0)
+-		order = 0;
++	int order = get_order(sizeof(struct pasid_entry) * iommu->pasid_max);
+ 
+ 	if (iommu->pasid_table) {
+ 		free_pages((unsigned long)iommu->pasid_table, order);
+@@ -371,8 +377,8 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
+ 		}
+ 		svm->iommu = iommu;
+ 
+-		if (pasid_max > 2 << ecap_pss(iommu->ecap))
+-			pasid_max = 2 << ecap_pss(iommu->ecap);
++		if (pasid_max > iommu->pasid_max)
++			pasid_max = iommu->pasid_max;
+ 
+ 		/* Do not use PASID 0 in caching mode (virtualised IOMMU) */
+ 		ret = idr_alloc(&iommu->pasid_idr, svm,
+diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
+index 317ef63ee789..8d96a22647b3 100644
+--- a/drivers/media/tuners/tuner-xc2028.c
++++ b/drivers/media/tuners/tuner-xc2028.c
+@@ -281,6 +281,14 @@ static void free_firmware(struct xc2028_data *priv)
+ 	int i;
+ 	tuner_dbg("%s called\n", __func__);
+ 
++	/* free allocated f/w string */
++	if (priv->fname != firmware_name)
++		kfree(priv->fname);
++	priv->fname = NULL;
++
++	priv->state = XC2028_NO_FIRMWARE;
++	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
++
+ 	if (!priv->firm)
+ 		return;
+ 
+@@ -291,9 +299,6 @@ static void free_firmware(struct xc2028_data *priv)
+ 
+ 	priv->firm = NULL;
+ 	priv->firm_size = 0;
+-	priv->state = XC2028_NO_FIRMWARE;
+-
+-	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+ }
+ 
+ static int load_all_firmwares(struct dvb_frontend *fe,
+@@ -884,9 +889,8 @@ read_not_reliable:
+ 	return 0;
+ 
+ fail:
+-	priv->state = XC2028_NO_FIRMWARE;
++	free_firmware(priv);
+ 
+-	memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
+ 	if (retry_count < 8) {
+ 		msleep(50);
+ 		retry_count++;
+@@ -1332,11 +1336,8 @@ static int xc2028_dvb_release(struct dvb_frontend *fe)
+ 	mutex_lock(&xc2028_list_mutex);
+ 
+ 	/* only perform final cleanup if this is the last instance */
+-	if (hybrid_tuner_report_instance_count(priv) == 1) {
++	if (hybrid_tuner_report_instance_count(priv) == 1)
+ 		free_firmware(priv);
+-		kfree(priv->ctrl.fname);
+-		priv->ctrl.fname = NULL;
+-	}
+ 
+ 	if (priv)
+ 		hybrid_tuner_release_state(priv);
+@@ -1399,19 +1400,8 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
+ 
+ 	/*
+ 	 * Copy the config data.
+-	 * For the firmware name, keep a local copy of the string,
+-	 * in order to avoid troubles during device release.
+ 	 */
+-	kfree(priv->ctrl.fname);
+-	priv->ctrl.fname = NULL;
+ 	memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
+-	if (p->fname) {
+-		priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
+-		if (priv->ctrl.fname == NULL) {
+-			rc = -ENOMEM;
+-			goto unlock;
+-		}
+-	}
+ 
+ 	/*
+ 	 * If firmware name changed, frees firmware. As free_firmware will
+@@ -1426,10 +1416,15 @@ static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
+ 
+ 	if (priv->state == XC2028_NO_FIRMWARE) {
+ 		if (!firmware_name[0])
+-			priv->fname = priv->ctrl.fname;
++			priv->fname = kstrdup(p->fname, GFP_KERNEL);
+ 		else
+ 			priv->fname = firmware_name;
+ 
++		if (!priv->fname) {
++			rc = -ENOMEM;
++			goto unlock;
++		}
++
+ 		rc = request_firmware_nowait(THIS_MODULE, 1,
+ 					     priv->fname,
+ 					     priv->i2c_props.adap->dev.parent,
+diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c
+index 239be2fde242..2267601f0ac1 100644
+--- a/drivers/mmc/host/sdhci-of-esdhc.c
++++ b/drivers/mmc/host/sdhci-of-esdhc.c
+@@ -66,6 +66,20 @@ static u32 esdhc_readl_fixup(struct sdhci_host *host,
+ 			return ret;
+ 		}
+ 	}
++	/*
++	 * The DAT[3:0] line signal levels and the CMD line signal level are
++	 * not compatible with standard SDHC register. The line signal levels
++	 * DAT[7:0] are at bits 31:24 and the command line signal level is at
++	 * bit 23. All other bits are the same as in the standard SDHC
++	 * register.
++	 */
++	if (spec_reg == SDHCI_PRESENT_STATE) {
++		ret = value & 0x000fffff;
++		ret |= (value >> 4) & SDHCI_DATA_LVL_MASK;
++		ret |= (value << 1) & SDHCI_CMD_LVL;
++		return ret;
++	}
++
+ 	ret = value;
+ 	return ret;
+ }
+diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
+index 0411c9f36461..1b3bd1c7f4f6 100644
+--- a/drivers/mmc/host/sdhci.h
++++ b/drivers/mmc/host/sdhci.h
+@@ -73,6 +73,7 @@
+ #define  SDHCI_DATA_LVL_MASK	0x00F00000
+ #define   SDHCI_DATA_LVL_SHIFT	20
+ #define   SDHCI_DATA_0_LVL_MASK	0x00100000
++#define  SDHCI_CMD_LVL		0x01000000
+ 
+ #define SDHCI_HOST_CONTROL	0x28
+ #define  SDHCI_CTRL_LED		0x01
+diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+index 46c0f5ecd99d..58e60298a360 100644
+--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
++++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+@@ -3894,6 +3894,11 @@ _scsih_temp_threshold_events(struct MPT3SAS_ADAPTER *ioc,
+ 	}
+ }
+ 
++static inline bool ata_12_16_cmd(struct scsi_cmnd *scmd)
++{
++	return (scmd->cmnd[0] == ATA_12 || scmd->cmnd[0] == ATA_16);
++}
++
+ /**
+  * _scsih_flush_running_cmds - completing outstanding commands.
+  * @ioc: per adapter object
+@@ -3915,6 +3920,9 @@ _scsih_flush_running_cmds(struct MPT3SAS_ADAPTER *ioc)
+ 		if (!scmd)
+ 			continue;
+ 		count++;
++		if (ata_12_16_cmd(scmd))
++			scsi_internal_device_unblock(scmd->device,
++							SDEV_RUNNING);
+ 		mpt3sas_base_free_smid(ioc, smid);
+ 		scsi_dma_unmap(scmd);
+ 		if (ioc->pci_error_recovery)
+@@ -4019,8 +4027,6 @@ _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status)
+ 	    SAM_STAT_CHECK_CONDITION;
+ }
+ 
+-
+-
+ /**
+  * scsih_qcmd - main scsi request entry point
+  * @scmd: pointer to scsi command object
+@@ -4047,6 +4053,13 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
+ 	if (ioc->logging_level & MPT_DEBUG_SCSI)
+ 		scsi_print_command(scmd);
+ 
++	/*
++	 * Lock the device for any subsequent command until command is
++	 * done.
++	 */
++	if (ata_12_16_cmd(scmd))
++		scsi_internal_device_block(scmd->device);
++
+ 	sas_device_priv_data = scmd->device->hostdata;
+ 	if (!sas_device_priv_data || !sas_device_priv_data->sas_target) {
+ 		scmd->result = DID_NO_CONNECT << 16;
+@@ -4622,6 +4635,9 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply)
+ 	if (scmd == NULL)
+ 		return 1;
+ 
++	if (ata_12_16_cmd(scmd))
++		scsi_internal_device_unblock(scmd->device, SDEV_RUNNING);
++
+ 	mpi_request = mpt3sas_base_get_msg_frame(ioc, smid);
+ 
+ 	if (mpi_reply == NULL) {
+diff --git a/drivers/thermal/intel_powerclamp.c b/drivers/thermal/intel_powerclamp.c
+index 7a223074df3d..afada655f861 100644
+--- a/drivers/thermal/intel_powerclamp.c
++++ b/drivers/thermal/intel_powerclamp.c
+@@ -669,9 +669,16 @@ static struct thermal_cooling_device_ops powerclamp_cooling_ops = {
+ 	.set_cur_state = powerclamp_set_cur_state,
+ };
+ 
++static const struct x86_cpu_id __initconst intel_powerclamp_ids[] = {
++	{ X86_VENDOR_INTEL, X86_FAMILY_ANY, X86_MODEL_ANY, X86_FEATURE_MWAIT },
++	{}
++};
++MODULE_DEVICE_TABLE(x86cpu, intel_powerclamp_ids);
++
+ static int __init powerclamp_probe(void)
+ {
+-	if (!boot_cpu_has(X86_FEATURE_MWAIT)) {
++
++	if (!x86_match_cpu(intel_powerclamp_ids)) {
+ 		pr_err("CPU does not support MWAIT");
+ 		return -ENODEV;
+ 	}
+diff --git a/drivers/usb/chipidea/core.c b/drivers/usb/chipidea/core.c
+index 69426e644d17..3dbb4a21ab44 100644
+--- a/drivers/usb/chipidea/core.c
++++ b/drivers/usb/chipidea/core.c
+@@ -914,6 +914,7 @@ static int ci_hdrc_probe(struct platform_device *pdev)
+ 	if (!ci)
+ 		return -ENOMEM;
+ 
++	spin_lock_init(&ci->lock);
+ 	ci->dev = dev;
+ 	ci->platdata = dev_get_platdata(dev);
+ 	ci->imx28_write_fix = !!(ci->platdata->flags &
+diff --git a/drivers/usb/chipidea/udc.c b/drivers/usb/chipidea/udc.c
+index b93356834bb5..bced28fa1cbd 100644
+--- a/drivers/usb/chipidea/udc.c
++++ b/drivers/usb/chipidea/udc.c
+@@ -1895,8 +1895,6 @@ static int udc_start(struct ci_hdrc *ci)
+ 	struct usb_otg_caps *otg_caps = &ci->platdata->ci_otg_caps;
+ 	int retval = 0;
+ 
+-	spin_lock_init(&ci->lock);
+-
+ 	ci->gadget.ops          = &usb_gadget_ops;
+ 	ci->gadget.speed        = USB_SPEED_UNKNOWN;
+ 	ci->gadget.max_speed    = USB_SPEED_HIGH;
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index f61477bed3a8..243ac5ebe46a 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -131,6 +131,7 @@ static const struct usb_device_id id_table[] = {
+ 	{ USB_DEVICE(0x10C4, 0x88A4) }, /* MMB Networks ZigBee USB Device */
+ 	{ USB_DEVICE(0x10C4, 0x88A5) }, /* Planet Innovation Ingeni ZigBee USB Device */
+ 	{ USB_DEVICE(0x10C4, 0x8946) }, /* Ketra N1 Wireless Interface */
++	{ USB_DEVICE(0x10C4, 0x8962) }, /* Brim Brothers charging dock */
+ 	{ USB_DEVICE(0x10C4, 0x8977) },	/* CEL MeshWorks DevKit Device */
+ 	{ USB_DEVICE(0x10C4, 0x8998) }, /* KCF Technologies PRN */
+ 	{ USB_DEVICE(0x10C4, 0x8A2A) }, /* HubZ dual ZigBee and Z-Wave dongle */
+diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
+index 0ff7f38d7800..6e9fc8bcc285 100644
+--- a/drivers/usb/serial/ftdi_sio.c
++++ b/drivers/usb/serial/ftdi_sio.c
+@@ -1012,6 +1012,8 @@ static const struct usb_device_id id_table_combined[] = {
+ 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7561U_PID) },
+ 	{ USB_DEVICE(ICPDAS_VID, ICPDAS_I7563U_PID) },
+ 	{ USB_DEVICE(WICED_VID, WICED_USB20706V2_PID) },
++	{ USB_DEVICE(TI_VID, TI_CC3200_LAUNCHPAD_PID),
++		.driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
+ 	{ }					/* Terminating entry */
+ };
+ 
+diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
+index 21011c0a4c64..48ee04c94a75 100644
+--- a/drivers/usb/serial/ftdi_sio_ids.h
++++ b/drivers/usb/serial/ftdi_sio_ids.h
+@@ -596,6 +596,12 @@
+ #define STK541_PID		0x2109 /* Zigbee Controller */
+ 
+ /*
++ * Texas Instruments
++ */
++#define TI_VID			0x0451
++#define TI_CC3200_LAUNCHPAD_PID	0xC32A /* SimpleLink Wi-Fi CC3200 LaunchPad */
++
++/*
+  * Blackfin gnICE JTAG
+  * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice
+  */
+diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
+index ffd086733421..1a59f335b063 100644
+--- a/drivers/usb/storage/transport.c
++++ b/drivers/usb/storage/transport.c
+@@ -954,10 +954,15 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us)
+ 
+ 	/* COMMAND STAGE */
+ 	/* let's send the command via the control pipe */
++	/*
++	 * Command is sometime (f.e. after scsi_eh_prep_cmnd) on the stack.
++	 * Stack may be vmallocated.  So no DMA for us.  Make a copy.
++	 */
++	memcpy(us->iobuf, srb->cmnd, srb->cmd_len);
+ 	result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe,
+ 				      US_CBI_ADSC, 
+ 				      USB_TYPE_CLASS | USB_RECIP_INTERFACE, 0, 
+-				      us->ifnum, srb->cmnd, srb->cmd_len);
++				      us->ifnum, us->iobuf, srb->cmd_len);
+ 
+ 	/* check the return code for the command */
+ 	usb_stor_dbg(us, "Call to usb_stor_ctrl_transfer() returned %d\n",
+diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
+index 52a28311e2a4..48efe62e1302 100644
+--- a/fs/nfs/callback.c
++++ b/fs/nfs/callback.c
+@@ -261,7 +261,7 @@ static int nfs_callback_up_net(int minorversion, struct svc_serv *serv,
+ 	}
+ 
+ 	ret = -EPROTONOSUPPORT;
+-	if (minorversion == 0)
++	if (!IS_ENABLED(CONFIG_NFS_V4_1) || minorversion == 0)
+ 		ret = nfs4_callback_up_net(serv, net);
+ 	else if (xprt->ops->bc_up)
+ 		ret = xprt->ops->bc_up(serv, net);
+diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
+index 2d9b650047a5..d49e26c6cdc7 100644
+--- a/include/linux/intel-iommu.h
++++ b/include/linux/intel-iommu.h
+@@ -429,6 +429,7 @@ struct intel_iommu {
+ 	struct page_req_dsc *prq;
+ 	unsigned char prq_name[16];    /* Name for PRQ interrupt */
+ 	struct idr pasid_idr;
++	u32 pasid_max;
+ #endif
+ 	struct q_inval  *qi;            /* Queued invalidation info */
+ 	u32 *iommu_state; /* Store iommu states between suspend and resume.*/
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index fc9bb2225291..f8c5f5ec666e 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -7908,6 +7908,7 @@ restart:
+  * if <size> is not specified, the range is treated as a single address.
+  */
+ enum {
++	IF_ACT_NONE = -1,
+ 	IF_ACT_FILTER,
+ 	IF_ACT_START,
+ 	IF_ACT_STOP,
+@@ -7931,6 +7932,7 @@ static const match_table_t if_tokens = {
+ 	{ IF_SRC_KERNEL,	"%u/%u" },
+ 	{ IF_SRC_FILEADDR,	"%u@%s" },
+ 	{ IF_SRC_KERNELADDR,	"%u" },
++	{ IF_ACT_NONE,		NULL },
+ };
+ 
+ /*
+diff --git a/lib/mpi/mpi-pow.c b/lib/mpi/mpi-pow.c
+index 5464c8744ea9..e24388a863a7 100644
+--- a/lib/mpi/mpi-pow.c
++++ b/lib/mpi/mpi-pow.c
+@@ -64,8 +64,13 @@ int mpi_powm(MPI res, MPI base, MPI exp, MPI mod)
+ 	if (!esize) {
+ 		/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0
+ 		 * depending on if MOD equals 1.  */
+-		rp[0] = 1;
+ 		res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
++		if (res->nlimbs) {
++			if (mpi_resize(res, 1) < 0)
++				goto enomem;
++			rp = res->d;
++			rp[0] = 1;
++		}
+ 		res->sign = 0;
+ 		goto leave;
+ 	}
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index a2214c64ed3c..7401e996009a 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -3161,6 +3161,16 @@ should_compact_retry(struct alloc_context *ac, unsigned int order, int alloc_fla
+ 	if (!order || order > PAGE_ALLOC_COSTLY_ORDER)
+ 		return false;
+ 
++#ifdef CONFIG_COMPACTION
++	/*
++	 * This is a gross workaround to compensate a lack of reliable compaction
++	 * operation. We cannot simply go OOM with the current state of the compaction
++	 * code because this can lead to pre mature OOM declaration.
++	 */
++	if (order <= PAGE_ALLOC_COSTLY_ORDER)
++		return true;
++#endif
++
+ 	/*
+ 	 * There are setups with compaction disabled which would prefer to loop
+ 	 * inside the allocator rather than hit the oom killer prematurely.
+diff --git a/net/can/bcm.c b/net/can/bcm.c
+index 8af9d25ff988..436a7537e6a9 100644
+--- a/net/can/bcm.c
++++ b/net/can/bcm.c
+@@ -77,7 +77,7 @@
+ 		     (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \
+ 		     (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
+ 
+-#define CAN_BCM_VERSION "20160617"
++#define CAN_BCM_VERSION "20161123"
+ 
+ MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
+ MODULE_LICENSE("Dual BSD/GPL");
+@@ -109,8 +109,9 @@ struct bcm_op {
+ 	u32 count;
+ 	u32 nframes;
+ 	u32 currframe;
+-	struct canfd_frame *frames;
+-	struct canfd_frame *last_frames;
++	/* void pointers to arrays of struct can[fd]_frame */
++	void *frames;
++	void *last_frames;
+ 	struct canfd_frame sframe;
+ 	struct canfd_frame last_sframe;
+ 	struct sock *sk;
+@@ -681,7 +682,7 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
+ 
+ 	if (op->flags & RX_FILTER_ID) {
+ 		/* the easiest case */
+-		bcm_rx_update_and_send(op, &op->last_frames[0], rxframe);
++		bcm_rx_update_and_send(op, op->last_frames, rxframe);
+ 		goto rx_starttimer;
+ 	}
+ 
+@@ -1068,7 +1069,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+ 
+ 		if (msg_head->nframes) {
+ 			/* update CAN frames content */
+-			err = memcpy_from_msg((u8 *)op->frames, msg,
++			err = memcpy_from_msg(op->frames, msg,
+ 					      msg_head->nframes * op->cfsiz);
+ 			if (err < 0)
+ 				return err;
+@@ -1118,7 +1119,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+ 		}
+ 
+ 		if (msg_head->nframes) {
+-			err = memcpy_from_msg((u8 *)op->frames, msg,
++			err = memcpy_from_msg(op->frames, msg,
+ 					      msg_head->nframes * op->cfsiz);
+ 			if (err < 0) {
+ 				if (op->frames != &op->sframe)
+@@ -1163,6 +1164,7 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+ 	/* check flags */
+ 
+ 	if (op->flags & RX_RTR_FRAME) {
++		struct canfd_frame *frame0 = op->frames;
+ 
+ 		/* no timers in RTR-mode */
+ 		hrtimer_cancel(&op->thrtimer);
+@@ -1174,8 +1176,8 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
+ 		 * prevent a full-load-loopback-test ... ;-]
+ 		 */
+ 		if ((op->flags & TX_CP_CAN_ID) ||
+-		    (op->frames[0].can_id == op->can_id))
+-			op->frames[0].can_id = op->can_id & ~CAN_RTR_FLAG;
++		    (frame0->can_id == op->can_id))
++			frame0->can_id = op->can_id & ~CAN_RTR_FLAG;
+ 
+ 	} else {
+ 		if (op->flags & SETTIMER) {
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 5550a86f7264..396aac7e6e79 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -945,4 +945,4 @@ static int __init init_default_flow_dissectors(void)
+ 	return 0;
+ }
+ 
+-late_initcall_sync(init_default_flow_dissectors);
++core_initcall(init_default_flow_dissectors);
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index eee91443924d..66f2a1145d7c 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -71,6 +71,7 @@ struct cfg80211_registered_device {
+ 	struct list_head bss_list;
+ 	struct rb_root bss_tree;
+ 	u32 bss_generation;
++	u32 bss_entries;
+ 	struct cfg80211_scan_request *scan_req; /* protected by RTNL */
+ 	struct sk_buff *scan_msg;
+ 	struct cfg80211_sched_scan_request __rcu *sched_scan_req;
+diff --git a/net/wireless/scan.c b/net/wireless/scan.c
+index 0358e12be54b..438143a3827d 100644
+--- a/net/wireless/scan.c
++++ b/net/wireless/scan.c
+@@ -57,6 +57,19 @@
+  * also linked into the probe response struct.
+  */
+ 
++/*
++ * Limit the number of BSS entries stored in mac80211. Each one is
++ * a bit over 4k at most, so this limits to roughly 4-5M of memory.
++ * If somebody wants to really attack this though, they'd likely
++ * use small beacons, and only one type of frame, limiting each of
++ * the entries to a much smaller size (in order to generate more
++ * entries in total, so overhead is bigger.)
++ */
++static int bss_entries_limit = 1000;
++module_param(bss_entries_limit, int, 0644);
++MODULE_PARM_DESC(bss_entries_limit,
++                 "limit to number of scan BSS entries (per wiphy, default 1000)");
++
+ #define IEEE80211_SCAN_RESULT_EXPIRE	(30 * HZ)
+ 
+ static void bss_free(struct cfg80211_internal_bss *bss)
+@@ -137,6 +150,10 @@ static bool __cfg80211_unlink_bss(struct cfg80211_registered_device *rdev,
+ 
+ 	list_del_init(&bss->list);
+ 	rb_erase(&bss->rbn, &rdev->bss_tree);
++	rdev->bss_entries--;
++	WARN_ONCE((rdev->bss_entries == 0) ^ list_empty(&rdev->bss_list),
++		  "rdev bss entries[%d]/list[empty:%d] corruption\n",
++		  rdev->bss_entries, list_empty(&rdev->bss_list));
+ 	bss_ref_put(rdev, bss);
+ 	return true;
+ }
+@@ -163,6 +180,40 @@ static void __cfg80211_bss_expire(struct cfg80211_registered_device *rdev,
+ 		rdev->bss_generation++;
+ }
+ 
++static bool cfg80211_bss_expire_oldest(struct cfg80211_registered_device *rdev)
++{
++	struct cfg80211_internal_bss *bss, *oldest = NULL;
++	bool ret;
++
++	lockdep_assert_held(&rdev->bss_lock);
++
++	list_for_each_entry(bss, &rdev->bss_list, list) {
++		if (atomic_read(&bss->hold))
++			continue;
++
++		if (!list_empty(&bss->hidden_list) &&
++		    !bss->pub.hidden_beacon_bss)
++			continue;
++
++		if (oldest && time_before(oldest->ts, bss->ts))
++			continue;
++		oldest = bss;
++	}
++
++	if (WARN_ON(!oldest))
++		return false;
++
++	/*
++	 * The callers make sure to increase rdev->bss_generation if anything
++	 * gets removed (and a new entry added), so there's no need to also do
++	 * it here.
++	 */
++
++	ret = __cfg80211_unlink_bss(rdev, oldest);
++	WARN_ON(!ret);
++	return ret;
++}
++
+ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev,
+ 			   bool send_message)
+ {
+@@ -693,6 +744,7 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
+ 	const u8 *ie;
+ 	int i, ssidlen;
+ 	u8 fold = 0;
++	u32 n_entries = 0;
+ 
+ 	ies = rcu_access_pointer(new->pub.beacon_ies);
+ 	if (WARN_ON(!ies))
+@@ -716,6 +768,12 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
+ 	/* This is the bad part ... */
+ 
+ 	list_for_each_entry(bss, &rdev->bss_list, list) {
++		/*
++		 * we're iterating all the entries anyway, so take the
++		 * opportunity to validate the list length accounting
++		 */
++		n_entries++;
++
+ 		if (!ether_addr_equal(bss->pub.bssid, new->pub.bssid))
+ 			continue;
+ 		if (bss->pub.channel != new->pub.channel)
+@@ -744,6 +802,10 @@ static bool cfg80211_combine_bsses(struct cfg80211_registered_device *rdev,
+ 				   new->pub.beacon_ies);
+ 	}
+ 
++	WARN_ONCE(n_entries != rdev->bss_entries,
++		  "rdev bss entries[%d]/list[len:%d] corruption\n",
++		  rdev->bss_entries, n_entries);
++
+ 	return true;
+ }
+ 
+@@ -898,7 +960,14 @@ cfg80211_bss_update(struct cfg80211_registered_device *rdev,
+ 			}
+ 		}
+ 
++		if (rdev->bss_entries >= bss_entries_limit &&
++		    !cfg80211_bss_expire_oldest(rdev)) {
++			kfree(new);
++			goto drop;
++		}
++
+ 		list_add_tail(&new->list, &rdev->bss_list);
++		rdev->bss_entries++;
+ 		rb_insert_bss(rdev, new);
+ 		found = new;
+ 	}
+diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c
+index fc3036b34e51..a4d90aa1045a 100644
+--- a/security/apparmor/domain.c
++++ b/security/apparmor/domain.c
+@@ -621,8 +621,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest)
+ 	/* released below */
+ 	cred = get_current_cred();
+ 	cxt = cred_cxt(cred);
+-	profile = aa_cred_profile(cred);
+-	previous_profile = cxt->previous;
++	profile = aa_get_newest_profile(aa_cred_profile(cred));
++	previous_profile = aa_get_newest_profile(cxt->previous);
+ 
+ 	if (unconfined(profile)) {
+ 		info = "unconfined";
+@@ -718,6 +718,8 @@ audit:
+ out:
+ 	aa_put_profile(hat);
+ 	kfree(name);
++	aa_put_profile(profile);
++	aa_put_profile(previous_profile);
+ 	put_cred(cred);
+ 
+ 	return error;


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-12-07 23:26 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-12-07 23:26 UTC (permalink / raw
  To: gentoo-commits

commit:     04658ca7a302b81aa1b6c44e4bda9850eff15279
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Dec  7 23:26:04 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Dec  7 23:26:04 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=04658ca7

packet: fix race condition in packet_set_ring. CVE-2016-8655. Bug #601926.

 0000_README                                      |  4 ++
 1520_fix-race-condition-in-packet-set-ring.patch | 62 ++++++++++++++++++++++++
 2 files changed, 66 insertions(+)

diff --git a/0000_README b/0000_README
index cd56013..af402d3 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.
 
+Patch:  1520_fix-race-condition-in-packet-set-ring.patch
+From:   https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=84ac7260236a49c79eede91617700174c2c19b0c
+Desc:   packet: fix race condition in packet_set_ring. CVE-2016-8655. Bug #601926.
+
 Patch:  2900_dev-root-proc-mount-fix.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=438380
 Desc:   Ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs.

diff --git a/1520_fix-race-condition-in-packet-set-ring.patch b/1520_fix-race-condition-in-packet-set-ring.patch
new file mode 100644
index 0000000..d85527f
--- /dev/null
+++ b/1520_fix-race-condition-in-packet-set-ring.patch
@@ -0,0 +1,62 @@
+--- a/net/packet/af_packet.c	2016-12-07 18:10:25.785812861 -0500
++++ b/net/packet/af_packet.c	2016-12-07 18:18:45.597933525 -0500
+@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, i
+ 
+ 		if (optlen != sizeof(val))
+ 			return -EINVAL;
+-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+-			return -EBUSY;
+ 		if (copy_from_user(&val, optval, sizeof(val)))
+ 			return -EFAULT;
+ 		switch (val) {
+ 		case TPACKET_V1:
+ 		case TPACKET_V2:
+ 		case TPACKET_V3:
+-			po->tp_version = val;
+-			return 0;
++			break;
+ 		default:
+ 			return -EINVAL;
+ 		}
++		lock_sock(sk);
++		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
++			ret = -EBUSY;
++		} else {
++			po->tp_version = val;
++			ret = 0;
++		}
++		release_sock(sk);
++		return ret;
+ 	}
+ 	case PACKET_RESERVE:
+ 	{
+@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *
+ 	/* Added to avoid minimal code churn */
+ 	struct tpacket_req *req = &req_u->req;
+ 
++	lock_sock(sk);
+ 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
+ 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
+ 		net_warn_ratelimited("Tx-ring is not supported.\n");
+@@ -4245,8 +4252,6 @@ static int packet_set_ring(struct sock *
+ 			goto out;
+ 	}
+ 
+-	lock_sock(sk);
+-
+ 	/* Detach socket from network */
+ 	spin_lock(&po->bind_lock);
+ 	was_running = po->running;
+@@ -4294,11 +4299,11 @@ static int packet_set_ring(struct sock *
+ 		if (!tx_ring)
+ 			prb_shutdown_retire_blk_timer(po, rb_queue);
+ 	}
+-	release_sock(sk);
+ 
+ 	if (pg_vec)
+ 		free_pg_vec(pg_vec, order, req->tp_block_nr);
+ out:
++	release_sock(sk);
+ 	return err;
+ }
+ 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-12-09  7:25 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-12-09  7:25 UTC (permalink / raw
  To: gentoo-commits

commit:     ab0207b2570dea0fc1ca4d158a531e50aab2b7bb
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Fri Dec  9 07:27:50 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Fri Dec  9 07:27:50 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=ab0207b2

Linux patch 4.8.13

 0000_README             |    4 +
 1012_linux-4.8.13.patch | 1063 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1067 insertions(+)

diff --git a/0000_README b/0000_README
index af402d3..f162b9e 100644
--- a/0000_README
+++ b/0000_README
@@ -91,6 +91,10 @@ Patch:  1011_linux-4.8.12.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.12
 
+Patch:  1012_linux-4.8.13.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.13
+
 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/1012_linux-4.8.13.patch b/1012_linux-4.8.13.patch
new file mode 100644
index 0000000..63e8dae
--- /dev/null
+++ b/1012_linux-4.8.13.patch
@@ -0,0 +1,1063 @@
+diff --git a/Makefile b/Makefile
+index 7b0c92f53169..b38abe9adef8 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 12
++SUBLEVEL = 13
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arc/include/asm/delay.h b/arch/arc/include/asm/delay.h
+index 08e7e2a16ac1..a36e8601114d 100644
+--- a/arch/arc/include/asm/delay.h
++++ b/arch/arc/include/asm/delay.h
+@@ -22,10 +22,11 @@
+ static inline void __delay(unsigned long loops)
+ {
+ 	__asm__ __volatile__(
+-	"	lp  1f	\n"
+-	"	nop	\n"
+-	"1:		\n"
+-	: "+l"(loops));
++	"	mov lp_count, %0	\n"
++	"	lp  1f			\n"
++	"	nop			\n"
++	"1:				\n"
++	: : "r"(loops));
+ }
+ 
+ extern void __bad_udelay(void);
+diff --git a/arch/arc/include/asm/pgtable.h b/arch/arc/include/asm/pgtable.h
+index 89eeb3720051..e94ca72b974e 100644
+--- a/arch/arc/include/asm/pgtable.h
++++ b/arch/arc/include/asm/pgtable.h
+@@ -280,7 +280,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
+ 
+ #define pte_page(pte)		pfn_to_page(pte_pfn(pte))
+ #define mk_pte(page, prot)	pfn_pte(page_to_pfn(page), prot)
+-#define pfn_pte(pfn, prot)	__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))
++#define pfn_pte(pfn, prot)	__pte(__pfn_to_phys(pfn) | pgprot_val(prot))
+ 
+ /* Don't use virt_to_pfn for macros below: could cause truncations for PAE40*/
+ #define pte_pfn(pte)		(pte_val(pte) >> PAGE_SHIFT)
+diff --git a/arch/arm64/boot/dts/arm/juno-r1.dts b/arch/arm64/boot/dts/arm/juno-r1.dts
+index 123a58b29cbd..f0b857d6d73c 100644
+--- a/arch/arm64/boot/dts/arm/juno-r1.dts
++++ b/arch/arm64/boot/dts/arm/juno-r1.dts
+@@ -76,7 +76,7 @@
+ 				compatible = "arm,idle-state";
+ 				arm,psci-suspend-param = <0x1010000>;
+ 				local-timer-stop;
+-				entry-latency-us = <300>;
++				entry-latency-us = <400>;
+ 				exit-latency-us = <1200>;
+ 				min-residency-us = <2500>;
+ 			};
+diff --git a/arch/arm64/boot/dts/arm/juno-r2.dts b/arch/arm64/boot/dts/arm/juno-r2.dts
+index 007be826efce..26aaa6a7670f 100644
+--- a/arch/arm64/boot/dts/arm/juno-r2.dts
++++ b/arch/arm64/boot/dts/arm/juno-r2.dts
+@@ -76,7 +76,7 @@
+ 				compatible = "arm,idle-state";
+ 				arm,psci-suspend-param = <0x1010000>;
+ 				local-timer-stop;
+-				entry-latency-us = <300>;
++				entry-latency-us = <400>;
+ 				exit-latency-us = <1200>;
+ 				min-residency-us = <2500>;
+ 			};
+diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts
+index a7270eff6939..6e154d948a80 100644
+--- a/arch/arm64/boot/dts/arm/juno.dts
++++ b/arch/arm64/boot/dts/arm/juno.dts
+@@ -76,7 +76,7 @@
+ 				compatible = "arm,idle-state";
+ 				arm,psci-suspend-param = <0x1010000>;
+ 				local-timer-stop;
+-				entry-latency-us = <300>;
++				entry-latency-us = <400>;
+ 				exit-latency-us = <1200>;
+ 				min-residency-us = <2500>;
+ 			};
+diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
+index 7099f26e3702..b96346b943b7 100644
+--- a/arch/arm64/include/asm/cpufeature.h
++++ b/arch/arm64/include/asm/cpufeature.h
+@@ -90,7 +90,7 @@ struct arm64_cpu_capabilities {
+ 	u16 capability;
+ 	int def_scope;			/* default scope */
+ 	bool (*matches)(const struct arm64_cpu_capabilities *caps, int scope);
+-	void (*enable)(void *);		/* Called on all active CPUs */
++	int (*enable)(void *);		/* Called on all active CPUs */
+ 	union {
+ 		struct {	/* To be used for erratum handling only */
+ 			u32 midr_model;
+diff --git a/arch/arm64/include/asm/exec.h b/arch/arm64/include/asm/exec.h
+index db0563c23482..f7865dd9d868 100644
+--- a/arch/arm64/include/asm/exec.h
++++ b/arch/arm64/include/asm/exec.h
+@@ -18,6 +18,9 @@
+ #ifndef __ASM_EXEC_H
+ #define __ASM_EXEC_H
+ 
++#include <linux/sched.h>
++
+ extern unsigned long arch_align_stack(unsigned long sp);
++void uao_thread_switch(struct task_struct *next);
+ 
+ #endif	/* __ASM_EXEC_H */
+diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
+index ace0a96e7d6e..3be0ab013e35 100644
+--- a/arch/arm64/include/asm/processor.h
++++ b/arch/arm64/include/asm/processor.h
+@@ -190,8 +190,8 @@ static inline void spin_lock_prefetch(const void *ptr)
+ 
+ #endif
+ 
+-void cpu_enable_pan(void *__unused);
+-void cpu_enable_uao(void *__unused);
+-void cpu_enable_cache_maint_trap(void *__unused);
++int cpu_enable_pan(void *__unused);
++int cpu_enable_uao(void *__unused);
++int cpu_enable_cache_maint_trap(void *__unused);
+ 
+ #endif /* __ASM_PROCESSOR_H */
+diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
+index 62272eac1352..94a0330f7ec9 100644
+--- a/arch/arm64/kernel/cpufeature.c
++++ b/arch/arm64/kernel/cpufeature.c
+@@ -19,7 +19,9 @@
+ #define pr_fmt(fmt) "CPU features: " fmt
+ 
+ #include <linux/bsearch.h>
++#include <linux/cpumask.h>
+ #include <linux/sort.h>
++#include <linux/stop_machine.h>
+ #include <linux/types.h>
+ #include <asm/cpu.h>
+ #include <asm/cpufeature.h>
+@@ -936,7 +938,13 @@ void __init enable_cpu_capabilities(const struct arm64_cpu_capabilities *caps)
+ {
+ 	for (; caps->matches; caps++)
+ 		if (caps->enable && cpus_have_cap(caps->capability))
+-			on_each_cpu(caps->enable, NULL, true);
++			/*
++			 * Use stop_machine() as it schedules the work allowing
++			 * us to modify PSTATE, instead of on_each_cpu() which
++			 * uses an IPI, giving us a PSTATE that disappears when
++			 * we return.
++			 */
++			stop_machine(caps->enable, NULL, cpu_online_mask);
+ }
+ 
+ /*
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c
+index 6cd2612236dc..9cc8667212a6 100644
+--- a/arch/arm64/kernel/process.c
++++ b/arch/arm64/kernel/process.c
+@@ -49,6 +49,7 @@
+ #include <asm/alternative.h>
+ #include <asm/compat.h>
+ #include <asm/cacheflush.h>
++#include <asm/exec.h>
+ #include <asm/fpsimd.h>
+ #include <asm/mmu_context.h>
+ #include <asm/processor.h>
+@@ -303,7 +304,7 @@ static void tls_thread_switch(struct task_struct *next)
+ }
+ 
+ /* Restore the UAO state depending on next's addr_limit */
+-static void uao_thread_switch(struct task_struct *next)
++void uao_thread_switch(struct task_struct *next)
+ {
+ 	if (IS_ENABLED(CONFIG_ARM64_UAO)) {
+ 		if (task_thread_info(next)->addr_limit == KERNEL_DS)
+diff --git a/arch/arm64/kernel/suspend.c b/arch/arm64/kernel/suspend.c
+index b616e365cee3..23ddf5500b09 100644
+--- a/arch/arm64/kernel/suspend.c
++++ b/arch/arm64/kernel/suspend.c
+@@ -1,8 +1,11 @@
+ #include <linux/ftrace.h>
+ #include <linux/percpu.h>
+ #include <linux/slab.h>
++#include <asm/alternative.h>
+ #include <asm/cacheflush.h>
++#include <asm/cpufeature.h>
+ #include <asm/debug-monitors.h>
++#include <asm/exec.h>
+ #include <asm/pgtable.h>
+ #include <asm/memory.h>
+ #include <asm/mmu_context.h>
+@@ -48,6 +51,14 @@ void notrace __cpu_suspend_exit(void)
+ 	set_my_cpu_offset(per_cpu_offset(smp_processor_id()));
+ 
+ 	/*
++	 * PSTATE was not saved over suspend/resume, re-enable any detected
++	 * features that might not have been set correctly.
++	 */
++	asm(ALTERNATIVE("nop", SET_PSTATE_PAN(1), ARM64_HAS_PAN,
++			CONFIG_ARM64_PAN));
++	uao_thread_switch(current);
++
++	/*
+ 	 * Restore HW breakpoint registers to sane values
+ 	 * before debug exceptions are possibly reenabled
+ 	 * through local_dbg_restore.
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index 771a01a7fbce..9595d3d9c3db 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -428,9 +428,10 @@ asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
+ 	force_signal_inject(SIGILL, ILL_ILLOPC, regs, 0);
+ }
+ 
+-void cpu_enable_cache_maint_trap(void *__unused)
++int cpu_enable_cache_maint_trap(void *__unused)
+ {
+ 	config_sctlr_el1(SCTLR_EL1_UCI, 0);
++	return 0;
+ }
+ 
+ #define __user_cache_maint(insn, address, res)			\
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index 05d2bd776c69..67506c3c5476 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -29,7 +29,9 @@
+ #include <linux/sched.h>
+ #include <linux/highmem.h>
+ #include <linux/perf_event.h>
++#include <linux/preempt.h>
+ 
++#include <asm/bug.h>
+ #include <asm/cpufeature.h>
+ #include <asm/exception.h>
+ #include <asm/debug-monitors.h>
+@@ -671,9 +673,17 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
+ NOKPROBE_SYMBOL(do_debug_exception);
+ 
+ #ifdef CONFIG_ARM64_PAN
+-void cpu_enable_pan(void *__unused)
++int cpu_enable_pan(void *__unused)
+ {
++	/*
++	 * We modify PSTATE. This won't work from irq context as the PSTATE
++	 * is discarded once we return from the exception.
++	 */
++	WARN_ON_ONCE(in_interrupt());
++
+ 	config_sctlr_el1(SCTLR_EL1_SPAN, 0);
++	asm(SET_PSTATE_PAN(1));
++	return 0;
+ }
+ #endif /* CONFIG_ARM64_PAN */
+ 
+@@ -684,8 +694,9 @@ void cpu_enable_pan(void *__unused)
+  * We need to enable the feature at runtime (instead of adding it to
+  * PSR_MODE_EL1h) as the feature may not be implemented by the cpu.
+  */
+-void cpu_enable_uao(void *__unused)
++int cpu_enable_uao(void *__unused)
+ {
+ 	asm(SET_PSTATE_UAO(1));
++	return 0;
+ }
+ #endif /* CONFIG_ARM64_UAO */
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index d0efb5cb1b00..a4e070a51584 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -2344,7 +2344,7 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
+ 		frame.next_frame     = 0;
+ 		frame.return_address = 0;
+ 
+-		if (!access_ok(VERIFY_READ, fp, 8))
++		if (!valid_user_frame(fp, sizeof(frame)))
+ 			break;
+ 
+ 		bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4);
+@@ -2354,9 +2354,6 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry_ctx *ent
+ 		if (bytes != 0)
+ 			break;
+ 
+-		if (!valid_user_frame(fp, sizeof(frame)))
+-			break;
+-
+ 		perf_callchain_store(entry, cs_base + frame.return_address);
+ 		fp = compat_ptr(ss_base + frame.next_frame);
+ 	}
+@@ -2405,7 +2402,7 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
+ 		frame.next_frame	     = NULL;
+ 		frame.return_address = 0;
+ 
+-		if (!access_ok(VERIFY_READ, fp, sizeof(*fp) * 2))
++		if (!valid_user_frame(fp, sizeof(frame)))
+ 			break;
+ 
+ 		bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp));
+@@ -2415,9 +2412,6 @@ perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs
+ 		if (bytes != 0)
+ 			break;
+ 
+-		if (!valid_user_frame(fp, sizeof(frame)))
+-			break;
+-
+ 		perf_callchain_store(entry, frame.return_address);
+ 		fp = (void __user *)frame.next_frame;
+ 	}
+diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
+index e207b33e4ce9..1e007a93bdcc 100644
+--- a/drivers/ata/libata-scsi.c
++++ b/drivers/ata/libata-scsi.c
+@@ -1088,7 +1088,7 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
+ 		desc[1] = tf->command; /* status */
+ 		desc[2] = tf->device;
+ 		desc[3] = tf->nsect;
+-		desc[0] = 0;
++		desc[7] = 0;
+ 		if (tf->flags & ATA_TFLAG_LBA48)  {
+ 			desc[8] |= 0x80;
+ 			if (tf->hob_nsect)
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index 04365b17ee67..5163c8f918cb 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1403,7 +1403,8 @@ static ssize_t hot_remove_store(struct class *class,
+ 	zram = idr_find(&zram_index_idr, dev_id);
+ 	if (zram) {
+ 		ret = zram_remove(zram);
+-		idr_remove(&zram_index_idr, dev_id);
++		if (!ret)
++			idr_remove(&zram_index_idr, dev_id);
+ 	} else {
+ 		ret = -ENODEV;
+ 	}
+diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c
+index 838b22aa8b67..f2c9274b8bd5 100644
+--- a/drivers/clk/sunxi/clk-sunxi.c
++++ b/drivers/clk/sunxi/clk-sunxi.c
+@@ -373,7 +373,7 @@ static void sun4i_get_apb1_factors(struct factors_request *req)
+ 	else
+ 		calcp = 3;
+ 
+-	calcm = (req->parent_rate >> calcp) - 1;
++	calcm = (div >> calcp) - 1;
+ 
+ 	req->rate = (req->parent_rate >> calcp) / (calcm + 1);
+ 	req->m = calcm;
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+index 10b5ddf2c588..1ed085f01a49 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_atpx_handler.c
+@@ -33,6 +33,7 @@ struct amdgpu_atpx {
+ 
+ static struct amdgpu_atpx_priv {
+ 	bool atpx_detected;
++	bool bridge_pm_usable;
+ 	/* handle for device - and atpx */
+ 	acpi_handle dhandle;
+ 	acpi_handle other_handle;
+@@ -200,7 +201,11 @@ static int amdgpu_atpx_validate(struct amdgpu_atpx *atpx)
+ 	atpx->is_hybrid = false;
+ 	if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
+ 		printk("ATPX Hybrid Graphics\n");
+-		atpx->functions.power_cntl = false;
++		/*
++		 * Disable legacy PM methods only when pcie port PM is usable,
++		 * otherwise the device might fail to power off or power on.
++		 */
++		atpx->functions.power_cntl = !amdgpu_atpx_priv.bridge_pm_usable;
+ 		atpx->is_hybrid = true;
+ 	}
+ 
+@@ -546,17 +551,25 @@ static bool amdgpu_atpx_detect(void)
+ 	struct pci_dev *pdev = NULL;
+ 	bool has_atpx = false;
+ 	int vga_count = 0;
++	bool d3_supported = false;
++	struct pci_dev *parent_pdev;
+ 
+ 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ 		vga_count++;
+ 
+ 		has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
++
++		parent_pdev = pci_upstream_bridge(pdev);
++		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
+ 	}
+ 
+ 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_OTHER << 8, pdev)) != NULL) {
+ 		vga_count++;
+ 
+ 		has_atpx |= (amdgpu_atpx_pci_probe_handle(pdev) == true);
++
++		parent_pdev = pci_upstream_bridge(pdev);
++		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
+ 	}
+ 
+ 	if (has_atpx && vga_count == 2) {
+@@ -564,6 +577,7 @@ static bool amdgpu_atpx_detect(void)
+ 		printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
+ 		       acpi_method_name);
+ 		amdgpu_atpx_priv.atpx_detected = true;
++		amdgpu_atpx_priv.bridge_pm_usable = d3_supported;
+ 		amdgpu_atpx_init();
+ 		return true;
+ 	}
+diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
+index a77ce9983f69..b8e3854a1f20 100644
+--- a/drivers/gpu/drm/i915/i915_gem.c
++++ b/drivers/gpu/drm/i915/i915_gem.c
+@@ -2540,7 +2540,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
+ 			page = shmem_read_mapping_page(mapping, i);
+ 			if (IS_ERR(page)) {
+ 				ret = PTR_ERR(page);
+-				goto err_pages;
++				goto err_sg;
+ 			}
+ 		}
+ #ifdef CONFIG_SWIOTLB
+@@ -2583,8 +2583,9 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
+ 
+ 	return 0;
+ 
+-err_pages:
++err_sg:
+ 	sg_mark_end(sg);
++err_pages:
+ 	for_each_sgt_page(page, sgt_iter, st)
+ 		put_page(page);
+ 	sg_free_table(st);
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index e26f88965c58..35d385d70d8e 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -11791,7 +11791,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc,
+ 	intel_crtc->reset_counter = i915_reset_counter(&dev_priv->gpu_error);
+ 	if (__i915_reset_in_progress_or_wedged(intel_crtc->reset_counter)) {
+ 		ret = -EIO;
+-		goto cleanup;
++		goto unlock;
+ 	}
+ 
+ 	atomic_inc(&intel_crtc->unpin_work_count);
+@@ -11877,6 +11877,7 @@ cleanup_pending:
+ 	if (!IS_ERR_OR_NULL(request))
+ 		i915_add_request_no_flush(request);
+ 	atomic_dec(&intel_crtc->unpin_work_count);
++unlock:
+ 	mutex_unlock(&dev->struct_mutex);
+ cleanup:
+ 	crtc->primary->fb = old_fb;
+diff --git a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+index 8f62671fcfbf..54acfccee7eb 100644
+--- a/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
++++ b/drivers/gpu/drm/mediatek/mtk_disp_ovl.c
+@@ -249,13 +249,6 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
+ 	if (irq < 0)
+ 		return irq;
+ 
+-	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
+-			       IRQF_TRIGGER_NONE, dev_name(dev), priv);
+-	if (ret < 0) {
+-		dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
+-		return ret;
+-	}
+-
+ 	comp_id = mtk_ddp_comp_get_id(dev->of_node, MTK_DISP_OVL);
+ 	if (comp_id < 0) {
+ 		dev_err(dev, "Failed to identify by alias: %d\n", comp_id);
+@@ -271,6 +264,13 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, priv);
+ 
++	ret = devm_request_irq(dev, irq, mtk_disp_ovl_irq_handler,
++			       IRQF_TRIGGER_NONE, dev_name(dev), priv);
++	if (ret < 0) {
++		dev_err(dev, "Failed to request irq %d: %d\n", irq, ret);
++		return ret;
++	}
++
+ 	ret = component_add(dev, &mtk_disp_ovl_component_ops);
+ 	if (ret)
+ 		dev_err(dev, "Failed to add component: %d\n", ret);
+diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+index ddef0d494084..34b4ace5d75f 100644
+--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
++++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+@@ -33,6 +33,7 @@ struct radeon_atpx {
+ 
+ static struct radeon_atpx_priv {
+ 	bool atpx_detected;
++	bool bridge_pm_usable;
+ 	/* handle for device - and atpx */
+ 	acpi_handle dhandle;
+ 	struct radeon_atpx atpx;
+@@ -198,7 +199,11 @@ static int radeon_atpx_validate(struct radeon_atpx *atpx)
+ 	atpx->is_hybrid = false;
+ 	if (valid_bits & ATPX_MS_HYBRID_GFX_SUPPORTED) {
+ 		printk("ATPX Hybrid Graphics\n");
+-		atpx->functions.power_cntl = false;
++		/*
++		 * Disable legacy PM methods only when pcie port PM is usable,
++		 * otherwise the device might fail to power off or power on.
++		 */
++		atpx->functions.power_cntl = !radeon_atpx_priv.bridge_pm_usable;
+ 		atpx->is_hybrid = true;
+ 	}
+ 
+@@ -543,11 +548,16 @@ static bool radeon_atpx_detect(void)
+ 	struct pci_dev *pdev = NULL;
+ 	bool has_atpx = false;
+ 	int vga_count = 0;
++	bool d3_supported = false;
++	struct pci_dev *parent_pdev;
+ 
+ 	while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ 		vga_count++;
+ 
+ 		has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
++
++		parent_pdev = pci_upstream_bridge(pdev);
++		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
+ 	}
+ 
+ 	/* some newer PX laptops mark the dGPU as a non-VGA display device */
+@@ -555,6 +565,9 @@ static bool radeon_atpx_detect(void)
+ 		vga_count++;
+ 
+ 		has_atpx |= (radeon_atpx_pci_probe_handle(pdev) == true);
++
++		parent_pdev = pci_upstream_bridge(pdev);
++		d3_supported |= parent_pdev && parent_pdev->bridge_d3;
+ 	}
+ 
+ 	if (has_atpx && vga_count == 2) {
+@@ -562,6 +575,7 @@ static bool radeon_atpx_detect(void)
+ 		printk(KERN_INFO "vga_switcheroo: detected switching method %s handle\n",
+ 		       acpi_method_name);
+ 		radeon_atpx_priv.atpx_detected = true;
++		radeon_atpx_priv.bridge_pm_usable = d3_supported;
+ 		radeon_atpx_init();
+ 		return true;
+ 	}
+diff --git a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
+index 5784e20542a4..9f6203c8577c 100644
+--- a/drivers/input/mouse/psmouse-base.c
++++ b/drivers/input/mouse/psmouse-base.c
+@@ -1115,10 +1115,6 @@ static int psmouse_extensions(struct psmouse *psmouse,
+ 		if (psmouse_try_protocol(psmouse, PSMOUSE_TOUCHKIT_PS2,
+ 					 &max_proto, set_properties, true))
+ 			return PSMOUSE_TOUCHKIT_PS2;
+-
+-		if (psmouse_try_protocol(psmouse, PSMOUSE_BYD,
+-					 &max_proto, set_properties, true))
+-			return PSMOUSE_BYD;
+ 	}
+ 
+ 	/*
+diff --git a/drivers/net/wireless/marvell/mwifiex/cfg80211.c b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+index a8ff969c95c2..cbc7dfae0a0e 100644
+--- a/drivers/net/wireless/marvell/mwifiex/cfg80211.c
++++ b/drivers/net/wireless/marvell/mwifiex/cfg80211.c
+@@ -2203,8 +2203,9 @@ done:
+ 			is_scanning_required = 1;
+ 		} else {
+ 			mwifiex_dbg(priv->adapter, MSG,
+-				    "info: trying to associate to '%s' bssid %pM\n",
+-				    (char *)req_ssid.ssid, bss->bssid);
++				    "info: trying to associate to '%.*s' bssid %pM\n",
++				    req_ssid.ssid_len, (char *)req_ssid.ssid,
++				    bss->bssid);
+ 			memcpy(&priv->cfg_bssid, bss->bssid, ETH_ALEN);
+ 			break;
+ 		}
+@@ -2264,8 +2265,8 @@ mwifiex_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ 	}
+ 
+ 	mwifiex_dbg(adapter, INFO,
+-		    "info: Trying to associate to %s and bssid %pM\n",
+-		    (char *)sme->ssid, sme->bssid);
++		    "info: Trying to associate to %.*s and bssid %pM\n",
++		    (int)sme->ssid_len, (char *)sme->ssid, sme->bssid);
+ 
+ 	if (!mwifiex_stop_bg_scan(priv))
+ 		cfg80211_sched_scan_stopped_rtnl(priv->wdev.wiphy);
+@@ -2398,8 +2399,8 @@ mwifiex_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
+ 	}
+ 
+ 	mwifiex_dbg(priv->adapter, MSG,
+-		    "info: trying to join to %s and bssid %pM\n",
+-		    (char *)params->ssid, params->bssid);
++		    "info: trying to join to %.*s and bssid %pM\n",
++		    params->ssid_len, (char *)params->ssid, params->bssid);
+ 
+ 	mwifiex_set_ibss_params(priv, params);
+ 
+diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
+index db553dc22c8e..2b6a59266689 100644
+--- a/drivers/pci/pcie/aer/aer_inject.c
++++ b/drivers/pci/pcie/aer/aer_inject.c
+@@ -307,20 +307,6 @@ out:
+ 	return 0;
+ }
+ 
+-static struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
+-{
+-	while (1) {
+-		if (!pci_is_pcie(dev))
+-			break;
+-		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
+-			return dev;
+-		if (!dev->bus->self)
+-			break;
+-		dev = dev->bus->self;
+-	}
+-	return NULL;
+-}
+-
+ static int find_aer_device_iter(struct device *device, void *data)
+ {
+ 	struct pcie_device **result = data;
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 93f280df3428..f6eff4aaffd7 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -1439,6 +1439,21 @@ static void program_hpp_type1(struct pci_dev *dev, struct hpp_type1 *hpp)
+ 		dev_warn(&dev->dev, "PCI-X settings not supported\n");
+ }
+ 
++static bool pcie_root_rcb_set(struct pci_dev *dev)
++{
++	struct pci_dev *rp = pcie_find_root_port(dev);
++	u16 lnkctl;
++
++	if (!rp)
++		return false;
++
++	pcie_capability_read_word(rp, PCI_EXP_LNKCTL, &lnkctl);
++	if (lnkctl & PCI_EXP_LNKCTL_RCB)
++		return true;
++
++	return false;
++}
++
+ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
+ {
+ 	int pos;
+@@ -1468,9 +1483,20 @@ static void program_hpp_type2(struct pci_dev *dev, struct hpp_type2 *hpp)
+ 			~hpp->pci_exp_devctl_and, hpp->pci_exp_devctl_or);
+ 
+ 	/* Initialize Link Control Register */
+-	if (pcie_cap_has_lnkctl(dev))
++	if (pcie_cap_has_lnkctl(dev)) {
++
++		/*
++		 * If the Root Port supports Read Completion Boundary of
++		 * 128, set RCB to 128.  Otherwise, clear it.
++		 */
++		hpp->pci_exp_lnkctl_and |= PCI_EXP_LNKCTL_RCB;
++		hpp->pci_exp_lnkctl_or &= ~PCI_EXP_LNKCTL_RCB;
++		if (pcie_root_rcb_set(dev))
++			hpp->pci_exp_lnkctl_or |= PCI_EXP_LNKCTL_RCB;
++
+ 		pcie_capability_clear_and_set_word(dev, PCI_EXP_LNKCTL,
+ 			~hpp->pci_exp_lnkctl_and, hpp->pci_exp_lnkctl_or);
++	}
+ 
+ 	/* Find Advanced Error Reporting Enhanced Capability */
+ 	pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
+diff --git a/drivers/pwm/sysfs.c b/drivers/pwm/sysfs.c
+index 0296d8178ae2..a813239300c3 100644
+--- a/drivers/pwm/sysfs.c
++++ b/drivers/pwm/sysfs.c
+@@ -425,6 +425,8 @@ void pwmchip_sysfs_unexport_children(struct pwm_chip *chip)
+ 		if (test_bit(PWMF_EXPORTED, &pwm->flags))
+ 			pwm_unexport_child(parent, pwm);
+ 	}
++
++	put_device(parent);
+ }
+ 
+ static int __init pwm_sysfs_init(void)
+diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c
+index 030d0023e1d2..5138a841ff4f 100644
+--- a/drivers/scsi/hpsa.c
++++ b/drivers/scsi/hpsa.c
+@@ -2007,7 +2007,7 @@ static struct hpsa_scsi_dev_t *lookup_hpsa_scsi_dev(struct ctlr_info *h,
+ 
+ static int hpsa_slave_alloc(struct scsi_device *sdev)
+ {
+-	struct hpsa_scsi_dev_t *sd;
++	struct hpsa_scsi_dev_t *sd = NULL;
+ 	unsigned long flags;
+ 	struct ctlr_info *h;
+ 
+@@ -2024,7 +2024,8 @@ static int hpsa_slave_alloc(struct scsi_device *sdev)
+ 			sd->target = sdev_id(sdev);
+ 			sd->lun = sdev->lun;
+ 		}
+-	} else
++	}
++	if (!sd)
+ 		sd = lookup_hpsa_scsi_dev(h, sdev_channel(sdev),
+ 					sdev_id(sdev), sdev->lun);
+ 
+@@ -3805,6 +3806,7 @@ static int hpsa_update_device_info(struct ctlr_info *h,
+ 		sizeof(this_device->vendor));
+ 	memcpy(this_device->model, &inq_buff[16],
+ 		sizeof(this_device->model));
++	this_device->rev = inq_buff[2];
+ 	memset(this_device->device_id, 0,
+ 		sizeof(this_device->device_id));
+ 	hpsa_get_device_id(h, scsi3addr, this_device->device_id, 8,
+@@ -3887,10 +3889,14 @@ static void figure_bus_target_lun(struct ctlr_info *h,
+ 
+ 	if (!is_logical_dev_addr_mode(lunaddrbytes)) {
+ 		/* physical device, target and lun filled in later */
+-		if (is_hba_lunid(lunaddrbytes))
++		if (is_hba_lunid(lunaddrbytes)) {
++			int bus = HPSA_HBA_BUS;
++
++			if (!device->rev)
++				bus = HPSA_LEGACY_HBA_BUS;
+ 			hpsa_set_bus_target_lun(device,
+-					HPSA_HBA_BUS, 0, lunid & 0x3fff);
+-		else
++					bus, 0, lunid & 0x3fff);
++		} else
+ 			/* defer target, lun assignment for physical devices */
+ 			hpsa_set_bus_target_lun(device,
+ 					HPSA_PHYSICAL_DEVICE_BUS, -1, -1);
+diff --git a/drivers/scsi/hpsa.h b/drivers/scsi/hpsa.h
+index a1487e67f7a1..9d45dde5747f 100644
+--- a/drivers/scsi/hpsa.h
++++ b/drivers/scsi/hpsa.h
+@@ -69,6 +69,7 @@ struct hpsa_scsi_dev_t {
+ 	u64 sas_address;
+ 	unsigned char vendor[8];        /* bytes 8-15 of inquiry data */
+ 	unsigned char model[16];        /* bytes 16-31 of inquiry data */
++	unsigned char rev;		/* byte 2 of inquiry data */
+ 	unsigned char raid_level;	/* from inquiry page 0xC1 */
+ 	unsigned char volume_offline;	/* discovered via TUR or VPD */
+ 	u16 queue_depth;		/* max queue_depth for this device */
+@@ -403,6 +404,7 @@ struct offline_device_entry {
+ #define HPSA_RAID_VOLUME_BUS		1
+ #define HPSA_EXTERNAL_RAID_VOLUME_BUS	2
+ #define HPSA_HBA_BUS			0
++#define HPSA_LEGACY_HBA_BUS		3
+ 
+ /*
+ 	Send the command to the hardware
+diff --git a/drivers/scsi/libfc/fc_lport.c b/drivers/scsi/libfc/fc_lport.c
+index 04ce7cfb6d1b..50c71678a156 100644
+--- a/drivers/scsi/libfc/fc_lport.c
++++ b/drivers/scsi/libfc/fc_lport.c
+@@ -308,7 +308,7 @@ struct fc_host_statistics *fc_get_host_stats(struct Scsi_Host *shost)
+ 	fc_stats = &lport->host_stats;
+ 	memset(fc_stats, 0, sizeof(struct fc_host_statistics));
+ 
+-	fc_stats->seconds_since_last_reset = (lport->boot_time - jiffies) / HZ;
++	fc_stats->seconds_since_last_reset = (jiffies - lport->boot_time) / HZ;
+ 
+ 	for_each_possible_cpu(cpu) {
+ 		struct fc_stats *stats;
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index a78415d77434..78be4aee7064 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -329,11 +329,11 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
+ 	if (!real)
+ 		goto bug;
+ 
++	/* Handle recursion */
++	real = d_real(real, inode, open_flags);
++
+ 	if (!inode || inode == d_inode(real))
+ 		return real;
+-
+-	/* Handle recursion */
+-	return d_real(real, inode, open_flags);
+ bug:
+ 	WARN(1, "ovl_d_real(%pd4, %s:%lu): real dentry not found\n", dentry,
+ 	     inode ? inode->i_sb->s_id : "NULL", inode ? inode->i_ino : 0);
+diff --git a/include/linux/compiler-gcc.h b/include/linux/compiler-gcc.h
+index 573c5a18908f..0a0b2d5148e1 100644
+--- a/include/linux/compiler-gcc.h
++++ b/include/linux/compiler-gcc.h
+@@ -256,7 +256,9 @@
+ #endif
+ #endif /* CONFIG_ARCH_USE_BUILTIN_BSWAP && !__CHECKER__ */
+ 
+-#if GCC_VERSION >= 50000
++#if GCC_VERSION >= 70000
++#define KASAN_ABI_VERSION 5
++#elif GCC_VERSION >= 50000
+ #define KASAN_ABI_VERSION 4
+ #elif GCC_VERSION >= 40902
+ #define KASAN_ABI_VERSION 3
+diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
+index 01e84436cddf..d47cc4ab74ee 100644
+--- a/include/linux/pagemap.h
++++ b/include/linux/pagemap.h
+@@ -364,16 +364,13 @@ static inline struct page *read_mapping_page(struct address_space *mapping,
+ }
+ 
+ /*
+- * Get the offset in PAGE_SIZE.
+- * (TODO: hugepage should have ->index in PAGE_SIZE)
++ * Get index of the page with in radix-tree
++ * (TODO: remove once hugetlb pages will have ->index in PAGE_SIZE)
+  */
+-static inline pgoff_t page_to_pgoff(struct page *page)
++static inline pgoff_t page_to_index(struct page *page)
+ {
+ 	pgoff_t pgoff;
+ 
+-	if (unlikely(PageHeadHuge(page)))
+-		return page->index << compound_order(page);
+-
+ 	if (likely(!PageTransTail(page)))
+ 		return page->index;
+ 
+@@ -387,6 +384,18 @@ static inline pgoff_t page_to_pgoff(struct page *page)
+ }
+ 
+ /*
++ * Get the offset in PAGE_SIZE.
++ * (TODO: hugepage should have ->index in PAGE_SIZE)
++ */
++static inline pgoff_t page_to_pgoff(struct page *page)
++{
++	if (unlikely(PageHeadHuge(page)))
++		return page->index << compound_order(page);
++
++	return page_to_index(page);
++}
++
++/*
+  * Return byte-offset into filesystem object for page.
+  */
+ static inline loff_t page_offset(struct page *page)
+diff --git a/include/linux/pci.h b/include/linux/pci.h
+index 0ab835965669..03f3df0888fe 100644
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -1896,6 +1896,20 @@ static inline int pci_pcie_type(const struct pci_dev *dev)
+ 	return (pcie_caps_reg(dev) & PCI_EXP_FLAGS_TYPE) >> 4;
+ }
+ 
++static inline struct pci_dev *pcie_find_root_port(struct pci_dev *dev)
++{
++	while (1) {
++		if (!pci_is_pcie(dev))
++			break;
++		if (pci_pcie_type(dev) == PCI_EXP_TYPE_ROOT_PORT)
++			return dev;
++		if (!dev->bus->self)
++			break;
++		dev = dev->bus->self;
++	}
++	return NULL;
++}
++
+ void pci_request_acs(void);
+ bool pci_acs_enabled(struct pci_dev *pdev, u16 acs_flags);
+ bool pci_acs_path_enabled(struct pci_dev *start,
+diff --git a/include/uapi/linux/input-event-codes.h b/include/uapi/linux/input-event-codes.h
+index d6d071fc3c56..3af60ee69053 100644
+--- a/include/uapi/linux/input-event-codes.h
++++ b/include/uapi/linux/input-event-codes.h
+@@ -640,7 +640,7 @@
+  * Control a data application associated with the currently viewed channel,
+  * e.g. teletext or data broadcast application (MHEG, MHP, HbbTV, etc.)
+  */
+-#define KEY_DATA			0x275
++#define KEY_DATA			0x277
+ 
+ #define BTN_TRIGGER_HAPPY		0x2c0
+ #define BTN_TRIGGER_HAPPY1		0x2c0
+diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
+index 0082fce402a0..85c5a883c6e3 100644
+--- a/kernel/rcu/tree_plugin.h
++++ b/kernel/rcu/tree_plugin.h
+@@ -2173,6 +2173,7 @@ static int rcu_nocb_kthread(void *arg)
+ 				cl++;
+ 			c++;
+ 			local_bh_enable();
++			cond_resched_rcu_qs();
+ 			list = next;
+ 		}
+ 		trace_rcu_batch_end(rdp->rsp->name, c, !!list, 0, 0, 1);
+diff --git a/mm/kasan/kasan.h b/mm/kasan/kasan.h
+index e5c2181fee6f..03f4545b103d 100644
+--- a/mm/kasan/kasan.h
++++ b/mm/kasan/kasan.h
+@@ -53,6 +53,9 @@ struct kasan_global {
+ #if KASAN_ABI_VERSION >= 4
+ 	struct kasan_source_location *location;
+ #endif
++#if KASAN_ABI_VERSION >= 5
++	char *odr_indicator;
++#endif
+ };
+ 
+ /**
+diff --git a/mm/khugepaged.c b/mm/khugepaged.c
+index 728d7790dc2d..87e1a7ca3846 100644
+--- a/mm/khugepaged.c
++++ b/mm/khugepaged.c
+@@ -103,6 +103,7 @@ static struct khugepaged_scan khugepaged_scan = {
+ 	.mm_head = LIST_HEAD_INIT(khugepaged_scan.mm_head),
+ };
+ 
++#ifdef CONFIG_SYSFS
+ static ssize_t scan_sleep_millisecs_show(struct kobject *kobj,
+ 					 struct kobj_attribute *attr,
+ 					 char *buf)
+@@ -295,6 +296,7 @@ struct attribute_group khugepaged_attr_group = {
+ 	.attrs = khugepaged_attr,
+ 	.name = "khugepaged",
+ };
++#endif /* CONFIG_SYSFS */
+ 
+ #define VM_NO_KHUGEPAGED (VM_SPECIAL | VM_HUGETLB)
+ 
+diff --git a/mm/mlock.c b/mm/mlock.c
+index 14645be06e30..9c91acc0e328 100644
+--- a/mm/mlock.c
++++ b/mm/mlock.c
+@@ -190,10 +190,13 @@ unsigned int munlock_vma_page(struct page *page)
+ 	 */
+ 	spin_lock_irq(zone_lru_lock(zone));
+ 
+-	nr_pages = hpage_nr_pages(page);
+-	if (!TestClearPageMlocked(page))
++	if (!TestClearPageMlocked(page)) {
++		/* Potentially, PTE-mapped THP: do not skip the rest PTEs */
++		nr_pages = 1;
+ 		goto unlock_out;
++	}
+ 
++	nr_pages = hpage_nr_pages(page);
+ 	__mod_zone_page_state(zone, NR_MLOCK, -nr_pages);
+ 
+ 	if (__munlock_isolate_lru_page(page, true)) {
+diff --git a/mm/truncate.c b/mm/truncate.c
+index a01cce450a26..8d8c62d89e6d 100644
+--- a/mm/truncate.c
++++ b/mm/truncate.c
+@@ -283,7 +283,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
+ 
+ 			if (!trylock_page(page))
+ 				continue;
+-			WARN_ON(page_to_pgoff(page) != index);
++			WARN_ON(page_to_index(page) != index);
+ 			if (PageWriteback(page)) {
+ 				unlock_page(page);
+ 				continue;
+@@ -371,7 +371,7 @@ void truncate_inode_pages_range(struct address_space *mapping,
+ 			}
+ 
+ 			lock_page(page);
+-			WARN_ON(page_to_pgoff(page) != index);
++			WARN_ON(page_to_index(page) != index);
+ 			wait_on_page_writeback(page);
+ 			truncate_inode_page(mapping, page);
+ 			unlock_page(page);
+@@ -492,7 +492,7 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping,
+ 			if (!trylock_page(page))
+ 				continue;
+ 
+-			WARN_ON(page_to_pgoff(page) != index);
++			WARN_ON(page_to_index(page) != index);
+ 
+ 			/* Middle of THP: skip */
+ 			if (PageTransTail(page)) {
+@@ -612,7 +612,7 @@ int invalidate_inode_pages2_range(struct address_space *mapping,
+ 			}
+ 
+ 			lock_page(page);
+-			WARN_ON(page_to_pgoff(page) != index);
++			WARN_ON(page_to_index(page) != index);
+ 			if (page->mapping != mapping) {
+ 				unlock_page(page);
+ 				continue;
+diff --git a/mm/workingset.c b/mm/workingset.c
+index 617475f529f4..fb1f9183d89a 100644
+--- a/mm/workingset.c
++++ b/mm/workingset.c
+@@ -348,7 +348,7 @@ static unsigned long count_shadow_nodes(struct shrinker *shrinker,
+ 	shadow_nodes = list_lru_shrink_count(&workingset_shadow_nodes, sc);
+ 	local_irq_enable();
+ 
+-	if (memcg_kmem_enabled()) {
++	if (sc->memcg) {
+ 		pages = mem_cgroup_node_nr_lru_pages(sc->memcg, sc->nid,
+ 						     LRU_ALL_FILE);
+ 	} else {
+diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c
+index 2333777f919d..8af1611b8ab2 100644
+--- a/net/batman-adv/tp_meter.c
++++ b/net/batman-adv/tp_meter.c
+@@ -837,6 +837,7 @@ static int batadv_tp_send(void *arg)
+ 	primary_if = batadv_primary_if_get_selected(bat_priv);
+ 	if (unlikely(!primary_if)) {
+ 		err = BATADV_TP_REASON_DST_UNREACHABLE;
++		tp_vars->reason = err;
+ 		goto out;
+ 	}
+ 
+diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c
+index 0bf6709d1006..6fb4314cec49 100644
+--- a/virt/kvm/arm/vgic/vgic-v2.c
++++ b/virt/kvm/arm/vgic/vgic-v2.c
+@@ -50,8 +50,10 @@ void vgic_v2_process_maintenance(struct kvm_vcpu *vcpu)
+ 
+ 			WARN_ON(cpuif->vgic_lr[lr] & GICH_LR_STATE);
+ 
+-			kvm_notify_acked_irq(vcpu->kvm, 0,
+-					     intid - VGIC_NR_PRIVATE_IRQS);
++			/* Only SPIs require notification */
++			if (vgic_valid_spi(vcpu->kvm, intid))
++				kvm_notify_acked_irq(vcpu->kvm, 0,
++						     intid - VGIC_NR_PRIVATE_IRQS);
+ 		}
+ 	}
+ 
+diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c
+index 9f0dae397d9c..5c9f9745e6ca 100644
+--- a/virt/kvm/arm/vgic/vgic-v3.c
++++ b/virt/kvm/arm/vgic/vgic-v3.c
+@@ -41,8 +41,10 @@ void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
+ 
+ 			WARN_ON(cpuif->vgic_lr[lr] & ICH_LR_STATE);
+ 
+-			kvm_notify_acked_irq(vcpu->kvm, 0,
+-					     intid - VGIC_NR_PRIVATE_IRQS);
++			/* Only SPIs require notification */
++			if (vgic_valid_spi(vcpu->kvm, intid))
++				kvm_notify_acked_irq(vcpu->kvm, 0,
++						     intid - VGIC_NR_PRIVATE_IRQS);
+ 		}
+ 
+ 		/*
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 195078225aa5..690d15eaee05 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2852,10 +2852,10 @@ static int kvm_ioctl_create_device(struct kvm *kvm,
+ 
+ 	ret = anon_inode_getfd(ops->name, &kvm_device_fops, dev, O_RDWR | O_CLOEXEC);
+ 	if (ret < 0) {
+-		ops->destroy(dev);
+ 		mutex_lock(&kvm->lock);
+ 		list_del(&dev->vm_node);
+ 		mutex_unlock(&kvm->lock);
++		ops->destroy(dev);
+ 		return ret;
+ 	}
+ 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-12-11  7:18 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2016-12-11  7:18 UTC (permalink / raw
  To: gentoo-commits

commit:     6a66ca4c64bcb45ae769c732d3e5540063c5e685
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 11 07:17:34 2016 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Sun Dec 11 07:17:34 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=6a66ca4c

Linux patch 4.8.14

 0000_README                                      |    8 +-
 1013_linux-4.8.14.patch                          | 1725 ++++++++++++++++++++++
 1520_fix-race-condition-in-packet-set-ring.patch |   62 -
 3 files changed, 1729 insertions(+), 66 deletions(-)

diff --git a/0000_README b/0000_README
index f162b9e..9b67d47 100644
--- a/0000_README
+++ b/0000_README
@@ -95,6 +95,10 @@ Patch:  1012_linux-4.8.13.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.13
 
+Patch:  1013_linux-4.8.14.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.14
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.
@@ -103,10 +107,6 @@ Patch:  1510_fs-enable-link-security-restrictions-by-default.patch
 From:   http://sources.debian.net/src/linux/3.16.7-ckt4-3/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch/
 Desc:   Enable link security restrictions by default.
 
-Patch:  1520_fix-race-condition-in-packet-set-ring.patch
-From:   https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=84ac7260236a49c79eede91617700174c2c19b0c
-Desc:   packet: fix race condition in packet_set_ring. CVE-2016-8655. Bug #601926.
-
 Patch:  2900_dev-root-proc-mount-fix.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=438380
 Desc:   Ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs.

diff --git a/1013_linux-4.8.14.patch b/1013_linux-4.8.14.patch
new file mode 100644
index 0000000..65e8e07
--- /dev/null
+++ b/1013_linux-4.8.14.patch
@@ -0,0 +1,1725 @@
+diff --git a/Makefile b/Makefile
+index b38abe9adef8..6a7492473a0d 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 13
++SUBLEVEL = 14
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
+index c3c12efe0bc0..9c0c8fd0b292 100644
+--- a/arch/sparc/kernel/signal_32.c
++++ b/arch/sparc/kernel/signal_32.c
+@@ -89,7 +89,7 @@ asmlinkage void do_sigreturn(struct pt_regs *regs)
+ 	sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
+ 
+ 	/* 1. Make sure we are not getting garbage from the user */
+-	if (!invalid_frame_pointer(sf, sizeof(*sf)))
++	if (invalid_frame_pointer(sf, sizeof(*sf)))
+ 		goto segv_and_exit;
+ 
+ 	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
+@@ -150,7 +150,7 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
+ 
+ 	synchronize_user_stack();
+ 	sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
+-	if (!invalid_frame_pointer(sf, sizeof(*sf)))
++	if (invalid_frame_pointer(sf, sizeof(*sf)))
+ 		goto segv;
+ 
+ 	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
+index 7ac6b62fb7c1..05c770825386 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -802,8 +802,10 @@ struct mdesc_mblock {
+ };
+ static struct mdesc_mblock *mblocks;
+ static int num_mblocks;
++static int find_numa_node_for_addr(unsigned long pa,
++				   struct node_mem_mask *pnode_mask);
+ 
+-static unsigned long ra_to_pa(unsigned long addr)
++static unsigned long __init ra_to_pa(unsigned long addr)
+ {
+ 	int i;
+ 
+@@ -819,8 +821,11 @@ static unsigned long ra_to_pa(unsigned long addr)
+ 	return addr;
+ }
+ 
+-static int find_node(unsigned long addr)
++static int __init find_node(unsigned long addr)
+ {
++	static bool search_mdesc = true;
++	static struct node_mem_mask last_mem_mask = { ~0UL, ~0UL };
++	static int last_index;
+ 	int i;
+ 
+ 	addr = ra_to_pa(addr);
+@@ -830,13 +835,30 @@ static int find_node(unsigned long addr)
+ 		if ((addr & p->mask) == p->val)
+ 			return i;
+ 	}
+-	/* The following condition has been observed on LDOM guests.*/
+-	WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node"
+-		" rule. Some physical memory will be owned by node 0.");
+-	return 0;
++	/* The following condition has been observed on LDOM guests because
++	 * node_masks only contains the best latency mask and value.
++	 * LDOM guest's mdesc can contain a single latency group to
++	 * cover multiple address range. Print warning message only if the
++	 * address cannot be found in node_masks nor mdesc.
++	 */
++	if ((search_mdesc) &&
++	    ((addr & last_mem_mask.mask) != last_mem_mask.val)) {
++		/* find the available node in the mdesc */
++		last_index = find_numa_node_for_addr(addr, &last_mem_mask);
++		numadbg("find_node: latency group for address 0x%lx is %d\n",
++			addr, last_index);
++		if ((last_index < 0) || (last_index >= num_node_masks)) {
++			/* WARN_ONCE() and use default group 0 */
++			WARN_ONCE(1, "find_node: A physical address doesn't match a NUMA node rule. Some physical memory will be owned by node 0.");
++			search_mdesc = false;
++			last_index = 0;
++		}
++	}
++
++	return last_index;
+ }
+ 
+-static u64 memblock_nid_range(u64 start, u64 end, int *nid)
++static u64 __init memblock_nid_range(u64 start, u64 end, int *nid)
+ {
+ 	*nid = find_node(start);
+ 	start += PAGE_SIZE;
+@@ -1160,6 +1182,41 @@ int __node_distance(int from, int to)
+ 	return numa_latency[from][to];
+ }
+ 
++static int find_numa_node_for_addr(unsigned long pa,
++				   struct node_mem_mask *pnode_mask)
++{
++	struct mdesc_handle *md = mdesc_grab();
++	u64 node, arc;
++	int i = 0;
++
++	node = mdesc_node_by_name(md, MDESC_NODE_NULL, "latency-groups");
++	if (node == MDESC_NODE_NULL)
++		goto out;
++
++	mdesc_for_each_node_by_name(md, node, "group") {
++		mdesc_for_each_arc(arc, md, node, MDESC_ARC_TYPE_FWD) {
++			u64 target = mdesc_arc_target(md, arc);
++			struct mdesc_mlgroup *m = find_mlgroup(target);
++
++			if (!m)
++				continue;
++			if ((pa & m->mask) == m->match) {
++				if (pnode_mask) {
++					pnode_mask->mask = m->mask;
++					pnode_mask->val = m->match;
++				}
++				mdesc_release(md);
++				return i;
++			}
++		}
++		i++;
++	}
++
++out:
++	mdesc_release(md);
++	return -1;
++}
++
+ static int __init find_best_numa_node_for_mlgroup(struct mdesc_mlgroup *grp)
+ {
+ 	int i;
+diff --git a/block/blk-map.c b/block/blk-map.c
+index b8657fa8dc9a..27fd8d92892d 100644
+--- a/block/blk-map.c
++++ b/block/blk-map.c
+@@ -118,6 +118,9 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
+ 	struct iov_iter i;
+ 	int ret;
+ 
++	if (!iter_is_iovec(iter))
++		goto fail;
++
+ 	if (map_data)
+ 		copy = true;
+ 	else if (iov_iter_alignment(iter) & align)
+@@ -140,6 +143,7 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq,
+ 
+ unmap_rq:
+ 	__blk_rq_unmap_user(bio);
++fail:
+ 	rq->bio = NULL;
+ 	return -EINVAL;
+ }
+diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c
+index bda37d336736..b081929e80bc 100644
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -904,9 +904,10 @@ static void b53_vlan_add(struct dsa_switch *ds, int port,
+ 
+ 		vl->members |= BIT(port) | BIT(cpu_port);
+ 		if (untagged)
+-			vl->untag |= BIT(port) | BIT(cpu_port);
++			vl->untag |= BIT(port);
+ 		else
+-			vl->untag &= ~(BIT(port) | BIT(cpu_port));
++			vl->untag &= ~BIT(port);
++		vl->untag &= ~BIT(cpu_port);
+ 
+ 		b53_set_vlan_entry(dev, vid, vl);
+ 		b53_fast_age_vlan(dev, vid);
+@@ -915,8 +916,6 @@ static void b53_vlan_add(struct dsa_switch *ds, int port,
+ 	if (pvid) {
+ 		b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port),
+ 			    vlan->vid_end);
+-		b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port),
+-			    vlan->vid_end);
+ 		b53_fast_age_vlan(dev, vid);
+ 	}
+ }
+@@ -926,7 +925,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port,
+ {
+ 	struct b53_device *dev = ds_to_priv(ds);
+ 	bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
+-	unsigned int cpu_port = dev->cpu_port;
+ 	struct b53_vlan *vl;
+ 	u16 vid;
+ 	u16 pvid;
+@@ -939,8 +937,6 @@ static int b53_vlan_del(struct dsa_switch *ds, int port,
+ 		b53_get_vlan_entry(dev, vid, vl);
+ 
+ 		vl->members &= ~BIT(port);
+-		if ((vl->members & BIT(cpu_port)) == BIT(cpu_port))
+-			vl->members = 0;
+ 
+ 		if (pvid == vid) {
+ 			if (is5325(dev) || is5365(dev))
+@@ -949,18 +945,14 @@ static int b53_vlan_del(struct dsa_switch *ds, int port,
+ 				pvid = 0;
+ 		}
+ 
+-		if (untagged) {
++		if (untagged)
+ 			vl->untag &= ~(BIT(port));
+-			if ((vl->untag & BIT(cpu_port)) == BIT(cpu_port))
+-				vl->untag = 0;
+-		}
+ 
+ 		b53_set_vlan_entry(dev, vid, vl);
+ 		b53_fast_age_vlan(dev, vid);
+ 	}
+ 
+ 	b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(port), pvid);
+-	b53_write16(dev, B53_VLAN_PAGE, B53_VLAN_PORT_DEF_TAG(cpu_port), pvid);
+ 	b53_fast_age_vlan(dev, pvid);
+ 
+ 	return 0;
+diff --git a/drivers/net/dsa/bcm_sf2.c b/drivers/net/dsa/bcm_sf2.c
+index b2b838724a9b..4036865b7c08 100644
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -1167,6 +1167,7 @@ static void bcm_sf2_sw_adjust_link(struct dsa_switch *ds, int port,
+ 				   struct phy_device *phydev)
+ {
+ 	struct bcm_sf2_priv *priv = ds_to_priv(ds);
++	struct ethtool_eee *p = &priv->port_sts[port].eee;
+ 	u32 id_mode_dis = 0, port_mode;
+ 	const char *str = NULL;
+ 	u32 reg;
+@@ -1241,6 +1242,9 @@ force_link:
+ 		reg |= DUPLX_MODE;
+ 
+ 	core_writel(priv, reg, CORE_STS_OVERRIDE_GMIIP_PORT(port));
++
++	if (!phydev->is_pseudo_fixed_link)
++		p->eee_enabled = bcm_sf2_eee_init(ds, port, phydev);
+ }
+ 
+ static void bcm_sf2_sw_fixed_link_update(struct dsa_switch *ds, int port,
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+index 541456398dfb..842d8b90484e 100644
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c
+@@ -1172,6 +1172,7 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
+ 					  struct bcmgenet_tx_ring *ring)
+ {
+ 	struct bcmgenet_priv *priv = netdev_priv(dev);
++	struct device *kdev = &priv->pdev->dev;
+ 	struct enet_cb *tx_cb_ptr;
+ 	struct netdev_queue *txq;
+ 	unsigned int pkts_compl = 0;
+@@ -1199,13 +1200,13 @@ static unsigned int __bcmgenet_tx_reclaim(struct net_device *dev,
+ 		if (tx_cb_ptr->skb) {
+ 			pkts_compl++;
+ 			bytes_compl += GENET_CB(tx_cb_ptr->skb)->bytes_sent;
+-			dma_unmap_single(&dev->dev,
++			dma_unmap_single(kdev,
+ 					 dma_unmap_addr(tx_cb_ptr, dma_addr),
+ 					 dma_unmap_len(tx_cb_ptr, dma_len),
+ 					 DMA_TO_DEVICE);
+ 			bcmgenet_free_cb(tx_cb_ptr);
+ 		} else if (dma_unmap_addr(tx_cb_ptr, dma_addr)) {
+-			dma_unmap_page(&dev->dev,
++			dma_unmap_page(kdev,
+ 				       dma_unmap_addr(tx_cb_ptr, dma_addr),
+ 				       dma_unmap_len(tx_cb_ptr, dma_len),
+ 				       DMA_TO_DEVICE);
+@@ -1775,6 +1776,7 @@ static int bcmgenet_alloc_rx_buffers(struct bcmgenet_priv *priv,
+ 
+ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
+ {
++	struct device *kdev = &priv->pdev->dev;
+ 	struct enet_cb *cb;
+ 	int i;
+ 
+@@ -1782,7 +1784,7 @@ static void bcmgenet_free_rx_buffers(struct bcmgenet_priv *priv)
+ 		cb = &priv->rx_cbs[i];
+ 
+ 		if (dma_unmap_addr(cb, dma_addr)) {
+-			dma_unmap_single(&priv->dev->dev,
++			dma_unmap_single(kdev,
+ 					 dma_unmap_addr(cb, dma_addr),
+ 					 priv->rx_buf_len, DMA_FROM_DEVICE);
+ 			dma_unmap_addr_set(cb, dma_addr, 0);
+diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
+index d954a97b0b0b..ef0dbcfa6ce6 100644
+--- a/drivers/net/ethernet/cadence/macb.c
++++ b/drivers/net/ethernet/cadence/macb.c
+@@ -959,6 +959,7 @@ static inline void macb_init_rx_ring(struct macb *bp)
+ 		addr += bp->rx_buffer_size;
+ 	}
+ 	bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
++	bp->rx_tail = 0;
+ }
+ 
+ static int macb_rx(struct macb *bp, int budget)
+@@ -1597,8 +1598,6 @@ static void macb_init_rings(struct macb *bp)
+ 	bp->queues[0].tx_head = 0;
+ 	bp->queues[0].tx_tail = 0;
+ 	bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
+-
+-	bp->rx_tail = 0;
+ }
+ 
+ static void macb_reset_hw(struct macb *bp)
+diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
+index 467138b423d3..d747e17d3429 100644
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -5220,6 +5220,19 @@ static SIMPLE_DEV_PM_OPS(sky2_pm_ops, sky2_suspend, sky2_resume);
+ 
+ static void sky2_shutdown(struct pci_dev *pdev)
+ {
++	struct sky2_hw *hw = pci_get_drvdata(pdev);
++	int port;
++
++	for (port = 0; port < hw->ports; port++) {
++		struct net_device *ndev = hw->dev[port];
++
++		rtnl_lock();
++		if (netif_running(ndev)) {
++			dev_close(ndev);
++			netif_device_detach(ndev);
++		}
++		rtnl_unlock();
++	}
+ 	sky2_suspend(&pdev->dev);
+ 	pci_wake_from_d3(pdev, device_may_wakeup(&pdev->dev));
+ 	pci_set_power_state(pdev, PCI_D3hot);
+diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c
+index 054e795df90f..92c9a95169c8 100644
+--- a/drivers/net/ethernet/renesas/sh_eth.c
++++ b/drivers/net/ethernet/renesas/sh_eth.c
+@@ -518,7 +518,7 @@ static struct sh_eth_cpu_data r7s72100_data = {
+ 
+ 	.ecsr_value	= ECSR_ICD,
+ 	.ecsipr_value	= ECSIPR_ICDIP,
+-	.eesipr_value	= 0xff7f009f,
++	.eesipr_value	= 0xe77f009f,
+ 
+ 	.tx_check	= EESR_TC1 | EESR_FTC,
+ 	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT |
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 16af1ce99233..5ad706b99af8 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -844,7 +844,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 	struct geneve_dev *geneve = netdev_priv(dev);
+ 	struct geneve_sock *gs4 = geneve->sock4;
+ 	struct rtable *rt = NULL;
+-	const struct iphdr *iip; /* interior IP header */
+ 	int err = -EINVAL;
+ 	struct flowi4 fl4;
+ 	__u8 tos, ttl;
+@@ -871,8 +870,6 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+ 	skb_reset_mac_header(skb);
+ 
+-	iip = ip_hdr(skb);
+-
+ 	if (info) {
+ 		const struct ip_tunnel_key *key = &info->key;
+ 		u8 *opts = NULL;
+@@ -892,7 +889,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 		if (unlikely(err))
+ 			goto tx_error;
+ 
+-		tos = ip_tunnel_ecn_encap(key->tos, iip, skb);
++		tos = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
+ 		ttl = key->ttl;
+ 		df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
+ 	} else {
+@@ -901,7 +898,7 @@ static netdev_tx_t geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 		if (unlikely(err))
+ 			goto tx_error;
+ 
+-		tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, iip, skb);
++		tos = ip_tunnel_ecn_encap(fl4.flowi4_tos, ip_hdr(skb), skb);
+ 		ttl = geneve->ttl;
+ 		if (!ttl && IN_MULTICAST(ntohl(fl4.daddr)))
+ 			ttl = 1;
+@@ -934,7 +931,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 	struct geneve_dev *geneve = netdev_priv(dev);
+ 	struct geneve_sock *gs6 = geneve->sock6;
+ 	struct dst_entry *dst = NULL;
+-	const struct iphdr *iip; /* interior IP header */
+ 	int err = -EINVAL;
+ 	struct flowi6 fl6;
+ 	__u8 prio, ttl;
+@@ -959,8 +955,6 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 	sport = udp_flow_src_port(geneve->net, skb, 1, USHRT_MAX, true);
+ 	skb_reset_mac_header(skb);
+ 
+-	iip = ip_hdr(skb);
+-
+ 	if (info) {
+ 		const struct ip_tunnel_key *key = &info->key;
+ 		u8 *opts = NULL;
+@@ -981,7 +975,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 		if (unlikely(err))
+ 			goto tx_error;
+ 
+-		prio = ip_tunnel_ecn_encap(key->tos, iip, skb);
++		prio = ip_tunnel_ecn_encap(key->tos, ip_hdr(skb), skb);
+ 		ttl = key->ttl;
+ 		label = info->key.label;
+ 	} else {
+@@ -991,7 +985,7 @@ static netdev_tx_t geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
+ 			goto tx_error;
+ 
+ 		prio = ip_tunnel_ecn_encap(ip6_tclass(fl6.flowlabel),
+-					   iip, skb);
++					   ip_hdr(skb), skb);
+ 		ttl = geneve->ttl;
+ 		if (!ttl && ipv6_addr_is_multicast(&fl6.daddr))
+ 			ttl = 1;
+diff --git a/drivers/net/usb/cdc_ether.c b/drivers/net/usb/cdc_ether.c
+index c47ec0a04c8e..dd623f674487 100644
+--- a/drivers/net/usb/cdc_ether.c
++++ b/drivers/net/usb/cdc_ether.c
+@@ -388,12 +388,6 @@ void usbnet_cdc_status(struct usbnet *dev, struct urb *urb)
+ 	case USB_CDC_NOTIFY_NETWORK_CONNECTION:
+ 		netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
+ 			  event->wValue ? "on" : "off");
+-
+-		/* Work-around for devices with broken off-notifications */
+-		if (event->wValue &&
+-		    !test_bit(__LINK_STATE_NOCARRIER, &dev->net->state))
+-			usbnet_link_change(dev, 0, 0);
+-
+ 		usbnet_link_change(dev, !!event->wValue, 0);
+ 		break;
+ 	case USB_CDC_NOTIFY_SPEED_CHANGE:	/* tx/rx rates */
+@@ -466,6 +460,36 @@ static int usbnet_cdc_zte_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
+ 	return 1;
+ }
+ 
++/* Ensure correct link state
++ *
++ * Some devices (ZTE MF823/831/910) export two carrier on notifications when
++ * connected. This causes the link state to be incorrect. Work around this by
++ * always setting the state to off, then on.
++ */
++void usbnet_cdc_zte_status(struct usbnet *dev, struct urb *urb)
++{
++	struct usb_cdc_notification *event;
++
++	if (urb->actual_length < sizeof(*event))
++		return;
++
++	event = urb->transfer_buffer;
++
++	if (event->bNotificationType != USB_CDC_NOTIFY_NETWORK_CONNECTION) {
++		usbnet_cdc_status(dev, urb);
++		return;
++	}
++
++	netif_dbg(dev, timer, dev->net, "CDC: carrier %s\n",
++		  event->wValue ? "on" : "off");
++
++	if (event->wValue &&
++	    netif_carrier_ok(dev->net))
++		netif_carrier_off(dev->net);
++
++	usbnet_link_change(dev, !!event->wValue, 0);
++}
++
+ static const struct driver_info	cdc_info = {
+ 	.description =	"CDC Ethernet Device",
+ 	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
+@@ -481,7 +505,7 @@ static const struct driver_info	zte_cdc_info = {
+ 	.flags =	FLAG_ETHER | FLAG_POINTTOPOINT,
+ 	.bind =		usbnet_cdc_zte_bind,
+ 	.unbind =	usbnet_cdc_unbind,
+-	.status =	usbnet_cdc_status,
++	.status =	usbnet_cdc_zte_status,
+ 	.set_rx_mode =	usbnet_cdc_update_filter,
+ 	.manage_power =	usbnet_manage_power,
+ 	.rx_fixup = usbnet_cdc_zte_rx_fixup,
+diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
+index bf3fd34924bd..d8072092e5f0 100644
+--- a/drivers/net/virtio_net.c
++++ b/drivers/net/virtio_net.c
+@@ -1468,6 +1468,11 @@ static void virtnet_free_queues(struct virtnet_info *vi)
+ 		netif_napi_del(&vi->rq[i].napi);
+ 	}
+ 
++	/* We called napi_hash_del() before netif_napi_del(),
++	 * we need to respect an RCU grace period before freeing vi->rq
++	 */
++	synchronize_net();
++
+ 	kfree(vi->rq);
+ 	kfree(vi->sq);
+ }
+diff --git a/include/linux/uio.h b/include/linux/uio.h
+index 75b4aaf31a9d..944e7baf17eb 100644
+--- a/include/linux/uio.h
++++ b/include/linux/uio.h
+@@ -102,12 +102,12 @@ int iov_iter_npages(const struct iov_iter *i, int maxpages);
+ 
+ const void *dup_iter(struct iov_iter *new, struct iov_iter *old, gfp_t flags);
+ 
+-static inline size_t iov_iter_count(struct iov_iter *i)
++static inline size_t iov_iter_count(const struct iov_iter *i)
+ {
+ 	return i->count;
+ }
+ 
+-static inline bool iter_is_iovec(struct iov_iter *i)
++static inline bool iter_is_iovec(const struct iov_iter *i)
+ {
+ 	return !(i->type & (ITER_BVEC | ITER_KVEC));
+ }
+diff --git a/include/net/gro_cells.h b/include/net/gro_cells.h
+index d15214d673b2..2a1abbf8da74 100644
+--- a/include/net/gro_cells.h
++++ b/include/net/gro_cells.h
+@@ -68,6 +68,9 @@ static inline int gro_cells_init(struct gro_cells *gcells, struct net_device *de
+ 		struct gro_cell *cell = per_cpu_ptr(gcells->cells, i);
+ 
+ 		__skb_queue_head_init(&cell->napi_skbs);
++
++		set_bit(NAPI_STATE_NO_BUSY_POLL, &cell->napi.state);
++
+ 		netif_napi_add(dev, &cell->napi, gro_cell_poll, 64);
+ 		napi_enable(&cell->napi);
+ 	}
+diff --git a/net/core/flow.c b/net/core/flow.c
+index 3937b1b68d5b..18e8893d4be5 100644
+--- a/net/core/flow.c
++++ b/net/core/flow.c
+@@ -95,7 +95,6 @@ static void flow_cache_gc_task(struct work_struct *work)
+ 	list_for_each_entry_safe(fce, n, &gc_list, u.gc_list) {
+ 		flow_entry_kill(fce, xfrm);
+ 		atomic_dec(&xfrm->flow_cache_gc_count);
+-		WARN_ON(atomic_read(&xfrm->flow_cache_gc_count) < 0);
+ 	}
+ }
+ 
+@@ -236,9 +235,8 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
+ 		if (fcp->hash_count > fc->high_watermark)
+ 			flow_cache_shrink(fc, fcp);
+ 
+-		if (fcp->hash_count > 2 * fc->high_watermark ||
+-		    atomic_read(&net->xfrm.flow_cache_gc_count) > fc->high_watermark) {
+-			atomic_inc(&net->xfrm.flow_cache_genid);
++		if (atomic_read(&net->xfrm.flow_cache_gc_count) >
++		    2 * num_online_cpus() * fc->high_watermark) {
+ 			flo = ERR_PTR(-ENOBUFS);
+ 			goto ret_object;
+ 		}
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
+index 2c2eb1b629b1..2e9a1c2818c7 100644
+--- a/net/core/net_namespace.c
++++ b/net/core/net_namespace.c
+@@ -217,6 +217,8 @@ int peernet2id_alloc(struct net *net, struct net *peer)
+ 	bool alloc;
+ 	int id;
+ 
++	if (atomic_read(&net->count) == 0)
++		return NETNSA_NSID_NOT_ASSIGNED;
+ 	spin_lock_irqsave(&net->nsid_lock, flags);
+ 	alloc = atomic_read(&peer->count) == 0 ? false : true;
+ 	id = __peernet2id_alloc(net, peer, &alloc);
+diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
+index 189cc78c77eb..08c3702f7074 100644
+--- a/net/core/rtnetlink.c
++++ b/net/core/rtnetlink.c
+@@ -1578,7 +1578,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
+ 		head = &net->dev_index_head[h];
+ 		hlist_for_each_entry(dev, head, index_hlist) {
+ 			if (link_dump_filtered(dev, master_idx, kind_ops))
+-				continue;
++				goto cont;
+ 			if (idx < s_idx)
+ 				goto cont;
+ 			err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
+@@ -2791,7 +2791,10 @@ nla_put_failure:
+ 
+ static inline size_t rtnl_fdb_nlmsg_size(void)
+ {
+-	return NLMSG_ALIGN(sizeof(struct ndmsg)) + nla_total_size(ETH_ALEN);
++	return NLMSG_ALIGN(sizeof(struct ndmsg)) +
++	       nla_total_size(ETH_ALEN) +	/* NDA_LLADDR */
++	       nla_total_size(sizeof(u16)) +	/* NDA_VLAN */
++	       0;
+ }
+ 
+ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, u16 vid, int type,
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 10acaccca5c8..ba27920b6bbc 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -715,7 +715,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
+ 		val = min_t(u32, val, sysctl_wmem_max);
+ set_sndbuf:
+ 		sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
+-		sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
++		sk->sk_sndbuf = max_t(int, val * 2, SOCK_MIN_SNDBUF);
+ 		/* Wake up sending tasks if we upped the value. */
+ 		sk->sk_write_space(sk);
+ 		break;
+@@ -751,7 +751,7 @@ set_rcvbuf:
+ 		 * returning the value we actually used in getsockopt
+ 		 * is the most desirable behavior.
+ 		 */
+-		sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
++		sk->sk_rcvbuf = max_t(int, val * 2, SOCK_MIN_RCVBUF);
+ 		break;
+ 
+ 	case SO_RCVBUFFORCE:
+diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
+index b567c8725aea..edbe59d203ef 100644
+--- a/net/dccp/ipv4.c
++++ b/net/dccp/ipv4.c
+@@ -700,6 +700,7 @@ int dccp_invalid_packet(struct sk_buff *skb)
+ {
+ 	const struct dccp_hdr *dh;
+ 	unsigned int cscov;
++	u8 dccph_doff;
+ 
+ 	if (skb->pkt_type != PACKET_HOST)
+ 		return 1;
+@@ -721,18 +722,19 @@ int dccp_invalid_packet(struct sk_buff *skb)
+ 	/*
+ 	 * If P.Data Offset is too small for packet type, drop packet and return
+ 	 */
+-	if (dh->dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
+-		DCCP_WARN("P.Data Offset(%u) too small\n", dh->dccph_doff);
++	dccph_doff = dh->dccph_doff;
++	if (dccph_doff < dccp_hdr_len(skb) / sizeof(u32)) {
++		DCCP_WARN("P.Data Offset(%u) too small\n", dccph_doff);
+ 		return 1;
+ 	}
+ 	/*
+ 	 * If P.Data Offset is too too large for packet, drop packet and return
+ 	 */
+-	if (!pskb_may_pull(skb, dh->dccph_doff * sizeof(u32))) {
+-		DCCP_WARN("P.Data Offset(%u) too large\n", dh->dccph_doff);
++	if (!pskb_may_pull(skb, dccph_doff * sizeof(u32))) {
++		DCCP_WARN("P.Data Offset(%u) too large\n", dccph_doff);
+ 		return 1;
+ 	}
+-
++	dh = dccp_hdr(skb);
+ 	/*
+ 	 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
+ 	 * has short sequence numbers), drop packet and return
+diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c
+index f30bad9678f0..3bdecd2f9b88 100644
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -28,8 +28,10 @@ static struct dsa_switch_tree *dsa_get_dst(u32 tree)
+ 	struct dsa_switch_tree *dst;
+ 
+ 	list_for_each_entry(dst, &dsa_switch_trees, list)
+-		if (dst->tree == tree)
++		if (dst->tree == tree) {
++			kref_get(&dst->refcount);
+ 			return dst;
++		}
+ 	return NULL;
+ }
+ 
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index eebbc0f2baa8..ed22af67c58a 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1237,7 +1237,7 @@ struct sk_buff *inet_gso_segment(struct sk_buff *skb,
+ 		fixedid = !!(skb_shinfo(skb)->gso_type & SKB_GSO_TCP_FIXEDID);
+ 
+ 		/* fixed ID is invalid if DF bit is not set */
+-		if (fixedid && !(iph->frag_off & htons(IP_DF)))
++		if (fixedid && !(ip_hdr(skb)->frag_off & htons(IP_DF)))
+ 			goto out;
+ 	}
+ 
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index d95631d09248..20fb25e3027b 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -476,7 +476,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+ 		esph = (void *)skb_push(skb, 4);
+ 		*seqhi = esph->spi;
+ 		esph->spi = esph->seq_no;
+-		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
++		esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
+ 		aead_request_set_callback(req, 0, esp_input_done_esn, skb);
+ 	}
+ 
+diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
+index 1b25daf8c7f1..9301308528f8 100644
+--- a/net/ipv4/fib_frontend.c
++++ b/net/ipv4/fib_frontend.c
+@@ -157,7 +157,7 @@ static void fib_replace_table(struct net *net, struct fib_table *old,
+ 
+ int fib_unmerge(struct net *net)
+ {
+-	struct fib_table *old, *new;
++	struct fib_table *old, *new, *main_table;
+ 
+ 	/* attempt to fetch local table if it has been allocated */
+ 	old = fib_get_table(net, RT_TABLE_LOCAL);
+@@ -168,11 +168,21 @@ int fib_unmerge(struct net *net)
+ 	if (!new)
+ 		return -ENOMEM;
+ 
++	/* table is already unmerged */
++	if (new == old)
++		return 0;
++
+ 	/* replace merged table with clean table */
+-	if (new != old) {
+-		fib_replace_table(net, old, new);
+-		fib_free_table(old);
+-	}
++	fib_replace_table(net, old, new);
++	fib_free_table(old);
++
++	/* attempt to fetch main table if it has been allocated */
++	main_table = fib_get_table(net, RT_TABLE_MAIN);
++	if (!main_table)
++		return 0;
++
++	/* flush local entries from main table */
++	fib_table_flush_external(main_table);
+ 
+ 	return 0;
+ }
+diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
+index 7ef703102dca..84fd727274cf 100644
+--- a/net/ipv4/fib_trie.c
++++ b/net/ipv4/fib_trie.c
+@@ -681,6 +681,13 @@ static unsigned char update_suffix(struct key_vector *tn)
+ {
+ 	unsigned char slen = tn->pos;
+ 	unsigned long stride, i;
++	unsigned char slen_max;
++
++	/* only vector 0 can have a suffix length greater than or equal to
++	 * tn->pos + tn->bits, the second highest node will have a suffix
++	 * length at most of tn->pos + tn->bits - 1
++	 */
++	slen_max = min_t(unsigned char, tn->pos + tn->bits - 1, tn->slen);
+ 
+ 	/* search though the list of children looking for nodes that might
+ 	 * have a suffix greater than the one we currently have.  This is
+@@ -698,12 +705,8 @@ static unsigned char update_suffix(struct key_vector *tn)
+ 		slen = n->slen;
+ 		i &= ~(stride - 1);
+ 
+-		/* if slen covers all but the last bit we can stop here
+-		 * there will be nothing longer than that since only node
+-		 * 0 and 1 << (bits - 1) could have that as their suffix
+-		 * length.
+-		 */
+-		if ((slen + 1) >= (tn->pos + tn->bits))
++		/* stop searching if we have hit the maximum possible value */
++		if (slen >= slen_max)
+ 			break;
+ 	}
+ 
+@@ -875,39 +878,27 @@ static struct key_vector *resize(struct trie *t, struct key_vector *tn)
+ 		return collapse(t, tn);
+ 
+ 	/* update parent in case halve failed */
+-	tp = node_parent(tn);
+-
+-	/* Return if at least one deflate was run */
+-	if (max_work != MAX_WORK)
+-		return tp;
+-
+-	/* push the suffix length to the parent node */
+-	if (tn->slen > tn->pos) {
+-		unsigned char slen = update_suffix(tn);
+-
+-		if (slen > tp->slen)
+-			tp->slen = slen;
+-	}
+-
+-	return tp;
++	return node_parent(tn);
+ }
+ 
+-static void leaf_pull_suffix(struct key_vector *tp, struct key_vector *l)
++static void node_pull_suffix(struct key_vector *tn, unsigned char slen)
+ {
+-	while ((tp->slen > tp->pos) && (tp->slen > l->slen)) {
+-		if (update_suffix(tp) > l->slen)
++	unsigned char node_slen = tn->slen;
++
++	while ((node_slen > tn->pos) && (node_slen > slen)) {
++		slen = update_suffix(tn);
++		if (node_slen == slen)
+ 			break;
+-		tp = node_parent(tp);
++
++		tn = node_parent(tn);
++		node_slen = tn->slen;
+ 	}
+ }
+ 
+-static void leaf_push_suffix(struct key_vector *tn, struct key_vector *l)
++static void node_push_suffix(struct key_vector *tn, unsigned char slen)
+ {
+-	/* if this is a new leaf then tn will be NULL and we can sort
+-	 * out parent suffix lengths as a part of trie_rebalance
+-	 */
+-	while (tn->slen < l->slen) {
+-		tn->slen = l->slen;
++	while (tn->slen < slen) {
++		tn->slen = slen;
+ 		tn = node_parent(tn);
+ 	}
+ }
+@@ -1028,6 +1019,7 @@ static int fib_insert_node(struct trie *t, struct key_vector *tp,
+ 	}
+ 
+ 	/* Case 3: n is NULL, and will just insert a new leaf */
++	node_push_suffix(tp, new->fa_slen);
+ 	NODE_INIT_PARENT(l, tp);
+ 	put_child_root(tp, key, l);
+ 	trie_rebalance(t, tp);
+@@ -1069,7 +1061,7 @@ static int fib_insert_alias(struct trie *t, struct key_vector *tp,
+ 	/* if we added to the tail node then we need to update slen */
+ 	if (l->slen < new->fa_slen) {
+ 		l->slen = new->fa_slen;
+-		leaf_push_suffix(tp, l);
++		node_push_suffix(tp, new->fa_slen);
+ 	}
+ 
+ 	return 0;
+@@ -1470,6 +1462,8 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
+ 	 * out parent suffix lengths as a part of trie_rebalance
+ 	 */
+ 	if (hlist_empty(&l->leaf)) {
++		if (tp->slen == l->slen)
++			node_pull_suffix(tp, tp->pos);
+ 		put_child_root(tp, l->key, NULL);
+ 		node_free(l);
+ 		trie_rebalance(t, tp);
+@@ -1482,7 +1476,7 @@ static void fib_remove_alias(struct trie *t, struct key_vector *tp,
+ 
+ 	/* update the trie with the latest suffix length */
+ 	l->slen = fa->fa_slen;
+-	leaf_pull_suffix(tp, l);
++	node_pull_suffix(tp, fa->fa_slen);
+ }
+ 
+ /* Caller must hold RTNL. */
+@@ -1713,8 +1707,10 @@ struct fib_table *fib_trie_unmerge(struct fib_table *oldtb)
+ 				local_l = fib_find_node(lt, &local_tp, l->key);
+ 
+ 			if (fib_insert_alias(lt, local_tp, local_l, new_fa,
+-					     NULL, l->key))
++					     NULL, l->key)) {
++				kmem_cache_free(fn_alias_kmem, new_fa);
+ 				goto out;
++			}
+ 		}
+ 
+ 		/* stop loop if key wrapped back to 0 */
+@@ -1751,6 +1747,10 @@ void fib_table_flush_external(struct fib_table *tb)
+ 			if (IS_TRIE(pn))
+ 				break;
+ 
++			/* update the suffix to address pulled leaves */
++			if (pn->slen > pn->pos)
++				update_suffix(pn);
++
+ 			/* resize completed node */
+ 			pn = resize(t, pn);
+ 			cindex = get_index(pkey, pn);
+@@ -1826,6 +1826,10 @@ int fib_table_flush(struct fib_table *tb)
+ 			if (IS_TRIE(pn))
+ 				break;
+ 
++			/* update the suffix to address pulled leaves */
++			if (pn->slen > pn->pos)
++				update_suffix(pn);
++
+ 			/* resize completed node */
+ 			pn = resize(t, pn);
+ 			cindex = get_index(pkey, pn);
+diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
+index 307daed9a4b9..f4790c30c543 100644
+--- a/net/ipv4/ip_output.c
++++ b/net/ipv4/ip_output.c
+@@ -98,6 +98,9 @@ int __ip_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
+ 
+ 	iph->tot_len = htons(skb->len);
+ 	ip_send_check(iph);
++
++	skb->protocol = htons(ETH_P_IP);
++
+ 	return nf_hook(NFPROTO_IPV4, NF_INET_LOCAL_OUT,
+ 		       net, sk, skb, NULL, skb_dst(skb)->dev,
+ 		       dst_output);
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index 66ddcb60519a..dcdd5aed7eb1 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -662,6 +662,10 @@ int ping_common_sendmsg(int family, struct msghdr *msg, size_t len,
+ 	if (len > 0xFFFF)
+ 		return -EMSGSIZE;
+ 
++	/* Must have at least a full ICMP header. */
++	if (len < icmph_len)
++		return -EINVAL;
++
+ 	/*
+ 	 *	Check the flags.
+ 	 */
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index c0d71e7d663e..a2d54f5b0fe0 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1451,7 +1451,7 @@ static void udp_v4_rehash(struct sock *sk)
+ 	udp_lib_rehash(sk, new_hash);
+ }
+ 
+-static int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
++int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc;
+ 
+diff --git a/net/ipv4/udp_impl.h b/net/ipv4/udp_impl.h
+index 7e0fe4bdd967..feb50a16398d 100644
+--- a/net/ipv4/udp_impl.h
++++ b/net/ipv4/udp_impl.h
+@@ -25,7 +25,7 @@ int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
+ 		int flags, int *addr_len);
+ int udp_sendpage(struct sock *sk, struct page *page, int offset, size_t size,
+ 		 int flags);
+-int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
++int __udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+ void udp_destroy_sock(struct sock *sk);
+ 
+ #ifdef CONFIG_PROC_FS
+diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c
+index 2eea073e27ef..705d9fbf0bcf 100644
+--- a/net/ipv4/udplite.c
++++ b/net/ipv4/udplite.c
+@@ -50,7 +50,7 @@ struct proto 	udplite_prot = {
+ 	.sendmsg	   = udp_sendmsg,
+ 	.recvmsg	   = udp_recvmsg,
+ 	.sendpage	   = udp_sendpage,
+-	.backlog_rcv	   = udp_queue_rcv_skb,
++	.backlog_rcv	   = __udp_queue_rcv_skb,
+ 	.hash		   = udp_lib_hash,
+ 	.unhash		   = udp_lib_unhash,
+ 	.get_port	   = udp_v4_get_port,
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index f5432d65e6bf..8f2e36f8afd9 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -163,7 +163,7 @@ static struct rt6_info *addrconf_get_prefix_route(const struct in6_addr *pfx,
+ 
+ static void addrconf_dad_start(struct inet6_ifaddr *ifp);
+ static void addrconf_dad_work(struct work_struct *w);
+-static void addrconf_dad_completed(struct inet6_ifaddr *ifp);
++static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id);
+ static void addrconf_dad_run(struct inet6_dev *idev);
+ static void addrconf_rs_timer(unsigned long data);
+ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifa);
+@@ -2893,6 +2893,7 @@ static void add_addr(struct inet6_dev *idev, const struct in6_addr *addr,
+ 		spin_lock_bh(&ifp->lock);
+ 		ifp->flags &= ~IFA_F_TENTATIVE;
+ 		spin_unlock_bh(&ifp->lock);
++		rt_genid_bump_ipv6(dev_net(idev->dev));
+ 		ipv6_ifa_notify(RTM_NEWADDR, ifp);
+ 		in6_ifa_put(ifp);
+ 	}
+@@ -3736,7 +3737,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
+ {
+ 	struct inet6_dev *idev = ifp->idev;
+ 	struct net_device *dev = idev->dev;
+-	bool notify = false;
++	bool bump_id, notify = false;
+ 
+ 	addrconf_join_solict(dev, &ifp->addr);
+ 
+@@ -3751,11 +3752,12 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
+ 	    idev->cnf.accept_dad < 1 ||
+ 	    !(ifp->flags&IFA_F_TENTATIVE) ||
+ 	    ifp->flags & IFA_F_NODAD) {
++		bump_id = ifp->flags & IFA_F_TENTATIVE;
+ 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
+ 		spin_unlock(&ifp->lock);
+ 		read_unlock_bh(&idev->lock);
+ 
+-		addrconf_dad_completed(ifp);
++		addrconf_dad_completed(ifp, bump_id);
+ 		return;
+ 	}
+ 
+@@ -3815,8 +3817,8 @@ static void addrconf_dad_work(struct work_struct *w)
+ 						struct inet6_ifaddr,
+ 						dad_work);
+ 	struct inet6_dev *idev = ifp->idev;
++	bool bump_id, disable_ipv6 = false;
+ 	struct in6_addr mcaddr;
+-	bool disable_ipv6 = false;
+ 
+ 	enum {
+ 		DAD_PROCESS,
+@@ -3886,11 +3888,12 @@ static void addrconf_dad_work(struct work_struct *w)
+ 		 * DAD was successful
+ 		 */
+ 
++		bump_id = ifp->flags & IFA_F_TENTATIVE;
+ 		ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC|IFA_F_DADFAILED);
+ 		spin_unlock(&ifp->lock);
+ 		write_unlock_bh(&idev->lock);
+ 
+-		addrconf_dad_completed(ifp);
++		addrconf_dad_completed(ifp, bump_id);
+ 
+ 		goto out;
+ 	}
+@@ -3927,7 +3930,7 @@ static bool ipv6_lonely_lladdr(struct inet6_ifaddr *ifp)
+ 	return true;
+ }
+ 
+-static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
++static void addrconf_dad_completed(struct inet6_ifaddr *ifp, bool bump_id)
+ {
+ 	struct net_device *dev = ifp->idev->dev;
+ 	struct in6_addr lladdr;
+@@ -3978,6 +3981,9 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
+ 		spin_unlock(&ifp->lock);
+ 		write_unlock_bh(&ifp->idev->lock);
+ 	}
++
++	if (bump_id)
++		rt_genid_bump_ipv6(dev_net(dev));
+ }
+ 
+ static void addrconf_dad_run(struct inet6_dev *idev)
+diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
+index 060a60b2f8a6..111ba55fd512 100644
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -418,7 +418,7 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
+ 		esph = (void *)skb_push(skb, 4);
+ 		*seqhi = esph->spi;
+ 		esph->spi = esph->seq_no;
+-		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.input.hi);
++		esph->seq_no = XFRM_SKB_CB(skb)->seq.input.hi;
+ 		aead_request_set_callback(req, 0, esp_input_done_esn, skb);
+ 	}
+ 
+diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c
+index a09418bda1f8..93294cf4525c 100644
+--- a/net/ipv6/ip6_offload.c
++++ b/net/ipv6/ip6_offload.c
+@@ -98,7 +98,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
+ 		segs = ops->callbacks.gso_segment(skb, features);
+ 	}
+ 
+-	if (IS_ERR(segs))
++	if (IS_ERR_OR_NULL(segs))
+ 		goto out;
+ 
+ 	for (skb = segs; skb; skb = skb->next) {
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 41489f39c456..da4e7b377812 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -1014,6 +1014,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ 	int mtu;
+ 	unsigned int psh_hlen = sizeof(struct ipv6hdr) + t->encap_hlen;
+ 	unsigned int max_headroom = psh_hlen;
++	bool use_cache = false;
+ 	int err = -1;
+ 
+ 	/* NBMA tunnel */
+@@ -1038,7 +1039,15 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ 
+ 		memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr));
+ 		neigh_release(neigh);
+-	} else if (!fl6->flowi6_mark)
++	} else if (!(t->parms.flags &
++		     (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) {
++		/* enable the cache only only if the routing decision does
++		 * not depend on the current inner header value
++		 */
++		use_cache = true;
++	}
++
++	if (use_cache)
+ 		dst = dst_cache_get(&t->dst_cache);
+ 
+ 	if (!ip6_tnl_xmit_ctl(t, &fl6->saddr, &fl6->daddr))
+@@ -1113,7 +1122,7 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ 		skb = new_skb;
+ 	}
+ 
+-	if (!fl6->flowi6_mark && ndst)
++	if (use_cache && ndst)
+ 		dst_cache_set_ip6(&t->dst_cache, ndst, &fl6->saddr);
+ 	skb_dst_set(skb, dst);
+ 
+@@ -1134,7 +1143,6 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
+ 	if (err)
+ 		return err;
+ 
+-	skb->protocol = htons(ETH_P_IPV6);
+ 	skb_push(skb, sizeof(struct ipv6hdr));
+ 	skb_reset_network_header(skb);
+ 	ipv6h = ipv6_hdr(skb);
+diff --git a/net/ipv6/output_core.c b/net/ipv6/output_core.c
+index 462f2a76b5c2..1d184322a7b1 100644
+--- a/net/ipv6/output_core.c
++++ b/net/ipv6/output_core.c
+@@ -148,6 +148,8 @@ int __ip6_local_out(struct net *net, struct sock *sk, struct sk_buff *skb)
+ 	ipv6_hdr(skb)->payload_len = htons(len);
+ 	IP6CB(skb)->nhoff = offsetof(struct ipv6hdr, nexthdr);
+ 
++	skb->protocol = htons(ETH_P_IPV6);
++
+ 	return nf_hook(NFPROTO_IPV6, NF_INET_LOCAL_OUT,
+ 		       net, sk, skb, NULL, skb_dst(skb)->dev,
+ 		       dst_output);
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index c2a8656c22eb..fa39ab8ec1fc 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -514,7 +514,7 @@ out:
+ 	return;
+ }
+ 
+-static int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
++int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ {
+ 	int rc;
+ 
+diff --git a/net/ipv6/udp_impl.h b/net/ipv6/udp_impl.h
+index 0682c031ccdc..3c1dbc9f74cf 100644
+--- a/net/ipv6/udp_impl.h
++++ b/net/ipv6/udp_impl.h
+@@ -26,7 +26,7 @@ int compat_udpv6_getsockopt(struct sock *sk, int level, int optname,
+ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len);
+ int udpv6_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
+ 		  int flags, int *addr_len);
+-int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
++int __udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb);
+ void udpv6_destroy_sock(struct sock *sk);
+ 
+ void udp_v6_clear_sk(struct sock *sk, int size);
+diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c
+index fd6ef414899b..af2895c77ed6 100644
+--- a/net/ipv6/udplite.c
++++ b/net/ipv6/udplite.c
+@@ -45,7 +45,7 @@ struct proto udplitev6_prot = {
+ 	.getsockopt	   = udpv6_getsockopt,
+ 	.sendmsg	   = udpv6_sendmsg,
+ 	.recvmsg	   = udpv6_recvmsg,
+-	.backlog_rcv	   = udpv6_queue_rcv_skb,
++	.backlog_rcv	   = __udpv6_queue_rcv_skb,
+ 	.hash		   = udp_lib_hash,
+ 	.unhash		   = udp_lib_unhash,
+ 	.get_port	   = udp_v6_get_port,
+diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
+index 42de4ccd159f..d0e906d39642 100644
+--- a/net/l2tp/l2tp_ip.c
++++ b/net/l2tp/l2tp_ip.c
+@@ -251,8 +251,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ 	int ret;
+ 	int chk_addr_ret;
+ 
+-	if (!sock_flag(sk, SOCK_ZAPPED))
+-		return -EINVAL;
+ 	if (addr_len < sizeof(struct sockaddr_l2tpip))
+ 		return -EINVAL;
+ 	if (addr->l2tp_family != AF_INET)
+@@ -267,6 +265,9 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ 	read_unlock_bh(&l2tp_ip_lock);
+ 
+ 	lock_sock(sk);
++	if (!sock_flag(sk, SOCK_ZAPPED))
++		goto out;
++
+ 	if (sk->sk_state != TCP_CLOSE || addr_len < sizeof(struct sockaddr_l2tpip))
+ 		goto out;
+ 
+diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
+index ea2ae6664cc8..b9c6a412b806 100644
+--- a/net/l2tp/l2tp_ip6.c
++++ b/net/l2tp/l2tp_ip6.c
+@@ -269,8 +269,6 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ 	int addr_type;
+ 	int err;
+ 
+-	if (!sock_flag(sk, SOCK_ZAPPED))
+-		return -EINVAL;
+ 	if (addr->l2tp_family != AF_INET6)
+ 		return -EINVAL;
+ 	if (addr_len < sizeof(*addr))
+@@ -296,6 +294,9 @@ static int l2tp_ip6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
+ 	lock_sock(sk);
+ 
+ 	err = -EINVAL;
++	if (!sock_flag(sk, SOCK_ZAPPED))
++		goto out_unlock;
++
+ 	if (sk->sk_state != TCP_CLOSE)
+ 		goto out_unlock;
+ 
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 62bea4591054..246f29d365c0 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -329,7 +329,6 @@ static void netlink_sock_destruct(struct sock *sk)
+ 	if (nlk->cb_running) {
+ 		if (nlk->cb.done)
+ 			nlk->cb.done(&nlk->cb);
+-
+ 		module_put(nlk->cb.module);
+ 		kfree_skb(nlk->cb.skb);
+ 	}
+@@ -346,6 +345,14 @@ static void netlink_sock_destruct(struct sock *sk)
+ 	WARN_ON(nlk_sk(sk)->groups);
+ }
+ 
++static void netlink_sock_destruct_work(struct work_struct *work)
++{
++	struct netlink_sock *nlk = container_of(work, struct netlink_sock,
++						work);
++
++	sk_free(&nlk->sk);
++}
++
+ /* This lock without WQ_FLAG_EXCLUSIVE is good on UP and it is _very_ bad on
+  * SMP. Look, when several writers sleep and reader wakes them up, all but one
+  * immediately hit write lock and grab all the cpus. Exclusive sleep solves
+@@ -648,8 +655,18 @@ out_module:
+ static void deferred_put_nlk_sk(struct rcu_head *head)
+ {
+ 	struct netlink_sock *nlk = container_of(head, struct netlink_sock, rcu);
++	struct sock *sk = &nlk->sk;
++
++	if (!atomic_dec_and_test(&sk->sk_refcnt))
++		return;
++
++	if (nlk->cb_running && nlk->cb.done) {
++		INIT_WORK(&nlk->work, netlink_sock_destruct_work);
++		schedule_work(&nlk->work);
++		return;
++	}
+ 
+-	sock_put(&nlk->sk);
++	sk_free(sk);
+ }
+ 
+ static int netlink_release(struct socket *sock)
+diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
+index 3cfd6cc60504..4fdb38318977 100644
+--- a/net/netlink/af_netlink.h
++++ b/net/netlink/af_netlink.h
+@@ -3,6 +3,7 @@
+ 
+ #include <linux/rhashtable.h>
+ #include <linux/atomic.h>
++#include <linux/workqueue.h>
+ #include <net/sock.h>
+ 
+ #define NLGRPSZ(x)	(ALIGN(x, sizeof(unsigned long) * 8) / 8)
+@@ -33,6 +34,7 @@ struct netlink_sock {
+ 
+ 	struct rhash_head	node;
+ 	struct rcu_head		rcu;
++	struct work_struct	work;
+ };
+ 
+ static inline struct netlink_sock *nlk_sk(struct sock *sk)
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index d2238b204691..dd2332390c45 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
+ 
+ 		if (optlen != sizeof(val))
+ 			return -EINVAL;
+-		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
+-			return -EBUSY;
+ 		if (copy_from_user(&val, optval, sizeof(val)))
+ 			return -EFAULT;
+ 		switch (val) {
+ 		case TPACKET_V1:
+ 		case TPACKET_V2:
+ 		case TPACKET_V3:
+-			po->tp_version = val;
+-			return 0;
++			break;
+ 		default:
+ 			return -EINVAL;
+ 		}
++		lock_sock(sk);
++		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
++			ret = -EBUSY;
++		} else {
++			po->tp_version = val;
++			ret = 0;
++		}
++		release_sock(sk);
++		return ret;
+ 	}
+ 	case PACKET_RESERVE:
+ 	{
+@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ 	/* Added to avoid minimal code churn */
+ 	struct tpacket_req *req = &req_u->req;
+ 
++	lock_sock(sk);
+ 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
+ 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
+ 		net_warn_ratelimited("Tx-ring is not supported.\n");
+@@ -4245,7 +4252,6 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ 			goto out;
+ 	}
+ 
+-	lock_sock(sk);
+ 
+ 	/* Detach socket from network */
+ 	spin_lock(&po->bind_lock);
+@@ -4294,11 +4300,11 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
+ 		if (!tx_ring)
+ 			prb_shutdown_retire_blk_timer(po, rb_queue);
+ 	}
+-	release_sock(sk);
+ 
+ 	if (pg_vec)
+ 		free_pg_vec(pg_vec, order, req->tp_block_nr);
+ out:
++	release_sock(sk);
+ 	return err;
+ }
+ 
+diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c
+index b54d56d4959b..cf9b2fe8eac6 100644
+--- a/net/sched/act_pedit.c
++++ b/net/sched/act_pedit.c
+@@ -108,6 +108,17 @@ static void tcf_pedit_cleanup(struct tc_action *a, int bind)
+ 	kfree(keys);
+ }
+ 
++static bool offset_valid(struct sk_buff *skb, int offset)
++{
++	if (offset > 0 && offset > skb->len)
++		return false;
++
++	if  (offset < 0 && -offset > skb_headroom(skb))
++		return false;
++
++	return true;
++}
++
+ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
+ 		     struct tcf_result *res)
+ {
+@@ -134,6 +145,11 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
+ 			if (tkey->offmask) {
+ 				char *d, _d;
+ 
++				if (!offset_valid(skb, off + tkey->at)) {
++					pr_info("tc filter pedit 'at' offset %d out of bounds\n",
++						off + tkey->at);
++					goto bad;
++				}
+ 				d = skb_header_pointer(skb, off + tkey->at, 1,
+ 						       &_d);
+ 				if (!d)
+@@ -146,10 +162,10 @@ static int tcf_pedit(struct sk_buff *skb, const struct tc_action *a,
+ 					" offset must be on 32 bit boundaries\n");
+ 				goto bad;
+ 			}
+-			if (offset > 0 && offset > skb->len) {
+-				pr_info("tc filter pedit"
+-					" offset %d can't exceed pkt length %d\n",
+-				       offset, skb->len);
++
++			if (!offset_valid(skb, off + offset)) {
++				pr_info("tc filter pedit offset %d out of bounds\n",
++					offset);
+ 				goto bad;
+ 			}
+ 
+diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
+index 0b8c3ace671f..1bf1f4517db6 100644
+--- a/net/sched/cls_basic.c
++++ b/net/sched/cls_basic.c
+@@ -62,9 +62,6 @@ static unsigned long basic_get(struct tcf_proto *tp, u32 handle)
+ 	struct basic_head *head = rtnl_dereference(tp->root);
+ 	struct basic_filter *f;
+ 
+-	if (head == NULL)
+-		return 0UL;
+-
+ 	list_for_each_entry(f, &head->flist, link) {
+ 		if (f->handle == handle) {
+ 			l = (unsigned long) f;
+@@ -109,7 +106,6 @@ static bool basic_destroy(struct tcf_proto *tp, bool force)
+ 		tcf_unbind_filter(tp, &f->res);
+ 		call_rcu(&f->rcu, basic_delete_filter);
+ 	}
+-	RCU_INIT_POINTER(tp->root, NULL);
+ 	kfree_rcu(head, rcu);
+ 	return true;
+ }
+diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
+index c3002c2c68bb..dbec45848fe1 100644
+--- a/net/sched/cls_bpf.c
++++ b/net/sched/cls_bpf.c
+@@ -200,7 +200,6 @@ static bool cls_bpf_destroy(struct tcf_proto *tp, bool force)
+ 		call_rcu(&prog->rcu, __cls_bpf_delete_prog);
+ 	}
+ 
+-	RCU_INIT_POINTER(tp->root, NULL);
+ 	kfree_rcu(head, rcu);
+ 	return true;
+ }
+@@ -211,9 +210,6 @@ static unsigned long cls_bpf_get(struct tcf_proto *tp, u32 handle)
+ 	struct cls_bpf_prog *prog;
+ 	unsigned long ret = 0UL;
+ 
+-	if (head == NULL)
+-		return 0UL;
+-
+ 	list_for_each_entry(prog, &head->plist, link) {
+ 		if (prog->handle == handle) {
+ 			ret = (unsigned long) prog;
+diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
+index 4c85bd3a750c..c104c2019feb 100644
+--- a/net/sched/cls_cgroup.c
++++ b/net/sched/cls_cgroup.c
+@@ -130,11 +130,10 @@ static bool cls_cgroup_destroy(struct tcf_proto *tp, bool force)
+ 
+ 	if (!force)
+ 		return false;
+-
+-	if (head) {
+-		RCU_INIT_POINTER(tp->root, NULL);
++	/* Head can still be NULL due to cls_cgroup_init(). */
++	if (head)
+ 		call_rcu(&head->rcu, cls_cgroup_destroy_rcu);
+-	}
++
+ 	return true;
+ }
+ 
+diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
+index fbfec6a18839..d7ba2b4ff0f3 100644
+--- a/net/sched/cls_flow.c
++++ b/net/sched/cls_flow.c
+@@ -583,7 +583,6 @@ static bool flow_destroy(struct tcf_proto *tp, bool force)
+ 		list_del_rcu(&f->list);
+ 		call_rcu(&f->rcu, flow_destroy_filter);
+ 	}
+-	RCU_INIT_POINTER(tp->root, NULL);
+ 	kfree_rcu(head, rcu);
+ 	return true;
+ }
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
+index 5060801a2f6d..a411571c4d4a 100644
+--- a/net/sched/cls_flower.c
++++ b/net/sched/cls_flower.c
+@@ -13,6 +13,7 @@
+ #include <linux/init.h>
+ #include <linux/module.h>
+ #include <linux/rhashtable.h>
++#include <linux/workqueue.h>
+ 
+ #include <linux/if_ether.h>
+ #include <linux/in6.h>
+@@ -55,7 +56,10 @@ struct cls_fl_head {
+ 	bool mask_assigned;
+ 	struct list_head filters;
+ 	struct rhashtable_params ht_params;
+-	struct rcu_head rcu;
++	union {
++		struct work_struct work;
++		struct rcu_head	rcu;
++	};
+ };
+ 
+ struct cls_fl_filter {
+@@ -239,6 +243,24 @@ static void fl_hw_update_stats(struct tcf_proto *tp, struct cls_fl_filter *f)
+ 	dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc);
+ }
+ 
++static void fl_destroy_sleepable(struct work_struct *work)
++{
++	struct cls_fl_head *head = container_of(work, struct cls_fl_head,
++						work);
++	if (head->mask_assigned)
++		rhashtable_destroy(&head->ht);
++	kfree(head);
++	module_put(THIS_MODULE);
++}
++
++static void fl_destroy_rcu(struct rcu_head *rcu)
++{
++	struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu);
++
++	INIT_WORK(&head->work, fl_destroy_sleepable);
++	schedule_work(&head->work);
++}
++
+ static bool fl_destroy(struct tcf_proto *tp, bool force)
+ {
+ 	struct cls_fl_head *head = rtnl_dereference(tp->root);
+@@ -252,10 +274,9 @@ static bool fl_destroy(struct tcf_proto *tp, bool force)
+ 		list_del_rcu(&f->list);
+ 		call_rcu(&f->rcu, fl_destroy_filter);
+ 	}
+-	RCU_INIT_POINTER(tp->root, NULL);
+-	if (head->mask_assigned)
+-		rhashtable_destroy(&head->ht);
+-	kfree_rcu(head, rcu);
++
++	__module_get(THIS_MODULE);
++	call_rcu(&head->rcu, fl_destroy_rcu);
+ 	return true;
+ }
+ 
+diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c
+index 25927b6c4436..f935429bd5ef 100644
+--- a/net/sched/cls_matchall.c
++++ b/net/sched/cls_matchall.c
+@@ -114,7 +114,6 @@ static bool mall_destroy(struct tcf_proto *tp, bool force)
+ 
+ 		call_rcu(&f->rcu, mall_destroy_filter);
+ 	}
+-	RCU_INIT_POINTER(tp->root, NULL);
+ 	kfree_rcu(head, rcu);
+ 	return true;
+ }
+diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
+index f9c9fc075fe6..9992dfac6938 100644
+--- a/net/sched/cls_rsvp.h
++++ b/net/sched/cls_rsvp.h
+@@ -152,7 +152,8 @@ static int rsvp_classify(struct sk_buff *skb, const struct tcf_proto *tp,
+ 		return -1;
+ 	nhptr = ip_hdr(skb);
+ #endif
+-
++	if (unlikely(!head))
++		return -1;
+ restart:
+ 
+ #if RSVP_DST_LEN == 4
+diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
+index 944c8ff45055..403746b20263 100644
+--- a/net/sched/cls_tcindex.c
++++ b/net/sched/cls_tcindex.c
+@@ -503,7 +503,6 @@ static bool tcindex_destroy(struct tcf_proto *tp, bool force)
+ 	walker.fn = tcindex_destroy_element;
+ 	tcindex_walk(tp, &walker);
+ 
+-	RCU_INIT_POINTER(tp->root, NULL);
+ 	call_rcu(&p->rcu, __tcindex_destroy);
+ 	return true;
+ }
+diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
+index 65b1bbf133bd..616769983bcd 100644
+--- a/net/tipc/bearer.c
++++ b/net/tipc/bearer.c
+@@ -402,6 +402,10 @@ int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b,
+ 	dev = dev_get_by_name(net, driver_name);
+ 	if (!dev)
+ 		return -ENODEV;
++	if (tipc_mtu_bad(dev, 0)) {
++		dev_put(dev);
++		return -EINVAL;
++	}
+ 
+ 	/* Associate TIPC bearer with L2 bearer */
+ 	rcu_assign_pointer(b->media_ptr, dev);
+@@ -606,8 +610,6 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
+ 	if (!b)
+ 		return NOTIFY_DONE;
+ 
+-	b->mtu = dev->mtu;
+-
+ 	switch (evt) {
+ 	case NETDEV_CHANGE:
+ 		if (netif_carrier_ok(dev))
+@@ -621,6 +623,11 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
+ 		tipc_reset_bearer(net, b);
+ 		break;
+ 	case NETDEV_CHANGEMTU:
++		if (tipc_mtu_bad(dev, 0)) {
++			bearer_disable(net, b);
++			break;
++		}
++		b->mtu = dev->mtu;
+ 		tipc_reset_bearer(net, b);
+ 		break;
+ 	case NETDEV_CHANGEADDR:
+diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
+index 43757f1f9cb3..d93f1f1a21e6 100644
+--- a/net/tipc/bearer.h
++++ b/net/tipc/bearer.h
+@@ -39,6 +39,7 @@
+ 
+ #include "netlink.h"
+ #include "core.h"
++#include "msg.h"
+ #include <net/genetlink.h>
+ 
+ #define MAX_MEDIA	3
+@@ -59,6 +60,9 @@
+ #define TIPC_MEDIA_TYPE_IB	2
+ #define TIPC_MEDIA_TYPE_UDP	3
+ 
++/* minimum bearer MTU */
++#define TIPC_MIN_BEARER_MTU	(MAX_H_SIZE + INT_H_SIZE)
++
+ /**
+  * struct tipc_media_addr - destination address used by TIPC bearers
+  * @value: address info (format defined by media)
+@@ -213,4 +217,13 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id,
+ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id,
+ 			 struct sk_buff_head *xmitq);
+ 
++/* check if device MTU is too low for tipc headers */
++static inline bool tipc_mtu_bad(struct net_device *dev, unsigned int reserve)
++{
++	if (dev->mtu >= TIPC_MIN_BEARER_MTU + reserve)
++		return false;
++	netdev_warn(dev, "MTU too low for tipc bearer\n");
++	return true;
++}
++
+ #endif	/* _TIPC_BEARER_H */
+diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c
+index ae7e14cae085..f60f346e75b3 100644
+--- a/net/tipc/udp_media.c
++++ b/net/tipc/udp_media.c
+@@ -372,6 +372,11 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
+ 		udp_conf.local_ip.s_addr = htonl(INADDR_ANY);
+ 		udp_conf.use_udp_checksums = false;
+ 		ub->ifindex = dev->ifindex;
++		if (tipc_mtu_bad(dev, sizeof(struct iphdr) +
++				      sizeof(struct udphdr))) {
++			err = -EINVAL;
++			goto err;
++		}
+ 		b->mtu = dev->mtu - sizeof(struct iphdr)
+ 			- sizeof(struct udphdr);
+ #if IS_ENABLED(CONFIG_IPV6)
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 8309687a56b0..568f307afdcf 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -2199,7 +2199,8 @@ out:
+  *	Sleep until more data has arrived. But check for races..
+  */
+ static long unix_stream_data_wait(struct sock *sk, long timeo,
+-				  struct sk_buff *last, unsigned int last_len)
++				  struct sk_buff *last, unsigned int last_len,
++				  bool freezable)
+ {
+ 	struct sk_buff *tail;
+ 	DEFINE_WAIT(wait);
+@@ -2220,7 +2221,10 @@ static long unix_stream_data_wait(struct sock *sk, long timeo,
+ 
+ 		sk_set_bit(SOCKWQ_ASYNC_WAITDATA, sk);
+ 		unix_state_unlock(sk);
+-		timeo = freezable_schedule_timeout(timeo);
++		if (freezable)
++			timeo = freezable_schedule_timeout(timeo);
++		else
++			timeo = schedule_timeout(timeo);
+ 		unix_state_lock(sk);
+ 
+ 		if (sock_flag(sk, SOCK_DEAD))
+@@ -2250,7 +2254,8 @@ struct unix_stream_read_state {
+ 	unsigned int splice_flags;
+ };
+ 
+-static int unix_stream_read_generic(struct unix_stream_read_state *state)
++static int unix_stream_read_generic(struct unix_stream_read_state *state,
++				    bool freezable)
+ {
+ 	struct scm_cookie scm;
+ 	struct socket *sock = state->socket;
+@@ -2330,7 +2335,7 @@ again:
+ 			mutex_unlock(&u->iolock);
+ 
+ 			timeo = unix_stream_data_wait(sk, timeo, last,
+-						      last_len);
++						      last_len, freezable);
+ 
+ 			if (signal_pending(current)) {
+ 				err = sock_intr_errno(timeo);
+@@ -2472,7 +2477,7 @@ static int unix_stream_recvmsg(struct socket *sock, struct msghdr *msg,
+ 		.flags = flags
+ 	};
+ 
+-	return unix_stream_read_generic(&state);
++	return unix_stream_read_generic(&state, true);
+ }
+ 
+ static ssize_t skb_unix_socket_splice(struct sock *sk,
+@@ -2518,7 +2523,7 @@ static ssize_t unix_stream_splice_read(struct socket *sock,  loff_t *ppos,
+ 	    flags & SPLICE_F_NONBLOCK)
+ 		state.flags = MSG_DONTWAIT;
+ 
+-	return unix_stream_read_generic(&state);
++	return unix_stream_read_generic(&state, false);
+ }
+ 
+ static int unix_shutdown(struct socket *sock, int mode)

diff --git a/1520_fix-race-condition-in-packet-set-ring.patch b/1520_fix-race-condition-in-packet-set-ring.patch
deleted file mode 100644
index d85527f..0000000
--- a/1520_fix-race-condition-in-packet-set-ring.patch
+++ /dev/null
@@ -1,62 +0,0 @@
---- a/net/packet/af_packet.c	2016-12-07 18:10:25.785812861 -0500
-+++ b/net/packet/af_packet.c	2016-12-07 18:18:45.597933525 -0500
-@@ -3648,19 +3648,25 @@ packet_setsockopt(struct socket *sock, i
- 
- 		if (optlen != sizeof(val))
- 			return -EINVAL;
--		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec)
--			return -EBUSY;
- 		if (copy_from_user(&val, optval, sizeof(val)))
- 			return -EFAULT;
- 		switch (val) {
- 		case TPACKET_V1:
- 		case TPACKET_V2:
- 		case TPACKET_V3:
--			po->tp_version = val;
--			return 0;
-+			break;
- 		default:
- 			return -EINVAL;
- 		}
-+		lock_sock(sk);
-+		if (po->rx_ring.pg_vec || po->tx_ring.pg_vec) {
-+			ret = -EBUSY;
-+		} else {
-+			po->tp_version = val;
-+			ret = 0;
-+		}
-+		release_sock(sk);
-+		return ret;
- 	}
- 	case PACKET_RESERVE:
- 	{
-@@ -4164,6 +4170,7 @@ static int packet_set_ring(struct sock *
- 	/* Added to avoid minimal code churn */
- 	struct tpacket_req *req = &req_u->req;
- 
-+	lock_sock(sk);
- 	/* Opening a Tx-ring is NOT supported in TPACKET_V3 */
- 	if (!closing && tx_ring && (po->tp_version > TPACKET_V2)) {
- 		net_warn_ratelimited("Tx-ring is not supported.\n");
-@@ -4245,8 +4252,6 @@ static int packet_set_ring(struct sock *
- 			goto out;
- 	}
- 
--	lock_sock(sk);
--
- 	/* Detach socket from network */
- 	spin_lock(&po->bind_lock);
- 	was_running = po->running;
-@@ -4294,11 +4299,11 @@ static int packet_set_ring(struct sock *
- 		if (!tx_ring)
- 			prb_shutdown_retire_blk_timer(po, rb_queue);
- 	}
--	release_sock(sk);
- 
- 	if (pg_vec)
- 		free_pg_vec(pg_vec, order, req->tp_block_nr);
- out:
-+	release_sock(sk);
- 	return err;
- }
- 


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2016-12-15 23:43 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2016-12-15 23:43 UTC (permalink / raw
  To: gentoo-commits

commit:     5ab163abb40b21be3023de3568846f00c39d729a
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Dec 15 23:43:07 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Dec 15 23:43:07 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5ab163ab

Linux patch 4.8.15

 0000_README             |    4 +
 1014_linux-4.8.15.patch | 1042 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1046 insertions(+)

diff --git a/0000_README b/0000_README
index 9b67d47..37d0ff1 100644
--- a/0000_README
+++ b/0000_README
@@ -99,6 +99,10 @@ Patch:  1013_linux-4.8.14.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.14
 
+Patch:  1014_linux-4.8.15.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.15
+
 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/1014_linux-4.8.15.patch b/1014_linux-4.8.15.patch
new file mode 100644
index 0000000..fb44713
--- /dev/null
+++ b/1014_linux-4.8.15.patch
@@ -0,0 +1,1042 @@
+diff --git a/Makefile b/Makefile
+index 6a7492473a0d..c7f0e798ca34 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 14
++SUBLEVEL = 15
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/boot/dts/imx7s.dtsi b/arch/arm/boot/dts/imx7s.dtsi
+index 1e90bdbe3a6e..fb307de5422c 100644
+--- a/arch/arm/boot/dts/imx7s.dtsi
++++ b/arch/arm/boot/dts/imx7s.dtsi
+@@ -640,9 +640,8 @@
+ 				reg = <0x30730000 0x10000>;
+ 				interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+ 				clocks = <&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>,
+-					<&clks IMX7D_CLK_DUMMY>,
+-					<&clks IMX7D_CLK_DUMMY>;
+-				clock-names = "pix", "axi", "disp_axi";
++					<&clks IMX7D_LCDIF_PIXEL_ROOT_CLK>;
++				clock-names = "pix", "axi";
+ 				status = "disabled";
+ 			};
+ 		};
+diff --git a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
+index 1cf644bfd7ea..51dc734cd5b9 100644
+--- a/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
++++ b/arch/arm/boot/dts/orion5x-linkstation-lsgl.dts
+@@ -82,6 +82,10 @@
+ 	gpios = <&gpio0 9 GPIO_ACTIVE_HIGH>;
+ };
+ 
++&sata {
++	nr-ports = <2>;
++};
++
+ &ehci1 {
+ 	status = "okay";
+ };
+diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h
+index d28fa8fe26fe..c598d847d56b 100644
+--- a/arch/m68k/include/asm/delay.h
++++ b/arch/m68k/include/asm/delay.h
+@@ -114,6 +114,6 @@ static inline void __udelay(unsigned long usecs)
+  */
+ #define	HZSCALE		(268435456 / (1000000 / HZ))
+ 
+-#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000));
++#define ndelay(n) __delay(DIV_ROUND_UP((n) * ((((HZSCALE) >> 11) * (loops_per_jiffy >> 11)) >> 6), 1000))
+ 
+ #endif /* defined(_M68K_DELAY_H) */
+diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
+index c2c43f714684..3a4ed9f91d57 100644
+--- a/arch/parisc/include/asm/pgtable.h
++++ b/arch/parisc/include/asm/pgtable.h
+@@ -65,9 +65,9 @@ static inline void purge_tlb_entries(struct mm_struct *mm, unsigned long addr)
+ 		unsigned long flags;				\
+ 		spin_lock_irqsave(&pa_tlb_lock, flags);		\
+ 		old_pte = *ptep;				\
+-		set_pte(ptep, pteval);				\
+ 		if (pte_inserted(old_pte))			\
+ 			purge_tlb_entries(mm, addr);		\
++		set_pte(ptep, pteval);				\
+ 		spin_unlock_irqrestore(&pa_tlb_lock, flags);	\
+ 	} while (0)
+ 
+@@ -478,8 +478,8 @@ static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned
+ 		spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ 		return 0;
+ 	}
+-	set_pte(ptep, pte_mkold(pte));
+ 	purge_tlb_entries(vma->vm_mm, addr);
++	set_pte(ptep, pte_mkold(pte));
+ 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ 	return 1;
+ }
+@@ -492,9 +492,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ 
+ 	spin_lock_irqsave(&pa_tlb_lock, flags);
+ 	old_pte = *ptep;
+-	set_pte(ptep, __pte(0));
+ 	if (pte_inserted(old_pte))
+ 		purge_tlb_entries(mm, addr);
++	set_pte(ptep, __pte(0));
+ 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ 
+ 	return old_pte;
+@@ -504,8 +504,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
+ {
+ 	unsigned long flags;
+ 	spin_lock_irqsave(&pa_tlb_lock, flags);
+-	set_pte(ptep, pte_wrprotect(*ptep));
+ 	purge_tlb_entries(mm, addr);
++	set_pte(ptep, pte_wrprotect(*ptep));
+ 	spin_unlock_irqrestore(&pa_tlb_lock, flags);
+ }
+ 
+diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
+index c2259d4a3c33..bbb314eb7027 100644
+--- a/arch/parisc/kernel/cache.c
++++ b/arch/parisc/kernel/cache.c
+@@ -393,6 +393,15 @@ void __init parisc_setup_cache_timing(void)
+ 
+ 	/* calculate TLB flush threshold */
+ 
++	/* On SMP machines, skip the TLB measure of kernel text which
++	 * has been mapped as huge pages. */
++	if (num_online_cpus() > 1 && !parisc_requires_coherency()) {
++		threshold = max(cache_info.it_size, cache_info.dt_size);
++		threshold *= PAGE_SIZE;
++		threshold /= num_online_cpus();
++		goto set_tlb_threshold;
++	}
++
+ 	alltime = mfctl(16);
+ 	flush_tlb_all();
+ 	alltime = mfctl(16) - alltime;
+@@ -411,6 +420,8 @@ void __init parisc_setup_cache_timing(void)
+ 		alltime, size, rangetime);
+ 
+ 	threshold = PAGE_ALIGN(num_online_cpus() * size * alltime / rangetime);
++
++set_tlb_threshold:
+ 	if (threshold)
+ 		parisc_tlb_flush_threshold = threshold;
+ 	printk(KERN_INFO "TLB flush threshold set to %lu KiB\n",
+diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
+index 675521919229..a4761b772406 100644
+--- a/arch/parisc/kernel/pacache.S
++++ b/arch/parisc/kernel/pacache.S
+@@ -886,19 +886,10 @@ ENTRY(flush_dcache_page_asm)
+ 	fdc,m		r31(%r28)
+ 	fdc,m		r31(%r28)
+ 	fdc,m		r31(%r28)
+-	cmpb,COND(<<)		%r28, %r25,1b
++	cmpb,COND(<<)	%r28, %r25,1b
+ 	fdc,m		r31(%r28)
+ 
+ 	sync
+-
+-#ifdef CONFIG_PA20
+-	pdtlb,l		%r0(%r25)
+-#else
+-	tlb_lock	%r20,%r21,%r22
+-	pdtlb		%r0(%r25)
+-	tlb_unlock	%r20,%r21,%r22
+-#endif
+-
+ 	bv		%r0(%r2)
+ 	nop
+ 	.exit
+@@ -973,17 +964,6 @@ ENTRY(flush_icache_page_asm)
+ 	fic,m		%r31(%sr4,%r28)
+ 
+ 	sync
+-
+-#ifdef CONFIG_PA20
+-	pdtlb,l		%r0(%r28)
+-	pitlb,l         %r0(%sr4,%r25)
+-#else
+-	tlb_lock        %r20,%r21,%r22
+-	pdtlb		%r0(%r28)
+-	pitlb           %r0(%sr4,%r25)
+-	tlb_unlock      %r20,%r21,%r22
+-#endif
+-
+ 	bv		%r0(%r2)
+ 	nop
+ 	.exit
+diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
+index 1a2a6e8dc40d..1894beb2c208 100644
+--- a/arch/powerpc/boot/Makefile
++++ b/arch/powerpc/boot/Makefile
+@@ -78,7 +78,8 @@ src-wlib-y := string.S crt0.S crtsavres.S stdio.c main.c \
+ 		ns16550.c serial.c simple_alloc.c div64.S util.S \
+ 		gunzip_util.c elf_util.c $(zlib) devtree.c stdlib.c \
+ 		oflib.c ofconsole.c cuboot.c mpsc.c cpm-serial.c \
+-		uartlite.c mpc52xx-psc.c opal.c opal-calls.S
++		uartlite.c mpc52xx-psc.c opal.c
++src-wlib-$(CONFIG_PPC64_BOOT_WRAPPER) +=  opal-calls.S
+ src-wlib-$(CONFIG_40x) += 4xx.c planetcore.c
+ src-wlib-$(CONFIG_44x) += 4xx.c ebony.c bamboo.c
+ src-wlib-$(CONFIG_8xx) += mpc8xx.c planetcore.c fsl-soc.c
+diff --git a/arch/powerpc/boot/opal.c b/arch/powerpc/boot/opal.c
+index d7b4fd47eb44..0272570d02de 100644
+--- a/arch/powerpc/boot/opal.c
++++ b/arch/powerpc/boot/opal.c
+@@ -13,7 +13,7 @@
+ #include <libfdt.h>
+ #include "../include/asm/opal-api.h"
+ 
+-#ifdef __powerpc64__
++#ifdef CONFIG_PPC64_BOOT_WRAPPER
+ 
+ /* Global OPAL struct used by opal-call.S */
+ struct opal {
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index 29aa8d1ce273..248f28bc4641 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -671,8 +671,10 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
+ 
+ 	/* Clear frozen state */
+ 	rc = eeh_clear_pe_frozen_state(pe, false);
+-	if (rc)
++	if (rc) {
++		pci_unlock_rescan_remove();
+ 		return rc;
++	}
+ 
+ 	/* Give the system 5 seconds to finish running the user-space
+ 	 * hotplug shutdown scripts, e.g. ifdown for ethernet.  Yes,
+diff --git a/arch/powerpc/mm/hash64_4k.c b/arch/powerpc/mm/hash64_4k.c
+index 42c702b3be1f..6fa450c12d6d 100644
+--- a/arch/powerpc/mm/hash64_4k.c
++++ b/arch/powerpc/mm/hash64_4k.c
+@@ -55,7 +55,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ 	 */
+ 	rflags = htab_convert_pte_flags(new_pte);
+ 
+-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
++	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ 		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+ 
+diff --git a/arch/powerpc/mm/hash64_64k.c b/arch/powerpc/mm/hash64_64k.c
+index 3bbbea07378c..1a68cb19b0e3 100644
+--- a/arch/powerpc/mm/hash64_64k.c
++++ b/arch/powerpc/mm/hash64_64k.c
+@@ -87,7 +87,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
+ 	subpg_pte = new_pte & ~subpg_prot;
+ 	rflags = htab_convert_pte_flags(subpg_pte);
+ 
+-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
++	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) {
+ 
+ 		/*
+@@ -258,7 +258,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
+ 
+ 	rflags = htab_convert_pte_flags(new_pte);
+ 
+-	if (!cpu_has_feature(CPU_FTR_NOEXECUTE) &&
++	if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
+ 	    !cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
+ 		rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap);
+ 
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index a4e070a51584..8c925ecaf534 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -68,7 +68,7 @@ u64 x86_perf_event_update(struct perf_event *event)
+ 	int shift = 64 - x86_pmu.cntval_bits;
+ 	u64 prev_raw_count, new_raw_count;
+ 	int idx = hwc->idx;
+-	s64 delta;
++	u64 delta;
+ 
+ 	if (idx == INTEL_PMC_IDX_FIXED_BTS)
+ 		return 0;
+diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
+index 4c9a79b9cd69..3ef34c6e63ca 100644
+--- a/arch/x86/events/intel/core.c
++++ b/arch/x86/events/intel/core.c
+@@ -4024,7 +4024,7 @@ __init int intel_pmu_init(void)
+ 
+ 	/* Support full width counters using alternative MSR range */
+ 	if (x86_pmu.intel_cap.full_width_write) {
+-		x86_pmu.max_period = x86_pmu.cntval_mask;
++		x86_pmu.max_period = x86_pmu.cntval_mask >> 1;
+ 		x86_pmu.perfctr = MSR_IA32_PMC0;
+ 		pr_cont("full-width counters, ");
+ 	}
+diff --git a/crypto/Makefile b/crypto/Makefile
+index 99cc64ac70ef..bd6a029094e6 100644
+--- a/crypto/Makefile
++++ b/crypto/Makefile
+@@ -40,6 +40,7 @@ obj-$(CONFIG_CRYPTO_ECDH) += ecdh_generic.o
+ 
+ $(obj)/rsapubkey-asn1.o: $(obj)/rsapubkey-asn1.c $(obj)/rsapubkey-asn1.h
+ $(obj)/rsaprivkey-asn1.o: $(obj)/rsaprivkey-asn1.c $(obj)/rsaprivkey-asn1.h
++$(obj)/rsa_helper.o: $(obj)/rsapubkey-asn1.h $(obj)/rsaprivkey-asn1.h
+ clean-files += rsapubkey-asn1.c rsapubkey-asn1.h
+ clean-files += rsaprivkey-asn1.c rsaprivkey-asn1.h
+ 
+diff --git a/crypto/mcryptd.c b/crypto/mcryptd.c
+index 86fb59b109a9..c6e992082259 100644
+--- a/crypto/mcryptd.c
++++ b/crypto/mcryptd.c
+@@ -254,18 +254,22 @@ out_free_inst:
+ 	goto out;
+ }
+ 
+-static inline void mcryptd_check_internal(struct rtattr **tb, u32 *type,
++static inline bool mcryptd_check_internal(struct rtattr **tb, u32 *type,
+ 					  u32 *mask)
+ {
+ 	struct crypto_attr_type *algt;
+ 
+ 	algt = crypto_get_attr_type(tb);
+ 	if (IS_ERR(algt))
+-		return;
+-	if ((algt->type & CRYPTO_ALG_INTERNAL))
+-		*type |= CRYPTO_ALG_INTERNAL;
+-	if ((algt->mask & CRYPTO_ALG_INTERNAL))
+-		*mask |= CRYPTO_ALG_INTERNAL;
++		return false;
++
++	*type |= algt->type & CRYPTO_ALG_INTERNAL;
++	*mask |= algt->mask & CRYPTO_ALG_INTERNAL;
++
++	if (*type & *mask & CRYPTO_ALG_INTERNAL)
++		return true;
++	else
++		return false;
+ }
+ 
+ static int mcryptd_hash_init_tfm(struct crypto_tfm *tfm)
+@@ -492,7 +496,8 @@ static int mcryptd_create_hash(struct crypto_template *tmpl, struct rtattr **tb,
+ 	u32 mask = 0;
+ 	int err;
+ 
+-	mcryptd_check_internal(tb, &type, &mask);
++	if (!mcryptd_check_internal(tb, &type, &mask))
++		return -EINVAL;
+ 
+ 	halg = ahash_attr_alg(tb[1], type, mask);
+ 	if (IS_ERR(halg))
+diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
+index 2accf784534e..93e0d8333a20 100644
+--- a/drivers/acpi/nfit/core.c
++++ b/drivers/acpi/nfit/core.c
+@@ -94,7 +94,7 @@ static struct acpi_device *to_acpi_dev(struct acpi_nfit_desc *acpi_desc)
+ 	return to_acpi_device(acpi_desc->dev);
+ }
+ 
+-static int xlat_status(void *buf, unsigned int cmd, u32 status)
++static int xlat_bus_status(void *buf, unsigned int cmd, u32 status)
+ {
+ 	struct nd_cmd_clear_error *clear_err;
+ 	struct nd_cmd_ars_status *ars_status;
+@@ -113,7 +113,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 		flags = ND_ARS_PERSISTENT | ND_ARS_VOLATILE;
+ 		if ((status >> 16 & flags) == 0)
+ 			return -ENOTTY;
+-		break;
++		return 0;
+ 	case ND_CMD_ARS_START:
+ 		/* ARS is in progress */
+ 		if ((status & 0xffff) == NFIT_ARS_START_BUSY)
+@@ -122,7 +122,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 		/* Command failed */
+ 		if (status & 0xffff)
+ 			return -EIO;
+-		break;
++		return 0;
+ 	case ND_CMD_ARS_STATUS:
+ 		ars_status = buf;
+ 		/* Command failed */
+@@ -146,7 +146,8 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 		 * then just continue with the returned results.
+ 		 */
+ 		if (status == NFIT_ARS_STATUS_INTR) {
+-			if (ars_status->flags & NFIT_ARS_F_OVERFLOW)
++			if (ars_status->out_length >= 40 && (ars_status->flags
++						& NFIT_ARS_F_OVERFLOW))
+ 				return -ENOSPC;
+ 			return 0;
+ 		}
+@@ -154,7 +155,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 		/* Unknown status */
+ 		if (status >> 16)
+ 			return -EIO;
+-		break;
++		return 0;
+ 	case ND_CMD_CLEAR_ERROR:
+ 		clear_err = buf;
+ 		if (status & 0xffff)
+@@ -163,7 +164,7 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 			return -EIO;
+ 		if (clear_err->length > clear_err->cleared)
+ 			return clear_err->cleared;
+-		break;
++		return 0;
+ 	default:
+ 		break;
+ 	}
+@@ -174,6 +175,16 @@ static int xlat_status(void *buf, unsigned int cmd, u32 status)
+ 	return 0;
+ }
+ 
++static int xlat_status(struct nvdimm *nvdimm, void *buf, unsigned int cmd,
++		u32 status)
++{
++	if (!nvdimm)
++		return xlat_bus_status(buf, cmd, status);
++	if (status)
++		return -EIO;
++	return 0;
++}
++
+ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
+ 		struct nvdimm *nvdimm, unsigned int cmd, void *buf,
+ 		unsigned int buf_len, int *cmd_rc)
+@@ -298,7 +309,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
+ 
+ 	for (i = 0, offset = 0; i < desc->out_num; i++) {
+ 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i, buf,
+-				(u32 *) out_obj->buffer.pointer);
++				(u32 *) out_obj->buffer.pointer,
++				out_obj->buffer.length - offset);
+ 
+ 		if (offset + out_size > out_obj->buffer.length) {
+ 			dev_dbg(dev, "%s:%s output object underflow cmd: %s field: %d\n",
+@@ -333,7 +345,8 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
+ 			 */
+ 			rc = buf_len - offset - in_buf.buffer.length;
+ 			if (cmd_rc)
+-				*cmd_rc = xlat_status(buf, cmd, fw_status);
++				*cmd_rc = xlat_status(nvdimm, buf, cmd,
++						fw_status);
+ 		} else {
+ 			dev_err(dev, "%s:%s underrun cmd: %s buf_len: %d out_len: %d\n",
+ 					__func__, dimm_name, cmd_name, buf_len,
+@@ -343,7 +356,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
+ 	} else {
+ 		rc = 0;
+ 		if (cmd_rc)
+-			*cmd_rc = xlat_status(buf, cmd, fw_status);
++			*cmd_rc = xlat_status(nvdimm, buf, cmd, fw_status);
+ 	}
+ 
+  out:
+@@ -1857,19 +1870,32 @@ static int ars_get_status(struct acpi_nfit_desc *acpi_desc)
+ 	return cmd_rc;
+ }
+ 
+-static int ars_status_process_records(struct nvdimm_bus *nvdimm_bus,
++static int ars_status_process_records(struct acpi_nfit_desc *acpi_desc,
+ 		struct nd_cmd_ars_status *ars_status)
+ {
++	struct nvdimm_bus *nvdimm_bus = acpi_desc->nvdimm_bus;
+ 	int rc;
+ 	u32 i;
+ 
++	/*
++	 * First record starts at 44 byte offset from the start of the
++	 * payload.
++	 */
++	if (ars_status->out_length < 44)
++		return 0;
+ 	for (i = 0; i < ars_status->num_records; i++) {
++		/* only process full records */
++		if (ars_status->out_length
++				< 44 + sizeof(struct nd_ars_record) * (i + 1))
++			break;
+ 		rc = nvdimm_bus_add_poison(nvdimm_bus,
+ 				ars_status->records[i].err_address,
+ 				ars_status->records[i].length);
+ 		if (rc)
+ 			return rc;
+ 	}
++	if (i < ars_status->num_records)
++		dev_warn(acpi_desc->dev, "detected truncated ars results\n");
+ 
+ 	return 0;
+ }
+@@ -2122,8 +2148,7 @@ static int acpi_nfit_query_poison(struct acpi_nfit_desc *acpi_desc,
+ 	if (rc < 0 && rc != -ENOSPC)
+ 		return rc;
+ 
+-	if (ars_status_process_records(acpi_desc->nvdimm_bus,
+-				acpi_desc->ars_status))
++	if (ars_status_process_records(acpi_desc, acpi_desc->ars_status))
+ 		return -ENOMEM;
+ 
+ 	return 0;
+diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c
+index 2b38c1bb0446..7a2e4d45b266 100644
+--- a/drivers/acpi/sleep.c
++++ b/drivers/acpi/sleep.c
+@@ -47,32 +47,15 @@ static void acpi_sleep_tts_switch(u32 acpi_state)
+ 	}
+ }
+ 
+-static void acpi_sleep_pts_switch(u32 acpi_state)
+-{
+-	acpi_status status;
+-
+-	status = acpi_execute_simple_method(NULL, "\\_PTS", acpi_state);
+-	if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
+-		/*
+-		 * OS can't evaluate the _PTS object correctly. Some warning
+-		 * message will be printed. But it won't break anything.
+-		 */
+-		printk(KERN_NOTICE "Failure in evaluating _PTS object\n");
+-	}
+-}
+-
+-static int sleep_notify_reboot(struct notifier_block *this,
++static int tts_notify_reboot(struct notifier_block *this,
+ 			unsigned long code, void *x)
+ {
+ 	acpi_sleep_tts_switch(ACPI_STATE_S5);
+-
+-	acpi_sleep_pts_switch(ACPI_STATE_S5);
+-
+ 	return NOTIFY_DONE;
+ }
+ 
+-static struct notifier_block sleep_notifier = {
+-	.notifier_call	= sleep_notify_reboot,
++static struct notifier_block tts_notifier = {
++	.notifier_call	= tts_notify_reboot,
+ 	.next		= NULL,
+ 	.priority	= 0,
+ };
+@@ -916,9 +899,9 @@ int __init acpi_sleep_init(void)
+ 	pr_info(PREFIX "(supports%s)\n", supported);
+ 
+ 	/*
+-	 * Register the sleep_notifier to reboot notifier list so that the _TTS
+-	 * and _PTS object can also be evaluated when the system enters S5.
++	 * Register the tts_notifier to reboot notifier list so that the _TTS
++	 * object can also be evaluated when the system enters S5.
+ 	 */
+-	register_reboot_notifier(&sleep_notifier);
++	register_reboot_notifier(&tts_notifier);
+ 	return 0;
+ }
+diff --git a/drivers/block/zram/zram_drv.c b/drivers/block/zram/zram_drv.c
+index 5163c8f918cb..5497f7fc44d0 100644
+--- a/drivers/block/zram/zram_drv.c
++++ b/drivers/block/zram/zram_drv.c
+@@ -1413,8 +1413,14 @@ static ssize_t hot_remove_store(struct class *class,
+ 	return ret ? ret : count;
+ }
+ 
++/*
++ * NOTE: hot_add attribute is not the usual read-only sysfs attribute. In a
++ * sense that reading from this file does alter the state of your system -- it
++ * creates a new un-initialized zram device and returns back this device's
++ * device_id (or an error code if it fails to create a new device).
++ */
+ static struct class_attribute zram_control_class_attrs[] = {
+-	__ATTR_RO(hot_add),
++	__ATTR(hot_add, 0400, hot_add_show, NULL),
+ 	__ATTR_WO(hot_remove),
+ 	__ATTR_NULL,
+ };
+diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
+index 0ec112ee5204..2341f3799591 100644
+--- a/drivers/crypto/caam/ctrl.c
++++ b/drivers/crypto/caam/ctrl.c
+@@ -557,8 +557,9 @@ static int caam_probe(struct platform_device *pdev)
+ 	 * Enable DECO watchdogs and, if this is a PHYS_ADDR_T_64BIT kernel,
+ 	 * long pointers in master configuration register
+ 	 */
+-	clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK, MCFGR_AWCACHE_CACH |
+-		      MCFGR_AWCACHE_BUFF | MCFGR_WDENABLE | MCFGR_LARGE_BURST |
++	clrsetbits_32(&ctrl->mcr, MCFGR_AWCACHE_MASK | MCFGR_LONG_PTR,
++		      MCFGR_AWCACHE_CACH | MCFGR_AWCACHE_BUFF |
++		      MCFGR_WDENABLE | MCFGR_LARGE_BURST |
+ 		      (sizeof(dma_addr_t) == sizeof(u64) ? MCFGR_LONG_PTR : 0));
+ 
+ 	/*
+diff --git a/drivers/crypto/marvell/hash.c b/drivers/crypto/marvell/hash.c
+index b111e14bac1e..13e89afdbb87 100644
+--- a/drivers/crypto/marvell/hash.c
++++ b/drivers/crypto/marvell/hash.c
+@@ -168,12 +168,11 @@ static void mv_cesa_ahash_std_step(struct ahash_request *req)
+ 	mv_cesa_adjust_op(engine, &creq->op_tmpl);
+ 	memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
+ 
+-	digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
+-	for (i = 0; i < digsize / 4; i++)
+-		writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
+-
+-	mv_cesa_adjust_op(engine, &creq->op_tmpl);
+-	memcpy_toio(engine->sram, &creq->op_tmpl, sizeof(creq->op_tmpl));
++	if (!sreq->offset) {
++		digsize = crypto_ahash_digestsize(crypto_ahash_reqtfm(req));
++		for (i = 0; i < digsize / 4; i++)
++			writel_relaxed(creq->state[i], engine->regs + CESA_IVDIG(i));
++	}
+ 
+ 	if (creq->cache_ptr)
+ 		memcpy_toio(engine->sram + CESA_SA_DATA_SRAM_OFFSET,
+diff --git a/drivers/dax/dax.c b/drivers/dax/dax.c
+index ff64313770bd..4894199cebab 100644
+--- a/drivers/dax/dax.c
++++ b/drivers/dax/dax.c
+@@ -324,7 +324,7 @@ static int check_vma(struct dax_dev *dax_dev, struct vm_area_struct *vma,
+ 		return -ENXIO;
+ 
+ 	/* prevent private mappings from being established */
+-	if ((vma->vm_flags & VM_SHARED) != VM_SHARED) {
++	if ((vma->vm_flags & VM_MAYSHARE) != VM_MAYSHARE) {
+ 		dev_info(dev, "%s: %s: fail, attempted private mapping\n",
+ 				current->comm, func);
+ 		return -EINVAL;
+diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+index bfb91d8fa460..1006af40481d 100644
+--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
++++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+@@ -872,23 +872,25 @@ lbl_free_candev:
+ static void peak_usb_disconnect(struct usb_interface *intf)
+ {
+ 	struct peak_usb_device *dev;
++	struct peak_usb_device *dev_prev_siblings;
+ 
+ 	/* unregister as many netdev devices as siblings */
+-	for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) {
++	for (dev = usb_get_intfdata(intf); dev; dev = dev_prev_siblings) {
+ 		struct net_device *netdev = dev->netdev;
+ 		char name[IFNAMSIZ];
+ 
++		dev_prev_siblings = dev->prev_siblings;
+ 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
+ 		strncpy(name, netdev->name, IFNAMSIZ);
+ 
+ 		unregister_netdev(netdev);
+-		free_candev(netdev);
+ 
+ 		kfree(dev->cmd_buf);
+ 		dev->next_siblings = NULL;
+ 		if (dev->adapter->dev_free)
+ 			dev->adapter->dev_free(dev);
+ 
++		free_candev(netdev);
+ 		dev_info(&intf->dev, "%s removed\n", name);
+ 	}
+ 
+diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
+index a8b6949a8778..23d4a1728cdf 100644
+--- a/drivers/nvdimm/bus.c
++++ b/drivers/nvdimm/bus.c
+@@ -715,7 +715,7 @@ EXPORT_SYMBOL_GPL(nd_cmd_in_size);
+ 
+ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
+ 		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
+-		const u32 *out_field)
++		const u32 *out_field, unsigned long remainder)
+ {
+ 	if (idx >= desc->out_num)
+ 		return UINT_MAX;
+@@ -727,9 +727,24 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
+ 		return in_field[1];
+ 	else if (nvdimm && cmd == ND_CMD_VENDOR && idx == 2)
+ 		return out_field[1];
+-	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2)
+-		return out_field[1] - 8;
+-	else if (cmd == ND_CMD_CALL) {
++	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2) {
++		/*
++		 * Per table 9-276 ARS Data in ACPI 6.1, out_field[1] is
++		 * "Size of Output Buffer in bytes, including this
++		 * field."
++		 */
++		if (out_field[1] < 4)
++			return 0;
++		/*
++		 * ACPI 6.1 is ambiguous if 'status' is included in the
++		 * output size. If we encounter an output size that
++		 * overshoots the remainder by 4 bytes, assume it was
++		 * including 'status'.
++		 */
++		if (out_field[1] - 8 == remainder)
++			return remainder;
++		return out_field[1] - 4;
++	} else if (cmd == ND_CMD_CALL) {
+ 		struct nd_cmd_pkg *pkg = (struct nd_cmd_pkg *) in_field;
+ 
+ 		return pkg->nd_size_out;
+@@ -876,7 +891,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
+ 	/* process an output envelope */
+ 	for (i = 0; i < desc->out_num; i++) {
+ 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
+-				(u32 *) in_env, (u32 *) out_env);
++				(u32 *) in_env, (u32 *) out_env, 0);
+ 		u32 copy;
+ 
+ 		if (out_size == UINT_MAX) {
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c
+index 7080ce2920fd..8214ebae9d50 100644
+--- a/drivers/scsi/lpfc/lpfc_sli.c
++++ b/drivers/scsi/lpfc/lpfc_sli.c
+@@ -1323,18 +1323,20 @@ lpfc_sli_ringtxcmpl_put(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
+ {
+ 	lockdep_assert_held(&phba->hbalock);
+ 
+-	BUG_ON(!piocb || !piocb->vport);
++	BUG_ON(!piocb);
+ 
+ 	list_add_tail(&piocb->list, &pring->txcmplq);
+ 	piocb->iocb_flag |= LPFC_IO_ON_TXCMPLQ;
+ 
+ 	if ((unlikely(pring->ringno == LPFC_ELS_RING)) &&
+ 	   (piocb->iocb.ulpCommand != CMD_ABORT_XRI_CN) &&
+-	   (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN) &&
+-	    (!(piocb->vport->load_flag & FC_UNLOADING)))
+-		mod_timer(&piocb->vport->els_tmofunc,
+-			  jiffies +
+-			  msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
++	   (piocb->iocb.ulpCommand != CMD_CLOSE_XRI_CN)) {
++		BUG_ON(!piocb->vport);
++		if (!(piocb->vport->load_flag & FC_UNLOADING))
++			mod_timer(&piocb->vport->els_tmofunc,
++				  jiffies +
++				  msecs_to_jiffies(1000 * (phba->fc_ratov << 1)));
++	}
+ 
+ 	return 0;
+ }
+diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
+index e3b30ea9ece5..a504e2e003da 100644
+--- a/drivers/vhost/vsock.c
++++ b/drivers/vhost/vsock.c
+@@ -506,7 +506,7 @@ static void vhost_vsock_reset_orphans(struct sock *sk)
+ 	 * executing.
+ 	 */
+ 
+-	if (!vhost_vsock_get(vsk->local_addr.svm_cid)) {
++	if (!vhost_vsock_get(vsk->remote_addr.svm_cid)) {
+ 		sock_set_flag(sk, SOCK_DONE);
+ 		vsk->peer_shutdown = SHUTDOWN_MASK;
+ 		sk->sk_state = SS_UNCONNECTED;
+diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
+index df4b3e6fa563..93142bfe6112 100644
+--- a/fs/ceph/dir.c
++++ b/fs/ceph/dir.c
+@@ -1257,26 +1257,30 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
+ 			return -ECHILD;
+ 
+ 		op = ceph_snap(dir) == CEPH_SNAPDIR ?
+-			CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_LOOKUP;
++			CEPH_MDS_OP_LOOKUPSNAP : CEPH_MDS_OP_GETATTR;
+ 		req = ceph_mdsc_create_request(mdsc, op, USE_ANY_MDS);
+ 		if (!IS_ERR(req)) {
+ 			req->r_dentry = dget(dentry);
+-			req->r_num_caps = 2;
++			req->r_num_caps = op == CEPH_MDS_OP_GETATTR ? 1 : 2;
+ 
+ 			mask = CEPH_STAT_CAP_INODE | CEPH_CAP_AUTH_SHARED;
+ 			if (ceph_security_xattr_wanted(dir))
+ 				mask |= CEPH_CAP_XATTR_SHARED;
+ 			req->r_args.getattr.mask = mask;
+ 
+-			req->r_locked_dir = dir;
+ 			err = ceph_mdsc_do_request(mdsc, NULL, req);
+-			if (err == 0 || err == -ENOENT) {
+-				if (dentry == req->r_dentry) {
+-					valid = !d_unhashed(dentry);
+-				} else {
+-					d_invalidate(req->r_dentry);
+-					err = -EAGAIN;
+-				}
++			switch (err) {
++			case 0:
++				if (d_really_is_positive(dentry) &&
++				    d_inode(dentry) == req->r_target_inode)
++					valid = 1;
++				break;
++			case -ENOENT:
++				if (d_really_is_negative(dentry))
++					valid = 1;
++				/* Fallthrough */
++			default:
++				break;
+ 			}
+ 			ceph_mdsc_put_request(req);
+ 			dout("d_revalidate %p lookup result=%d\n",
+diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
+index 4ff9251e9d3a..eb5373a026e3 100644
+--- a/fs/fuse/dir.c
++++ b/fs/fuse/dir.c
+@@ -1709,8 +1709,6 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+ 		return -EACCES;
+ 
+ 	if (attr->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID)) {
+-		int kill;
+-
+ 		attr->ia_valid &= ~(ATTR_KILL_SUID | ATTR_KILL_SGID |
+ 				    ATTR_MODE);
+ 		/*
+@@ -1722,12 +1720,11 @@ static int fuse_setattr(struct dentry *entry, struct iattr *attr)
+ 			return ret;
+ 
+ 		attr->ia_mode = inode->i_mode;
+-		kill = should_remove_suid(entry);
+-		if (kill & ATTR_KILL_SUID) {
++		if (inode->i_mode & S_ISUID) {
+ 			attr->ia_valid |= ATTR_MODE;
+ 			attr->ia_mode &= ~S_ISUID;
+ 		}
+-		if (kill & ATTR_KILL_SGID) {
++		if ((inode->i_mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
+ 			attr->ia_valid |= ATTR_MODE;
+ 			attr->ia_mode &= ~S_ISGID;
+ 		}
+diff --git a/include/linux/cpu.h b/include/linux/cpu.h
+index 797d9c8e9a1b..c8938eb21e34 100644
+--- a/include/linux/cpu.h
++++ b/include/linux/cpu.h
+@@ -105,22 +105,16 @@ extern bool cpuhp_tasks_frozen;
+ 		{ .notifier_call = fn, .priority = pri };	\
+ 	__register_cpu_notifier(&fn##_nb);			\
+ }
+-#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
+-#define cpu_notifier(fn, pri)	do { (void)(fn); } while (0)
+-#define __cpu_notifier(fn, pri)	do { (void)(fn); } while (0)
+-#endif /* #else #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
+ 
+-#ifdef CONFIG_HOTPLUG_CPU
+ extern int register_cpu_notifier(struct notifier_block *nb);
+ extern int __register_cpu_notifier(struct notifier_block *nb);
+ extern void unregister_cpu_notifier(struct notifier_block *nb);
+ extern void __unregister_cpu_notifier(struct notifier_block *nb);
+-#else
+ 
+-#ifndef MODULE
+-extern int register_cpu_notifier(struct notifier_block *nb);
+-extern int __register_cpu_notifier(struct notifier_block *nb);
+-#else
++#else /* #if defined(CONFIG_HOTPLUG_CPU) || !defined(MODULE) */
++#define cpu_notifier(fn, pri)	do { (void)(fn); } while (0)
++#define __cpu_notifier(fn, pri)	do { (void)(fn); } while (0)
++
+ static inline int register_cpu_notifier(struct notifier_block *nb)
+ {
+ 	return 0;
+@@ -130,7 +124,6 @@ static inline int __register_cpu_notifier(struct notifier_block *nb)
+ {
+ 	return 0;
+ }
+-#endif
+ 
+ static inline void unregister_cpu_notifier(struct notifier_block *nb)
+ {
+diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
+index bbfce62a0bd7..d02d65dfe2d0 100644
+--- a/include/linux/libnvdimm.h
++++ b/include/linux/libnvdimm.h
+@@ -153,7 +153,7 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
+ 		const struct nd_cmd_desc *desc, int idx, void *buf);
+ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
+ 		const struct nd_cmd_desc *desc, int idx, const u32 *in_field,
+-		const u32 *out_field);
++		const u32 *out_field, unsigned long remainder);
+ int nvdimm_bus_check_dimm_count(struct nvdimm_bus *nvdimm_bus, int dimm_count);
+ struct nd_region *nvdimm_pmem_region_create(struct nvdimm_bus *nvdimm_bus,
+ 		struct nd_region_desc *ndr_desc);
+diff --git a/include/uapi/linux/can.h b/include/uapi/linux/can.h
+index 9692cda5f8fc..c48d93a28d1a 100644
+--- a/include/uapi/linux/can.h
++++ b/include/uapi/linux/can.h
+@@ -196,5 +196,6 @@ struct can_filter {
+ };
+ 
+ #define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
++#define CAN_RAW_FILTER_MAX 512 /* maximum number of can_filter set via setsockopt() */
+ 
+ #endif /* !_UAPI_CAN_H */
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 341bf80f80bd..73fb59fda809 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -578,7 +578,6 @@ void __init cpuhp_threads_init(void)
+ 	kthread_unpark(this_cpu_read(cpuhp_state.thread));
+ }
+ 
+-#ifdef CONFIG_HOTPLUG_CPU
+ EXPORT_SYMBOL(register_cpu_notifier);
+ EXPORT_SYMBOL(__register_cpu_notifier);
+ void unregister_cpu_notifier(struct notifier_block *nb)
+@@ -595,6 +594,7 @@ void __unregister_cpu_notifier(struct notifier_block *nb)
+ }
+ EXPORT_SYMBOL(__unregister_cpu_notifier);
+ 
++#ifdef CONFIG_HOTPLUG_CPU
+ /**
+  * clear_tasks_mm_cpumask - Safely clear tasks' mm_cpumask for a CPU
+  * @cpu: a CPU id
+diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c
+index 1ec0f48962b3..2c49d76f96c3 100644
+--- a/kernel/locking/rtmutex.c
++++ b/kernel/locking/rtmutex.c
+@@ -65,8 +65,72 @@ static inline void clear_rt_mutex_waiters(struct rt_mutex *lock)
+ 
+ static void fixup_rt_mutex_waiters(struct rt_mutex *lock)
+ {
+-	if (!rt_mutex_has_waiters(lock))
+-		clear_rt_mutex_waiters(lock);
++	unsigned long owner, *p = (unsigned long *) &lock->owner;
++
++	if (rt_mutex_has_waiters(lock))
++		return;
++
++	/*
++	 * The rbtree has no waiters enqueued, now make sure that the
++	 * lock->owner still has the waiters bit set, otherwise the
++	 * following can happen:
++	 *
++	 * CPU 0	CPU 1		CPU2
++	 * l->owner=T1
++	 *		rt_mutex_lock(l)
++	 *		lock(l->lock)
++	 *		l->owner = T1 | HAS_WAITERS;
++	 *		enqueue(T2)
++	 *		boost()
++	 *		  unlock(l->lock)
++	 *		block()
++	 *
++	 *				rt_mutex_lock(l)
++	 *				lock(l->lock)
++	 *				l->owner = T1 | HAS_WAITERS;
++	 *				enqueue(T3)
++	 *				boost()
++	 *				  unlock(l->lock)
++	 *				block()
++	 *		signal(->T2)	signal(->T3)
++	 *		lock(l->lock)
++	 *		dequeue(T2)
++	 *		deboost()
++	 *		  unlock(l->lock)
++	 *				lock(l->lock)
++	 *				dequeue(T3)
++	 *				 ==> wait list is empty
++	 *				deboost()
++	 *				 unlock(l->lock)
++	 *		lock(l->lock)
++	 *		fixup_rt_mutex_waiters()
++	 *		  if (wait_list_empty(l) {
++	 *		    l->owner = owner
++	 *		    owner = l->owner & ~HAS_WAITERS;
++	 *		      ==> l->owner = T1
++	 *		  }
++	 *				lock(l->lock)
++	 * rt_mutex_unlock(l)		fixup_rt_mutex_waiters()
++	 *				  if (wait_list_empty(l) {
++	 *				    owner = l->owner & ~HAS_WAITERS;
++	 * cmpxchg(l->owner, T1, NULL)
++	 *  ===> Success (l->owner = NULL)
++	 *
++	 *				    l->owner = owner
++	 *				      ==> l->owner = T1
++	 *				  }
++	 *
++	 * With the check for the waiter bit in place T3 on CPU2 will not
++	 * overwrite. All tasks fiddling with the waiters bit are
++	 * serialized by l->lock, so nothing else can modify the waiters
++	 * bit. If the bit is set then nothing can change l->owner either
++	 * so the simple RMW is safe. The cmpxchg() will simply fail if it
++	 * happens in the middle of the RMW because the waiters bit is
++	 * still set.
++	 */
++	owner = READ_ONCE(*p);
++	if (owner & RT_MUTEX_HAS_WAITERS)
++		WRITE_ONCE(*p, owner & ~RT_MUTEX_HAS_WAITERS);
+ }
+ 
+ /*
+diff --git a/kernel/locking/rtmutex_common.h b/kernel/locking/rtmutex_common.h
+index 4f5f83c7d2d3..e317e1cbb3eb 100644
+--- a/kernel/locking/rtmutex_common.h
++++ b/kernel/locking/rtmutex_common.h
+@@ -75,8 +75,9 @@ task_top_pi_waiter(struct task_struct *p)
+ 
+ static inline struct task_struct *rt_mutex_owner(struct rt_mutex *lock)
+ {
+-	return (struct task_struct *)
+-		((unsigned long)lock->owner & ~RT_MUTEX_OWNER_MASKALL);
++	unsigned long owner = (unsigned long) READ_ONCE(lock->owner);
++
++	return (struct task_struct *) (owner & ~RT_MUTEX_OWNER_MASKALL);
+ }
+ 
+ /*
+diff --git a/kernel/sched/auto_group.c b/kernel/sched/auto_group.c
+index a5d966cb8891..418d9b6276a3 100644
+--- a/kernel/sched/auto_group.c
++++ b/kernel/sched/auto_group.c
+@@ -192,6 +192,7 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
+ {
+ 	static unsigned long next = INITIAL_JIFFIES;
+ 	struct autogroup *ag;
++	unsigned long shares;
+ 	int err;
+ 
+ 	if (nice < MIN_NICE || nice > MAX_NICE)
+@@ -210,9 +211,10 @@ int proc_sched_autogroup_set_nice(struct task_struct *p, int nice)
+ 
+ 	next = HZ / 10 + jiffies;
+ 	ag = autogroup_task_get(p);
++	shares = scale_load(sched_prio_to_weight[nice + 20]);
+ 
+ 	down_write(&ag->lock);
+-	err = sched_group_set_shares(ag->tg, sched_prio_to_weight[nice + 20]);
++	err = sched_group_set_shares(ag->tg, shares);
+ 	if (!err)
+ 		ag->nice = nice;
+ 	up_write(&ag->lock);
+diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c
+index 7e6df7a4964a..67f8fa9fc15a 100644
+--- a/net/batman-adv/translation-table.c
++++ b/net/batman-adv/translation-table.c
+@@ -2849,7 +2849,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
+ 							     &tvlv_tt_data,
+ 							     &tt_change,
+ 							     &tt_len);
+-		if (!tt_len)
++		if (!tt_len || !tvlv_len)
+ 			goto unlock;
+ 
+ 		/* Copy the last orig_node's OGM buffer */
+@@ -2867,7 +2867,7 @@ static bool batadv_send_my_tt_response(struct batadv_priv *bat_priv,
+ 							     &tvlv_tt_data,
+ 							     &tt_change,
+ 							     &tt_len);
+-		if (!tt_len)
++		if (!tt_len || !tvlv_len)
+ 			goto out;
+ 
+ 		/* fill the rest of the tvlv with the real TT entries */
+diff --git a/net/can/raw.c b/net/can/raw.c
+index 972c187d40ab..b075f028d7e2 100644
+--- a/net/can/raw.c
++++ b/net/can/raw.c
+@@ -499,6 +499,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
+ 		if (optlen % sizeof(struct can_filter) != 0)
+ 			return -EINVAL;
+ 
++		if (optlen > CAN_RAW_FILTER_MAX * sizeof(struct can_filter))
++			return -EINVAL;
++
+ 		count = optlen / sizeof(struct can_filter);
+ 
+ 		if (count > 1) {


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2017-01-06 23:11 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2017-01-06 23:11 UTC (permalink / raw
  To: gentoo-commits

commit:     81befa1208eed1da45b7a12153560ab1c0c184ce
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Jan  6 23:11:42 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Jan  6 23:11:42 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=81befa12

Linux patch 4.8.15

 0000_README             |    4 +
 1015_linux-4.8.16.patch | 3559 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3563 insertions(+)

diff --git a/0000_README b/0000_README
index 37d0ff1..e7fac7c 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch:  1014_linux-4.8.15.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.15
 
+Patch:  1015_linux-4.8.16.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.16
+
 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/1015_linux-4.8.16.patch b/1015_linux-4.8.16.patch
new file mode 100644
index 0000000..9977d7a
--- /dev/null
+++ b/1015_linux-4.8.16.patch
@@ -0,0 +1,3559 @@
+diff --git a/Makefile b/Makefile
+index c7f0e798ca34..50f68648a79a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 15
++SUBLEVEL = 16
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
+index f193414d0f6f..4986dc0c1dff 100644
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -372,8 +372,7 @@ static int __init xen_guest_init(void)
+ 	 * for secondary CPUs as they are brought up.
+ 	 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
+ 	 */
+-	xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
+-			                       sizeof(struct vcpu_info));
++	xen_vcpu_info = alloc_percpu(struct vcpu_info);
+ 	if (xen_vcpu_info == NULL)
+ 		return -ENOMEM;
+ 
+diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
+index 5420cb0fcb3e..e517088d635f 100644
+--- a/arch/arm64/include/asm/acpi.h
++++ b/arch/arm64/include/asm/acpi.h
+@@ -12,7 +12,7 @@
+ #ifndef _ASM_ACPI_H
+ #define _ASM_ACPI_H
+ 
+-#include <linux/mm.h>
++#include <linux/memblock.h>
+ #include <linux/psci.h>
+ 
+ #include <asm/cputype.h>
+@@ -32,7 +32,11 @@
+ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
+ 					    acpi_size size)
+ {
+-	if (!page_is_ram(phys >> PAGE_SHIFT))
++	/*
++	 * EFI's reserve_regions() call adds memory with the WB attribute
++	 * to memblock via early_init_dt_add_memory_arch().
++	 */
++	if (!memblock_is_memory(phys))
+ 		return ioremap(phys, size);
+ 
+ 	return ioremap_cache(phys, size);
+diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
+index 536dce22fe76..514b4e3ba029 100644
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -206,10 +206,15 @@ static void __init request_standard_resources(void)
+ 
+ 	for_each_memblock(memory, region) {
+ 		res = alloc_bootmem_low(sizeof(*res));
+-		res->name  = "System RAM";
++		if (memblock_is_nomap(region)) {
++			res->name  = "reserved";
++			res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++		} else {
++			res->name  = "System RAM";
++			res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
++		}
+ 		res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+ 		res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+-		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+ 
+ 		request_resource(&iomem_resource, res);
+ 
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index c207fa9870eb..494e0d800976 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1371,9 +1371,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
+ 		blk_mq_put_ctx(data.ctx);
+ 		if (!old_rq)
+ 			goto done;
+-		if (!blk_mq_direct_issue_request(old_rq, &cookie))
+-			goto done;
+-		blk_mq_insert_request(old_rq, false, true, true);
++		if (test_bit(BLK_MQ_S_STOPPED, &data.hctx->state) ||
++		    blk_mq_direct_issue_request(old_rq, &cookie) != 0)
++			blk_mq_insert_request(old_rq, false, true, true);
+ 		goto done;
+ 	}
+ 
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 0a8bdade53f2..88df65d1e6f6 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -836,11 +836,29 @@ static struct kobject *get_device_parent(struct device *dev,
+ 	return NULL;
+ }
+ 
++static inline bool live_in_glue_dir(struct kobject *kobj,
++				    struct device *dev)
++{
++	if (!kobj || !dev->class ||
++	    kobj->kset != &dev->class->p->glue_dirs)
++		return false;
++	return true;
++}
++
++static inline struct kobject *get_glue_dir(struct device *dev)
++{
++	return dev->kobj.parent;
++}
++
++/*
++ * make sure cleaning up dir as the last step, we need to make
++ * sure .release handler of kobject is run with holding the
++ * global lock
++ */
+ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
+ {
+ 	/* see if we live in a "glue" directory */
+-	if (!glue_dir || !dev->class ||
+-	    glue_dir->kset != &dev->class->p->glue_dirs)
++	if (!live_in_glue_dir(glue_dir, dev))
+ 		return;
+ 
+ 	mutex_lock(&gdp_mutex);
+@@ -848,11 +866,6 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
+ 	mutex_unlock(&gdp_mutex);
+ }
+ 
+-static void cleanup_device_parent(struct device *dev)
+-{
+-	cleanup_glue_dir(dev, dev->kobj.parent);
+-}
+-
+ static int device_add_class_symlinks(struct device *dev)
+ {
+ 	struct device_node *of_node = dev_of_node(dev);
+@@ -1028,6 +1041,7 @@ int device_add(struct device *dev)
+ 	struct kobject *kobj;
+ 	struct class_interface *class_intf;
+ 	int error = -EINVAL;
++	struct kobject *glue_dir = NULL;
+ 
+ 	dev = get_device(dev);
+ 	if (!dev)
+@@ -1072,8 +1086,10 @@ int device_add(struct device *dev)
+ 	/* first, register with generic layer. */
+ 	/* we require the name to be set before, and pass NULL */
+ 	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
+-	if (error)
++	if (error) {
++		glue_dir = get_glue_dir(dev);
+ 		goto Error;
++	}
+ 
+ 	/* notify platform of device entry */
+ 	if (platform_notify)
+@@ -1154,9 +1170,10 @@ done:
+ 	device_remove_file(dev, &dev_attr_uevent);
+  attrError:
+ 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
++	glue_dir = get_glue_dir(dev);
+ 	kobject_del(&dev->kobj);
+  Error:
+-	cleanup_device_parent(dev);
++	cleanup_glue_dir(dev, glue_dir);
+ 	put_device(parent);
+ name_error:
+ 	kfree(dev->p);
+@@ -1232,6 +1249,7 @@ EXPORT_SYMBOL_GPL(put_device);
+ void device_del(struct device *dev)
+ {
+ 	struct device *parent = dev->parent;
++	struct kobject *glue_dir = NULL;
+ 	struct class_interface *class_intf;
+ 
+ 	/* Notify clients of device removal.  This call must come
+@@ -1276,8 +1294,9 @@ void device_del(struct device *dev)
+ 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+ 					     BUS_NOTIFY_REMOVED_DEVICE, dev);
+ 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+-	cleanup_device_parent(dev);
++	glue_dir = get_glue_dir(dev);
+ 	kobject_del(&dev->kobj);
++	cleanup_glue_dir(dev, glue_dir);
+ 	put_device(parent);
+ }
+ EXPORT_SYMBOL_GPL(device_del);
+diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
+index df0c70963d9e..94b33ce96be7 100644
+--- a/drivers/base/power/opp/core.c
++++ b/drivers/base/power/opp/core.c
+@@ -1320,7 +1320,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+ 	struct opp_table *opp_table;
+ 	struct regulator *reg;
+@@ -1358,20 +1358,20 @@ int dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ 	opp_table->regulator = reg;
+ 
+ 	mutex_unlock(&opp_table_lock);
+-	return 0;
++	return opp_table;
+ 
+ err:
+ 	_remove_opp_table(opp_table);
+ unlock:
+ 	mutex_unlock(&opp_table_lock);
+ 
+-	return ret;
++	return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+ 
+ /**
+  * dev_pm_opp_put_regulator() - Releases resources blocked for regulator
+- * @dev: Device for which regulator was set.
++ * @opp_table: OPP table returned from dev_pm_opp_set_regulator().
+  *
+  * Locking: The internal opp_table and opp structures are RCU protected.
+  * Hence this function internally uses RCU updater strategy with mutex locks
+@@ -1379,22 +1379,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-void dev_pm_opp_put_regulator(struct device *dev)
++void dev_pm_opp_put_regulator(struct opp_table *opp_table)
+ {
+-	struct opp_table *opp_table;
+-
+ 	mutex_lock(&opp_table_lock);
+ 
+-	/* Check for existing table for 'dev' first */
+-	opp_table = _find_opp_table(dev);
+-	if (IS_ERR(opp_table)) {
+-		dev_err(dev, "Failed to find opp_table: %ld\n",
+-			PTR_ERR(opp_table));
+-		goto unlock;
+-	}
+-
+ 	if (IS_ERR(opp_table->regulator)) {
+-		dev_err(dev, "%s: Doesn't have regulator set\n", __func__);
++		pr_err("%s: Doesn't have regulator set\n", __func__);
+ 		goto unlock;
+ 	}
+ 
+diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
+index ab19adb07a12..3c606c09fd5a 100644
+--- a/drivers/block/aoe/aoecmd.c
++++ b/drivers/block/aoe/aoecmd.c
+@@ -853,45 +853,6 @@ rqbiocnt(struct request *r)
+ 	return n;
+ }
+ 
+-/* This can be removed if we are certain that no users of the block
+- * layer will ever use zero-count pages in bios.  Otherwise we have to
+- * protect against the put_page sometimes done by the network layer.
+- *
+- * See http://oss.sgi.com/archives/xfs/2007-01/msg00594.html for
+- * discussion.
+- *
+- * We cannot use get_page in the workaround, because it insists on a
+- * positive page count as a precondition.  So we use _refcount directly.
+- */
+-static void
+-bio_pageinc(struct bio *bio)
+-{
+-	struct bio_vec bv;
+-	struct page *page;
+-	struct bvec_iter iter;
+-
+-	bio_for_each_segment(bv, bio, iter) {
+-		/* Non-zero page count for non-head members of
+-		 * compound pages is no longer allowed by the kernel.
+-		 */
+-		page = compound_head(bv.bv_page);
+-		page_ref_inc(page);
+-	}
+-}
+-
+-static void
+-bio_pagedec(struct bio *bio)
+-{
+-	struct page *page;
+-	struct bio_vec bv;
+-	struct bvec_iter iter;
+-
+-	bio_for_each_segment(bv, bio, iter) {
+-		page = compound_head(bv.bv_page);
+-		page_ref_dec(page);
+-	}
+-}
+-
+ static void
+ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
+ {
+@@ -899,7 +860,6 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
+ 	buf->rq = rq;
+ 	buf->bio = bio;
+ 	buf->iter = bio->bi_iter;
+-	bio_pageinc(bio);
+ }
+ 
+ static struct buf *
+@@ -1127,7 +1087,6 @@ aoe_end_buf(struct aoedev *d, struct buf *buf)
+ 	if (buf == d->ip.buf)
+ 		d->ip.buf = NULL;
+ 	rq = buf->rq;
+-	bio_pagedec(buf->bio);
+ 	mempool_free(buf, d->bufpool);
+ 	n = (unsigned long) rq->special;
+ 	rq->special = (void *) --n;
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index c9f2107f7095..b314a57e3c86 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1646,7 +1646,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
+ 	blk_mq_start_request(bd->rq);
+ 
+ 	if (lo->lo_state != Lo_bound)
+-		return -EIO;
++		return BLK_MQ_RQ_QUEUE_ERROR;
+ 
+ 	switch (req_op(cmd->rq)) {
+ 	case REQ_OP_FLUSH:
+diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
+index 62028f483bba..a2ab00831df1 100644
+--- a/drivers/char/tpm/xen-tpmfront.c
++++ b/drivers/char/tpm/xen-tpmfront.c
+@@ -307,7 +307,6 @@ static int tpmfront_probe(struct xenbus_device *dev,
+ 	rv = setup_ring(dev, priv);
+ 	if (rv) {
+ 		chip = dev_get_drvdata(&dev->dev);
+-		tpm_chip_unregister(chip);
+ 		ring_free(priv);
+ 		return rv;
+ 	}
+diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c
+index 8831e1a05367..11d8aa3ec186 100644
+--- a/drivers/clk/ti/clk-3xxx.c
++++ b/drivers/clk/ti/clk-3xxx.c
+@@ -22,13 +22,6 @@
+ 
+ #include "clock.h"
+ 
+-/*
+- * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+- * that are sourced by DPLL5, and both of these require this clock
+- * to be at 120 MHz for proper operation.
+- */
+-#define DPLL5_FREQ_FOR_USBHOST		120000000
+-
+ #define OMAP3430ES2_ST_DSS_IDLE_SHIFT			1
+ #define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT		5
+ #define OMAP3430ES2_ST_SSI_IDLE_SHIFT			8
+@@ -546,14 +539,21 @@ void __init omap3_clk_lock_dpll5(void)
+ 	struct clk *dpll5_clk;
+ 	struct clk *dpll5_m2_clk;
+ 
++	/*
++	 * Errata sprz319f advisory 2.1 documents a USB host clock drift issue
++	 * that can be worked around using specially crafted dpll5 settings
++	 * with a dpll5_m2 divider set to 8. Set the dpll5 rate to 8x the USB
++	 * host clock rate, its .set_rate handler() will detect that frequency
++	 * and use the errata settings.
++	 */
+ 	dpll5_clk = clk_get(NULL, "dpll5_ck");
+-	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
++	clk_set_rate(dpll5_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST * 8);
+ 	clk_prepare_enable(dpll5_clk);
+ 
+-	/* Program dpll5_m2_clk divider for no division */
++	/* Program dpll5_m2_clk divider */
+ 	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+ 	clk_prepare_enable(dpll5_m2_clk);
+-	clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
++	clk_set_rate(dpll5_m2_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST);
+ 
+ 	clk_disable_unprepare(dpll5_m2_clk);
+ 	clk_disable_unprepare(dpll5_clk);
+diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
+index 90f3f472ae1c..13c37f48d9d6 100644
+--- a/drivers/clk/ti/clock.h
++++ b/drivers/clk/ti/clock.h
+@@ -257,11 +257,20 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
+ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
+ 				    unsigned long parent_rate);
+ 
++/*
++ * OMAP3_DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
++ * that are sourced by DPLL5, and both of these require this clock
++ * to be at 120 MHz for proper operation.
++ */
++#define OMAP3_DPLL5_FREQ_FOR_USBHOST	120000000
++
+ unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
+ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
+ 			 unsigned long parent_rate);
+ int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ 				    unsigned long parent_rate, u8 index);
++int omap3_dpll5_set_rate(struct clk_hw *hw, unsigned long rate,
++			 unsigned long parent_rate);
+ void omap3_clk_lock_dpll5(void);
+ 
+ unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
+diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
+index 9fc8754a6e61..4b9a419d8e14 100644
+--- a/drivers/clk/ti/dpll.c
++++ b/drivers/clk/ti/dpll.c
+@@ -114,6 +114,18 @@ static const struct clk_ops omap3_dpll_ck_ops = {
+ 	.round_rate	= &omap2_dpll_round_rate,
+ };
+ 
++static const struct clk_ops omap3_dpll5_ck_ops = {
++	.enable		= &omap3_noncore_dpll_enable,
++	.disable	= &omap3_noncore_dpll_disable,
++	.get_parent	= &omap2_init_dpll_parent,
++	.recalc_rate	= &omap3_dpll_recalc,
++	.set_rate	= &omap3_dpll5_set_rate,
++	.set_parent	= &omap3_noncore_dpll_set_parent,
++	.set_rate_and_parent	= &omap3_noncore_dpll_set_rate_and_parent,
++	.determine_rate	= &omap3_noncore_dpll_determine_rate,
++	.round_rate	= &omap2_dpll_round_rate,
++};
++
+ static const struct clk_ops omap3_dpll_per_ck_ops = {
+ 	.enable		= &omap3_noncore_dpll_enable,
+ 	.disable	= &omap3_noncore_dpll_disable,
+@@ -474,7 +486,12 @@ static void __init of_ti_omap3_dpll_setup(struct device_node *node)
+ 		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ 	};
+ 
+-	of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
++	if ((of_machine_is_compatible("ti,omap3630") ||
++	     of_machine_is_compatible("ti,omap36xx")) &&
++	    !strcmp(node->name, "dpll5_ck"))
++		of_ti_dpll_setup(node, &omap3_dpll5_ck_ops, &dd);
++	else
++		of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
+ }
+ CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
+ 	       of_ti_omap3_dpll_setup);
+diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
+index 88f2ce81ba55..4cdd28a25584 100644
+--- a/drivers/clk/ti/dpll3xxx.c
++++ b/drivers/clk/ti/dpll3xxx.c
+@@ -838,3 +838,70 @@ int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ 	return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate,
+ 						      index);
+ }
++
++/* Apply DM3730 errata sprz319 advisory 2.1. */
++static bool omap3_dpll5_apply_errata(struct clk_hw *hw,
++				     unsigned long parent_rate)
++{
++	struct omap3_dpll5_settings {
++		unsigned int rate, m, n;
++	};
++
++	static const struct omap3_dpll5_settings precomputed[] = {
++		/*
++		 * From DM3730 errata advisory 2.1, table 35 and 36.
++		 * The N value is increased by 1 compared to the tables as the
++		 * errata lists register values while last_rounded_field is the
++		 * real divider value.
++		 */
++		{ 12000000,  80,  0 + 1 },
++		{ 13000000, 443,  5 + 1 },
++		{ 19200000,  50,  0 + 1 },
++		{ 26000000, 443, 11 + 1 },
++		{ 38400000,  25,  0 + 1 }
++	};
++
++	const struct omap3_dpll5_settings *d;
++	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
++	struct dpll_data *dd;
++	unsigned int i;
++
++	for (i = 0; i < ARRAY_SIZE(precomputed); ++i) {
++		if (parent_rate == precomputed[i].rate)
++			break;
++	}
++
++	if (i == ARRAY_SIZE(precomputed))
++		return false;
++
++	d = &precomputed[i];
++
++	/* Update the M, N and rounded rate values and program the DPLL. */
++	dd = clk->dpll_data;
++	dd->last_rounded_m = d->m;
++	dd->last_rounded_n = d->n;
++	dd->last_rounded_rate = div_u64((u64)parent_rate * d->m, d->n);
++	omap3_noncore_dpll_program(clk, 0);
++
++	return true;
++}
++
++/**
++ * omap3_dpll5_set_rate - set rate for omap3 dpll5
++ * @hw: clock to change
++ * @rate: target rate for clock
++ * @parent_rate: rate of the parent clock
++ *
++ * Set rate for the DPLL5 clock. Apply the sprz319 advisory 2.1 on OMAP36xx if
++ * the DPLL is used for USB host (detected through the requested rate).
++ */
++int omap3_dpll5_set_rate(struct clk_hw *hw, unsigned long rate,
++			 unsigned long parent_rate)
++{
++	if (rate == OMAP3_DPLL5_FREQ_FOR_USBHOST * 8) {
++		if (omap3_dpll5_apply_errata(hw, parent_rate))
++			return 0;
++	}
++
++	return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
++}
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index 3957de801ae8..204cd527ff34 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -26,6 +26,7 @@
+ #include <linux/thermal.h>
+ 
+ struct private_data {
++	struct opp_table *opp_table;
+ 	struct device *cpu_dev;
+ 	struct thermal_cooling_device *cdev;
+ 	const char *reg_name;
+@@ -141,6 +142,7 @@ static int resources_available(void)
+ static int cpufreq_init(struct cpufreq_policy *policy)
+ {
+ 	struct cpufreq_frequency_table *freq_table;
++	struct opp_table *opp_table = NULL;
+ 	struct private_data *priv;
+ 	struct device *cpu_dev;
+ 	struct clk *cpu_clk;
+@@ -184,8 +186,9 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ 	 */
+ 	name = find_supply_name(cpu_dev);
+ 	if (name) {
+-		ret = dev_pm_opp_set_regulator(cpu_dev, name);
+-		if (ret) {
++		opp_table = dev_pm_opp_set_regulator(cpu_dev, name);
++		if (IS_ERR(opp_table)) {
++			ret = PTR_ERR(opp_table);
+ 			dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n",
+ 				policy->cpu, ret);
+ 			goto out_put_clk;
+@@ -235,6 +238,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ 	}
+ 
+ 	priv->reg_name = name;
++	priv->opp_table = opp_table;
+ 
+ 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ 	if (ret) {
+@@ -283,7 +287,7 @@ out_free_priv:
+ out_free_opp:
+ 	dev_pm_opp_of_cpumask_remove_table(policy->cpus);
+ 	if (name)
+-		dev_pm_opp_put_regulator(cpu_dev);
++		dev_pm_opp_put_regulator(opp_table);
+ out_put_clk:
+ 	clk_put(cpu_clk);
+ 
+@@ -298,7 +302,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
+ 	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+ 	dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+ 	if (priv->reg_name)
+-		dev_pm_opp_put_regulator(priv->cpu_dev);
++		dev_pm_opp_put_regulator(priv->opp_table);
+ 
+ 	clk_put(policy->clk);
+ 	kfree(priv);
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
+index 2cde3796cb82..f3307fc38e79 100644
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -702,7 +702,9 @@ copy_iv:
+ 
+ 	/* Will read cryptlen */
+ 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
+-	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
++	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
++			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
++	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
+ 
+ 	/* Write ICV */
+ 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 6fc8923bd92a..bd56a3ecb29c 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1503,12 +1503,15 @@ static int crypt_set_key(struct crypt_config *cc, char *key)
+ 	if (!cc->key_size && strcmp(key, "-"))
+ 		goto out;
+ 
++	/* clear the flag since following operations may invalidate previously valid key */
++	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
++
+ 	if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0)
+ 		goto out;
+ 
+-	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+-
+ 	r = crypt_setkey_allcpus(cc);
++	if (!r)
++		set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+ 
+ out:
+ 	/* Hex key string not needed after here, so wipe it. */
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index 6a2e8dd44a1b..3643cba71351 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -200,11 +200,13 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ 
+ 	if (!(fc->up_interval + fc->down_interval)) {
+ 		ti->error = "Total (up + down) interval is zero";
++		r = -EINVAL;
+ 		goto bad;
+ 	}
+ 
+ 	if (fc->up_interval + fc->down_interval < fc->up_interval) {
+ 		ti->error = "Interval overflow";
++		r = -EINVAL;
+ 		goto bad;
+ 	}
+ 
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 6d53810963f7..af2d79b52484 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -2994,6 +2994,9 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ 		}
+ 	}
+ 
++	/* Disable/enable discard support on raid set. */
++	configure_discard_support(rs);
++
+ 	mddev_unlock(&rs->md);
+ 	return 0;
+ 
+@@ -3580,12 +3583,6 @@ static int raid_preresume(struct dm_target *ti)
+ 	if (test_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags))
+ 		rs_update_sbs(rs);
+ 
+-	/*
+-	 * Disable/enable discard support on raid set after any
+-	 * conversion, because devices can have been added
+-	 */
+-	configure_discard_support(rs);
+-
+ 	/* Load the bitmap from disk unless raid0 */
+ 	r = __load_dirty_region_bitmap(rs);
+ 	if (r)
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 2154596eedf3..b6af2860cbc6 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -218,6 +218,9 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
+  */
+ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
+ {
++	struct request_queue *q = md->queue;
++	unsigned long flags;
++
+ 	atomic_dec(&md->pending[rw]);
+ 
+ 	/* nudge anyone waiting on suspend queue */
+@@ -230,8 +233,11 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
+ 	 * back into ->request_fn() could deadlock attempting to grab the
+ 	 * queue lock again.
+ 	 */
+-	if (!md->queue->mq_ops && run_queue)
+-		blk_run_queue_async(md->queue);
++	if (!q->mq_ops && run_queue) {
++		spin_lock_irqsave(q->queue_lock, flags);
++		blk_run_queue_async(q);
++		spin_unlock_irqrestore(q->queue_lock, flags);
++	}
+ 
+ 	/*
+ 	 * dm_put() must be at the end of this function. See the comment above
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index c4b53b332607..5ac239d0f787 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -924,12 +924,6 @@ static int dm_table_determine_type(struct dm_table *t)
+ 
+ 	BUG_ON(!request_based); /* No targets in this table */
+ 
+-	if (list_empty(devices) && __table_type_request_based(live_md_type)) {
+-		/* inherit live MD type */
+-		t->type = live_md_type;
+-		return 0;
+-	}
+-
+ 	/*
+ 	 * The only way to establish DM_TYPE_MQ_REQUEST_BASED is by
+ 	 * having a compatible target use dm_table_set_type.
+@@ -948,6 +942,19 @@ verify_rq_based:
+ 		return -EINVAL;
+ 	}
+ 
++	if (list_empty(devices)) {
++		int srcu_idx;
++		struct dm_table *live_table = dm_get_live_table(t->md, &srcu_idx);
++
++		/* inherit live table's type and all_blk_mq */
++		if (live_table) {
++			t->type = live_table->type;
++			t->all_blk_mq = live_table->all_blk_mq;
++		}
++		dm_put_live_table(t->md, srcu_idx);
++		return 0;
++	}
++
+ 	/* Non-request-stackable devices can't be used for request-based dm */
+ 	list_for_each_entry(dd, devices, list) {
+ 		struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev);
+@@ -974,6 +981,11 @@ verify_rq_based:
+ 		t->all_blk_mq = true;
+ 	}
+ 
++	if (t->type == DM_TYPE_MQ_REQUEST_BASED && !t->all_blk_mq) {
++		DMERR("table load rejected: all devices are not blk-mq request-stackable");
++		return -EINVAL;
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
+index 7e44005595c1..20557e2c60c6 100644
+--- a/drivers/md/persistent-data/dm-space-map-metadata.c
++++ b/drivers/md/persistent-data/dm-space-map-metadata.c
+@@ -775,17 +775,15 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
+ 	memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+ 
+ 	r = sm_ll_new_metadata(&smm->ll, tm);
++	if (!r) {
++		if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
++			nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
++		r = sm_ll_extend(&smm->ll, nr_blocks);
++	}
++	memcpy(&smm->sm, &ops, sizeof(smm->sm));
+ 	if (r)
+ 		return r;
+ 
+-	if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
+-		nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
+-	r = sm_ll_extend(&smm->ll, nr_blocks);
+-	if (r)
+-		return r;
+-
+-	memcpy(&smm->sm, &ops, sizeof(smm->sm));
+-
+ 	/*
+ 	 * Now we need to update the newly created data structures with the
+ 	 * allocated blocks that they were built from.
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index af5e2dc4a3d5..011f88e5663e 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -271,7 +271,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
+ 
+ 	mutex_lock(&subsys->lock);
+ 	ret = -EBUSY;
+-	if (nvmet_ns_enabled(ns))
++	if (ns->enabled)
+ 		goto out_unlock;
+ 
+ 	kfree(ns->device_path);
+@@ -307,7 +307,7 @@ static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
+ 	int ret = 0;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (nvmet_ns_enabled(ns)) {
++	if (ns->enabled) {
+ 		ret = -EBUSY;
+ 		goto out_unlock;
+ 	}
+@@ -339,7 +339,7 @@ CONFIGFS_ATTR(nvmet_ns_, device_nguid);
+ 
+ static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
+ {
+-	return sprintf(page, "%d\n", nvmet_ns_enabled(to_nvmet_ns(item)));
++	return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
+ }
+ 
+ static ssize_t nvmet_ns_enable_store(struct config_item *item,
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 6559d5afa7bf..e9500d41b943 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -264,7 +264,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
+ 	int ret = 0;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (!list_empty(&ns->dev_link))
++	if (ns->enabled)
+ 		goto out_unlock;
+ 
+ 	ns->bdev = blkdev_get_by_path(ns->device_path, FMODE_READ | FMODE_WRITE,
+@@ -309,6 +309,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
+ 	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
+ 		nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
+ 
++	ns->enabled = true;
+ 	ret = 0;
+ out_unlock:
+ 	mutex_unlock(&subsys->lock);
+@@ -325,11 +326,11 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
+ 	struct nvmet_ctrl *ctrl;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (list_empty(&ns->dev_link)) {
+-		mutex_unlock(&subsys->lock);
+-		return;
+-	}
+-	list_del_init(&ns->dev_link);
++	if (!ns->enabled)
++		goto out_unlock;
++
++	ns->enabled = false;
++	list_del_rcu(&ns->dev_link);
+ 	mutex_unlock(&subsys->lock);
+ 
+ 	/*
+@@ -351,6 +352,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
+ 
+ 	if (ns->bdev)
+ 		blkdev_put(ns->bdev, FMODE_WRITE|FMODE_READ);
++out_unlock:
+ 	mutex_unlock(&subsys->lock);
+ }
+ 
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index 76b6eedccaf9..7655a351320f 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -47,6 +47,7 @@ struct nvmet_ns {
+ 	loff_t			size;
+ 	u8			nguid[16];
+ 
++	bool			enabled;
+ 	struct nvmet_subsys	*subsys;
+ 	const char		*device_path;
+ 
+@@ -61,11 +62,6 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
+ 	return container_of(to_config_group(item), struct nvmet_ns, group);
+ }
+ 
+-static inline bool nvmet_ns_enabled(struct nvmet_ns *ns)
+-{
+-	return !list_empty_careful(&ns->dev_link);
+-}
+-
+ struct nvmet_cq {
+ 	u16			qid;
+ 	u16			size;
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 3ca9fdb0a271..3f9ac8be77e1 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1732,6 +1732,7 @@ static const struct usb_device_id acm_ids[] = {
+ 	{ USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */
+ 	.driver_info = QUIRK_CONTROL_LINE_STATE, },
+ 	{ USB_DEVICE(0x2184, 0x001c) },	/* GW Instek AFG-2225 */
++	{ USB_DEVICE(0x2184, 0x0036) },	/* GW Instek AFG-125 */
+ 	{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
+ 	},
+ 	/* Motorola H24 HSPA module: */
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 1d5fc32d06d0..f3a7408d6417 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -101,6 +101,8 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
+ 
+ static void hub_release(struct kref *kref);
+ static int usb_reset_and_verify_device(struct usb_device *udev);
++static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++					  struct usb_port *port_dev);
+ 
+ static inline char *portspeed(struct usb_hub *hub, int portstatus)
+ {
+@@ -899,82 +901,28 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1,
+ }
+ 
+ /*
+- * If USB 3.0 ports are placed into the Disabled state, they will no longer
+- * detect any device connects or disconnects.  This is generally not what the
+- * USB core wants, since it expects a disabled port to produce a port status
+- * change event when a new device connects.
+- *
+- * Instead, set the link state to Disabled, wait for the link to settle into
+- * that state, clear any change bits, and then put the port into the RxDetect
+- * state.
++ * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
++ * a connection with a plugged-in cable but will signal the host when the cable
++ * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
+  */
+-static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
+-{
+-	int ret;
+-	int total_time;
+-	u16 portchange, portstatus;
+-
+-	if (!hub_is_superspeed(hub->hdev))
+-		return -EINVAL;
+-
+-	ret = hub_port_status(hub, port1, &portstatus, &portchange);
+-	if (ret < 0)
+-		return ret;
+-
+-	/*
+-	 * USB controller Advanced Micro Devices, Inc. [AMD] FCH USB XHCI
+-	 * Controller [1022:7814] will have spurious result making the following
+-	 * usb 3.0 device hotplugging route to the 2.0 root hub and recognized
+-	 * as high-speed device if we set the usb 3.0 port link state to
+-	 * Disabled. Since it's already in USB_SS_PORT_LS_RX_DETECT state, we
+-	 * check the state here to avoid the bug.
+-	 */
+-	if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+-				USB_SS_PORT_LS_RX_DETECT) {
+-		dev_dbg(&hub->ports[port1 - 1]->dev,
+-			 "Not disabling port; link state is RxDetect\n");
+-		return ret;
+-	}
+-
+-	ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED);
+-	if (ret)
+-		return ret;
+-
+-	/* Wait for the link to enter the disabled state. */
+-	for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
+-		ret = hub_port_status(hub, port1, &portstatus, &portchange);
+-		if (ret < 0)
+-			return ret;
+-
+-		if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+-				USB_SS_PORT_LS_SS_DISABLED)
+-			break;
+-		if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+-			break;
+-		msleep(HUB_DEBOUNCE_STEP);
+-	}
+-	if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+-		dev_warn(&hub->ports[port1 - 1]->dev,
+-				"Could not disable after %d ms\n", total_time);
+-
+-	return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
+-}
+-
+ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+ {
+ 	struct usb_port *port_dev = hub->ports[port1 - 1];
+ 	struct usb_device *hdev = hub->hdev;
+ 	int ret = 0;
+ 
+-	if (port_dev->child && set_state)
+-		usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+ 	if (!hub->error) {
+-		if (hub_is_superspeed(hub->hdev))
+-			ret = hub_usb3_port_disable(hub, port1);
+-		else
++		if (hub_is_superspeed(hub->hdev)) {
++			hub_usb3_port_prepare_disable(hub, port_dev);
++			ret = hub_set_port_link_state(hub, port_dev->portnum,
++						      USB_SS_PORT_LS_U3);
++		} else {
+ 			ret = usb_clear_port_feature(hdev, port1,
+ 					USB_PORT_FEAT_ENABLE);
++		}
+ 	}
++	if (port_dev->child && set_state)
++		usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+ 	if (ret && ret != -ENODEV)
+ 		dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
+ 	return ret;
+@@ -4142,6 +4090,26 @@ void usb_unlocked_enable_lpm(struct usb_device *udev)
+ }
+ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
+ 
++/* usb3 devices use U3 for disabled, make sure remote wakeup is disabled */
++static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++					  struct usb_port *port_dev)
++{
++	struct usb_device *udev = port_dev->child;
++	int ret;
++
++	if (udev && udev->port_is_suspended && udev->do_remote_wakeup) {
++		ret = hub_set_port_link_state(hub, port_dev->portnum,
++					      USB_SS_PORT_LS_U0);
++		if (!ret) {
++			msleep(USB_RESUME_TIMEOUT);
++			ret = usb_disable_remote_wakeup(udev);
++		}
++		if (ret)
++			dev_warn(&udev->dev,
++				 "Port disable: can't disable remote wake\n");
++		udev->do_remote_wakeup = 0;
++	}
++}
+ 
+ #else	/* CONFIG_PM */
+ 
+@@ -4149,6 +4117,9 @@ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
+ #define hub_resume		NULL
+ #define hub_reset_resume	NULL
+ 
++static inline void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++						 struct usb_port *port_dev) { }
++
+ int usb_disable_lpm(struct usb_device *udev)
+ {
+ 	return 0;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index dc3b5962d087..717d5f6d3e7c 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -775,6 +775,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 		unsigned length, unsigned last, unsigned chain, unsigned node)
+ {
+ 	struct dwc3_trb		*trb;
++	struct dwc3		*dwc = dep->dwc;
++	struct usb_gadget	*gadget = &dwc->gadget;
++	enum usb_device_speed	speed = gadget->speed;
+ 
+ 	dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s",
+ 			dep->name, req, (unsigned long long) dma,
+@@ -804,10 +807,16 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 		break;
+ 
+ 	case USB_ENDPOINT_XFER_ISOC:
+-		if (!node)
++		if (!node) {
+ 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+-		else
++
++			if (speed == USB_SPEED_HIGH) {
++				struct usb_ep *ep = &dep->endpoint;
++				trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1);
++			}
++		} else {
+ 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
++		}
+ 
+ 		/* always enable Interrupt on Missed ISOC */
+ 		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 5ebe6af7976e..e2abaa7943d9 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -197,11 +197,16 @@ int config_ep_by_speed(struct usb_gadget *g,
+ 
+ ep_found:
+ 	/* commit results */
+-	_ep->maxpacket = usb_endpoint_maxp(chosen_desc);
++	_ep->maxpacket = usb_endpoint_maxp(chosen_desc) & 0x7ff;
+ 	_ep->desc = chosen_desc;
+ 	_ep->comp_desc = NULL;
+ 	_ep->maxburst = 0;
+-	_ep->mult = 0;
++	_ep->mult = 1;
++
++	if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) ||
++				usb_endpoint_xfer_int(_ep->desc)))
++		_ep->mult = usb_endpoint_maxp(_ep->desc) & 0x7ff;
++
+ 	if (!want_comp_desc)
+ 		return 0;
+ 
+@@ -218,7 +223,7 @@ ep_found:
+ 		switch (usb_endpoint_type(_ep->desc)) {
+ 		case USB_ENDPOINT_XFER_ISOC:
+ 			/* mult: bits 1:0 of bmAttributes */
+-			_ep->mult = comp_desc->bmAttributes & 0x3;
++			_ep->mult = (comp_desc->bmAttributes & 0x3) + 1;
+ 		case USB_ENDPOINT_XFER_BULK:
+ 		case USB_ENDPOINT_XFER_INT:
+ 			_ep->maxburst = comp_desc->bMaxBurst + 1;
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
+index cd214ec8a601..969cfe741380 100644
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -1067,13 +1067,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
+ 	if (!agdev->out_ep) {
+ 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
+ 	if (!agdev->in_ep) {
+ 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	uac2->p_prm.uac2 = uac2;
+@@ -1091,7 +1091,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL,
+ 				     NULL);
+ 	if (ret)
+-		goto err;
++		return ret;
+ 
+ 	prm = &agdev->uac2.c_prm;
+ 	prm->max_psize = hs_epout_desc.wMaxPacketSize;
+@@ -1106,19 +1106,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL);
+ 	if (!prm->rbuf) {
+ 		prm->max_psize = 0;
+-		goto err_free_descs;
++		goto err;
+ 	}
+ 
+ 	ret = alsa_uac2_init(agdev);
+ 	if (ret)
+-		goto err_free_descs;
++		goto err;
+ 	return 0;
+ 
+-err_free_descs:
+-	usb_free_all_descriptors(fn);
+ err:
+ 	kfree(agdev->uac2.p_prm.rbuf);
+ 	kfree(agdev->uac2.c_prm.rbuf);
++err_free_descs:
++	usb_free_all_descriptors(fn);
+ 	return -EINVAL;
+ }
+ 
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index 3d0d5d94a62f..0f01c04d7cbd 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -243,7 +243,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
+ 
+ 	req_size = video->ep->maxpacket
+ 		 * max_t(unsigned int, video->ep->maxburst, 1)
+-		 * (video->ep->mult + 1);
++		 * (video->ep->mult);
+ 
+ 	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
+ 		video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
+diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
+index 940304c33224..02260cfdedb1 100644
+--- a/drivers/usb/host/uhci-pci.c
++++ b/drivers/usb/host/uhci-pci.c
+@@ -129,6 +129,10 @@ static int uhci_pci_init(struct usb_hcd *hcd)
+ 	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP)
+ 		uhci->wait_for_hp = 1;
+ 
++	/* Intel controllers use non-PME wakeup signalling */
++	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
++		device_set_run_wake(uhci_dev(uhci), 1);
++
+ 	/* Set up pointers to PCI-specific functions */
+ 	uhci->reset_hc = uhci_pci_reset_hc;
+ 	uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc;
+diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
+index fc5d3a791e08..6f29bfadbe33 100644
+--- a/drivers/usb/serial/kl5kusb105.c
++++ b/drivers/usb/serial/kl5kusb105.c
+@@ -296,7 +296,7 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
+ 	rc = usb_serial_generic_open(tty, port);
+ 	if (rc) {
+ 		retval = rc;
+-		goto exit;
++		goto err_free_cfg;
+ 	}
+ 
+ 	rc = usb_control_msg(port->serial->dev,
+@@ -315,17 +315,32 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
+ 		dev_dbg(&port->dev, "%s - enabled reading\n", __func__);
+ 
+ 	rc = klsi_105_get_line_state(port, &line_state);
+-	if (rc >= 0) {
+-		spin_lock_irqsave(&priv->lock, flags);
+-		priv->line_state = line_state;
+-		spin_unlock_irqrestore(&priv->lock, flags);
+-		dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
+-		retval = 0;
+-	} else
++	if (rc < 0) {
+ 		retval = rc;
++		goto err_disable_read;
++	}
++
++	spin_lock_irqsave(&priv->lock, flags);
++	priv->line_state = line_state;
++	spin_unlock_irqrestore(&priv->lock, flags);
++	dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__,
++			line_state);
++
++	return 0;
+ 
+-exit:
++err_disable_read:
++	usb_control_msg(port->serial->dev,
++			     usb_sndctrlpipe(port->serial->dev, 0),
++			     KL5KUSB105A_SIO_CONFIGURE,
++			     USB_TYPE_VENDOR | USB_DIR_OUT,
++			     KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
++			     0, /* index */
++			     NULL, 0,
++			     KLSI_TIMEOUT);
++	usb_serial_generic_close(port);
++err_free_cfg:
+ 	kfree(cfg);
++
+ 	return retval;
+ }
+ 
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 9894e341c6ac..7ce31a4c7e7f 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -268,6 +268,8 @@ static void option_instat_callback(struct urb *urb);
+ #define TELIT_PRODUCT_CC864_SINGLE		0x1006
+ #define TELIT_PRODUCT_DE910_DUAL		0x1010
+ #define TELIT_PRODUCT_UE910_V2			0x1012
++#define TELIT_PRODUCT_LE922_USBCFG1		0x1040
++#define TELIT_PRODUCT_LE922_USBCFG2		0x1041
+ #define TELIT_PRODUCT_LE922_USBCFG0		0x1042
+ #define TELIT_PRODUCT_LE922_USBCFG3		0x1043
+ #define TELIT_PRODUCT_LE922_USBCFG5		0x1045
+@@ -1210,6 +1212,10 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
+ 		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
++	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
++		.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
++	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2),
++		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
+ 		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+ 	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+@@ -1989,6 +1995,7 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
++	{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) },			/* D-Link DWM-158 */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),			/* D-Link DWM-221 B1 */
+ 	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
+diff --git a/drivers/usb/usbip/vudc_transfer.c b/drivers/usb/usbip/vudc_transfer.c
+index aba6bd478045..bc0296d937d0 100644
+--- a/drivers/usb/usbip/vudc_transfer.c
++++ b/drivers/usb/usbip/vudc_transfer.c
+@@ -339,6 +339,8 @@ static void v_timer(unsigned long _vudc)
+ 		total = timer->frame_limit;
+ 	}
+ 
++	/* We have to clear ep0 flags separately as it's not on the list */
++	udc->ep[0].already_seen = 0;
+ 	list_for_each_entry(_ep, &udc->gadget.ep_list, ep_list) {
+ 		ep = to_vep(_ep);
+ 		ep->already_seen = 0;
+diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
+index 630bd189f167..2a9d5cdedea2 100644
+--- a/drivers/watchdog/mei_wdt.c
++++ b/drivers/watchdog/mei_wdt.c
+@@ -389,6 +389,8 @@ static int mei_wdt_register(struct mei_wdt *wdt)
+ 	wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
+ 
+ 	watchdog_set_drvdata(&wdt->wdd, wdt);
++	watchdog_stop_on_reboot(&wdt->wdd);
++
+ 	ret = watchdog_register_device(&wdt->wdd);
+ 	if (ret) {
+ 		dev_err(dev, "unable to register watchdog device = %d.\n", ret);
+diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
+index 5796b5d1b3f2..4f47b5e90956 100644
+--- a/drivers/watchdog/qcom-wdt.c
++++ b/drivers/watchdog/qcom-wdt.c
+@@ -209,7 +209,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
+ 	wdt->wdd.parent = &pdev->dev;
+ 	wdt->layout = regs;
+ 
+-	if (readl(wdt->base + WDT_STS) & 1)
++	if (readl(wdt_addr(wdt, WDT_STS)) & 1)
+ 		wdt->wdd.bootstatus = WDIOF_CARDRESET;
+ 
+ 	/*
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
+index bb952121ea94..2ef2b61b69df 100644
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -1007,7 +1007,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ 
+ 	vma->vm_ops = &gntdev_vmops;
+ 
+-	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
++	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP;
+ 
+ 	if (use_ptemod)
+ 		vma->vm_flags |= VM_DONTCOPY;
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 08ae99343d92..b010242bab32 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -837,7 +837,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
+ 		return true;	 /* already a holder */
+ 	else if (bdev->bd_holder != NULL)
+ 		return false; 	 /* held by someone else */
+-	else if (bdev->bd_contains == bdev)
++	else if (whole == bdev)
+ 		return true;  	 /* is a whole device which isn't held */
+ 
+ 	else if (whole->bd_holder == bd_may_claim)
+diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
+index e0f071f6b5a7..63d197724519 100644
+--- a/fs/btrfs/async-thread.c
++++ b/fs/btrfs/async-thread.c
+@@ -86,6 +86,20 @@ btrfs_work_owner(struct btrfs_work *work)
+ 	return work->wq->fs_info;
+ }
+ 
++bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq)
++{
++	/*
++	 * We could compare wq->normal->pending with num_online_cpus()
++	 * to support "thresh == NO_THRESHOLD" case, but it requires
++	 * moving up atomic_inc/dec in thresh_queue/exec_hook. Let's
++	 * postpone it until someone needs the support of that case.
++	 */
++	if (wq->normal->thresh == NO_THRESHOLD)
++		return false;
++
++	return atomic_read(&wq->normal->pending) > wq->normal->thresh * 2;
++}
++
+ BTRFS_WORK_HELPER(worker_helper);
+ BTRFS_WORK_HELPER(delalloc_helper);
+ BTRFS_WORK_HELPER(flush_delalloc_helper);
+diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h
+index 8e52484cd461..1f9597355c9d 100644
+--- a/fs/btrfs/async-thread.h
++++ b/fs/btrfs/async-thread.h
+@@ -84,4 +84,5 @@ void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
+ void btrfs_set_work_high_priority(struct btrfs_work *work);
+ struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work);
+ struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq);
++bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq);
+ #endif
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 791e47ce9d27..469fa3268d9b 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2210,6 +2210,8 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu,
+ 	cpu->target = le64_to_cpu(disk->target);
+ 	cpu->flags = le64_to_cpu(disk->flags);
+ 	cpu->limit = le64_to_cpu(disk->limit);
++	cpu->stripes_min = le32_to_cpu(disk->stripes_min);
++	cpu->stripes_max = le32_to_cpu(disk->stripes_max);
+ }
+ 
+ static inline void
+@@ -2228,6 +2230,8 @@ btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk,
+ 	disk->target = cpu_to_le64(cpu->target);
+ 	disk->flags = cpu_to_le64(cpu->flags);
+ 	disk->limit = cpu_to_le64(cpu->limit);
++	disk->stripes_min = cpu_to_le32(cpu->stripes_min);
++	disk->stripes_max = cpu_to_le32(cpu->stripes_max);
+ }
+ 
+ /* struct btrfs_super_block */
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 3eeb9cd8cfa5..de946dd743b7 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1356,7 +1356,8 @@ release_path:
+ 	total_done++;
+ 
+ 	btrfs_release_prepared_delayed_node(delayed_node);
+-	if (async_work->nr == 0 || total_done < async_work->nr)
++	if ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK) ||
++	    total_done < async_work->nr)
+ 		goto again;
+ 
+ free_path:
+@@ -1372,7 +1373,8 @@ static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
+ {
+ 	struct btrfs_async_delayed_work *async_work;
+ 
+-	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
++	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND ||
++	    btrfs_workqueue_normal_congested(fs_info->delayed_workers))
+ 		return 0;
+ 
+ 	async_work = kmalloc(sizeof(*async_work), GFP_NOFS);
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 3dede6d53bad..dafcfd017d37 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -559,7 +559,15 @@ static noinline int check_leaf(struct btrfs_root *root,
+ 	u32 nritems = btrfs_header_nritems(leaf);
+ 	int slot;
+ 
+-	if (nritems == 0) {
++	/*
++	 * Extent buffers from a relocation tree have a owner field that
++	 * corresponds to the subvolume tree they are based on. So just from an
++	 * extent buffer alone we can not find out what is the id of the
++	 * corresponding subvolume tree, so we can not figure out if the extent
++	 * buffer corresponds to the root of the relocation tree or not. So skip
++	 * this check for relocation trees.
++	 */
++	if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) {
+ 		struct btrfs_root *check_root;
+ 
+ 		key.objectid = btrfs_header_owner(leaf);
+@@ -572,17 +580,24 @@ static noinline int check_leaf(struct btrfs_root *root,
+ 		 * open_ctree() some roots has not yet been set up.
+ 		 */
+ 		if (!IS_ERR_OR_NULL(check_root)) {
++			struct extent_buffer *eb;
++
++			eb = btrfs_root_node(check_root);
+ 			/* if leaf is the root, then it's fine */
+-			if (leaf->start !=
+-			    btrfs_root_bytenr(&check_root->root_item)) {
++			if (leaf != eb) {
+ 				CORRUPT("non-root leaf's nritems is 0",
+-					leaf, root, 0);
++					leaf, check_root, 0);
++				free_extent_buffer(eb);
+ 				return -EIO;
+ 			}
++			free_extent_buffer(eb);
+ 		}
+ 		return 0;
+ 	}
+ 
++	if (nritems == 0)
++		return 0;
++
+ 	/* Check the 0 item */
+ 	if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
+ 	    BTRFS_LEAF_DATA_SIZE(root)) {
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 665da8f66ff1..a1b40ab5770a 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -8884,14 +8884,13 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
+ 	ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1,
+ 				       &wc->refs[level - 1],
+ 				       &wc->flags[level - 1]);
+-	if (ret < 0) {
+-		btrfs_tree_unlock(next);
+-		return ret;
+-	}
++	if (ret < 0)
++		goto out_unlock;
+ 
+ 	if (unlikely(wc->refs[level - 1] == 0)) {
+ 		btrfs_err(root->fs_info, "Missing references.");
+-		BUG();
++		ret = -EIO;
++		goto out_unlock;
+ 	}
+ 	*lookup_info = 0;
+ 
+@@ -8943,7 +8942,12 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
+ 	}
+ 
+ 	level--;
+-	BUG_ON(level != btrfs_header_level(next));
++	ASSERT(level == btrfs_header_level(next));
++	if (level != btrfs_header_level(next)) {
++		btrfs_err(root->fs_info, "mismatched level");
++		ret = -EIO;
++		goto out_unlock;
++	}
+ 	path->nodes[level] = next;
+ 	path->slots[level] = 0;
+ 	path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
+@@ -8958,8 +8962,15 @@ skip:
+ 		if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
+ 			parent = path->nodes[level]->start;
+ 		} else {
+-			BUG_ON(root->root_key.objectid !=
++			ASSERT(root->root_key.objectid ==
+ 			       btrfs_header_owner(path->nodes[level]));
++			if (root->root_key.objectid !=
++			    btrfs_header_owner(path->nodes[level])) {
++				btrfs_err(root->fs_info,
++						"mismatched block owner");
++				ret = -EIO;
++				goto out_unlock;
++			}
+ 			parent = 0;
+ 		}
+ 
+@@ -8976,12 +8987,18 @@ skip:
+ 		}
+ 		ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
+ 				root->root_key.objectid, level - 1, 0);
+-		BUG_ON(ret); /* -ENOMEM */
++		if (ret)
++			goto out_unlock;
+ 	}
++
++	*lookup_info = 1;
++	ret = 1;
++
++out_unlock:
+ 	btrfs_tree_unlock(next);
+ 	free_extent_buffer(next);
+-	*lookup_info = 1;
+-	return 1;
++
++	return ret;
+ }
+ 
+ /*
+@@ -10127,6 +10144,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
+ 	struct extent_buffer *leaf;
+ 	int need_clear = 0;
+ 	u64 cache_gen;
++	u64 feature;
++	int mixed;
++
++	feature = btrfs_super_incompat_flags(info->super_copy);
++	mixed = !!(feature & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS);
+ 
+ 	root = info->extent_root;
+ 	key.objectid = 0;
+@@ -10180,6 +10202,15 @@ int btrfs_read_block_groups(struct btrfs_root *root)
+ 				   btrfs_item_ptr_offset(leaf, path->slots[0]),
+ 				   sizeof(cache->item));
+ 		cache->flags = btrfs_block_group_flags(&cache->item);
++		if (!mixed &&
++		    ((cache->flags & BTRFS_BLOCK_GROUP_METADATA) &&
++		    (cache->flags & BTRFS_BLOCK_GROUP_DATA))) {
++			btrfs_err(info,
++"bg %llu is a mixed block group but filesystem hasn't enabled mixed block groups",
++				  cache->key.objectid);
++			ret = -EINVAL;
++			goto error;
++		}
+ 
+ 		key.objectid = found_key.objectid + found_key.offset;
+ 		btrfs_release_path(path);
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index c3ec30dea9a5..3f9a6b40fbbd 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -5209,11 +5209,20 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
+ 			lock_page(page);
+ 		}
+ 		locked_pages++;
++	}
++	/*
++	 * We need to firstly lock all pages to make sure that
++	 * the uptodate bit of our pages won't be affected by
++	 * clear_extent_buffer_uptodate().
++	 */
++	for (i = start_i; i < num_pages; i++) {
++		page = eb->pages[i];
+ 		if (!PageUptodate(page)) {
+ 			num_reads++;
+ 			all_uptodate = 0;
+ 		}
+ 	}
++
+ 	if (all_uptodate) {
+ 		if (start_i == 0)
+ 			set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 7fd939bfbd99..fcd2b3be21bf 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3813,6 +3813,11 @@ process_slot:
+ 		}
+ 		btrfs_release_path(path);
+ 		key.offset = next_key_min_offset;
++
++		if (fatal_signal_pending(current)) {
++			ret = -EINTR;
++			goto out;
++		}
+ 	}
+ 	ret = 0;
+ 
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 8db2e29fdcf4..9cf03ebb27cc 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -2332,10 +2332,6 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
+ 	int err = -ENOMEM;
+ 	int ret = 0;
+ 
+-	mutex_lock(&fs_info->qgroup_rescan_lock);
+-	fs_info->qgroup_rescan_running = true;
+-	mutex_unlock(&fs_info->qgroup_rescan_lock);
+-
+ 	path = btrfs_alloc_path();
+ 	if (!path)
+ 		goto out;
+@@ -2446,6 +2442,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
+ 		sizeof(fs_info->qgroup_rescan_progress));
+ 	fs_info->qgroup_rescan_progress.objectid = progress_objectid;
+ 	init_completion(&fs_info->qgroup_rescan_completion);
++	fs_info->qgroup_rescan_running = true;
+ 
+ 	spin_unlock(&fs_info->qgroup_lock);
+ 	mutex_unlock(&fs_info->qgroup_rescan_lock);
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index c0c13dc6fe12..d08a79dbf323 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -923,9 +923,16 @@ again:
+ 			path2->slots[level]--;
+ 
+ 		eb = path2->nodes[level];
+-		WARN_ON(btrfs_node_blockptr(eb, path2->slots[level]) !=
+-			cur->bytenr);
+-
++		if (btrfs_node_blockptr(eb, path2->slots[level]) !=
++		    cur->bytenr) {
++			btrfs_err(root->fs_info,
++	"couldn't find block (%llu) (level %d) in tree (%llu) with key (%llu %u %llu)",
++				  cur->bytenr, level - 1, root->objectid,
++				  node_key->objectid, node_key->type,
++				  node_key->offset);
++			err = -ENOENT;
++			goto out;
++		}
+ 		lower = cur;
+ 		need_check = true;
+ 		for (; level < BTRFS_MAX_LEVEL; level++) {
+@@ -1387,14 +1394,23 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+ 	root_key.offset = objectid;
+ 
+ 	if (root->root_key.objectid == objectid) {
++		u64 commit_root_gen;
++
+ 		/* called by btrfs_init_reloc_root */
+ 		ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
+ 				      BTRFS_TREE_RELOC_OBJECTID);
+ 		BUG_ON(ret);
+-
+ 		last_snap = btrfs_root_last_snapshot(&root->root_item);
+-		btrfs_set_root_last_snapshot(&root->root_item,
+-					     trans->transid - 1);
++		/*
++		 * Set the last_snapshot field to the generation of the commit
++		 * root - like this ctree.c:btrfs_block_can_be_shared() behaves
++		 * correctly (returns true) when the relocation root is created
++		 * either inside the critical section of a transaction commit
++		 * (through transaction.c:qgroup_account_snapshot()) and when
++		 * it's created before the transaction commit is started.
++		 */
++		commit_root_gen = btrfs_header_generation(root->commit_root);
++		btrfs_set_root_last_snapshot(&root->root_item, commit_root_gen);
+ 	} else {
+ 		/*
+ 		 * called by btrfs_reloc_post_snapshot_hook.
+@@ -2350,6 +2366,10 @@ void free_reloc_roots(struct list_head *list)
+ 	while (!list_empty(list)) {
+ 		reloc_root = list_entry(list->next, struct btrfs_root,
+ 					root_list);
++		free_extent_buffer(reloc_root->node);
++		free_extent_buffer(reloc_root->commit_root);
++		reloc_root->node = NULL;
++		reloc_root->commit_root = NULL;
+ 		__del_reloc_root(reloc_root);
+ 	}
+ }
+@@ -2686,11 +2706,15 @@ static int do_relocation(struct btrfs_trans_handle *trans,
+ 
+ 		if (!upper->eb) {
+ 			ret = btrfs_search_slot(trans, root, key, path, 0, 1);
+-			if (ret < 0) {
+-				err = ret;
++			if (ret) {
++				if (ret < 0)
++					err = ret;
++				else
++					err = -ENOENT;
++
++				btrfs_release_path(path);
+ 				break;
+ 			}
+-			BUG_ON(ret > 0);
+ 
+ 			if (!upper->eb) {
+ 				upper->eb = path->nodes[upper->level];
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index a87675ffd02b..563878a141a3 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5802,6 +5802,64 @@ static int changed_extent(struct send_ctx *sctx,
+ 	int ret = 0;
+ 
+ 	if (sctx->cur_ino != sctx->cmp_key->objectid) {
++
++		if (result == BTRFS_COMPARE_TREE_CHANGED) {
++			struct extent_buffer *leaf_l;
++			struct extent_buffer *leaf_r;
++			struct btrfs_file_extent_item *ei_l;
++			struct btrfs_file_extent_item *ei_r;
++
++			leaf_l = sctx->left_path->nodes[0];
++			leaf_r = sctx->right_path->nodes[0];
++			ei_l = btrfs_item_ptr(leaf_l,
++					      sctx->left_path->slots[0],
++					      struct btrfs_file_extent_item);
++			ei_r = btrfs_item_ptr(leaf_r,
++					      sctx->right_path->slots[0],
++					      struct btrfs_file_extent_item);
++
++			/*
++			 * We may have found an extent item that has changed
++			 * only its disk_bytenr field and the corresponding
++			 * inode item was not updated. This case happens due to
++			 * very specific timings during relocation when a leaf
++			 * that contains file extent items is COWed while
++			 * relocation is ongoing and its in the stage where it
++			 * updates data pointers. So when this happens we can
++			 * safely ignore it since we know it's the same extent,
++			 * but just at different logical and physical locations
++			 * (when an extent is fully replaced with a new one, we
++			 * know the generation number must have changed too,
++			 * since snapshot creation implies committing the current
++			 * transaction, and the inode item must have been updated
++			 * as well).
++			 * This replacement of the disk_bytenr happens at
++			 * relocation.c:replace_file_extents() through
++			 * relocation.c:btrfs_reloc_cow_block().
++			 */
++			if (btrfs_file_extent_generation(leaf_l, ei_l) ==
++			    btrfs_file_extent_generation(leaf_r, ei_r) &&
++			    btrfs_file_extent_ram_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_ram_bytes(leaf_r, ei_r) &&
++			    btrfs_file_extent_compression(leaf_l, ei_l) ==
++			    btrfs_file_extent_compression(leaf_r, ei_r) &&
++			    btrfs_file_extent_encryption(leaf_l, ei_l) ==
++			    btrfs_file_extent_encryption(leaf_r, ei_r) &&
++			    btrfs_file_extent_other_encoding(leaf_l, ei_l) ==
++			    btrfs_file_extent_other_encoding(leaf_r, ei_r) &&
++			    btrfs_file_extent_type(leaf_l, ei_l) ==
++			    btrfs_file_extent_type(leaf_r, ei_r) &&
++			    btrfs_file_extent_disk_bytenr(leaf_l, ei_l) !=
++			    btrfs_file_extent_disk_bytenr(leaf_r, ei_r) &&
++			    btrfs_file_extent_disk_num_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_disk_num_bytes(leaf_r, ei_r) &&
++			    btrfs_file_extent_offset(leaf_l, ei_l) ==
++			    btrfs_file_extent_offset(leaf_r, ei_r) &&
++			    btrfs_file_extent_num_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_num_bytes(leaf_r, ei_r))
++				return 0;
++		}
++
+ 		inconsistent_snapshot_error(sctx, result, "extent");
+ 		return -EIO;
+ 	}
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 90e1198bc63d..e63c96ca0e96 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -1940,12 +1940,11 @@ static noinline int find_dir_range(struct btrfs_root *root,
+ next:
+ 	/* check the next slot in the tree to see if it is a valid item */
+ 	nritems = btrfs_header_nritems(path->nodes[0]);
++	path->slots[0]++;
+ 	if (path->slots[0] >= nritems) {
+ 		ret = btrfs_next_leaf(root, path);
+ 		if (ret)
+ 			goto out;
+-	} else {
+-		path->slots[0]++;
+ 	}
+ 
+ 	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+@@ -5205,6 +5204,7 @@ process_leaf:
+ 			if (di_key.type == BTRFS_ROOT_ITEM_KEY)
+ 				continue;
+ 
++			btrfs_release_path(path);
+ 			di_inode = btrfs_iget(root->fs_info->sb, &di_key,
+ 					      root, NULL);
+ 			if (IS_ERR(di_inode)) {
+@@ -5214,13 +5214,12 @@ process_leaf:
+ 
+ 			if (btrfs_inode_in_log(di_inode, trans->transid)) {
+ 				iput(di_inode);
+-				continue;
++				break;
+ 			}
+ 
+ 			ctx->log_new_dentries = false;
+ 			if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
+ 				log_mode = LOG_INODE_ALL;
+-			btrfs_release_path(path);
+ 			ret = btrfs_log_inode(trans, root, di_inode,
+ 					      log_mode, 0, LLONG_MAX, ctx);
+ 			if (!ret &&
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 035efce603a9..7c9c6a4be4fd 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -859,7 +859,7 @@ static void btrfs_close_bdev(struct btrfs_device *device)
+ 		blkdev_put(device->bdev, device->mode);
+ }
+ 
+-static void btrfs_close_one_device(struct btrfs_device *device)
++static void btrfs_prepare_close_one_device(struct btrfs_device *device)
+ {
+ 	struct btrfs_fs_devices *fs_devices = device->fs_devices;
+ 	struct btrfs_device *new_device;
+@@ -877,8 +877,6 @@ static void btrfs_close_one_device(struct btrfs_device *device)
+ 	if (device->missing)
+ 		fs_devices->missing_devices--;
+ 
+-	btrfs_close_bdev(device);
+-
+ 	new_device = btrfs_alloc_device(NULL, &device->devid,
+ 					device->uuid);
+ 	BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
+@@ -892,23 +890,39 @@ static void btrfs_close_one_device(struct btrfs_device *device)
+ 
+ 	list_replace_rcu(&device->dev_list, &new_device->dev_list);
+ 	new_device->fs_devices = device->fs_devices;
+-
+-	call_rcu(&device->rcu, free_device);
+ }
+ 
+ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
+ {
+ 	struct btrfs_device *device, *tmp;
++	struct list_head pending_put;
++
++	INIT_LIST_HEAD(&pending_put);
+ 
+ 	if (--fs_devices->opened > 0)
+ 		return 0;
+ 
+ 	mutex_lock(&fs_devices->device_list_mutex);
+ 	list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
+-		btrfs_close_one_device(device);
++		btrfs_prepare_close_one_device(device);
++		list_add(&device->dev_list, &pending_put);
+ 	}
+ 	mutex_unlock(&fs_devices->device_list_mutex);
+ 
++	/*
++	 * btrfs_show_devname() is using the device_list_mutex,
++	 * sometimes call to blkdev_put() leads vfs calling
++	 * into this func. So do put outside of device_list_mutex,
++	 * as of now.
++	 */
++	while (!list_empty(&pending_put)) {
++		device = list_first_entry(&pending_put,
++				struct btrfs_device, dev_list);
++		list_del(&device->dev_list);
++		btrfs_close_bdev(device);
++		call_rcu(&device->rcu, free_device);
++	}
++
+ 	WARN_ON(fs_devices->open_devices);
+ 	WARN_ON(fs_devices->rw_devices);
+ 	fs_devices->opened = 0;
+@@ -1846,7 +1860,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 	u64 num_devices;
+ 	int ret = 0;
+ 	bool clear_super = false;
+-	char *dev_name = NULL;
+ 
+ 	mutex_lock(&uuid_mutex);
+ 
+@@ -1882,11 +1895,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 		list_del_init(&device->dev_alloc_list);
+ 		device->fs_devices->rw_devices--;
+ 		unlock_chunks(root);
+-		dev_name = kstrdup(device->name->str, GFP_KERNEL);
+-		if (!dev_name) {
+-			ret = -ENOMEM;
+-			goto error_undo;
+-		}
+ 		clear_super = true;
+ 	}
+ 
+@@ -1936,14 +1944,21 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 		btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
+ 	}
+ 
+-	btrfs_close_bdev(device);
+-
+-	call_rcu(&device->rcu, free_device);
+-
+ 	num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
+ 	btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices);
+ 	mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+ 
++	/*
++	 * at this point, the device is zero sized and detached from
++	 * the devices list.  All that's left is to zero out the old
++	 * supers and free the device.
++	 */
++	if (device->writeable)
++		btrfs_scratch_superblocks(device->bdev, device->name->str);
++
++	btrfs_close_bdev(device);
++	call_rcu(&device->rcu, free_device);
++
+ 	if (cur_devices->open_devices == 0) {
+ 		struct btrfs_fs_devices *fs_devices;
+ 		fs_devices = root->fs_info->fs_devices;
+@@ -1962,24 +1977,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 	root->fs_info->num_tolerated_disk_barrier_failures =
+ 		btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
+ 
+-	/*
+-	 * at this point, the device is zero sized.  We want to
+-	 * remove it from the devices list and zero out the old super
+-	 */
+-	if (clear_super) {
+-		struct block_device *bdev;
+-
+-		bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
+-						root->fs_info->bdev_holder);
+-		if (!IS_ERR(bdev)) {
+-			btrfs_scratch_superblocks(bdev, dev_name);
+-			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
+-		}
+-	}
+-
+ out:
+-	kfree(dev_name);
+-
+ 	mutex_unlock(&uuid_mutex);
+ 	return ret;
+ 
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 65f78b7a9062..24184cae83d2 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -629,6 +629,8 @@ struct TCP_Server_Info {
+ 	unsigned int	max_read;
+ 	unsigned int	max_write;
+ 	__u8		preauth_hash[512];
++	struct delayed_work reconnect; /* reconnect workqueue job */
++	struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
+ #endif /* CONFIG_CIFS_SMB2 */
+ 	unsigned long echo_interval;
+ };
+@@ -832,6 +834,7 @@ cap_unix(struct cifs_ses *ses)
+ struct cifs_tcon {
+ 	struct list_head tcon_list;
+ 	int tc_count;
++	struct list_head rlist; /* reconnect list */
+ 	struct list_head openFileList;
+ 	spinlock_t open_file_lock; /* protects list above */
+ 	struct cifs_ses *ses;	/* pointer to session associated with */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 95dab43646f0..ca76f8a7267f 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -204,6 +204,9 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid,
+ 					 struct tcon_link *tlink,
+ 					 struct cifs_pending_open *open);
+ extern void cifs_del_pending_open(struct cifs_pending_open *open);
++extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
++				 int from_reconnect);
++extern void cifs_put_tcon(struct cifs_tcon *tcon);
+ 
+ #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
+ extern void cifs_dfs_release_automount_timer(void);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 7b67179521cf..a178f3a5b052 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -52,6 +52,9 @@
+ #include "nterr.h"
+ #include "rfc1002pdu.h"
+ #include "fscache.h"
++#ifdef CONFIG_CIFS_SMB2
++#include "smb2proto.h"
++#endif
+ 
+ #define CIFS_PORT 445
+ #define RFC1001_PORT 139
+@@ -2076,8 +2079,8 @@ cifs_find_tcp_session(struct smb_vol *vol)
+ 	return NULL;
+ }
+ 
+-static void
+-cifs_put_tcp_session(struct TCP_Server_Info *server)
++void
++cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ {
+ 	struct task_struct *task;
+ 
+@@ -2094,6 +2097,19 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
+ 
+ 	cancel_delayed_work_sync(&server->echo);
+ 
++#ifdef CONFIG_CIFS_SMB2
++	if (from_reconnect)
++		/*
++		 * Avoid deadlock here: reconnect work calls
++		 * cifs_put_tcp_session() at its end. Need to be sure
++		 * that reconnect work does nothing with server pointer after
++		 * that step.
++		 */
++		cancel_delayed_work(&server->reconnect);
++	else
++		cancel_delayed_work_sync(&server->reconnect);
++#endif
++
+ 	spin_lock(&GlobalMid_Lock);
+ 	server->tcpStatus = CifsExiting;
+ 	spin_unlock(&GlobalMid_Lock);
+@@ -2158,6 +2174,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
+ 	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
+ 	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+ 	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
++#ifdef CONFIG_CIFS_SMB2
++	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
++	mutex_init(&tcp_ses->reconnect_mutex);
++#endif
+ 	memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
+ 	       sizeof(tcp_ses->srcaddr));
+ 	memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
+@@ -2316,7 +2336,7 @@ cifs_put_smb_ses(struct cifs_ses *ses)
+ 	spin_unlock(&cifs_tcp_ses_lock);
+ 
+ 	sesInfoFree(ses);
+-	cifs_put_tcp_session(server);
++	cifs_put_tcp_session(server, 0);
+ }
+ 
+ #ifdef CONFIG_KEYS
+@@ -2490,7 +2510,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
+ 		mutex_unlock(&ses->session_mutex);
+ 
+ 		/* existing SMB ses has a server reference already */
+-		cifs_put_tcp_session(server);
++		cifs_put_tcp_session(server, 0);
+ 		free_xid(xid);
+ 		return ses;
+ 	}
+@@ -2580,7 +2600,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc)
+ 	return NULL;
+ }
+ 
+-static void
++void
+ cifs_put_tcon(struct cifs_tcon *tcon)
+ {
+ 	unsigned int xid;
+@@ -3762,7 +3782,7 @@ mount_fail_check:
+ 		else if (ses)
+ 			cifs_put_smb_ses(ses);
+ 		else
+-			cifs_put_tcp_session(server);
++			cifs_put_tcp_session(server, 0);
+ 		bdi_destroy(&cifs_sb->bdi);
+ 	}
+ 
+@@ -4073,7 +4093,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
+ 	ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
+ 	if (IS_ERR(ses)) {
+ 		tcon = (struct cifs_tcon *)ses;
+-		cifs_put_tcp_session(master_tcon->ses->server);
++		cifs_put_tcp_session(master_tcon->ses->server, 0);
+ 		goto out;
+ 	}
+ 
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index f9e766f464be..b2aff0c6f22c 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -260,7 +260,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
+ 	 * and check it for zero before using.
+ 	 */
+ 	max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
+-	if (!max_buf) {
++	if (max_buf < sizeof(struct smb2_lock_element)) {
+ 		free_xid(xid);
+ 		return -EINVAL;
+ 	}
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 3eec96ca87d9..32e0e06f972c 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -275,7 +275,7 @@ out:
+ 	case SMB2_CHANGE_NOTIFY:
+ 	case SMB2_QUERY_INFO:
+ 	case SMB2_SET_INFO:
+-		return -EAGAIN;
++		rc = -EAGAIN;
+ 	}
+ 	unload_nls(nls_codepage);
+ 	return rc;
+@@ -1820,6 +1820,54 @@ smb2_echo_callback(struct mid_q_entry *mid)
+ 	add_credits(server, credits_received, CIFS_ECHO_OP);
+ }
+ 
++void smb2_reconnect_server(struct work_struct *work)
++{
++	struct TCP_Server_Info *server = container_of(work,
++					struct TCP_Server_Info, reconnect.work);
++	struct cifs_ses *ses;
++	struct cifs_tcon *tcon, *tcon2;
++	struct list_head tmp_list;
++	int tcon_exist = false;
++
++	/* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
++	mutex_lock(&server->reconnect_mutex);
++
++	INIT_LIST_HEAD(&tmp_list);
++	cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
++
++	spin_lock(&cifs_tcp_ses_lock);
++	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
++			if (tcon->need_reconnect) {
++				tcon->tc_count++;
++				list_add_tail(&tcon->rlist, &tmp_list);
++				tcon_exist = true;
++			}
++		}
++	}
++	/*
++	 * Get the reference to server struct to be sure that the last call of
++	 * cifs_put_tcon() in the loop below won't release the server pointer.
++	 */
++	if (tcon_exist)
++		server->srv_count++;
++
++	spin_unlock(&cifs_tcp_ses_lock);
++
++	list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
++		smb2_reconnect(SMB2_ECHO, tcon);
++		list_del_init(&tcon->rlist);
++		cifs_put_tcon(tcon);
++	}
++
++	cifs_dbg(FYI, "Reconnecting tcons finished\n");
++	mutex_unlock(&server->reconnect_mutex);
++
++	/* now we can safely release srv struct */
++	if (tcon_exist)
++		cifs_put_tcp_session(server, 1);
++}
++
+ int
+ SMB2_echo(struct TCP_Server_Info *server)
+ {
+@@ -1832,32 +1880,11 @@ SMB2_echo(struct TCP_Server_Info *server)
+ 	cifs_dbg(FYI, "In echo request\n");
+ 
+ 	if (server->tcpStatus == CifsNeedNegotiate) {
+-		struct list_head *tmp, *tmp2;
+-		struct cifs_ses *ses;
+-		struct cifs_tcon *tcon;
+-
+-		cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+-		spin_lock(&cifs_tcp_ses_lock);
+-		list_for_each(tmp, &server->smb_ses_list) {
+-			ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+-			list_for_each(tmp2, &ses->tcon_list) {
+-				tcon = list_entry(tmp2, struct cifs_tcon,
+-						  tcon_list);
+-				/* add check for persistent handle reconnect */
+-				if (tcon && tcon->need_reconnect) {
+-					spin_unlock(&cifs_tcp_ses_lock);
+-					rc = smb2_reconnect(SMB2_ECHO, tcon);
+-					spin_lock(&cifs_tcp_ses_lock);
+-				}
+-			}
+-		}
+-		spin_unlock(&cifs_tcp_ses_lock);
++		/* No need to send echo on newly established connections */
++		queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++		return rc;
+ 	}
+ 
+-	/* if no session, renegotiate failed above */
+-	if (server->tcpStatus == CifsNeedNegotiate)
+-		return -EIO;
+-
+ 	rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
+ 	if (rc)
+ 		return rc;
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
+index eb2cde2f64ba..f2d511a6971b 100644
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned int xid,
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+ 			     struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
++extern void smb2_reconnect_server(struct work_struct *work);
+ 
+ /*
+  * SMB2 Worker functions - most of protocol specific implementation details
+diff --git a/fs/exec.c b/fs/exec.c
+index 6fcfb3f7b137..eebe8be7a29d 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -19,7 +19,7 @@
+  * current->executable is only used by the procfs.  This allows a dispatch
+  * table to check for several different types  of binary formats.  We keep
+  * trying until we recognize the file or we run out of supported binary
+- * formats. 
++ * formats.
+  */
+ 
+ #include <linux/slab.h>
+@@ -1261,6 +1261,13 @@ int flush_old_exec(struct linux_binprm * bprm)
+ 	flush_thread();
+ 	current->personality &= ~bprm->per_clear;
+ 
++	/*
++	 * We have to apply CLOEXEC before we change whether the process is
++	 * dumpable (in setup_new_exec) to avoid a race with a process in userspace
++	 * trying to access the should-be-closed file descriptors of a process
++	 * undergoing exec(2).
++	 */
++	do_close_on_exec(current->files);
+ 	return 0;
+ 
+ out:
+@@ -1270,8 +1277,22 @@ EXPORT_SYMBOL(flush_old_exec);
+ 
+ void would_dump(struct linux_binprm *bprm, struct file *file)
+ {
+-	if (inode_permission(file_inode(file), MAY_READ) < 0)
++	struct inode *inode = file_inode(file);
++	if (inode_permission(inode, MAY_READ) < 0) {
++		struct user_namespace *old, *user_ns;
+ 		bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
++
++		/* Ensure mm->user_ns contains the executable */
++		user_ns = old = bprm->mm->user_ns;
++		while ((user_ns != &init_user_ns) &&
++		       !privileged_wrt_inode_uidgid(user_ns, inode))
++			user_ns = user_ns->parent;
++
++		if (old != user_ns) {
++			bprm->mm->user_ns = get_user_ns(user_ns);
++			put_user_ns(old);
++		}
++	}
+ }
+ EXPORT_SYMBOL(would_dump);
+ 
+@@ -1301,7 +1322,6 @@ void setup_new_exec(struct linux_binprm * bprm)
+ 	    !gid_eq(bprm->cred->gid, current_egid())) {
+ 		current->pdeath_signal = 0;
+ 	} else {
+-		would_dump(bprm, bprm->file);
+ 		if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
+ 			set_dumpable(current->mm, suid_dumpable);
+ 	}
+@@ -1310,7 +1330,6 @@ void setup_new_exec(struct linux_binprm * bprm)
+ 	   group */
+ 	current->self_exec_id++;
+ 	flush_signal_handlers(current, 0);
+-	do_close_on_exec(current->files);
+ }
+ EXPORT_SYMBOL(setup_new_exec);
+ 
+@@ -1401,7 +1420,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
+ 	unsigned n_fs;
+ 
+ 	if (p->ptrace) {
+-		if (p->ptrace & PT_PTRACE_CAP)
++		if (ptracer_capable(p, current_user_ns()))
+ 			bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
+ 		else
+ 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
+@@ -1736,6 +1755,8 @@ static int do_execveat_common(int fd, struct filename *filename,
+ 	if (retval < 0)
+ 		goto out;
+ 
++	would_dump(bprm, bprm->file);
++
+ 	retval = exec_binprm(bprm);
+ 	if (retval < 0)
+ 		goto out;
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
+index b1d52c14098e..f97611171023 100644
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -414,17 +414,19 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
+ 		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+ 	/* We do not support data journalling with delayed allocation */
+ 	if (!S_ISREG(inode->i_mode) ||
+-	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+-		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
+-	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
+-	    !test_opt(inode->i_sb, DELALLOC))
++	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
++	    (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
++	    !test_opt(inode->i_sb, DELALLOC))) {
++		/* We do not support data journalling for encrypted data */
++		if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode))
++			return EXT4_INODE_ORDERED_DATA_MODE;  /* ordered */
+ 		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
++	}
+ 	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+ 		return EXT4_INODE_ORDERED_DATA_MODE;	/* ordered */
+ 	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+ 		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+-	else
+-		BUG();
++	BUG();
+ }
+ 
+ static inline int ext4_should_journal_data(struct inode *inode)
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index f74d5ee2cdec..d8ca4b9f9dd6 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -336,8 +336,10 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
+ 
+ 	len -= EXT4_MIN_INLINE_DATA_SIZE;
+ 	value = kzalloc(len, GFP_NOFS);
+-	if (!value)
++	if (!value) {
++		error = -ENOMEM;
+ 		goto out;
++	}
+ 
+ 	error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
+ 				     value, len);
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index f4cdc647ecfc..27e4348efc4e 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4438,6 +4438,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ 	struct inode *inode;
+ 	journal_t *journal = EXT4_SB(sb)->s_journal;
+ 	long ret;
++	loff_t size;
+ 	int block;
+ 	uid_t i_uid;
+ 	gid_t i_gid;
+@@ -4538,6 +4539,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ 		ei->i_file_acl |=
+ 			((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
+ 	inode->i_size = ext4_isize(raw_inode);
++	if ((size = i_size_read(inode)) < 0) {
++		EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size);
++		ret = -EFSCORRUPTED;
++		goto bad_inode;
++	}
+ 	ei->i_disksize = inode->i_size;
+ #ifdef CONFIG_QUOTA
+ 	ei->i_reserved_quota = 0;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index f418f55c2bbe..7ae43c59bc79 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -669,7 +669,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
+ 	ext4_grpblk_t min;
+ 	ext4_grpblk_t max;
+ 	ext4_grpblk_t chunk;
+-	unsigned short border;
++	unsigned int border;
+ 
+ 	BUG_ON(len > EXT4_CLUSTERS_PER_GROUP(sb));
+ 
+@@ -2287,7 +2287,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
+ 	struct ext4_group_info *grinfo;
+ 	struct sg {
+ 		struct ext4_group_info info;
+-		ext4_grpblk_t counters[16];
++		ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2];
+ 	} sg;
+ 
+ 	group--;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index ec89f5005c2d..d0d4377680c7 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3161,10 +3161,15 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
+ 			ext4_set_bit(s++, buf);
+ 			count++;
+ 		}
+-		for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) {
+-			ext4_set_bit(EXT4_B2C(sbi, s++), buf);
+-			count++;
++		j = ext4_bg_num_gdb(sb, grp);
++		if (s + j > EXT4_BLOCKS_PER_GROUP(sb)) {
++			ext4_error(sb, "Invalid number of block group "
++				   "descriptor blocks: %d", j);
++			j = EXT4_BLOCKS_PER_GROUP(sb) - s;
+ 		}
++		count += j;
++		for (; j > 0; j--)
++			ext4_set_bit(EXT4_B2C(sbi, s++), buf);
+ 	}
+ 	if (!count)
+ 		return 0;
+@@ -3254,7 +3259,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	char *orig_data = kstrdup(data, GFP_KERNEL);
+ 	struct buffer_head *bh;
+ 	struct ext4_super_block *es = NULL;
+-	struct ext4_sb_info *sbi;
++	struct ext4_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ 	ext4_fsblk_t block;
+ 	ext4_fsblk_t sb_block = get_sb_block(&data);
+ 	ext4_fsblk_t logical_sb_block;
+@@ -3273,16 +3278,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
+ 	ext4_group_t first_not_zeroed;
+ 
+-	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+-	if (!sbi)
+-		goto out_free_orig;
++	if ((data && !orig_data) || !sbi)
++		goto out_free_base;
+ 
+ 	sbi->s_blockgroup_lock =
+ 		kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
+-	if (!sbi->s_blockgroup_lock) {
+-		kfree(sbi);
+-		goto out_free_orig;
+-	}
++	if (!sbi->s_blockgroup_lock)
++		goto out_free_base;
++
+ 	sb->s_fs_info = sbi;
+ 	sbi->s_sb = sb;
+ 	sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS;
+@@ -3428,11 +3431,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	 */
+ 	sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
+ 
+-	if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
+-			   &journal_devnum, &journal_ioprio, 0)) {
+-		ext4_msg(sb, KERN_WARNING,
+-			 "failed to parse options in superblock: %s",
+-			 sbi->s_es->s_mount_opts);
++	if (sbi->s_es->s_mount_opts[0]) {
++		char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts,
++					      sizeof(sbi->s_es->s_mount_opts),
++					      GFP_KERNEL);
++		if (!s_mount_opts)
++			goto failed_mount;
++		if (!parse_options(s_mount_opts, sb, &journal_devnum,
++				   &journal_ioprio, 0)) {
++			ext4_msg(sb, KERN_WARNING,
++				 "failed to parse options in superblock: %s",
++				 s_mount_opts);
++		}
++		kfree(s_mount_opts);
+ 	}
+ 	sbi->s_def_mount_opt = sbi->s_mount_opt;
+ 	if (!parse_options((char *) data, sb, &journal_devnum,
+@@ -3458,6 +3469,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 				 "both data=journal and dax");
+ 			goto failed_mount;
+ 		}
++		if (ext4_has_feature_encrypt(sb)) {
++			ext4_msg(sb, KERN_WARNING,
++				 "encrypted files will use data=ordered "
++				 "instead of data journaling mode");
++		}
+ 		if (test_opt(sb, DELALLOC))
+ 			clear_opt(sb, DELALLOC);
+ 	} else {
+@@ -3613,12 +3629,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 
+ 	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
+ 	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+-	if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0)
+-		goto cantfind_ext4;
+ 
+ 	sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb);
+ 	if (sbi->s_inodes_per_block == 0)
+ 		goto cantfind_ext4;
++	if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
++	    sbi->s_inodes_per_group > blocksize * 8) {
++		ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n",
++			 sbi->s_blocks_per_group);
++		goto failed_mount;
++	}
+ 	sbi->s_itb_per_group = sbi->s_inodes_per_group /
+ 					sbi->s_inodes_per_block;
+ 	sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
+@@ -3701,13 +3721,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	}
+ 	sbi->s_cluster_ratio = clustersize / blocksize;
+ 
+-	if (sbi->s_inodes_per_group > blocksize * 8) {
+-		ext4_msg(sb, KERN_ERR,
+-		       "#inodes per group too big: %lu",
+-		       sbi->s_inodes_per_group);
+-		goto failed_mount;
+-	}
+-
+ 	/* Do we have standard group size of clustersize * 8 blocks ? */
+ 	if (sbi->s_blocks_per_group == clustersize << 3)
+ 		set_opt2(sb, STD_GROUP_SIZE);
+@@ -4113,7 +4126,9 @@ no_journal:
+ 
+ 	if (___ratelimit(&ext4_mount_msg_ratelimit, "EXT4-fs mount"))
+ 		ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. "
+-			 "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts,
++			 "Opts: %.*s%s%s", descr,
++			 (int) sizeof(sbi->s_es->s_mount_opts),
++			 sbi->s_es->s_mount_opts,
+ 			 *sbi->s_es->s_mount_opts ? "; " : "", orig_data);
+ 
+ 	if (es->s_error_count)
+@@ -4192,8 +4207,8 @@ failed_mount:
+ out_fail:
+ 	sb->s_fs_info = NULL;
+ 	kfree(sbi->s_blockgroup_lock);
++out_free_base:
+ 	kfree(sbi);
+-out_free_orig:
+ 	kfree(orig_data);
+ 	return err ? err : ret;
+ }
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index badd407bb622..c05d66d98871 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -362,6 +362,7 @@ static int stat_open(struct inode *inode, struct file *file)
+ }
+ 
+ static const struct file_operations stat_fops = {
++	.owner = THIS_MODULE,
+ 	.open = stat_open,
+ 	.read = seq_read,
+ 	.llseek = seq_lseek,
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 14f5fe2b841e..8467f4221f57 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -451,7 +451,7 @@ struct f2fs_inode_info {
+ 	/* Use below internally in f2fs*/
+ 	unsigned long flags;		/* use to pass per-file flags */
+ 	struct rw_semaphore i_sem;	/* protect fi info */
+-	struct percpu_counter dirty_pages;	/* # of dirty pages */
++	atomic_t dirty_pages;		/* # of dirty pages */
+ 	f2fs_hash_t chash;		/* hash value of given file name */
+ 	unsigned int clevel;		/* maximum level of given file name */
+ 	nid_t i_xattr_nid;		/* node id that contains xattrs */
+@@ -1198,7 +1198,7 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
+ 
+ static inline void inode_inc_dirty_pages(struct inode *inode)
+ {
+-	percpu_counter_inc(&F2FS_I(inode)->dirty_pages);
++	atomic_inc(&F2FS_I(inode)->dirty_pages);
+ 	inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
+ 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+ }
+@@ -1214,7 +1214,7 @@ static inline void inode_dec_dirty_pages(struct inode *inode)
+ 			!S_ISLNK(inode->i_mode))
+ 		return;
+ 
+-	percpu_counter_dec(&F2FS_I(inode)->dirty_pages);
++	atomic_dec(&F2FS_I(inode)->dirty_pages);
+ 	dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
+ 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+ }
+@@ -1224,9 +1224,9 @@ static inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
+ 	return percpu_counter_sum_positive(&sbi->nr_pages[count_type]);
+ }
+ 
+-static inline s64 get_dirty_pages(struct inode *inode)
++static inline int get_dirty_pages(struct inode *inode)
+ {
+-	return percpu_counter_sum_positive(&F2FS_I(inode)->dirty_pages);
++	return atomic_read(&F2FS_I(inode)->dirty_pages);
+ }
+ 
+ static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 28f4f4cbb8d8..06f39db65923 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -970,7 +970,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
+ 				new_size = (dst + i) << PAGE_SHIFT;
+ 				if (dst_inode->i_size < new_size)
+ 					f2fs_i_size_write(dst_inode, new_size);
+-			} while ((do_replace[i] || blkaddr[i] == NULL_ADDR) && --ilen);
++			} while (--ilen && (do_replace[i] || blkaddr[i] == NULL_ADDR));
+ 
+ 			f2fs_put_dnode(&dn);
+ 		} else {
+@@ -1529,7 +1529,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ 		goto out;
+ 
+ 	f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
+-		"Unexpected flush for atomic writes: ino=%lu, npages=%lld",
++		"Unexpected flush for atomic writes: ino=%lu, npages=%u",
+ 					inode->i_ino, get_dirty_pages(inode));
+ 	ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ 	if (ret)
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 7f863a645ab1..37edc853c66c 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -565,13 +565,9 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
+ 
+ 	init_once((void *) fi);
+ 
+-	if (percpu_counter_init(&fi->dirty_pages, 0, GFP_NOFS)) {
+-		kmem_cache_free(f2fs_inode_cachep, fi);
+-		return NULL;
+-	}
+-
+ 	/* Initialize f2fs-specific inode info */
+ 	fi->vfs_inode.i_version = 1;
++	atomic_set(&fi->dirty_pages, 0);
+ 	fi->i_current_depth = 1;
+ 	fi->i_advise = 0;
+ 	init_rwsem(&fi->i_sem);
+@@ -694,7 +690,6 @@ static void f2fs_i_callback(struct rcu_head *head)
+ 
+ static void f2fs_destroy_inode(struct inode *inode)
+ {
+-	percpu_counter_destroy(&F2FS_I(inode)->dirty_pages);
+ 	call_rcu(&inode->i_rcu, f2fs_i_callback);
+ }
+ 
+diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
+index e8638fd2c0c3..6f07b3e89ff2 100644
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -4506,6 +4506,7 @@ xlog_recover_clear_agi_bucket(
+ 	agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+ 	offset = offsetof(xfs_agi_t, agi_unlinked) +
+ 		 (sizeof(xfs_agino_t) * bucket);
++	xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
+ 	xfs_trans_log_buf(tp, agibp, offset,
+ 			  (offset + sizeof(xfs_agino_t) - 1));
+ 
+diff --git a/include/linux/capability.h b/include/linux/capability.h
+index dbc21c719ce6..6ffb67e10c06 100644
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -240,8 +240,10 @@ static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+ 	return true;
+ }
+ #endif /* CONFIG_MULTIUSER */
++extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
+ extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
+ extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
++extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
+ 
+ /* audit system wants to get cap info from files as well */
+ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 903200f4ec41..39820082ce91 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -473,6 +473,7 @@ struct mm_struct {
+ 	 */
+ 	struct task_struct __rcu *owner;
+ #endif
++	struct user_namespace *user_ns;
+ 
+ 	/* store ref to file /proc/<pid>/exe symlink points to */
+ 	struct file __rcu *exe_file;
+diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
+index bca26157f5b6..f6bc76501912 100644
+--- a/include/linux/pm_opp.h
++++ b/include/linux/pm_opp.h
+@@ -19,6 +19,7 @@
+ 
+ struct dev_pm_opp;
+ struct device;
++struct opp_table;
+ 
+ enum dev_pm_opp_event {
+ 	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+@@ -62,8 +63,8 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
+ void dev_pm_opp_put_supported_hw(struct device *dev);
+ int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
+ void dev_pm_opp_put_prop_name(struct device *dev);
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name);
+-void dev_pm_opp_put_regulator(struct device *dev);
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name);
++void dev_pm_opp_put_regulator(struct opp_table *opp_table);
+ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
+ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
+ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
+@@ -170,12 +171,12 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
+ 
+ static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
+ 
+-static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++static inline struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+-	return -ENOTSUPP;
++	return ERR_PTR(-ENOTSUPP);
+ }
+ 
+-static inline void dev_pm_opp_put_regulator(struct device *dev) {}
++static inline void dev_pm_opp_put_regulator(struct opp_table *opp_table) {}
+ 
+ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
+ {
+diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
+index 504c98a278d4..e13bfdf7f314 100644
+--- a/include/linux/ptrace.h
++++ b/include/linux/ptrace.h
+@@ -19,7 +19,6 @@
+ #define PT_SEIZED	0x00010000	/* SEIZE used, enable new behavior */
+ #define PT_PTRACED	0x00000001
+ #define PT_DTRACE	0x00000002	/* delayed trace (used on m68k, i386) */
+-#define PT_PTRACE_CAP	0x00000004	/* ptracer can follow suid-exec */
+ 
+ #define PT_OPT_FLAG_SHIFT	3
+ /* PT_TRACE_* event enable flags */
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 62c68e513e39..f52d4cc97788 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1631,6 +1631,7 @@ struct task_struct {
+ 	struct list_head cpu_timers[3];
+ 
+ /* process credentials */
++	const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
+ 	const struct cred __rcu *real_cred; /* objective and real subjective task
+ 					 * credentials (COW) */
+ 	const struct cred __rcu *cred;	/* effective (overridable) subjective task
+diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
+index 445b019c2078..de45666f96b4 100644
+--- a/include/net/netfilter/nf_conntrack.h
++++ b/include/net/netfilter/nf_conntrack.h
+@@ -17,7 +17,6 @@
+ #include <linux/bitops.h>
+ #include <linux/compiler.h>
+ #include <linux/atomic.h>
+-#include <linux/rhashtable.h>
+ 
+ #include <linux/netfilter/nf_conntrack_tcp.h>
+ #include <linux/netfilter/nf_conntrack_dccp.h>
+@@ -118,9 +117,6 @@ struct nf_conn {
+ 	/* Extensions */
+ 	struct nf_ct_ext *ext;
+ 
+-#if IS_ENABLED(CONFIG_NF_NAT)
+-	struct rhash_head	nat_bysource;
+-#endif
+ 	/* Storage reserved for other modules, must be the last member */
+ 	union nf_conntrack_proto proto;
+ };
+diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
+index 1c3035dda31f..b925395fa5ed 100644
+--- a/include/net/netfilter/nf_conntrack_extend.h
++++ b/include/net/netfilter/nf_conntrack_extend.h
+@@ -99,6 +99,9 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ struct nf_ct_ext_type {
+ 	/* Destroys relationships (can be NULL). */
+ 	void (*destroy)(struct nf_conn *ct);
++	/* Called when realloacted (can be NULL).
++	   Contents has already been moved. */
++	void (*move)(void *new, void *old);
+ 
+ 	enum nf_ct_ext_id id;
+ 
+diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
+index c327a431a6f3..344b1ab19220 100644
+--- a/include/net/netfilter/nf_nat.h
++++ b/include/net/netfilter/nf_nat.h
+@@ -1,6 +1,5 @@
+ #ifndef _NF_NAT_H
+ #define _NF_NAT_H
+-#include <linux/rhashtable.h>
+ #include <linux/netfilter_ipv4.h>
+ #include <linux/netfilter/nf_nat.h>
+ #include <net/netfilter/nf_conntrack_tuple.h>
+@@ -30,6 +29,8 @@ struct nf_conn;
+ 
+ /* The structure embedded in the conntrack structure. */
+ struct nf_conn_nat {
++	struct hlist_node bysource;
++	struct nf_conn *ct;
+ 	union nf_conntrack_nat_help help;
+ #if IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV4) || \
+     IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV6)
+diff --git a/kernel/capability.c b/kernel/capability.c
+index 00411c82dac5..4984e1f552eb 100644
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -457,6 +457,19 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
+ EXPORT_SYMBOL(file_ns_capable);
+ 
+ /**
++ * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
++ * @ns: The user namespace in question
++ * @inode: The inode in question
++ *
++ * Return true if the inode uid and gid are within the namespace.
++ */
++bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
++{
++	return kuid_has_mapping(ns, inode->i_uid) &&
++		kgid_has_mapping(ns, inode->i_gid);
++}
++
++/**
+  * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
+  * @inode: The inode in question
+  * @cap: The capability in question
+@@ -469,7 +482,26 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
+ {
+ 	struct user_namespace *ns = current_user_ns();
+ 
+-	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+-		kgid_has_mapping(ns, inode->i_gid);
++	return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
+ }
+ EXPORT_SYMBOL(capable_wrt_inode_uidgid);
++
++/**
++ * ptracer_capable - Determine if the ptracer holds CAP_SYS_PTRACE in the namespace
++ * @tsk: The task that may be ptraced
++ * @ns: The user namespace to search for CAP_SYS_PTRACE in
++ *
++ * Return true if the task that is ptracing the current task had CAP_SYS_PTRACE
++ * in the specified user namespace.
++ */
++bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns)
++{
++	int ret = 0;  /* An absent tracer adds no restrictions */
++	const struct cred *cred;
++	rcu_read_lock();
++	cred = rcu_dereference(tsk->ptracer_cred);
++	if (cred)
++		ret = security_capable_noaudit(cred, ns, CAP_SYS_PTRACE);
++	rcu_read_unlock();
++	return (ret == 0);
++}
+diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
+index 0874e2edd275..79517e5549f1 100644
+--- a/kernel/debug/debug_core.c
++++ b/kernel/debug/debug_core.c
+@@ -598,11 +598,11 @@ return_normal:
+ 	/*
+ 	 * Wait for the other CPUs to be notified and be waiting for us:
+ 	 */
+-	time_left = loops_per_jiffy * HZ;
++	time_left = MSEC_PER_SEC;
+ 	while (kgdb_do_roundup && --time_left &&
+ 	       (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
+ 		   online_cpus)
+-		cpu_relax();
++		udelay(1000);
+ 	if (!time_left)
+ 		pr_crit("Timed out waiting for secondary CPUs.\n");
+ 
+diff --git a/kernel/fork.c b/kernel/fork.c
+index beb31725f7e2..9f8dae785f07 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -598,7 +598,8 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
+ #endif
+ }
+ 
+-static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
++static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
++	struct user_namespace *user_ns)
+ {
+ 	mm->mmap = NULL;
+ 	mm->mm_rb = RB_ROOT;
+@@ -638,6 +639,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+ 	if (init_new_context(p, mm))
+ 		goto fail_nocontext;
+ 
++	mm->user_ns = get_user_ns(user_ns);
+ 	return mm;
+ 
+ fail_nocontext:
+@@ -683,7 +685,7 @@ struct mm_struct *mm_alloc(void)
+ 		return NULL;
+ 
+ 	memset(mm, 0, sizeof(*mm));
+-	return mm_init(mm, current);
++	return mm_init(mm, current, current_user_ns());
+ }
+ 
+ /*
+@@ -698,6 +700,7 @@ void __mmdrop(struct mm_struct *mm)
+ 	destroy_context(mm);
+ 	mmu_notifier_mm_destroy(mm);
+ 	check_mm(mm);
++	put_user_ns(mm->user_ns);
+ 	free_mm(mm);
+ }
+ EXPORT_SYMBOL_GPL(__mmdrop);
+@@ -977,7 +980,7 @@ static struct mm_struct *dup_mm(struct task_struct *tsk)
+ 
+ 	memcpy(mm, oldmm, sizeof(*mm));
+ 
+-	if (!mm_init(mm, tsk))
++	if (!mm_init(mm, tsk, mm->user_ns))
+ 		goto fail_nomem;
+ 
+ 	err = dup_mmap(mm, oldmm);
+diff --git a/kernel/ptrace.c b/kernel/ptrace.c
+index 1d3b7665d0be..7b20baea41e7 100644
+--- a/kernel/ptrace.c
++++ b/kernel/ptrace.c
+@@ -39,6 +39,9 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
+ 	BUG_ON(!list_empty(&child->ptrace_entry));
+ 	list_add(&child->ptrace_entry, &new_parent->ptraced);
+ 	child->parent = new_parent;
++	rcu_read_lock();
++	child->ptracer_cred = get_cred(__task_cred(new_parent));
++	rcu_read_unlock();
+ }
+ 
+ /**
+@@ -71,10 +74,14 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
+  */
+ void __ptrace_unlink(struct task_struct *child)
+ {
++	const struct cred *old_cred;
+ 	BUG_ON(!child->ptrace);
+ 
+ 	child->parent = child->real_parent;
+ 	list_del_init(&child->ptrace_entry);
++	old_cred = child->ptracer_cred;
++	child->ptracer_cred = NULL;
++	put_cred(old_cred);
+ 
+ 	spin_lock(&child->sighand->siglock);
+ 	child->ptrace = 0;
+@@ -218,7 +225,7 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+ {
+ 	const struct cred *cred = current_cred(), *tcred;
+-	int dumpable = 0;
++	struct mm_struct *mm;
+ 	kuid_t caller_uid;
+ 	kgid_t caller_gid;
+ 
+@@ -269,16 +276,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+ 	return -EPERM;
+ ok:
+ 	rcu_read_unlock();
+-	smp_rmb();
+-	if (task->mm)
+-		dumpable = get_dumpable(task->mm);
+-	rcu_read_lock();
+-	if (dumpable != SUID_DUMP_USER &&
+-	    !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+-		rcu_read_unlock();
+-		return -EPERM;
+-	}
+-	rcu_read_unlock();
++	mm = task->mm;
++	if (mm &&
++	    ((get_dumpable(mm) != SUID_DUMP_USER) &&
++	     !ptrace_has_cap(mm->user_ns, mode)))
++	    return -EPERM;
+ 
+ 	return security_ptrace_access_check(task, mode);
+ }
+@@ -342,10 +344,6 @@ static int ptrace_attach(struct task_struct *task, long request,
+ 
+ 	if (seize)
+ 		flags |= PT_SEIZED;
+-	rcu_read_lock();
+-	if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE))
+-		flags |= PT_PTRACE_CAP;
+-	rcu_read_unlock();
+ 	task->ptrace = flags;
+ 
+ 	__ptrace_link(task, current);
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index 9acb29f280ec..6d1020c03d41 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -344,7 +344,6 @@ static void watchdog_overflow_callback(struct perf_event *event,
+ 	 */
+ 	if (is_hardlockup()) {
+ 		int this_cpu = smp_processor_id();
+-		struct pt_regs *regs = get_irq_regs();
+ 
+ 		/* only print hardlockups once */
+ 		if (__this_cpu_read(hard_watchdog_warn) == true)
+diff --git a/mm/filemap.c b/mm/filemap.c
+index ced9ef6c06b0..f1da48d1f95f 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1688,7 +1688,7 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos,
+ 	int error = 0;
+ 
+ 	if (unlikely(*ppos >= inode->i_sb->s_maxbytes))
+-		return -EINVAL;
++		return 0;
+ 	iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
+ 
+ 	index = *ppos >> PAGE_SHIFT;
+diff --git a/mm/init-mm.c b/mm/init-mm.c
+index a56a851908d2..975e49f00f34 100644
+--- a/mm/init-mm.c
++++ b/mm/init-mm.c
+@@ -6,6 +6,7 @@
+ #include <linux/cpumask.h>
+ 
+ #include <linux/atomic.h>
++#include <linux/user_namespace.h>
+ #include <asm/pgtable.h>
+ #include <asm/mmu.h>
+ 
+@@ -21,5 +22,6 @@ struct mm_struct init_mm = {
+ 	.mmap_sem	= __RWSEM_INITIALIZER(init_mm.mmap_sem),
+ 	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
+ 	.mmlist		= LIST_HEAD_INIT(init_mm.mmlist),
++	.user_ns	= &init_user_ns,
+ 	INIT_MM_CONTEXT(init_mm)
+ };
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 7401e996009a..212a017a2f02 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2173,7 +2173,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+ 			unsigned long count, struct list_head *list,
+ 			int migratetype, bool cold)
+ {
+-	int i;
++	int i, alloced = 0;
+ 
+ 	spin_lock(&zone->lock);
+ 	for (i = 0; i < count; ++i) {
+@@ -2198,13 +2198,21 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+ 		else
+ 			list_add_tail(&page->lru, list);
+ 		list = &page->lru;
++		alloced++;
+ 		if (is_migrate_cma(get_pcppage_migratetype(page)))
+ 			__mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
+ 					      -(1 << order));
+ 	}
++
++	/*
++	 * i pages were removed from the buddy list even if some leak due
++	 * to check_pcp_refill failing so adjust NR_FREE_PAGES based
++	 * on i. Do not confuse with 'alloced' which is the number of
++	 * pages added to the pcp list.
++	 */
+ 	__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
+ 	spin_unlock(&zone->lock);
+-	return i;
++	return alloced;
+ }
+ 
+ #ifdef CONFIG_NUMA
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index ba0fad78e5d4..5c313a0d1626 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -291,6 +291,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 	int nid = shrinkctl->nid;
+ 	long batch_size = shrinker->batch ? shrinker->batch
+ 					  : SHRINK_BATCH;
++	long scanned = 0, next_deferred;
+ 
+ 	freeable = shrinker->count_objects(shrinker, shrinkctl);
+ 	if (freeable == 0)
+@@ -312,7 +313,9 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 		pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n",
+ 		       shrinker->scan_objects, total_scan);
+ 		total_scan = freeable;
+-	}
++		next_deferred = nr;
++	} else
++		next_deferred = total_scan;
+ 
+ 	/*
+ 	 * We need to avoid excessive windup on filesystem shrinkers
+@@ -369,17 +372,22 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 
+ 		count_vm_events(SLABS_SCANNED, nr_to_scan);
+ 		total_scan -= nr_to_scan;
++		scanned += nr_to_scan;
+ 
+ 		cond_resched();
+ 	}
+ 
++	if (next_deferred >= scanned)
++		next_deferred -= scanned;
++	else
++		next_deferred = 0;
+ 	/*
+ 	 * move the unused scan count back into the shrinker in a
+ 	 * manner that handles concurrent updates. If we exhausted the
+ 	 * scan, there is no need to do an update.
+ 	 */
+-	if (total_scan > 0)
+-		new_nr = atomic_long_add_return(total_scan,
++	if (next_deferred > 0)
++		new_nr = atomic_long_add_return(next_deferred,
+ 						&shrinker->nr_deferred[nid]);
+ 	else
+ 		new_nr = atomic_long_read(&shrinker->nr_deferred[nid]);
+diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
+index 02bcf00c2492..1a9545965c0d 100644
+--- a/net/netfilter/nf_conntrack_extend.c
++++ b/net/netfilter/nf_conntrack_extend.c
+@@ -73,7 +73,7 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ 			     size_t var_alloc_len, gfp_t gfp)
+ {
+ 	struct nf_ct_ext *old, *new;
+-	int newlen, newoff;
++	int i, newlen, newoff;
+ 	struct nf_ct_ext_type *t;
+ 
+ 	/* Conntrack must not be confirmed to avoid races on reallocation. */
+@@ -99,8 +99,19 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ 		return NULL;
+ 
+ 	if (new != old) {
++		for (i = 0; i < NF_CT_EXT_NUM; i++) {
++			if (!__nf_ct_ext_exist(old, i))
++				continue;
++
++			rcu_read_lock();
++			t = rcu_dereference(nf_ct_ext_types[i]);
++			if (t && t->move)
++				t->move((void *)new + new->offset[i],
++					(void *)old + old->offset[i]);
++			rcu_read_unlock();
++		}
+ 		kfree_rcu(old, rcu);
+-		rcu_assign_pointer(ct->ext, new);
++		ct->ext = new;
+ 	}
+ 
+ 	new->offset[id] = newoff;
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index ecee105bbada..4bf9b50cbb4c 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -30,19 +30,17 @@
+ #include <net/netfilter/nf_conntrack_zones.h>
+ #include <linux/netfilter/nf_nat.h>
+ 
++static DEFINE_SPINLOCK(nf_nat_lock);
++
+ static DEFINE_MUTEX(nf_nat_proto_mutex);
+ static const struct nf_nat_l3proto __rcu *nf_nat_l3protos[NFPROTO_NUMPROTO]
+ 						__read_mostly;
+ static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO]
+ 						__read_mostly;
+ 
+-struct nf_nat_conn_key {
+-	const struct net *net;
+-	const struct nf_conntrack_tuple *tuple;
+-	const struct nf_conntrack_zone *zone;
+-};
+-
+-static struct rhashtable nf_nat_bysource_table;
++static struct hlist_head *nf_nat_bysource __read_mostly;
++static unsigned int nf_nat_htable_size __read_mostly;
++static unsigned int nf_nat_hash_rnd __read_mostly;
+ 
+ inline const struct nf_nat_l3proto *
+ __nf_nat_l3proto_find(u8 family)
+@@ -121,17 +119,19 @@ int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family)
+ EXPORT_SYMBOL(nf_xfrm_me_harder);
+ #endif /* CONFIG_XFRM */
+ 
+-static u32 nf_nat_bysource_hash(const void *data, u32 len, u32 seed)
++/* We keep an extra hash for each conntrack, for fast searching. */
++static inline unsigned int
++hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple)
+ {
+-	const struct nf_conntrack_tuple *t;
+-	const struct nf_conn *ct = data;
++	unsigned int hash;
++
++	get_random_once(&nf_nat_hash_rnd, sizeof(nf_nat_hash_rnd));
+ 
+-	t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ 	/* Original src, to ensure we map it consistently if poss. */
++	hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
++		      tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n));
+ 
+-	seed ^= net_hash_mix(nf_ct_net(ct));
+-	return jhash2((const u32 *)&t->src, sizeof(t->src) / sizeof(u32),
+-		      t->dst.protonum ^ seed);
++	return reciprocal_scale(hash, nf_nat_htable_size);
+ }
+ 
+ /* Is this tuple already taken? (not by us) */
+@@ -187,26 +187,6 @@ same_src(const struct nf_conn *ct,
+ 		t->src.u.all == tuple->src.u.all);
+ }
+ 
+-static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg,
+-			       const void *obj)
+-{
+-	const struct nf_nat_conn_key *key = arg->key;
+-	const struct nf_conn *ct = obj;
+-
+-	return same_src(ct, key->tuple) &&
+-	       net_eq(nf_ct_net(ct), key->net) &&
+-	       nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL);
+-}
+-
+-static struct rhashtable_params nf_nat_bysource_params = {
+-	.head_offset = offsetof(struct nf_conn, nat_bysource),
+-	.obj_hashfn = nf_nat_bysource_hash,
+-	.obj_cmpfn = nf_nat_bysource_cmp,
+-	.nelem_hint = 256,
+-	.min_size = 1024,
+-	.nulls_base = (1U << RHT_BASE_SHIFT),
+-};
+-
+ /* Only called for SRC manip */
+ static int
+ find_appropriate_src(struct net *net,
+@@ -217,23 +197,25 @@ find_appropriate_src(struct net *net,
+ 		     struct nf_conntrack_tuple *result,
+ 		     const struct nf_nat_range *range)
+ {
++	unsigned int h = hash_by_src(net, tuple);
++	const struct nf_conn_nat *nat;
+ 	const struct nf_conn *ct;
+-	struct nf_nat_conn_key key = {
+-		.net = net,
+-		.tuple = tuple,
+-		.zone = zone
+-	};
+ 
+-	ct = rhashtable_lookup_fast(&nf_nat_bysource_table, &key,
+-				    nf_nat_bysource_params);
+-	if (!ct)
+-		return 0;
+-
+-	nf_ct_invert_tuplepr(result,
+-			     &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+-	result->dst = tuple->dst;
+-
+-	return in_range(l3proto, l4proto, result, range);
++	hlist_for_each_entry_rcu(nat, &nf_nat_bysource[h], bysource) {
++		ct = nat->ct;
++		if (same_src(ct, tuple) &&
++		    net_eq(net, nf_ct_net(ct)) &&
++		    nf_ct_zone_equal(ct, zone, IP_CT_DIR_ORIGINAL)) {
++			/* Copy source part from reply tuple. */
++			nf_ct_invert_tuplepr(result,
++				       &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
++			result->dst = tuple->dst;
++
++			if (in_range(l3proto, l4proto, result, range))
++				return 1;
++		}
++	}
++	return 0;
+ }
+ 
+ /* For [FUTURE] fragmentation handling, we want the least-used
+@@ -405,6 +387,7 @@ nf_nat_setup_info(struct nf_conn *ct,
+ 		  const struct nf_nat_range *range,
+ 		  enum nf_nat_manip_type maniptype)
+ {
++	struct net *net = nf_ct_net(ct);
+ 	struct nf_conntrack_tuple curr_tuple, new_tuple;
+ 	struct nf_conn_nat *nat;
+ 
+@@ -446,13 +429,17 @@ nf_nat_setup_info(struct nf_conn *ct,
+ 	}
+ 
+ 	if (maniptype == NF_NAT_MANIP_SRC) {
+-		int err;
+-
+-		err = rhashtable_insert_fast(&nf_nat_bysource_table,
+-					     &ct->nat_bysource,
+-					     nf_nat_bysource_params);
+-		if (err)
+-			return NF_DROP;
++		unsigned int srchash;
++
++		srchash = hash_by_src(net,
++				      &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
++		spin_lock_bh(&nf_nat_lock);
++		/* nf_conntrack_alter_reply might re-allocate extension aera */
++		nat = nfct_nat(ct);
++		nat->ct = ct;
++		hlist_add_head_rcu(&nat->bysource,
++				   &nf_nat_bysource[srchash]);
++		spin_unlock_bh(&nf_nat_lock);
+ 	}
+ 
+ 	/* It's done. */
+@@ -557,7 +544,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
+ 	if (nf_nat_proto_remove(ct, data))
+ 		return 1;
+ 
+-	if (!nat)
++	if (!nat || !nat->ct)
+ 		return 0;
+ 
+ 	/* This netns is being destroyed, and conntrack has nat null binding.
+@@ -569,10 +556,11 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
+ 	if (!del_timer(&ct->timeout))
+ 		return 1;
+ 
++	spin_lock_bh(&nf_nat_lock);
++	hlist_del_rcu(&nat->bysource);
+ 	ct->status &= ~IPS_NAT_DONE_MASK;
+-
+-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
+-			       nf_nat_bysource_params);
++	nat->ct = NULL;
++	spin_unlock_bh(&nf_nat_lock);
+ 
+ 	add_timer(&ct->timeout);
+ 
+@@ -701,17 +689,35 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
+ {
+ 	struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+ 
+-	if (!nat)
++	if (nat == NULL || nat->ct == NULL)
+ 		return;
+ 
+-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
+-			       nf_nat_bysource_params);
++	NF_CT_ASSERT(nat->ct->status & IPS_SRC_NAT_DONE);
++
++	spin_lock_bh(&nf_nat_lock);
++	hlist_del_rcu(&nat->bysource);
++	spin_unlock_bh(&nf_nat_lock);
++}
++
++static void nf_nat_move_storage(void *new, void *old)
++{
++	struct nf_conn_nat *new_nat = new;
++	struct nf_conn_nat *old_nat = old;
++	struct nf_conn *ct = old_nat->ct;
++
++	if (!ct || !(ct->status & IPS_SRC_NAT_DONE))
++		return;
++
++	spin_lock_bh(&nf_nat_lock);
++	hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
++	spin_unlock_bh(&nf_nat_lock);
+ }
+ 
+ static struct nf_ct_ext_type nat_extend __read_mostly = {
+ 	.len		= sizeof(struct nf_conn_nat),
+ 	.align		= __alignof__(struct nf_conn_nat),
+ 	.destroy	= nf_nat_cleanup_conntrack,
++	.move		= nf_nat_move_storage,
+ 	.id		= NF_CT_EXT_NAT,
+ 	.flags		= NF_CT_EXT_F_PREALLOC,
+ };
+@@ -840,13 +846,16 @@ static int __init nf_nat_init(void)
+ {
+ 	int ret;
+ 
+-	ret = rhashtable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
+-	if (ret)
+-		return ret;
++	/* Leave them the same for the moment. */
++	nf_nat_htable_size = nf_conntrack_htable_size;
++
++	nf_nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 0);
++	if (!nf_nat_bysource)
++		return -ENOMEM;
+ 
+ 	ret = nf_ct_extend_register(&nat_extend);
+ 	if (ret < 0) {
+-		rhashtable_destroy(&nf_nat_bysource_table);
++		nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ 		printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
+ 		return ret;
+ 	}
+@@ -870,7 +879,7 @@ static int __init nf_nat_init(void)
+ 	return 0;
+ 
+  cleanup_extend:
+-	rhashtable_destroy(&nf_nat_bysource_table);
++	nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ 	nf_ct_extend_unregister(&nat_extend);
+ 	return ret;
+ }
+@@ -888,8 +897,8 @@ static void __exit nf_nat_cleanup(void)
+ #endif
+ 	for (i = 0; i < NFPROTO_NUMPROTO; i++)
+ 		kfree(nf_nat_l4protos[i]);
+-
+-	rhashtable_destroy(&nf_nat_bysource_table);
++	synchronize_net();
++	nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ }
+ 
+ MODULE_LICENSE("GPL");
+diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
+index 7f57a145a47e..a03cf68d0bcd 100644
+--- a/sound/pci/hda/hda_auto_parser.c
++++ b/sound/pci/hda/hda_auto_parser.c
+@@ -884,6 +884,8 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
+ 
++#define IGNORE_SEQ_ASSOC (~(AC_DEFCFG_SEQUENCE | AC_DEFCFG_DEF_ASSOC))
++
+ static bool pin_config_match(struct hda_codec *codec,
+ 			     const struct hda_pintbl *pins)
+ {
+@@ -901,7 +903,7 @@ static bool pin_config_match(struct hda_codec *codec,
+ 		for (; t_pins->nid; t_pins++) {
+ 			if (t_pins->nid == nid) {
+ 				found = 1;
+-				if (t_pins->val == cfg)
++				if ((t_pins->val & IGNORE_SEQ_ASSOC) == (cfg & IGNORE_SEQ_ASSOC))
+ 					break;
+ 				else if ((cfg & 0xf0000000) == 0x40000000 && (t_pins->val & 0xf0000000) == 0x40000000)
+ 					break;
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 9ceb2bc36e68..c146d0de53d8 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -780,6 +780,7 @@ static const struct hda_pintbl alienware_pincfgs[] = {
+ static const struct snd_pci_quirk ca0132_quirks[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
+ 	SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
++	SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
+ 	{}
+ };
+ 
+diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
+index ed62748a6d55..c15c51bea26d 100644
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -262,6 +262,7 @@ enum {
+ 	CXT_FIXUP_CAP_MIX_AMP_5047,
+ 	CXT_FIXUP_MUTE_LED_EAPD,
+ 	CXT_FIXUP_HP_SPECTRE,
++	CXT_FIXUP_HP_GATE_MIC,
+ };
+ 
+ /* for hda_fixup_thinkpad_acpi() */
+@@ -633,6 +634,17 @@ static void cxt_fixup_cap_mix_amp_5047(struct hda_codec *codec,
+ 				  (1 << AC_AMPCAP_MUTE_SHIFT));
+ }
+ 
++static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,
++				       const struct hda_fixup *fix,
++				       int action)
++{
++	/* the mic pin (0x19) doesn't give an unsolicited event;
++	 * probe the mic pin together with the headphone pin (0x16)
++	 */
++	if (action == HDA_FIXUP_ACT_PROBE)
++		snd_hda_jack_set_gating_jack(codec, 0x19, 0x16);
++}
++
+ /* ThinkPad X200 & co with cxt5051 */
+ static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
+ 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
+@@ -774,6 +786,10 @@ static const struct hda_fixup cxt_fixups[] = {
+ 			{ }
+ 		}
+ 	},
++	[CXT_FIXUP_HP_GATE_MIC] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = cxt_fixup_hp_gate_mic_jack,
++	},
+ };
+ 
+ static const struct snd_pci_quirk cxt5045_fixups[] = {
+@@ -824,6 +840,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
+ 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
+ 	SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
+ 	SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
++	SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
+ 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
+ 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
+ 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 162818058a5d..512fd83407f2 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5915,6 +5915,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x12, 0x90a60180},
+ 		{0x14, 0x90170120},
+ 		{0x21, 0x02211030}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x1b, 0x01011020},
++		{0x21, 0x02211010}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x12, 0x90a60160},
+ 		{0x14, 0x90170120},
+diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+index 52ed434cbca6..f1223045c400 100644
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -771,6 +771,9 @@ static int sst_soc_prepare(struct device *dev)
+ 	struct sst_data *drv = dev_get_drvdata(dev);
+ 	struct snd_soc_pcm_runtime *rtd;
+ 
++	if (!drv->soc_card)
++		return 0;
++
+ 	/* suspend all pcms first */
+ 	snd_soc_suspend(drv->soc_card->dev);
+ 	snd_soc_poweroff(drv->soc_card->dev);
+@@ -793,6 +796,9 @@ static void sst_soc_complete(struct device *dev)
+ 	struct sst_data *drv = dev_get_drvdata(dev);
+ 	struct snd_soc_pcm_runtime *rtd;
+ 
++	if (!drv->soc_card)
++		return;
++
+ 	/* restart SSPs */
+ 	list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
+ 		struct snd_soc_dai *dai = rtd->cpu_dai;
+diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c
+index 2c44139b4041..33db205dd12b 100644
+--- a/sound/usb/hiface/pcm.c
++++ b/sound/usb/hiface/pcm.c
+@@ -445,6 +445,8 @@ static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
+ 
+ 	mutex_lock(&rt->stream_mutex);
+ 
++	hiface_pcm_stream_stop(rt);
++
+ 	sub->dma_off = 0;
+ 	sub->period_off = 0;
+ 
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index 2f8c388ef84f..4703caea56b2 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -932,9 +932,10 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
+ 	case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
+ 	case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */
+ 	case USB_ID(0x046d, 0x0991):
++	case USB_ID(0x046d, 0x09a2): /* QuickCam Communicate Deluxe/S7500 */
+ 	/* Most audio usb devices lie about volume resolution.
+ 	 * Most Logitech webcams have res = 384.
+-	 * Proboly there is some logitech magic behind this number --fishor
++	 * Probably there is some logitech magic behind this number --fishor
+ 	 */
+ 		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+ 			usb_audio_info(chip,


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2017-01-06 23:43 Mike Pagano
  0 siblings, 0 replies; 26+ messages in thread
From: Mike Pagano @ 2017-01-06 23:43 UTC (permalink / raw
  To: gentoo-commits

commit:     5a0bfade39e12ebb3a33a6868f6ebfe07297d6c6
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Jan  6 23:11:42 2017 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Jan  6 23:42:50 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=5a0bfade

Linux patch 4.8.16

 0000_README             |    4 +
 1015_linux-4.8.16.patch | 3559 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3563 insertions(+)

diff --git a/0000_README b/0000_README
index 37d0ff1..e7fac7c 100644
--- a/0000_README
+++ b/0000_README
@@ -103,6 +103,10 @@ Patch:  1014_linux-4.8.15.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.15
 
+Patch:  1015_linux-4.8.16.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.16
+
 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/1015_linux-4.8.16.patch b/1015_linux-4.8.16.patch
new file mode 100644
index 0000000..9977d7a
--- /dev/null
+++ b/1015_linux-4.8.16.patch
@@ -0,0 +1,3559 @@
+diff --git a/Makefile b/Makefile
+index c7f0e798ca34..50f68648a79a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 15
++SUBLEVEL = 16
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
+index f193414d0f6f..4986dc0c1dff 100644
+--- a/arch/arm/xen/enlighten.c
++++ b/arch/arm/xen/enlighten.c
+@@ -372,8 +372,7 @@ static int __init xen_guest_init(void)
+ 	 * for secondary CPUs as they are brought up.
+ 	 * For uniformity we use VCPUOP_register_vcpu_info even on cpu0.
+ 	 */
+-	xen_vcpu_info = __alloc_percpu(sizeof(struct vcpu_info),
+-			                       sizeof(struct vcpu_info));
++	xen_vcpu_info = alloc_percpu(struct vcpu_info);
+ 	if (xen_vcpu_info == NULL)
+ 		return -ENOMEM;
+ 
+diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h
+index 5420cb0fcb3e..e517088d635f 100644
+--- a/arch/arm64/include/asm/acpi.h
++++ b/arch/arm64/include/asm/acpi.h
+@@ -12,7 +12,7 @@
+ #ifndef _ASM_ACPI_H
+ #define _ASM_ACPI_H
+ 
+-#include <linux/mm.h>
++#include <linux/memblock.h>
+ #include <linux/psci.h>
+ 
+ #include <asm/cputype.h>
+@@ -32,7 +32,11 @@
+ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
+ 					    acpi_size size)
+ {
+-	if (!page_is_ram(phys >> PAGE_SHIFT))
++	/*
++	 * EFI's reserve_regions() call adds memory with the WB attribute
++	 * to memblock via early_init_dt_add_memory_arch().
++	 */
++	if (!memblock_is_memory(phys))
+ 		return ioremap(phys, size);
+ 
+ 	return ioremap_cache(phys, size);
+diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c
+index 536dce22fe76..514b4e3ba029 100644
+--- a/arch/arm64/kernel/setup.c
++++ b/arch/arm64/kernel/setup.c
+@@ -206,10 +206,15 @@ static void __init request_standard_resources(void)
+ 
+ 	for_each_memblock(memory, region) {
+ 		res = alloc_bootmem_low(sizeof(*res));
+-		res->name  = "System RAM";
++		if (memblock_is_nomap(region)) {
++			res->name  = "reserved";
++			res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
++		} else {
++			res->name  = "System RAM";
++			res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
++		}
+ 		res->start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+ 		res->end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
+-		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+ 
+ 		request_resource(&iomem_resource, res);
+ 
+diff --git a/block/blk-mq.c b/block/blk-mq.c
+index c207fa9870eb..494e0d800976 100644
+--- a/block/blk-mq.c
++++ b/block/blk-mq.c
+@@ -1371,9 +1371,9 @@ static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
+ 		blk_mq_put_ctx(data.ctx);
+ 		if (!old_rq)
+ 			goto done;
+-		if (!blk_mq_direct_issue_request(old_rq, &cookie))
+-			goto done;
+-		blk_mq_insert_request(old_rq, false, true, true);
++		if (test_bit(BLK_MQ_S_STOPPED, &data.hctx->state) ||
++		    blk_mq_direct_issue_request(old_rq, &cookie) != 0)
++			blk_mq_insert_request(old_rq, false, true, true);
+ 		goto done;
+ 	}
+ 
+diff --git a/drivers/base/core.c b/drivers/base/core.c
+index 0a8bdade53f2..88df65d1e6f6 100644
+--- a/drivers/base/core.c
++++ b/drivers/base/core.c
+@@ -836,11 +836,29 @@ static struct kobject *get_device_parent(struct device *dev,
+ 	return NULL;
+ }
+ 
++static inline bool live_in_glue_dir(struct kobject *kobj,
++				    struct device *dev)
++{
++	if (!kobj || !dev->class ||
++	    kobj->kset != &dev->class->p->glue_dirs)
++		return false;
++	return true;
++}
++
++static inline struct kobject *get_glue_dir(struct device *dev)
++{
++	return dev->kobj.parent;
++}
++
++/*
++ * make sure cleaning up dir as the last step, we need to make
++ * sure .release handler of kobject is run with holding the
++ * global lock
++ */
+ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
+ {
+ 	/* see if we live in a "glue" directory */
+-	if (!glue_dir || !dev->class ||
+-	    glue_dir->kset != &dev->class->p->glue_dirs)
++	if (!live_in_glue_dir(glue_dir, dev))
+ 		return;
+ 
+ 	mutex_lock(&gdp_mutex);
+@@ -848,11 +866,6 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
+ 	mutex_unlock(&gdp_mutex);
+ }
+ 
+-static void cleanup_device_parent(struct device *dev)
+-{
+-	cleanup_glue_dir(dev, dev->kobj.parent);
+-}
+-
+ static int device_add_class_symlinks(struct device *dev)
+ {
+ 	struct device_node *of_node = dev_of_node(dev);
+@@ -1028,6 +1041,7 @@ int device_add(struct device *dev)
+ 	struct kobject *kobj;
+ 	struct class_interface *class_intf;
+ 	int error = -EINVAL;
++	struct kobject *glue_dir = NULL;
+ 
+ 	dev = get_device(dev);
+ 	if (!dev)
+@@ -1072,8 +1086,10 @@ int device_add(struct device *dev)
+ 	/* first, register with generic layer. */
+ 	/* we require the name to be set before, and pass NULL */
+ 	error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);
+-	if (error)
++	if (error) {
++		glue_dir = get_glue_dir(dev);
+ 		goto Error;
++	}
+ 
+ 	/* notify platform of device entry */
+ 	if (platform_notify)
+@@ -1154,9 +1170,10 @@ done:
+ 	device_remove_file(dev, &dev_attr_uevent);
+  attrError:
+ 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
++	glue_dir = get_glue_dir(dev);
+ 	kobject_del(&dev->kobj);
+  Error:
+-	cleanup_device_parent(dev);
++	cleanup_glue_dir(dev, glue_dir);
+ 	put_device(parent);
+ name_error:
+ 	kfree(dev->p);
+@@ -1232,6 +1249,7 @@ EXPORT_SYMBOL_GPL(put_device);
+ void device_del(struct device *dev)
+ {
+ 	struct device *parent = dev->parent;
++	struct kobject *glue_dir = NULL;
+ 	struct class_interface *class_intf;
+ 
+ 	/* Notify clients of device removal.  This call must come
+@@ -1276,8 +1294,9 @@ void device_del(struct device *dev)
+ 		blocking_notifier_call_chain(&dev->bus->p->bus_notifier,
+ 					     BUS_NOTIFY_REMOVED_DEVICE, dev);
+ 	kobject_uevent(&dev->kobj, KOBJ_REMOVE);
+-	cleanup_device_parent(dev);
++	glue_dir = get_glue_dir(dev);
+ 	kobject_del(&dev->kobj);
++	cleanup_glue_dir(dev, glue_dir);
+ 	put_device(parent);
+ }
+ EXPORT_SYMBOL_GPL(device_del);
+diff --git a/drivers/base/power/opp/core.c b/drivers/base/power/opp/core.c
+index df0c70963d9e..94b33ce96be7 100644
+--- a/drivers/base/power/opp/core.c
++++ b/drivers/base/power/opp/core.c
+@@ -1320,7 +1320,7 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_put_prop_name);
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+ 	struct opp_table *opp_table;
+ 	struct regulator *reg;
+@@ -1358,20 +1358,20 @@ int dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ 	opp_table->regulator = reg;
+ 
+ 	mutex_unlock(&opp_table_lock);
+-	return 0;
++	return opp_table;
+ 
+ err:
+ 	_remove_opp_table(opp_table);
+ unlock:
+ 	mutex_unlock(&opp_table_lock);
+ 
+-	return ret;
++	return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+ 
+ /**
+  * dev_pm_opp_put_regulator() - Releases resources blocked for regulator
+- * @dev: Device for which regulator was set.
++ * @opp_table: OPP table returned from dev_pm_opp_set_regulator().
+  *
+  * Locking: The internal opp_table and opp structures are RCU protected.
+  * Hence this function internally uses RCU updater strategy with mutex locks
+@@ -1379,22 +1379,12 @@ EXPORT_SYMBOL_GPL(dev_pm_opp_set_regulator);
+  * that this function is *NOT* called under RCU protection or in contexts where
+  * mutex cannot be locked.
+  */
+-void dev_pm_opp_put_regulator(struct device *dev)
++void dev_pm_opp_put_regulator(struct opp_table *opp_table)
+ {
+-	struct opp_table *opp_table;
+-
+ 	mutex_lock(&opp_table_lock);
+ 
+-	/* Check for existing table for 'dev' first */
+-	opp_table = _find_opp_table(dev);
+-	if (IS_ERR(opp_table)) {
+-		dev_err(dev, "Failed to find opp_table: %ld\n",
+-			PTR_ERR(opp_table));
+-		goto unlock;
+-	}
+-
+ 	if (IS_ERR(opp_table->regulator)) {
+-		dev_err(dev, "%s: Doesn't have regulator set\n", __func__);
++		pr_err("%s: Doesn't have regulator set\n", __func__);
+ 		goto unlock;
+ 	}
+ 
+diff --git a/drivers/block/aoe/aoecmd.c b/drivers/block/aoe/aoecmd.c
+index ab19adb07a12..3c606c09fd5a 100644
+--- a/drivers/block/aoe/aoecmd.c
++++ b/drivers/block/aoe/aoecmd.c
+@@ -853,45 +853,6 @@ rqbiocnt(struct request *r)
+ 	return n;
+ }
+ 
+-/* This can be removed if we are certain that no users of the block
+- * layer will ever use zero-count pages in bios.  Otherwise we have to
+- * protect against the put_page sometimes done by the network layer.
+- *
+- * See http://oss.sgi.com/archives/xfs/2007-01/msg00594.html for
+- * discussion.
+- *
+- * We cannot use get_page in the workaround, because it insists on a
+- * positive page count as a precondition.  So we use _refcount directly.
+- */
+-static void
+-bio_pageinc(struct bio *bio)
+-{
+-	struct bio_vec bv;
+-	struct page *page;
+-	struct bvec_iter iter;
+-
+-	bio_for_each_segment(bv, bio, iter) {
+-		/* Non-zero page count for non-head members of
+-		 * compound pages is no longer allowed by the kernel.
+-		 */
+-		page = compound_head(bv.bv_page);
+-		page_ref_inc(page);
+-	}
+-}
+-
+-static void
+-bio_pagedec(struct bio *bio)
+-{
+-	struct page *page;
+-	struct bio_vec bv;
+-	struct bvec_iter iter;
+-
+-	bio_for_each_segment(bv, bio, iter) {
+-		page = compound_head(bv.bv_page);
+-		page_ref_dec(page);
+-	}
+-}
+-
+ static void
+ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
+ {
+@@ -899,7 +860,6 @@ bufinit(struct buf *buf, struct request *rq, struct bio *bio)
+ 	buf->rq = rq;
+ 	buf->bio = bio;
+ 	buf->iter = bio->bi_iter;
+-	bio_pageinc(bio);
+ }
+ 
+ static struct buf *
+@@ -1127,7 +1087,6 @@ aoe_end_buf(struct aoedev *d, struct buf *buf)
+ 	if (buf == d->ip.buf)
+ 		d->ip.buf = NULL;
+ 	rq = buf->rq;
+-	bio_pagedec(buf->bio);
+ 	mempool_free(buf, d->bufpool);
+ 	n = (unsigned long) rq->special;
+ 	rq->special = (void *) --n;
+diff --git a/drivers/block/loop.c b/drivers/block/loop.c
+index c9f2107f7095..b314a57e3c86 100644
+--- a/drivers/block/loop.c
++++ b/drivers/block/loop.c
+@@ -1646,7 +1646,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
+ 	blk_mq_start_request(bd->rq);
+ 
+ 	if (lo->lo_state != Lo_bound)
+-		return -EIO;
++		return BLK_MQ_RQ_QUEUE_ERROR;
+ 
+ 	switch (req_op(cmd->rq)) {
+ 	case REQ_OP_FLUSH:
+diff --git a/drivers/char/tpm/xen-tpmfront.c b/drivers/char/tpm/xen-tpmfront.c
+index 62028f483bba..a2ab00831df1 100644
+--- a/drivers/char/tpm/xen-tpmfront.c
++++ b/drivers/char/tpm/xen-tpmfront.c
+@@ -307,7 +307,6 @@ static int tpmfront_probe(struct xenbus_device *dev,
+ 	rv = setup_ring(dev, priv);
+ 	if (rv) {
+ 		chip = dev_get_drvdata(&dev->dev);
+-		tpm_chip_unregister(chip);
+ 		ring_free(priv);
+ 		return rv;
+ 	}
+diff --git a/drivers/clk/ti/clk-3xxx.c b/drivers/clk/ti/clk-3xxx.c
+index 8831e1a05367..11d8aa3ec186 100644
+--- a/drivers/clk/ti/clk-3xxx.c
++++ b/drivers/clk/ti/clk-3xxx.c
+@@ -22,13 +22,6 @@
+ 
+ #include "clock.h"
+ 
+-/*
+- * DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
+- * that are sourced by DPLL5, and both of these require this clock
+- * to be at 120 MHz for proper operation.
+- */
+-#define DPLL5_FREQ_FOR_USBHOST		120000000
+-
+ #define OMAP3430ES2_ST_DSS_IDLE_SHIFT			1
+ #define OMAP3430ES2_ST_HSOTGUSB_IDLE_SHIFT		5
+ #define OMAP3430ES2_ST_SSI_IDLE_SHIFT			8
+@@ -546,14 +539,21 @@ void __init omap3_clk_lock_dpll5(void)
+ 	struct clk *dpll5_clk;
+ 	struct clk *dpll5_m2_clk;
+ 
++	/*
++	 * Errata sprz319f advisory 2.1 documents a USB host clock drift issue
++	 * that can be worked around using specially crafted dpll5 settings
++	 * with a dpll5_m2 divider set to 8. Set the dpll5 rate to 8x the USB
++	 * host clock rate, its .set_rate handler() will detect that frequency
++	 * and use the errata settings.
++	 */
+ 	dpll5_clk = clk_get(NULL, "dpll5_ck");
+-	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
++	clk_set_rate(dpll5_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST * 8);
+ 	clk_prepare_enable(dpll5_clk);
+ 
+-	/* Program dpll5_m2_clk divider for no division */
++	/* Program dpll5_m2_clk divider */
+ 	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
+ 	clk_prepare_enable(dpll5_m2_clk);
+-	clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
++	clk_set_rate(dpll5_m2_clk, OMAP3_DPLL5_FREQ_FOR_USBHOST);
+ 
+ 	clk_disable_unprepare(dpll5_m2_clk);
+ 	clk_disable_unprepare(dpll5_clk);
+diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h
+index 90f3f472ae1c..13c37f48d9d6 100644
+--- a/drivers/clk/ti/clock.h
++++ b/drivers/clk/ti/clock.h
+@@ -257,11 +257,20 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
+ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
+ 				    unsigned long parent_rate);
+ 
++/*
++ * OMAP3_DPLL5_FREQ_FOR_USBHOST: USBHOST and USBTLL are the only clocks
++ * that are sourced by DPLL5, and both of these require this clock
++ * to be at 120 MHz for proper operation.
++ */
++#define OMAP3_DPLL5_FREQ_FOR_USBHOST	120000000
++
+ unsigned long omap3_dpll_recalc(struct clk_hw *hw, unsigned long parent_rate);
+ int omap3_dpll4_set_rate(struct clk_hw *clk, unsigned long rate,
+ 			 unsigned long parent_rate);
+ int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ 				    unsigned long parent_rate, u8 index);
++int omap3_dpll5_set_rate(struct clk_hw *hw, unsigned long rate,
++			 unsigned long parent_rate);
+ void omap3_clk_lock_dpll5(void);
+ 
+ unsigned long omap4_dpll_regm4xen_recalc(struct clk_hw *hw,
+diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c
+index 9fc8754a6e61..4b9a419d8e14 100644
+--- a/drivers/clk/ti/dpll.c
++++ b/drivers/clk/ti/dpll.c
+@@ -114,6 +114,18 @@ static const struct clk_ops omap3_dpll_ck_ops = {
+ 	.round_rate	= &omap2_dpll_round_rate,
+ };
+ 
++static const struct clk_ops omap3_dpll5_ck_ops = {
++	.enable		= &omap3_noncore_dpll_enable,
++	.disable	= &omap3_noncore_dpll_disable,
++	.get_parent	= &omap2_init_dpll_parent,
++	.recalc_rate	= &omap3_dpll_recalc,
++	.set_rate	= &omap3_dpll5_set_rate,
++	.set_parent	= &omap3_noncore_dpll_set_parent,
++	.set_rate_and_parent	= &omap3_noncore_dpll_set_rate_and_parent,
++	.determine_rate	= &omap3_noncore_dpll_determine_rate,
++	.round_rate	= &omap2_dpll_round_rate,
++};
++
+ static const struct clk_ops omap3_dpll_per_ck_ops = {
+ 	.enable		= &omap3_noncore_dpll_enable,
+ 	.disable	= &omap3_noncore_dpll_disable,
+@@ -474,7 +486,12 @@ static void __init of_ti_omap3_dpll_setup(struct device_node *node)
+ 		.modes = (1 << DPLL_LOW_POWER_BYPASS) | (1 << DPLL_LOCKED),
+ 	};
+ 
+-	of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
++	if ((of_machine_is_compatible("ti,omap3630") ||
++	     of_machine_is_compatible("ti,omap36xx")) &&
++	    !strcmp(node->name, "dpll5_ck"))
++		of_ti_dpll_setup(node, &omap3_dpll5_ck_ops, &dd);
++	else
++		of_ti_dpll_setup(node, &omap3_dpll_ck_ops, &dd);
+ }
+ CLK_OF_DECLARE(ti_omap3_dpll_clock, "ti,omap3-dpll-clock",
+ 	       of_ti_omap3_dpll_setup);
+diff --git a/drivers/clk/ti/dpll3xxx.c b/drivers/clk/ti/dpll3xxx.c
+index 88f2ce81ba55..4cdd28a25584 100644
+--- a/drivers/clk/ti/dpll3xxx.c
++++ b/drivers/clk/ti/dpll3xxx.c
+@@ -838,3 +838,70 @@ int omap3_dpll4_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
+ 	return omap3_noncore_dpll_set_rate_and_parent(hw, rate, parent_rate,
+ 						      index);
+ }
++
++/* Apply DM3730 errata sprz319 advisory 2.1. */
++static bool omap3_dpll5_apply_errata(struct clk_hw *hw,
++				     unsigned long parent_rate)
++{
++	struct omap3_dpll5_settings {
++		unsigned int rate, m, n;
++	};
++
++	static const struct omap3_dpll5_settings precomputed[] = {
++		/*
++		 * From DM3730 errata advisory 2.1, table 35 and 36.
++		 * The N value is increased by 1 compared to the tables as the
++		 * errata lists register values while last_rounded_field is the
++		 * real divider value.
++		 */
++		{ 12000000,  80,  0 + 1 },
++		{ 13000000, 443,  5 + 1 },
++		{ 19200000,  50,  0 + 1 },
++		{ 26000000, 443, 11 + 1 },
++		{ 38400000,  25,  0 + 1 }
++	};
++
++	const struct omap3_dpll5_settings *d;
++	struct clk_hw_omap *clk = to_clk_hw_omap(hw);
++	struct dpll_data *dd;
++	unsigned int i;
++
++	for (i = 0; i < ARRAY_SIZE(precomputed); ++i) {
++		if (parent_rate == precomputed[i].rate)
++			break;
++	}
++
++	if (i == ARRAY_SIZE(precomputed))
++		return false;
++
++	d = &precomputed[i];
++
++	/* Update the M, N and rounded rate values and program the DPLL. */
++	dd = clk->dpll_data;
++	dd->last_rounded_m = d->m;
++	dd->last_rounded_n = d->n;
++	dd->last_rounded_rate = div_u64((u64)parent_rate * d->m, d->n);
++	omap3_noncore_dpll_program(clk, 0);
++
++	return true;
++}
++
++/**
++ * omap3_dpll5_set_rate - set rate for omap3 dpll5
++ * @hw: clock to change
++ * @rate: target rate for clock
++ * @parent_rate: rate of the parent clock
++ *
++ * Set rate for the DPLL5 clock. Apply the sprz319 advisory 2.1 on OMAP36xx if
++ * the DPLL is used for USB host (detected through the requested rate).
++ */
++int omap3_dpll5_set_rate(struct clk_hw *hw, unsigned long rate,
++			 unsigned long parent_rate)
++{
++	if (rate == OMAP3_DPLL5_FREQ_FOR_USBHOST * 8) {
++		if (omap3_dpll5_apply_errata(hw, parent_rate))
++			return 0;
++	}
++
++	return omap3_noncore_dpll_set_rate(hw, rate, parent_rate);
++}
+diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
+index 3957de801ae8..204cd527ff34 100644
+--- a/drivers/cpufreq/cpufreq-dt.c
++++ b/drivers/cpufreq/cpufreq-dt.c
+@@ -26,6 +26,7 @@
+ #include <linux/thermal.h>
+ 
+ struct private_data {
++	struct opp_table *opp_table;
+ 	struct device *cpu_dev;
+ 	struct thermal_cooling_device *cdev;
+ 	const char *reg_name;
+@@ -141,6 +142,7 @@ static int resources_available(void)
+ static int cpufreq_init(struct cpufreq_policy *policy)
+ {
+ 	struct cpufreq_frequency_table *freq_table;
++	struct opp_table *opp_table = NULL;
+ 	struct private_data *priv;
+ 	struct device *cpu_dev;
+ 	struct clk *cpu_clk;
+@@ -184,8 +186,9 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ 	 */
+ 	name = find_supply_name(cpu_dev);
+ 	if (name) {
+-		ret = dev_pm_opp_set_regulator(cpu_dev, name);
+-		if (ret) {
++		opp_table = dev_pm_opp_set_regulator(cpu_dev, name);
++		if (IS_ERR(opp_table)) {
++			ret = PTR_ERR(opp_table);
+ 			dev_err(cpu_dev, "Failed to set regulator for cpu%d: %d\n",
+ 				policy->cpu, ret);
+ 			goto out_put_clk;
+@@ -235,6 +238,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
+ 	}
+ 
+ 	priv->reg_name = name;
++	priv->opp_table = opp_table;
+ 
+ 	ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table);
+ 	if (ret) {
+@@ -283,7 +287,7 @@ out_free_priv:
+ out_free_opp:
+ 	dev_pm_opp_of_cpumask_remove_table(policy->cpus);
+ 	if (name)
+-		dev_pm_opp_put_regulator(cpu_dev);
++		dev_pm_opp_put_regulator(opp_table);
+ out_put_clk:
+ 	clk_put(cpu_clk);
+ 
+@@ -298,7 +302,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
+ 	dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
+ 	dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
+ 	if (priv->reg_name)
+-		dev_pm_opp_put_regulator(priv->cpu_dev);
++		dev_pm_opp_put_regulator(priv->opp_table);
+ 
+ 	clk_put(policy->clk);
+ 	kfree(priv);
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
+index 2cde3796cb82..f3307fc38e79 100644
+--- a/drivers/crypto/caam/caamalg.c
++++ b/drivers/crypto/caam/caamalg.c
+@@ -702,7 +702,9 @@ copy_iv:
+ 
+ 	/* Will read cryptlen */
+ 	append_math_add(desc, VARSEQINLEN, SEQINLEN, REG0, CAAM_CMD_SZ);
+-	aead_append_src_dst(desc, FIFOLD_TYPE_MSG1OUT2);
++	append_seq_fifo_load(desc, 0, FIFOLD_CLASS_BOTH | KEY_VLF |
++			     FIFOLD_TYPE_MSG1OUT2 | FIFOLD_TYPE_LASTBOTH);
++	append_seq_fifo_store(desc, 0, FIFOST_TYPE_MESSAGE_DATA | KEY_VLF);
+ 
+ 	/* Write ICV */
+ 	append_seq_store(desc, ctx->authsize, LDST_CLASS_2_CCB |
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 6fc8923bd92a..bd56a3ecb29c 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -1503,12 +1503,15 @@ static int crypt_set_key(struct crypt_config *cc, char *key)
+ 	if (!cc->key_size && strcmp(key, "-"))
+ 		goto out;
+ 
++	/* clear the flag since following operations may invalidate previously valid key */
++	clear_bit(DM_CRYPT_KEY_VALID, &cc->flags);
++
+ 	if (cc->key_size && crypt_decode_key(cc->key, key, cc->key_size) < 0)
+ 		goto out;
+ 
+-	set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+-
+ 	r = crypt_setkey_allcpus(cc);
++	if (!r)
++		set_bit(DM_CRYPT_KEY_VALID, &cc->flags);
+ 
+ out:
+ 	/* Hex key string not needed after here, so wipe it. */
+diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
+index 6a2e8dd44a1b..3643cba71351 100644
+--- a/drivers/md/dm-flakey.c
++++ b/drivers/md/dm-flakey.c
+@@ -200,11 +200,13 @@ static int flakey_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ 
+ 	if (!(fc->up_interval + fc->down_interval)) {
+ 		ti->error = "Total (up + down) interval is zero";
++		r = -EINVAL;
+ 		goto bad;
+ 	}
+ 
+ 	if (fc->up_interval + fc->down_interval < fc->up_interval) {
+ 		ti->error = "Interval overflow";
++		r = -EINVAL;
+ 		goto bad;
+ 	}
+ 
+diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
+index 6d53810963f7..af2d79b52484 100644
+--- a/drivers/md/dm-raid.c
++++ b/drivers/md/dm-raid.c
+@@ -2994,6 +2994,9 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
+ 		}
+ 	}
+ 
++	/* Disable/enable discard support on raid set. */
++	configure_discard_support(rs);
++
+ 	mddev_unlock(&rs->md);
+ 	return 0;
+ 
+@@ -3580,12 +3583,6 @@ static int raid_preresume(struct dm_target *ti)
+ 	if (test_bit(RT_FLAG_UPDATE_SBS, &rs->runtime_flags))
+ 		rs_update_sbs(rs);
+ 
+-	/*
+-	 * Disable/enable discard support on raid set after any
+-	 * conversion, because devices can have been added
+-	 */
+-	configure_discard_support(rs);
+-
+ 	/* Load the bitmap from disk unless raid0 */
+ 	r = __load_dirty_region_bitmap(rs);
+ 	if (r)
+diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
+index 2154596eedf3..b6af2860cbc6 100644
+--- a/drivers/md/dm-rq.c
++++ b/drivers/md/dm-rq.c
+@@ -218,6 +218,9 @@ static void rq_end_stats(struct mapped_device *md, struct request *orig)
+  */
+ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
+ {
++	struct request_queue *q = md->queue;
++	unsigned long flags;
++
+ 	atomic_dec(&md->pending[rw]);
+ 
+ 	/* nudge anyone waiting on suspend queue */
+@@ -230,8 +233,11 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
+ 	 * back into ->request_fn() could deadlock attempting to grab the
+ 	 * queue lock again.
+ 	 */
+-	if (!md->queue->mq_ops && run_queue)
+-		blk_run_queue_async(md->queue);
++	if (!q->mq_ops && run_queue) {
++		spin_lock_irqsave(q->queue_lock, flags);
++		blk_run_queue_async(q);
++		spin_unlock_irqrestore(q->queue_lock, flags);
++	}
+ 
+ 	/*
+ 	 * dm_put() must be at the end of this function. See the comment above
+diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
+index c4b53b332607..5ac239d0f787 100644
+--- a/drivers/md/dm-table.c
++++ b/drivers/md/dm-table.c
+@@ -924,12 +924,6 @@ static int dm_table_determine_type(struct dm_table *t)
+ 
+ 	BUG_ON(!request_based); /* No targets in this table */
+ 
+-	if (list_empty(devices) && __table_type_request_based(live_md_type)) {
+-		/* inherit live MD type */
+-		t->type = live_md_type;
+-		return 0;
+-	}
+-
+ 	/*
+ 	 * The only way to establish DM_TYPE_MQ_REQUEST_BASED is by
+ 	 * having a compatible target use dm_table_set_type.
+@@ -948,6 +942,19 @@ verify_rq_based:
+ 		return -EINVAL;
+ 	}
+ 
++	if (list_empty(devices)) {
++		int srcu_idx;
++		struct dm_table *live_table = dm_get_live_table(t->md, &srcu_idx);
++
++		/* inherit live table's type and all_blk_mq */
++		if (live_table) {
++			t->type = live_table->type;
++			t->all_blk_mq = live_table->all_blk_mq;
++		}
++		dm_put_live_table(t->md, srcu_idx);
++		return 0;
++	}
++
+ 	/* Non-request-stackable devices can't be used for request-based dm */
+ 	list_for_each_entry(dd, devices, list) {
+ 		struct request_queue *q = bdev_get_queue(dd->dm_dev->bdev);
+@@ -974,6 +981,11 @@ verify_rq_based:
+ 		t->all_blk_mq = true;
+ 	}
+ 
++	if (t->type == DM_TYPE_MQ_REQUEST_BASED && !t->all_blk_mq) {
++		DMERR("table load rejected: all devices are not blk-mq request-stackable");
++		return -EINVAL;
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
+index 7e44005595c1..20557e2c60c6 100644
+--- a/drivers/md/persistent-data/dm-space-map-metadata.c
++++ b/drivers/md/persistent-data/dm-space-map-metadata.c
+@@ -775,17 +775,15 @@ int dm_sm_metadata_create(struct dm_space_map *sm,
+ 	memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+ 
+ 	r = sm_ll_new_metadata(&smm->ll, tm);
++	if (!r) {
++		if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
++			nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
++		r = sm_ll_extend(&smm->ll, nr_blocks);
++	}
++	memcpy(&smm->sm, &ops, sizeof(smm->sm));
+ 	if (r)
+ 		return r;
+ 
+-	if (nr_blocks > DM_SM_METADATA_MAX_BLOCKS)
+-		nr_blocks = DM_SM_METADATA_MAX_BLOCKS;
+-	r = sm_ll_extend(&smm->ll, nr_blocks);
+-	if (r)
+-		return r;
+-
+-	memcpy(&smm->sm, &ops, sizeof(smm->sm));
+-
+ 	/*
+ 	 * Now we need to update the newly created data structures with the
+ 	 * allocated blocks that they were built from.
+diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
+index af5e2dc4a3d5..011f88e5663e 100644
+--- a/drivers/nvme/target/configfs.c
++++ b/drivers/nvme/target/configfs.c
+@@ -271,7 +271,7 @@ static ssize_t nvmet_ns_device_path_store(struct config_item *item,
+ 
+ 	mutex_lock(&subsys->lock);
+ 	ret = -EBUSY;
+-	if (nvmet_ns_enabled(ns))
++	if (ns->enabled)
+ 		goto out_unlock;
+ 
+ 	kfree(ns->device_path);
+@@ -307,7 +307,7 @@ static ssize_t nvmet_ns_device_nguid_store(struct config_item *item,
+ 	int ret = 0;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (nvmet_ns_enabled(ns)) {
++	if (ns->enabled) {
+ 		ret = -EBUSY;
+ 		goto out_unlock;
+ 	}
+@@ -339,7 +339,7 @@ CONFIGFS_ATTR(nvmet_ns_, device_nguid);
+ 
+ static ssize_t nvmet_ns_enable_show(struct config_item *item, char *page)
+ {
+-	return sprintf(page, "%d\n", nvmet_ns_enabled(to_nvmet_ns(item)));
++	return sprintf(page, "%d\n", to_nvmet_ns(item)->enabled);
+ }
+ 
+ static ssize_t nvmet_ns_enable_store(struct config_item *item,
+diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
+index 6559d5afa7bf..e9500d41b943 100644
+--- a/drivers/nvme/target/core.c
++++ b/drivers/nvme/target/core.c
+@@ -264,7 +264,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
+ 	int ret = 0;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (!list_empty(&ns->dev_link))
++	if (ns->enabled)
+ 		goto out_unlock;
+ 
+ 	ns->bdev = blkdev_get_by_path(ns->device_path, FMODE_READ | FMODE_WRITE,
+@@ -309,6 +309,7 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
+ 	list_for_each_entry(ctrl, &subsys->ctrls, subsys_entry)
+ 		nvmet_add_async_event(ctrl, NVME_AER_TYPE_NOTICE, 0, 0);
+ 
++	ns->enabled = true;
+ 	ret = 0;
+ out_unlock:
+ 	mutex_unlock(&subsys->lock);
+@@ -325,11 +326,11 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
+ 	struct nvmet_ctrl *ctrl;
+ 
+ 	mutex_lock(&subsys->lock);
+-	if (list_empty(&ns->dev_link)) {
+-		mutex_unlock(&subsys->lock);
+-		return;
+-	}
+-	list_del_init(&ns->dev_link);
++	if (!ns->enabled)
++		goto out_unlock;
++
++	ns->enabled = false;
++	list_del_rcu(&ns->dev_link);
+ 	mutex_unlock(&subsys->lock);
+ 
+ 	/*
+@@ -351,6 +352,7 @@ void nvmet_ns_disable(struct nvmet_ns *ns)
+ 
+ 	if (ns->bdev)
+ 		blkdev_put(ns->bdev, FMODE_WRITE|FMODE_READ);
++out_unlock:
+ 	mutex_unlock(&subsys->lock);
+ }
+ 
+diff --git a/drivers/nvme/target/nvmet.h b/drivers/nvme/target/nvmet.h
+index 76b6eedccaf9..7655a351320f 100644
+--- a/drivers/nvme/target/nvmet.h
++++ b/drivers/nvme/target/nvmet.h
+@@ -47,6 +47,7 @@ struct nvmet_ns {
+ 	loff_t			size;
+ 	u8			nguid[16];
+ 
++	bool			enabled;
+ 	struct nvmet_subsys	*subsys;
+ 	const char		*device_path;
+ 
+@@ -61,11 +62,6 @@ static inline struct nvmet_ns *to_nvmet_ns(struct config_item *item)
+ 	return container_of(to_config_group(item), struct nvmet_ns, group);
+ }
+ 
+-static inline bool nvmet_ns_enabled(struct nvmet_ns *ns)
+-{
+-	return !list_empty_careful(&ns->dev_link);
+-}
+-
+ struct nvmet_cq {
+ 	u16			qid;
+ 	u16			size;
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index 3ca9fdb0a271..3f9ac8be77e1 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1732,6 +1732,7 @@ static const struct usb_device_id acm_ids[] = {
+ 	{ USB_DEVICE(0x20df, 0x0001), /* Simtec Electronics Entropy Key */
+ 	.driver_info = QUIRK_CONTROL_LINE_STATE, },
+ 	{ USB_DEVICE(0x2184, 0x001c) },	/* GW Instek AFG-2225 */
++	{ USB_DEVICE(0x2184, 0x0036) },	/* GW Instek AFG-125 */
+ 	{ USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */
+ 	},
+ 	/* Motorola H24 HSPA module: */
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 1d5fc32d06d0..f3a7408d6417 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -101,6 +101,8 @@ EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem);
+ 
+ static void hub_release(struct kref *kref);
+ static int usb_reset_and_verify_device(struct usb_device *udev);
++static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++					  struct usb_port *port_dev);
+ 
+ static inline char *portspeed(struct usb_hub *hub, int portstatus)
+ {
+@@ -899,82 +901,28 @@ static int hub_set_port_link_state(struct usb_hub *hub, int port1,
+ }
+ 
+ /*
+- * If USB 3.0 ports are placed into the Disabled state, they will no longer
+- * detect any device connects or disconnects.  This is generally not what the
+- * USB core wants, since it expects a disabled port to produce a port status
+- * change event when a new device connects.
+- *
+- * Instead, set the link state to Disabled, wait for the link to settle into
+- * that state, clear any change bits, and then put the port into the RxDetect
+- * state.
++ * USB-3 does not have a similar link state as USB-2 that will avoid negotiating
++ * a connection with a plugged-in cable but will signal the host when the cable
++ * is unplugged. Disable remote wake and set link state to U3 for USB-3 devices
+  */
+-static int hub_usb3_port_disable(struct usb_hub *hub, int port1)
+-{
+-	int ret;
+-	int total_time;
+-	u16 portchange, portstatus;
+-
+-	if (!hub_is_superspeed(hub->hdev))
+-		return -EINVAL;
+-
+-	ret = hub_port_status(hub, port1, &portstatus, &portchange);
+-	if (ret < 0)
+-		return ret;
+-
+-	/*
+-	 * USB controller Advanced Micro Devices, Inc. [AMD] FCH USB XHCI
+-	 * Controller [1022:7814] will have spurious result making the following
+-	 * usb 3.0 device hotplugging route to the 2.0 root hub and recognized
+-	 * as high-speed device if we set the usb 3.0 port link state to
+-	 * Disabled. Since it's already in USB_SS_PORT_LS_RX_DETECT state, we
+-	 * check the state here to avoid the bug.
+-	 */
+-	if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+-				USB_SS_PORT_LS_RX_DETECT) {
+-		dev_dbg(&hub->ports[port1 - 1]->dev,
+-			 "Not disabling port; link state is RxDetect\n");
+-		return ret;
+-	}
+-
+-	ret = hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_SS_DISABLED);
+-	if (ret)
+-		return ret;
+-
+-	/* Wait for the link to enter the disabled state. */
+-	for (total_time = 0; ; total_time += HUB_DEBOUNCE_STEP) {
+-		ret = hub_port_status(hub, port1, &portstatus, &portchange);
+-		if (ret < 0)
+-			return ret;
+-
+-		if ((portstatus & USB_PORT_STAT_LINK_STATE) ==
+-				USB_SS_PORT_LS_SS_DISABLED)
+-			break;
+-		if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+-			break;
+-		msleep(HUB_DEBOUNCE_STEP);
+-	}
+-	if (total_time >= HUB_DEBOUNCE_TIMEOUT)
+-		dev_warn(&hub->ports[port1 - 1]->dev,
+-				"Could not disable after %d ms\n", total_time);
+-
+-	return hub_set_port_link_state(hub, port1, USB_SS_PORT_LS_RX_DETECT);
+-}
+-
+ static int hub_port_disable(struct usb_hub *hub, int port1, int set_state)
+ {
+ 	struct usb_port *port_dev = hub->ports[port1 - 1];
+ 	struct usb_device *hdev = hub->hdev;
+ 	int ret = 0;
+ 
+-	if (port_dev->child && set_state)
+-		usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+ 	if (!hub->error) {
+-		if (hub_is_superspeed(hub->hdev))
+-			ret = hub_usb3_port_disable(hub, port1);
+-		else
++		if (hub_is_superspeed(hub->hdev)) {
++			hub_usb3_port_prepare_disable(hub, port_dev);
++			ret = hub_set_port_link_state(hub, port_dev->portnum,
++						      USB_SS_PORT_LS_U3);
++		} else {
+ 			ret = usb_clear_port_feature(hdev, port1,
+ 					USB_PORT_FEAT_ENABLE);
++		}
+ 	}
++	if (port_dev->child && set_state)
++		usb_set_device_state(port_dev->child, USB_STATE_NOTATTACHED);
+ 	if (ret && ret != -ENODEV)
+ 		dev_err(&port_dev->dev, "cannot disable (err = %d)\n", ret);
+ 	return ret;
+@@ -4142,6 +4090,26 @@ void usb_unlocked_enable_lpm(struct usb_device *udev)
+ }
+ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
+ 
++/* usb3 devices use U3 for disabled, make sure remote wakeup is disabled */
++static void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++					  struct usb_port *port_dev)
++{
++	struct usb_device *udev = port_dev->child;
++	int ret;
++
++	if (udev && udev->port_is_suspended && udev->do_remote_wakeup) {
++		ret = hub_set_port_link_state(hub, port_dev->portnum,
++					      USB_SS_PORT_LS_U0);
++		if (!ret) {
++			msleep(USB_RESUME_TIMEOUT);
++			ret = usb_disable_remote_wakeup(udev);
++		}
++		if (ret)
++			dev_warn(&udev->dev,
++				 "Port disable: can't disable remote wake\n");
++		udev->do_remote_wakeup = 0;
++	}
++}
+ 
+ #else	/* CONFIG_PM */
+ 
+@@ -4149,6 +4117,9 @@ EXPORT_SYMBOL_GPL(usb_unlocked_enable_lpm);
+ #define hub_resume		NULL
+ #define hub_reset_resume	NULL
+ 
++static inline void hub_usb3_port_prepare_disable(struct usb_hub *hub,
++						 struct usb_port *port_dev) { }
++
+ int usb_disable_lpm(struct usb_device *udev)
+ {
+ 	return 0;
+diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
+index dc3b5962d087..717d5f6d3e7c 100644
+--- a/drivers/usb/dwc3/gadget.c
++++ b/drivers/usb/dwc3/gadget.c
+@@ -775,6 +775,9 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 		unsigned length, unsigned last, unsigned chain, unsigned node)
+ {
+ 	struct dwc3_trb		*trb;
++	struct dwc3		*dwc = dep->dwc;
++	struct usb_gadget	*gadget = &dwc->gadget;
++	enum usb_device_speed	speed = gadget->speed;
+ 
+ 	dwc3_trace(trace_dwc3_gadget, "%s: req %p dma %08llx length %d%s%s",
+ 			dep->name, req, (unsigned long long) dma,
+@@ -804,10 +807,16 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
+ 		break;
+ 
+ 	case USB_ENDPOINT_XFER_ISOC:
+-		if (!node)
++		if (!node) {
+ 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
+-		else
++
++			if (speed == USB_SPEED_HIGH) {
++				struct usb_ep *ep = &dep->endpoint;
++				trb->size |= DWC3_TRB_SIZE_PCM1(ep->mult - 1);
++			}
++		} else {
+ 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
++		}
+ 
+ 		/* always enable Interrupt on Missed ISOC */
+ 		trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
+diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
+index 5ebe6af7976e..e2abaa7943d9 100644
+--- a/drivers/usb/gadget/composite.c
++++ b/drivers/usb/gadget/composite.c
+@@ -197,11 +197,16 @@ int config_ep_by_speed(struct usb_gadget *g,
+ 
+ ep_found:
+ 	/* commit results */
+-	_ep->maxpacket = usb_endpoint_maxp(chosen_desc);
++	_ep->maxpacket = usb_endpoint_maxp(chosen_desc) & 0x7ff;
+ 	_ep->desc = chosen_desc;
+ 	_ep->comp_desc = NULL;
+ 	_ep->maxburst = 0;
+-	_ep->mult = 0;
++	_ep->mult = 1;
++
++	if (g->speed == USB_SPEED_HIGH && (usb_endpoint_xfer_isoc(_ep->desc) ||
++				usb_endpoint_xfer_int(_ep->desc)))
++		_ep->mult = usb_endpoint_maxp(_ep->desc) & 0x7ff;
++
+ 	if (!want_comp_desc)
+ 		return 0;
+ 
+@@ -218,7 +223,7 @@ ep_found:
+ 		switch (usb_endpoint_type(_ep->desc)) {
+ 		case USB_ENDPOINT_XFER_ISOC:
+ 			/* mult: bits 1:0 of bmAttributes */
+-			_ep->mult = comp_desc->bmAttributes & 0x3;
++			_ep->mult = (comp_desc->bmAttributes & 0x3) + 1;
+ 		case USB_ENDPOINT_XFER_BULK:
+ 		case USB_ENDPOINT_XFER_INT:
+ 			_ep->maxburst = comp_desc->bMaxBurst + 1;
+diff --git a/drivers/usb/gadget/function/f_uac2.c b/drivers/usb/gadget/function/f_uac2.c
+index cd214ec8a601..969cfe741380 100644
+--- a/drivers/usb/gadget/function/f_uac2.c
++++ b/drivers/usb/gadget/function/f_uac2.c
+@@ -1067,13 +1067,13 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	agdev->out_ep = usb_ep_autoconfig(gadget, &fs_epout_desc);
+ 	if (!agdev->out_ep) {
+ 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	agdev->in_ep = usb_ep_autoconfig(gadget, &fs_epin_desc);
+ 	if (!agdev->in_ep) {
+ 		dev_err(dev, "%s:%d Error!\n", __func__, __LINE__);
+-		goto err;
++		return ret;
+ 	}
+ 
+ 	uac2->p_prm.uac2 = uac2;
+@@ -1091,7 +1091,7 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	ret = usb_assign_descriptors(fn, fs_audio_desc, hs_audio_desc, NULL,
+ 				     NULL);
+ 	if (ret)
+-		goto err;
++		return ret;
+ 
+ 	prm = &agdev->uac2.c_prm;
+ 	prm->max_psize = hs_epout_desc.wMaxPacketSize;
+@@ -1106,19 +1106,19 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
+ 	prm->rbuf = kzalloc(prm->max_psize * USB_XFERS, GFP_KERNEL);
+ 	if (!prm->rbuf) {
+ 		prm->max_psize = 0;
+-		goto err_free_descs;
++		goto err;
+ 	}
+ 
+ 	ret = alsa_uac2_init(agdev);
+ 	if (ret)
+-		goto err_free_descs;
++		goto err;
+ 	return 0;
+ 
+-err_free_descs:
+-	usb_free_all_descriptors(fn);
+ err:
+ 	kfree(agdev->uac2.p_prm.rbuf);
+ 	kfree(agdev->uac2.c_prm.rbuf);
++err_free_descs:
++	usb_free_all_descriptors(fn);
+ 	return -EINVAL;
+ }
+ 
+diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
+index 3d0d5d94a62f..0f01c04d7cbd 100644
+--- a/drivers/usb/gadget/function/uvc_video.c
++++ b/drivers/usb/gadget/function/uvc_video.c
+@@ -243,7 +243,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
+ 
+ 	req_size = video->ep->maxpacket
+ 		 * max_t(unsigned int, video->ep->maxburst, 1)
+-		 * (video->ep->mult + 1);
++		 * (video->ep->mult);
+ 
+ 	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
+ 		video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
+diff --git a/drivers/usb/host/uhci-pci.c b/drivers/usb/host/uhci-pci.c
+index 940304c33224..02260cfdedb1 100644
+--- a/drivers/usb/host/uhci-pci.c
++++ b/drivers/usb/host/uhci-pci.c
+@@ -129,6 +129,10 @@ static int uhci_pci_init(struct usb_hcd *hcd)
+ 	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_HP)
+ 		uhci->wait_for_hp = 1;
+ 
++	/* Intel controllers use non-PME wakeup signalling */
++	if (to_pci_dev(uhci_dev(uhci))->vendor == PCI_VENDOR_ID_INTEL)
++		device_set_run_wake(uhci_dev(uhci), 1);
++
+ 	/* Set up pointers to PCI-specific functions */
+ 	uhci->reset_hc = uhci_pci_reset_hc;
+ 	uhci->check_and_reset_hc = uhci_pci_check_and_reset_hc;
+diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c
+index fc5d3a791e08..6f29bfadbe33 100644
+--- a/drivers/usb/serial/kl5kusb105.c
++++ b/drivers/usb/serial/kl5kusb105.c
+@@ -296,7 +296,7 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
+ 	rc = usb_serial_generic_open(tty, port);
+ 	if (rc) {
+ 		retval = rc;
+-		goto exit;
++		goto err_free_cfg;
+ 	}
+ 
+ 	rc = usb_control_msg(port->serial->dev,
+@@ -315,17 +315,32 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
+ 		dev_dbg(&port->dev, "%s - enabled reading\n", __func__);
+ 
+ 	rc = klsi_105_get_line_state(port, &line_state);
+-	if (rc >= 0) {
+-		spin_lock_irqsave(&priv->lock, flags);
+-		priv->line_state = line_state;
+-		spin_unlock_irqrestore(&priv->lock, flags);
+-		dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__, line_state);
+-		retval = 0;
+-	} else
++	if (rc < 0) {
+ 		retval = rc;
++		goto err_disable_read;
++	}
++
++	spin_lock_irqsave(&priv->lock, flags);
++	priv->line_state = line_state;
++	spin_unlock_irqrestore(&priv->lock, flags);
++	dev_dbg(&port->dev, "%s - read line state 0x%lx\n", __func__,
++			line_state);
++
++	return 0;
+ 
+-exit:
++err_disable_read:
++	usb_control_msg(port->serial->dev,
++			     usb_sndctrlpipe(port->serial->dev, 0),
++			     KL5KUSB105A_SIO_CONFIGURE,
++			     USB_TYPE_VENDOR | USB_DIR_OUT,
++			     KL5KUSB105A_SIO_CONFIGURE_READ_OFF,
++			     0, /* index */
++			     NULL, 0,
++			     KLSI_TIMEOUT);
++	usb_serial_generic_close(port);
++err_free_cfg:
+ 	kfree(cfg);
++
+ 	return retval;
+ }
+ 
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index 9894e341c6ac..7ce31a4c7e7f 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -268,6 +268,8 @@ static void option_instat_callback(struct urb *urb);
+ #define TELIT_PRODUCT_CC864_SINGLE		0x1006
+ #define TELIT_PRODUCT_DE910_DUAL		0x1010
+ #define TELIT_PRODUCT_UE910_V2			0x1012
++#define TELIT_PRODUCT_LE922_USBCFG1		0x1040
++#define TELIT_PRODUCT_LE922_USBCFG2		0x1041
+ #define TELIT_PRODUCT_LE922_USBCFG0		0x1042
+ #define TELIT_PRODUCT_LE922_USBCFG3		0x1043
+ #define TELIT_PRODUCT_LE922_USBCFG5		0x1045
+@@ -1210,6 +1212,10 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG0),
+ 		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
++	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG1),
++		.driver_info = (kernel_ulong_t)&telit_le910_blacklist },
++	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG2),
++		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+ 	{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
+ 		.driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
+ 	{ USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
+@@ -1989,6 +1995,7 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d02, 0xff, 0x00, 0x00) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x02, 0x01) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x2001, 0x7d03, 0xff, 0x00, 0x00) },
++	{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7d04, 0xff) },			/* D-Link DWM-158 */
+ 	{ USB_DEVICE_INTERFACE_CLASS(0x2001, 0x7e19, 0xff),			/* D-Link DWM-221 B1 */
+ 	  .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(0x07d1, 0x3e01, 0xff, 0xff, 0xff) }, /* D-Link DWM-152/C1 */
+diff --git a/drivers/usb/usbip/vudc_transfer.c b/drivers/usb/usbip/vudc_transfer.c
+index aba6bd478045..bc0296d937d0 100644
+--- a/drivers/usb/usbip/vudc_transfer.c
++++ b/drivers/usb/usbip/vudc_transfer.c
+@@ -339,6 +339,8 @@ static void v_timer(unsigned long _vudc)
+ 		total = timer->frame_limit;
+ 	}
+ 
++	/* We have to clear ep0 flags separately as it's not on the list */
++	udc->ep[0].already_seen = 0;
+ 	list_for_each_entry(_ep, &udc->gadget.ep_list, ep_list) {
+ 		ep = to_vep(_ep);
+ 		ep->already_seen = 0;
+diff --git a/drivers/watchdog/mei_wdt.c b/drivers/watchdog/mei_wdt.c
+index 630bd189f167..2a9d5cdedea2 100644
+--- a/drivers/watchdog/mei_wdt.c
++++ b/drivers/watchdog/mei_wdt.c
+@@ -389,6 +389,8 @@ static int mei_wdt_register(struct mei_wdt *wdt)
+ 	wdt->wdd.max_timeout = MEI_WDT_MAX_TIMEOUT;
+ 
+ 	watchdog_set_drvdata(&wdt->wdd, wdt);
++	watchdog_stop_on_reboot(&wdt->wdd);
++
+ 	ret = watchdog_register_device(&wdt->wdd);
+ 	if (ret) {
+ 		dev_err(dev, "unable to register watchdog device = %d.\n", ret);
+diff --git a/drivers/watchdog/qcom-wdt.c b/drivers/watchdog/qcom-wdt.c
+index 5796b5d1b3f2..4f47b5e90956 100644
+--- a/drivers/watchdog/qcom-wdt.c
++++ b/drivers/watchdog/qcom-wdt.c
+@@ -209,7 +209,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
+ 	wdt->wdd.parent = &pdev->dev;
+ 	wdt->layout = regs;
+ 
+-	if (readl(wdt->base + WDT_STS) & 1)
++	if (readl(wdt_addr(wdt, WDT_STS)) & 1)
+ 		wdt->wdd.bootstatus = WDIOF_CARDRESET;
+ 
+ 	/*
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
+index bb952121ea94..2ef2b61b69df 100644
+--- a/drivers/xen/gntdev.c
++++ b/drivers/xen/gntdev.c
+@@ -1007,7 +1007,7 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
+ 
+ 	vma->vm_ops = &gntdev_vmops;
+ 
+-	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_IO;
++	vma->vm_flags |= VM_DONTEXPAND | VM_DONTDUMP | VM_MIXEDMAP;
+ 
+ 	if (use_ptemod)
+ 		vma->vm_flags |= VM_DONTCOPY;
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index 08ae99343d92..b010242bab32 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -837,7 +837,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole,
+ 		return true;	 /* already a holder */
+ 	else if (bdev->bd_holder != NULL)
+ 		return false; 	 /* held by someone else */
+-	else if (bdev->bd_contains == bdev)
++	else if (whole == bdev)
+ 		return true;  	 /* is a whole device which isn't held */
+ 
+ 	else if (whole->bd_holder == bd_may_claim)
+diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
+index e0f071f6b5a7..63d197724519 100644
+--- a/fs/btrfs/async-thread.c
++++ b/fs/btrfs/async-thread.c
+@@ -86,6 +86,20 @@ btrfs_work_owner(struct btrfs_work *work)
+ 	return work->wq->fs_info;
+ }
+ 
++bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq)
++{
++	/*
++	 * We could compare wq->normal->pending with num_online_cpus()
++	 * to support "thresh == NO_THRESHOLD" case, but it requires
++	 * moving up atomic_inc/dec in thresh_queue/exec_hook. Let's
++	 * postpone it until someone needs the support of that case.
++	 */
++	if (wq->normal->thresh == NO_THRESHOLD)
++		return false;
++
++	return atomic_read(&wq->normal->pending) > wq->normal->thresh * 2;
++}
++
+ BTRFS_WORK_HELPER(worker_helper);
+ BTRFS_WORK_HELPER(delalloc_helper);
+ BTRFS_WORK_HELPER(flush_delalloc_helper);
+diff --git a/fs/btrfs/async-thread.h b/fs/btrfs/async-thread.h
+index 8e52484cd461..1f9597355c9d 100644
+--- a/fs/btrfs/async-thread.h
++++ b/fs/btrfs/async-thread.h
+@@ -84,4 +84,5 @@ void btrfs_workqueue_set_max(struct btrfs_workqueue *wq, int max);
+ void btrfs_set_work_high_priority(struct btrfs_work *work);
+ struct btrfs_fs_info *btrfs_work_owner(struct btrfs_work *work);
+ struct btrfs_fs_info *btrfs_workqueue_owner(struct __btrfs_workqueue *wq);
++bool btrfs_workqueue_normal_congested(struct btrfs_workqueue *wq);
+ #endif
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 791e47ce9d27..469fa3268d9b 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2210,6 +2210,8 @@ btrfs_disk_balance_args_to_cpu(struct btrfs_balance_args *cpu,
+ 	cpu->target = le64_to_cpu(disk->target);
+ 	cpu->flags = le64_to_cpu(disk->flags);
+ 	cpu->limit = le64_to_cpu(disk->limit);
++	cpu->stripes_min = le32_to_cpu(disk->stripes_min);
++	cpu->stripes_max = le32_to_cpu(disk->stripes_max);
+ }
+ 
+ static inline void
+@@ -2228,6 +2230,8 @@ btrfs_cpu_balance_args_to_disk(struct btrfs_disk_balance_args *disk,
+ 	disk->target = cpu_to_le64(cpu->target);
+ 	disk->flags = cpu_to_le64(cpu->flags);
+ 	disk->limit = cpu_to_le64(cpu->limit);
++	disk->stripes_min = cpu_to_le32(cpu->stripes_min);
++	disk->stripes_max = cpu_to_le32(cpu->stripes_max);
+ }
+ 
+ /* struct btrfs_super_block */
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 3eeb9cd8cfa5..de946dd743b7 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1356,7 +1356,8 @@ release_path:
+ 	total_done++;
+ 
+ 	btrfs_release_prepared_delayed_node(delayed_node);
+-	if (async_work->nr == 0 || total_done < async_work->nr)
++	if ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK) ||
++	    total_done < async_work->nr)
+ 		goto again;
+ 
+ free_path:
+@@ -1372,7 +1373,8 @@ static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
+ {
+ 	struct btrfs_async_delayed_work *async_work;
+ 
+-	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
++	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND ||
++	    btrfs_workqueue_normal_congested(fs_info->delayed_workers))
+ 		return 0;
+ 
+ 	async_work = kmalloc(sizeof(*async_work), GFP_NOFS);
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 3dede6d53bad..dafcfd017d37 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -559,7 +559,15 @@ static noinline int check_leaf(struct btrfs_root *root,
+ 	u32 nritems = btrfs_header_nritems(leaf);
+ 	int slot;
+ 
+-	if (nritems == 0) {
++	/*
++	 * Extent buffers from a relocation tree have a owner field that
++	 * corresponds to the subvolume tree they are based on. So just from an
++	 * extent buffer alone we can not find out what is the id of the
++	 * corresponding subvolume tree, so we can not figure out if the extent
++	 * buffer corresponds to the root of the relocation tree or not. So skip
++	 * this check for relocation trees.
++	 */
++	if (nritems == 0 && !btrfs_header_flag(leaf, BTRFS_HEADER_FLAG_RELOC)) {
+ 		struct btrfs_root *check_root;
+ 
+ 		key.objectid = btrfs_header_owner(leaf);
+@@ -572,17 +580,24 @@ static noinline int check_leaf(struct btrfs_root *root,
+ 		 * open_ctree() some roots has not yet been set up.
+ 		 */
+ 		if (!IS_ERR_OR_NULL(check_root)) {
++			struct extent_buffer *eb;
++
++			eb = btrfs_root_node(check_root);
+ 			/* if leaf is the root, then it's fine */
+-			if (leaf->start !=
+-			    btrfs_root_bytenr(&check_root->root_item)) {
++			if (leaf != eb) {
+ 				CORRUPT("non-root leaf's nritems is 0",
+-					leaf, root, 0);
++					leaf, check_root, 0);
++				free_extent_buffer(eb);
+ 				return -EIO;
+ 			}
++			free_extent_buffer(eb);
+ 		}
+ 		return 0;
+ 	}
+ 
++	if (nritems == 0)
++		return 0;
++
+ 	/* Check the 0 item */
+ 	if (btrfs_item_offset_nr(leaf, 0) + btrfs_item_size_nr(leaf, 0) !=
+ 	    BTRFS_LEAF_DATA_SIZE(root)) {
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 665da8f66ff1..a1b40ab5770a 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -8884,14 +8884,13 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
+ 	ret = btrfs_lookup_extent_info(trans, root, bytenr, level - 1, 1,
+ 				       &wc->refs[level - 1],
+ 				       &wc->flags[level - 1]);
+-	if (ret < 0) {
+-		btrfs_tree_unlock(next);
+-		return ret;
+-	}
++	if (ret < 0)
++		goto out_unlock;
+ 
+ 	if (unlikely(wc->refs[level - 1] == 0)) {
+ 		btrfs_err(root->fs_info, "Missing references.");
+-		BUG();
++		ret = -EIO;
++		goto out_unlock;
+ 	}
+ 	*lookup_info = 0;
+ 
+@@ -8943,7 +8942,12 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
+ 	}
+ 
+ 	level--;
+-	BUG_ON(level != btrfs_header_level(next));
++	ASSERT(level == btrfs_header_level(next));
++	if (level != btrfs_header_level(next)) {
++		btrfs_err(root->fs_info, "mismatched level");
++		ret = -EIO;
++		goto out_unlock;
++	}
+ 	path->nodes[level] = next;
+ 	path->slots[level] = 0;
+ 	path->locks[level] = BTRFS_WRITE_LOCK_BLOCKING;
+@@ -8958,8 +8962,15 @@ skip:
+ 		if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) {
+ 			parent = path->nodes[level]->start;
+ 		} else {
+-			BUG_ON(root->root_key.objectid !=
++			ASSERT(root->root_key.objectid ==
+ 			       btrfs_header_owner(path->nodes[level]));
++			if (root->root_key.objectid !=
++			    btrfs_header_owner(path->nodes[level])) {
++				btrfs_err(root->fs_info,
++						"mismatched block owner");
++				ret = -EIO;
++				goto out_unlock;
++			}
+ 			parent = 0;
+ 		}
+ 
+@@ -8976,12 +8987,18 @@ skip:
+ 		}
+ 		ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent,
+ 				root->root_key.objectid, level - 1, 0);
+-		BUG_ON(ret); /* -ENOMEM */
++		if (ret)
++			goto out_unlock;
+ 	}
++
++	*lookup_info = 1;
++	ret = 1;
++
++out_unlock:
+ 	btrfs_tree_unlock(next);
+ 	free_extent_buffer(next);
+-	*lookup_info = 1;
+-	return 1;
++
++	return ret;
+ }
+ 
+ /*
+@@ -10127,6 +10144,11 @@ int btrfs_read_block_groups(struct btrfs_root *root)
+ 	struct extent_buffer *leaf;
+ 	int need_clear = 0;
+ 	u64 cache_gen;
++	u64 feature;
++	int mixed;
++
++	feature = btrfs_super_incompat_flags(info->super_copy);
++	mixed = !!(feature & BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS);
+ 
+ 	root = info->extent_root;
+ 	key.objectid = 0;
+@@ -10180,6 +10202,15 @@ int btrfs_read_block_groups(struct btrfs_root *root)
+ 				   btrfs_item_ptr_offset(leaf, path->slots[0]),
+ 				   sizeof(cache->item));
+ 		cache->flags = btrfs_block_group_flags(&cache->item);
++		if (!mixed &&
++		    ((cache->flags & BTRFS_BLOCK_GROUP_METADATA) &&
++		    (cache->flags & BTRFS_BLOCK_GROUP_DATA))) {
++			btrfs_err(info,
++"bg %llu is a mixed block group but filesystem hasn't enabled mixed block groups",
++				  cache->key.objectid);
++			ret = -EINVAL;
++			goto error;
++		}
+ 
+ 		key.objectid = found_key.objectid + found_key.offset;
+ 		btrfs_release_path(path);
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index c3ec30dea9a5..3f9a6b40fbbd 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -5209,11 +5209,20 @@ int read_extent_buffer_pages(struct extent_io_tree *tree,
+ 			lock_page(page);
+ 		}
+ 		locked_pages++;
++	}
++	/*
++	 * We need to firstly lock all pages to make sure that
++	 * the uptodate bit of our pages won't be affected by
++	 * clear_extent_buffer_uptodate().
++	 */
++	for (i = start_i; i < num_pages; i++) {
++		page = eb->pages[i];
+ 		if (!PageUptodate(page)) {
+ 			num_reads++;
+ 			all_uptodate = 0;
+ 		}
+ 	}
++
+ 	if (all_uptodate) {
+ 		if (start_i == 0)
+ 			set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 7fd939bfbd99..fcd2b3be21bf 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -3813,6 +3813,11 @@ process_slot:
+ 		}
+ 		btrfs_release_path(path);
+ 		key.offset = next_key_min_offset;
++
++		if (fatal_signal_pending(current)) {
++			ret = -EINTR;
++			goto out;
++		}
+ 	}
+ 	ret = 0;
+ 
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c
+index 8db2e29fdcf4..9cf03ebb27cc 100644
+--- a/fs/btrfs/qgroup.c
++++ b/fs/btrfs/qgroup.c
+@@ -2332,10 +2332,6 @@ static void btrfs_qgroup_rescan_worker(struct btrfs_work *work)
+ 	int err = -ENOMEM;
+ 	int ret = 0;
+ 
+-	mutex_lock(&fs_info->qgroup_rescan_lock);
+-	fs_info->qgroup_rescan_running = true;
+-	mutex_unlock(&fs_info->qgroup_rescan_lock);
+-
+ 	path = btrfs_alloc_path();
+ 	if (!path)
+ 		goto out;
+@@ -2446,6 +2442,7 @@ qgroup_rescan_init(struct btrfs_fs_info *fs_info, u64 progress_objectid,
+ 		sizeof(fs_info->qgroup_rescan_progress));
+ 	fs_info->qgroup_rescan_progress.objectid = progress_objectid;
+ 	init_completion(&fs_info->qgroup_rescan_completion);
++	fs_info->qgroup_rescan_running = true;
+ 
+ 	spin_unlock(&fs_info->qgroup_lock);
+ 	mutex_unlock(&fs_info->qgroup_rescan_lock);
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index c0c13dc6fe12..d08a79dbf323 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -923,9 +923,16 @@ again:
+ 			path2->slots[level]--;
+ 
+ 		eb = path2->nodes[level];
+-		WARN_ON(btrfs_node_blockptr(eb, path2->slots[level]) !=
+-			cur->bytenr);
+-
++		if (btrfs_node_blockptr(eb, path2->slots[level]) !=
++		    cur->bytenr) {
++			btrfs_err(root->fs_info,
++	"couldn't find block (%llu) (level %d) in tree (%llu) with key (%llu %u %llu)",
++				  cur->bytenr, level - 1, root->objectid,
++				  node_key->objectid, node_key->type,
++				  node_key->offset);
++			err = -ENOENT;
++			goto out;
++		}
+ 		lower = cur;
+ 		need_check = true;
+ 		for (; level < BTRFS_MAX_LEVEL; level++) {
+@@ -1387,14 +1394,23 @@ static struct btrfs_root *create_reloc_root(struct btrfs_trans_handle *trans,
+ 	root_key.offset = objectid;
+ 
+ 	if (root->root_key.objectid == objectid) {
++		u64 commit_root_gen;
++
+ 		/* called by btrfs_init_reloc_root */
+ 		ret = btrfs_copy_root(trans, root, root->commit_root, &eb,
+ 				      BTRFS_TREE_RELOC_OBJECTID);
+ 		BUG_ON(ret);
+-
+ 		last_snap = btrfs_root_last_snapshot(&root->root_item);
+-		btrfs_set_root_last_snapshot(&root->root_item,
+-					     trans->transid - 1);
++		/*
++		 * Set the last_snapshot field to the generation of the commit
++		 * root - like this ctree.c:btrfs_block_can_be_shared() behaves
++		 * correctly (returns true) when the relocation root is created
++		 * either inside the critical section of a transaction commit
++		 * (through transaction.c:qgroup_account_snapshot()) and when
++		 * it's created before the transaction commit is started.
++		 */
++		commit_root_gen = btrfs_header_generation(root->commit_root);
++		btrfs_set_root_last_snapshot(&root->root_item, commit_root_gen);
+ 	} else {
+ 		/*
+ 		 * called by btrfs_reloc_post_snapshot_hook.
+@@ -2350,6 +2366,10 @@ void free_reloc_roots(struct list_head *list)
+ 	while (!list_empty(list)) {
+ 		reloc_root = list_entry(list->next, struct btrfs_root,
+ 					root_list);
++		free_extent_buffer(reloc_root->node);
++		free_extent_buffer(reloc_root->commit_root);
++		reloc_root->node = NULL;
++		reloc_root->commit_root = NULL;
+ 		__del_reloc_root(reloc_root);
+ 	}
+ }
+@@ -2686,11 +2706,15 @@ static int do_relocation(struct btrfs_trans_handle *trans,
+ 
+ 		if (!upper->eb) {
+ 			ret = btrfs_search_slot(trans, root, key, path, 0, 1);
+-			if (ret < 0) {
+-				err = ret;
++			if (ret) {
++				if (ret < 0)
++					err = ret;
++				else
++					err = -ENOENT;
++
++				btrfs_release_path(path);
+ 				break;
+ 			}
+-			BUG_ON(ret > 0);
+ 
+ 			if (!upper->eb) {
+ 				upper->eb = path->nodes[upper->level];
+diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
+index a87675ffd02b..563878a141a3 100644
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -5802,6 +5802,64 @@ static int changed_extent(struct send_ctx *sctx,
+ 	int ret = 0;
+ 
+ 	if (sctx->cur_ino != sctx->cmp_key->objectid) {
++
++		if (result == BTRFS_COMPARE_TREE_CHANGED) {
++			struct extent_buffer *leaf_l;
++			struct extent_buffer *leaf_r;
++			struct btrfs_file_extent_item *ei_l;
++			struct btrfs_file_extent_item *ei_r;
++
++			leaf_l = sctx->left_path->nodes[0];
++			leaf_r = sctx->right_path->nodes[0];
++			ei_l = btrfs_item_ptr(leaf_l,
++					      sctx->left_path->slots[0],
++					      struct btrfs_file_extent_item);
++			ei_r = btrfs_item_ptr(leaf_r,
++					      sctx->right_path->slots[0],
++					      struct btrfs_file_extent_item);
++
++			/*
++			 * We may have found an extent item that has changed
++			 * only its disk_bytenr field and the corresponding
++			 * inode item was not updated. This case happens due to
++			 * very specific timings during relocation when a leaf
++			 * that contains file extent items is COWed while
++			 * relocation is ongoing and its in the stage where it
++			 * updates data pointers. So when this happens we can
++			 * safely ignore it since we know it's the same extent,
++			 * but just at different logical and physical locations
++			 * (when an extent is fully replaced with a new one, we
++			 * know the generation number must have changed too,
++			 * since snapshot creation implies committing the current
++			 * transaction, and the inode item must have been updated
++			 * as well).
++			 * This replacement of the disk_bytenr happens at
++			 * relocation.c:replace_file_extents() through
++			 * relocation.c:btrfs_reloc_cow_block().
++			 */
++			if (btrfs_file_extent_generation(leaf_l, ei_l) ==
++			    btrfs_file_extent_generation(leaf_r, ei_r) &&
++			    btrfs_file_extent_ram_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_ram_bytes(leaf_r, ei_r) &&
++			    btrfs_file_extent_compression(leaf_l, ei_l) ==
++			    btrfs_file_extent_compression(leaf_r, ei_r) &&
++			    btrfs_file_extent_encryption(leaf_l, ei_l) ==
++			    btrfs_file_extent_encryption(leaf_r, ei_r) &&
++			    btrfs_file_extent_other_encoding(leaf_l, ei_l) ==
++			    btrfs_file_extent_other_encoding(leaf_r, ei_r) &&
++			    btrfs_file_extent_type(leaf_l, ei_l) ==
++			    btrfs_file_extent_type(leaf_r, ei_r) &&
++			    btrfs_file_extent_disk_bytenr(leaf_l, ei_l) !=
++			    btrfs_file_extent_disk_bytenr(leaf_r, ei_r) &&
++			    btrfs_file_extent_disk_num_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_disk_num_bytes(leaf_r, ei_r) &&
++			    btrfs_file_extent_offset(leaf_l, ei_l) ==
++			    btrfs_file_extent_offset(leaf_r, ei_r) &&
++			    btrfs_file_extent_num_bytes(leaf_l, ei_l) ==
++			    btrfs_file_extent_num_bytes(leaf_r, ei_r))
++				return 0;
++		}
++
+ 		inconsistent_snapshot_error(sctx, result, "extent");
+ 		return -EIO;
+ 	}
+diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
+index 90e1198bc63d..e63c96ca0e96 100644
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -1940,12 +1940,11 @@ static noinline int find_dir_range(struct btrfs_root *root,
+ next:
+ 	/* check the next slot in the tree to see if it is a valid item */
+ 	nritems = btrfs_header_nritems(path->nodes[0]);
++	path->slots[0]++;
+ 	if (path->slots[0] >= nritems) {
+ 		ret = btrfs_next_leaf(root, path);
+ 		if (ret)
+ 			goto out;
+-	} else {
+-		path->slots[0]++;
+ 	}
+ 
+ 	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+@@ -5205,6 +5204,7 @@ process_leaf:
+ 			if (di_key.type == BTRFS_ROOT_ITEM_KEY)
+ 				continue;
+ 
++			btrfs_release_path(path);
+ 			di_inode = btrfs_iget(root->fs_info->sb, &di_key,
+ 					      root, NULL);
+ 			if (IS_ERR(di_inode)) {
+@@ -5214,13 +5214,12 @@ process_leaf:
+ 
+ 			if (btrfs_inode_in_log(di_inode, trans->transid)) {
+ 				iput(di_inode);
+-				continue;
++				break;
+ 			}
+ 
+ 			ctx->log_new_dentries = false;
+ 			if (type == BTRFS_FT_DIR || type == BTRFS_FT_SYMLINK)
+ 				log_mode = LOG_INODE_ALL;
+-			btrfs_release_path(path);
+ 			ret = btrfs_log_inode(trans, root, di_inode,
+ 					      log_mode, 0, LLONG_MAX, ctx);
+ 			if (!ret &&
+diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
+index 035efce603a9..7c9c6a4be4fd 100644
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -859,7 +859,7 @@ static void btrfs_close_bdev(struct btrfs_device *device)
+ 		blkdev_put(device->bdev, device->mode);
+ }
+ 
+-static void btrfs_close_one_device(struct btrfs_device *device)
++static void btrfs_prepare_close_one_device(struct btrfs_device *device)
+ {
+ 	struct btrfs_fs_devices *fs_devices = device->fs_devices;
+ 	struct btrfs_device *new_device;
+@@ -877,8 +877,6 @@ static void btrfs_close_one_device(struct btrfs_device *device)
+ 	if (device->missing)
+ 		fs_devices->missing_devices--;
+ 
+-	btrfs_close_bdev(device);
+-
+ 	new_device = btrfs_alloc_device(NULL, &device->devid,
+ 					device->uuid);
+ 	BUG_ON(IS_ERR(new_device)); /* -ENOMEM */
+@@ -892,23 +890,39 @@ static void btrfs_close_one_device(struct btrfs_device *device)
+ 
+ 	list_replace_rcu(&device->dev_list, &new_device->dev_list);
+ 	new_device->fs_devices = device->fs_devices;
+-
+-	call_rcu(&device->rcu, free_device);
+ }
+ 
+ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices)
+ {
+ 	struct btrfs_device *device, *tmp;
++	struct list_head pending_put;
++
++	INIT_LIST_HEAD(&pending_put);
+ 
+ 	if (--fs_devices->opened > 0)
+ 		return 0;
+ 
+ 	mutex_lock(&fs_devices->device_list_mutex);
+ 	list_for_each_entry_safe(device, tmp, &fs_devices->devices, dev_list) {
+-		btrfs_close_one_device(device);
++		btrfs_prepare_close_one_device(device);
++		list_add(&device->dev_list, &pending_put);
+ 	}
+ 	mutex_unlock(&fs_devices->device_list_mutex);
+ 
++	/*
++	 * btrfs_show_devname() is using the device_list_mutex,
++	 * sometimes call to blkdev_put() leads vfs calling
++	 * into this func. So do put outside of device_list_mutex,
++	 * as of now.
++	 */
++	while (!list_empty(&pending_put)) {
++		device = list_first_entry(&pending_put,
++				struct btrfs_device, dev_list);
++		list_del(&device->dev_list);
++		btrfs_close_bdev(device);
++		call_rcu(&device->rcu, free_device);
++	}
++
+ 	WARN_ON(fs_devices->open_devices);
+ 	WARN_ON(fs_devices->rw_devices);
+ 	fs_devices->opened = 0;
+@@ -1846,7 +1860,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 	u64 num_devices;
+ 	int ret = 0;
+ 	bool clear_super = false;
+-	char *dev_name = NULL;
+ 
+ 	mutex_lock(&uuid_mutex);
+ 
+@@ -1882,11 +1895,6 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 		list_del_init(&device->dev_alloc_list);
+ 		device->fs_devices->rw_devices--;
+ 		unlock_chunks(root);
+-		dev_name = kstrdup(device->name->str, GFP_KERNEL);
+-		if (!dev_name) {
+-			ret = -ENOMEM;
+-			goto error_undo;
+-		}
+ 		clear_super = true;
+ 	}
+ 
+@@ -1936,14 +1944,21 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 		btrfs_sysfs_rm_device_link(root->fs_info->fs_devices, device);
+ 	}
+ 
+-	btrfs_close_bdev(device);
+-
+-	call_rcu(&device->rcu, free_device);
+-
+ 	num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1;
+ 	btrfs_set_super_num_devices(root->fs_info->super_copy, num_devices);
+ 	mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);
+ 
++	/*
++	 * at this point, the device is zero sized and detached from
++	 * the devices list.  All that's left is to zero out the old
++	 * supers and free the device.
++	 */
++	if (device->writeable)
++		btrfs_scratch_superblocks(device->bdev, device->name->str);
++
++	btrfs_close_bdev(device);
++	call_rcu(&device->rcu, free_device);
++
+ 	if (cur_devices->open_devices == 0) {
+ 		struct btrfs_fs_devices *fs_devices;
+ 		fs_devices = root->fs_info->fs_devices;
+@@ -1962,24 +1977,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path, u64 devid)
+ 	root->fs_info->num_tolerated_disk_barrier_failures =
+ 		btrfs_calc_num_tolerated_disk_barrier_failures(root->fs_info);
+ 
+-	/*
+-	 * at this point, the device is zero sized.  We want to
+-	 * remove it from the devices list and zero out the old super
+-	 */
+-	if (clear_super) {
+-		struct block_device *bdev;
+-
+-		bdev = blkdev_get_by_path(dev_name, FMODE_READ | FMODE_EXCL,
+-						root->fs_info->bdev_holder);
+-		if (!IS_ERR(bdev)) {
+-			btrfs_scratch_superblocks(bdev, dev_name);
+-			blkdev_put(bdev, FMODE_READ | FMODE_EXCL);
+-		}
+-	}
+-
+ out:
+-	kfree(dev_name);
+-
+ 	mutex_unlock(&uuid_mutex);
+ 	return ret;
+ 
+diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
+index 65f78b7a9062..24184cae83d2 100644
+--- a/fs/cifs/cifsglob.h
++++ b/fs/cifs/cifsglob.h
+@@ -629,6 +629,8 @@ struct TCP_Server_Info {
+ 	unsigned int	max_read;
+ 	unsigned int	max_write;
+ 	__u8		preauth_hash[512];
++	struct delayed_work reconnect; /* reconnect workqueue job */
++	struct mutex reconnect_mutex; /* prevent simultaneous reconnects */
+ #endif /* CONFIG_CIFS_SMB2 */
+ 	unsigned long echo_interval;
+ };
+@@ -832,6 +834,7 @@ cap_unix(struct cifs_ses *ses)
+ struct cifs_tcon {
+ 	struct list_head tcon_list;
+ 	int tc_count;
++	struct list_head rlist; /* reconnect list */
+ 	struct list_head openFileList;
+ 	spinlock_t open_file_lock; /* protects list above */
+ 	struct cifs_ses *ses;	/* pointer to session associated with */
+diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
+index 95dab43646f0..ca76f8a7267f 100644
+--- a/fs/cifs/cifsproto.h
++++ b/fs/cifs/cifsproto.h
+@@ -204,6 +204,9 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid,
+ 					 struct tcon_link *tlink,
+ 					 struct cifs_pending_open *open);
+ extern void cifs_del_pending_open(struct cifs_pending_open *open);
++extern void cifs_put_tcp_session(struct TCP_Server_Info *server,
++				 int from_reconnect);
++extern void cifs_put_tcon(struct cifs_tcon *tcon);
+ 
+ #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL)
+ extern void cifs_dfs_release_automount_timer(void);
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 7b67179521cf..a178f3a5b052 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -52,6 +52,9 @@
+ #include "nterr.h"
+ #include "rfc1002pdu.h"
+ #include "fscache.h"
++#ifdef CONFIG_CIFS_SMB2
++#include "smb2proto.h"
++#endif
+ 
+ #define CIFS_PORT 445
+ #define RFC1001_PORT 139
+@@ -2076,8 +2079,8 @@ cifs_find_tcp_session(struct smb_vol *vol)
+ 	return NULL;
+ }
+ 
+-static void
+-cifs_put_tcp_session(struct TCP_Server_Info *server)
++void
++cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect)
+ {
+ 	struct task_struct *task;
+ 
+@@ -2094,6 +2097,19 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
+ 
+ 	cancel_delayed_work_sync(&server->echo);
+ 
++#ifdef CONFIG_CIFS_SMB2
++	if (from_reconnect)
++		/*
++		 * Avoid deadlock here: reconnect work calls
++		 * cifs_put_tcp_session() at its end. Need to be sure
++		 * that reconnect work does nothing with server pointer after
++		 * that step.
++		 */
++		cancel_delayed_work(&server->reconnect);
++	else
++		cancel_delayed_work_sync(&server->reconnect);
++#endif
++
+ 	spin_lock(&GlobalMid_Lock);
+ 	server->tcpStatus = CifsExiting;
+ 	spin_unlock(&GlobalMid_Lock);
+@@ -2158,6 +2174,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
+ 	INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
+ 	INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
+ 	INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request);
++#ifdef CONFIG_CIFS_SMB2
++	INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server);
++	mutex_init(&tcp_ses->reconnect_mutex);
++#endif
+ 	memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
+ 	       sizeof(tcp_ses->srcaddr));
+ 	memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr,
+@@ -2316,7 +2336,7 @@ cifs_put_smb_ses(struct cifs_ses *ses)
+ 	spin_unlock(&cifs_tcp_ses_lock);
+ 
+ 	sesInfoFree(ses);
+-	cifs_put_tcp_session(server);
++	cifs_put_tcp_session(server, 0);
+ }
+ 
+ #ifdef CONFIG_KEYS
+@@ -2490,7 +2510,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
+ 		mutex_unlock(&ses->session_mutex);
+ 
+ 		/* existing SMB ses has a server reference already */
+-		cifs_put_tcp_session(server);
++		cifs_put_tcp_session(server, 0);
+ 		free_xid(xid);
+ 		return ses;
+ 	}
+@@ -2580,7 +2600,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc)
+ 	return NULL;
+ }
+ 
+-static void
++void
+ cifs_put_tcon(struct cifs_tcon *tcon)
+ {
+ 	unsigned int xid;
+@@ -3762,7 +3782,7 @@ mount_fail_check:
+ 		else if (ses)
+ 			cifs_put_smb_ses(ses);
+ 		else
+-			cifs_put_tcp_session(server);
++			cifs_put_tcp_session(server, 0);
+ 		bdi_destroy(&cifs_sb->bdi);
+ 	}
+ 
+@@ -4073,7 +4093,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
+ 	ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
+ 	if (IS_ERR(ses)) {
+ 		tcon = (struct cifs_tcon *)ses;
+-		cifs_put_tcp_session(master_tcon->ses->server);
++		cifs_put_tcp_session(master_tcon->ses->server, 0);
+ 		goto out;
+ 	}
+ 
+diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c
+index f9e766f464be..b2aff0c6f22c 100644
+--- a/fs/cifs/smb2file.c
++++ b/fs/cifs/smb2file.c
+@@ -260,7 +260,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile)
+ 	 * and check it for zero before using.
+ 	 */
+ 	max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf;
+-	if (!max_buf) {
++	if (max_buf < sizeof(struct smb2_lock_element)) {
+ 		free_xid(xid);
+ 		return -EINVAL;
+ 	}
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 3eec96ca87d9..32e0e06f972c 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -275,7 +275,7 @@ out:
+ 	case SMB2_CHANGE_NOTIFY:
+ 	case SMB2_QUERY_INFO:
+ 	case SMB2_SET_INFO:
+-		return -EAGAIN;
++		rc = -EAGAIN;
+ 	}
+ 	unload_nls(nls_codepage);
+ 	return rc;
+@@ -1820,6 +1820,54 @@ smb2_echo_callback(struct mid_q_entry *mid)
+ 	add_credits(server, credits_received, CIFS_ECHO_OP);
+ }
+ 
++void smb2_reconnect_server(struct work_struct *work)
++{
++	struct TCP_Server_Info *server = container_of(work,
++					struct TCP_Server_Info, reconnect.work);
++	struct cifs_ses *ses;
++	struct cifs_tcon *tcon, *tcon2;
++	struct list_head tmp_list;
++	int tcon_exist = false;
++
++	/* Prevent simultaneous reconnects that can corrupt tcon->rlist list */
++	mutex_lock(&server->reconnect_mutex);
++
++	INIT_LIST_HEAD(&tmp_list);
++	cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
++
++	spin_lock(&cifs_tcp_ses_lock);
++	list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
++		list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
++			if (tcon->need_reconnect) {
++				tcon->tc_count++;
++				list_add_tail(&tcon->rlist, &tmp_list);
++				tcon_exist = true;
++			}
++		}
++	}
++	/*
++	 * Get the reference to server struct to be sure that the last call of
++	 * cifs_put_tcon() in the loop below won't release the server pointer.
++	 */
++	if (tcon_exist)
++		server->srv_count++;
++
++	spin_unlock(&cifs_tcp_ses_lock);
++
++	list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) {
++		smb2_reconnect(SMB2_ECHO, tcon);
++		list_del_init(&tcon->rlist);
++		cifs_put_tcon(tcon);
++	}
++
++	cifs_dbg(FYI, "Reconnecting tcons finished\n");
++	mutex_unlock(&server->reconnect_mutex);
++
++	/* now we can safely release srv struct */
++	if (tcon_exist)
++		cifs_put_tcp_session(server, 1);
++}
++
+ int
+ SMB2_echo(struct TCP_Server_Info *server)
+ {
+@@ -1832,32 +1880,11 @@ SMB2_echo(struct TCP_Server_Info *server)
+ 	cifs_dbg(FYI, "In echo request\n");
+ 
+ 	if (server->tcpStatus == CifsNeedNegotiate) {
+-		struct list_head *tmp, *tmp2;
+-		struct cifs_ses *ses;
+-		struct cifs_tcon *tcon;
+-
+-		cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n");
+-		spin_lock(&cifs_tcp_ses_lock);
+-		list_for_each(tmp, &server->smb_ses_list) {
+-			ses = list_entry(tmp, struct cifs_ses, smb_ses_list);
+-			list_for_each(tmp2, &ses->tcon_list) {
+-				tcon = list_entry(tmp2, struct cifs_tcon,
+-						  tcon_list);
+-				/* add check for persistent handle reconnect */
+-				if (tcon && tcon->need_reconnect) {
+-					spin_unlock(&cifs_tcp_ses_lock);
+-					rc = smb2_reconnect(SMB2_ECHO, tcon);
+-					spin_lock(&cifs_tcp_ses_lock);
+-				}
+-			}
+-		}
+-		spin_unlock(&cifs_tcp_ses_lock);
++		/* No need to send echo on newly established connections */
++		queue_delayed_work(cifsiod_wq, &server->reconnect, 0);
++		return rc;
+ 	}
+ 
+-	/* if no session, renegotiate failed above */
+-	if (server->tcpStatus == CifsNeedNegotiate)
+-		return -EIO;
+-
+ 	rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req);
+ 	if (rc)
+ 		return rc;
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
+index eb2cde2f64ba..f2d511a6971b 100644
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned int xid,
+ extern int smb2_unlock_range(struct cifsFileInfo *cfile,
+ 			     struct file_lock *flock, const unsigned int xid);
+ extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile);
++extern void smb2_reconnect_server(struct work_struct *work);
+ 
+ /*
+  * SMB2 Worker functions - most of protocol specific implementation details
+diff --git a/fs/exec.c b/fs/exec.c
+index 6fcfb3f7b137..eebe8be7a29d 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -19,7 +19,7 @@
+  * current->executable is only used by the procfs.  This allows a dispatch
+  * table to check for several different types  of binary formats.  We keep
+  * trying until we recognize the file or we run out of supported binary
+- * formats. 
++ * formats.
+  */
+ 
+ #include <linux/slab.h>
+@@ -1261,6 +1261,13 @@ int flush_old_exec(struct linux_binprm * bprm)
+ 	flush_thread();
+ 	current->personality &= ~bprm->per_clear;
+ 
++	/*
++	 * We have to apply CLOEXEC before we change whether the process is
++	 * dumpable (in setup_new_exec) to avoid a race with a process in userspace
++	 * trying to access the should-be-closed file descriptors of a process
++	 * undergoing exec(2).
++	 */
++	do_close_on_exec(current->files);
+ 	return 0;
+ 
+ out:
+@@ -1270,8 +1277,22 @@ EXPORT_SYMBOL(flush_old_exec);
+ 
+ void would_dump(struct linux_binprm *bprm, struct file *file)
+ {
+-	if (inode_permission(file_inode(file), MAY_READ) < 0)
++	struct inode *inode = file_inode(file);
++	if (inode_permission(inode, MAY_READ) < 0) {
++		struct user_namespace *old, *user_ns;
+ 		bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
++
++		/* Ensure mm->user_ns contains the executable */
++		user_ns = old = bprm->mm->user_ns;
++		while ((user_ns != &init_user_ns) &&
++		       !privileged_wrt_inode_uidgid(user_ns, inode))
++			user_ns = user_ns->parent;
++
++		if (old != user_ns) {
++			bprm->mm->user_ns = get_user_ns(user_ns);
++			put_user_ns(old);
++		}
++	}
+ }
+ EXPORT_SYMBOL(would_dump);
+ 
+@@ -1301,7 +1322,6 @@ void setup_new_exec(struct linux_binprm * bprm)
+ 	    !gid_eq(bprm->cred->gid, current_egid())) {
+ 		current->pdeath_signal = 0;
+ 	} else {
+-		would_dump(bprm, bprm->file);
+ 		if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP)
+ 			set_dumpable(current->mm, suid_dumpable);
+ 	}
+@@ -1310,7 +1330,6 @@ void setup_new_exec(struct linux_binprm * bprm)
+ 	   group */
+ 	current->self_exec_id++;
+ 	flush_signal_handlers(current, 0);
+-	do_close_on_exec(current->files);
+ }
+ EXPORT_SYMBOL(setup_new_exec);
+ 
+@@ -1401,7 +1420,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm)
+ 	unsigned n_fs;
+ 
+ 	if (p->ptrace) {
+-		if (p->ptrace & PT_PTRACE_CAP)
++		if (ptracer_capable(p, current_user_ns()))
+ 			bprm->unsafe |= LSM_UNSAFE_PTRACE_CAP;
+ 		else
+ 			bprm->unsafe |= LSM_UNSAFE_PTRACE;
+@@ -1736,6 +1755,8 @@ static int do_execveat_common(int fd, struct filename *filename,
+ 	if (retval < 0)
+ 		goto out;
+ 
++	would_dump(bprm, bprm->file);
++
+ 	retval = exec_binprm(bprm);
+ 	if (retval < 0)
+ 		goto out;
+diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h
+index b1d52c14098e..f97611171023 100644
+--- a/fs/ext4/ext4_jbd2.h
++++ b/fs/ext4/ext4_jbd2.h
+@@ -414,17 +414,19 @@ static inline int ext4_inode_journal_mode(struct inode *inode)
+ 		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+ 	/* We do not support data journalling with delayed allocation */
+ 	if (!S_ISREG(inode->i_mode) ||
+-	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)
+-		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
+-	if (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
+-	    !test_opt(inode->i_sb, DELALLOC))
++	    test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA ||
++	    (ext4_test_inode_flag(inode, EXT4_INODE_JOURNAL_DATA) &&
++	    !test_opt(inode->i_sb, DELALLOC))) {
++		/* We do not support data journalling for encrypted data */
++		if (S_ISREG(inode->i_mode) && ext4_encrypted_inode(inode))
++			return EXT4_INODE_ORDERED_DATA_MODE;  /* ordered */
+ 		return EXT4_INODE_JOURNAL_DATA_MODE;	/* journal data */
++	}
+ 	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_ORDERED_DATA)
+ 		return EXT4_INODE_ORDERED_DATA_MODE;	/* ordered */
+ 	if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)
+ 		return EXT4_INODE_WRITEBACK_DATA_MODE;	/* writeback */
+-	else
+-		BUG();
++	BUG();
+ }
+ 
+ static inline int ext4_should_journal_data(struct inode *inode)
+diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c
+index f74d5ee2cdec..d8ca4b9f9dd6 100644
+--- a/fs/ext4/inline.c
++++ b/fs/ext4/inline.c
+@@ -336,8 +336,10 @@ static int ext4_update_inline_data(handle_t *handle, struct inode *inode,
+ 
+ 	len -= EXT4_MIN_INLINE_DATA_SIZE;
+ 	value = kzalloc(len, GFP_NOFS);
+-	if (!value)
++	if (!value) {
++		error = -ENOMEM;
+ 		goto out;
++	}
+ 
+ 	error = ext4_xattr_ibody_get(inode, i.name_index, i.name,
+ 				     value, len);
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index f4cdc647ecfc..27e4348efc4e 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -4438,6 +4438,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ 	struct inode *inode;
+ 	journal_t *journal = EXT4_SB(sb)->s_journal;
+ 	long ret;
++	loff_t size;
+ 	int block;
+ 	uid_t i_uid;
+ 	gid_t i_gid;
+@@ -4538,6 +4539,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino)
+ 		ei->i_file_acl |=
+ 			((__u64)le16_to_cpu(raw_inode->i_file_acl_high)) << 32;
+ 	inode->i_size = ext4_isize(raw_inode);
++	if ((size = i_size_read(inode)) < 0) {
++		EXT4_ERROR_INODE(inode, "bad i_size value: %lld", size);
++		ret = -EFSCORRUPTED;
++		goto bad_inode;
++	}
+ 	ei->i_disksize = inode->i_size;
+ #ifdef CONFIG_QUOTA
+ 	ei->i_reserved_quota = 0;
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index f418f55c2bbe..7ae43c59bc79 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -669,7 +669,7 @@ static void ext4_mb_mark_free_simple(struct super_block *sb,
+ 	ext4_grpblk_t min;
+ 	ext4_grpblk_t max;
+ 	ext4_grpblk_t chunk;
+-	unsigned short border;
++	unsigned int border;
+ 
+ 	BUG_ON(len > EXT4_CLUSTERS_PER_GROUP(sb));
+ 
+@@ -2287,7 +2287,7 @@ static int ext4_mb_seq_groups_show(struct seq_file *seq, void *v)
+ 	struct ext4_group_info *grinfo;
+ 	struct sg {
+ 		struct ext4_group_info info;
+-		ext4_grpblk_t counters[16];
++		ext4_grpblk_t counters[EXT4_MAX_BLOCK_LOG_SIZE + 2];
+ 	} sg;
+ 
+ 	group--;
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index ec89f5005c2d..d0d4377680c7 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -3161,10 +3161,15 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp,
+ 			ext4_set_bit(s++, buf);
+ 			count++;
+ 		}
+-		for (j = ext4_bg_num_gdb(sb, grp); j > 0; j--) {
+-			ext4_set_bit(EXT4_B2C(sbi, s++), buf);
+-			count++;
++		j = ext4_bg_num_gdb(sb, grp);
++		if (s + j > EXT4_BLOCKS_PER_GROUP(sb)) {
++			ext4_error(sb, "Invalid number of block group "
++				   "descriptor blocks: %d", j);
++			j = EXT4_BLOCKS_PER_GROUP(sb) - s;
+ 		}
++		count += j;
++		for (; j > 0; j--)
++			ext4_set_bit(EXT4_B2C(sbi, s++), buf);
+ 	}
+ 	if (!count)
+ 		return 0;
+@@ -3254,7 +3259,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	char *orig_data = kstrdup(data, GFP_KERNEL);
+ 	struct buffer_head *bh;
+ 	struct ext4_super_block *es = NULL;
+-	struct ext4_sb_info *sbi;
++	struct ext4_sb_info *sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ 	ext4_fsblk_t block;
+ 	ext4_fsblk_t sb_block = get_sb_block(&data);
+ 	ext4_fsblk_t logical_sb_block;
+@@ -3273,16 +3278,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	unsigned int journal_ioprio = DEFAULT_JOURNAL_IOPRIO;
+ 	ext4_group_t first_not_zeroed;
+ 
+-	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+-	if (!sbi)
+-		goto out_free_orig;
++	if ((data && !orig_data) || !sbi)
++		goto out_free_base;
+ 
+ 	sbi->s_blockgroup_lock =
+ 		kzalloc(sizeof(struct blockgroup_lock), GFP_KERNEL);
+-	if (!sbi->s_blockgroup_lock) {
+-		kfree(sbi);
+-		goto out_free_orig;
+-	}
++	if (!sbi->s_blockgroup_lock)
++		goto out_free_base;
++
+ 	sb->s_fs_info = sbi;
+ 	sbi->s_sb = sb;
+ 	sbi->s_inode_readahead_blks = EXT4_DEF_INODE_READAHEAD_BLKS;
+@@ -3428,11 +3431,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	 */
+ 	sbi->s_li_wait_mult = EXT4_DEF_LI_WAIT_MULT;
+ 
+-	if (!parse_options((char *) sbi->s_es->s_mount_opts, sb,
+-			   &journal_devnum, &journal_ioprio, 0)) {
+-		ext4_msg(sb, KERN_WARNING,
+-			 "failed to parse options in superblock: %s",
+-			 sbi->s_es->s_mount_opts);
++	if (sbi->s_es->s_mount_opts[0]) {
++		char *s_mount_opts = kstrndup(sbi->s_es->s_mount_opts,
++					      sizeof(sbi->s_es->s_mount_opts),
++					      GFP_KERNEL);
++		if (!s_mount_opts)
++			goto failed_mount;
++		if (!parse_options(s_mount_opts, sb, &journal_devnum,
++				   &journal_ioprio, 0)) {
++			ext4_msg(sb, KERN_WARNING,
++				 "failed to parse options in superblock: %s",
++				 s_mount_opts);
++		}
++		kfree(s_mount_opts);
+ 	}
+ 	sbi->s_def_mount_opt = sbi->s_mount_opt;
+ 	if (!parse_options((char *) data, sb, &journal_devnum,
+@@ -3458,6 +3469,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 				 "both data=journal and dax");
+ 			goto failed_mount;
+ 		}
++		if (ext4_has_feature_encrypt(sb)) {
++			ext4_msg(sb, KERN_WARNING,
++				 "encrypted files will use data=ordered "
++				 "instead of data journaling mode");
++		}
+ 		if (test_opt(sb, DELALLOC))
+ 			clear_opt(sb, DELALLOC);
+ 	} else {
+@@ -3613,12 +3629,16 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 
+ 	sbi->s_blocks_per_group = le32_to_cpu(es->s_blocks_per_group);
+ 	sbi->s_inodes_per_group = le32_to_cpu(es->s_inodes_per_group);
+-	if (EXT4_INODE_SIZE(sb) == 0 || EXT4_INODES_PER_GROUP(sb) == 0)
+-		goto cantfind_ext4;
+ 
+ 	sbi->s_inodes_per_block = blocksize / EXT4_INODE_SIZE(sb);
+ 	if (sbi->s_inodes_per_block == 0)
+ 		goto cantfind_ext4;
++	if (sbi->s_inodes_per_group < sbi->s_inodes_per_block ||
++	    sbi->s_inodes_per_group > blocksize * 8) {
++		ext4_msg(sb, KERN_ERR, "invalid inodes per group: %lu\n",
++			 sbi->s_blocks_per_group);
++		goto failed_mount;
++	}
+ 	sbi->s_itb_per_group = sbi->s_inodes_per_group /
+ 					sbi->s_inodes_per_block;
+ 	sbi->s_desc_per_block = blocksize / EXT4_DESC_SIZE(sb);
+@@ -3701,13 +3721,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 	}
+ 	sbi->s_cluster_ratio = clustersize / blocksize;
+ 
+-	if (sbi->s_inodes_per_group > blocksize * 8) {
+-		ext4_msg(sb, KERN_ERR,
+-		       "#inodes per group too big: %lu",
+-		       sbi->s_inodes_per_group);
+-		goto failed_mount;
+-	}
+-
+ 	/* Do we have standard group size of clustersize * 8 blocks ? */
+ 	if (sbi->s_blocks_per_group == clustersize << 3)
+ 		set_opt2(sb, STD_GROUP_SIZE);
+@@ -4113,7 +4126,9 @@ no_journal:
+ 
+ 	if (___ratelimit(&ext4_mount_msg_ratelimit, "EXT4-fs mount"))
+ 		ext4_msg(sb, KERN_INFO, "mounted filesystem with%s. "
+-			 "Opts: %s%s%s", descr, sbi->s_es->s_mount_opts,
++			 "Opts: %.*s%s%s", descr,
++			 (int) sizeof(sbi->s_es->s_mount_opts),
++			 sbi->s_es->s_mount_opts,
+ 			 *sbi->s_es->s_mount_opts ? "; " : "", orig_data);
+ 
+ 	if (es->s_error_count)
+@@ -4192,8 +4207,8 @@ failed_mount:
+ out_fail:
+ 	sb->s_fs_info = NULL;
+ 	kfree(sbi->s_blockgroup_lock);
++out_free_base:
+ 	kfree(sbi);
+-out_free_orig:
+ 	kfree(orig_data);
+ 	return err ? err : ret;
+ }
+diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c
+index badd407bb622..c05d66d98871 100644
+--- a/fs/f2fs/debug.c
++++ b/fs/f2fs/debug.c
+@@ -362,6 +362,7 @@ static int stat_open(struct inode *inode, struct file *file)
+ }
+ 
+ static const struct file_operations stat_fops = {
++	.owner = THIS_MODULE,
+ 	.open = stat_open,
+ 	.read = seq_read,
+ 	.llseek = seq_lseek,
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 14f5fe2b841e..8467f4221f57 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -451,7 +451,7 @@ struct f2fs_inode_info {
+ 	/* Use below internally in f2fs*/
+ 	unsigned long flags;		/* use to pass per-file flags */
+ 	struct rw_semaphore i_sem;	/* protect fi info */
+-	struct percpu_counter dirty_pages;	/* # of dirty pages */
++	atomic_t dirty_pages;		/* # of dirty pages */
+ 	f2fs_hash_t chash;		/* hash value of given file name */
+ 	unsigned int clevel;		/* maximum level of given file name */
+ 	nid_t i_xattr_nid;		/* node id that contains xattrs */
+@@ -1198,7 +1198,7 @@ static inline void inc_page_count(struct f2fs_sb_info *sbi, int count_type)
+ 
+ static inline void inode_inc_dirty_pages(struct inode *inode)
+ {
+-	percpu_counter_inc(&F2FS_I(inode)->dirty_pages);
++	atomic_inc(&F2FS_I(inode)->dirty_pages);
+ 	inc_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
+ 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+ }
+@@ -1214,7 +1214,7 @@ static inline void inode_dec_dirty_pages(struct inode *inode)
+ 			!S_ISLNK(inode->i_mode))
+ 		return;
+ 
+-	percpu_counter_dec(&F2FS_I(inode)->dirty_pages);
++	atomic_dec(&F2FS_I(inode)->dirty_pages);
+ 	dec_page_count(F2FS_I_SB(inode), S_ISDIR(inode->i_mode) ?
+ 				F2FS_DIRTY_DENTS : F2FS_DIRTY_DATA);
+ }
+@@ -1224,9 +1224,9 @@ static inline s64 get_pages(struct f2fs_sb_info *sbi, int count_type)
+ 	return percpu_counter_sum_positive(&sbi->nr_pages[count_type]);
+ }
+ 
+-static inline s64 get_dirty_pages(struct inode *inode)
++static inline int get_dirty_pages(struct inode *inode)
+ {
+-	return percpu_counter_sum_positive(&F2FS_I(inode)->dirty_pages);
++	return atomic_read(&F2FS_I(inode)->dirty_pages);
+ }
+ 
+ static inline int get_blocktype_secs(struct f2fs_sb_info *sbi, int block_type)
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
+index 28f4f4cbb8d8..06f39db65923 100644
+--- a/fs/f2fs/file.c
++++ b/fs/f2fs/file.c
+@@ -970,7 +970,7 @@ static int __clone_blkaddrs(struct inode *src_inode, struct inode *dst_inode,
+ 				new_size = (dst + i) << PAGE_SHIFT;
+ 				if (dst_inode->i_size < new_size)
+ 					f2fs_i_size_write(dst_inode, new_size);
+-			} while ((do_replace[i] || blkaddr[i] == NULL_ADDR) && --ilen);
++			} while (--ilen && (do_replace[i] || blkaddr[i] == NULL_ADDR));
+ 
+ 			f2fs_put_dnode(&dn);
+ 		} else {
+@@ -1529,7 +1529,7 @@ static int f2fs_ioc_start_atomic_write(struct file *filp)
+ 		goto out;
+ 
+ 	f2fs_msg(F2FS_I_SB(inode)->sb, KERN_WARNING,
+-		"Unexpected flush for atomic writes: ino=%lu, npages=%lld",
++		"Unexpected flush for atomic writes: ino=%lu, npages=%u",
+ 					inode->i_ino, get_dirty_pages(inode));
+ 	ret = filemap_write_and_wait_range(inode->i_mapping, 0, LLONG_MAX);
+ 	if (ret)
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 7f863a645ab1..37edc853c66c 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -565,13 +565,9 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb)
+ 
+ 	init_once((void *) fi);
+ 
+-	if (percpu_counter_init(&fi->dirty_pages, 0, GFP_NOFS)) {
+-		kmem_cache_free(f2fs_inode_cachep, fi);
+-		return NULL;
+-	}
+-
+ 	/* Initialize f2fs-specific inode info */
+ 	fi->vfs_inode.i_version = 1;
++	atomic_set(&fi->dirty_pages, 0);
+ 	fi->i_current_depth = 1;
+ 	fi->i_advise = 0;
+ 	init_rwsem(&fi->i_sem);
+@@ -694,7 +690,6 @@ static void f2fs_i_callback(struct rcu_head *head)
+ 
+ static void f2fs_destroy_inode(struct inode *inode)
+ {
+-	percpu_counter_destroy(&F2FS_I(inode)->dirty_pages);
+ 	call_rcu(&inode->i_rcu, f2fs_i_callback);
+ }
+ 
+diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
+index e8638fd2c0c3..6f07b3e89ff2 100644
+--- a/fs/xfs/xfs_log_recover.c
++++ b/fs/xfs/xfs_log_recover.c
+@@ -4506,6 +4506,7 @@ xlog_recover_clear_agi_bucket(
+ 	agi->agi_unlinked[bucket] = cpu_to_be32(NULLAGINO);
+ 	offset = offsetof(xfs_agi_t, agi_unlinked) +
+ 		 (sizeof(xfs_agino_t) * bucket);
++	xfs_trans_buf_set_type(tp, agibp, XFS_BLFT_AGI_BUF);
+ 	xfs_trans_log_buf(tp, agibp, offset,
+ 			  (offset + sizeof(xfs_agino_t) - 1));
+ 
+diff --git a/include/linux/capability.h b/include/linux/capability.h
+index dbc21c719ce6..6ffb67e10c06 100644
+--- a/include/linux/capability.h
++++ b/include/linux/capability.h
+@@ -240,8 +240,10 @@ static inline bool ns_capable_noaudit(struct user_namespace *ns, int cap)
+ 	return true;
+ }
+ #endif /* CONFIG_MULTIUSER */
++extern bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode);
+ extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
+ extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
++extern bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns);
+ 
+ /* audit system wants to get cap info from files as well */
+ extern int get_vfs_caps_from_disk(const struct dentry *dentry, struct cpu_vfs_cap_data *cpu_caps);
+diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
+index 903200f4ec41..39820082ce91 100644
+--- a/include/linux/mm_types.h
++++ b/include/linux/mm_types.h
+@@ -473,6 +473,7 @@ struct mm_struct {
+ 	 */
+ 	struct task_struct __rcu *owner;
+ #endif
++	struct user_namespace *user_ns;
+ 
+ 	/* store ref to file /proc/<pid>/exe symlink points to */
+ 	struct file __rcu *exe_file;
+diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
+index bca26157f5b6..f6bc76501912 100644
+--- a/include/linux/pm_opp.h
++++ b/include/linux/pm_opp.h
+@@ -19,6 +19,7 @@
+ 
+ struct dev_pm_opp;
+ struct device;
++struct opp_table;
+ 
+ enum dev_pm_opp_event {
+ 	OPP_EVENT_ADD, OPP_EVENT_REMOVE, OPP_EVENT_ENABLE, OPP_EVENT_DISABLE,
+@@ -62,8 +63,8 @@ int dev_pm_opp_set_supported_hw(struct device *dev, const u32 *versions,
+ void dev_pm_opp_put_supported_hw(struct device *dev);
+ int dev_pm_opp_set_prop_name(struct device *dev, const char *name);
+ void dev_pm_opp_put_prop_name(struct device *dev);
+-int dev_pm_opp_set_regulator(struct device *dev, const char *name);
+-void dev_pm_opp_put_regulator(struct device *dev);
++struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name);
++void dev_pm_opp_put_regulator(struct opp_table *opp_table);
+ int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
+ int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
+ int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
+@@ -170,12 +171,12 @@ static inline int dev_pm_opp_set_prop_name(struct device *dev, const char *name)
+ 
+ static inline void dev_pm_opp_put_prop_name(struct device *dev) {}
+ 
+-static inline int dev_pm_opp_set_regulator(struct device *dev, const char *name)
++static inline struct opp_table *dev_pm_opp_set_regulator(struct device *dev, const char *name)
+ {
+-	return -ENOTSUPP;
++	return ERR_PTR(-ENOTSUPP);
+ }
+ 
+-static inline void dev_pm_opp_put_regulator(struct device *dev) {}
++static inline void dev_pm_opp_put_regulator(struct opp_table *opp_table) {}
+ 
+ static inline int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq)
+ {
+diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
+index 504c98a278d4..e13bfdf7f314 100644
+--- a/include/linux/ptrace.h
++++ b/include/linux/ptrace.h
+@@ -19,7 +19,6 @@
+ #define PT_SEIZED	0x00010000	/* SEIZE used, enable new behavior */
+ #define PT_PTRACED	0x00000001
+ #define PT_DTRACE	0x00000002	/* delayed trace (used on m68k, i386) */
+-#define PT_PTRACE_CAP	0x00000004	/* ptracer can follow suid-exec */
+ 
+ #define PT_OPT_FLAG_SHIFT	3
+ /* PT_TRACE_* event enable flags */
+diff --git a/include/linux/sched.h b/include/linux/sched.h
+index 62c68e513e39..f52d4cc97788 100644
+--- a/include/linux/sched.h
++++ b/include/linux/sched.h
+@@ -1631,6 +1631,7 @@ struct task_struct {
+ 	struct list_head cpu_timers[3];
+ 
+ /* process credentials */
++	const struct cred __rcu *ptracer_cred; /* Tracer's credentials at attach */
+ 	const struct cred __rcu *real_cred; /* objective and real subjective task
+ 					 * credentials (COW) */
+ 	const struct cred __rcu *cred;	/* effective (overridable) subjective task
+diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
+index 445b019c2078..de45666f96b4 100644
+--- a/include/net/netfilter/nf_conntrack.h
++++ b/include/net/netfilter/nf_conntrack.h
+@@ -17,7 +17,6 @@
+ #include <linux/bitops.h>
+ #include <linux/compiler.h>
+ #include <linux/atomic.h>
+-#include <linux/rhashtable.h>
+ 
+ #include <linux/netfilter/nf_conntrack_tcp.h>
+ #include <linux/netfilter/nf_conntrack_dccp.h>
+@@ -118,9 +117,6 @@ struct nf_conn {
+ 	/* Extensions */
+ 	struct nf_ct_ext *ext;
+ 
+-#if IS_ENABLED(CONFIG_NF_NAT)
+-	struct rhash_head	nat_bysource;
+-#endif
+ 	/* Storage reserved for other modules, must be the last member */
+ 	union nf_conntrack_proto proto;
+ };
+diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
+index 1c3035dda31f..b925395fa5ed 100644
+--- a/include/net/netfilter/nf_conntrack_extend.h
++++ b/include/net/netfilter/nf_conntrack_extend.h
+@@ -99,6 +99,9 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ struct nf_ct_ext_type {
+ 	/* Destroys relationships (can be NULL). */
+ 	void (*destroy)(struct nf_conn *ct);
++	/* Called when realloacted (can be NULL).
++	   Contents has already been moved. */
++	void (*move)(void *new, void *old);
+ 
+ 	enum nf_ct_ext_id id;
+ 
+diff --git a/include/net/netfilter/nf_nat.h b/include/net/netfilter/nf_nat.h
+index c327a431a6f3..344b1ab19220 100644
+--- a/include/net/netfilter/nf_nat.h
++++ b/include/net/netfilter/nf_nat.h
+@@ -1,6 +1,5 @@
+ #ifndef _NF_NAT_H
+ #define _NF_NAT_H
+-#include <linux/rhashtable.h>
+ #include <linux/netfilter_ipv4.h>
+ #include <linux/netfilter/nf_nat.h>
+ #include <net/netfilter/nf_conntrack_tuple.h>
+@@ -30,6 +29,8 @@ struct nf_conn;
+ 
+ /* The structure embedded in the conntrack structure. */
+ struct nf_conn_nat {
++	struct hlist_node bysource;
++	struct nf_conn *ct;
+ 	union nf_conntrack_nat_help help;
+ #if IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV4) || \
+     IS_ENABLED(CONFIG_NF_NAT_MASQUERADE_IPV6)
+diff --git a/kernel/capability.c b/kernel/capability.c
+index 00411c82dac5..4984e1f552eb 100644
+--- a/kernel/capability.c
++++ b/kernel/capability.c
+@@ -457,6 +457,19 @@ bool file_ns_capable(const struct file *file, struct user_namespace *ns,
+ EXPORT_SYMBOL(file_ns_capable);
+ 
+ /**
++ * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode?
++ * @ns: The user namespace in question
++ * @inode: The inode in question
++ *
++ * Return true if the inode uid and gid are within the namespace.
++ */
++bool privileged_wrt_inode_uidgid(struct user_namespace *ns, const struct inode *inode)
++{
++	return kuid_has_mapping(ns, inode->i_uid) &&
++		kgid_has_mapping(ns, inode->i_gid);
++}
++
++/**
+  * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
+  * @inode: The inode in question
+  * @cap: The capability in question
+@@ -469,7 +482,26 @@ bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
+ {
+ 	struct user_namespace *ns = current_user_ns();
+ 
+-	return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
+-		kgid_has_mapping(ns, inode->i_gid);
++	return ns_capable(ns, cap) && privileged_wrt_inode_uidgid(ns, inode);
+ }
+ EXPORT_SYMBOL(capable_wrt_inode_uidgid);
++
++/**
++ * ptracer_capable - Determine if the ptracer holds CAP_SYS_PTRACE in the namespace
++ * @tsk: The task that may be ptraced
++ * @ns: The user namespace to search for CAP_SYS_PTRACE in
++ *
++ * Return true if the task that is ptracing the current task had CAP_SYS_PTRACE
++ * in the specified user namespace.
++ */
++bool ptracer_capable(struct task_struct *tsk, struct user_namespace *ns)
++{
++	int ret = 0;  /* An absent tracer adds no restrictions */
++	const struct cred *cred;
++	rcu_read_lock();
++	cred = rcu_dereference(tsk->ptracer_cred);
++	if (cred)
++		ret = security_capable_noaudit(cred, ns, CAP_SYS_PTRACE);
++	rcu_read_unlock();
++	return (ret == 0);
++}
+diff --git a/kernel/debug/debug_core.c b/kernel/debug/debug_core.c
+index 0874e2edd275..79517e5549f1 100644
+--- a/kernel/debug/debug_core.c
++++ b/kernel/debug/debug_core.c
+@@ -598,11 +598,11 @@ return_normal:
+ 	/*
+ 	 * Wait for the other CPUs to be notified and be waiting for us:
+ 	 */
+-	time_left = loops_per_jiffy * HZ;
++	time_left = MSEC_PER_SEC;
+ 	while (kgdb_do_roundup && --time_left &&
+ 	       (atomic_read(&masters_in_kgdb) + atomic_read(&slaves_in_kgdb)) !=
+ 		   online_cpus)
+-		cpu_relax();
++		udelay(1000);
+ 	if (!time_left)
+ 		pr_crit("Timed out waiting for secondary CPUs.\n");
+ 
+diff --git a/kernel/fork.c b/kernel/fork.c
+index beb31725f7e2..9f8dae785f07 100644
+--- a/kernel/fork.c
++++ b/kernel/fork.c
+@@ -598,7 +598,8 @@ static void mm_init_owner(struct mm_struct *mm, struct task_struct *p)
+ #endif
+ }
+ 
+-static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
++static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p,
++	struct user_namespace *user_ns)
+ {
+ 	mm->mmap = NULL;
+ 	mm->mm_rb = RB_ROOT;
+@@ -638,6 +639,7 @@ static struct mm_struct *mm_init(struct mm_struct *mm, struct task_struct *p)
+ 	if (init_new_context(p, mm))
+ 		goto fail_nocontext;
+ 
++	mm->user_ns = get_user_ns(user_ns);
+ 	return mm;
+ 
+ fail_nocontext:
+@@ -683,7 +685,7 @@ struct mm_struct *mm_alloc(void)
+ 		return NULL;
+ 
+ 	memset(mm, 0, sizeof(*mm));
+-	return mm_init(mm, current);
++	return mm_init(mm, current, current_user_ns());
+ }
+ 
+ /*
+@@ -698,6 +700,7 @@ void __mmdrop(struct mm_struct *mm)
+ 	destroy_context(mm);
+ 	mmu_notifier_mm_destroy(mm);
+ 	check_mm(mm);
++	put_user_ns(mm->user_ns);
+ 	free_mm(mm);
+ }
+ EXPORT_SYMBOL_GPL(__mmdrop);
+@@ -977,7 +980,7 @@ static struct mm_struct *dup_mm(struct task_struct *tsk)
+ 
+ 	memcpy(mm, oldmm, sizeof(*mm));
+ 
+-	if (!mm_init(mm, tsk))
++	if (!mm_init(mm, tsk, mm->user_ns))
+ 		goto fail_nomem;
+ 
+ 	err = dup_mmap(mm, oldmm);
+diff --git a/kernel/ptrace.c b/kernel/ptrace.c
+index 1d3b7665d0be..7b20baea41e7 100644
+--- a/kernel/ptrace.c
++++ b/kernel/ptrace.c
+@@ -39,6 +39,9 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
+ 	BUG_ON(!list_empty(&child->ptrace_entry));
+ 	list_add(&child->ptrace_entry, &new_parent->ptraced);
+ 	child->parent = new_parent;
++	rcu_read_lock();
++	child->ptracer_cred = get_cred(__task_cred(new_parent));
++	rcu_read_unlock();
+ }
+ 
+ /**
+@@ -71,10 +74,14 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
+  */
+ void __ptrace_unlink(struct task_struct *child)
+ {
++	const struct cred *old_cred;
+ 	BUG_ON(!child->ptrace);
+ 
+ 	child->parent = child->real_parent;
+ 	list_del_init(&child->ptrace_entry);
++	old_cred = child->ptracer_cred;
++	child->ptracer_cred = NULL;
++	put_cred(old_cred);
+ 
+ 	spin_lock(&child->sighand->siglock);
+ 	child->ptrace = 0;
+@@ -218,7 +225,7 @@ static int ptrace_has_cap(struct user_namespace *ns, unsigned int mode)
+ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+ {
+ 	const struct cred *cred = current_cred(), *tcred;
+-	int dumpable = 0;
++	struct mm_struct *mm;
+ 	kuid_t caller_uid;
+ 	kgid_t caller_gid;
+ 
+@@ -269,16 +276,11 @@ static int __ptrace_may_access(struct task_struct *task, unsigned int mode)
+ 	return -EPERM;
+ ok:
+ 	rcu_read_unlock();
+-	smp_rmb();
+-	if (task->mm)
+-		dumpable = get_dumpable(task->mm);
+-	rcu_read_lock();
+-	if (dumpable != SUID_DUMP_USER &&
+-	    !ptrace_has_cap(__task_cred(task)->user_ns, mode)) {
+-		rcu_read_unlock();
+-		return -EPERM;
+-	}
+-	rcu_read_unlock();
++	mm = task->mm;
++	if (mm &&
++	    ((get_dumpable(mm) != SUID_DUMP_USER) &&
++	     !ptrace_has_cap(mm->user_ns, mode)))
++	    return -EPERM;
+ 
+ 	return security_ptrace_access_check(task, mode);
+ }
+@@ -342,10 +344,6 @@ static int ptrace_attach(struct task_struct *task, long request,
+ 
+ 	if (seize)
+ 		flags |= PT_SEIZED;
+-	rcu_read_lock();
+-	if (ns_capable(__task_cred(task)->user_ns, CAP_SYS_PTRACE))
+-		flags |= PT_PTRACE_CAP;
+-	rcu_read_unlock();
+ 	task->ptrace = flags;
+ 
+ 	__ptrace_link(task, current);
+diff --git a/kernel/watchdog.c b/kernel/watchdog.c
+index 9acb29f280ec..6d1020c03d41 100644
+--- a/kernel/watchdog.c
++++ b/kernel/watchdog.c
+@@ -344,7 +344,6 @@ static void watchdog_overflow_callback(struct perf_event *event,
+ 	 */
+ 	if (is_hardlockup()) {
+ 		int this_cpu = smp_processor_id();
+-		struct pt_regs *regs = get_irq_regs();
+ 
+ 		/* only print hardlockups once */
+ 		if (__this_cpu_read(hard_watchdog_warn) == true)
+diff --git a/mm/filemap.c b/mm/filemap.c
+index ced9ef6c06b0..f1da48d1f95f 100644
+--- a/mm/filemap.c
++++ b/mm/filemap.c
+@@ -1688,7 +1688,7 @@ static ssize_t do_generic_file_read(struct file *filp, loff_t *ppos,
+ 	int error = 0;
+ 
+ 	if (unlikely(*ppos >= inode->i_sb->s_maxbytes))
+-		return -EINVAL;
++		return 0;
+ 	iov_iter_truncate(iter, inode->i_sb->s_maxbytes);
+ 
+ 	index = *ppos >> PAGE_SHIFT;
+diff --git a/mm/init-mm.c b/mm/init-mm.c
+index a56a851908d2..975e49f00f34 100644
+--- a/mm/init-mm.c
++++ b/mm/init-mm.c
+@@ -6,6 +6,7 @@
+ #include <linux/cpumask.h>
+ 
+ #include <linux/atomic.h>
++#include <linux/user_namespace.h>
+ #include <asm/pgtable.h>
+ #include <asm/mmu.h>
+ 
+@@ -21,5 +22,6 @@ struct mm_struct init_mm = {
+ 	.mmap_sem	= __RWSEM_INITIALIZER(init_mm.mmap_sem),
+ 	.page_table_lock =  __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock),
+ 	.mmlist		= LIST_HEAD_INIT(init_mm.mmlist),
++	.user_ns	= &init_user_ns,
+ 	INIT_MM_CONTEXT(init_mm)
+ };
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 7401e996009a..212a017a2f02 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -2173,7 +2173,7 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+ 			unsigned long count, struct list_head *list,
+ 			int migratetype, bool cold)
+ {
+-	int i;
++	int i, alloced = 0;
+ 
+ 	spin_lock(&zone->lock);
+ 	for (i = 0; i < count; ++i) {
+@@ -2198,13 +2198,21 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
+ 		else
+ 			list_add_tail(&page->lru, list);
+ 		list = &page->lru;
++		alloced++;
+ 		if (is_migrate_cma(get_pcppage_migratetype(page)))
+ 			__mod_zone_page_state(zone, NR_FREE_CMA_PAGES,
+ 					      -(1 << order));
+ 	}
++
++	/*
++	 * i pages were removed from the buddy list even if some leak due
++	 * to check_pcp_refill failing so adjust NR_FREE_PAGES based
++	 * on i. Do not confuse with 'alloced' which is the number of
++	 * pages added to the pcp list.
++	 */
+ 	__mod_zone_page_state(zone, NR_FREE_PAGES, -(i << order));
+ 	spin_unlock(&zone->lock);
+-	return i;
++	return alloced;
+ }
+ 
+ #ifdef CONFIG_NUMA
+diff --git a/mm/vmscan.c b/mm/vmscan.c
+index ba0fad78e5d4..5c313a0d1626 100644
+--- a/mm/vmscan.c
++++ b/mm/vmscan.c
+@@ -291,6 +291,7 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 	int nid = shrinkctl->nid;
+ 	long batch_size = shrinker->batch ? shrinker->batch
+ 					  : SHRINK_BATCH;
++	long scanned = 0, next_deferred;
+ 
+ 	freeable = shrinker->count_objects(shrinker, shrinkctl);
+ 	if (freeable == 0)
+@@ -312,7 +313,9 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 		pr_err("shrink_slab: %pF negative objects to delete nr=%ld\n",
+ 		       shrinker->scan_objects, total_scan);
+ 		total_scan = freeable;
+-	}
++		next_deferred = nr;
++	} else
++		next_deferred = total_scan;
+ 
+ 	/*
+ 	 * We need to avoid excessive windup on filesystem shrinkers
+@@ -369,17 +372,22 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl,
+ 
+ 		count_vm_events(SLABS_SCANNED, nr_to_scan);
+ 		total_scan -= nr_to_scan;
++		scanned += nr_to_scan;
+ 
+ 		cond_resched();
+ 	}
+ 
++	if (next_deferred >= scanned)
++		next_deferred -= scanned;
++	else
++		next_deferred = 0;
+ 	/*
+ 	 * move the unused scan count back into the shrinker in a
+ 	 * manner that handles concurrent updates. If we exhausted the
+ 	 * scan, there is no need to do an update.
+ 	 */
+-	if (total_scan > 0)
+-		new_nr = atomic_long_add_return(total_scan,
++	if (next_deferred > 0)
++		new_nr = atomic_long_add_return(next_deferred,
+ 						&shrinker->nr_deferred[nid]);
+ 	else
+ 		new_nr = atomic_long_read(&shrinker->nr_deferred[nid]);
+diff --git a/net/netfilter/nf_conntrack_extend.c b/net/netfilter/nf_conntrack_extend.c
+index 02bcf00c2492..1a9545965c0d 100644
+--- a/net/netfilter/nf_conntrack_extend.c
++++ b/net/netfilter/nf_conntrack_extend.c
+@@ -73,7 +73,7 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ 			     size_t var_alloc_len, gfp_t gfp)
+ {
+ 	struct nf_ct_ext *old, *new;
+-	int newlen, newoff;
++	int i, newlen, newoff;
+ 	struct nf_ct_ext_type *t;
+ 
+ 	/* Conntrack must not be confirmed to avoid races on reallocation. */
+@@ -99,8 +99,19 @@ void *__nf_ct_ext_add_length(struct nf_conn *ct, enum nf_ct_ext_id id,
+ 		return NULL;
+ 
+ 	if (new != old) {
++		for (i = 0; i < NF_CT_EXT_NUM; i++) {
++			if (!__nf_ct_ext_exist(old, i))
++				continue;
++
++			rcu_read_lock();
++			t = rcu_dereference(nf_ct_ext_types[i]);
++			if (t && t->move)
++				t->move((void *)new + new->offset[i],
++					(void *)old + old->offset[i]);
++			rcu_read_unlock();
++		}
+ 		kfree_rcu(old, rcu);
+-		rcu_assign_pointer(ct->ext, new);
++		ct->ext = new;
+ 	}
+ 
+ 	new->offset[id] = newoff;
+diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c
+index ecee105bbada..4bf9b50cbb4c 100644
+--- a/net/netfilter/nf_nat_core.c
++++ b/net/netfilter/nf_nat_core.c
+@@ -30,19 +30,17 @@
+ #include <net/netfilter/nf_conntrack_zones.h>
+ #include <linux/netfilter/nf_nat.h>
+ 
++static DEFINE_SPINLOCK(nf_nat_lock);
++
+ static DEFINE_MUTEX(nf_nat_proto_mutex);
+ static const struct nf_nat_l3proto __rcu *nf_nat_l3protos[NFPROTO_NUMPROTO]
+ 						__read_mostly;
+ static const struct nf_nat_l4proto __rcu **nf_nat_l4protos[NFPROTO_NUMPROTO]
+ 						__read_mostly;
+ 
+-struct nf_nat_conn_key {
+-	const struct net *net;
+-	const struct nf_conntrack_tuple *tuple;
+-	const struct nf_conntrack_zone *zone;
+-};
+-
+-static struct rhashtable nf_nat_bysource_table;
++static struct hlist_head *nf_nat_bysource __read_mostly;
++static unsigned int nf_nat_htable_size __read_mostly;
++static unsigned int nf_nat_hash_rnd __read_mostly;
+ 
+ inline const struct nf_nat_l3proto *
+ __nf_nat_l3proto_find(u8 family)
+@@ -121,17 +119,19 @@ int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family)
+ EXPORT_SYMBOL(nf_xfrm_me_harder);
+ #endif /* CONFIG_XFRM */
+ 
+-static u32 nf_nat_bysource_hash(const void *data, u32 len, u32 seed)
++/* We keep an extra hash for each conntrack, for fast searching. */
++static inline unsigned int
++hash_by_src(const struct net *n, const struct nf_conntrack_tuple *tuple)
+ {
+-	const struct nf_conntrack_tuple *t;
+-	const struct nf_conn *ct = data;
++	unsigned int hash;
++
++	get_random_once(&nf_nat_hash_rnd, sizeof(nf_nat_hash_rnd));
+ 
+-	t = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
+ 	/* Original src, to ensure we map it consistently if poss. */
++	hash = jhash2((u32 *)&tuple->src, sizeof(tuple->src) / sizeof(u32),
++		      tuple->dst.protonum ^ nf_nat_hash_rnd ^ net_hash_mix(n));
+ 
+-	seed ^= net_hash_mix(nf_ct_net(ct));
+-	return jhash2((const u32 *)&t->src, sizeof(t->src) / sizeof(u32),
+-		      t->dst.protonum ^ seed);
++	return reciprocal_scale(hash, nf_nat_htable_size);
+ }
+ 
+ /* Is this tuple already taken? (not by us) */
+@@ -187,26 +187,6 @@ same_src(const struct nf_conn *ct,
+ 		t->src.u.all == tuple->src.u.all);
+ }
+ 
+-static int nf_nat_bysource_cmp(struct rhashtable_compare_arg *arg,
+-			       const void *obj)
+-{
+-	const struct nf_nat_conn_key *key = arg->key;
+-	const struct nf_conn *ct = obj;
+-
+-	return same_src(ct, key->tuple) &&
+-	       net_eq(nf_ct_net(ct), key->net) &&
+-	       nf_ct_zone_equal(ct, key->zone, IP_CT_DIR_ORIGINAL);
+-}
+-
+-static struct rhashtable_params nf_nat_bysource_params = {
+-	.head_offset = offsetof(struct nf_conn, nat_bysource),
+-	.obj_hashfn = nf_nat_bysource_hash,
+-	.obj_cmpfn = nf_nat_bysource_cmp,
+-	.nelem_hint = 256,
+-	.min_size = 1024,
+-	.nulls_base = (1U << RHT_BASE_SHIFT),
+-};
+-
+ /* Only called for SRC manip */
+ static int
+ find_appropriate_src(struct net *net,
+@@ -217,23 +197,25 @@ find_appropriate_src(struct net *net,
+ 		     struct nf_conntrack_tuple *result,
+ 		     const struct nf_nat_range *range)
+ {
++	unsigned int h = hash_by_src(net, tuple);
++	const struct nf_conn_nat *nat;
+ 	const struct nf_conn *ct;
+-	struct nf_nat_conn_key key = {
+-		.net = net,
+-		.tuple = tuple,
+-		.zone = zone
+-	};
+ 
+-	ct = rhashtable_lookup_fast(&nf_nat_bysource_table, &key,
+-				    nf_nat_bysource_params);
+-	if (!ct)
+-		return 0;
+-
+-	nf_ct_invert_tuplepr(result,
+-			     &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
+-	result->dst = tuple->dst;
+-
+-	return in_range(l3proto, l4proto, result, range);
++	hlist_for_each_entry_rcu(nat, &nf_nat_bysource[h], bysource) {
++		ct = nat->ct;
++		if (same_src(ct, tuple) &&
++		    net_eq(net, nf_ct_net(ct)) &&
++		    nf_ct_zone_equal(ct, zone, IP_CT_DIR_ORIGINAL)) {
++			/* Copy source part from reply tuple. */
++			nf_ct_invert_tuplepr(result,
++				       &ct->tuplehash[IP_CT_DIR_REPLY].tuple);
++			result->dst = tuple->dst;
++
++			if (in_range(l3proto, l4proto, result, range))
++				return 1;
++		}
++	}
++	return 0;
+ }
+ 
+ /* For [FUTURE] fragmentation handling, we want the least-used
+@@ -405,6 +387,7 @@ nf_nat_setup_info(struct nf_conn *ct,
+ 		  const struct nf_nat_range *range,
+ 		  enum nf_nat_manip_type maniptype)
+ {
++	struct net *net = nf_ct_net(ct);
+ 	struct nf_conntrack_tuple curr_tuple, new_tuple;
+ 	struct nf_conn_nat *nat;
+ 
+@@ -446,13 +429,17 @@ nf_nat_setup_info(struct nf_conn *ct,
+ 	}
+ 
+ 	if (maniptype == NF_NAT_MANIP_SRC) {
+-		int err;
+-
+-		err = rhashtable_insert_fast(&nf_nat_bysource_table,
+-					     &ct->nat_bysource,
+-					     nf_nat_bysource_params);
+-		if (err)
+-			return NF_DROP;
++		unsigned int srchash;
++
++		srchash = hash_by_src(net,
++				      &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
++		spin_lock_bh(&nf_nat_lock);
++		/* nf_conntrack_alter_reply might re-allocate extension aera */
++		nat = nfct_nat(ct);
++		nat->ct = ct;
++		hlist_add_head_rcu(&nat->bysource,
++				   &nf_nat_bysource[srchash]);
++		spin_unlock_bh(&nf_nat_lock);
+ 	}
+ 
+ 	/* It's done. */
+@@ -557,7 +544,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
+ 	if (nf_nat_proto_remove(ct, data))
+ 		return 1;
+ 
+-	if (!nat)
++	if (!nat || !nat->ct)
+ 		return 0;
+ 
+ 	/* This netns is being destroyed, and conntrack has nat null binding.
+@@ -569,10 +556,11 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
+ 	if (!del_timer(&ct->timeout))
+ 		return 1;
+ 
++	spin_lock_bh(&nf_nat_lock);
++	hlist_del_rcu(&nat->bysource);
+ 	ct->status &= ~IPS_NAT_DONE_MASK;
+-
+-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
+-			       nf_nat_bysource_params);
++	nat->ct = NULL;
++	spin_unlock_bh(&nf_nat_lock);
+ 
+ 	add_timer(&ct->timeout);
+ 
+@@ -701,17 +689,35 @@ static void nf_nat_cleanup_conntrack(struct nf_conn *ct)
+ {
+ 	struct nf_conn_nat *nat = nf_ct_ext_find(ct, NF_CT_EXT_NAT);
+ 
+-	if (!nat)
++	if (nat == NULL || nat->ct == NULL)
+ 		return;
+ 
+-	rhashtable_remove_fast(&nf_nat_bysource_table, &ct->nat_bysource,
+-			       nf_nat_bysource_params);
++	NF_CT_ASSERT(nat->ct->status & IPS_SRC_NAT_DONE);
++
++	spin_lock_bh(&nf_nat_lock);
++	hlist_del_rcu(&nat->bysource);
++	spin_unlock_bh(&nf_nat_lock);
++}
++
++static void nf_nat_move_storage(void *new, void *old)
++{
++	struct nf_conn_nat *new_nat = new;
++	struct nf_conn_nat *old_nat = old;
++	struct nf_conn *ct = old_nat->ct;
++
++	if (!ct || !(ct->status & IPS_SRC_NAT_DONE))
++		return;
++
++	spin_lock_bh(&nf_nat_lock);
++	hlist_replace_rcu(&old_nat->bysource, &new_nat->bysource);
++	spin_unlock_bh(&nf_nat_lock);
+ }
+ 
+ static struct nf_ct_ext_type nat_extend __read_mostly = {
+ 	.len		= sizeof(struct nf_conn_nat),
+ 	.align		= __alignof__(struct nf_conn_nat),
+ 	.destroy	= nf_nat_cleanup_conntrack,
++	.move		= nf_nat_move_storage,
+ 	.id		= NF_CT_EXT_NAT,
+ 	.flags		= NF_CT_EXT_F_PREALLOC,
+ };
+@@ -840,13 +846,16 @@ static int __init nf_nat_init(void)
+ {
+ 	int ret;
+ 
+-	ret = rhashtable_init(&nf_nat_bysource_table, &nf_nat_bysource_params);
+-	if (ret)
+-		return ret;
++	/* Leave them the same for the moment. */
++	nf_nat_htable_size = nf_conntrack_htable_size;
++
++	nf_nat_bysource = nf_ct_alloc_hashtable(&nf_nat_htable_size, 0);
++	if (!nf_nat_bysource)
++		return -ENOMEM;
+ 
+ 	ret = nf_ct_extend_register(&nat_extend);
+ 	if (ret < 0) {
+-		rhashtable_destroy(&nf_nat_bysource_table);
++		nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ 		printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
+ 		return ret;
+ 	}
+@@ -870,7 +879,7 @@ static int __init nf_nat_init(void)
+ 	return 0;
+ 
+  cleanup_extend:
+-	rhashtable_destroy(&nf_nat_bysource_table);
++	nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ 	nf_ct_extend_unregister(&nat_extend);
+ 	return ret;
+ }
+@@ -888,8 +897,8 @@ static void __exit nf_nat_cleanup(void)
+ #endif
+ 	for (i = 0; i < NFPROTO_NUMPROTO; i++)
+ 		kfree(nf_nat_l4protos[i]);
+-
+-	rhashtable_destroy(&nf_nat_bysource_table);
++	synchronize_net();
++	nf_ct_free_hashtable(nf_nat_bysource, nf_nat_htable_size);
+ }
+ 
+ MODULE_LICENSE("GPL");
+diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c
+index 7f57a145a47e..a03cf68d0bcd 100644
+--- a/sound/pci/hda/hda_auto_parser.c
++++ b/sound/pci/hda/hda_auto_parser.c
+@@ -884,6 +884,8 @@ void snd_hda_apply_fixup(struct hda_codec *codec, int action)
+ }
+ EXPORT_SYMBOL_GPL(snd_hda_apply_fixup);
+ 
++#define IGNORE_SEQ_ASSOC (~(AC_DEFCFG_SEQUENCE | AC_DEFCFG_DEF_ASSOC))
++
+ static bool pin_config_match(struct hda_codec *codec,
+ 			     const struct hda_pintbl *pins)
+ {
+@@ -901,7 +903,7 @@ static bool pin_config_match(struct hda_codec *codec,
+ 		for (; t_pins->nid; t_pins++) {
+ 			if (t_pins->nid == nid) {
+ 				found = 1;
+-				if (t_pins->val == cfg)
++				if ((t_pins->val & IGNORE_SEQ_ASSOC) == (cfg & IGNORE_SEQ_ASSOC))
+ 					break;
+ 				else if ((cfg & 0xf0000000) == 0x40000000 && (t_pins->val & 0xf0000000) == 0x40000000)
+ 					break;
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 9ceb2bc36e68..c146d0de53d8 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -780,6 +780,7 @@ static const struct hda_pintbl alienware_pincfgs[] = {
+ static const struct snd_pci_quirk ca0132_quirks[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x0685, "Alienware 15 2015", QUIRK_ALIENWARE),
+ 	SND_PCI_QUIRK(0x1028, 0x0688, "Alienware 17 2015", QUIRK_ALIENWARE),
++	SND_PCI_QUIRK(0x1028, 0x0708, "Alienware 15 R2 2016", QUIRK_ALIENWARE),
+ 	{}
+ };
+ 
+diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
+index ed62748a6d55..c15c51bea26d 100644
+--- a/sound/pci/hda/patch_conexant.c
++++ b/sound/pci/hda/patch_conexant.c
+@@ -262,6 +262,7 @@ enum {
+ 	CXT_FIXUP_CAP_MIX_AMP_5047,
+ 	CXT_FIXUP_MUTE_LED_EAPD,
+ 	CXT_FIXUP_HP_SPECTRE,
++	CXT_FIXUP_HP_GATE_MIC,
+ };
+ 
+ /* for hda_fixup_thinkpad_acpi() */
+@@ -633,6 +634,17 @@ static void cxt_fixup_cap_mix_amp_5047(struct hda_codec *codec,
+ 				  (1 << AC_AMPCAP_MUTE_SHIFT));
+ }
+ 
++static void cxt_fixup_hp_gate_mic_jack(struct hda_codec *codec,
++				       const struct hda_fixup *fix,
++				       int action)
++{
++	/* the mic pin (0x19) doesn't give an unsolicited event;
++	 * probe the mic pin together with the headphone pin (0x16)
++	 */
++	if (action == HDA_FIXUP_ACT_PROBE)
++		snd_hda_jack_set_gating_jack(codec, 0x19, 0x16);
++}
++
+ /* ThinkPad X200 & co with cxt5051 */
+ static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
+ 	{ 0x16, 0x042140ff }, /* HP (seq# overridden) */
+@@ -774,6 +786,10 @@ static const struct hda_fixup cxt_fixups[] = {
+ 			{ }
+ 		}
+ 	},
++	[CXT_FIXUP_HP_GATE_MIC] = {
++		.type = HDA_FIXUP_FUNC,
++		.v.func = cxt_fixup_hp_gate_mic_jack,
++	},
+ };
+ 
+ static const struct snd_pci_quirk cxt5045_fixups[] = {
+@@ -824,6 +840,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = {
+ 	SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT_FIXUP_ASPIRE_DMIC),
+ 	SND_PCI_QUIRK(0x1025, 0x054f, "Acer Aspire 4830T", CXT_FIXUP_ASPIRE_DMIC),
+ 	SND_PCI_QUIRK(0x103c, 0x8174, "HP Spectre x360", CXT_FIXUP_HP_SPECTRE),
++	SND_PCI_QUIRK(0x103c, 0x8115, "HP Z1 Gen3", CXT_FIXUP_HP_GATE_MIC),
+ 	SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
+ 	SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT_FIXUP_OLPC_XO),
+ 	SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 162818058a5d..512fd83407f2 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5915,6 +5915,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x12, 0x90a60180},
+ 		{0x14, 0x90170120},
+ 		{0x21, 0x02211030}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x1b, 0x01011020},
++		{0x21, 0x02211010}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x12, 0x90a60160},
+ 		{0x14, 0x90170120},
+diff --git a/sound/soc/intel/atom/sst-mfld-platform-pcm.c b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+index 52ed434cbca6..f1223045c400 100644
+--- a/sound/soc/intel/atom/sst-mfld-platform-pcm.c
++++ b/sound/soc/intel/atom/sst-mfld-platform-pcm.c
+@@ -771,6 +771,9 @@ static int sst_soc_prepare(struct device *dev)
+ 	struct sst_data *drv = dev_get_drvdata(dev);
+ 	struct snd_soc_pcm_runtime *rtd;
+ 
++	if (!drv->soc_card)
++		return 0;
++
+ 	/* suspend all pcms first */
+ 	snd_soc_suspend(drv->soc_card->dev);
+ 	snd_soc_poweroff(drv->soc_card->dev);
+@@ -793,6 +796,9 @@ static void sst_soc_complete(struct device *dev)
+ 	struct sst_data *drv = dev_get_drvdata(dev);
+ 	struct snd_soc_pcm_runtime *rtd;
+ 
++	if (!drv->soc_card)
++		return;
++
+ 	/* restart SSPs */
+ 	list_for_each_entry(rtd, &drv->soc_card->rtd_list, list) {
+ 		struct snd_soc_dai *dai = rtd->cpu_dai;
+diff --git a/sound/usb/hiface/pcm.c b/sound/usb/hiface/pcm.c
+index 2c44139b4041..33db205dd12b 100644
+--- a/sound/usb/hiface/pcm.c
++++ b/sound/usb/hiface/pcm.c
+@@ -445,6 +445,8 @@ static int hiface_pcm_prepare(struct snd_pcm_substream *alsa_sub)
+ 
+ 	mutex_lock(&rt->stream_mutex);
+ 
++	hiface_pcm_stream_stop(rt);
++
+ 	sub->dma_off = 0;
+ 	sub->period_off = 0;
+ 
+diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c
+index 2f8c388ef84f..4703caea56b2 100644
+--- a/sound/usb/mixer.c
++++ b/sound/usb/mixer.c
+@@ -932,9 +932,10 @@ static void volume_control_quirks(struct usb_mixer_elem_info *cval,
+ 	case USB_ID(0x046d, 0x0826): /* HD Webcam c525 */
+ 	case USB_ID(0x046d, 0x08ca): /* Logitech Quickcam Fusion */
+ 	case USB_ID(0x046d, 0x0991):
++	case USB_ID(0x046d, 0x09a2): /* QuickCam Communicate Deluxe/S7500 */
+ 	/* Most audio usb devices lie about volume resolution.
+ 	 * Most Logitech webcams have res = 384.
+-	 * Proboly there is some logitech magic behind this number --fishor
++	 * Probably there is some logitech magic behind this number --fishor
+ 	 */
+ 		if (!strcmp(kctl->id.name, "Mic Capture Volume")) {
+ 			usb_audio_info(chip,


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [gentoo-commits] proj/linux-patches:4.8 commit in: /
@ 2017-01-09 11:44 Alice Ferrazzi
  0 siblings, 0 replies; 26+ messages in thread
From: Alice Ferrazzi @ 2017-01-09 11:44 UTC (permalink / raw
  To: gentoo-commits

commit:     203f855f3df02c2e1878212e32716806671716cd
Author:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
AuthorDate: Mon Jan  9 11:43:12 2017 +0000
Commit:     Alice Ferrazzi <alicef <AT> gentoo <DOT> org>
CommitDate: Mon Jan  9 11:43:12 2017 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=203f855f

Linux patch 4.8.17

 0000_README             |    4 +
 1016_linux-4.8.17.patch | 3229 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3233 insertions(+)

diff --git a/0000_README b/0000_README
index e7fac7c..f8302fa 100644
--- a/0000_README
+++ b/0000_README
@@ -107,6 +107,10 @@ Patch:  1015_linux-4.8.16.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.8.16
 
+Patch:  1016_linux-4.8.17.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.8.17
+
 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/1016_linux-4.8.17.patch b/1016_linux-4.8.17.patch
new file mode 100644
index 0000000..7782469
--- /dev/null
+++ b/1016_linux-4.8.17.patch
@@ -0,0 +1,3229 @@
+diff --git a/Documentation/sphinx/rstFlatTable.py b/Documentation/sphinx/rstFlatTable.py
+index 26db852e3c74..99163598f18b 100644
+--- a/Documentation/sphinx/rstFlatTable.py
++++ b/Documentation/sphinx/rstFlatTable.py
+@@ -151,6 +151,11 @@ class ListTableBuilder(object):
+     def buildTableNode(self):
+ 
+         colwidths    = self.directive.get_column_widths(self.max_cols)
++        if isinstance(colwidths, tuple):
++            # Since docutils 0.13, get_column_widths returns a (widths,
++            # colwidths) tuple, where widths is a string (i.e. 'auto').
++            # See https://sourceforge.net/p/docutils/patches/120/.
++            colwidths = colwidths[1]
+         stub_columns = self.directive.options.get('stub-columns', 0)
+         header_rows  = self.directive.options.get('header-rows', 0)
+ 
+diff --git a/Documentation/virtual/kvm/api.txt b/Documentation/virtual/kvm/api.txt
+index 739db9ab16b2..a7596e9fdf06 100644
+--- a/Documentation/virtual/kvm/api.txt
++++ b/Documentation/virtual/kvm/api.txt
+@@ -2039,6 +2039,7 @@ registers, find a list below:
+   PPC   | KVM_REG_PPC_TM_VSCR           | 32
+   PPC   | KVM_REG_PPC_TM_DSCR           | 64
+   PPC   | KVM_REG_PPC_TM_TAR            | 64
++  PPC   | KVM_REG_PPC_TM_XER            | 64
+         |                               |
+   MIPS  | KVM_REG_MIPS_R0               | 64
+           ...
+diff --git a/Makefile b/Makefile
+index 50f68648a79a..ace32d3bac4b 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 8
+-SUBLEVEL = 16
++SUBLEVEL = 17
+ EXTRAVERSION =
+ NAME = Psychotic Stoned Sheep
+ 
+diff --git a/arch/arc/include/asm/cacheflush.h b/arch/arc/include/asm/cacheflush.h
+index a093adbdb017..fc662f49c55a 100644
+--- a/arch/arc/include/asm/cacheflush.h
++++ b/arch/arc/include/asm/cacheflush.h
+@@ -85,6 +85,10 @@ void flush_anon_page(struct vm_area_struct *vma,
+  */
+ #define PG_dc_clean	PG_arch_1
+ 
++#define CACHE_COLORS_NUM	4
++#define CACHE_COLORS_MSK	(CACHE_COLORS_NUM - 1)
++#define CACHE_COLOR(addr)	(((unsigned long)(addr) >> (PAGE_SHIFT)) & CACHE_COLORS_MSK)
++
+ /*
+  * Simple wrapper over config option
+  * Bootup code ensures that hardware matches kernel configuration
+@@ -94,8 +98,6 @@ static inline int cache_is_vipt_aliasing(void)
+ 	return IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
+ }
+ 
+-#define CACHE_COLOR(addr)	(((unsigned long)(addr) >> (PAGE_SHIFT)) & 1)
+-
+ /*
+  * checks if two addresses (after page aligning) index into same cache set
+  */
+diff --git a/arch/arc/mm/cache.c b/arch/arc/mm/cache.c
+index 0b10efe3a6a7..ab1aaf2a28c8 100644
+--- a/arch/arc/mm/cache.c
++++ b/arch/arc/mm/cache.c
+@@ -967,11 +967,16 @@ void arc_cache_init(void)
+ 		/* check for D-Cache aliasing on ARCompact: ARCv2 has PIPT */
+ 		if (is_isa_arcompact()) {
+ 			int handled = IS_ENABLED(CONFIG_ARC_CACHE_VIPT_ALIASING);
+-
+-			if (dc->alias && !handled)
+-				panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
+-			else if (!dc->alias && handled)
++			int num_colors = dc->sz_k/dc->assoc/TO_KB(PAGE_SIZE);
++
++			if (dc->alias) {
++				if (!handled)
++					panic("Enable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
++				if (CACHE_COLORS_NUM != num_colors)
++					panic("CACHE_COLORS_NUM not optimized for config\n");
++			} else if (!dc->alias && handled) {
+ 				panic("Disable CONFIG_ARC_CACHE_VIPT_ALIASING\n");
++			}
+ 		}
+ 	}
+ 
+diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+index 5fda583351d7..906fb836d241 100644
+--- a/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
++++ b/arch/arm64/boot/dts/nvidia/tegra210-p2180.dtsi
+@@ -21,6 +21,10 @@
+ 		reg = <0x0 0x80000000 0x1 0x0>;
+ 	};
+ 
++	gpu@57000000 {
++		vdd-supply = <&vdd_gpu>;
++	};
++
+ 	/* debug port */
+ 	serial@70006000 {
+ 		status = "okay";
+@@ -291,4 +295,18 @@
+ 			clock-frequency = <32768>;
+ 		};
+ 	};
++
++	regulators {
++		vdd_gpu: regulator@100 {
++			compatible = "pwm-regulator";
++			reg = <100>;
++			pwms = <&pwm 1 4880>;
++			regulator-name = "VDD_GPU";
++			regulator-min-microvolt = <710000>;
++			regulator-max-microvolt = <1320000>;
++			enable-gpios = <&pmic 6 GPIO_ACTIVE_HIGH>;
++			regulator-ramp-delay = <80>;
++			regulator-enable-ramp-delay = <1000>;
++		};
++	};
+ };
+diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
+index 5a84b4562603..03498c8f0cf7 100644
+--- a/arch/arm64/kvm/hyp/switch.c
++++ b/arch/arm64/kvm/hyp/switch.c
+@@ -82,7 +82,13 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
+ 	write_sysreg(val, hcr_el2);
+ 	/* Trap on AArch32 cp15 c15 accesses (EL1 or EL0) */
+ 	write_sysreg(1 << 15, hstr_el2);
+-	/* Make sure we trap PMU access from EL0 to EL2 */
++	/*
++	 * Make sure we trap PMU access from EL0 to EL2. Also sanitize
++	 * PMSELR_EL0 to make sure it never contains the cycle
++	 * counter, which could make a PMXEVCNTR_EL0 access UNDEF at
++	 * EL1 instead of being trapped to EL2.
++	 */
++	write_sysreg(0, pmselr_el0);
+ 	write_sysreg(ARMV8_PMU_USERENR_MASK, pmuserenr_el0);
+ 	write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+ 	__activate_traps_arch()();
+diff --git a/arch/powerpc/boot/ps3-head.S b/arch/powerpc/boot/ps3-head.S
+index b6fcbaf5027b..3dc44b05fb97 100644
+--- a/arch/powerpc/boot/ps3-head.S
++++ b/arch/powerpc/boot/ps3-head.S
+@@ -57,11 +57,6 @@ __system_reset_overlay:
+ 	bctr
+ 
+ 1:
+-	/* Save the value at addr zero for a null pointer write check later. */
+-
+-	li	r4, 0
+-	lwz	r3, 0(r4)
+-
+ 	/* Primary delays then goes to _zimage_start in wrapper. */
+ 
+ 	or	31, 31, 31 /* db16cyc */
+diff --git a/arch/powerpc/boot/ps3.c b/arch/powerpc/boot/ps3.c
+index 4ec2d86d3c50..a05558a7e51a 100644
+--- a/arch/powerpc/boot/ps3.c
++++ b/arch/powerpc/boot/ps3.c
+@@ -119,13 +119,12 @@ void ps3_copy_vectors(void)
+ 	flush_cache((void *)0x100, 512);
+ }
+ 
+-void platform_init(unsigned long null_check)
++void platform_init(void)
+ {
+ 	const u32 heapsize = 0x1000000 - (u32)_end; /* 16MiB */
+ 	void *chosen;
+ 	unsigned long ft_addr;
+ 	u64 rm_size;
+-	unsigned long val;
+ 
+ 	console_ops.write = ps3_console_write;
+ 	platform_ops.exit = ps3_exit;
+@@ -153,11 +152,6 @@ void platform_init(unsigned long null_check)
+ 
+ 	printf(" flat tree at 0x%lx\n\r", ft_addr);
+ 
+-	val = *(unsigned long *)0;
+-
+-	if (val != null_check)
+-		printf("null check failed: %lx != %lx\n\r", val, null_check);
+-
+ 	((kernel_entry_t)0)(ft_addr, 0, NULL);
+ 
+ 	ps3_exit();
+diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h
+index ec35af34a3fb..f2c5dde507c7 100644
+--- a/arch/powerpc/include/asm/kvm_host.h
++++ b/arch/powerpc/include/asm/kvm_host.h
+@@ -555,6 +555,7 @@ struct kvm_vcpu_arch {
+ 	u64 tfiar;
+ 
+ 	u32 cr_tm;
++	u64 xer_tm;
+ 	u64 lr_tm;
+ 	u64 ctr_tm;
+ 	u64 amr_tm;
+diff --git a/arch/powerpc/include/uapi/asm/kvm.h b/arch/powerpc/include/uapi/asm/kvm.h
+index c93cf35ce379..0fb1326c3ea2 100644
+--- a/arch/powerpc/include/uapi/asm/kvm.h
++++ b/arch/powerpc/include/uapi/asm/kvm.h
+@@ -596,6 +596,7 @@ struct kvm_get_htab_header {
+ #define KVM_REG_PPC_TM_VSCR	(KVM_REG_PPC_TM | KVM_REG_SIZE_U32 | 0x67)
+ #define KVM_REG_PPC_TM_DSCR	(KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x68)
+ #define KVM_REG_PPC_TM_TAR	(KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x69)
++#define KVM_REG_PPC_TM_XER	(KVM_REG_PPC_TM | KVM_REG_SIZE_U64 | 0x6a)
+ 
+ /* PPC64 eXternal Interrupt Controller Specification */
+ #define KVM_DEV_XICS_GRP_SOURCES	1	/* 64-bit source attributes */
+diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
+index b89d14c0352c..6ba221c76214 100644
+--- a/arch/powerpc/kernel/asm-offsets.c
++++ b/arch/powerpc/kernel/asm-offsets.c
+@@ -569,6 +569,7 @@ int main(void)
+ 	DEFINE(VCPU_VRS_TM, offsetof(struct kvm_vcpu, arch.vr_tm.vr));
+ 	DEFINE(VCPU_VRSAVE_TM, offsetof(struct kvm_vcpu, arch.vrsave_tm));
+ 	DEFINE(VCPU_CR_TM, offsetof(struct kvm_vcpu, arch.cr_tm));
++	DEFINE(VCPU_XER_TM, offsetof(struct kvm_vcpu, arch.xer_tm));
+ 	DEFINE(VCPU_LR_TM, offsetof(struct kvm_vcpu, arch.lr_tm));
+ 	DEFINE(VCPU_CTR_TM, offsetof(struct kvm_vcpu, arch.ctr_tm));
+ 	DEFINE(VCPU_AMR_TM, offsetof(struct kvm_vcpu, arch.amr_tm));
+diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
+index f765b0434731..882578929fe7 100644
+--- a/arch/powerpc/kernel/head_64.S
++++ b/arch/powerpc/kernel/head_64.S
+@@ -201,9 +201,9 @@ booting_thread_hwid:
+  */
+ _GLOBAL(book3e_start_thread)
+ 	LOAD_REG_IMMEDIATE(r5, MSR_KERNEL)
+-	cmpi	0, r3, 0
++	cmpwi	r3, 0
+ 	beq	10f
+-	cmpi	0, r3, 1
++	cmpwi	r3, 1
+ 	beq	11f
+ 	/* If the thread id is invalid, just exit. */
+ 	b	13f
+@@ -228,9 +228,9 @@ _GLOBAL(book3e_start_thread)
+  * r3 = the thread physical id
+  */
+ _GLOBAL(book3e_stop_thread)
+-	cmpi	0, r3, 0
++	cmpwi	r3, 0
+ 	beq	10f
+-	cmpi	0, r3, 1
++	cmpwi	r3, 1
+ 	beq	10f
+ 	/* If the thread id is invalid, just exit. */
+ 	b	13f
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
+index 2fd5580c8f6e..4c8d344486e6 100644
+--- a/arch/powerpc/kvm/book3s_hv.c
++++ b/arch/powerpc/kvm/book3s_hv.c
+@@ -1235,6 +1235,9 @@ static int kvmppc_get_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
+ 	case KVM_REG_PPC_TM_CR:
+ 		*val = get_reg_val(id, vcpu->arch.cr_tm);
+ 		break;
++	case KVM_REG_PPC_TM_XER:
++		*val = get_reg_val(id, vcpu->arch.xer_tm);
++		break;
+ 	case KVM_REG_PPC_TM_LR:
+ 		*val = get_reg_val(id, vcpu->arch.lr_tm);
+ 		break;
+@@ -1442,6 +1445,9 @@ static int kvmppc_set_one_reg_hv(struct kvm_vcpu *vcpu, u64 id,
+ 	case KVM_REG_PPC_TM_CR:
+ 		vcpu->arch.cr_tm = set_reg_val(id, *val);
+ 		break;
++	case KVM_REG_PPC_TM_XER:
++		vcpu->arch.xer_tm = set_reg_val(id, *val);
++		break;
+ 	case KVM_REG_PPC_TM_LR:
+ 		vcpu->arch.lr_tm = set_reg_val(id, *val);
+ 		break;
+diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+index 99b4e9d5dd23..5420d060c6f6 100644
+--- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c
++++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c
+@@ -653,6 +653,8 @@ long kvmppc_h_protect(struct kvm_vcpu *vcpu, unsigned long flags,
+ 					      HPTE_V_ABSENT);
+ 			do_tlbies(kvm, &rb, 1, global_invalidates(kvm, flags),
+ 				  true);
++			/* Don't lose R/C bit updates done by hardware */
++			r |= be64_to_cpu(hpte[1]) & (HPTE_R_R | HPTE_R_C);
+ 			hpte[1] = cpu_to_be64(r);
+ 		}
+ 	}
+diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+index 975655573844..bf243a4caa63 100644
+--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
++++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+@@ -2579,11 +2579,13 @@ kvmppc_save_tm:
+ 	mfctr	r7
+ 	mfspr	r8, SPRN_AMR
+ 	mfspr	r10, SPRN_TAR
++	mfxer	r11
+ 	std	r5, VCPU_LR_TM(r9)
+ 	stw	r6, VCPU_CR_TM(r9)
+ 	std	r7, VCPU_CTR_TM(r9)
+ 	std	r8, VCPU_AMR_TM(r9)
+ 	std	r10, VCPU_TAR_TM(r9)
++	std	r11, VCPU_XER_TM(r9)
+ 
+ 	/* Restore r12 as trap number. */
+ 	lwz	r12, VCPU_TRAP(r9)
+@@ -2676,11 +2678,13 @@ kvmppc_restore_tm:
+ 	ld	r7, VCPU_CTR_TM(r4)
+ 	ld	r8, VCPU_AMR_TM(r4)
+ 	ld	r9, VCPU_TAR_TM(r4)
++	ld	r10, VCPU_XER_TM(r4)
+ 	mtlr	r5
+ 	mtcr	r6
+ 	mtctr	r7
+ 	mtspr	SPRN_AMR, r8
+ 	mtspr	SPRN_TAR, r9
++	mtxer	r10
+ 
+ 	/*
+ 	 * Load up PPR and DSCR values but don't put them in the actual SPRs
+diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
+index 7f7ba5f23f13..d027f2eb3559 100644
+--- a/arch/s390/kernel/setup.c
++++ b/arch/s390/kernel/setup.c
+@@ -445,7 +445,7 @@ static void __init setup_resources(void)
+ 	 * part of the System RAM resource.
+ 	 */
+ 	if (crashk_res.end) {
+-		memblock_add(crashk_res.start, resource_size(&crashk_res));
++		memblock_add_node(crashk_res.start, resource_size(&crashk_res), 0);
+ 		memblock_reserve(crashk_res.start, resource_size(&crashk_res));
+ 		insert_resource(&iomem_resource, &crashk_res);
+ 	}
+diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
+index 0b56666e6039..b84a3496994c 100644
+--- a/arch/x86/entry/entry_32.S
++++ b/arch/x86/entry/entry_32.S
+@@ -852,8 +852,8 @@ ftrace_graph_call:
+ 	jmp	ftrace_stub
+ #endif
+ 
+-.globl ftrace_stub
+-ftrace_stub:
++/* This is weak to keep gas from relaxing the jumps */
++WEAK(ftrace_stub)
+ 	ret
+ END(ftrace_caller)
+ 
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 8c925ecaf534..7b0f1d932c87 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -364,7 +364,11 @@ int x86_add_exclusive(unsigned int what)
+ {
+ 	int i;
+ 
+-	if (x86_pmu.lbr_pt_coexist)
++	/*
++	 * When lbr_pt_coexist we allow PT to coexist with either LBR or BTS.
++	 * LBR and BTS are still mutually exclusive.
++	 */
++	if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
+ 		return 0;
+ 
+ 	if (!atomic_inc_not_zero(&x86_pmu.lbr_exclusive[what])) {
+@@ -387,7 +391,7 @@ fail_unlock:
+ 
+ void x86_del_exclusive(unsigned int what)
+ {
+-	if (x86_pmu.lbr_pt_coexist)
++	if (x86_pmu.lbr_pt_coexist && what == x86_lbr_exclusive_pt)
+ 		return;
+ 
+ 	atomic_dec(&x86_pmu.lbr_exclusive[what]);
+diff --git a/arch/x86/events/intel/cstate.c b/arch/x86/events/intel/cstate.c
+index 3ca87b5a8677..834262aec88d 100644
+--- a/arch/x86/events/intel/cstate.c
++++ b/arch/x86/events/intel/cstate.c
+@@ -571,6 +571,9 @@ static int __init cstate_probe(const struct cstate_model *cm)
+ 
+ static inline void cstate_cleanup(void)
+ {
++	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_ONLINE);
++	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_STARTING);
++
+ 	if (has_cstate_core)
+ 		perf_pmu_unregister(&cstate_core_pmu);
+ 
+@@ -583,16 +586,16 @@ static int __init cstate_init(void)
+ 	int err;
+ 
+ 	cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_STARTING,
+-			  "AP_PERF_X86_CSTATE_STARTING", cstate_cpu_init,
+-			  NULL);
++			  "perf/x86/cstate:starting", cstate_cpu_init, NULL);
+ 	cpuhp_setup_state(CPUHP_AP_PERF_X86_CSTATE_ONLINE,
+-			  "AP_PERF_X86_CSTATE_ONLINE", NULL, cstate_cpu_exit);
++			  "perf/x86/cstate:online", NULL, cstate_cpu_exit);
+ 
+ 	if (has_cstate_core) {
+ 		err = perf_pmu_register(&cstate_core_pmu, cstate_core_pmu.name, -1);
+ 		if (err) {
+ 			has_cstate_core = false;
+ 			pr_info("Failed to register cstate core pmu\n");
++			cstate_cleanup();
+ 			return err;
+ 		}
+ 	}
+@@ -606,8 +609,7 @@ static int __init cstate_init(void)
+ 			return err;
+ 		}
+ 	}
+-
+-	return err;
++	return 0;
+ }
+ 
+ static int __init cstate_pmu_init(void)
+@@ -632,8 +634,6 @@ module_init(cstate_pmu_init);
+ 
+ static void __exit cstate_pmu_exit(void)
+ {
+-	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_ONLINE);
+-	cpuhp_remove_state_nocalls(CPUHP_AP_PERF_X86_CSTATE_STARTING);
+ 	cstate_cleanup();
+ }
+ module_exit(cstate_pmu_exit);
+diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
+index 181c238d4df9..4ab002d4c9fd 100644
+--- a/arch/x86/events/perf_event.h
++++ b/arch/x86/events/perf_event.h
+@@ -601,7 +601,7 @@ struct x86_pmu {
+ 	u64		lbr_sel_mask;		   /* LBR_SELECT valid bits */
+ 	const int	*lbr_sel_map;		   /* lbr_select mappings */
+ 	bool		lbr_double_abort;	   /* duplicated lbr aborts */
+-	bool		lbr_pt_coexist;		   /* LBR may coexist with PT */
++	bool		lbr_pt_coexist;		   /* (LBR|BTS) may coexist with PT */
+ 
+ 	/*
+ 	 * Intel PT/LBR/BTS are exclusive
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 5cede40e2552..7a72db5350aa 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -1336,10 +1336,10 @@ static inline bool nested_cpu_has_posted_intr(struct vmcs12 *vmcs12)
+ 	return vmcs12->pin_based_vm_exec_control & PIN_BASED_POSTED_INTR;
+ }
+ 
+-static inline bool is_exception(u32 intr_info)
++static inline bool is_nmi(u32 intr_info)
+ {
+ 	return (intr_info & (INTR_INFO_INTR_TYPE_MASK | INTR_INFO_VALID_MASK))
+-		== (INTR_TYPE_HARD_EXCEPTION | INTR_INFO_VALID_MASK);
++		== (INTR_TYPE_NMI_INTR | INTR_INFO_VALID_MASK);
+ }
+ 
+ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason,
+@@ -5467,7 +5467,7 @@ static int handle_exception(struct kvm_vcpu *vcpu)
+ 	if (is_machine_check(intr_info))
+ 		return handle_machine_check(vcpu);
+ 
+-	if ((intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR)
++	if (is_nmi(intr_info))
+ 		return 1;  /* already handled by vmx_vcpu_run() */
+ 
+ 	if (is_no_device(intr_info)) {
+@@ -7974,7 +7974,7 @@ static bool nested_vmx_exit_handled(struct kvm_vcpu *vcpu)
+ 
+ 	switch (exit_reason) {
+ 	case EXIT_REASON_EXCEPTION_NMI:
+-		if (!is_exception(intr_info))
++		if (is_nmi(intr_info))
+ 			return false;
+ 		else if (is_page_fault(intr_info))
+ 			return enable_ept;
+@@ -8572,8 +8572,7 @@ static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx)
+ 		kvm_machine_check();
+ 
+ 	/* We need to handle NMIs before interrupts are enabled */
+-	if ((exit_intr_info & INTR_INFO_INTR_TYPE_MASK) == INTR_TYPE_NMI_INTR &&
+-	    (exit_intr_info & INTR_INFO_VALID_MASK)) {
++	if (is_nmi(exit_intr_info)) {
+ 		kvm_before_handle_nmi(&vmx->vcpu);
+ 		asm("int $2");
+ 		kvm_after_handle_nmi(&vmx->vcpu);
+diff --git a/block/bsg.c b/block/bsg.c
+index d214e929ce18..b9a53615bdef 100644
+--- a/block/bsg.c
++++ b/block/bsg.c
+@@ -655,6 +655,9 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
+ 
+ 	dprintk("%s: write %Zd bytes\n", bd->name, count);
+ 
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
++		return -EINVAL;
++
+ 	bsg_set_block(bd, file);
+ 
+ 	bytes_written = 0;
+diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c
+index a6b36fc53aec..02ded25c82e4 100644
+--- a/drivers/acpi/video_detect.c
++++ b/drivers/acpi/video_detect.c
+@@ -296,6 +296,26 @@ static const struct dmi_system_id video_detect_dmi_table[] = {
+ 		DMI_MATCH(DMI_PRODUCT_NAME, "Vostro V131"),
+ 		},
+ 	},
++	{
++	 /* https://bugzilla.redhat.com/show_bug.cgi?id=1123661 */
++	 .callback = video_detect_force_native,
++	 .ident = "Dell XPS 17 L702X",
++	 .matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++		DMI_MATCH(DMI_PRODUCT_NAME, "Dell System XPS L702X"),
++		},
++	},
++	{
++	/* https://bugzilla.redhat.com/show_bug.cgi?id=1204476 */
++	/* https://bugs.launchpad.net/ubuntu/+source/linux-lts-trusty/+bug/1416940 */
++	.callback = video_detect_force_native,
++	.ident = "HP Pavilion dv6",
++	.matches = {
++		DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
++		DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion dv6 Notebook PC"),
++		},
++	},
++
+ 	{ },
+ };
+ 
+diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c
+index 22d1760a4278..a95e1e572697 100644
+--- a/drivers/base/firmware_class.c
++++ b/drivers/base/firmware_class.c
+@@ -955,13 +955,14 @@ static int _request_firmware_load(struct firmware_priv *fw_priv,
+ 		timeout = MAX_JIFFY_OFFSET;
+ 	}
+ 
+-	retval = wait_for_completion_interruptible_timeout(&buf->completion,
++	timeout = wait_for_completion_interruptible_timeout(&buf->completion,
+ 			timeout);
+-	if (retval == -ERESTARTSYS || !retval) {
++	if (timeout == -ERESTARTSYS || !timeout) {
++		retval = timeout;
+ 		mutex_lock(&fw_lock);
+ 		fw_load_abort(fw_priv);
+ 		mutex_unlock(&fw_lock);
+-	} else if (retval > 0) {
++	} else if (timeout > 0) {
+ 		retval = 0;
+ 	}
+ 
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 0fc71cbaa440..3250694fd793 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -751,7 +751,9 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw)
+ 	cprman_write(cprman, data->cm_reg,
+ 		     (cprman_read(cprman, data->cm_reg) &
+ 		      ~data->load_mask) | data->hold_mask);
+-	cprman_write(cprman, data->a2w_reg, A2W_PLL_CHANNEL_DISABLE);
++	cprman_write(cprman, data->a2w_reg,
++		     cprman_read(cprman, data->a2w_reg) |
++		     A2W_PLL_CHANNEL_DISABLE);
+ 	spin_unlock(&cprman->regs_lock);
+ }
+ 
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index 15704aaf9e4e..a8eea8a69da3 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -984,7 +984,8 @@ static int gpio_chrdev_open(struct inode *inode, struct file *filp)
+ 		return -ENODEV;
+ 	get_device(&gdev->dev);
+ 	filp->private_data = gdev;
+-	return 0;
++
++	return nonseekable_open(inode, filp);
+ }
+ 
+ /**
+@@ -1009,7 +1010,7 @@ static const struct file_operations gpio_fileops = {
+ 	.release = gpio_chrdev_release,
+ 	.open = gpio_chrdev_open,
+ 	.owner = THIS_MODULE,
+-	.llseek = noop_llseek,
++	.llseek = no_llseek,
+ 	.unlocked_ioctl = gpio_ioctl,
+ #ifdef CONFIG_COMPAT
+ 	.compat_ioctl = gpio_ioctl_compat,
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+index b8184617ca25..8199232c2fbd 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
+@@ -3798,8 +3798,12 @@ static int gfx_v8_0_init_save_restore_list(struct amdgpu_device *adev)
+ 	temp = mmRLC_SRM_INDEX_CNTL_ADDR_0;
+ 	data = mmRLC_SRM_INDEX_CNTL_DATA_0;
+ 	for (i = 0; i < sizeof(unique_indices) / sizeof(int); i++) {
+-		amdgpu_mm_wreg(adev, temp + i, unique_indices[i] & 0x3FFFF, false);
+-		amdgpu_mm_wreg(adev, data + i, unique_indices[i] >> 20, false);
++		if (unique_indices[i] != 0) {
++			amdgpu_mm_wreg(adev, temp + i,
++					unique_indices[i] & 0x3FFFF, false);
++			amdgpu_mm_wreg(adev, data + i,
++					unique_indices[i] >> 20, false);
++		}
+ 	}
+ 	kfree(register_list_format);
+ 
+@@ -5735,29 +5739,24 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev
+ 	adev->gfx.rlc.funcs->enter_safe_mode(adev);
+ 
+ 	if (enable && (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGCG)) {
+-		/* 1 enable cntx_empty_int_enable/cntx_busy_int_enable/
+-		 * Cmp_busy/GFX_Idle interrupts
+-		 */
+-		gfx_v8_0_enable_gui_idle_interrupt(adev, true);
+-
+ 		temp1 = data1 =	RREG32(mmRLC_CGTT_MGCG_OVERRIDE);
+ 		data1 &= ~RLC_CGTT_MGCG_OVERRIDE__CGCG_MASK;
+ 		if (temp1 != data1)
+ 			WREG32(mmRLC_CGTT_MGCG_OVERRIDE, data1);
+ 
+-		/* 2 wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
++		/* : wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+ 		gfx_v8_0_wait_for_rlc_serdes(adev);
+ 
+-		/* 3 - clear cgcg override */
++		/* 2 - clear cgcg override */
+ 		gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGCG_OVERRIDE, CLE_BPM_SERDES_CMD);
+ 
+ 		/* wait for RLC_SERDES_CU_MASTER & RLC_SERDES_NONCU_MASTER idle */
+ 		gfx_v8_0_wait_for_rlc_serdes(adev);
+ 
+-		/* 4 - write cmd to set CGLS */
++		/* 3 - write cmd to set CGLS */
+ 		gfx_v8_0_send_serdes_cmd(adev, BPM_REG_CGLS_EN, SET_BPM_SERDES_CMD);
+ 
+-		/* 5 - enable cgcg */
++		/* 4 - enable cgcg */
+ 		data |= RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK;
+ 
+ 		if (adev->cg_flags & AMD_CG_SUPPORT_GFX_CGLS) {
+@@ -5775,6 +5774,11 @@ static void gfx_v8_0_update_coarse_grain_clock_gating(struct amdgpu_device *adev
+ 
+ 		if (temp != data)
+ 			WREG32(mmRLC_CGCG_CGLS_CTRL, data);
++
++		/* 5 enable cntx_empty_int_enable/cntx_busy_int_enable/
++		 * Cmp_busy/GFX_Idle interrupts
++		 */
++		gfx_v8_0_enable_gui_idle_interrupt(adev, true);
+ 	} else {
+ 		/* disable cntx_empty_int_enable & GFX Idle interrupt */
+ 		gfx_v8_0_enable_gui_idle_interrupt(adev, false);
+diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
+index 904beaa932d0..f75c6421db62 100644
+--- a/drivers/gpu/drm/ast/ast_main.c
++++ b/drivers/gpu/drm/ast/ast_main.c
+@@ -223,7 +223,8 @@ static int ast_get_dram_info(struct drm_device *dev)
+ 	ast_write32(ast, 0x10000, 0xfc600309);
+ 
+ 	do {
+-		;
++		if (pci_channel_offline(dev->pdev))
++			return -EIO;
+ 	} while (ast_read32(ast, 0x10000) != 0x01);
+ 	data = ast_read32(ast, 0x10004);
+ 
+@@ -428,7 +429,9 @@ int ast_driver_load(struct drm_device *dev, unsigned long flags)
+ 	ast_detect_chip(dev, &need_post);
+ 
+ 	if (ast->chip != AST1180) {
+-		ast_get_dram_info(dev);
++		ret = ast_get_dram_info(dev);
++		if (ret)
++			goto out_free;
+ 		ast->vram_size = ast_get_vram_info(dev);
+ 		DRM_INFO("dram %d %d %d %08x\n", ast->mclk, ast->dram_type, ast->dram_bus_width, ast->vram_size);
+ 	}
+diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
+index 50eb944fb78a..8f3ca526bd1b 100644
+--- a/drivers/gpu/drm/gma500/psb_drv.c
++++ b/drivers/gpu/drm/gma500/psb_drv.c
+@@ -473,6 +473,9 @@ static const struct file_operations psb_gem_fops = {
+ 	.open = drm_open,
+ 	.release = drm_release,
+ 	.unlocked_ioctl = psb_unlocked_ioctl,
++#ifdef CONFIG_COMPAT
++	.compat_ioctl = drm_compat_ioctl,
++#endif
+ 	.mmap = drm_gem_mmap,
+ 	.poll = drm_poll,
+ 	.read = drm_read,
+diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
+index 2bb69f3c5b84..b386b3162e29 100644
+--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
++++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
+@@ -55,10 +55,9 @@ int i915_gem_stolen_insert_node_in_range(struct drm_i915_private *dev_priv,
+ 		return -ENODEV;
+ 
+ 	/* See the comment at the drm_mm_init() call for more about this check.
+-	 * WaSkipStolenMemoryFirstPage:bdw,chv,kbl (incomplete)
++	 * WaSkipStolenMemoryFirstPage:bdw+ (incomplete)
+ 	 */
+-	if (start < 4096 && (IS_GEN8(dev_priv) ||
+-			     IS_KBL_REVID(dev_priv, 0, KBL_REVID_A0)))
++	if (start < 4096 && INTEL_GEN(dev_priv) >= 8)
+ 		start = 4096;
+ 
+ 	mutex_lock(&dev_priv->mm.stolen_lock);
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 35d385d70d8e..6bc93ba7e1dd 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -13494,8 +13494,9 @@ static int intel_modeset_checks(struct drm_atomic_state *state)
+ 
+ 		DRM_DEBUG_KMS("New cdclk calculated to be atomic %u, actual %u\n",
+ 			      intel_state->cdclk, intel_state->dev_cdclk);
+-	} else
++	} else {
+ 		to_intel_atomic_state(state)->cdclk = dev_priv->atomic_cdclk_freq;
++	}
+ 
+ 	intel_modeset_clear_plls(state);
+ 
+@@ -13596,8 +13597,9 @@ static int intel_atomic_check(struct drm_device *dev,
+ 
+ 		if (ret)
+ 			return ret;
+-	} else
+-		intel_state->cdclk = dev_priv->cdclk_freq;
++	} else {
++		intel_state->cdclk = dev_priv->atomic_cdclk_freq;
++	}
+ 
+ 	ret = drm_atomic_helper_check_planes(dev, state);
+ 	if (ret)
+@@ -15902,6 +15904,7 @@ void intel_modeset_init(struct drm_device *dev)
+ 
+ 	intel_update_czclk(dev_priv);
+ 	intel_update_cdclk(dev);
++	dev_priv->atomic_cdclk_freq = dev_priv->cdclk_freq;
+ 
+ 	intel_shared_dpll_init(dev);
+ 
+diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+index cd154ce6b6c1..34601574fc6e 100644
+--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
++++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+@@ -296,7 +296,8 @@ static void chv_exec_gpio(struct drm_i915_private *dev_priv,
+ 	mutex_lock(&dev_priv->sb_lock);
+ 	vlv_iosf_sb_write(dev_priv, port, cfg1, 0);
+ 	vlv_iosf_sb_write(dev_priv, port, cfg0,
+-			  CHV_GPIO_GPIOCFG_GPO | CHV_GPIO_GPIOTXSTATE(value));
++			  CHV_GPIO_GPIOEN | CHV_GPIO_GPIOCFG_GPO |
++			  CHV_GPIO_GPIOTXSTATE(value));
+ 	mutex_unlock(&dev_priv->sb_lock);
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c
+index 1c603bbe5784..07a7cc0d4ebb 100644
+--- a/drivers/gpu/drm/i915/intel_runtime_pm.c
++++ b/drivers/gpu/drm/i915/intel_runtime_pm.c
+@@ -1062,7 +1062,18 @@ static bool vlv_power_well_enabled(struct drm_i915_private *dev_priv,
+ 
+ static void vlv_init_display_clock_gating(struct drm_i915_private *dev_priv)
+ {
+-	I915_WRITE(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE);
++	u32 val;
++
++	/*
++	 * On driver load, a pipe may be active and driving a DSI display.
++	 * Preserve DPOUNIT_CLOCK_GATE_DISABLE to avoid the pipe getting stuck
++	 * (and never recovering) in this case. intel_dsi_post_disable() will
++	 * clear it when we turn off the display.
++	 */
++	val = I915_READ(DSPCLK_GATE_D);
++	val &= DPOUNIT_CLOCK_GATE_DISABLE;
++	val |= VRHUNIT_CLOCK_GATE_DISABLE;
++	I915_WRITE(DSPCLK_GATE_D, val);
+ 
+ 	/*
+ 	 * Disable trickle feed and enable pnd deadline calculation
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
+index a1570b109434..23ffe8571a99 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
+@@ -333,6 +333,9 @@ get_fp_strap(struct drm_device *dev, struct nvbios *bios)
+ 	if (bios->major_version < 5 && bios->data[0x48] & 0x4)
+ 		return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf;
+ 
++	if (drm->device.info.family >= NV_DEVICE_INFO_V0_MAXWELL)
++		return nvif_rd32(device, 0x001800) & 0x0000000f;
++	else
+ 	if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
+ 		return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
+ 	else
+diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
+index 864323b19cf7..fad263b3c7f7 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
++++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
+@@ -1209,6 +1209,7 @@ nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
+ 			       nvbo->page_shift != vma->vm->mmu->lpg_shift)) {
+ 			nvkm_vm_map(vma, new_mem->mm_node);
+ 		} else {
++			WARN_ON(ttm_bo_wait(bo, false, false));
+ 			nvkm_vm_unmap(vma);
+ 		}
+ 	}
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+index 7218a067a6c5..e0d7f8472ac6 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
+@@ -1851,7 +1851,7 @@ nvf1_chipset = {
+ 	.fb = gk104_fb_new,
+ 	.fuse = gf100_fuse_new,
+ 	.gpio = gk104_gpio_new,
+-	.i2c = gf119_i2c_new,
++	.i2c = gk104_i2c_new,
+ 	.ibus = gk104_ibus_new,
+ 	.iccsense = gf100_iccsense_new,
+ 	.imem = nv50_instmem_new,
+@@ -1965,7 +1965,7 @@ nv117_chipset = {
+ 	.fb = gm107_fb_new,
+ 	.fuse = gm107_fuse_new,
+ 	.gpio = gk104_gpio_new,
+-	.i2c = gf119_i2c_new,
++	.i2c = gk104_i2c_new,
+ 	.ibus = gk104_ibus_new,
+ 	.iccsense = gf100_iccsense_new,
+ 	.imem = nv50_instmem_new,
+@@ -1999,7 +1999,7 @@ nv118_chipset = {
+ 	.fb = gm107_fb_new,
+ 	.fuse = gm107_fuse_new,
+ 	.gpio = gk104_gpio_new,
+-	.i2c = gf119_i2c_new,
++	.i2c = gk104_i2c_new,
+ 	.ibus = gk104_ibus_new,
+ 	.iccsense = gf100_iccsense_new,
+ 	.imem = nv50_instmem_new,
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
+index cbc67f262322..12d964260a29 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
+@@ -60,6 +60,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
+ 	struct nvkm_gpuobj *inst = chan->base.inst;
+ 	int ret = 0;
+ 
++	mutex_lock(&subdev->mutex);
+ 	nvkm_wr32(device, 0x002634, chan->base.chid);
+ 	if (nvkm_msec(device, 2000,
+ 		if (nvkm_rd32(device, 0x002634) == chan->base.chid)
+@@ -67,10 +68,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
+ 	) < 0) {
+ 		nvkm_error(subdev, "channel %d [%s] kick timeout\n",
+ 			   chan->base.chid, chan->base.object.client->name);
+-		ret = -EBUSY;
+-		if (suspend)
+-			return ret;
++		ret = -ETIMEDOUT;
+ 	}
++	mutex_unlock(&subdev->mutex);
++
++	if (ret && suspend)
++		return ret;
+ 
+ 	if (offset) {
+ 		nvkm_kmap(inst);
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+index ed4351032ed6..a2df4f3e7763 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+@@ -40,7 +40,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
+ 	struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
+ 	struct nvkm_device *device = subdev->device;
+ 	struct nvkm_client *client = chan->base.object.client;
++	int ret = 0;
+ 
++	mutex_lock(&subdev->mutex);
+ 	nvkm_wr32(device, 0x002634, chan->base.chid);
+ 	if (nvkm_msec(device, 2000,
+ 		if (!(nvkm_rd32(device, 0x002634) & 0x00100000))
+@@ -48,10 +50,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
+ 	) < 0) {
+ 		nvkm_error(subdev, "channel %d [%s] kick timeout\n",
+ 			   chan->base.chid, client->name);
+-		return -EBUSY;
++		ret = -ETIMEDOUT;
+ 	}
+-
+-	return 0;
++	mutex_unlock(&subdev->mutex);
++	return ret;
+ }
+ 
+ static u32
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+index 157919c788e6..6584d505460c 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+@@ -1756,6 +1756,50 @@ gf100_gr_ = {
+ };
+ 
+ int
++gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
++			struct gf100_gr_fuc *fuc, int ret)
++{
++	struct nvkm_subdev *subdev = &gr->base.engine.subdev;
++	struct nvkm_device *device = subdev->device;
++	const struct firmware *fw;
++	char f[32];
++
++	/* see if this firmware has a legacy path */
++	if (!strcmp(fwname, "fecs_inst"))
++		fwname = "fuc409c";
++	else if (!strcmp(fwname, "fecs_data"))
++		fwname = "fuc409d";
++	else if (!strcmp(fwname, "gpccs_inst"))
++		fwname = "fuc41ac";
++	else if (!strcmp(fwname, "gpccs_data"))
++		fwname = "fuc41ad";
++	else {
++		/* nope, let's just return the error we got */
++		nvkm_error(subdev, "failed to load %s\n", fwname);
++		return ret;
++	}
++
++	/* yes, try to load from the legacy path */
++	nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname);
++
++	snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
++	ret = request_firmware(&fw, f, device->dev);
++	if (ret) {
++		snprintf(f, sizeof(f), "nouveau/%s", fwname);
++		ret = request_firmware(&fw, f, device->dev);
++		if (ret) {
++			nvkm_error(subdev, "failed to load %s\n", fwname);
++			return ret;
++		}
++	}
++
++	fuc->size = fw->size;
++	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
++	release_firmware(fw);
++	return (fuc->data != NULL) ? 0 : -ENOMEM;
++}
++
++int
+ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
+ 		 struct gf100_gr_fuc *fuc)
+ {
+@@ -1765,10 +1809,8 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
+ 	int ret;
+ 
+ 	ret = nvkm_firmware_get(device, fwname, &fw);
+-	if (ret) {
+-		nvkm_error(subdev, "failed to load %s\n", fwname);
+-		return ret;
+-	}
++	if (ret)
++		return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
+ 
+ 	fuc->size = fw->size;
+ 	fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
+index 212800ecdce9..7d1d3c6b4b72 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
+@@ -12,6 +12,7 @@ struct nvbios_source {
+ 	bool rw;
+ 	bool ignore_checksum;
+ 	bool no_pcir;
++	bool require_checksum;
+ };
+ 
+ int nvbios_extend(struct nvkm_bios *, u32 length);
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
+index b2557e87afdd..7deb81b6dbac 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
+@@ -86,9 +86,12 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
+ 		    nvbios_checksum(&bios->data[image.base], image.size)) {
+ 			nvkm_debug(subdev, "%08x: checksum failed\n",
+ 				   image.base);
+-			if (mthd->func->rw)
++			if (!mthd->func->require_checksum) {
++				if (mthd->func->rw)
++					score += 1;
+ 				score += 1;
+-			score += 1;
++			} else
++				return 0;
+ 		} else {
+ 			score += 3;
+ 		}
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
+index 8fecb5ff22a0..06572f8ce914 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
+@@ -99,6 +99,7 @@ nvbios_acpi_fast = {
+ 	.init = acpi_init,
+ 	.read = acpi_read_fast,
+ 	.rw = false,
++	.require_checksum = true,
+ };
+ 
+ const struct nvbios_source
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
+index 39c2a38e54f7..0c7ef250dcaf 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/base.c
+@@ -47,8 +47,10 @@ nvkm_ltc_tags_clear(struct nvkm_ltc *ltc, u32 first, u32 count)
+ 
+ 	BUG_ON((first > limit) || (limit >= ltc->num_tags));
+ 
++	mutex_lock(&ltc->subdev.mutex);
+ 	ltc->func->cbc_clear(ltc, first, limit);
+ 	ltc->func->cbc_wait(ltc);
++	mutex_unlock(&ltc->subdev.mutex);
+ }
+ 
+ int
+diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c
+index 2a10e24b34b1..87a72476d313 100644
+--- a/drivers/gpu/drm/radeon/radeon_cursor.c
++++ b/drivers/gpu/drm/radeon/radeon_cursor.c
+@@ -90,6 +90,9 @@ static void radeon_show_cursor(struct drm_crtc *crtc)
+ 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
+ 	struct radeon_device *rdev = crtc->dev->dev_private;
+ 
++	if (radeon_crtc->cursor_out_of_bounds)
++		return;
++
+ 	if (ASIC_IS_DCE4(rdev)) {
+ 		WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
+ 		       upper_32_bits(radeon_crtc->cursor_addr));
+@@ -148,16 +151,17 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
+ 		x += crtc->x;
+ 		y += crtc->y;
+ 	}
+-	DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
+ 
+-	if (x < 0) {
++	if (x < 0)
+ 		xorigin = min(-x, radeon_crtc->max_cursor_width - 1);
+-		x = 0;
+-	}
+-	if (y < 0) {
++	if (y < 0)
+ 		yorigin = min(-y, radeon_crtc->max_cursor_height - 1);
+-		y = 0;
++
++	if (!ASIC_IS_AVIVO(rdev)) {
++		x += crtc->x;
++		y += crtc->y;
+ 	}
++	DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
+ 
+ 	/* fixed on DCE6 and newer */
+ 	if (ASIC_IS_AVIVO(rdev) && !ASIC_IS_DCE6(rdev)) {
+@@ -180,27 +184,31 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
+ 		if (i > 1) {
+ 			int cursor_end, frame_end;
+ 
+-			cursor_end = x - xorigin + w;
++			cursor_end = x + w;
+ 			frame_end = crtc->x + crtc->mode.crtc_hdisplay;
+ 			if (cursor_end >= frame_end) {
+ 				w = w - (cursor_end - frame_end);
+ 				if (!(frame_end & 0x7f))
+ 					w--;
+-			} else {
+-				if (!(cursor_end & 0x7f))
+-					w--;
++			} else if (cursor_end <= 0) {
++				goto out_of_bounds;
++			} else if (!(cursor_end & 0x7f)) {
++				w--;
+ 			}
+ 			if (w <= 0) {
+-				w = 1;
+-				cursor_end = x - xorigin + w;
+-				if (!(cursor_end & 0x7f)) {
+-					x--;
+-					WARN_ON_ONCE(x < 0);
+-				}
++				goto out_of_bounds;
+ 			}
+ 		}
+ 	}
+ 
++	if (x <= (crtc->x - w) || y <= (crtc->y - radeon_crtc->cursor_height) ||
++	    x >= (crtc->x + crtc->mode.crtc_hdisplay) ||
++	    y >= (crtc->y + crtc->mode.crtc_vdisplay))
++		goto out_of_bounds;
++
++	x += xorigin;
++	y += yorigin;
++
+ 	if (ASIC_IS_DCE4(rdev)) {
+ 		WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset, (x << 16) | y);
+ 		WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset, (xorigin << 16) | yorigin);
+@@ -212,6 +220,9 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
+ 		WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
+ 		       ((w - 1) << 16) | (radeon_crtc->cursor_height - 1));
+ 	} else {
++		x -= crtc->x;
++		y -= crtc->y;
++
+ 		if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
+ 			y *= 2;
+ 
+@@ -232,6 +243,19 @@ static int radeon_cursor_move_locked(struct drm_crtc *crtc, int x, int y)
+ 	radeon_crtc->cursor_x = x;
+ 	radeon_crtc->cursor_y = y;
+ 
++	if (radeon_crtc->cursor_out_of_bounds) {
++		radeon_crtc->cursor_out_of_bounds = false;
++		if (radeon_crtc->cursor_bo)
++			radeon_show_cursor(crtc);
++	}
++
++	return 0;
++
++ out_of_bounds:
++	if (!radeon_crtc->cursor_out_of_bounds) {
++		radeon_hide_cursor(crtc);
++		radeon_crtc->cursor_out_of_bounds = true;
++	}
+ 	return 0;
+ }
+ 
+@@ -297,22 +321,23 @@ int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
+ 		return ret;
+ 	}
+ 
+-	radeon_crtc->cursor_width = width;
+-	radeon_crtc->cursor_height = height;
+-
+ 	radeon_lock_cursor(crtc, true);
+ 
+-	if (hot_x != radeon_crtc->cursor_hot_x ||
++	if (width != radeon_crtc->cursor_width ||
++	    height != radeon_crtc->cursor_height ||
++	    hot_x != radeon_crtc->cursor_hot_x ||
+ 	    hot_y != radeon_crtc->cursor_hot_y) {
+ 		int x, y;
+ 
+ 		x = radeon_crtc->cursor_x + radeon_crtc->cursor_hot_x - hot_x;
+ 		y = radeon_crtc->cursor_y + radeon_crtc->cursor_hot_y - hot_y;
+ 
+-		radeon_cursor_move_locked(crtc, x, y);
+-
++		radeon_crtc->cursor_width = width;
++		radeon_crtc->cursor_height = height;
+ 		radeon_crtc->cursor_hot_x = hot_x;
+ 		radeon_crtc->cursor_hot_y = hot_y;
++
++		radeon_cursor_move_locked(crtc, x, y);
+ 	}
+ 
+ 	radeon_show_cursor(crtc);
+diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
+index bb75201a24ba..f1da484864a9 100644
+--- a/drivers/gpu/drm/radeon/radeon_mode.h
++++ b/drivers/gpu/drm/radeon/radeon_mode.h
+@@ -330,6 +330,7 @@ struct radeon_crtc {
+ 	u16 lut_r[256], lut_g[256], lut_b[256];
+ 	bool enabled;
+ 	bool can_tile;
++	bool cursor_out_of_bounds;
+ 	uint32_t crtc_offset;
+ 	struct drm_gem_object *cursor_bo;
+ 	uint64_t cursor_addr;
+diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
+index 2523ca96c6c7..2297ec7954af 100644
+--- a/drivers/gpu/drm/radeon/si.c
++++ b/drivers/gpu/drm/radeon/si.c
+@@ -1722,6 +1722,7 @@ static int si_init_microcode(struct radeon_device *rdev)
+ 		    (rdev->pdev->revision == 0x80) ||
+ 		    (rdev->pdev->revision == 0x81) ||
+ 		    (rdev->pdev->revision == 0x83) ||
++		    (rdev->pdev->revision == 0x87) ||
+ 		    (rdev->pdev->device == 0x6604) ||
+ 		    (rdev->pdev->device == 0x6605))
+ 			new_smc = true;
+diff --git a/drivers/gpu/drm/radeon/si_dpm.c b/drivers/gpu/drm/radeon/si_dpm.c
+index c49934527a87..8b5e697f2549 100644
+--- a/drivers/gpu/drm/radeon/si_dpm.c
++++ b/drivers/gpu/drm/radeon/si_dpm.c
+@@ -3026,6 +3026,7 @@ static void si_apply_state_adjust_rules(struct radeon_device *rdev,
+ 		    (rdev->pdev->revision == 0x80) ||
+ 		    (rdev->pdev->revision == 0x81) ||
+ 		    (rdev->pdev->revision == 0x83) ||
++		    (rdev->pdev->revision == 0x87) ||
+ 		    (rdev->pdev->device == 0x6604) ||
+ 		    (rdev->pdev->device == 0x6605)) {
+ 			max_sclk = 75000;
+diff --git a/drivers/hv/channel_mgmt.c b/drivers/hv/channel_mgmt.c
+index b6c1211b4df7..04508526f1d5 100644
+--- a/drivers/hv/channel_mgmt.c
++++ b/drivers/hv/channel_mgmt.c
+@@ -348,6 +348,7 @@ void vmbus_free_channels(void)
+ {
+ 	struct vmbus_channel *channel, *tmp;
+ 
++	mutex_lock(&vmbus_connection.channel_mutex);
+ 	list_for_each_entry_safe(channel, tmp, &vmbus_connection.chn_list,
+ 		listentry) {
+ 		/* hv_process_channel_removal() needs this */
+@@ -355,6 +356,7 @@ void vmbus_free_channels(void)
+ 
+ 		vmbus_device_unregister(channel->device_obj);
+ 	}
++	mutex_unlock(&vmbus_connection.channel_mutex);
+ }
+ 
+ /*
+diff --git a/drivers/hwtracing/stm/core.c b/drivers/hwtracing/stm/core.c
+index 51f81d64ca37..a6ea387b5b00 100644
+--- a/drivers/hwtracing/stm/core.c
++++ b/drivers/hwtracing/stm/core.c
+@@ -361,7 +361,7 @@ static int stm_char_open(struct inode *inode, struct file *file)
+ 	struct stm_file *stmf;
+ 	struct device *dev;
+ 	unsigned int major = imajor(inode);
+-	int err = -ENODEV;
++	int err = -ENOMEM;
+ 
+ 	dev = class_find_device(&stm_class, NULL, &major, major_match);
+ 	if (!dev)
+@@ -369,8 +369,9 @@ static int stm_char_open(struct inode *inode, struct file *file)
+ 
+ 	stmf = kzalloc(sizeof(*stmf), GFP_KERNEL);
+ 	if (!stmf)
+-		return -ENOMEM;
++		goto err_put_device;
+ 
++	err = -ENODEV;
+ 	stm_output_init(&stmf->output);
+ 	stmf->stm = to_stm_device(dev);
+ 
+@@ -382,9 +383,10 @@ static int stm_char_open(struct inode *inode, struct file *file)
+ 	return nonseekable_open(inode, file);
+ 
+ err_free:
++	kfree(stmf);
++err_put_device:
+ 	/* matches class_find_device() above */
+ 	put_device(dev);
+-	kfree(stmf);
+ 
+ 	return err;
+ }
+diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
+index 2d49228f28b2..85b2bfedd6be 100644
+--- a/drivers/infiniband/core/mad.c
++++ b/drivers/infiniband/core/mad.c
+@@ -1746,7 +1746,7 @@ find_mad_agent(struct ib_mad_port_private *port_priv,
+ 			if (!class)
+ 				goto out;
+ 			if (convert_mgmt_class(mad_hdr->mgmt_class) >=
+-			    IB_MGMT_MAX_METHODS)
++			    ARRAY_SIZE(class->method_table))
+ 				goto out;
+ 			method = class->method_table[convert_mgmt_class(
+ 							mad_hdr->mgmt_class)];
+diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
+index 51c79b2fb0b8..45523cf1b83b 100644
+--- a/drivers/infiniband/core/multicast.c
++++ b/drivers/infiniband/core/multicast.c
+@@ -518,8 +518,11 @@ static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
+ 		process_join_error(group, status);
+ 	else {
+ 		int mgids_changed, is_mgid0;
+-		ib_find_pkey(group->port->dev->device, group->port->port_num,
+-			     be16_to_cpu(rec->pkey), &pkey_index);
++
++		if (ib_find_pkey(group->port->dev->device,
++				 group->port->port_num, be16_to_cpu(rec->pkey),
++				 &pkey_index))
++			pkey_index = MCAST_INVALID_PKEY_INDEX;
+ 
+ 		spin_lock_irq(&group->port->lock);
+ 		if (group->state == MCAST_BUSY &&
+diff --git a/drivers/infiniband/hw/i40iw/i40iw_verbs.c b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+index 6329c971c22f..4b892ca2b13a 100644
+--- a/drivers/infiniband/hw/i40iw/i40iw_verbs.c
++++ b/drivers/infiniband/hw/i40iw/i40iw_verbs.c
+@@ -2501,7 +2501,7 @@ static int i40iw_get_hw_stats(struct ib_device *ibdev,
+ 			return -ENOSYS;
+ 	}
+ 
+-	memcpy(&stats->value[0], &hw_stats, sizeof(*hw_stats));
++	memcpy(&stats->value[0], hw_stats, sizeof(*hw_stats));
+ 
+ 	return stats->num_counters;
+ }
+diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c
+index f724a7ef9b67..979e445186cf 100644
+--- a/drivers/infiniband/sw/rxe/rxe_qp.c
++++ b/drivers/infiniband/sw/rxe/rxe_qp.c
+@@ -850,4 +850,5 @@ void rxe_qp_cleanup(void *arg)
+ 	free_rd_atomic_resources(qp);
+ 
+ 	kernel_sock_shutdown(qp->sk, SHUT_RDWR);
++	sock_release(qp->sk);
+ }
+diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+index 1909dd252c94..fddff403d5d2 100644
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -575,8 +575,11 @@ void ipoib_mcast_join_task(struct work_struct *work)
+ 	if (!test_bit(IPOIB_FLAG_OPER_UP, &priv->flags))
+ 		return;
+ 
+-	if (ib_query_port(priv->ca, priv->port, &port_attr) ||
+-	    port_attr.state != IB_PORT_ACTIVE) {
++	if (ib_query_port(priv->ca, priv->port, &port_attr)) {
++		ipoib_dbg(priv, "ib_query_port() failed\n");
++		return;
++	}
++	if (port_attr.state != IB_PORT_ACTIVE) {
+ 		ipoib_dbg(priv, "port state is not ACTIVE (state = %d) suspending join task\n",
+ 			  port_attr.state);
+ 		return;
+diff --git a/drivers/input/misc/drv260x.c b/drivers/input/misc/drv260x.c
+index 2adfd86c869a..930424e55439 100644
+--- a/drivers/input/misc/drv260x.c
++++ b/drivers/input/misc/drv260x.c
+@@ -592,7 +592,6 @@ static int drv260x_probe(struct i2c_client *client,
+ 	}
+ 
+ 	haptics->input_dev->name = "drv260x:haptics";
+-	haptics->input_dev->dev.parent = client->dev.parent;
+ 	haptics->input_dev->close = drv260x_close;
+ 	input_set_drvdata(haptics->input_dev, haptics);
+ 	input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
+index ee7fc3701700..a87549be8e53 100644
+--- a/drivers/md/raid5.c
++++ b/drivers/md/raid5.c
+@@ -7017,6 +7017,15 @@ static int raid5_run(struct mddev *mddev)
+ 			stripe = (stripe | (stripe-1)) + 1;
+ 		mddev->queue->limits.discard_alignment = stripe;
+ 		mddev->queue->limits.discard_granularity = stripe;
++
++		/*
++		 * We use 16-bit counter of active stripes in bi_phys_segments
++		 * (minus one for over-loaded initialization)
++		 */
++		blk_queue_max_hw_sectors(mddev->queue, 0xfffe * STRIPE_SECTORS);
++		blk_queue_max_discard_sectors(mddev->queue,
++					      0xfffe * STRIPE_SECTORS);
++
+ 		/*
+ 		 * unaligned part of discard request will be ignored, so can't
+ 		 * guarantee discard_zeroes_data
+diff --git a/drivers/media/dvb-frontends/mn88472.c b/drivers/media/dvb-frontends/mn88472.c
+index 18fb2df1e2bd..72650116732c 100644
+--- a/drivers/media/dvb-frontends/mn88472.c
++++ b/drivers/media/dvb-frontends/mn88472.c
+@@ -488,18 +488,6 @@ static int mn88472_probe(struct i2c_client *client,
+ 		goto err_kfree;
+ 	}
+ 
+-	/* Check demod answers with correct chip id */
+-	ret = regmap_read(dev->regmap[0], 0xff, &utmp);
+-	if (ret)
+-		goto err_regmap_0_regmap_exit;
+-
+-	dev_dbg(&client->dev, "chip id=%02x\n", utmp);
+-
+-	if (utmp != 0x02) {
+-		ret = -ENODEV;
+-		goto err_regmap_0_regmap_exit;
+-	}
+-
+ 	/*
+ 	 * Chip has three I2C addresses for different register banks. Used
+ 	 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
+@@ -536,6 +524,18 @@ static int mn88472_probe(struct i2c_client *client,
+ 	}
+ 	i2c_set_clientdata(dev->client[2], dev);
+ 
++	/* Check demod answers with correct chip id */
++	ret = regmap_read(dev->regmap[2], 0xff, &utmp);
++	if (ret)
++		goto err_regmap_2_regmap_exit;
++
++	dev_dbg(&client->dev, "chip id=%02x\n", utmp);
++
++	if (utmp != 0x02) {
++		ret = -ENODEV;
++		goto err_regmap_2_regmap_exit;
++	}
++
+ 	/* Sleep because chip is active by default */
+ 	ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
+ 	if (ret)
+diff --git a/drivers/media/dvb-frontends/mn88473.c b/drivers/media/dvb-frontends/mn88473.c
+index 451974a1d7ed..2932bdc8fa94 100644
+--- a/drivers/media/dvb-frontends/mn88473.c
++++ b/drivers/media/dvb-frontends/mn88473.c
+@@ -485,18 +485,6 @@ static int mn88473_probe(struct i2c_client *client,
+ 		goto err_kfree;
+ 	}
+ 
+-	/* Check demod answers with correct chip id */
+-	ret = regmap_read(dev->regmap[0], 0xff, &uitmp);
+-	if (ret)
+-		goto err_regmap_0_regmap_exit;
+-
+-	dev_dbg(&client->dev, "chip id=%02x\n", uitmp);
+-
+-	if (uitmp != 0x03) {
+-		ret = -ENODEV;
+-		goto err_regmap_0_regmap_exit;
+-	}
+-
+ 	/*
+ 	 * Chip has three I2C addresses for different register banks. Used
+ 	 * addresses are 0x18, 0x1a and 0x1c. We register two dummy clients,
+@@ -533,6 +521,18 @@ static int mn88473_probe(struct i2c_client *client,
+ 	}
+ 	i2c_set_clientdata(dev->client[2], dev);
+ 
++	/* Check demod answers with correct chip id */
++	ret = regmap_read(dev->regmap[2], 0xff, &uitmp);
++	if (ret)
++		goto err_regmap_2_regmap_exit;
++
++	dev_dbg(&client->dev, "chip id=%02x\n", uitmp);
++
++	if (uitmp != 0x03) {
++		ret = -ENODEV;
++		goto err_regmap_2_regmap_exit;
++	}
++
+ 	/* Sleep because chip is active by default */
+ 	ret = regmap_write(dev->regmap[2], 0x05, 0x3e);
+ 	if (ret)
+diff --git a/drivers/media/i2c/tvp5150.c b/drivers/media/i2c/tvp5150.c
+index 0b6d46c453bf..02a8f511443a 100644
+--- a/drivers/media/i2c/tvp5150.c
++++ b/drivers/media/i2c/tvp5150.c
+@@ -815,6 +815,7 @@ static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
+ 		return 0;
+ 	case V4L2_CID_HUE:
+ 		tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
++		break;
+ 	case V4L2_CID_TEST_PATTERN:
+ 		decoder->enable = ctrl->val ? false : true;
+ 		tvp5150_selmux(sd);
+diff --git a/drivers/media/pci/solo6x10/solo6x10.h b/drivers/media/pci/solo6x10/solo6x10.h
+index 5bd498735a66..3f8da5e8c430 100644
+--- a/drivers/media/pci/solo6x10/solo6x10.h
++++ b/drivers/media/pci/solo6x10/solo6x10.h
+@@ -284,7 +284,10 @@ static inline u32 solo_reg_read(struct solo_dev *solo_dev, int reg)
+ static inline void solo_reg_write(struct solo_dev *solo_dev, int reg,
+ 				  u32 data)
+ {
++	u16 val;
++
+ 	writel(data, solo_dev->reg_base + reg);
++	pci_read_config_word(solo_dev->pdev, PCI_STATUS, &val);
+ }
+ 
+ static inline void solo_irq_on(struct solo_dev *dev, u32 mask)
+diff --git a/drivers/media/platform/s5p-mfc/s5p_mfc.c b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+index e3f104fafd0a..9e88c2f65333 100644
+--- a/drivers/media/platform/s5p-mfc/s5p_mfc.c
++++ b/drivers/media/platform/s5p-mfc/s5p_mfc.c
+@@ -1073,6 +1073,7 @@ static struct device *s5p_mfc_alloc_memdev(struct device *dev,
+ 							 idx);
+ 		if (ret == 0)
+ 			return child;
++		device_del(child);
+ 	}
+ 
+ 	put_device(child);
+diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
+index 641c1a566687..75be3d5b2430 100644
+--- a/drivers/misc/mei/client.c
++++ b/drivers/misc/mei/client.c
+@@ -675,7 +675,7 @@ void mei_host_client_init(struct mei_device *dev)
+ 
+ 	pm_runtime_mark_last_busy(dev->dev);
+ 	dev_dbg(dev->dev, "rpm: autosuspend\n");
+-	pm_runtime_autosuspend(dev->dev);
++	pm_request_autosuspend(dev->dev);
+ }
+ 
+ /**
+diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
+index 7ad15d678878..c8307e8b4c16 100644
+--- a/drivers/misc/mei/hw-me-regs.h
++++ b/drivers/misc/mei/hw-me-regs.h
+@@ -122,6 +122,8 @@
+ #define MEI_DEV_ID_SPT_H      0xA13A  /* Sunrise Point H */
+ #define MEI_DEV_ID_SPT_H_2    0xA13B  /* Sunrise Point H 2 */
+ 
++#define MEI_DEV_ID_LBG        0xA1BA  /* Lewisburg (SPT) */
++
+ #define MEI_DEV_ID_BXT_M      0x1A9A  /* Broxton M */
+ #define MEI_DEV_ID_APL_I      0x5A9A  /* Apollo Lake I */
+ 
+diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
+index 5eb9b75ae9ec..69fca9b545df 100644
+--- a/drivers/misc/mei/pci-me.c
++++ b/drivers/misc/mei/pci-me.c
+@@ -87,6 +87,7 @@ static const struct pci_device_id mei_me_pci_tbl[] = {
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_2, mei_me_pch8_cfg)},
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H, mei_me_pch8_sps_cfg)},
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_SPT_H_2, mei_me_pch8_sps_cfg)},
++	{MEI_PCI_DEVICE(MEI_DEV_ID_LBG, mei_me_pch8_cfg)},
+ 
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_BXT_M, mei_me_pch8_cfg)},
+ 	{MEI_PCI_DEVICE(MEI_DEV_ID_APL_I, mei_me_pch8_cfg)},
+diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
+index 6eb8f0705c65..1f6205c959cd 100644
+--- a/drivers/mmc/host/sdhci.c
++++ b/drivers/mmc/host/sdhci.c
+@@ -2074,7 +2074,27 @@ static int sdhci_execute_tuning(struct mmc_host *mmc, u32 opcode)
+ 			ctrl &= ~SDHCI_CTRL_EXEC_TUNING;
+ 			sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
+ 
++			sdhci_do_reset(host, SDHCI_RESET_CMD);
++			sdhci_do_reset(host, SDHCI_RESET_DATA);
++
+ 			err = -EIO;
++
++			if (cmd.opcode != MMC_SEND_TUNING_BLOCK_HS200)
++				goto out;
++
++			sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
++			sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
++
++			spin_unlock_irqrestore(&host->lock, flags);
++
++			memset(&cmd, 0, sizeof(cmd));
++			cmd.opcode = MMC_STOP_TRANSMISSION;
++			cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
++			cmd.busy_timeout = 50;
++			mmc_wait_for_cmd(mmc, &cmd, 0);
++
++			spin_lock_irqsave(&host->lock, flags);
++
+ 			goto out;
+ 		}
+ 
+diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c
+index 60227a3452a4..5588c560ec61 100644
+--- a/drivers/net/ethernet/marvell/mvpp2.c
++++ b/drivers/net/ethernet/marvell/mvpp2.c
+@@ -770,6 +770,17 @@ struct mvpp2_rx_desc {
+ 	u32 reserved8;
+ };
+ 
++struct mvpp2_txq_pcpu_buf {
++	/* Transmitted SKB */
++	struct sk_buff *skb;
++
++	/* Physical address of transmitted buffer */
++	dma_addr_t phys;
++
++	/* Size transmitted */
++	size_t size;
++};
++
+ /* Per-CPU Tx queue control */
+ struct mvpp2_txq_pcpu {
+ 	int cpu;
+@@ -785,11 +796,8 @@ struct mvpp2_txq_pcpu {
+ 	/* Number of Tx DMA descriptors reserved for each CPU */
+ 	int reserved_num;
+ 
+-	/* Array of transmitted skb */
+-	struct sk_buff **tx_skb;
+-
+-	/* Array of transmitted buffers' physical addresses */
+-	dma_addr_t *tx_buffs;
++	/* Infos about transmitted buffers */
++	struct mvpp2_txq_pcpu_buf *buffs;
+ 
+ 	/* Index of last TX DMA descriptor that was inserted */
+ 	int txq_put_index;
+@@ -979,10 +987,11 @@ static void mvpp2_txq_inc_put(struct mvpp2_txq_pcpu *txq_pcpu,
+ 			      struct sk_buff *skb,
+ 			      struct mvpp2_tx_desc *tx_desc)
+ {
+-	txq_pcpu->tx_skb[txq_pcpu->txq_put_index] = skb;
+-	if (skb)
+-		txq_pcpu->tx_buffs[txq_pcpu->txq_put_index] =
+-							 tx_desc->buf_phys_addr;
++	struct mvpp2_txq_pcpu_buf *tx_buf =
++		txq_pcpu->buffs + txq_pcpu->txq_put_index;
++	tx_buf->skb = skb;
++	tx_buf->size = tx_desc->data_size;
++	tx_buf->phys = tx_desc->buf_phys_addr;
+ 	txq_pcpu->txq_put_index++;
+ 	if (txq_pcpu->txq_put_index == txq_pcpu->size)
+ 		txq_pcpu->txq_put_index = 0;
+@@ -4401,17 +4410,16 @@ static void mvpp2_txq_bufs_free(struct mvpp2_port *port,
+ 	int i;
+ 
+ 	for (i = 0; i < num; i++) {
+-		dma_addr_t buf_phys_addr =
+-				    txq_pcpu->tx_buffs[txq_pcpu->txq_get_index];
+-		struct sk_buff *skb = txq_pcpu->tx_skb[txq_pcpu->txq_get_index];
++		struct mvpp2_txq_pcpu_buf *tx_buf =
++			txq_pcpu->buffs + txq_pcpu->txq_get_index;
+ 
+ 		mvpp2_txq_inc_get(txq_pcpu);
+ 
+-		dma_unmap_single(port->dev->dev.parent, buf_phys_addr,
+-				 skb_headlen(skb), DMA_TO_DEVICE);
+-		if (!skb)
++		dma_unmap_single(port->dev->dev.parent, tx_buf->phys,
++				 tx_buf->size, DMA_TO_DEVICE);
++		if (!tx_buf->skb)
+ 			continue;
+-		dev_kfree_skb_any(skb);
++		dev_kfree_skb_any(tx_buf->skb);
+ 	}
+ }
+ 
+@@ -4651,15 +4659,10 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
+ 	for_each_present_cpu(cpu) {
+ 		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+ 		txq_pcpu->size = txq->size;
+-		txq_pcpu->tx_skb = kmalloc(txq_pcpu->size *
+-					   sizeof(*txq_pcpu->tx_skb),
+-					   GFP_KERNEL);
+-		if (!txq_pcpu->tx_skb)
+-			goto error;
+-
+-		txq_pcpu->tx_buffs = kmalloc(txq_pcpu->size *
+-					     sizeof(dma_addr_t), GFP_KERNEL);
+-		if (!txq_pcpu->tx_buffs)
++		txq_pcpu->buffs = kmalloc(txq_pcpu->size *
++					  sizeof(struct mvpp2_txq_pcpu_buf),
++					  GFP_KERNEL);
++		if (!txq_pcpu->buffs)
+ 			goto error;
+ 
+ 		txq_pcpu->count = 0;
+@@ -4673,8 +4676,7 @@ static int mvpp2_txq_init(struct mvpp2_port *port,
+ error:
+ 	for_each_present_cpu(cpu) {
+ 		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+-		kfree(txq_pcpu->tx_skb);
+-		kfree(txq_pcpu->tx_buffs);
++		kfree(txq_pcpu->buffs);
+ 	}
+ 
+ 	dma_free_coherent(port->dev->dev.parent,
+@@ -4693,8 +4695,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port,
+ 
+ 	for_each_present_cpu(cpu) {
+ 		txq_pcpu = per_cpu_ptr(txq->pcpu, cpu);
+-		kfree(txq_pcpu->tx_skb);
+-		kfree(txq_pcpu->tx_buffs);
++		kfree(txq_pcpu->buffs);
+ 	}
+ 
+ 	if (txq->descs)
+diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
+index 14b13f07cd1f..a35f78be8dec 100644
+--- a/drivers/net/wireless/ath/ath9k/hw.c
++++ b/drivers/net/wireless/ath/ath9k/hw.c
+@@ -2792,7 +2792,7 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio)
+ 		WARN_ON(1);
+ 	}
+ 
+-	return val;
++	return !!val;
+ }
+ EXPORT_SYMBOL(ath9k_hw_gpio_get);
+ 
+diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
+index 0dd454acf22a..aff473dfa10d 100644
+--- a/drivers/net/wireless/ath/ath9k/pci.c
++++ b/drivers/net/wireless/ath/ath9k/pci.c
+@@ -26,7 +26,6 @@ static const struct pci_device_id ath_pci_id_table[] = {
+ 	{ PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI   */
+ 	{ PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
+ 	{ PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI   */
+-	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+ 
+ #ifdef CONFIG_ATH9K_PCOEM
+ 	/* Mini PCI AR9220 MB92 cards: Compex WLM200NX, Wistron DNMA-92 */
+@@ -37,7 +36,7 @@ static const struct pci_device_id ath_pci_id_table[] = {
+ 	  .driver_data = ATH9K_PCI_LED_ACT_HI },
+ #endif
+ 
+-	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
++	{ PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI   */
+ 
+ #ifdef CONFIG_ATH9K_PCOEM
+ 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+@@ -85,7 +84,11 @@ static const struct pci_device_id ath_pci_id_table[] = {
+ 			 0x10CF, /* Fujitsu */
+ 			 0x1536),
+ 	  .driver_data = ATH9K_PCI_D3_L1_WAR },
++#endif
+ 
++	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
++
++#ifdef CONFIG_ATH9K_PCOEM
+ 	/* AR9285 card for Asus */
+ 	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
+ 			 0x002B,
+diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+index c6b246aa2419..4b7807902700 100644
+--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
++++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
+@@ -4401,6 +4401,13 @@ void rtl8xxxu_gen1_report_connect(struct rtl8xxxu_priv *priv,
+ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
+ 				  u8 macid, bool connect)
+ {
++#ifdef RTL8XXXU_GEN2_REPORT_CONNECT
++	/*
++	 * Barry Day reports this causes issues with 8192eu and 8723bu
++	 * devices reconnecting. The reason for this is unclear, but
++	 * until it is better understood, leave the code in place but
++	 * disabled, so it is not lost.
++	 */
+ 	struct h2c_cmd h2c;
+ 
+ 	memset(&h2c, 0, sizeof(struct h2c_cmd));
+@@ -4412,6 +4419,7 @@ void rtl8xxxu_gen2_report_connect(struct rtl8xxxu_priv *priv,
+ 		h2c.media_status_rpt.parm &= ~BIT(0);
+ 
+ 	rtl8xxxu_gen2_h2c_cmd(priv, &h2c, sizeof(h2c.media_status_rpt));
++#endif
+ }
+ 
+ void rtl8xxxu_gen1_init_aggregation(struct rtl8xxxu_priv *priv)
+diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
+index 264466f59c57..4ac928bf1f8e 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/base.c
++++ b/drivers/net/wireless/realtek/rtlwifi/base.c
+@@ -1303,12 +1303,13 @@ EXPORT_SYMBOL_GPL(rtl_action_proc);
+ 
+ static void setup_arp_tx(struct rtl_priv *rtlpriv, struct rtl_ps_ctl *ppsc)
+ {
++	struct ieee80211_hw *hw = rtlpriv->hw;
++
+ 	rtlpriv->ra.is_special_data = true;
+ 	if (rtlpriv->cfg->ops->get_btc_status())
+ 		rtlpriv->btcoexist.btc_ops->btc_special_packet_notify(
+ 					rtlpriv, 1);
+-	rtlpriv->enter_ps = false;
+-	schedule_work(&rtlpriv->works.lps_change_work);
++	rtl_lps_leave(hw);
+ 	ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+ 
+@@ -1381,8 +1382,7 @@ u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx,
+ 
+ 		if (is_tx) {
+ 			rtlpriv->ra.is_special_data = true;
+-			rtlpriv->enter_ps = false;
+-			schedule_work(&rtlpriv->works.lps_change_work);
++			rtl_lps_leave(hw);
+ 			ppsc->last_delaylps_stamp_jiffies = jiffies;
+ 		}
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
+index 41f77f8a309e..8f783efac960 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/core.c
++++ b/drivers/net/wireless/realtek/rtlwifi/core.c
+@@ -1149,10 +1149,8 @@ static void rtl_op_bss_info_changed(struct ieee80211_hw *hw,
+ 		} else {
+ 			mstatus = RT_MEDIA_DISCONNECT;
+ 
+-			if (mac->link_state == MAC80211_LINKED) {
+-				rtlpriv->enter_ps = false;
+-				schedule_work(&rtlpriv->works.lps_change_work);
+-			}
++			if (mac->link_state == MAC80211_LINKED)
++				rtl_lps_leave(hw);
+ 			if (ppsc->p2p_ps_info.p2p_ps_mode > P2P_PS_NONE)
+ 				rtl_p2p_ps_cmd(hw, P2P_PS_DISABLE);
+ 			mac->link_state = MAC80211_NOLINK;
+@@ -1430,8 +1428,7 @@ static void rtl_op_sw_scan_start(struct ieee80211_hw *hw,
+ 	}
+ 
+ 	if (mac->link_state == MAC80211_LINKED) {
+-		rtlpriv->enter_ps = false;
+-		schedule_work(&rtlpriv->works.lps_change_work);
++		rtl_lps_leave(hw);
+ 		mac->link_state = MAC80211_LINKED_SCANNING;
+ 	} else {
+ 		rtl_ips_nic_on(hw);
+diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
+index d12586d4f845..e538e23baa9f 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
+@@ -662,11 +662,9 @@ tx_status_ok:
+ 	}
+ 
+ 	if (((rtlpriv->link_info.num_rx_inperiod +
+-		rtlpriv->link_info.num_tx_inperiod) > 8) ||
+-		(rtlpriv->link_info.num_rx_inperiod > 2)) {
+-		rtlpriv->enter_ps = false;
+-		schedule_work(&rtlpriv->works.lps_change_work);
+-	}
++	      rtlpriv->link_info.num_tx_inperiod) > 8) ||
++	      (rtlpriv->link_info.num_rx_inperiod > 2))
++		rtl_lps_leave(hw);
+ }
+ 
+ static int _rtl_pci_init_one_rxdesc(struct ieee80211_hw *hw,
+@@ -917,10 +915,8 @@ new_trx_end:
+ 		}
+ 		if (((rtlpriv->link_info.num_rx_inperiod +
+ 		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
+-		      (rtlpriv->link_info.num_rx_inperiod > 2)) {
+-			rtlpriv->enter_ps = false;
+-			schedule_work(&rtlpriv->works.lps_change_work);
+-		}
++		      (rtlpriv->link_info.num_rx_inperiod > 2))
++			rtl_lps_leave(hw);
+ 		skb = new_skb;
+ no_new:
+ 		if (rtlpriv->use_new_trx_flow) {
+diff --git a/drivers/net/wireless/realtek/rtlwifi/ps.c b/drivers/net/wireless/realtek/rtlwifi/ps.c
+index 9a64f9b703e5..424e262939c9 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/ps.c
++++ b/drivers/net/wireless/realtek/rtlwifi/ps.c
+@@ -407,8 +407,8 @@ void rtl_lps_set_psmode(struct ieee80211_hw *hw, u8 rt_psmode)
+ 	}
+ }
+ 
+-/*Enter the leisure power save mode.*/
+-void rtl_lps_enter(struct ieee80211_hw *hw)
++/* Interrupt safe routine to enter the leisure power save mode.*/
++static void rtl_lps_enter_core(struct ieee80211_hw *hw)
+ {
+ 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+@@ -444,10 +444,9 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
+ 
+ 	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+ }
+-EXPORT_SYMBOL(rtl_lps_enter);
+ 
+-/*Leave the leisure power save mode.*/
+-void rtl_lps_leave(struct ieee80211_hw *hw)
++/* Interrupt safe routine to leave the leisure power save mode.*/
++static void rtl_lps_leave_core(struct ieee80211_hw *hw)
+ {
+ 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+ 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+@@ -477,7 +476,6 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
+ 	}
+ 	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flag);
+ }
+-EXPORT_SYMBOL(rtl_lps_leave);
+ 
+ /* For sw LPS*/
+ void rtl_swlps_beacon(struct ieee80211_hw *hw, void *data, unsigned int len)
+@@ -670,12 +668,34 @@ void rtl_lps_change_work_callback(struct work_struct *work)
+ 	struct rtl_priv *rtlpriv = rtl_priv(hw);
+ 
+ 	if (rtlpriv->enter_ps)
+-		rtl_lps_enter(hw);
++		rtl_lps_enter_core(hw);
+ 	else
+-		rtl_lps_leave(hw);
++		rtl_lps_leave_core(hw);
+ }
+ EXPORT_SYMBOL_GPL(rtl_lps_change_work_callback);
+ 
++void rtl_lps_enter(struct ieee80211_hw *hw)
++{
++	struct rtl_priv *rtlpriv = rtl_priv(hw);
++
++	if (!in_interrupt())
++		return rtl_lps_enter_core(hw);
++	rtlpriv->enter_ps = true;
++	schedule_work(&rtlpriv->works.lps_change_work);
++}
++EXPORT_SYMBOL_GPL(rtl_lps_enter);
++
++void rtl_lps_leave(struct ieee80211_hw *hw)
++{
++	struct rtl_priv *rtlpriv = rtl_priv(hw);
++
++	if (!in_interrupt())
++		return rtl_lps_leave_core(hw);
++	rtlpriv->enter_ps = false;
++	schedule_work(&rtlpriv->works.lps_change_work);
++}
++EXPORT_SYMBOL_GPL(rtl_lps_leave);
++
+ void rtl_swlps_wq_callback(void *data)
+ {
+ 	struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
+index cea8350fbc7e..a2ac9e641aa9 100644
+--- a/drivers/nvdimm/pfn_devs.c
++++ b/drivers/nvdimm/pfn_devs.c
+@@ -108,7 +108,7 @@ static ssize_t align_show(struct device *dev,
+ {
+ 	struct nd_pfn *nd_pfn = to_nd_pfn_safe(dev);
+ 
+-	return sprintf(buf, "%lx\n", nd_pfn->align);
++	return sprintf(buf, "%ld\n", nd_pfn->align);
+ }
+ 
+ static ssize_t __align_store(struct nd_pfn *nd_pfn, const char *buf)
+diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
+index aab9d5115a5f..24db77ea5093 100644
+--- a/drivers/pci/pci.c
++++ b/drivers/pci/pci.c
+@@ -2064,6 +2064,10 @@ bool pci_dev_run_wake(struct pci_dev *dev)
+ 	if (!dev->pme_support)
+ 		return false;
+ 
++	/* PME-capable in principle, but not from the intended sleep state */
++	if (!pci_pme_capable(dev, pci_target_state(dev)))
++		return false;
++
+ 	while (bus->parent) {
+ 		struct pci_dev *bridge = bus->self;
+ 
+diff --git a/drivers/platform/x86/asus-nb-wmi.c b/drivers/platform/x86/asus-nb-wmi.c
+index adecc1c555f0..c4ed3e53c0ea 100644
+--- a/drivers/platform/x86/asus-nb-wmi.c
++++ b/drivers/platform/x86/asus-nb-wmi.c
+@@ -137,6 +137,15 @@ static const struct dmi_system_id asus_quirks[] = {
+ 	},
+ 	{
+ 		.callback = dmi_matched,
++		.ident = "ASUSTeK COMPUTER INC. X45U",
++		.matches = {
++			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
++			DMI_MATCH(DMI_PRODUCT_NAME, "X45U"),
++		},
++		.driver_data = &quirk_asus_wapf4,
++	},
++	{
++		.callback = dmi_matched,
+ 		.ident = "ASUSTeK COMPUTER INC. X456UA",
+ 		.matches = {
+ 			DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+diff --git a/drivers/regulator/stw481x-vmmc.c b/drivers/regulator/stw481x-vmmc.c
+index 7d2ae3e9e942..342f5da79975 100644
+--- a/drivers/regulator/stw481x-vmmc.c
++++ b/drivers/regulator/stw481x-vmmc.c
+@@ -47,7 +47,8 @@ static struct regulator_desc vmmc_regulator = {
+ 	.volt_table = stw481x_vmmc_voltages,
+ 	.enable_time = 200, /* FIXME: look this up */
+ 	.enable_reg = STW_CONF1,
+-	.enable_mask = STW_CONF1_PDN_VMMC,
++	.enable_mask = STW_CONF1_PDN_VMMC | STW_CONF1_MMC_LS_STATUS,
++	.enable_val = STW_CONF1_PDN_VMMC,
+ 	.vsel_reg = STW_CONF1,
+ 	.vsel_mask = STW_CONF1_VMMC_MASK,
+ };
+diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
+index e883063c7258..3167e8581994 100644
+--- a/drivers/s390/char/vmlogrdr.c
++++ b/drivers/s390/char/vmlogrdr.c
+@@ -870,7 +870,7 @@ static int __init vmlogrdr_init(void)
+ 		goto cleanup;
+ 
+ 	for (i=0; i < MAXMINOR; ++i ) {
+-		sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL);
++		sys_ser[i].buffer = (char *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
+ 		if (!sys_ser[i].buffer) {
+ 			rc = -ENOMEM;
+ 			break;
+diff --git a/drivers/s390/scsi/zfcp_dbf.c b/drivers/s390/scsi/zfcp_dbf.c
+index 581001989937..d5bf36ec8a75 100644
+--- a/drivers/s390/scsi/zfcp_dbf.c
++++ b/drivers/s390/scsi/zfcp_dbf.c
+@@ -289,11 +289,12 @@ void zfcp_dbf_rec_trig(char *tag, struct zfcp_adapter *adapter,
+ 
+ 
+ /**
+- * zfcp_dbf_rec_run - trace event related to running recovery
++ * zfcp_dbf_rec_run_lvl - trace event related to running recovery
++ * @level: trace level to be used for event
+  * @tag: identifier for event
+  * @erp: erp_action running
+  */
+-void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
++void zfcp_dbf_rec_run_lvl(int level, char *tag, struct zfcp_erp_action *erp)
+ {
+ 	struct zfcp_dbf *dbf = erp->adapter->dbf;
+ 	struct zfcp_dbf_rec *rec = &dbf->rec_buf;
+@@ -319,11 +320,21 @@ void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
+ 	else
+ 		rec->u.run.rec_count = atomic_read(&erp->adapter->erp_counter);
+ 
+-	debug_event(dbf->rec, 1, rec, sizeof(*rec));
++	debug_event(dbf->rec, level, rec, sizeof(*rec));
+ 	spin_unlock_irqrestore(&dbf->rec_lock, flags);
+ }
+ 
+ /**
++ * zfcp_dbf_rec_run - trace event related to running recovery
++ * @tag: identifier for event
++ * @erp: erp_action running
++ */
++void zfcp_dbf_rec_run(char *tag, struct zfcp_erp_action *erp)
++{
++	zfcp_dbf_rec_run_lvl(1, tag, erp);
++}
++
++/**
+  * zfcp_dbf_rec_run_wka - trace wka port event with info like running recovery
+  * @tag: identifier for event
+  * @wka_port: well known address port
+diff --git a/drivers/s390/scsi/zfcp_dbf.h b/drivers/s390/scsi/zfcp_dbf.h
+index 36d07584271d..db186d44cfaf 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, 2015
++ * Copyright IBM Corp. 2008, 2016
+  */
+ 
+ #ifndef ZFCP_DBF_H
+@@ -283,6 +283,30 @@ struct zfcp_dbf {
+ 	struct zfcp_dbf_scsi		scsi_buf;
+ };
+ 
++/**
++ * zfcp_dbf_hba_fsf_resp_suppress - true if we should not trace by default
++ * @req: request that has been completed
++ *
++ * Returns true if FCP response with only benign residual under count.
++ */
++static inline
++bool zfcp_dbf_hba_fsf_resp_suppress(struct zfcp_fsf_req *req)
++{
++	struct fsf_qtcb *qtcb = req->qtcb;
++	u32 fsf_stat = qtcb->header.fsf_status;
++	struct fcp_resp *fcp_rsp;
++	u8 rsp_flags, fr_status;
++
++	if (qtcb->prefix.qtcb_type != FSF_IO_COMMAND)
++		return false; /* not an FCP response */
++	fcp_rsp = (struct fcp_resp *)&qtcb->bottom.io.fcp_rsp;
++	rsp_flags = fcp_rsp->fr_flags;
++	fr_status = fcp_rsp->fr_status;
++	return (fsf_stat == FSF_FCP_RSP_AVAILABLE) &&
++		(rsp_flags == FCP_RESID_UNDER) &&
++		(fr_status == SAM_STAT_GOOD);
++}
++
+ static inline
+ void zfcp_dbf_hba_fsf_resp(char *tag, int level, struct zfcp_fsf_req *req)
+ {
+@@ -304,7 +328,9 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
+ 		zfcp_dbf_hba_fsf_resp("fs_perr", 1, req);
+ 
+ 	} else if (qtcb->header.fsf_status != FSF_GOOD) {
+-		zfcp_dbf_hba_fsf_resp("fs_ferr", 1, req);
++		zfcp_dbf_hba_fsf_resp("fs_ferr",
++				      zfcp_dbf_hba_fsf_resp_suppress(req)
++				      ? 5 : 1, req);
+ 
+ 	} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
+ 		   (req->fsf_command == FSF_QTCB_OPEN_LUN)) {
+@@ -388,4 +414,15 @@ void zfcp_dbf_scsi_devreset(char *tag, struct scsi_cmnd *scmnd, u8 flag)
+ 	_zfcp_dbf_scsi(tmp_tag, 1, scmnd, NULL);
+ }
+ 
++/**
++ * zfcp_dbf_scsi_nullcmnd() - trace NULLify of SCSI command in dev/tgt-reset.
++ * @scmnd: SCSI command that was NULLified.
++ * @fsf_req: request that owned @scmnd.
++ */
++static inline void zfcp_dbf_scsi_nullcmnd(struct scsi_cmnd *scmnd,
++					  struct zfcp_fsf_req *fsf_req)
++{
++	_zfcp_dbf_scsi("scfc__1", 3, scmnd, fsf_req);
++}
++
+ #endif /* ZFCP_DBF_H */
+diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c
+index a59d678125bd..7ccfce559034 100644
+--- a/drivers/s390/scsi/zfcp_erp.c
++++ b/drivers/s390/scsi/zfcp_erp.c
+@@ -3,7 +3,7 @@
+  *
+  * Error Recovery Procedures (ERP).
+  *
+- * Copyright IBM Corp. 2002, 2015
++ * Copyright IBM Corp. 2002, 2016
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -1204,6 +1204,62 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
+ 	}
+ }
+ 
++/**
++ * zfcp_erp_try_rport_unblock - unblock rport if no more/new recovery
++ * @port: zfcp_port whose fc_rport we should try to unblock
++ */
++static void zfcp_erp_try_rport_unblock(struct zfcp_port *port)
++{
++	unsigned long flags;
++	struct zfcp_adapter *adapter = port->adapter;
++	int port_status;
++	struct Scsi_Host *shost = adapter->scsi_host;
++	struct scsi_device *sdev;
++
++	write_lock_irqsave(&adapter->erp_lock, flags);
++	port_status = atomic_read(&port->status);
++	if ((port_status & ZFCP_STATUS_COMMON_UNBLOCKED)    == 0 ||
++	    (port_status & (ZFCP_STATUS_COMMON_ERP_INUSE |
++			    ZFCP_STATUS_COMMON_ERP_FAILED)) != 0) {
++		/* new ERP of severity >= port triggered elsewhere meanwhile or
++		 * local link down (adapter erp_failed but not clear unblock)
++		 */
++		zfcp_dbf_rec_run_lvl(4, "ertru_p", &port->erp_action);
++		write_unlock_irqrestore(&adapter->erp_lock, flags);
++		return;
++	}
++	spin_lock(shost->host_lock);
++	__shost_for_each_device(sdev, shost) {
++		struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev);
++		int lun_status;
++
++		if (zsdev->port != port)
++			continue;
++		/* LUN under port of interest */
++		lun_status = atomic_read(&zsdev->status);
++		if ((lun_status & ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
++			continue; /* unblock rport despite failed LUNs */
++		/* LUN recovery not given up yet [maybe follow-up pending] */
++		if ((lun_status & ZFCP_STATUS_COMMON_UNBLOCKED) == 0 ||
++		    (lun_status & ZFCP_STATUS_COMMON_ERP_INUSE) != 0) {
++			/* LUN blocked:
++			 * not yet unblocked [LUN recovery pending]
++			 * or meanwhile blocked [new LUN recovery triggered]
++			 */
++			zfcp_dbf_rec_run_lvl(4, "ertru_l", &zsdev->erp_action);
++			spin_unlock(shost->host_lock);
++			write_unlock_irqrestore(&adapter->erp_lock, flags);
++			return;
++		}
++	}
++	/* now port has no child or all children have completed recovery,
++	 * and no ERP of severity >= port was meanwhile triggered elsewhere
++	 */
++	zfcp_scsi_schedule_rport_register(port);
++	spin_unlock(shost->host_lock);
++	write_unlock_irqrestore(&adapter->erp_lock, flags);
++}
++
+ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
+ {
+ 	struct zfcp_adapter *adapter = act->adapter;
+@@ -1214,6 +1270,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
+ 	case ZFCP_ERP_ACTION_REOPEN_LUN:
+ 		if (!(act->status & ZFCP_STATUS_ERP_NO_REF))
+ 			scsi_device_put(sdev);
++		zfcp_erp_try_rport_unblock(port);
+ 		break;
+ 
+ 	case ZFCP_ERP_ACTION_REOPEN_PORT:
+@@ -1224,7 +1281,7 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
+ 		 */
+ 		if (act->step != ZFCP_ERP_STEP_UNINITIALIZED)
+ 			if (result == ZFCP_ERP_SUCCEEDED)
+-				zfcp_scsi_schedule_rport_register(port);
++				zfcp_erp_try_rport_unblock(port);
+ 		/* fall through */
+ 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
+ 		put_device(&port->dev);
+diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h
+index c8fed9fa1cca..21c8c689b02b 100644
+--- a/drivers/s390/scsi/zfcp_ext.h
++++ b/drivers/s390/scsi/zfcp_ext.h
+@@ -3,7 +3,7 @@
+  *
+  * External function declarations.
+  *
+- * Copyright IBM Corp. 2002, 2015
++ * Copyright IBM Corp. 2002, 2016
+  */
+ 
+ #ifndef ZFCP_EXT_H
+@@ -35,6 +35,8 @@ extern void zfcp_dbf_adapter_unregister(struct zfcp_adapter *);
+ extern void zfcp_dbf_rec_trig(char *, struct zfcp_adapter *,
+ 			      struct zfcp_port *, struct scsi_device *, u8, u8);
+ extern void zfcp_dbf_rec_run(char *, struct zfcp_erp_action *);
++extern void zfcp_dbf_rec_run_lvl(int level, char *tag,
++				 struct zfcp_erp_action *erp);
+ extern void zfcp_dbf_rec_run_wka(char *, struct zfcp_fc_wka_port *, u64);
+ extern void zfcp_dbf_hba_fsf_uss(char *, struct zfcp_fsf_req *);
+ extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
+diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
+index be1c04b334c5..ea3c76ac0de1 100644
+--- a/drivers/s390/scsi/zfcp_fsf.h
++++ b/drivers/s390/scsi/zfcp_fsf.h
+@@ -3,7 +3,7 @@
+  *
+  * Interface to the FSF support functions.
+  *
+- * Copyright IBM Corp. 2002, 2015
++ * Copyright IBM Corp. 2002, 2016
+  */
+ 
+ #ifndef FSF_H
+@@ -78,6 +78,7 @@
+ #define FSF_APP_TAG_CHECK_FAILURE		0x00000082
+ #define FSF_REF_TAG_CHECK_FAILURE		0x00000083
+ #define FSF_ADAPTER_STATUS_AVAILABLE		0x000000AD
++#define FSF_FCP_RSP_AVAILABLE			0x000000AF
+ #define FSF_UNKNOWN_COMMAND			0x000000E2
+ #define FSF_UNKNOWN_OP_SUBTYPE                  0x000000E3
+ #define FSF_INVALID_COMMAND_OPTION              0x000000E5
+diff --git a/drivers/s390/scsi/zfcp_reqlist.h b/drivers/s390/scsi/zfcp_reqlist.h
+index 7c2c6194dfca..703fce59befe 100644
+--- a/drivers/s390/scsi/zfcp_reqlist.h
++++ b/drivers/s390/scsi/zfcp_reqlist.h
+@@ -4,7 +4,7 @@
+  * Data structure and helper functions for tracking pending FSF
+  * requests.
+  *
+- * Copyright IBM Corp. 2009
++ * Copyright IBM Corp. 2009, 2016
+  */
+ 
+ #ifndef ZFCP_REQLIST_H
+@@ -180,4 +180,32 @@ static inline void zfcp_reqlist_move(struct zfcp_reqlist *rl,
+ 	spin_unlock_irqrestore(&rl->lock, flags);
+ }
+ 
++/**
++ * zfcp_reqlist_apply_for_all() - apply a function to every request.
++ * @rl: the requestlist that contains the target requests.
++ * @f: the function to apply to each request; the first parameter of the
++ *     function will be the target-request; the second parameter is the same
++ *     pointer as given with the argument @data.
++ * @data: freely chosen argument; passed through to @f as second parameter.
++ *
++ * Uses :c:macro:`list_for_each_entry` to iterate over the lists in the hash-
++ * table (not a 'safe' variant, so don't modify the list).
++ *
++ * Holds @rl->lock over the entire request-iteration.
++ */
++static inline void
++zfcp_reqlist_apply_for_all(struct zfcp_reqlist *rl,
++			   void (*f)(struct zfcp_fsf_req *, void *), void *data)
++{
++	struct zfcp_fsf_req *req;
++	unsigned long flags;
++	unsigned int i;
++
++	spin_lock_irqsave(&rl->lock, flags);
++	for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
++		list_for_each_entry(req, &rl->buckets[i], list)
++			f(req, data);
++	spin_unlock_irqrestore(&rl->lock, flags);
++}
++
+ #endif /* ZFCP_REQLIST_H */
+diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c
+index 9069f98a1817..07ffdbb5107f 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, 2015
++ * Copyright IBM Corp. 2002, 2016
+  */
+ 
+ #define KMSG_COMPONENT "zfcp"
+@@ -88,9 +88,7 @@ int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt)
+ 	}
+ 
+ 	if (unlikely(!(status & ZFCP_STATUS_COMMON_UNBLOCKED))) {
+-		/* This could be either
+-		 * open LUN pending: this is temporary, will result in
+-		 *	open LUN or ERP_FAILED, so retry command
++		/* This could be
+ 		 * call to rport_delete pending: mimic retry from
+ 		 * 	fc_remote_port_chkready until rport is BLOCKED
+ 		 */
+@@ -209,6 +207,57 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
+ 	return retval;
+ }
+ 
++struct zfcp_scsi_req_filter {
++	u8 tmf_scope;
++	u32 lun_handle;
++	u32 port_handle;
++};
++
++static void zfcp_scsi_forget_cmnd(struct zfcp_fsf_req *old_req, void *data)
++{
++	struct zfcp_scsi_req_filter *filter =
++		(struct zfcp_scsi_req_filter *)data;
++
++	/* already aborted - prevent side-effects - or not a SCSI command */
++	if (old_req->data == NULL || old_req->fsf_command != FSF_QTCB_FCP_CMND)
++		return;
++
++	/* (tmf_scope == FCP_TMF_TGT_RESET || tmf_scope == FCP_TMF_LUN_RESET) */
++	if (old_req->qtcb->header.port_handle != filter->port_handle)
++		return;
++
++	if (filter->tmf_scope == FCP_TMF_LUN_RESET &&
++	    old_req->qtcb->header.lun_handle != filter->lun_handle)
++		return;
++
++	zfcp_dbf_scsi_nullcmnd((struct scsi_cmnd *)old_req->data, old_req);
++	old_req->data = NULL;
++}
++
++static void zfcp_scsi_forget_cmnds(struct zfcp_scsi_dev *zsdev, u8 tm_flags)
++{
++	struct zfcp_adapter *adapter = zsdev->port->adapter;
++	struct zfcp_scsi_req_filter filter = {
++		.tmf_scope = FCP_TMF_TGT_RESET,
++		.port_handle = zsdev->port->handle,
++	};
++	unsigned long flags;
++
++	if (tm_flags == FCP_TMF_LUN_RESET) {
++		filter.tmf_scope = FCP_TMF_LUN_RESET;
++		filter.lun_handle = zsdev->lun_handle;
++	}
++
++	/*
++	 * abort_lock secures against other processings - in the abort-function
++	 * and normal cmnd-handler - of (struct zfcp_fsf_req *)->data
++	 */
++	write_lock_irqsave(&adapter->abort_lock, flags);
++	zfcp_reqlist_apply_for_all(adapter->req_list, zfcp_scsi_forget_cmnd,
++				   &filter);
++	write_unlock_irqrestore(&adapter->abort_lock, flags);
++}
++
+ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
+ {
+ 	struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device);
+@@ -241,8 +290,10 @@ static int zfcp_task_mgmt_function(struct scsi_cmnd *scpnt, u8 tm_flags)
+ 	if (fsf_req->status & ZFCP_STATUS_FSFREQ_TMFUNCFAILED) {
+ 		zfcp_dbf_scsi_devreset("fail", scpnt, tm_flags);
+ 		retval = FAILED;
+-	} else
++	} else {
+ 		zfcp_dbf_scsi_devreset("okay", scpnt, tm_flags);
++		zfcp_scsi_forget_cmnds(zfcp_sdev, tm_flags);
++	}
+ 
+ 	zfcp_fsf_req_free(fsf_req);
+ 	return retval;
+diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
+index 79871f3519ff..d5b26fa541d3 100644
+--- a/drivers/scsi/aacraid/linit.c
++++ b/drivers/scsi/aacraid/linit.c
+@@ -160,7 +160,6 @@ static const struct pci_device_id aac_pci_tbl[] = {
+ 	{ 0x9005, 0x028b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 62 }, /* Adaptec PMC Series 6 (Tupelo) */
+ 	{ 0x9005, 0x028c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 63 }, /* Adaptec PMC Series 7 (Denali) */
+ 	{ 0x9005, 0x028d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 64 }, /* Adaptec PMC Series 8 */
+-	{ 0x9005, 0x028f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 65 }, /* Adaptec PMC Series 9 */
+ 	{ 0,}
+ };
+ MODULE_DEVICE_TABLE(pci, aac_pci_tbl);
+@@ -239,7 +238,6 @@ static struct aac_driver_ident aac_drivers[] = {
+ 	{ aac_src_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 6 (Tupelo) */
+ 	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 7 (Denali) */
+ 	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC }, /* Adaptec PMC Series 8 */
+-	{ aac_srcv_init, "aacraid", "ADAPTEC ", "RAID            ", 2, AAC_QUIRK_SRC } /* Adaptec PMC Series 9 */
+ };
+ 
+ /**
+diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
+index 52d8bbf7feb5..bd04bd01d34a 100644
+--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
++++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
+@@ -2000,6 +2000,8 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
+ 		io_request->DevHandle = pd_sync->seq[pd_index].devHandle;
+ 		pRAID_Context->regLockFlags |=
+ 			(MR_RL_FLAGS_SEQ_NUM_ENABLE|MR_RL_FLAGS_GRANT_DESTINATION_CUDA);
++		pRAID_Context->Type = MPI2_TYPE_CUDA;
++		pRAID_Context->nseg = 0x1;
+ 	} else if (fusion->fast_path_io) {
+ 		pRAID_Context->VirtualDiskTgtId = cpu_to_le16(device_id);
+ 		pRAID_Context->configSeqNum = 0;
+@@ -2035,12 +2037,10 @@ megasas_build_syspd_fusion(struct megasas_instance *instance,
+ 		pRAID_Context->timeoutValue =
+ 			cpu_to_le16((os_timeout_value > timeout_limit) ?
+ 			timeout_limit : os_timeout_value);
+-		if (fusion->adapter_type == INVADER_SERIES) {
+-			pRAID_Context->Type = MPI2_TYPE_CUDA;
+-			pRAID_Context->nseg = 0x1;
++		if (fusion->adapter_type == INVADER_SERIES)
+ 			io_request->IoFlags |=
+ 				cpu_to_le16(MPI25_SAS_DEVICE0_FLAGS_ENABLED_FAST_PATH);
+-		}
++
+ 		cmd->request_desc->SCSIIO.RequestFlags =
+ 			(MPI2_REQ_DESCRIPT_FLAGS_FP_IO <<
+ 				MEGASAS_REQ_DESCRIPT_FLAGS_TYPE_SHIFT);
+@@ -2823,6 +2823,7 @@ int megasas_wait_for_outstanding_fusion(struct megasas_instance *instance,
+ 		dev_err(&instance->pdev->dev, "pending commands remain after waiting, "
+ 		       "will reset adapter scsi%d.\n",
+ 		       instance->host->host_no);
++		*convert = 1;
+ 		retval = 1;
+ 	}
+ out:
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 07349270535d..82dfe07b1d47 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -1204,10 +1204,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
+ 	struct request_queue *rq = sdev->request_queue;
+ 	struct scsi_target *starget = sdev->sdev_target;
+ 
+-	error = scsi_device_set_state(sdev, SDEV_RUNNING);
+-	if (error)
+-		return error;
+-
+ 	error = scsi_target_add(starget);
+ 	if (error)
+ 		return error;
+diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
+index ae7d9bdf409c..a1c29b0afb22 100644
+--- a/drivers/scsi/sg.c
++++ b/drivers/scsi/sg.c
+@@ -592,6 +592,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
+ 	sg_io_hdr_t *hp;
+ 	unsigned char cmnd[SG_MAX_CDB_SIZE];
+ 
++	if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
++		return -EINVAL;
++
+ 	if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp)))
+ 		return -ENXIO;
+ 	SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp,
+diff --git a/drivers/ssb/pci.c b/drivers/ssb/pci.c
+index 0f28c08fcb3c..77b551da5728 100644
+--- a/drivers/ssb/pci.c
++++ b/drivers/ssb/pci.c
+@@ -909,6 +909,7 @@ static int ssb_pci_sprom_get(struct ssb_bus *bus,
+ 			if (err) {
+ 				ssb_warn("WARNING: Using fallback SPROM failed (err %d)\n",
+ 					 err);
++				goto out_free;
+ 			} else {
+ 				ssb_dbg("Using SPROM revision %d provided by platform\n",
+ 					sprom->revision);
+diff --git a/drivers/staging/comedi/drivers/ni_mio_common.c b/drivers/staging/comedi/drivers/ni_mio_common.c
+index 0f97d7b611d7..1c967c30e4ce 100644
+--- a/drivers/staging/comedi/drivers/ni_mio_common.c
++++ b/drivers/staging/comedi/drivers/ni_mio_common.c
+@@ -1832,7 +1832,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
+ 			   unsigned int *data)
+ {
+ 	struct ni_private *devpriv = dev->private;
+-	unsigned int mask = (s->maxdata + 1) >> 1;
++	unsigned int mask = s->maxdata;
+ 	int i, n;
+ 	unsigned int signbits;
+ 	unsigned int d;
+@@ -1875,7 +1875,7 @@ static int ni_ai_insn_read(struct comedi_device *dev,
+ 				return -ETIME;
+ 			}
+ 			d += signbits;
+-			data[n] = d;
++			data[n] = d & 0xffff;
+ 		}
+ 	} else if (devpriv->is_6143) {
+ 		for (n = 0; n < insn->n; n++) {
+@@ -1924,9 +1924,8 @@ static int ni_ai_insn_read(struct comedi_device *dev,
+ 				data[n] = dl;
+ 			} else {
+ 				d = ni_readw(dev, NI_E_AI_FIFO_DATA_REG);
+-				/* subtle: needs to be short addition */
+ 				d += signbits;
+-				data[n] = d;
++				data[n] = d & 0xffff;
+ 			}
+ 		}
+ 	}
+diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
+index 923c032f0b95..e980e2d0c2db 100644
+--- a/drivers/target/iscsi/iscsi_target_configfs.c
++++ b/drivers/target/iscsi/iscsi_target_configfs.c
+@@ -100,8 +100,10 @@ static ssize_t lio_target_np_driver_store(struct config_item *item,
+ 
+ 		tpg_np_new = iscsit_tpg_add_network_portal(tpg,
+ 					&np->np_sockaddr, tpg_np, type);
+-		if (IS_ERR(tpg_np_new))
++		if (IS_ERR(tpg_np_new)) {
++			rc = PTR_ERR(tpg_np_new);
+ 			goto out;
++		}
+ 	} else {
+ 		tpg_np_new = iscsit_tpg_locate_child_np(tpg_np, type);
+ 		if (tpg_np_new) {
+diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
+index 62bf4fe5704a..b8a986c2c567 100644
+--- a/drivers/target/target_core_user.c
++++ b/drivers/target/target_core_user.c
+@@ -682,8 +682,6 @@ static int tcmu_check_expired_cmd(int id, void *p, void *data)
+ 	target_complete_cmd(cmd->se_cmd, SAM_STAT_CHECK_CONDITION);
+ 	cmd->se_cmd = NULL;
+ 
+-	kmem_cache_free(tcmu_cmd_cache, cmd);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c
+index c41c7742903a..2dcd4194d103 100644
+--- a/drivers/thermal/thermal_hwmon.c
++++ b/drivers/thermal/thermal_hwmon.c
+@@ -98,7 +98,7 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf)
+ 	int temperature;
+ 	int ret;
+ 
+-	ret = tz->ops->get_trip_temp(tz, 0, &temperature);
++	ret = tz->ops->get_crit_temp(tz, &temperature);
+ 	if (ret)
+ 		return ret;
+ 
+diff --git a/drivers/tty/serial/sc16is7xx.c b/drivers/tty/serial/sc16is7xx.c
+index f36e6df2fa90..e086ea4d2997 100644
+--- a/drivers/tty/serial/sc16is7xx.c
++++ b/drivers/tty/serial/sc16is7xx.c
+@@ -1240,7 +1240,7 @@ static int sc16is7xx_probe(struct device *dev,
+ 
+ 	/* Setup interrupt */
+ 	ret = devm_request_irq(dev, irq, sc16is7xx_irq,
+-			       IRQF_ONESHOT | flags, dev_name(dev), s);
++			       flags, dev_name(dev), s);
+ 	if (!ret)
+ 		return 0;
+ 
+diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
+index 0f8caae4267d..ece10e6b731b 100644
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -982,7 +982,7 @@ static void kbd_led_trigger_activate(struct led_classdev *cdev)
+ 	KBD_LED_TRIGGER((_led_bit) + 8, _name)
+ 
+ static struct kbd_led_trigger kbd_led_triggers[] = {
+-	KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrollock"),
++	KBD_LED_TRIGGER(VC_SCROLLOCK, "kbd-scrolllock"),
+ 	KBD_LED_TRIGGER(VC_NUMLOCK,   "kbd-numlock"),
+ 	KBD_LED_TRIGGER(VC_CAPSLOCK,  "kbd-capslock"),
+ 	KBD_LED_TRIGGER(VC_KANALOCK,  "kbd-kanalock"),
+diff --git a/fs/block_dev.c b/fs/block_dev.c
+index b010242bab32..496d99b80fb0 100644
+--- a/fs/block_dev.c
++++ b/fs/block_dev.c
+@@ -1885,6 +1885,7 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
+ 	spin_lock(&blockdev_superblock->s_inode_list_lock);
+ 	list_for_each_entry(inode, &blockdev_superblock->s_inodes, i_sb_list) {
+ 		struct address_space *mapping = inode->i_mapping;
++		struct block_device *bdev;
+ 
+ 		spin_lock(&inode->i_lock);
+ 		if (inode->i_state & (I_FREEING|I_WILL_FREE|I_NEW) ||
+@@ -1905,8 +1906,12 @@ void iterate_bdevs(void (*func)(struct block_device *, void *), void *arg)
+ 		 */
+ 		iput(old_inode);
+ 		old_inode = inode;
++		bdev = I_BDEV(inode);
+ 
+-		func(I_BDEV(inode), arg);
++		mutex_lock(&bdev->bd_mutex);
++		if (bdev->bd_openers)
++			func(bdev, arg);
++		mutex_unlock(&bdev->bd_mutex);
+ 
+ 		spin_lock(&blockdev_superblock->s_inode_list_lock);
+ 	}
+diff --git a/fs/nfs/file.c b/fs/nfs/file.c
+index ca699ddc11c1..e6a0d22315e9 100644
+--- a/fs/nfs/file.c
++++ b/fs/nfs/file.c
+@@ -397,7 +397,7 @@ static int nfs_write_end(struct file *file, struct address_space *mapping,
+ 	 */
+ 	if (!PageUptodate(page)) {
+ 		unsigned pglen = nfs_page_length(page);
+-		unsigned end = offset + len;
++		unsigned end = offset + copied;
+ 
+ 		if (pglen == 0) {
+ 			zero_user_segments(page, 0, offset,
+diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
+index 51b51369704c..dcc21f9e4bd1 100644
+--- a/fs/nfs/flexfilelayout/flexfilelayout.c
++++ b/fs/nfs/flexfilelayout/flexfilelayout.c
+@@ -28,6 +28,9 @@
+ 
+ static struct group_info	*ff_zero_group;
+ 
++static void ff_layout_read_record_layoutstats_done(struct rpc_task *task,
++		struct nfs_pgio_header *hdr);
++
+ static struct pnfs_layout_hdr *
+ ff_layout_alloc_layout_hdr(struct inode *inode, gfp_t gfp_flags)
+ {
+@@ -1293,6 +1296,7 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
+ 					hdr->pgio_mirror_idx + 1,
+ 					&hdr->pgio_mirror_idx))
+ 			goto out_eagain;
++		ff_layout_read_record_layoutstats_done(task, hdr);
+ 		pnfs_read_resend_pnfs(hdr);
+ 		return task->tk_status;
+ 	case -NFS4ERR_RESET_TO_MDS:
+diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
+index 2c93a85eda51..eb8edb3d52e1 100644
+--- a/fs/nfs/pnfs.c
++++ b/fs/nfs/pnfs.c
+@@ -252,6 +252,14 @@ pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo)
+ 	}
+ }
+ 
++static void
++pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo)
++{
++	lo->plh_return_iomode = 0;
++	lo->plh_return_seq = 0;
++	clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
++}
++
+ /*
+  * Mark a pnfs_layout_hdr and all associated layout segments as invalid
+  *
+@@ -270,6 +278,7 @@ pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo,
+ 	};
+ 
+ 	set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
++	pnfs_clear_layoutreturn_info(lo);
+ 	return pnfs_mark_matching_lsegs_invalid(lo, lseg_list, &range, 0);
+ }
+ 
+@@ -364,7 +373,9 @@ pnfs_layout_remove_lseg(struct pnfs_layout_hdr *lo,
+ 	list_del_init(&lseg->pls_list);
+ 	/* Matched by pnfs_get_layout_hdr in pnfs_layout_insert_lseg */
+ 	atomic_dec(&lo->plh_refcount);
+-	if (list_empty(&lo->plh_segs)) {
++	if (list_empty(&lo->plh_segs) &&
++	    !test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags) &&
++	    !test_bit(NFS_LAYOUT_RETURN, &lo->plh_flags)) {
+ 		if (atomic_read(&lo->plh_outstanding) == 0)
+ 			set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags);
+ 		clear_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
+@@ -769,14 +780,6 @@ pnfs_destroy_all_layouts(struct nfs_client *clp)
+ 	pnfs_destroy_layouts_byclid(clp, false);
+ }
+ 
+-static void
+-pnfs_clear_layoutreturn_info(struct pnfs_layout_hdr *lo)
+-{
+-	lo->plh_return_iomode = 0;
+-	lo->plh_return_seq = 0;
+-	clear_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags);
+-}
+-
+ /* update lo->plh_stateid with new if is more recent */
+ void
+ pnfs_set_layout_stateid(struct pnfs_layout_hdr *lo, const nfs4_stateid *new,
+@@ -897,6 +900,7 @@ static void pnfs_clear_layoutcommit(struct inode *inode,
+ void pnfs_clear_layoutreturn_waitbit(struct pnfs_layout_hdr *lo)
+ {
+ 	clear_bit_unlock(NFS_LAYOUT_RETURN, &lo->plh_flags);
++	clear_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags);
+ 	smp_mb__after_atomic();
+ 	wake_up_bit(&lo->plh_flags, NFS_LAYOUT_RETURN);
+ 	rpc_wake_up(&NFS_SERVER(lo->plh_inode)->roc_rpcwaitq);
+@@ -910,8 +914,9 @@ pnfs_prepare_layoutreturn(struct pnfs_layout_hdr *lo,
+ 	/* Serialise LAYOUTGET/LAYOUTRETURN */
+ 	if (atomic_read(&lo->plh_outstanding) != 0)
+ 		return false;
+-	if (test_and_set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags))
++	if (test_and_set_bit(NFS_LAYOUT_RETURN_LOCK, &lo->plh_flags))
+ 		return false;
++	set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
+ 	pnfs_get_layout_hdr(lo);
+ 	if (test_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags)) {
+ 		if (stateid != NULL) {
+@@ -1903,6 +1908,8 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
+ 
+ 	spin_lock(&inode->i_lock);
+ 	pnfs_set_plh_return_info(lo, range.iomode, 0);
++	/* Block LAYOUTGET */
++	set_bit(NFS_LAYOUT_RETURN, &lo->plh_flags);
+ 	/*
+ 	 * mark all matching lsegs so that we are sure to have no live
+ 	 * segments at hand when sending layoutreturn. See pnfs_put_lseg()
+@@ -2241,6 +2248,10 @@ void pnfs_read_resend_pnfs(struct nfs_pgio_header *hdr)
+ 	struct nfs_pageio_descriptor pgio;
+ 
+ 	if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) {
++		/* Prevent deadlocks with layoutreturn! */
++		pnfs_put_lseg(hdr->lseg);
++		hdr->lseg = NULL;
++
+ 		nfs_pageio_init_read(&pgio, hdr->inode, false,
+ 					hdr->completion_ops);
+ 		hdr->task.tk_status = nfs_pageio_resend(&pgio, hdr);
+diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
+index 31d99b2927b0..98dbb51fcca8 100644
+--- a/fs/nfs/pnfs.h
++++ b/fs/nfs/pnfs.h
+@@ -96,6 +96,7 @@ enum {
+ 	NFS_LAYOUT_RW_FAILED,		/* get rw layout failed stop trying */
+ 	NFS_LAYOUT_BULK_RECALL,		/* bulk recall affecting layout */
+ 	NFS_LAYOUT_RETURN,		/* layoutreturn in progress */
++	NFS_LAYOUT_RETURN_LOCK,		/* Serialise layoutreturn */
+ 	NFS_LAYOUT_RETURN_REQUESTED,	/* Return this layout ASAP */
+ 	NFS_LAYOUT_INVALID_STID,	/* layout stateid id is invalid */
+ 	NFS_LAYOUT_FIRST_LAYOUTGET,	/* Serialize first layoutget */
+diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
+index 741077deef3b..a3645249f7ec 100644
+--- a/fs/notify/inode_mark.c
++++ b/fs/notify/inode_mark.c
+@@ -150,12 +150,10 @@ int fsnotify_add_inode_mark(struct fsnotify_mark *mark,
+  */
+ void fsnotify_unmount_inodes(struct super_block *sb)
+ {
+-	struct inode *inode, *next_i, *need_iput = NULL;
++	struct inode *inode, *iput_inode = NULL;
+ 
+ 	spin_lock(&sb->s_inode_list_lock);
+-	list_for_each_entry_safe(inode, next_i, &sb->s_inodes, i_sb_list) {
+-		struct inode *need_iput_tmp;
+-
++	list_for_each_entry(inode, &sb->s_inodes, i_sb_list) {
+ 		/*
+ 		 * We cannot __iget() an inode in state I_FREEING,
+ 		 * I_WILL_FREE, or I_NEW which is fine because by that point
+@@ -178,49 +176,24 @@ void fsnotify_unmount_inodes(struct super_block *sb)
+ 			continue;
+ 		}
+ 
+-		need_iput_tmp = need_iput;
+-		need_iput = NULL;
+-
+-		/* In case fsnotify_inode_delete() drops a reference. */
+-		if (inode != need_iput_tmp)
+-			__iget(inode);
+-		else
+-			need_iput_tmp = NULL;
++		__iget(inode);
+ 		spin_unlock(&inode->i_lock);
+-
+-		/* In case the dropping of a reference would nuke next_i. */
+-		while (&next_i->i_sb_list != &sb->s_inodes) {
+-			spin_lock(&next_i->i_lock);
+-			if (!(next_i->i_state & (I_FREEING | I_WILL_FREE)) &&
+-						atomic_read(&next_i->i_count)) {
+-				__iget(next_i);
+-				need_iput = next_i;
+-				spin_unlock(&next_i->i_lock);
+-				break;
+-			}
+-			spin_unlock(&next_i->i_lock);
+-			next_i = list_next_entry(next_i, i_sb_list);
+-		}
+-
+-		/*
+-		 * We can safely drop s_inode_list_lock here because either
+-		 * we actually hold references on both inode and next_i or
+-		 * end of list.  Also no new inodes will be added since the
+-		 * umount has begun.
+-		 */
+ 		spin_unlock(&sb->s_inode_list_lock);
+ 
+-		if (need_iput_tmp)
+-			iput(need_iput_tmp);
++		if (iput_inode)
++			iput(iput_inode);
+ 
+ 		/* for each watch, send FS_UNMOUNT and then remove it */
+ 		fsnotify(inode, FS_UNMOUNT, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
+ 
+ 		fsnotify_inode_delete(inode);
+ 
+-		iput(inode);
++		iput_inode = inode;
+ 
+ 		spin_lock(&sb->s_inode_list_lock);
+ 	}
+ 	spin_unlock(&sb->s_inode_list_lock);
++
++	if (iput_inode)
++		iput(iput_inode);
+ }
+diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
+index beb7610d64e9..95b1b57b28a2 100644
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -4393,6 +4393,17 @@ void cfg80211_rx_assoc_resp(struct net_device *dev,
+ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss);
+ 
+ /**
++ * cfg80211_abandon_assoc - notify cfg80211 of abandoned association attempt
++ * @dev: network device
++ * @bss: The BSS entry with which association was abandoned.
++ *
++ * Call this whenever - for reasons reported through other API, like deauth RX,
++ * an association attempt was abandoned.
++ * This function may sleep. The caller must hold the corresponding wdev's mutex.
++ */
++void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss);
++
++/**
+  * cfg80211_tx_mlme_mgmt - notification of transmitted deauth/disassoc frame
+  * @dev: network device
+  * @buf: 802.11 frame (header + body)
+diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
+index 931a47ba4571..1beab5532035 100644
+--- a/include/rdma/ib_addr.h
++++ b/include/rdma/ib_addr.h
+@@ -205,10 +205,12 @@ static inline void iboe_addr_get_sgid(struct rdma_dev_addr *dev_addr,
+ 
+ 	dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if);
+ 	if (dev) {
+-		ip4 = (struct in_device *)dev->ip_ptr;
+-		if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address)
++		ip4 = in_dev_get(dev);
++		if (ip4 && ip4->ifa_list && ip4->ifa_list->ifa_address) {
+ 			ipv6_addr_set_v4mapped(ip4->ifa_list->ifa_address,
+ 					       (struct in6_addr *)gid);
++			in_dev_put(ip4);
++		}
+ 		dev_put(dev);
+ 	}
+ }
+diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
+index 37dec7e3db43..46e312e9be38 100644
+--- a/kernel/time/timekeeping.c
++++ b/kernel/time/timekeeping.c
+@@ -299,10 +299,10 @@ u32 (*arch_gettimeoffset)(void) = default_arch_gettimeoffset;
+ static inline u32 arch_gettimeoffset(void) { return 0; }
+ #endif
+ 
+-static inline s64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
++static inline u64 timekeeping_delta_to_ns(struct tk_read_base *tkr,
+ 					  cycle_t delta)
+ {
+-	s64 nsec;
++	u64 nsec;
+ 
+ 	nsec = delta * tkr->mult + tkr->xtime_nsec;
+ 	nsec >>= tkr->shift;
+diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
+index 7363ccf79512..16047a818d2f 100644
+--- a/kernel/trace/trace_functions_graph.c
++++ b/kernel/trace/trace_functions_graph.c
+@@ -780,6 +780,10 @@ print_graph_entry_leaf(struct trace_iterator *iter,
+ 
+ 		cpu_data = per_cpu_ptr(data->cpu_data, cpu);
+ 
++		/* If a graph tracer ignored set_graph_notrace */
++		if (call->depth < -1)
++			call->depth += FTRACE_NOTRACE_DEPTH;
++
+ 		/*
+ 		 * Comments display at + 1 to depth. Since
+ 		 * this is a leaf function, keep the comments
+@@ -788,7 +792,8 @@ print_graph_entry_leaf(struct trace_iterator *iter,
+ 		cpu_data->depth = call->depth - 1;
+ 
+ 		/* No need to keep this function around for this depth */
+-		if (call->depth < FTRACE_RETFUNC_DEPTH)
++		if (call->depth < FTRACE_RETFUNC_DEPTH &&
++		    !WARN_ON_ONCE(call->depth < 0))
+ 			cpu_data->enter_funcs[call->depth] = 0;
+ 	}
+ 
+@@ -818,11 +823,16 @@ print_graph_entry_nested(struct trace_iterator *iter,
+ 		struct fgraph_cpu_data *cpu_data;
+ 		int cpu = iter->cpu;
+ 
++		/* If a graph tracer ignored set_graph_notrace */
++		if (call->depth < -1)
++			call->depth += FTRACE_NOTRACE_DEPTH;
++
+ 		cpu_data = per_cpu_ptr(data->cpu_data, cpu);
+ 		cpu_data->depth = call->depth;
+ 
+ 		/* Save this function pointer to see if the exit matches */
+-		if (call->depth < FTRACE_RETFUNC_DEPTH)
++		if (call->depth < FTRACE_RETFUNC_DEPTH &&
++		    !WARN_ON_ONCE(call->depth < 0))
+ 			cpu_data->enter_funcs[call->depth] = call->func;
+ 	}
+ 
+@@ -1052,7 +1062,8 @@ print_graph_return(struct ftrace_graph_ret *trace, struct trace_seq *s,
+ 		 */
+ 		cpu_data->depth = trace->depth - 1;
+ 
+-		if (trace->depth < FTRACE_RETFUNC_DEPTH) {
++		if (trace->depth < FTRACE_RETFUNC_DEPTH &&
++		    !WARN_ON_ONCE(trace->depth < 0)) {
+ 			if (cpu_data->enter_funcs[trace->depth] != trace->func)
+ 				func_match = 0;
+ 			cpu_data->enter_funcs[trace->depth] = 0;
+diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
+index a5502898ea33..2efb335deada 100644
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -2027,6 +2027,19 @@ static int process_connect(struct ceph_connection *con)
+ 
+ 	dout("process_connect on %p tag %d\n", con, (int)con->in_tag);
+ 
++	if (con->auth_reply_buf) {
++		/*
++		 * Any connection that defines ->get_authorizer()
++		 * should also define ->verify_authorizer_reply().
++		 * See get_connect_authorizer().
++		 */
++		ret = con->ops->verify_authorizer_reply(con, 0);
++		if (ret < 0) {
++			con->error_msg = "bad authorize reply";
++			return ret;
++		}
++	}
++
+ 	switch (con->in_reply.tag) {
+ 	case CEPH_MSGR_TAG_FEATURES:
+ 		pr_err("%s%lld %s feature set mismatch,"
+diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
+index 8d426f637f58..b2e3c320b648 100644
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -2506,7 +2506,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
+ }
+ 
+ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
+-					 bool assoc)
++					 bool assoc, bool abandon)
+ {
+ 	struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data;
+ 
+@@ -2529,6 +2529,9 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
+ 		mutex_lock(&sdata->local->mtx);
+ 		ieee80211_vif_release_channel(sdata);
+ 		mutex_unlock(&sdata->local->mtx);
++
++		if (abandon)
++			cfg80211_abandon_assoc(sdata->dev, assoc_data->bss);
+ 	}
+ 
+ 	kfree(assoc_data);
+@@ -2758,7 +2761,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
+ 			   bssid, reason_code,
+ 			   ieee80211_get_reason_code_string(reason_code));
+ 
+-		ieee80211_destroy_assoc_data(sdata, false);
++		ieee80211_destroy_assoc_data(sdata, false, true);
+ 
+ 		cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len);
+ 		return;
+@@ -3163,14 +3166,14 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 	if (status_code != WLAN_STATUS_SUCCESS) {
+ 		sdata_info(sdata, "%pM denied association (code=%d)\n",
+ 			   mgmt->sa, status_code);
+-		ieee80211_destroy_assoc_data(sdata, false);
++		ieee80211_destroy_assoc_data(sdata, false, false);
+ 		event.u.mlme.status = MLME_DENIED;
+ 		event.u.mlme.reason = status_code;
+ 		drv_event_callback(sdata->local, sdata, &event);
+ 	} else {
+ 		if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
+ 			/* oops -- internal error -- send timeout for now */
+-			ieee80211_destroy_assoc_data(sdata, false);
++			ieee80211_destroy_assoc_data(sdata, false, false);
+ 			cfg80211_assoc_timeout(sdata->dev, bss);
+ 			return;
+ 		}
+@@ -3183,7 +3186,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
+ 		 * recalc after assoc_data is NULL but before associated
+ 		 * is set can cause the interface to go idle
+ 		 */
+-		ieee80211_destroy_assoc_data(sdata, true);
++		ieee80211_destroy_assoc_data(sdata, true, false);
+ 
+ 		/* get uapsd queues configuration */
+ 		uapsd_queues = 0;
+@@ -3882,7 +3885,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
+ 				.u.mlme.status = MLME_TIMEOUT,
+ 			};
+ 
+-			ieee80211_destroy_assoc_data(sdata, false);
++			ieee80211_destroy_assoc_data(sdata, false, false);
+ 			cfg80211_assoc_timeout(sdata->dev, bss);
+ 			drv_event_callback(sdata->local, sdata, &event);
+ 		}
+@@ -4021,7 +4024,7 @@ void ieee80211_mgd_quiesce(struct ieee80211_sub_if_data *sdata)
+ 					       WLAN_REASON_DEAUTH_LEAVING,
+ 					       false, frame_buf);
+ 		if (ifmgd->assoc_data)
+-			ieee80211_destroy_assoc_data(sdata, false);
++			ieee80211_destroy_assoc_data(sdata, false, true);
+ 		if (ifmgd->auth_data)
+ 			ieee80211_destroy_auth_data(sdata, false);
+ 		cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf,
+@@ -4903,7 +4906,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
+ 					       IEEE80211_STYPE_DEAUTH,
+ 					       req->reason_code, tx,
+ 					       frame_buf);
+-		ieee80211_destroy_assoc_data(sdata, false);
++		ieee80211_destroy_assoc_data(sdata, false, true);
+ 		ieee80211_report_disconnect(sdata, frame_buf,
+ 					    sizeof(frame_buf), true,
+ 					    req->reason_code);
+@@ -4978,7 +4981,7 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
+ 	sdata_lock(sdata);
+ 	if (ifmgd->assoc_data) {
+ 		struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
+-		ieee80211_destroy_assoc_data(sdata, false);
++		ieee80211_destroy_assoc_data(sdata, false, false);
+ 		cfg80211_assoc_timeout(sdata->dev, bss);
+ 	}
+ 	if (ifmgd->auth_data)
+diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c
+index 976c7812bbd5..a0110c2f5ae4 100644
+--- a/net/sunrpc/auth_gss/auth_gss.c
++++ b/net/sunrpc/auth_gss/auth_gss.c
+@@ -541,9 +541,13 @@ gss_setup_upcall(struct gss_auth *gss_auth, struct rpc_cred *cred)
+ 		return gss_new;
+ 	gss_msg = gss_add_msg(gss_new);
+ 	if (gss_msg == gss_new) {
+-		int res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
++		int res;
++		atomic_inc(&gss_msg->count);
++		res = rpc_queue_upcall(gss_new->pipe, &gss_new->msg);
+ 		if (res) {
+ 			gss_unhash_msg(gss_new);
++			atomic_dec(&gss_msg->count);
++			gss_release_msg(gss_new);
+ 			gss_msg = ERR_PTR(res);
+ 		}
+ 	} else
+@@ -836,6 +840,7 @@ gss_pipe_destroy_msg(struct rpc_pipe_msg *msg)
+ 			warn_gssd();
+ 		gss_release_msg(gss_msg);
+ 	}
++	gss_release_msg(gss_msg);
+ }
+ 
+ static void gss_pipe_dentry_destroy(struct dentry *dir,
+diff --git a/net/vmw_vsock/virtio_transport_common.c b/net/vmw_vsock/virtio_transport_common.c
+index a53b3a16b4f1..62c056ea403b 100644
+--- a/net/vmw_vsock/virtio_transport_common.c
++++ b/net/vmw_vsock/virtio_transport_common.c
+@@ -606,9 +606,9 @@ static int virtio_transport_reset_no_sock(struct virtio_vsock_pkt *pkt)
+ 		return 0;
+ 
+ 	pkt = virtio_transport_alloc_pkt(&info, 0,
+-					 le32_to_cpu(pkt->hdr.dst_cid),
++					 le64_to_cpu(pkt->hdr.dst_cid),
+ 					 le32_to_cpu(pkt->hdr.dst_port),
+-					 le32_to_cpu(pkt->hdr.src_cid),
++					 le64_to_cpu(pkt->hdr.src_cid),
+ 					 le32_to_cpu(pkt->hdr.src_port));
+ 	if (!pkt)
+ 		return -ENOMEM;
+@@ -823,7 +823,7 @@ virtio_transport_send_response(struct vsock_sock *vsk,
+ 	struct virtio_vsock_pkt_info info = {
+ 		.op = VIRTIO_VSOCK_OP_RESPONSE,
+ 		.type = VIRTIO_VSOCK_TYPE_STREAM,
+-		.remote_cid = le32_to_cpu(pkt->hdr.src_cid),
++		.remote_cid = le64_to_cpu(pkt->hdr.src_cid),
+ 		.remote_port = le32_to_cpu(pkt->hdr.src_port),
+ 		.reply = true,
+ 	};
+@@ -863,9 +863,9 @@ virtio_transport_recv_listen(struct sock *sk, struct virtio_vsock_pkt *pkt)
+ 	child->sk_state = SS_CONNECTED;
+ 
+ 	vchild = vsock_sk(child);
+-	vsock_addr_init(&vchild->local_addr, le32_to_cpu(pkt->hdr.dst_cid),
++	vsock_addr_init(&vchild->local_addr, le64_to_cpu(pkt->hdr.dst_cid),
+ 			le32_to_cpu(pkt->hdr.dst_port));
+-	vsock_addr_init(&vchild->remote_addr, le32_to_cpu(pkt->hdr.src_cid),
++	vsock_addr_init(&vchild->remote_addr, le64_to_cpu(pkt->hdr.src_cid),
+ 			le32_to_cpu(pkt->hdr.src_port));
+ 
+ 	vsock_insert_connected(vchild);
+@@ -904,9 +904,9 @@ void virtio_transport_recv_pkt(struct virtio_vsock_pkt *pkt)
+ 	struct sock *sk;
+ 	bool space_available;
+ 
+-	vsock_addr_init(&src, le32_to_cpu(pkt->hdr.src_cid),
++	vsock_addr_init(&src, le64_to_cpu(pkt->hdr.src_cid),
+ 			le32_to_cpu(pkt->hdr.src_port));
+-	vsock_addr_init(&dst, le32_to_cpu(pkt->hdr.dst_cid),
++	vsock_addr_init(&dst, le64_to_cpu(pkt->hdr.dst_cid),
+ 			le32_to_cpu(pkt->hdr.dst_port));
+ 
+ 	trace_virtio_transport_recv_pkt(src.svm_cid, src.svm_port,
+diff --git a/net/wireless/core.h b/net/wireless/core.h
+index 66f2a1145d7c..b5cf21850be7 100644
+--- a/net/wireless/core.h
++++ b/net/wireless/core.h
+@@ -410,6 +410,7 @@ void cfg80211_sme_disassoc(struct wireless_dev *wdev);
+ void cfg80211_sme_deauth(struct wireless_dev *wdev);
+ void cfg80211_sme_auth_timeout(struct wireless_dev *wdev);
+ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev);
++void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev);
+ 
+ /* internal helpers */
+ bool cfg80211_supported_cipher_suite(struct wiphy *wiphy, u32 cipher);
+diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
+index c284d883c349..2a62ef628f42 100644
+--- a/net/wireless/mlme.c
++++ b/net/wireless/mlme.c
+@@ -149,6 +149,18 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
+ }
+ EXPORT_SYMBOL(cfg80211_assoc_timeout);
+ 
++void cfg80211_abandon_assoc(struct net_device *dev, struct cfg80211_bss *bss)
++{
++	struct wireless_dev *wdev = dev->ieee80211_ptr;
++	struct wiphy *wiphy = wdev->wiphy;
++
++	cfg80211_sme_abandon_assoc(wdev);
++
++	cfg80211_unhold_bss(bss_from_pub(bss));
++	cfg80211_put_bss(wiphy, bss);
++}
++EXPORT_SYMBOL(cfg80211_abandon_assoc);
++
+ void cfg80211_tx_mlme_mgmt(struct net_device *dev, const u8 *buf, size_t len)
+ {
+ 	struct wireless_dev *wdev = dev->ieee80211_ptr;
+diff --git a/net/wireless/sme.c b/net/wireless/sme.c
+index add6824c44fd..95c713cdabf0 100644
+--- a/net/wireless/sme.c
++++ b/net/wireless/sme.c
+@@ -39,6 +39,7 @@ struct cfg80211_conn {
+ 		CFG80211_CONN_ASSOCIATING,
+ 		CFG80211_CONN_ASSOC_FAILED,
+ 		CFG80211_CONN_DEAUTH,
++		CFG80211_CONN_ABANDON,
+ 		CFG80211_CONN_CONNECTED,
+ 	} state;
+ 	u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];
+@@ -206,6 +207,8 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
+ 		cfg80211_mlme_deauth(rdev, wdev->netdev, params->bssid,
+ 				     NULL, 0,
+ 				     WLAN_REASON_DEAUTH_LEAVING, false);
++		/* fall through */
++	case CFG80211_CONN_ABANDON:
+ 		/* free directly, disconnected event already sent */
+ 		cfg80211_sme_free(wdev);
+ 		return 0;
+@@ -423,6 +426,17 @@ void cfg80211_sme_assoc_timeout(struct wireless_dev *wdev)
+ 	schedule_work(&rdev->conn_work);
+ }
+ 
++void cfg80211_sme_abandon_assoc(struct wireless_dev *wdev)
++{
++	struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy);
++
++	if (!wdev->conn)
++		return;
++
++	wdev->conn->state = CFG80211_CONN_ABANDON;
++	schedule_work(&rdev->conn_work);
++}
++
+ static int cfg80211_sme_get_conn_ies(struct wireless_dev *wdev,
+ 				     const u8 *ies, size_t ies_len,
+ 				     const u8 **out_ies, size_t *out_ies_len)
+diff --git a/scripts/kconfig/nconf.gui.c b/scripts/kconfig/nconf.gui.c
+index 8275f0e55106..4b2f44c20caf 100644
+--- a/scripts/kconfig/nconf.gui.c
++++ b/scripts/kconfig/nconf.gui.c
+@@ -364,12 +364,14 @@ int dialog_inputbox(WINDOW *main_window,
+ 	WINDOW *prompt_win;
+ 	WINDOW *form_win;
+ 	PANEL *panel;
+-	int i, x, y;
++	int i, x, y, lines, columns, win_lines, win_cols;
+ 	int res = -1;
+ 	int cursor_position = strlen(init);
+ 	int cursor_form_win;
+ 	char *result = *resultp;
+ 
++	getmaxyx(stdscr, lines, columns);
++
+ 	if (strlen(init)+1 > *result_len) {
+ 		*result_len = strlen(init)+1;
+ 		*resultp = result = realloc(result, *result_len);
+@@ -386,14 +388,19 @@ int dialog_inputbox(WINDOW *main_window,
+ 	if (title)
+ 		prompt_width = max(prompt_width, strlen(title));
+ 
++	win_lines = min(prompt_lines+6, lines-2);
++	win_cols = min(prompt_width+7, columns-2);
++	prompt_lines = max(win_lines-6, 0);
++	prompt_width = max(win_cols-7, 0);
++
+ 	/* place dialog in middle of screen */
+-	y = (getmaxy(stdscr)-(prompt_lines+4))/2;
+-	x = (getmaxx(stdscr)-(prompt_width+4))/2;
++	y = (lines-win_lines)/2;
++	x = (columns-win_cols)/2;
+ 
+ 	strncpy(result, init, *result_len);
+ 
+ 	/* create the windows */
+-	win = newwin(prompt_lines+6, prompt_width+7, y, x);
++	win = newwin(win_lines, win_cols, y, x);
+ 	prompt_win = derwin(win, prompt_lines+1, prompt_width, 2, 2);
+ 	form_win = derwin(win, 1, prompt_width, prompt_lines+3, 2);
+ 	keypad(form_win, TRUE);


^ permalink raw reply related	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2017-01-09 11:44 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-08-22 15:06 [gentoo-commits] proj/linux-patches:4.8 commit in: / Mike Pagano
  -- strict thread matches above, loose matches on Subject: below --
2016-09-26 10:35 Mike Pagano
2016-09-26 10:37 Mike Pagano
2016-10-08 19:50 Mike Pagano
2016-10-11  0:07 Mike Pagano
2016-10-16 19:21 Mike Pagano
2016-10-21 11:11 Mike Pagano
2016-10-22 13:08 Mike Pagano
2016-10-23 13:59 Mike Pagano
2016-10-28 14:03 Alice Ferrazzi
2016-10-31 12:34 Alice Ferrazzi
2016-11-04 17:17 Mike Pagano
2016-11-10 16:37 Alice Ferrazzi
2016-11-15  7:59 Alice Ferrazzi
2016-11-19 11:05 Mike Pagano
2016-11-21 14:50 Mike Pagano
2016-11-21 14:55 Mike Pagano
2016-11-26 14:21 Alice Ferrazzi
2016-12-02 16:23 Alice Ferrazzi
2016-12-07 23:26 Mike Pagano
2016-12-09  7:25 Alice Ferrazzi
2016-12-11  7:18 Alice Ferrazzi
2016-12-15 23:43 Mike Pagano
2017-01-06 23:11 Mike Pagano
2017-01-06 23:43 Mike Pagano
2017-01-09 11:44 Alice Ferrazzi

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox