public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
* [gentoo-commits] proj/linux-patches:4.6 commit in: /
@ 2016-04-25 12:19 Mike Pagano
  0 siblings, 0 replies; 12+ messages in thread
From: Mike Pagano @ 2016-04-25 12:19 UTC (permalink / raw
  To: gentoo-commits

commit:     db486a2c722de027b6fb81d8e367c706d6944bbb
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 25 12:19:52 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Apr 25 12:19:52 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=db486a2c

Linux 4.6. Patch to enable link security restrictions by default. Patch to disable Windows 8 compatibility for some Lenovo ThinkPads. Patch to ensure that /dev/root doesn't appear in /proc/mounts when bootint without an initramfs.  fbcondecor bootsplash patch. Add Gentoo Linux support config settings and defaults. Kernel patch that enables gcc < v4.9 optimizations for additional CPUs.  Kernel patch enables gcc >= v4.9 optimizations for additional CPUs.

 0000_README                                        |   28 +
 1500_XATTR_USER_PREFIX.patch                       |   69 +
 ...ble-link-security-restrictions-by-default.patch |   22 +
 2700_ThinkPad-30-brightness-control-fix.patch      |   67 +
 2900_dev-root-proc-mount-fix.patch                 |   38 +
 4200_fbcondecor-3.19.patch                         | 2119 ++++++++++++++++++++
 ...able-additional-cpu-optimizations-for-gcc.patch |  327 +++
 ...-additional-cpu-optimizations-for-gcc-4.9.patch |  402 ++++
 8 files changed, 3072 insertions(+)

diff --git a/0000_README b/0000_README
index 9018993..8e70e78 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,34 @@ 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:  2700_ThinkPad-30-brightness-control-fix.patch
+From:   Seth Forshee <seth.forshee@canonical.com>
+Desc:   ACPI: Disable Windows 8 compatibility for some Lenovo ThinkPads.
+
+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-3.19.patch
+From:   http://www.mepiscommunity.org/fbcondecor
+Desc:   Bootsplash ported by Marco. (Bug #539616)
+
 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/2700_ThinkPad-30-brightness-control-fix.patch b/2700_ThinkPad-30-brightness-control-fix.patch
new file mode 100644
index 0000000..b548c6d
--- /dev/null
+++ b/2700_ThinkPad-30-brightness-control-fix.patch
@@ -0,0 +1,67 @@
+diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c
+index cb96296..6c242ed 100644
+--- a/drivers/acpi/blacklist.c
++++ b/drivers/acpi/blacklist.c
+@@ -269,6 +276,61 @@  static struct dmi_system_id acpi_osi_dmi_table[] __initdata = {
+ 	},
+ 
+ 	/*
++	 * The following Lenovo models have a broken workaround in the
++	 * acpi_video backlight implementation to meet the Windows 8
++	 * requirement of 101 backlight levels. Reverting to pre-Win8
++	 * behavior fixes the problem.
++	 */
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad L430",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad L430"),
++		},
++	},
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad T430s",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T430s"),
++		},
++	},
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad T530",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T530"),
++		},
++	},
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad W530",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad W530"),
++		},
++	},
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad X1 Carbon",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X1 Carbon"),
++		},
++	},
++	{
++	.callback = dmi_disable_osi_win8,
++	.ident = "Lenovo ThinkPad X230",
++	.matches = {
++		     DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
++		     DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X230"),
++		},
++	},
++
++	/*
+ 	 * BIOS invocation of _OSI(Linux) is almost always a BIOS bug.
+ 	 * Linux ignores it, except for the machines enumerated below.
+ 	 */
+

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/4200_fbcondecor-3.19.patch b/4200_fbcondecor-3.19.patch
new file mode 100644
index 0000000..29c379f
--- /dev/null
+++ b/4200_fbcondecor-3.19.patch
@@ -0,0 +1,2119 @@
+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..3388c61
+--- /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 7183b6a..d576148 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/
+ 
+@@ -42,11 +46,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 fe1cd01..6d2e87a 100644
+--- a/drivers/video/console/Kconfig
++++ b/drivers/video/console/Kconfig
+@@ -126,6 +126,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..cc104b6f 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 61b182b..984384b 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);
+ }
+ 
+@@ -380,11 +388,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..a2b4497
+--- /dev/null
++++ b/drivers/video/console/cfbcondecor.c
+@@ -0,0 +1,471 @@
++/*
++ *  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
++			}
++		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 f447734..da50d61 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;
+@@ -286,7 +287,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);
+@@ -551,6 +552,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;
+@@ -1007,6 +1011,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);
+@@ -1036,7 +1046,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))
+@@ -1260,6 +1270,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;
+@@ -1279,10 +1294,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)
+@@ -1298,8 +1318,13 @@ 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 +1844,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 +1937,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 +2087,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 +2164,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 +2201,21 @@ 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 int fbcon_set_palette(struct vc_data *vc, 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 -EINVAL;
+ 
+ 	if (!CON_IS_VISIBLE(vc))
+@@ -2683,14 +2759,56 @@ static int fbcon_set_palette(struct vc_data *vc, unsigned char *table)
+ 	} else
+ 		fb_copy_cmap(fb_default_cmap(1 << depth), &palette_cmap);
+ 
+-	return 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);
++		int h;
++
++		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);
++		}
++
++		h = fb_set_cmap(&cmap, info);
++		fbcon_decor_fix_pseudo_pal(info, vc_cons[fg_console].d);
++		kfree(red);
++
++		return h;
++
++	} 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:	return fb_set_cmap(&palette_cmap, info);
+ }
+ 
+ static u16 *fbcon_screen_pos(struct vc_data *vc, int offset)
+ {
+ 	unsigned long p;
+ 	int line;
+-	
++
+ 	if (vc->vc_num != fg_console || !softback_lines)
+ 		return (u16 *) (vc->vc_origin + offset);
+ 	line = offset / vc->vc_size_row;
+@@ -2909,7 +3027,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;
+@@ -2954,7 +3079,9 @@ 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)
+@@ -3596,6 +3723,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..babc8c5
+--- /dev/null
++++ b/drivers/video/console/fbcondecor.c
+@@ -0,0 +1,555 @@
++/*
++ *  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 <asm/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);
++char fbcon_decor_path[KMOD_PATH_LEN] = "/sbin/fbcondecor_helper";
++static int initialized = 0;
++
++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;
++
++//	if (origin == FBCON_DECOR_IO_ORIG_USER)
++		console_lock();
++	if (!state)
++		ret = fbcon_decor_disable(vc, 1);
++	else
++		ret = fbcon_decor_enable(vc);
++//	if (origin == FBCON_DECOR_IO_ORIG_USER)
++		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;
++
++	/* If this ioctl is a response to a request from kernel, the console sem
++	 * is already held; we also don't need to disable decor because either the
++	 * new config and background picture will be successfully loaded, and the
++	 * decor will stay on, or in case of a failure it'll be turned off in fbcon. */
++//	if (origin == FBCON_DECOR_IO_ORIG_USER) {
++		console_lock();
++		if (vc->vc_decor.state)
++			fbcon_decor_disable(vc, 1);
++//	}
++
++	if (vc->vc_decor.theme)
++		kfree(vc->vc_decor.theme);
++
++	vc->vc_decor = *cfg;
++
++//	if (origin == FBCON_DECOR_IO_ORIG_USER)
++		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;
++
++	/* If this ioctl is a response to a request from kernel, the console sem
++	 * is already held. */
++//	if (origin == FBCON_DECOR_IO_ORIG_USER)
++		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);
++	}
++
++//	if (origin == FBCON_DECOR_IO_ORIG_USER)
++		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;
++	}
++
++	return;
++}
++
++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;
++}
++
++EXPORT_SYMBOL(fbcon_decor_path);
+diff --git a/drivers/video/console/fbcondecor.h b/drivers/video/console/fbcondecor.h
+new file mode 100644
+index 0000000..3b3724b
+--- /dev/null
++++ b/drivers/video/console/fbcondecor.h
+@@ -0,0 +1,78 @@
++/* 
++ *  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 e1f4727..2952e33 100644
+--- a/drivers/video/fbdev/Kconfig
++++ b/drivers/video/fbdev/Kconfig
+@@ -1204,7 +1204,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..05e036c 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
+ };
+@@ -249,14 +251,17 @@ int fb_set_cmap(struct fb_cmap *cmap, struct fb_info *info)
+ 			if (transp)
+ 				htransp = *transp++;
+ 			if (info->fbops->fb_setcolreg(start++,
+-						      hred, hgreen, hblue,
++						      hred, hgreen, hblue, 
+ 						      htransp, 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 b6d5008..d6703f2 100644
+--- a/drivers/video/fbdev/core/fbmem.c
++++ b/drivers/video/fbdev/core/fbmem.c
+@@ -1250,15 +1250,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..04b8d80
+--- /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 7f0c329..98f5d60 100644
+--- a/include/linux/console_struct.h
++++ b/include/linux/console_struct.h
+@@ -19,6 +19,7 @@
+ struct vt_struct;
+ 
+ #define NPAR 16
++#include <linux/console_decor.h>
+ 
+ struct vc_data {
+ 	struct tty_port port;			/* Upper level data */
+@@ -107,6 +108,8 @@ struct vc_data {
+ 	unsigned long	vc_uni_pagedir;
+ 	unsigned long	*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 fe6ac95..1e36b03 100644
+--- a/include/linux/fb.h
++++ b/include/linux/fb.h
+@@ -219,6 +219,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
+  *
+@@ -489,6 +517,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..dc77a03 100644
+--- a/include/uapi/linux/fb.h
++++ b/include/uapi/linux/fb.h
+@@ -8,6 +8,25 @@
+ 
+ #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 +54,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 lenght 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 +315,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 74f5b58..6386ab0 100644
+--- a/kernel/sysctl.c
++++ b/kernel/sysctl.c
+@@ -146,6 +146,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
+@@ -255,6 +259,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
+ 	{ }
+ };
+ 

diff --git a/5000_enable-additional-cpu-optimizations-for-gcc.patch b/5000_enable-additional-cpu-optimizations-for-gcc.patch
new file mode 100644
index 0000000..f7ab6f0
--- /dev/null
+++ b/5000_enable-additional-cpu-optimizations-for-gcc.patch
@@ -0,0 +1,327 @@
+This patch has been tested on and known to work with kernel versions from 3.2
+up to the latest git version (pulled on 12/14/2013).
+
+This patch will expand the number of microarchitectures to include new
+processors including: AMD K10-family, AMD Family 10h (Barcelona), AMD Family
+14h (Bobcat), AMD Family 15h (Bulldozer), AMD Family 15h (Piledriver), AMD
+Family 16h (Jaguar), Intel 1st Gen Core i3/i5/i7 (Nehalem), Intel 2nd Gen Core
+i3/i5/i7 (Sandybridge), Intel 3rd Gen Core i3/i5/i7 (Ivybridge), and Intel 4th
+Gen Core i3/i5/i7 (Haswell). 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
+
+---
+diff -uprN a/arch/x86/include/asm/module.h b/arch/x86/include/asm/module.h
+--- a/arch/x86/include/asm/module.h	2013-11-03 18:41:51.000000000 -0500
++++ b/arch/x86/include/asm/module.h	2013-12-15 06:21:24.351122516 -0500
+@@ -15,6 +15,16 @@
+ #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_MCOREI7
++#define MODULE_PROC_FAMILY "COREI7 "
++#elif defined CONFIG_MCOREI7AVX
++#define MODULE_PROC_FAMILY "COREI7AVX "
++#elif defined CONFIG_MCOREAVXI
++#define MODULE_PROC_FAMILY "COREAVXI "
++#elif defined CONFIG_MCOREAVX2
++#define MODULE_PROC_FAMILY "COREAVX2 "
+ #elif defined CONFIG_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
+ #elif defined CONFIG_M686
+@@ -33,6 +43,18 @@
+ #define MODULE_PROC_FAMILY "K7 "
+ #elif defined CONFIG_MK8
+ #define MODULE_PROC_FAMILY "K8 "
++#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 "PILEDRIVER "
++#elif defined CONFIG_MJAGUAR
++#define MODULE_PROC_FAMILY "JAGUAR "
+ #elif defined CONFIG_MELAN
+ #define MODULE_PROC_FAMILY "ELAN "
+ #elif defined CONFIG_MCRUSOE
+diff -uprN a/arch/x86/Kconfig.cpu b/arch/x86/Kconfig.cpu
+--- a/arch/x86/Kconfig.cpu	2013-11-03 18:41:51.000000000 -0500
++++ b/arch/x86/Kconfig.cpu	2013-12-15 06:21:24.351122516 -0500
+@@ -139,7 +139,7 @@ config MPENTIUM4
+ 
+ 
+ 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 +147,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 +155,55 @@ 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 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 MJAGUAR
++	bool "AMD Jaguar"
++	---help---
++	  Select this for AMD Jaguar processors.
++
++	  Enables -march=btver2
++
+ config MCRUSOE
+ 	bool "Crusoe"
+ 	depends on X86_32
+@@ -251,8 +294,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 +312,40 @@ 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 MCOREI7
++	bool "Intel Core i7"
+ 	---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 the Intel Nehalem platform. Intel Nehalem proecessors
++	  include Core i3, i5, i7, Xeon: 34xx, 35xx, 55xx, 56xx, 75xx processors.
++
++	  Enables -march=corei7
++
++config MCOREI7AVX
++	bool "Intel Core 2nd Gen AVX"
++	---help---
++
++	  Select this for 2nd Gen Core processors including Sandy Bridge.
++
++	  Enables -march=corei7-avx
++
++config MCOREAVXI
++	bool "Intel Core 3rd Gen AVX"
++	---help---
++
++	  Select this for 3rd Gen Core processors including Ivy Bridge.
++
++	  Enables -march=core-avx-i
++
++config MCOREAVX2
++	bool "Intel Core AVX2"
++	---help---
++
++	  Select this for AVX2 enabled processors including Haswell.
++
++	  Enables -march=core-avx2
+ 
+ config GENERIC_CPU
+ 	bool "Generic-x86-64"
+@@ -276,6 +354,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 +391,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 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MPENTIUMM || MCORE2 || MCOREI7 || MCOREI7AVX || MCOREAVXI || MCOREAVX2 || MATOM || MVIAC7 || X86_GENERIC || MNATIVE || 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 +422,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 || MNATIVE || X86_GENERIC || MK8 || MK7 || MK10 || MBARCELONA || MEFFICEON || MCORE2 || MCOREI7 || MCOREI7AVX || MCOREAVXI || MCOREAVX2
+ 
+ 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 || MVIAC3_2 || MVIAC7 || MEFFICEON || MGEODE_LX || MCORE2 || MCOREI7 || MCOREI7AVX || MCOREAVXI || MCOREAVX2 || MATOM || MNATIVE
+ 
+ config X86_USE_3DNOW
+ 	def_bool y
+@@ -363,17 +454,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 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MCOREI7 || MCOREI7-AVX || MATOM) || X86_64 || MNATIVE
+ 
+ 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 || MCOREI7 || MCOREI7AVX || MCOREAVXI || MCOREAVX2 || 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 || MK10 || MBARCELONA || MBOBCAT || MBULLDOZER || MPILEDRIVER || MJAGUAR || MK7 || MCORE2 || MCOREI7 || MCOREI7AVX || MCOREAVXI || MCOREAVX2 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || MATOM || MGEODE_LX)
+ 
+ config X86_MINIMUM_CPU_FAMILY
+ 	int
+diff -uprN a/arch/x86/Makefile b/arch/x86/Makefile
+--- a/arch/x86/Makefile	2013-11-03 18:41:51.000000000 -0500
++++ b/arch/x86/Makefile	2013-12-15 06:21:24.354455723 -0500
+@@ -61,11 +61,26 @@ else
+ 	KBUILD_CFLAGS += $(call cc-option,-mno-sse -mpreferred-stack-boundary=3)
+ 
+         # 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_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_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))
++                $(call cc-option,-march=core2,$(call cc-option,-mtune=core2))
++        cflags-$(CONFIG_MCOREI7) += \
++                $(call cc-option,-march=corei7,$(call cc-option,-mtune=corei7))
++        cflags-$(CONFIG_MCOREI7AVX) += \
++                $(call cc-option,-march=corei7-avx,$(call cc-option,-mtune=corei7-avx))
++        cflags-$(CONFIG_MCOREAVXI) += \
++                $(call cc-option,-march=core-avx-i,$(call cc-option,-mtune=core-avx-i))
++        cflags-$(CONFIG_MCOREAVX2) += \
++                $(call cc-option,-march=core-avx2,$(call cc-option,-mtune=core-avx2))
+ 	cflags-$(CONFIG_MATOM) += $(call cc-option,-march=atom) \
+ 		$(call cc-option,-mtune=atom,$(call cc-option,-mtune=generic))
+         cflags-$(CONFIG_GENERIC_CPU) += $(call cc-option,-mtune=generic)
+diff -uprN a/arch/x86/Makefile_32.cpu b/arch/x86/Makefile_32.cpu
+--- a/arch/x86/Makefile_32.cpu	2013-11-03 18:41:51.000000000 -0500
++++ b/arch/x86/Makefile_32.cpu	2013-12-15 06:21:24.354455723 -0500
+@@ -23,7 +23,14 @@ 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_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_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,6 +39,10 @@ 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_MCOREI7)	+= -march=i686 $(call tune,corei7)
++cflags-$(CONFIG_MCOREI7AVX)	+= -march=i686 $(call tune,corei7-avx)
++cflags-$(CONFIG_MCOREAVXI)	+= -march=i686 $(call tune,core-avx-i)
++cflags-$(CONFIG_MCOREAVX2)	+= -march=i686 $(call tune,core-avx2)
+ 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))

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..418201d
--- /dev/null
+++ b/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
@@ -0,0 +1,402 @@
+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 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	2014-06-16 16:44:27.000000000 -0400
++++ b/arch/x86/include/asm/module.h	2015-03-07 03:27:32.556672424 -0500
+@@ -15,6 +15,22 @@
+ #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_MATOM
+ #define MODULE_PROC_FAMILY "ATOM "
+ #elif defined CONFIG_M686
+@@ -33,6 +49,20 @@
+ #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 "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	2014-06-16 16:44:27.000000000 -0400
++++ b/arch/x86/Kconfig.cpu	2015-03-07 03:32:14.337713226 -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,62 @@ 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 MJAGUAR
++	bool "AMD Jaguar"
++	---help---
++	  Select this for AMD Jaguar processors.
++
++	  Enables -march=btver2
++
+ config MCRUSOE
+ 	bool "Crusoe"
+ 	depends on X86_32
+@@ -251,8 +300,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 +318,63 @@ 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 GENERIC_CPU
+ 	bool "Generic-x86-64"
+@@ -276,6 +383,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 +420,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 || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || 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 +451,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 || 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 || MATOM || MNATIVE
+ 
+ config X86_USE_3DNOW
+ 	def_bool y
+@@ -359,17 +479,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 || 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 || 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 || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || 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	2014-06-16 16:44:27.000000000 -0400
++++ b/arch/x86/Makefile	2015-03-07 03:33:27.650843211 -0500
+@@ -92,13 +92,35 @@ else
+ 	KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
+ 
+         # 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_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_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	2014-06-16 16:44:27.000000000 -0400
++++ b/arch/x86/Makefile_32.cpu	2015-03-07 03:34:15.203586024 -0500
+@@ -23,7 +23,15 @@ 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_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 +40,15 @@ 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_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] 12+ messages in thread

* [gentoo-commits] proj/linux-patches:4.6 commit in: /
@ 2016-06-02 19:39 Mike Pagano
  0 siblings, 0 replies; 12+ messages in thread
From: Mike Pagano @ 2016-06-02 19:39 UTC (permalink / raw
  To: gentoo-commits

commit:     dc34aa235aa823a2bb5b439479041daca6a93749
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Thu Jun  2 19:39:11 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Thu Jun  2 19:39:11 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=dc34aa23

Linux patch 4.6.1

 0000_README            |    4 +
 1000_linux-4.6.1.patch | 4584 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4588 insertions(+)

diff --git a/0000_README b/0000_README
index 8e70e78..220d627 100644
--- a/0000_README
+++ b/0000_README
@@ -43,6 +43,10 @@ EXPERIMENTAL
 Individual Patch Descriptions:
 --------------------------------------------------------------------------
 
+Patch:  1000_linux-4.6.1.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.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.6.1.patch b/1000_linux-4.6.1.patch
new file mode 100644
index 0000000..7282235
--- /dev/null
+++ b/1000_linux-4.6.1.patch
@@ -0,0 +1,4584 @@
+diff --git a/Documentation/serial/tty.txt b/Documentation/serial/tty.txt
+index 798cba82c762..b48780977a68 100644
+--- a/Documentation/serial/tty.txt
++++ b/Documentation/serial/tty.txt
+@@ -210,9 +210,6 @@ TTY_IO_ERROR		If set, causes all subsequent userspace read/write
+ 
+ TTY_OTHER_CLOSED	Device is a pty and the other side has closed.
+ 
+-TTY_OTHER_DONE		Device is a pty and the other side has closed and
+-			all pending input processing has been completed.
+-
+ TTY_NO_WRITE_SPLIT	Prevent driver from splitting up writes into
+ 			smaller chunks.
+ 
+diff --git a/Makefile b/Makefile
+index 0f9cb36d45c2..2fcc41ea99a3 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 0
++SUBLEVEL = 1
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+@@ -697,9 +697,10 @@ KBUILD_CFLAGS += $(call cc-option, -mno-global-merge,)
+ KBUILD_CFLAGS += $(call cc-option, -fcatch-undefined-behavior)
+ else
+ 
+-# This warning generated too much noise in a regular build.
+-# Use make W=1 to enable this warning (see scripts/Makefile.build)
++# These warnings generated too much noise in a regular build.
++# Use make W=1 to enable them (see scripts/Makefile.build)
+ KBUILD_CFLAGS += $(call cc-disable-warning, unused-but-set-variable)
++KBUILD_CFLAGS += $(call cc-disable-warning, unused-const-variable)
+ endif
+ 
+ ifdef CONFIG_FRAME_POINTER
+diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
+index d6d4191e68f2..dea1452a8419 100644
+--- a/arch/arm/kvm/mmu.c
++++ b/arch/arm/kvm/mmu.c
+@@ -893,11 +893,14 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
+ 	VM_BUG_ON(pmd_present(*pmd) && pmd_pfn(*pmd) != pmd_pfn(*new_pmd));
+ 
+ 	old_pmd = *pmd;
+-	kvm_set_pmd(pmd, *new_pmd);
+-	if (pmd_present(old_pmd))
++	if (pmd_present(old_pmd)) {
++		pmd_clear(pmd);
+ 		kvm_tlb_flush_vmid_ipa(kvm, addr);
+-	else
++	} else {
+ 		get_page(virt_to_page(pmd));
++	}
++
++	kvm_set_pmd(pmd, *new_pmd);
+ 	return 0;
+ }
+ 
+@@ -946,12 +949,14 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
+ 
+ 	/* Create 2nd stage page table mapping - Level 3 */
+ 	old_pte = *pte;
+-	kvm_set_pte(pte, *new_pte);
+-	if (pte_present(old_pte))
++	if (pte_present(old_pte)) {
++		kvm_set_pte(pte, __pte(0));
+ 		kvm_tlb_flush_vmid_ipa(kvm, addr);
+-	else
++	} else {
+ 		get_page(virt_to_page(pte));
++	}
+ 
++	kvm_set_pte(pte, *new_pte);
+ 	return 0;
+ }
+ 
+diff --git a/arch/arm64/include/asm/pgtable-hwdef.h b/arch/arm64/include/asm/pgtable-hwdef.h
+index 5c25b831273d..9786f770088d 100644
+--- a/arch/arm64/include/asm/pgtable-hwdef.h
++++ b/arch/arm64/include/asm/pgtable-hwdef.h
+@@ -133,7 +133,6 @@
+  * Section
+  */
+ #define PMD_SECT_VALID		(_AT(pmdval_t, 1) << 0)
+-#define PMD_SECT_PROT_NONE	(_AT(pmdval_t, 1) << 58)
+ #define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
+ #define PMD_SECT_RDONLY		(_AT(pmdval_t, 1) << 7)		/* AP[2] */
+ #define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
+diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
+index 989fef16d461..44430ce5819e 100644
+--- a/arch/arm64/include/asm/pgtable.h
++++ b/arch/arm64/include/asm/pgtable.h
+@@ -280,6 +280,7 @@ static inline pgprot_t mk_sect_prot(pgprot_t prot)
+ #define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
+ #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+ 
++#define pmd_present(pmd)	pte_present(pmd_pte(pmd))
+ #define pmd_dirty(pmd)		pte_dirty(pmd_pte(pmd))
+ #define pmd_young(pmd)		pte_young(pmd_pte(pmd))
+ #define pmd_wrprotect(pmd)	pte_pmd(pte_wrprotect(pmd_pte(pmd)))
+@@ -288,7 +289,7 @@ static inline pgprot_t mk_sect_prot(pgprot_t prot)
+ #define pmd_mkclean(pmd)       pte_pmd(pte_mkclean(pmd_pte(pmd)))
+ #define pmd_mkdirty(pmd)	pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+ #define pmd_mkyoung(pmd)	pte_pmd(pte_mkyoung(pmd_pte(pmd)))
+-#define pmd_mknotpresent(pmd)	(__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
++#define pmd_mknotpresent(pmd)	(__pmd(pmd_val(pmd) & ~PMD_SECT_VALID))
+ 
+ #define __HAVE_ARCH_PMD_WRITE
+ #define pmd_write(pmd)		pte_write(pmd_pte(pmd))
+@@ -327,7 +328,6 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
+ 				     unsigned long size, pgprot_t vma_prot);
+ 
+ #define pmd_none(pmd)		(!pmd_val(pmd))
+-#define pmd_present(pmd)	(pmd_val(pmd))
+ 
+ #define pmd_bad(pmd)		(!(pmd_val(pmd) & 2))
+ 
+@@ -526,6 +526,21 @@ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+ }
+ 
+ #ifdef CONFIG_ARM64_HW_AFDBM
++#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
++extern int ptep_set_access_flags(struct vm_area_struct *vma,
++				 unsigned long address, pte_t *ptep,
++				 pte_t entry, int dirty);
++
++#ifdef CONFIG_TRANSPARENT_HUGEPAGE
++#define __HAVE_ARCH_PMDP_SET_ACCESS_FLAGS
++static inline int pmdp_set_access_flags(struct vm_area_struct *vma,
++					unsigned long address, pmd_t *pmdp,
++					pmd_t entry, int dirty)
++{
++	return ptep_set_access_flags(vma, address, (pte_t *)pmdp, pmd_pte(entry), dirty);
++}
++#endif
++
+ /*
+  * Atomic pte/pmd modifications.
+  */
+@@ -578,9 +593,9 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
+ }
+ 
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+-#define __HAVE_ARCH_PMDP_GET_AND_CLEAR
+-static inline pmd_t pmdp_get_and_clear(struct mm_struct *mm,
+-				       unsigned long address, pmd_t *pmdp)
++#define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
++static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
++					    unsigned long address, pmd_t *pmdp)
+ {
+ 	return pte_pmd(ptep_get_and_clear(mm, address, (pte_t *)pmdp));
+ }
+diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
+index 84c8684431c7..f0c3fb7ec8cf 100644
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -87,7 +87,8 @@ static const char *const compat_hwcap_str[] = {
+ 	"idivt",
+ 	"vfpd32",
+ 	"lpae",
+-	"evtstrm"
++	"evtstrm",
++	NULL
+ };
+ 
+ static const char *const compat_hwcap2_str[] = {
+diff --git a/arch/arm64/kvm/inject_fault.c b/arch/arm64/kvm/inject_fault.c
+index 4d1ac81870d2..e9e0e6db73f6 100644
+--- a/arch/arm64/kvm/inject_fault.c
++++ b/arch/arm64/kvm/inject_fault.c
+@@ -162,7 +162,7 @@ static void inject_abt64(struct kvm_vcpu *vcpu, bool is_iabt, unsigned long addr
+ 		esr |= (ESR_ELx_EC_IABT_CUR << ESR_ELx_EC_SHIFT);
+ 
+ 	if (!is_iabt)
+-		esr |= ESR_ELx_EC_DABT_LOW;
++		esr |= ESR_ELx_EC_DABT_LOW << ESR_ELx_EC_SHIFT;
+ 
+ 	vcpu_sys_reg(vcpu, ESR_EL1) = esr | ESR_ELx_FSC_EXTABT;
+ }
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index 95df28bc875f..3ae4a28c4aed 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -81,6 +81,56 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
+ 	printk("\n");
+ }
+ 
++#ifdef CONFIG_ARM64_HW_AFDBM
++/*
++ * This function sets the access flags (dirty, accessed), as well as write
++ * permission, and only to a more permissive setting.
++ *
++ * It needs to cope with hardware update of the accessed/dirty state by other
++ * agents in the system and can safely skip the __sync_icache_dcache() call as,
++ * like set_pte_at(), the PTE is never changed from no-exec to exec here.
++ *
++ * Returns whether or not the PTE actually changed.
++ */
++int ptep_set_access_flags(struct vm_area_struct *vma,
++			  unsigned long address, pte_t *ptep,
++			  pte_t entry, int dirty)
++{
++	pteval_t old_pteval;
++	unsigned int tmp;
++
++	if (pte_same(*ptep, entry))
++		return 0;
++
++	/* only preserve the access flags and write permission */
++	pte_val(entry) &= PTE_AF | PTE_WRITE | PTE_DIRTY;
++
++	/*
++	 * PTE_RDONLY is cleared by default in the asm below, so set it in
++	 * back if necessary (read-only or clean PTE).
++	 */
++	if (!pte_write(entry) || !dirty)
++		pte_val(entry) |= PTE_RDONLY;
++
++	/*
++	 * Setting the flags must be done atomically to avoid racing with the
++	 * hardware update of the access/dirty state.
++	 */
++	asm volatile("//	ptep_set_access_flags\n"
++	"	prfm	pstl1strm, %2\n"
++	"1:	ldxr	%0, %2\n"
++	"	and	%0, %0, %3		// clear PTE_RDONLY\n"
++	"	orr	%0, %0, %4		// set flags\n"
++	"	stxr	%w1, %0, %2\n"
++	"	cbnz	%w1, 1b\n"
++	: "=&r" (old_pteval), "=&r" (tmp), "+Q" (pte_val(*ptep))
++	: "L" (~PTE_RDONLY), "r" (pte_val(entry)));
++
++	flush_tlb_fix_spurious_fault(vma, address);
++	return 1;
++}
++#endif
++
+ /*
+  * The kernel tried to access some page that wasn't present.
+  */
+diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
+index f6b12790716c..942b8f6bf35b 100644
+--- a/arch/mips/include/asm/kvm_host.h
++++ b/arch/mips/include/asm/kvm_host.h
+@@ -747,7 +747,7 @@ extern enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu,
+ 
+ uint32_t kvm_mips_read_count(struct kvm_vcpu *vcpu);
+ void kvm_mips_write_count(struct kvm_vcpu *vcpu, uint32_t count);
+-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare);
++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack);
+ void kvm_mips_init_count(struct kvm_vcpu *vcpu);
+ int kvm_mips_set_count_ctl(struct kvm_vcpu *vcpu, s64 count_ctl);
+ int kvm_mips_set_count_resume(struct kvm_vcpu *vcpu, s64 count_resume);
+diff --git a/arch/mips/kvm/emulate.c b/arch/mips/kvm/emulate.c
+index b37954cc880d..b8b7860ec1a8 100644
+--- a/arch/mips/kvm/emulate.c
++++ b/arch/mips/kvm/emulate.c
+@@ -302,12 +302,31 @@ static inline ktime_t kvm_mips_count_time(struct kvm_vcpu *vcpu)
+  */
+ static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
+ {
+-	ktime_t expires;
++	struct mips_coproc *cop0 = vcpu->arch.cop0;
++	ktime_t expires, threshold;
++	uint32_t count, compare;
+ 	int running;
+ 
+-	/* Is the hrtimer pending? */
++	/* Calculate the biased and scaled guest CP0_Count */
++	count = vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
++	compare = kvm_read_c0_guest_compare(cop0);
++
++	/*
++	 * Find whether CP0_Count has reached the closest timer interrupt. If
++	 * not, we shouldn't inject it.
++	 */
++	if ((int32_t)(count - compare) < 0)
++		return count;
++
++	/*
++	 * The CP0_Count we're going to return has already reached the closest
++	 * timer interrupt. Quickly check if it really is a new interrupt by
++	 * looking at whether the interval until the hrtimer expiry time is
++	 * less than 1/4 of the timer period.
++	 */
+ 	expires = hrtimer_get_expires(&vcpu->arch.comparecount_timer);
+-	if (ktime_compare(now, expires) >= 0) {
++	threshold = ktime_add_ns(now, vcpu->arch.count_period / 4);
++	if (ktime_before(expires, threshold)) {
+ 		/*
+ 		 * Cancel it while we handle it so there's no chance of
+ 		 * interference with the timeout handler.
+@@ -329,8 +348,7 @@ static uint32_t kvm_mips_read_count_running(struct kvm_vcpu *vcpu, ktime_t now)
+ 		}
+ 	}
+ 
+-	/* Return the biased and scaled guest CP0_Count */
+-	return vcpu->arch.count_bias + kvm_mips_ktime_to_count(vcpu, now);
++	return count;
+ }
+ 
+ /**
+@@ -420,32 +438,6 @@ static void kvm_mips_resume_hrtimer(struct kvm_vcpu *vcpu,
+ }
+ 
+ /**
+- * kvm_mips_update_hrtimer() - Update next expiry time of hrtimer.
+- * @vcpu:	Virtual CPU.
+- *
+- * Recalculates and updates the expiry time of the hrtimer. This can be used
+- * after timer parameters have been altered which do not depend on the time that
+- * the change occurs (in those cases kvm_mips_freeze_hrtimer() and
+- * kvm_mips_resume_hrtimer() are used directly).
+- *
+- * It is guaranteed that no timer interrupts will be lost in the process.
+- *
+- * Assumes !kvm_mips_count_disabled(@vcpu) (guest CP0_Count timer is running).
+- */
+-static void kvm_mips_update_hrtimer(struct kvm_vcpu *vcpu)
+-{
+-	ktime_t now;
+-	uint32_t count;
+-
+-	/*
+-	 * freeze_hrtimer takes care of a timer interrupts <= count, and
+-	 * resume_hrtimer the hrtimer takes care of a timer interrupts > count.
+-	 */
+-	now = kvm_mips_freeze_hrtimer(vcpu, &count);
+-	kvm_mips_resume_hrtimer(vcpu, now, count);
+-}
+-
+-/**
+  * kvm_mips_write_count() - Modify the count and update timer.
+  * @vcpu:	Virtual CPU.
+  * @count:	Guest CP0_Count value to set.
+@@ -540,23 +532,42 @@ int kvm_mips_set_count_hz(struct kvm_vcpu *vcpu, s64 count_hz)
+  * kvm_mips_write_compare() - Modify compare and update timer.
+  * @vcpu:	Virtual CPU.
+  * @compare:	New CP0_Compare value.
++ * @ack:	Whether to acknowledge timer interrupt.
+  *
+  * Update CP0_Compare to a new value and update the timeout.
++ * If @ack, atomically acknowledge any pending timer interrupt, otherwise ensure
++ * any pending timer interrupt is preserved.
+  */
+-void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare)
++void kvm_mips_write_compare(struct kvm_vcpu *vcpu, uint32_t compare, bool ack)
+ {
+ 	struct mips_coproc *cop0 = vcpu->arch.cop0;
++	int dc;
++	u32 old_compare = kvm_read_c0_guest_compare(cop0);
++	ktime_t now;
++	uint32_t count;
+ 
+ 	/* if unchanged, must just be an ack */
+-	if (kvm_read_c0_guest_compare(cop0) == compare)
++	if (old_compare == compare) {
++		if (!ack)
++			return;
++		kvm_mips_callbacks->dequeue_timer_int(vcpu);
++		kvm_write_c0_guest_compare(cop0, compare);
+ 		return;
++	}
++
++	/* freeze_hrtimer() takes care of timer interrupts <= count */
++	dc = kvm_mips_count_disabled(vcpu);
++	if (!dc)
++		now = kvm_mips_freeze_hrtimer(vcpu, &count);
++
++	if (ack)
++		kvm_mips_callbacks->dequeue_timer_int(vcpu);
+ 
+-	/* Update compare */
+ 	kvm_write_c0_guest_compare(cop0, compare);
+ 
+-	/* Update timeout if count enabled */
+-	if (!kvm_mips_count_disabled(vcpu))
+-		kvm_mips_update_hrtimer(vcpu);
++	/* resume_hrtimer() takes care of timer interrupts > count */
++	if (!dc)
++		kvm_mips_resume_hrtimer(vcpu, now, count);
+ }
+ 
+ /**
+@@ -1095,9 +1106,9 @@ enum emulation_result kvm_mips_emulate_CP0(uint32_t inst, uint32_t *opc,
+ 
+ 				/* If we are writing to COMPARE */
+ 				/* Clear pending timer interrupt, if any */
+-				kvm_mips_callbacks->dequeue_timer_int(vcpu);
+ 				kvm_mips_write_compare(vcpu,
+-						       vcpu->arch.gprs[rt]);
++						       vcpu->arch.gprs[rt],
++						       true);
+ 			} else if ((rd == MIPS_CP0_STATUS) && (sel == 0)) {
+ 				unsigned int old_val, val, change;
+ 
+diff --git a/arch/mips/kvm/trap_emul.c b/arch/mips/kvm/trap_emul.c
+index c4038d2a724c..caa5ea1038a0 100644
+--- a/arch/mips/kvm/trap_emul.c
++++ b/arch/mips/kvm/trap_emul.c
+@@ -546,7 +546,7 @@ static int kvm_trap_emul_set_one_reg(struct kvm_vcpu *vcpu,
+ 		kvm_mips_write_count(vcpu, v);
+ 		break;
+ 	case KVM_REG_MIPS_CP0_COMPARE:
+-		kvm_mips_write_compare(vcpu, v);
++		kvm_mips_write_compare(vcpu, v, false);
+ 		break;
+ 	case KVM_REG_MIPS_CP0_CAUSE:
+ 		/*
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c
+index 84fb4fcfaa41..93243554cae9 100644
+--- a/arch/powerpc/kvm/book3s_hv.c
++++ b/arch/powerpc/kvm/book3s_hv.c
+@@ -27,6 +27,7 @@
+ #include <linux/export.h>
+ #include <linux/fs.h>
+ #include <linux/anon_inodes.h>
++#include <linux/cpu.h>
+ #include <linux/cpumask.h>
+ #include <linux/spinlock.h>
+ #include <linux/page-flags.h>
+diff --git a/arch/x86/crypto/sha-mb/sha1_x8_avx2.S b/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
+index 8e1b47792b31..c9dae1cd2919 100644
+--- a/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
++++ b/arch/x86/crypto/sha-mb/sha1_x8_avx2.S
+@@ -296,7 +296,11 @@ W14  = TMP_
+ #
+ ENTRY(sha1_x8_avx2)
+ 
+-	push	RSP_SAVE
++	# save callee-saved clobbered registers to comply with C function ABI
++	push	%r12
++	push	%r13
++	push	%r14
++	push	%r15
+ 
+ 	#save rsp
+ 	mov	%rsp, RSP_SAVE
+@@ -446,7 +450,12 @@ lloop:
+ 	## Postamble
+ 
+ 	mov     RSP_SAVE, %rsp
+-	pop	RSP_SAVE
++
++	# restore callee-saved clobbered registers
++	pop	%r15
++	pop	%r14
++	pop	%r13
++	pop	%r12
+ 
+ 	ret
+ ENDPROC(sha1_x8_avx2)
+diff --git a/arch/x86/events/intel/uncore.c b/arch/x86/events/intel/uncore.c
+index 7012d18bb293..f921a1ed43f7 100644
+--- a/arch/x86/events/intel/uncore.c
++++ b/arch/x86/events/intel/uncore.c
+@@ -888,7 +888,7 @@ static int uncore_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id
+ 		return -ENODEV;
+ 
+ 	pkg = topology_phys_to_logical_pkg(phys_id);
+-	if (WARN_ON_ONCE(pkg < 0))
++	if (pkg < 0)
+ 		return -EINVAL;
+ 
+ 	if (UNCORE_PCI_DEV_TYPE(id->driver_data) == UNCORE_EXTRA_PCI_DEV) {
+diff --git a/arch/x86/include/asm/cpufeature.h b/arch/x86/include/asm/cpufeature.h
+index 3636ec06c887..aeab47932933 100644
+--- a/arch/x86/include/asm/cpufeature.h
++++ b/arch/x86/include/asm/cpufeature.h
+@@ -63,9 +63,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
+ 	   (((bit)>>5)==11 && (1UL<<((bit)&31) & REQUIRED_MASK11)) ||	\
+ 	   (((bit)>>5)==12 && (1UL<<((bit)&31) & REQUIRED_MASK12)) ||	\
+ 	   (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK13)) ||	\
+-	   (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK14)) ||	\
+-	   (((bit)>>5)==13 && (1UL<<((bit)&31) & REQUIRED_MASK15)) ||	\
+-	   (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
++	   (((bit)>>5)==14 && (1UL<<((bit)&31) & REQUIRED_MASK14)) ||	\
++	   (((bit)>>5)==15 && (1UL<<((bit)&31) & REQUIRED_MASK15)) ||	\
++	   (((bit)>>5)==16 && (1UL<<((bit)&31) & REQUIRED_MASK16)) )
+ 
+ #define DISABLED_MASK_BIT_SET(bit)					\
+ 	 ( (((bit)>>5)==0  && (1UL<<((bit)&31) & DISABLED_MASK0 )) ||	\
+@@ -82,9 +82,9 @@ extern const char * const x86_bug_flags[NBUGINTS*32];
+ 	   (((bit)>>5)==11 && (1UL<<((bit)&31) & DISABLED_MASK11)) ||	\
+ 	   (((bit)>>5)==12 && (1UL<<((bit)&31) & DISABLED_MASK12)) ||	\
+ 	   (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK13)) ||	\
+-	   (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK14)) ||	\
+-	   (((bit)>>5)==13 && (1UL<<((bit)&31) & DISABLED_MASK15)) ||	\
+-	   (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
++	   (((bit)>>5)==14 && (1UL<<((bit)&31) & DISABLED_MASK14)) ||	\
++	   (((bit)>>5)==15 && (1UL<<((bit)&31) & DISABLED_MASK15)) ||	\
++	   (((bit)>>5)==16 && (1UL<<((bit)&31) & DISABLED_MASK16)) )
+ 
+ #define cpu_has(c, bit)							\
+ 	(__builtin_constant_p(bit) && REQUIRED_MASK_BIT_SET(bit) ? 1 :	\
+diff --git a/arch/x86/include/asm/disabled-features.h b/arch/x86/include/asm/disabled-features.h
+index 39343be7d4f4..911e9358ceb1 100644
+--- a/arch/x86/include/asm/disabled-features.h
++++ b/arch/x86/include/asm/disabled-features.h
+@@ -29,11 +29,11 @@
+ #endif /* CONFIG_X86_64 */
+ 
+ #ifdef CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS
+-# define DISABLE_PKU		(1<<(X86_FEATURE_PKU))
+-# define DISABLE_OSPKE		(1<<(X86_FEATURE_OSPKE))
+-#else
+ # define DISABLE_PKU		0
+ # define DISABLE_OSPKE		0
++#else
++# define DISABLE_PKU		(1<<(X86_FEATURE_PKU & 31))
++# define DISABLE_OSPKE		(1<<(X86_FEATURE_OSPKE & 31))
+ #endif /* CONFIG_X86_INTEL_MEMORY_PROTECTION_KEYS */
+ 
+ /*
+diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
+index 8394b3d1f94f..f45a4b9d28c8 100644
+--- a/arch/x86/kernel/cpu/common.c
++++ b/arch/x86/kernel/cpu/common.c
+@@ -310,6 +310,10 @@ static bool pku_disabled;
+ 
+ static __always_inline void setup_pku(struct cpuinfo_x86 *c)
+ {
++	/* check the boot processor, plus compile options for PKU: */
++	if (!cpu_feature_enabled(X86_FEATURE_PKU))
++		return;
++	/* checks the actual processor's cpuid bits: */
+ 	if (!cpu_has(c, X86_FEATURE_PKU))
+ 		return;
+ 	if (pku_disabled)
+diff --git a/arch/x86/kvm/mtrr.c b/arch/x86/kvm/mtrr.c
+index 3f8c732117ec..c146f3c262c3 100644
+--- a/arch/x86/kvm/mtrr.c
++++ b/arch/x86/kvm/mtrr.c
+@@ -44,8 +44,6 @@ static bool msr_mtrr_valid(unsigned msr)
+ 	case MSR_MTRRdefType:
+ 	case MSR_IA32_CR_PAT:
+ 		return true;
+-	case 0x2f8:
+-		return true;
+ 	}
+ 	return false;
+ }
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index 133679d520af..faf52bac1416 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -5050,8 +5050,8 @@ static void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event)
+ 		vmcs_write16(VIRTUAL_PROCESSOR_ID, vmx->vpid);
+ 
+ 	cr0 = X86_CR0_NW | X86_CR0_CD | X86_CR0_ET;
+-	vmx_set_cr0(vcpu, cr0); /* enter rmode */
+ 	vmx->vcpu.arch.cr0 = cr0;
++	vmx_set_cr0(vcpu, cr0); /* enter rmode */
+ 	vmx_set_cr4(vcpu, 0);
+ 	vmx_set_efer(vcpu, 0);
+ 	vmx_fpu_activate(vcpu);
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index beac4dfdade6..349b8ce92bf2 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -491,8 +491,11 @@ int __init pci_xen_initial_domain(void)
+ #endif
+ 	__acpi_register_gsi = acpi_register_gsi_xen;
+ 	__acpi_unregister_gsi = NULL;
+-	/* Pre-allocate legacy irqs */
+-	for (irq = 0; irq < nr_legacy_irqs(); irq++) {
++	/*
++	 * Pre-allocate the legacy IRQs.  Use NR_LEGACY_IRQS here
++	 * because we don't have a PIC and thus nr_legacy_irqs() is zero.
++	 */
++	for (irq = 0; irq < NR_IRQS_LEGACY; irq++) {
+ 		int trigger, polarity;
+ 
+ 		if (acpi_get_override_irq(irq, &trigger, &polarity) == -1)
+diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c
+index cd2c3d6d40e0..993fd31394c8 100644
+--- a/drivers/acpi/device_pm.c
++++ b/drivers/acpi/device_pm.c
+@@ -319,6 +319,7 @@ int acpi_device_fix_up_power(struct acpi_device *device)
+ 
+ 	return ret;
+ }
++EXPORT_SYMBOL_GPL(acpi_device_fix_up_power);
+ 
+ int acpi_device_update_power(struct acpi_device *device, int *state_p)
+ {
+diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
+index 814d5f83b75e..f03677588b9d 100644
+--- a/drivers/acpi/osl.c
++++ b/drivers/acpi/osl.c
+@@ -135,7 +135,7 @@ static struct osi_linux {
+ 	unsigned int	enable:1;
+ 	unsigned int	dmi:1;
+ 	unsigned int	cmdline:1;
+-	unsigned int	default_disabling:1;
++	u8		default_disabling;
+ } osi_linux = {0, 0, 0, 0};
+ 
+ static u32 acpi_osi_handler(acpi_string interface, u32 supported)
+@@ -1751,10 +1751,13 @@ void __init acpi_osi_setup(char *str)
+ 	if (*str == '!') {
+ 		str++;
+ 		if (*str == '\0') {
+-			osi_linux.default_disabling = 1;
++			/* Do not override acpi_osi=!* */
++			if (!osi_linux.default_disabling)
++				osi_linux.default_disabling =
++					ACPI_DISABLE_ALL_VENDOR_STRINGS;
+ 			return;
+ 		} else if (*str == '*') {
+-			acpi_update_interfaces(ACPI_DISABLE_ALL_STRINGS);
++			osi_linux.default_disabling = ACPI_DISABLE_ALL_STRINGS;
+ 			for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+ 				osi = &osi_setup_entries[i];
+ 				osi->enable = false;
+@@ -1827,10 +1830,13 @@ static void __init acpi_osi_setup_late(void)
+ 	acpi_status status;
+ 
+ 	if (osi_linux.default_disabling) {
+-		status = acpi_update_interfaces(ACPI_DISABLE_ALL_VENDOR_STRINGS);
++		status = acpi_update_interfaces(osi_linux.default_disabling);
+ 
+ 		if (ACPI_SUCCESS(status))
+-			printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors\n");
++			printk(KERN_INFO PREFIX "Disabled all _OSI OS vendors%s\n",
++				osi_linux.default_disabling ==
++				ACPI_DISABLE_ALL_STRINGS ?
++				" and feature groups" : "");
+ 	}
+ 
+ 	for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) {
+diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c
+index 80783dcb7f57..aba31210c802 100644
+--- a/drivers/bluetooth/hci_vhci.c
++++ b/drivers/bluetooth/hci_vhci.c
+@@ -50,6 +50,7 @@ struct vhci_data {
+ 	wait_queue_head_t read_wait;
+ 	struct sk_buff_head readq;
+ 
++	struct mutex open_mutex;
+ 	struct delayed_work open_timeout;
+ };
+ 
+@@ -87,12 +88,15 @@ static int vhci_send_frame(struct hci_dev *hdev, struct sk_buff *skb)
+ 	return 0;
+ }
+ 
+-static int vhci_create_device(struct vhci_data *data, __u8 opcode)
++static int __vhci_create_device(struct vhci_data *data, __u8 opcode)
+ {
+ 	struct hci_dev *hdev;
+ 	struct sk_buff *skb;
+ 	__u8 dev_type;
+ 
++	if (data->hdev)
++		return -EBADFD;
++
+ 	/* bits 0-1 are dev_type (BR/EDR or AMP) */
+ 	dev_type = opcode & 0x03;
+ 
+@@ -151,6 +155,17 @@ static int vhci_create_device(struct vhci_data *data, __u8 opcode)
+ 	return 0;
+ }
+ 
++static int vhci_create_device(struct vhci_data *data, __u8 opcode)
++{
++	int err;
++
++	mutex_lock(&data->open_mutex);
++	err = __vhci_create_device(data, opcode);
++	mutex_unlock(&data->open_mutex);
++
++	return err;
++}
++
+ static inline ssize_t vhci_get_user(struct vhci_data *data,
+ 				    struct iov_iter *from)
+ {
+@@ -189,11 +204,6 @@ static inline ssize_t vhci_get_user(struct vhci_data *data,
+ 		break;
+ 
+ 	case HCI_VENDOR_PKT:
+-		if (data->hdev) {
+-			kfree_skb(skb);
+-			return -EBADFD;
+-		}
+-
+ 		cancel_delayed_work_sync(&data->open_timeout);
+ 
+ 		opcode = *((__u8 *) skb->data);
+@@ -320,6 +330,7 @@ static int vhci_open(struct inode *inode, struct file *file)
+ 	skb_queue_head_init(&data->readq);
+ 	init_waitqueue_head(&data->read_wait);
+ 
++	mutex_init(&data->open_mutex);
+ 	INIT_DELAYED_WORK(&data->open_timeout, vhci_open_timeout);
+ 
+ 	file->private_data = data;
+@@ -333,15 +344,18 @@ static int vhci_open(struct inode *inode, struct file *file)
+ static int vhci_release(struct inode *inode, struct file *file)
+ {
+ 	struct vhci_data *data = file->private_data;
+-	struct hci_dev *hdev = data->hdev;
++	struct hci_dev *hdev;
+ 
+ 	cancel_delayed_work_sync(&data->open_timeout);
+ 
++	hdev = data->hdev;
++
+ 	if (hdev) {
+ 		hci_unregister_dev(hdev);
+ 		hci_free_dev(hdev);
+ 	}
+ 
++	skb_queue_purge(&data->readq);
+ 	file->private_data = NULL;
+ 	kfree(data);
+ 
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index c74ed3fd496d..90338c38e38a 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -1079,10 +1079,12 @@ static void bcm2835_pll_divider_off(struct clk_hw *hw)
+ 	struct bcm2835_cprman *cprman = divider->cprman;
+ 	const struct bcm2835_pll_divider_data *data = divider->data;
+ 
++	spin_lock(&cprman->regs_lock);
+ 	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);
++	spin_unlock(&cprman->regs_lock);
+ }
+ 
+ static int bcm2835_pll_divider_on(struct clk_hw *hw)
+@@ -1091,12 +1093,14 @@ static int bcm2835_pll_divider_on(struct clk_hw *hw)
+ 	struct bcm2835_cprman *cprman = divider->cprman;
+ 	const struct bcm2835_pll_divider_data *data = divider->data;
+ 
++	spin_lock(&cprman->regs_lock);
+ 	cprman_write(cprman, data->a2w_reg,
+ 		     cprman_read(cprman, data->a2w_reg) &
+ 		     ~A2W_PLL_CHANNEL_DISABLE);
+ 
+ 	cprman_write(cprman, data->cm_reg,
+ 		     cprman_read(cprman, data->cm_reg) & ~data->hold_mask);
++	spin_unlock(&cprman->regs_lock);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/clk/qcom/gcc-msm8916.c b/drivers/clk/qcom/gcc-msm8916.c
+index 9c29080a84d8..5c4e193164d4 100644
+--- a/drivers/clk/qcom/gcc-msm8916.c
++++ b/drivers/clk/qcom/gcc-msm8916.c
+@@ -2346,6 +2346,7 @@ static struct clk_branch gcc_crypto_ahb_clk = {
+ 				"pcnoc_bfdcd_clk_src",
+ 			},
+ 			.num_parents = 1,
++			.flags = CLK_SET_RATE_PARENT,
+ 			.ops = &clk_branch2_ops,
+ 		},
+ 	},
+@@ -2381,6 +2382,7 @@ static struct clk_branch gcc_crypto_clk = {
+ 				"crypto_clk_src",
+ 			},
+ 			.num_parents = 1,
++			.flags = CLK_SET_RATE_PARENT,
+ 			.ops = &clk_branch2_ops,
+ 		},
+ 	},
+diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
+index 6fd63a600614..5ef4be22eb80 100644
+--- a/drivers/crypto/caam/jr.c
++++ b/drivers/crypto/caam/jr.c
+@@ -248,7 +248,7 @@ static void caam_jr_dequeue(unsigned long devarg)
+ struct device *caam_jr_alloc(void)
+ {
+ 	struct caam_drv_private_jr *jrpriv, *min_jrpriv = NULL;
+-	struct device *dev = NULL;
++	struct device *dev = ERR_PTR(-ENODEV);
+ 	int min_tfm_cnt	= INT_MAX;
+ 	int tfm_cnt;
+ 
+diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+index 7be3fbcd8d78..3830d7c4e138 100644
+--- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
++++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
+@@ -35,6 +35,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
+ 	unsigned int todo;
+ 	struct sg_mapping_iter mi, mo;
+ 	unsigned int oi, oo; /* offset for in and out */
++	unsigned long flags;
+ 
+ 	if (areq->nbytes == 0)
+ 		return 0;
+@@ -49,7 +50,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq)
+ 		return -EINVAL;
+ 	}
+ 
+-	spin_lock_bh(&ss->slock);
++	spin_lock_irqsave(&ss->slock, flags);
+ 
+ 	for (i = 0; i < op->keylen; i += 4)
+ 		writel(*(op->key + i / 4), ss->base + SS_KEY0 + i);
+@@ -117,7 +118,7 @@ release_ss:
+ 	sg_miter_stop(&mi);
+ 	sg_miter_stop(&mo);
+ 	writel(0, ss->base + SS_CTL);
+-	spin_unlock_bh(&ss->slock);
++	spin_unlock_irqrestore(&ss->slock, flags);
+ 	return err;
+ }
+ 
+@@ -149,6 +150,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
+ 	unsigned int ob = 0;	/* offset in buf */
+ 	unsigned int obo = 0;	/* offset in bufo*/
+ 	unsigned int obl = 0;	/* length of data in bufo */
++	unsigned long flags;
+ 
+ 	if (areq->nbytes == 0)
+ 		return 0;
+@@ -181,7 +183,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq)
+ 	if (no_chunk == 1)
+ 		return sun4i_ss_opti_poll(areq);
+ 
+-	spin_lock_bh(&ss->slock);
++	spin_lock_irqsave(&ss->slock, flags);
+ 
+ 	for (i = 0; i < op->keylen; i += 4)
+ 		writel(*(op->key + i / 4), ss->base + SS_KEY0 + i);
+@@ -307,7 +309,7 @@ release_ss:
+ 	sg_miter_stop(&mi);
+ 	sg_miter_stop(&mo);
+ 	writel(0, ss->base + SS_CTL);
+-	spin_unlock_bh(&ss->slock);
++	spin_unlock_irqrestore(&ss->slock, flags);
+ 
+ 	return err;
+ }
+diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
+index aae05547b924..b7ee8d30147d 100644
+--- a/drivers/crypto/talitos.c
++++ b/drivers/crypto/talitos.c
+@@ -835,6 +835,16 @@ struct talitos_ahash_req_ctx {
+ 	struct scatterlist *psrc;
+ };
+ 
++struct talitos_export_state {
++	u32 hw_context[TALITOS_MDEU_MAX_CONTEXT_SIZE / sizeof(u32)];
++	u8 buf[HASH_MAX_BLOCK_SIZE];
++	unsigned int swinit;
++	unsigned int first;
++	unsigned int last;
++	unsigned int to_hash_later;
++	unsigned int nbuf;
++};
++
+ static int aead_setkey(struct crypto_aead *authenc,
+ 		       const u8 *key, unsigned int keylen)
+ {
+@@ -1981,6 +1991,46 @@ static int ahash_digest(struct ahash_request *areq)
+ 	return ahash_process_req(areq, areq->nbytes);
+ }
+ 
++static int ahash_export(struct ahash_request *areq, void *out)
++{
++	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
++	struct talitos_export_state *export = out;
++
++	memcpy(export->hw_context, req_ctx->hw_context,
++	       req_ctx->hw_context_size);
++	memcpy(export->buf, req_ctx->buf, req_ctx->nbuf);
++	export->swinit = req_ctx->swinit;
++	export->first = req_ctx->first;
++	export->last = req_ctx->last;
++	export->to_hash_later = req_ctx->to_hash_later;
++	export->nbuf = req_ctx->nbuf;
++
++	return 0;
++}
++
++static int ahash_import(struct ahash_request *areq, const void *in)
++{
++	struct talitos_ahash_req_ctx *req_ctx = ahash_request_ctx(areq);
++	struct crypto_ahash *tfm = crypto_ahash_reqtfm(areq);
++	const struct talitos_export_state *export = in;
++
++	memset(req_ctx, 0, sizeof(*req_ctx));
++	req_ctx->hw_context_size =
++		(crypto_ahash_digestsize(tfm) <= SHA256_DIGEST_SIZE)
++			? TALITOS_MDEU_CONTEXT_SIZE_MD5_SHA1_SHA256
++			: TALITOS_MDEU_CONTEXT_SIZE_SHA384_SHA512;
++	memcpy(req_ctx->hw_context, export->hw_context,
++	       req_ctx->hw_context_size);
++	memcpy(req_ctx->buf, export->buf, export->nbuf);
++	req_ctx->swinit = export->swinit;
++	req_ctx->first = export->first;
++	req_ctx->last = export->last;
++	req_ctx->to_hash_later = export->to_hash_later;
++	req_ctx->nbuf = export->nbuf;
++
++	return 0;
++}
++
+ struct keyhash_result {
+ 	struct completion completion;
+ 	int err;
+@@ -2458,6 +2508,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = MD5_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "md5",
+ 				.cra_driver_name = "md5-talitos",
+@@ -2473,6 +2524,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA1_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "sha1",
+ 				.cra_driver_name = "sha1-talitos",
+@@ -2488,6 +2540,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA224_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "sha224",
+ 				.cra_driver_name = "sha224-talitos",
+@@ -2503,6 +2556,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA256_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "sha256",
+ 				.cra_driver_name = "sha256-talitos",
+@@ -2518,6 +2572,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA384_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "sha384",
+ 				.cra_driver_name = "sha384-talitos",
+@@ -2533,6 +2588,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA512_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "sha512",
+ 				.cra_driver_name = "sha512-talitos",
+@@ -2548,6 +2604,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = MD5_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(md5)",
+ 				.cra_driver_name = "hmac-md5-talitos",
+@@ -2563,6 +2620,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA1_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(sha1)",
+ 				.cra_driver_name = "hmac-sha1-talitos",
+@@ -2578,6 +2636,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA224_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(sha224)",
+ 				.cra_driver_name = "hmac-sha224-talitos",
+@@ -2593,6 +2652,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA256_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(sha256)",
+ 				.cra_driver_name = "hmac-sha256-talitos",
+@@ -2608,6 +2668,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA384_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(sha384)",
+ 				.cra_driver_name = "hmac-sha384-talitos",
+@@ -2623,6 +2684,7 @@ static struct talitos_alg_template driver_algs[] = {
+ 	{	.type = CRYPTO_ALG_TYPE_AHASH,
+ 		.alg.hash = {
+ 			.halg.digestsize = SHA512_DIGEST_SIZE,
++			.halg.statesize = sizeof(struct talitos_export_state),
+ 			.halg.base = {
+ 				.cra_name = "hmac(sha512)",
+ 				.cra_driver_name = "hmac-sha512-talitos",
+@@ -2814,6 +2876,8 @@ static struct talitos_crypto_alg *talitos_alg_alloc(struct device *dev,
+ 		t_alg->algt.alg.hash.finup = ahash_finup;
+ 		t_alg->algt.alg.hash.digest = ahash_digest;
+ 		t_alg->algt.alg.hash.setkey = ahash_setkey;
++		t_alg->algt.alg.hash.import = ahash_import;
++		t_alg->algt.alg.hash.export = ahash_export;
+ 
+ 		if (!(priv->features & TALITOS_FTR_HMAC_OK) &&
+ 		    !strncmp(alg->cra_name, "hmac", 4)) {
+diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
+index b6bf20496021..845ce90c2885 100644
+--- a/drivers/infiniband/ulp/srp/ib_srp.c
++++ b/drivers/infiniband/ulp/srp/ib_srp.c
+@@ -448,16 +448,16 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target)
+ 
+ /**
+  * srp_destroy_qp() - destroy an RDMA queue pair
+- * @ch: SRP RDMA channel.
++ * @qp: RDMA queue pair.
+  *
+  * Drain the qp before destroying it.  This avoids that the receive
+  * completion handler can access the queue pair while it is
+  * being destroyed.
+  */
+-static void srp_destroy_qp(struct srp_rdma_ch *ch)
++static void srp_destroy_qp(struct ib_qp *qp)
+ {
+-	ib_drain_rq(ch->qp);
+-	ib_destroy_qp(ch->qp);
++	ib_drain_rq(qp);
++	ib_destroy_qp(qp);
+ }
+ 
+ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
+@@ -530,7 +530,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
+ 	}
+ 
+ 	if (ch->qp)
+-		srp_destroy_qp(ch);
++		srp_destroy_qp(ch->qp);
+ 	if (ch->recv_cq)
+ 		ib_free_cq(ch->recv_cq);
+ 	if (ch->send_cq)
+@@ -554,7 +554,7 @@ static int srp_create_ch_ib(struct srp_rdma_ch *ch)
+ 	return 0;
+ 
+ err_qp:
+-	srp_destroy_qp(ch);
++	srp_destroy_qp(qp);
+ 
+ err_send_cq:
+ 	ib_free_cq(send_cq);
+@@ -597,7 +597,7 @@ static void srp_free_ch_ib(struct srp_target_port *target,
+ 			ib_destroy_fmr_pool(ch->fmr_pool);
+ 	}
+ 
+-	srp_destroy_qp(ch);
++	srp_destroy_qp(ch->qp);
+ 	ib_free_cq(ch->send_cq);
+ 	ib_free_cq(ch->recv_cq);
+ 
+@@ -1509,7 +1509,7 @@ static int srp_map_idb(struct srp_rdma_ch *ch, struct srp_request *req,
+ 
+ 	if (dev->use_fast_reg) {
+ 		state.sg = idb_sg;
+-		sg_set_buf(idb_sg, req->indirect_desc, idb_len);
++		sg_init_one(idb_sg, req->indirect_desc, idb_len);
+ 		idb_sg->dma_address = req->indirect_dma_addr; /* hack! */
+ #ifdef CONFIG_NEED_SG_DMA_LENGTH
+ 		idb_sg->dma_length = idb_sg->length;	      /* hack^2 */
+diff --git a/drivers/input/misc/pwm-beeper.c b/drivers/input/misc/pwm-beeper.c
+index f2261ab54701..18663d4edae5 100644
+--- a/drivers/input/misc/pwm-beeper.c
++++ b/drivers/input/misc/pwm-beeper.c
+@@ -20,21 +20,40 @@
+ #include <linux/platform_device.h>
+ #include <linux/pwm.h>
+ #include <linux/slab.h>
++#include <linux/workqueue.h>
+ 
+ struct pwm_beeper {
+ 	struct input_dev *input;
+ 	struct pwm_device *pwm;
++	struct work_struct work;
+ 	unsigned long period;
+ };
+ 
+ #define HZ_TO_NANOSECONDS(x) (1000000000UL/(x))
+ 
++static void __pwm_beeper_set(struct pwm_beeper *beeper)
++{
++	unsigned long period = beeper->period;
++
++	if (period) {
++		pwm_config(beeper->pwm, period / 2, period);
++		pwm_enable(beeper->pwm);
++	} else
++		pwm_disable(beeper->pwm);
++}
++
++static void pwm_beeper_work(struct work_struct *work)
++{
++	struct pwm_beeper *beeper =
++		container_of(work, struct pwm_beeper, work);
++
++	__pwm_beeper_set(beeper);
++}
++
+ static int pwm_beeper_event(struct input_dev *input,
+ 			    unsigned int type, unsigned int code, int value)
+ {
+-	int ret = 0;
+ 	struct pwm_beeper *beeper = input_get_drvdata(input);
+-	unsigned long period;
+ 
+ 	if (type != EV_SND || value < 0)
+ 		return -EINVAL;
+@@ -49,22 +68,31 @@ static int pwm_beeper_event(struct input_dev *input,
+ 		return -EINVAL;
+ 	}
+ 
+-	if (value == 0) {
+-		pwm_disable(beeper->pwm);
+-	} else {
+-		period = HZ_TO_NANOSECONDS(value);
+-		ret = pwm_config(beeper->pwm, period / 2, period);
+-		if (ret)
+-			return ret;
+-		ret = pwm_enable(beeper->pwm);
+-		if (ret)
+-			return ret;
+-		beeper->period = period;
+-	}
++	if (value == 0)
++		beeper->period = 0;
++	else
++		beeper->period = HZ_TO_NANOSECONDS(value);
++
++	schedule_work(&beeper->work);
+ 
+ 	return 0;
+ }
+ 
++static void pwm_beeper_stop(struct pwm_beeper *beeper)
++{
++	cancel_work_sync(&beeper->work);
++
++	if (beeper->period)
++		pwm_disable(beeper->pwm);
++}
++
++static void pwm_beeper_close(struct input_dev *input)
++{
++	struct pwm_beeper *beeper = input_get_drvdata(input);
++
++	pwm_beeper_stop(beeper);
++}
++
+ static int pwm_beeper_probe(struct platform_device *pdev)
+ {
+ 	unsigned long pwm_id = (unsigned long)dev_get_platdata(&pdev->dev);
+@@ -87,6 +115,8 @@ static int pwm_beeper_probe(struct platform_device *pdev)
+ 		goto err_free;
+ 	}
+ 
++	INIT_WORK(&beeper->work, pwm_beeper_work);
++
+ 	beeper->input = input_allocate_device();
+ 	if (!beeper->input) {
+ 		dev_err(&pdev->dev, "Failed to allocate input device\n");
+@@ -106,6 +136,7 @@ static int pwm_beeper_probe(struct platform_device *pdev)
+ 	beeper->input->sndbit[0] = BIT(SND_TONE) | BIT(SND_BELL);
+ 
+ 	beeper->input->event = pwm_beeper_event;
++	beeper->input->close = pwm_beeper_close;
+ 
+ 	input_set_drvdata(beeper->input, beeper);
+ 
+@@ -135,7 +166,6 @@ static int pwm_beeper_remove(struct platform_device *pdev)
+ 
+ 	input_unregister_device(beeper->input);
+ 
+-	pwm_disable(beeper->pwm);
+ 	pwm_free(beeper->pwm);
+ 
+ 	kfree(beeper);
+@@ -147,8 +177,7 @@ static int __maybe_unused pwm_beeper_suspend(struct device *dev)
+ {
+ 	struct pwm_beeper *beeper = dev_get_drvdata(dev);
+ 
+-	if (beeper->period)
+-		pwm_disable(beeper->pwm);
++	pwm_beeper_stop(beeper);
+ 
+ 	return 0;
+ }
+@@ -157,10 +186,8 @@ static int __maybe_unused pwm_beeper_resume(struct device *dev)
+ {
+ 	struct pwm_beeper *beeper = dev_get_drvdata(dev);
+ 
+-	if (beeper->period) {
+-		pwm_config(beeper->pwm, beeper->period / 2, beeper->period);
+-		pwm_enable(beeper->pwm);
+-	}
++	if (beeper->period)
++		__pwm_beeper_set(beeper);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
+index 5b7d3c2129d8..390e0ece26dc 100644
+--- a/drivers/irqchip/irq-gic-v3.c
++++ b/drivers/irqchip/irq-gic-v3.c
+@@ -364,6 +364,13 @@ static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs
+ 			if (static_key_true(&supports_deactivate))
+ 				gic_write_dir(irqnr);
+ #ifdef CONFIG_SMP
++			/*
++			 * Unlike GICv2, we don't need an smp_rmb() here.
++			 * The control dependency from gic_read_iar to
++			 * the ISB in gic_write_eoir is enough to ensure
++			 * that any shared data read by handle_IPI will
++			 * be read after the ACK.
++			 */
+ 			handle_IPI(irqnr, regs);
+ #else
+ 			WARN_ONCE(true, "Unexpected SGI received!\n");
+@@ -383,6 +390,15 @@ static void __init gic_dist_init(void)
+ 	writel_relaxed(0, base + GICD_CTLR);
+ 	gic_dist_wait_for_rwp();
+ 
++	/*
++	 * Configure SPIs as non-secure Group-1. This will only matter
++	 * if the GIC only has a single security state. This will not
++	 * do the right thing if the kernel is running in secure mode,
++	 * but that's not the intended use case anyway.
++	 */
++	for (i = 32; i < gic_data.irq_nr; i += 32)
++		writel_relaxed(~0, base + GICD_IGROUPR + i / 8);
++
+ 	gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp);
+ 
+ 	/* Enable distributor with ARE, Group1 */
+@@ -500,6 +516,9 @@ static void gic_cpu_init(void)
+ 
+ 	rbase = gic_data_rdist_sgi_base();
+ 
++	/* Configure SGIs/PPIs as non-secure Group-1 */
++	writel_relaxed(~0, rbase + GICR_IGROUPR0);
++
+ 	gic_cpu_config(rbase, gic_redist_wait_for_rwp);
+ 
+ 	/* Give LPIs a spin */
+diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
+index 282344b95ec2..5c4da5808b15 100644
+--- a/drivers/irqchip/irq-gic.c
++++ b/drivers/irqchip/irq-gic.c
+@@ -344,6 +344,14 @@ static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
+ 			if (static_key_true(&supports_deactivate))
+ 				writel_relaxed(irqstat, cpu_base + GIC_CPU_DEACTIVATE);
+ #ifdef CONFIG_SMP
++			/*
++			 * Ensure any shared data written by the CPU sending
++			 * the IPI is read after we've read the ACK register
++			 * on the GIC.
++			 *
++			 * Pairs with the write barrier in gic_raise_softirq
++			 */
++			smp_rmb();
+ 			handle_IPI(irqnr, regs);
+ #endif
+ 			continue;
+diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
+index 004926955263..b0155b05cddb 100644
+--- a/drivers/mcb/mcb-parse.c
++++ b/drivers/mcb/mcb-parse.c
+@@ -57,7 +57,7 @@ static int chameleon_parse_gdd(struct mcb_bus *bus,
+ 	mdev->id = GDD_DEV(reg1);
+ 	mdev->rev = GDD_REV(reg1);
+ 	mdev->var = GDD_VAR(reg1);
+-	mdev->bar = GDD_BAR(reg1);
++	mdev->bar = GDD_BAR(reg2);
+ 	mdev->group = GDD_GRP(reg2);
+ 	mdev->inst = GDD_INS(reg2);
+ 
+diff --git a/drivers/md/md.c b/drivers/md/md.c
+index 14d3b37944df..85b16aadd459 100644
+--- a/drivers/md/md.c
++++ b/drivers/md/md.c
+@@ -307,7 +307,7 @@ static blk_qc_t md_make_request(struct request_queue *q, struct bio *bio)
+  */
+ void mddev_suspend(struct mddev *mddev)
+ {
+-	WARN_ON_ONCE(current == mddev->thread->tsk);
++	WARN_ON_ONCE(mddev->thread && current == mddev->thread->tsk);
+ 	if (mddev->suspended++)
+ 		return;
+ 	synchronize_rcu();
+diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
+index b7b3e8ee64f2..c30290f33430 100644
+--- a/drivers/mfd/omap-usb-tll.c
++++ b/drivers/mfd/omap-usb-tll.c
+@@ -269,6 +269,8 @@ static int usbtll_omap_probe(struct platform_device *pdev)
+ 
+ 		if (IS_ERR(tll->ch_clk[i]))
+ 			dev_dbg(dev, "can't get clock : %s\n", clkname);
++		else
++			clk_prepare(tll->ch_clk[i]);
+ 	}
+ 
+ 	pm_runtime_put_sync(dev);
+@@ -301,9 +303,12 @@ static int usbtll_omap_remove(struct platform_device *pdev)
+ 	tll_dev = NULL;
+ 	spin_unlock(&tll_lock);
+ 
+-	for (i = 0; i < tll->nch; i++)
+-		if (!IS_ERR(tll->ch_clk[i]))
++	for (i = 0; i < tll->nch; i++) {
++		if (!IS_ERR(tll->ch_clk[i])) {
++			clk_unprepare(tll->ch_clk[i]);
+ 			clk_put(tll->ch_clk[i]);
++		}
++	}
+ 
+ 	pm_runtime_disable(&pdev->dev);
+ 	return 0;
+@@ -420,7 +425,7 @@ int omap_tll_enable(struct usbhs_omap_platform_data *pdata)
+ 			if (IS_ERR(tll->ch_clk[i]))
+ 				continue;
+ 
+-			r = clk_prepare_enable(tll->ch_clk[i]);
++			r = clk_enable(tll->ch_clk[i]);
+ 			if (r) {
+ 				dev_err(tll_dev,
+ 				 "Error enabling ch %d clock: %d\n", i, r);
+@@ -448,7 +453,7 @@ int omap_tll_disable(struct usbhs_omap_platform_data *pdata)
+ 	for (i = 0; i < tll->nch; i++) {
+ 		if (omap_usb_mode_needs_tll(pdata->port_mode[i])) {
+ 			if (!IS_ERR(tll->ch_clk[i]))
+-				clk_disable_unprepare(tll->ch_clk[i]);
++				clk_disable(tll->ch_clk[i]);
+ 		}
+ 	}
+ 
+diff --git a/drivers/misc/mei/amthif.c b/drivers/misc/mei/amthif.c
+index 194360a5f782..a039a5df6f21 100644
+--- a/drivers/misc/mei/amthif.c
++++ b/drivers/misc/mei/amthif.c
+@@ -380,8 +380,10 @@ int mei_amthif_irq_read_msg(struct mei_cl *cl,
+ 
+ 	dev = cl->dev;
+ 
+-	if (dev->iamthif_state != MEI_IAMTHIF_READING)
++	if (dev->iamthif_state != MEI_IAMTHIF_READING) {
++		mei_irq_discard_msg(dev, mei_hdr);
+ 		return 0;
++	}
+ 
+ 	ret = mei_cl_irq_read_msg(cl, mei_hdr, cmpl_list);
+ 	if (ret)
+diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c
+index 5d5996e39a67..038b6dd24fb4 100644
+--- a/drivers/misc/mei/bus.c
++++ b/drivers/misc/mei/bus.c
+@@ -220,17 +220,23 @@ EXPORT_SYMBOL_GPL(mei_cldev_recv);
+ static void mei_cl_bus_event_work(struct work_struct *work)
+ {
+ 	struct mei_cl_device *cldev;
++	struct mei_device *bus;
+ 
+ 	cldev = container_of(work, struct mei_cl_device, event_work);
+ 
++	bus = cldev->bus;
++
+ 	if (cldev->event_cb)
+ 		cldev->event_cb(cldev, cldev->events, cldev->event_context);
+ 
+ 	cldev->events = 0;
+ 
+ 	/* Prepare for the next read */
+-	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX))
++	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
++		mutex_lock(&bus->device_lock);
+ 		mei_cl_read_start(cldev->cl, 0, NULL);
++		mutex_unlock(&bus->device_lock);
++	}
+ }
+ 
+ /**
+@@ -304,6 +310,7 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
+ 				unsigned long events_mask,
+ 				mei_cldev_event_cb_t event_cb, void *context)
+ {
++	struct mei_device *bus = cldev->bus;
+ 	int ret;
+ 
+ 	if (cldev->event_cb)
+@@ -316,15 +323,17 @@ int mei_cldev_register_event_cb(struct mei_cl_device *cldev,
+ 	INIT_WORK(&cldev->event_work, mei_cl_bus_event_work);
+ 
+ 	if (cldev->events_mask & BIT(MEI_CL_EVENT_RX)) {
++		mutex_lock(&bus->device_lock);
+ 		ret = mei_cl_read_start(cldev->cl, 0, NULL);
++		mutex_unlock(&bus->device_lock);
+ 		if (ret && ret != -EBUSY)
+ 			return ret;
+ 	}
+ 
+ 	if (cldev->events_mask & BIT(MEI_CL_EVENT_NOTIF)) {
+-		mutex_lock(&cldev->cl->dev->device_lock);
++		mutex_lock(&bus->device_lock);
+ 		ret = mei_cl_notify_request(cldev->cl, NULL, event_cb ? 1 : 0);
+-		mutex_unlock(&cldev->cl->dev->device_lock);
++		mutex_unlock(&bus->device_lock);
+ 		if (ret)
+ 			return ret;
+ 	}
+diff --git a/drivers/misc/mei/client.c b/drivers/misc/mei/client.c
+index bab17e4197b6..09f5280fa021 100644
+--- a/drivers/misc/mei/client.c
++++ b/drivers/misc/mei/client.c
+@@ -1767,6 +1767,10 @@ void mei_cl_complete(struct mei_cl *cl, struct mei_cl_cb *cb)
+ 			wake_up(&cl->wait);
+ 
+ 		break;
++	case MEI_FOP_DISCONNECT_RSP:
++		mei_io_cb_free(cb);
++		mei_cl_set_disconnected(cl);
++		break;
+ 	default:
+ 		BUG_ON(0);
+ 	}
+diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c
+index 5e305d2605f3..8fe1ef8215c1 100644
+--- a/drivers/misc/mei/hbm.c
++++ b/drivers/misc/mei/hbm.c
+@@ -882,8 +882,7 @@ static int mei_hbm_fw_disconnect_req(struct mei_device *dev,
+ 		cb = mei_io_cb_init(cl, MEI_FOP_DISCONNECT_RSP, NULL);
+ 		if (!cb)
+ 			return -ENOMEM;
+-		cl_dbg(dev, cl, "add disconnect response as first\n");
+-		list_add(&cb->list, &dev->ctrl_wr_list.list);
++		list_add_tail(&cb->list, &dev->ctrl_wr_list.list);
+ 	}
+ 	return 0;
+ }
+diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
+index 1e5cb1f704f8..3831a7ba2531 100644
+--- a/drivers/misc/mei/interrupt.c
++++ b/drivers/misc/mei/interrupt.c
+@@ -76,7 +76,6 @@ static inline int mei_cl_hbm_equal(struct mei_cl *cl,
+  * @dev: mei device
+  * @hdr: message header
+  */
+-static inline
+ void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr)
+ {
+ 	/*
+@@ -194,10 +193,7 @@ static int mei_cl_irq_disconnect_rsp(struct mei_cl *cl, struct mei_cl_cb *cb,
+ 		return -EMSGSIZE;
+ 
+ 	ret = mei_hbm_cl_disconnect_rsp(dev, cl);
+-	mei_cl_set_disconnected(cl);
+-	mei_io_cb_free(cb);
+-	mei_me_cl_put(cl->me_cl);
+-	cl->me_cl = NULL;
++	list_move_tail(&cb->list, &cmpl_list->list);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/misc/mei/mei_dev.h b/drivers/misc/mei/mei_dev.h
+index db78e6d99456..859bdac22352 100644
+--- a/drivers/misc/mei/mei_dev.h
++++ b/drivers/misc/mei/mei_dev.h
+@@ -704,6 +704,8 @@ bool mei_hbuf_acquire(struct mei_device *dev);
+ 
+ bool mei_write_is_idle(struct mei_device *dev);
+ 
++void mei_irq_discard_msg(struct mei_device *dev, struct mei_msg_hdr *hdr);
++
+ #if IS_ENABLED(CONFIG_DEBUG_FS)
+ int mei_dbgfs_register(struct mei_device *dev, const char *name);
+ void mei_dbgfs_deregister(struct mei_device *dev);
+diff --git a/drivers/misc/mic/vop/vop_vringh.c b/drivers/misc/mic/vop/vop_vringh.c
+index 88e45234d527..af57d2caac75 100644
+--- a/drivers/misc/mic/vop/vop_vringh.c
++++ b/drivers/misc/mic/vop/vop_vringh.c
+@@ -950,6 +950,11 @@ static long vop_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ 			ret = -EINVAL;
+ 			goto free_ret;
+ 		}
++		/* Ensure desc has not changed between the two reads */
++		if (memcmp(&dd, dd_config, sizeof(dd))) {
++			ret = -EINVAL;
++			goto free_ret;
++		}
+ 		mutex_lock(&vdev->vdev_mutex);
+ 		mutex_lock(&vi->vop_mutex);
+ 		ret = vop_virtio_add_device(vdev, dd_config);
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index 8a0147dfed27..b0a27413cb13 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -2494,11 +2494,12 @@ static const struct mmc_fixup blk_fixups[] =
+ 		  MMC_QUIRK_BLK_NO_CMD23),
+ 
+ 	/*
+-	 * Some Micron MMC cards needs longer data read timeout than
+-	 * indicated in CSD.
++	 * Some MMC cards need longer data read timeout than indicated in CSD.
+ 	 */
+ 	MMC_FIXUP(CID_NAME_ANY, CID_MANFID_MICRON, 0x200, add_quirk_mmc,
+ 		  MMC_QUIRK_LONG_READ_TIME),
++	MMC_FIXUP("008GE0", CID_MANFID_TOSHIBA, CID_OEMID_ANY, add_quirk_mmc,
++		  MMC_QUIRK_LONG_READ_TIME),
+ 
+ 	/*
+ 	 * On these Samsung MoviNAND parts, performing secure erase or
+diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
+index 41b1e761965f..9eba56c68ca1 100644
+--- a/drivers/mmc/core/core.c
++++ b/drivers/mmc/core/core.c
+@@ -868,11 +868,11 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
+ 	/*
+ 	 * Some cards require longer data read timeout than indicated in CSD.
+ 	 * Address this by setting the read timeout to a "reasonably high"
+-	 * value. For the cards tested, 300ms has proven enough. If necessary,
++	 * value. For the cards tested, 600ms has proven enough. If necessary,
+ 	 * this value can be increased if other problematic cards require this.
+ 	 */
+ 	if (mmc_card_long_read_time(card) && data->flags & MMC_DATA_READ) {
+-		data->timeout_ns = 300000000;
++		data->timeout_ns = 600000000;
+ 		data->timeout_clks = 0;
+ 	}
+ 
+diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
+index 4dbe3df8024b..80169643d59f 100644
+--- a/drivers/mmc/core/mmc.c
++++ b/drivers/mmc/core/mmc.c
+@@ -333,6 +333,9 @@ static void mmc_manage_gp_partitions(struct mmc_card *card, u8 *ext_csd)
+ 	}
+ }
+ 
++/* Minimum partition switch timeout in milliseconds */
++#define MMC_MIN_PART_SWITCH_TIME	300
++
+ /*
+  * Decode extended CSD.
+  */
+@@ -397,6 +400,10 @@ static int mmc_decode_ext_csd(struct mmc_card *card, u8 *ext_csd)
+ 
+ 		/* EXT_CSD value is in units of 10ms, but we store in ms */
+ 		card->ext_csd.part_time = 10 * ext_csd[EXT_CSD_PART_SWITCH_TIME];
++		/* Some eMMC set the value too low so set a minimum */
++		if (card->ext_csd.part_time &&
++		    card->ext_csd.part_time < MMC_MIN_PART_SWITCH_TIME)
++			card->ext_csd.part_time = MMC_MIN_PART_SWITCH_TIME;
+ 
+ 		/* Sleep / awake timeout in 100ns units */
+ 		if (sa_shift > 0 && sa_shift <= 0x17)
+diff --git a/drivers/mmc/host/sdhci-acpi.c b/drivers/mmc/host/sdhci-acpi.c
+index bed6a494f52c..c0e206d72153 100644
+--- a/drivers/mmc/host/sdhci-acpi.c
++++ b/drivers/mmc/host/sdhci-acpi.c
+@@ -277,7 +277,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_emmc = {
+ 	.chip    = &sdhci_acpi_chip_int,
+ 	.caps    = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
+ 		   MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
+-		   MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
++		   MMC_CAP_WAIT_WHILE_BUSY,
+ 	.caps2   = MMC_CAP2_HC_ERASE_SZ,
+ 	.flags   = SDHCI_ACPI_RUNTIME_PM,
+ 	.quirks  = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+@@ -292,7 +292,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sdio = {
+ 		   SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+ 	.quirks2 = SDHCI_QUIRK2_HOST_OFF_CARD_ON,
+ 	.caps    = MMC_CAP_NONREMOVABLE | MMC_CAP_POWER_OFF_CARD |
+-		   MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
++		   MMC_CAP_WAIT_WHILE_BUSY,
+ 	.flags   = SDHCI_ACPI_RUNTIME_PM,
+ 	.pm_caps = MMC_PM_KEEP_POWER,
+ 	.probe_slot	= sdhci_acpi_sdio_probe_slot,
+@@ -304,7 +304,7 @@ static const struct sdhci_acpi_slot sdhci_acpi_slot_int_sd = {
+ 	.quirks  = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+ 	.quirks2 = SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON |
+ 		   SDHCI_QUIRK2_STOP_WITH_TC,
+-	.caps    = MMC_CAP_BUS_WIDTH_TEST | MMC_CAP_WAIT_WHILE_BUSY,
++	.caps    = MMC_CAP_WAIT_WHILE_BUSY,
+ 	.probe_slot	= sdhci_acpi_sd_probe_slot,
+ };
+ 
+@@ -381,7 +381,7 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
+ {
+ 	struct device *dev = &pdev->dev;
+ 	acpi_handle handle = ACPI_HANDLE(dev);
+-	struct acpi_device *device;
++	struct acpi_device *device, *child;
+ 	struct sdhci_acpi_host *c;
+ 	struct sdhci_host *host;
+ 	struct resource *iomem;
+@@ -393,6 +393,11 @@ static int sdhci_acpi_probe(struct platform_device *pdev)
+ 	if (acpi_bus_get_device(handle, &device))
+ 		return -ENODEV;
+ 
++	/* Power on the SDHCI controller and its children */
++	acpi_device_fix_up_power(device);
++	list_for_each_entry(child, &device->children, node)
++		acpi_device_fix_up_power(child);
++
+ 	if (acpi_bus_get_status(device) || !device->status.present)
+ 		return -ENODEV;
+ 
+diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c
+index 79e19017343e..b42dd6a1b639 100644
+--- a/drivers/mmc/host/sdhci-pci-core.c
++++ b/drivers/mmc/host/sdhci-pci-core.c
+@@ -361,7 +361,6 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ {
+ 	slot->host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE |
+ 				 MMC_CAP_HW_RESET | MMC_CAP_1_8V_DDR |
+-				 MMC_CAP_BUS_WIDTH_TEST |
+ 				 MMC_CAP_WAIT_WHILE_BUSY;
+ 	slot->host->mmc->caps2 |= MMC_CAP2_HC_ERASE_SZ;
+ 	slot->hw_reset = sdhci_pci_int_hw_reset;
+@@ -377,15 +376,13 @@ static int byt_emmc_probe_slot(struct sdhci_pci_slot *slot)
+ static int byt_sdio_probe_slot(struct sdhci_pci_slot *slot)
+ {
+ 	slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE |
+-				 MMC_CAP_BUS_WIDTH_TEST |
+ 				 MMC_CAP_WAIT_WHILE_BUSY;
+ 	return 0;
+ }
+ 
+ static int byt_sd_probe_slot(struct sdhci_pci_slot *slot)
+ {
+-	slot->host->mmc->caps |= MMC_CAP_BUS_WIDTH_TEST |
+-				 MMC_CAP_WAIT_WHILE_BUSY;
++	slot->host->mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
+ 	slot->cd_con_id = NULL;
+ 	slot->cd_idx = 0;
+ 	slot->cd_override_level = true;
+diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
+index 5b9834cf2820..96fddb016bf1 100644
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -426,8 +426,25 @@ retry:
+ 						 pnum, vol_id, lnum);
+ 					err = -EBADMSG;
+ 				} else {
+-					err = -EINVAL;
+-					ubi_ro_mode(ubi);
++					/*
++					 * Ending up here in the non-Fastmap case
++					 * is a clear bug as the VID header had to
++					 * be present at scan time to have it referenced.
++					 * With fastmap the story is more complicated.
++					 * Fastmap has the mapping info without the need
++					 * of a full scan. So the LEB could have been
++					 * unmapped, Fastmap cannot know this and keeps
++					 * the LEB referenced.
++					 * This is valid and works as the layer above UBI
++					 * has to do bookkeeping about used/referenced
++					 * LEBs in any case.
++					 */
++					if (ubi->fast_attach) {
++						err = -EBADMSG;
++					} else {
++						err = -EINVAL;
++						ubi_ro_mode(ubi);
++					}
+ 				}
+ 			}
+ 			goto out_free;
+diff --git a/drivers/mtd/ubi/fastmap.c b/drivers/mtd/ubi/fastmap.c
+index 263b439e21a8..990898b9dc72 100644
+--- a/drivers/mtd/ubi/fastmap.c
++++ b/drivers/mtd/ubi/fastmap.c
+@@ -1058,6 +1058,7 @@ int ubi_scan_fastmap(struct ubi_device *ubi, struct ubi_attach_info *ai,
+ 	ubi_msg(ubi, "fastmap WL pool size: %d",
+ 		ubi->fm_wl_pool.max_size);
+ 	ubi->fm_disabled = 0;
++	ubi->fast_attach = 1;
+ 
+ 	ubi_free_vid_hdr(ubi, vh);
+ 	kfree(ech);
+diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h
+index dadc6a9d5755..61d4e99755a4 100644
+--- a/drivers/mtd/ubi/ubi.h
++++ b/drivers/mtd/ubi/ubi.h
+@@ -466,6 +466,7 @@ struct ubi_debug_info {
+  * @fm_eba_sem: allows ubi_update_fastmap() to block EBA table changes
+  * @fm_work: fastmap work queue
+  * @fm_work_scheduled: non-zero if fastmap work was scheduled
++ * @fast_attach: non-zero if UBI was attached by fastmap
+  *
+  * @used: RB-tree of used physical eraseblocks
+  * @erroneous: RB-tree of erroneous used physical eraseblocks
+@@ -574,6 +575,7 @@ struct ubi_device {
+ 	size_t fm_size;
+ 	struct work_struct fm_work;
+ 	int fm_work_scheduled;
++	int fast_attach;
+ 
+ 	/* Wear-leveling sub-system's stuff */
+ 	struct rb_root used;
+diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
+index 141c2a42d7ed..910c12e2638e 100644
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -696,11 +696,17 @@ int can_change_mtu(struct net_device *dev, int new_mtu)
+ 	/* allow change of MTU according to the CANFD ability of the device */
+ 	switch (new_mtu) {
+ 	case CAN_MTU:
++		/* 'CANFD-only' controllers can not switch to CAN_MTU */
++		if (priv->ctrlmode_static & CAN_CTRLMODE_FD)
++			return -EINVAL;
++
+ 		priv->ctrlmode &= ~CAN_CTRLMODE_FD;
+ 		break;
+ 
+ 	case CANFD_MTU:
+-		if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD))
++		/* check for potential CANFD ability */
++		if (!(priv->ctrlmode_supported & CAN_CTRLMODE_FD) &&
++		    !(priv->ctrlmode_static & CAN_CTRLMODE_FD))
+ 			return -EINVAL;
+ 
+ 		priv->ctrlmode |= CAN_CTRLMODE_FD;
+@@ -782,6 +788,35 @@ static const struct nla_policy can_policy[IFLA_CAN_MAX + 1] = {
+ 				= { .len = sizeof(struct can_bittiming_const) },
+ };
+ 
++static int can_validate(struct nlattr *tb[], struct nlattr *data[])
++{
++	bool is_can_fd = false;
++
++	/* Make sure that valid CAN FD configurations always consist of
++	 * - nominal/arbitration bittiming
++	 * - data bittiming
++	 * - control mode with CAN_CTRLMODE_FD set
++	 */
++
++	if (data[IFLA_CAN_CTRLMODE]) {
++		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
++
++		is_can_fd = cm->flags & cm->mask & CAN_CTRLMODE_FD;
++	}
++
++	if (is_can_fd) {
++		if (!data[IFLA_CAN_BITTIMING] || !data[IFLA_CAN_DATA_BITTIMING])
++			return -EOPNOTSUPP;
++	}
++
++	if (data[IFLA_CAN_DATA_BITTIMING]) {
++		if (!is_can_fd || !data[IFLA_CAN_BITTIMING])
++			return -EOPNOTSUPP;
++	}
++
++	return 0;
++}
++
+ static int can_changelink(struct net_device *dev,
+ 			  struct nlattr *tb[], struct nlattr *data[])
+ {
+@@ -813,19 +848,31 @@ static int can_changelink(struct net_device *dev,
+ 
+ 	if (data[IFLA_CAN_CTRLMODE]) {
+ 		struct can_ctrlmode *cm;
++		u32 ctrlstatic;
++		u32 maskedflags;
+ 
+ 		/* Do not allow changing controller mode while running */
+ 		if (dev->flags & IFF_UP)
+ 			return -EBUSY;
+ 		cm = nla_data(data[IFLA_CAN_CTRLMODE]);
++		ctrlstatic = priv->ctrlmode_static;
++		maskedflags = cm->flags & cm->mask;
++
++		/* check whether provided bits are allowed to be passed */
++		if (cm->mask & ~(priv->ctrlmode_supported | ctrlstatic))
++			return -EOPNOTSUPP;
++
++		/* do not check for static fd-non-iso if 'fd' is disabled */
++		if (!(maskedflags & CAN_CTRLMODE_FD))
++			ctrlstatic &= ~CAN_CTRLMODE_FD_NON_ISO;
+ 
+-		/* check whether changed bits are allowed to be modified */
+-		if (cm->mask & ~priv->ctrlmode_supported)
++		/* make sure static options are provided by configuration */
++		if ((maskedflags & ctrlstatic) != ctrlstatic)
+ 			return -EOPNOTSUPP;
+ 
+ 		/* clear bits to be modified and copy the flag values */
+ 		priv->ctrlmode &= ~cm->mask;
+-		priv->ctrlmode |= (cm->flags & cm->mask);
++		priv->ctrlmode |= maskedflags;
+ 
+ 		/* CAN_CTRLMODE_FD can only be set when driver supports FD */
+ 		if (priv->ctrlmode & CAN_CTRLMODE_FD)
+@@ -966,6 +1013,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
+ 	.maxtype	= IFLA_CAN_MAX,
+ 	.policy		= can_policy,
+ 	.setup		= can_setup,
++	.validate	= can_validate,
+ 	.newlink	= can_newlink,
+ 	.changelink	= can_changelink,
+ 	.get_size	= can_get_size,
+diff --git a/drivers/net/can/m_can/m_can.c b/drivers/net/can/m_can/m_can.c
+index 39cf911f7a1e..195f15edb32e 100644
+--- a/drivers/net/can/m_can/m_can.c
++++ b/drivers/net/can/m_can/m_can.c
+@@ -955,7 +955,7 @@ static struct net_device *alloc_m_can_dev(void)
+ 	priv->can.do_get_berr_counter = m_can_get_berr_counter;
+ 
+ 	/* CAN_CTRLMODE_FD_NON_ISO is fixed with M_CAN IP v3.0.1 */
+-	priv->can.ctrlmode = CAN_CTRLMODE_FD_NON_ISO;
++	can_set_static_ctrlmode(dev, CAN_CTRLMODE_FD_NON_ISO);
+ 
+ 	/* CAN_CTRLMODE_FD_NON_ISO can not be changed with M_CAN IP v3.0.1 */
+ 	priv->can.ctrlmode_supported = CAN_CTRLMODE_LOOPBACK |
+diff --git a/drivers/net/usb/asix_common.c b/drivers/net/usb/asix_common.c
+index 0c5c22b84da8..7de5ab589e4e 100644
+--- a/drivers/net/usb/asix_common.c
++++ b/drivers/net/usb/asix_common.c
+@@ -66,7 +66,7 @@ int asix_rx_fixup_internal(struct usbnet *dev, struct sk_buff *skb,
+ 	 * buffer.
+ 	 */
+ 	if (rx->remaining && (rx->remaining + sizeof(u32) <= skb->len)) {
+-		offset = ((rx->remaining + 1) & 0xfffe) + sizeof(u32);
++		offset = ((rx->remaining + 1) & 0xfffe);
+ 		rx->header = get_unaligned_le32(skb->data + offset);
+ 		offset = 0;
+ 
+diff --git a/drivers/nfc/st21nfca/i2c.c b/drivers/nfc/st21nfca/i2c.c
+index 1f44a151d206..d5a099b022e4 100644
+--- a/drivers/nfc/st21nfca/i2c.c
++++ b/drivers/nfc/st21nfca/i2c.c
+@@ -524,8 +524,10 @@ static int st21nfca_hci_i2c_acpi_request_resources(struct i2c_client *client)
+ 	/* Get EN GPIO from ACPI */
+ 	gpiod_ena = devm_gpiod_get_index(dev, ST21NFCA_GPIO_NAME_EN, 1,
+ 					 GPIOD_OUT_LOW);
+-	if (!IS_ERR(gpiod_ena))
+-		phy->gpio_ena = desc_to_gpio(gpiod_ena);
++	if (!IS_ERR(gpiod_ena)) {
++		nfc_err(dev, "Unable to get ENABLE GPIO\n");
++		return -ENODEV;
++	}
+ 
+ 	phy->gpio_ena = desc_to_gpio(gpiod_ena);
+ 
+diff --git a/drivers/platform/x86/dell-rbtn.c b/drivers/platform/x86/dell-rbtn.c
+index b51a2008d782..dcd9f40a4b18 100644
+--- a/drivers/platform/x86/dell-rbtn.c
++++ b/drivers/platform/x86/dell-rbtn.c
+@@ -28,6 +28,7 @@ struct rbtn_data {
+ 	enum rbtn_type type;
+ 	struct rfkill *rfkill;
+ 	struct input_dev *input_dev;
++	bool suspended;
+ };
+ 
+ 
+@@ -235,9 +236,55 @@ static const struct acpi_device_id rbtn_ids[] = {
+ 	{ "", 0 },
+ };
+ 
++#ifdef CONFIG_PM_SLEEP
++static void ACPI_SYSTEM_XFACE rbtn_clear_suspended_flag(void *context)
++{
++	struct rbtn_data *rbtn_data = context;
++
++	rbtn_data->suspended = false;
++}
++
++static int rbtn_suspend(struct device *dev)
++{
++	struct acpi_device *device = to_acpi_device(dev);
++	struct rbtn_data *rbtn_data = acpi_driver_data(device);
++
++	rbtn_data->suspended = true;
++
++	return 0;
++}
++
++static int rbtn_resume(struct device *dev)
++{
++	struct acpi_device *device = to_acpi_device(dev);
++	struct rbtn_data *rbtn_data = acpi_driver_data(device);
++	acpi_status status;
++
++	/*
++	 * Upon resume, some BIOSes send an ACPI notification thet triggers
++	 * an unwanted input event. In order to ignore it, we use a flag
++	 * that we set at suspend and clear once we have received the extra
++	 * ACPI notification. Since ACPI notifications are delivered
++	 * asynchronously to drivers, we clear the flag from the workqueue
++	 * used to deliver the notifications. This should be enough
++	 * to have the flag cleared only after we received the extra
++	 * notification, if any.
++	 */
++	status = acpi_os_execute(OSL_NOTIFY_HANDLER,
++			 rbtn_clear_suspended_flag, rbtn_data);
++	if (ACPI_FAILURE(status))
++		rbtn_clear_suspended_flag(rbtn_data);
++
++	return 0;
++}
++#endif
++
++static SIMPLE_DEV_PM_OPS(rbtn_pm_ops, rbtn_suspend, rbtn_resume);
++
+ static struct acpi_driver rbtn_driver = {
+ 	.name = "dell-rbtn",
+ 	.ids = rbtn_ids,
++	.drv.pm = &rbtn_pm_ops,
+ 	.ops = {
+ 		.add = rbtn_add,
+ 		.remove = rbtn_remove,
+@@ -399,6 +446,15 @@ static void rbtn_notify(struct acpi_device *device, u32 event)
+ {
+ 	struct rbtn_data *rbtn_data = device->driver_data;
+ 
++	/*
++	 * Some BIOSes send a notification at resume.
++	 * Ignore it to prevent unwanted input events.
++	 */
++	if (rbtn_data->suspended) {
++		dev_dbg(&device->dev, "ACPI notification ignored\n");
++		return;
++	}
++
+ 	if (event != 0x80) {
+ 		dev_info(&device->dev, "Received unknown event (0x%x)\n",
+ 			 event);
+diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
+index 97074c91e328..6b5811de6519 100644
+--- a/drivers/scsi/scsi_scan.c
++++ b/drivers/scsi/scsi_scan.c
+@@ -316,6 +316,7 @@ static void scsi_target_destroy(struct scsi_target *starget)
+ 	struct Scsi_Host *shost = dev_to_shost(dev->parent);
+ 	unsigned long flags;
+ 
++	BUG_ON(starget->state == STARGET_DEL);
+ 	starget->state = STARGET_DEL;
+ 	transport_destroy_device(dev);
+ 	spin_lock_irqsave(shost->host_lock, flags);
+diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
+index 2b642b145be1..c7e4b5e0bae3 100644
+--- a/drivers/scsi/scsi_sysfs.c
++++ b/drivers/scsi/scsi_sysfs.c
+@@ -1366,18 +1366,18 @@ static void __scsi_remove_target(struct scsi_target *starget)
+ void scsi_remove_target(struct device *dev)
+ {
+ 	struct Scsi_Host *shost = dev_to_shost(dev->parent);
+-	struct scsi_target *starget, *last_target = NULL;
++	struct scsi_target *starget;
+ 	unsigned long flags;
+ 
+ restart:
+ 	spin_lock_irqsave(shost->host_lock, flags);
+ 	list_for_each_entry(starget, &shost->__targets, siblings) {
+ 		if (starget->state == STARGET_DEL ||
+-		    starget == last_target)
++		    starget->state == STARGET_REMOVE)
+ 			continue;
+ 		if (starget->dev.parent == dev || &starget->dev == dev) {
+ 			kref_get(&starget->reap_ref);
+-			last_target = starget;
++			starget->state = STARGET_REMOVE;
+ 			spin_unlock_irqrestore(shost->host_lock, flags);
+ 			__scsi_remove_target(starget);
+ 			scsi_target_reap(starget);
+diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c
+index 940781183fac..3be10963f98b 100644
+--- a/drivers/staging/comedi/drivers/das1800.c
++++ b/drivers/staging/comedi/drivers/das1800.c
+@@ -567,14 +567,17 @@ static int das1800_cancel(struct comedi_device *dev, struct comedi_subdevice *s)
+ 	struct comedi_isadma_desc *desc;
+ 	int i;
+ 
+-	outb(0x0, dev->iobase + DAS1800_STATUS);	/* disable conversions */
+-	outb(0x0, dev->iobase + DAS1800_CONTROL_B);	/* disable interrupts and dma */
+-	outb(0x0, dev->iobase + DAS1800_CONTROL_A);	/* disable and clear fifo and stop triggering */
+-
+-	for (i = 0; i < 2; i++) {
+-		desc = &dma->desc[i];
+-		if (desc->chan)
+-			comedi_isadma_disable(desc->chan);
++	/* disable and stop conversions */
++	outb(0x0, dev->iobase + DAS1800_STATUS);
++	outb(0x0, dev->iobase + DAS1800_CONTROL_B);
++	outb(0x0, dev->iobase + DAS1800_CONTROL_A);
++
++	if (dma) {
++		for (i = 0; i < 2; i++) {
++			desc = &dma->desc[i];
++			if (desc->chan)
++				comedi_isadma_disable(desc->chan);
++		}
+ 	}
+ 
+ 	return 0;
+@@ -934,13 +937,14 @@ static void das1800_ai_setup_dma(struct comedi_device *dev,
+ {
+ 	struct das1800_private *devpriv = dev->private;
+ 	struct comedi_isadma *dma = devpriv->dma;
+-	struct comedi_isadma_desc *desc = &dma->desc[0];
++	struct comedi_isadma_desc *desc;
+ 	unsigned int bytes;
+ 
+ 	if ((devpriv->irq_dma_bits & DMA_ENABLED) == 0)
+ 		return;
+ 
+ 	dma->cur_dma = 0;
++	desc = &dma->desc[0];
+ 
+ 	/* determine a dma transfer size to fill buffer in 0.3 sec */
+ 	bytes = das1800_ai_transfer_size(dev, s, desc->maxsize, 300000000);
+diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c
+index 0dde34e3a7c5..545c60c826a1 100644
+--- a/drivers/thunderbolt/eeprom.c
++++ b/drivers/thunderbolt/eeprom.c
+@@ -444,6 +444,7 @@ int tb_drom_read(struct tb_switch *sw)
+ 	return tb_drom_parse_entries(sw);
+ err:
+ 	kfree(sw->drom);
++	sw->drom = NULL;
+ 	return -EIO;
+ 
+ }
+diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
+index c01620780f5b..365dfd8bc42b 100644
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -2045,7 +2045,9 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm)
+ 		}
+ 	}
+ 	spin_unlock(&gsm_mux_lock);
+-	WARN_ON(i == MAX_MUX);
++	/* open failed before registering => nothing to do */
++	if (i == MAX_MUX)
++		return;
+ 
+ 	/* In theory disconnecting DLCI 0 is sufficient but for some
+ 	   modems this is apparently not the case. */
+diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c
+index bcaba17688f6..a7fa016f31eb 100644
+--- a/drivers/tty/n_hdlc.c
++++ b/drivers/tty/n_hdlc.c
+@@ -599,7 +599,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file,
+ 	add_wait_queue(&tty->read_wait, &wait);
+ 
+ 	for (;;) {
+-		if (test_bit(TTY_OTHER_DONE, &tty->flags)) {
++		if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
+ 			ret = -EIO;
+ 			break;
+ 		}
+@@ -827,7 +827,7 @@ static unsigned int n_hdlc_tty_poll(struct tty_struct *tty, struct file *filp,
+ 		/* set bits for operations that won't block */
+ 		if (n_hdlc->rx_buf_list.head)
+ 			mask |= POLLIN | POLLRDNORM;	/* readable */
+-		if (test_bit(TTY_OTHER_DONE, &tty->flags))
++		if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
+ 			mask |= POLLHUP;
+ 		if (tty_hung_up_p(filp))
+ 			mask |= POLLHUP;
+diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
+index fb76a7d80e7e..bdf0e6e89991 100644
+--- a/drivers/tty/n_tty.c
++++ b/drivers/tty/n_tty.c
+@@ -1917,18 +1917,6 @@ static inline int input_available_p(struct tty_struct *tty, int poll)
+ 		return ldata->commit_head - ldata->read_tail >= amt;
+ }
+ 
+-static inline int check_other_done(struct tty_struct *tty)
+-{
+-	int done = test_bit(TTY_OTHER_DONE, &tty->flags);
+-	if (done) {
+-		/* paired with cmpxchg() in check_other_closed(); ensures
+-		 * read buffer head index is not stale
+-		 */
+-		smp_mb__after_atomic();
+-	}
+-	return done;
+-}
+-
+ /**
+  *	copy_from_read_buf	-	copy read data directly
+  *	@tty: terminal device
+@@ -2124,7 +2112,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
+ 	struct n_tty_data *ldata = tty->disc_data;
+ 	unsigned char __user *b = buf;
+ 	DEFINE_WAIT_FUNC(wait, woken_wake_function);
+-	int c, done;
++	int c;
+ 	int minimum, time;
+ 	ssize_t retval = 0;
+ 	long timeout;
+@@ -2183,32 +2171,35 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
+ 			break;
+ 		}
+ 
+-		done = check_other_done(tty);
+-
+ 		if (!input_available_p(tty, 0)) {
+-			if (done) {
+-				retval = -EIO;
+-				break;
+-			}
+-			if (tty_hung_up_p(file))
+-				break;
+-			if (!timeout)
+-				break;
+-			if (file->f_flags & O_NONBLOCK) {
+-				retval = -EAGAIN;
+-				break;
+-			}
+-			if (signal_pending(current)) {
+-				retval = -ERESTARTSYS;
+-				break;
+-			}
+ 			up_read(&tty->termios_rwsem);
++			tty_buffer_flush_work(tty->port);
++			down_read(&tty->termios_rwsem);
++			if (!input_available_p(tty, 0)) {
++				if (test_bit(TTY_OTHER_CLOSED, &tty->flags)) {
++					retval = -EIO;
++					break;
++				}
++				if (tty_hung_up_p(file))
++					break;
++				if (!timeout)
++					break;
++				if (file->f_flags & O_NONBLOCK) {
++					retval = -EAGAIN;
++					break;
++				}
++				if (signal_pending(current)) {
++					retval = -ERESTARTSYS;
++					break;
++				}
++				up_read(&tty->termios_rwsem);
+ 
+-			timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
+-					     timeout);
++				timeout = wait_woken(&wait, TASK_INTERRUPTIBLE,
++						timeout);
+ 
+-			down_read(&tty->termios_rwsem);
+-			continue;
++				down_read(&tty->termios_rwsem);
++				continue;
++			}
+ 		}
+ 
+ 		if (ldata->icanon && !L_EXTPROC(tty)) {
+@@ -2386,12 +2377,17 @@ static unsigned int n_tty_poll(struct tty_struct *tty, struct file *file,
+ 
+ 	poll_wait(file, &tty->read_wait, wait);
+ 	poll_wait(file, &tty->write_wait, wait);
+-	if (check_other_done(tty))
+-		mask |= POLLHUP;
+ 	if (input_available_p(tty, 1))
+ 		mask |= POLLIN | POLLRDNORM;
++	else {
++		tty_buffer_flush_work(tty->port);
++		if (input_available_p(tty, 1))
++			mask |= POLLIN | POLLRDNORM;
++	}
+ 	if (tty->packet && tty->link->ctrl_status)
+ 		mask |= POLLPRI | POLLIN | POLLRDNORM;
++	if (test_bit(TTY_OTHER_CLOSED, &tty->flags))
++		mask |= POLLHUP;
+ 	if (tty_hung_up_p(file))
+ 		mask |= POLLHUP;
+ 	if (tty->ops->write && !tty_is_writelocked(tty) &&
+diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
+index cf0dc51a2690..e198996c5b83 100644
+--- a/drivers/tty/pty.c
++++ b/drivers/tty/pty.c
+@@ -59,7 +59,7 @@ static void pty_close(struct tty_struct *tty, struct file *filp)
+ 	if (!tty->link)
+ 		return;
+ 	set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
+-	tty_flip_buffer_push(tty->link->port);
++	wake_up_interruptible(&tty->link->read_wait);
+ 	wake_up_interruptible(&tty->link->write_wait);
+ 	if (tty->driver->subtype == PTY_TYPE_MASTER) {
+ 		set_bit(TTY_OTHER_CLOSED, &tty->flags);
+@@ -247,9 +247,7 @@ static int pty_open(struct tty_struct *tty, struct file *filp)
+ 		goto out;
+ 
+ 	clear_bit(TTY_IO_ERROR, &tty->flags);
+-	/* TTY_OTHER_CLOSED must be cleared before TTY_OTHER_DONE */
+ 	clear_bit(TTY_OTHER_CLOSED, &tty->link->flags);
+-	clear_bit(TTY_OTHER_DONE, &tty->link->flags);
+ 	set_bit(TTY_THROTTLED, &tty->flags);
+ 	return 0;
+ 
+diff --git a/drivers/tty/serial/8250/8250_mid.c b/drivers/tty/serial/8250/8250_mid.c
+index 88531a36b69c..ed489880e62b 100644
+--- a/drivers/tty/serial/8250/8250_mid.c
++++ b/drivers/tty/serial/8250/8250_mid.c
+@@ -14,6 +14,7 @@
+ #include <linux/pci.h>
+ 
+ #include <linux/dma/hsu.h>
++#include <linux/8250_pci.h>
+ 
+ #include "8250.h"
+ 
+@@ -24,6 +25,7 @@
+ #define PCI_DEVICE_ID_INTEL_DNV_UART	0x19d8
+ 
+ /* Intel MID Specific registers */
++#define INTEL_MID_UART_DNV_FISR		0x08
+ #define INTEL_MID_UART_PS		0x30
+ #define INTEL_MID_UART_MUL		0x34
+ #define INTEL_MID_UART_DIV		0x38
+@@ -31,6 +33,7 @@
+ struct mid8250;
+ 
+ struct mid8250_board {
++	unsigned int flags;
+ 	unsigned long freq;
+ 	unsigned int base_baud;
+ 	int (*setup)(struct mid8250 *, struct uart_port *p);
+@@ -88,16 +91,16 @@ static int tng_setup(struct mid8250 *mid, struct uart_port *p)
+ static int dnv_handle_irq(struct uart_port *p)
+ {
+ 	struct mid8250 *mid = p->private_data;
+-	int ret;
+-
+-	ret = hsu_dma_irq(&mid->dma_chip, 0);
+-	ret |= hsu_dma_irq(&mid->dma_chip, 1);
+-
+-	/* For now, letting the HW generate separate interrupt for the UART */
+-	if (ret)
+-		return ret;
+-
+-	return serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
++	unsigned int fisr = serial_port_in(p, INTEL_MID_UART_DNV_FISR);
++	int ret = IRQ_NONE;
++
++	if (fisr & BIT(2))
++		ret |= hsu_dma_irq(&mid->dma_chip, 1);
++	if (fisr & BIT(1))
++		ret |= hsu_dma_irq(&mid->dma_chip, 0);
++	if (fisr & BIT(0))
++		ret |= serial8250_handle_irq(p, serial_port_in(p, UART_IIR));
++	return ret;
+ }
+ 
+ #define DNV_DMA_CHAN_OFFSET 0x80
+@@ -106,12 +109,13 @@ static int dnv_setup(struct mid8250 *mid, struct uart_port *p)
+ {
+ 	struct hsu_dma_chip *chip = &mid->dma_chip;
+ 	struct pci_dev *pdev = to_pci_dev(p->dev);
++	unsigned int bar = FL_GET_BASE(mid->board->flags);
+ 	int ret;
+ 
+ 	chip->dev = &pdev->dev;
+ 	chip->irq = pdev->irq;
+ 	chip->regs = p->membase;
+-	chip->length = pci_resource_len(pdev, 0);
++	chip->length = pci_resource_len(pdev, bar);
+ 	chip->offset = DNV_DMA_CHAN_OFFSET;
+ 
+ 	/* Falling back to PIO mode if DMA probing fails */
+@@ -217,6 +221,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ {
+ 	struct uart_8250_port uart;
+ 	struct mid8250 *mid;
++	unsigned int bar;
+ 	int ret;
+ 
+ 	ret = pcim_enable_device(pdev);
+@@ -230,6 +235,7 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 		return -ENOMEM;
+ 
+ 	mid->board = (struct mid8250_board *)id->driver_data;
++	bar = FL_GET_BASE(mid->board->flags);
+ 
+ 	memset(&uart, 0, sizeof(struct uart_8250_port));
+ 
+@@ -242,8 +248,8 @@ static int mid8250_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	uart.port.flags = UPF_SHARE_IRQ | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+ 	uart.port.set_termios = mid8250_set_termios;
+ 
+-	uart.port.mapbase = pci_resource_start(pdev, 0);
+-	uart.port.membase = pcim_iomap(pdev, 0, 0);
++	uart.port.mapbase = pci_resource_start(pdev, bar);
++	uart.port.membase = pcim_iomap(pdev, bar, 0);
+ 	if (!uart.port.membase)
+ 		return -ENOMEM;
+ 
+@@ -282,18 +288,21 @@ static void mid8250_remove(struct pci_dev *pdev)
+ }
+ 
+ static const struct mid8250_board pnw_board = {
++	.flags = FL_BASE0,
+ 	.freq = 50000000,
+ 	.base_baud = 115200,
+ 	.setup = pnw_setup,
+ };
+ 
+ static const struct mid8250_board tng_board = {
++	.flags = FL_BASE0,
+ 	.freq = 38400000,
+ 	.base_baud = 1843200,
+ 	.setup = tng_setup,
+ };
+ 
+ static const struct mid8250_board dnv_board = {
++	.flags = FL_BASE1,
+ 	.freq = 133333333,
+ 	.base_baud = 115200,
+ 	.setup = dnv_setup,
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 98862aa5bb58..4eedd1da32e6 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1377,6 +1377,9 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
+ 	unsigned long m, n;
+ 	u32 reg;
+ 
++	/* Gracefully handle the B0 case: fall back to B9600 */
++	fuart = fuart ? fuart : 9600 * 16;
++
+ 	/* Get Fuart closer to Fref */
+ 	fuart *= rounddown_pow_of_two(fref / fuart);
+ 
+diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c
+index d9439e6ab719..954941dd8124 100644
+--- a/drivers/tty/serial/atmel_serial.c
++++ b/drivers/tty/serial/atmel_serial.c
+@@ -274,6 +274,13 @@ static bool atmel_use_dma_rx(struct uart_port *port)
+ 	return atmel_port->use_dma_rx;
+ }
+ 
++static bool atmel_use_fifo(struct uart_port *port)
++{
++	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
++
++	return atmel_port->fifo_size;
++}
++
+ static unsigned int atmel_get_lines_status(struct uart_port *port)
+ {
+ 	struct atmel_uart_port *atmel_port = to_atmel_uart_port(port);
+@@ -2090,7 +2097,12 @@ 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) */
+-		mode |= ATMEL_US_USMODE_HWHS;
++		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 {
++			mode |= ATMEL_US_USMODE_HWHS;
++		}
+ 	} else {
+ 		/* RS232 without hadware handshake */
+ 		mode |= ATMEL_US_USMODE_NORMAL;
+diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
+index ac7f8df54406..99bb23161dd6 100644
+--- a/drivers/tty/serial/samsung.c
++++ b/drivers/tty/serial/samsung.c
+@@ -1271,6 +1271,8 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
+ 	/* check to see if we need  to change clock source */
+ 
+ 	if (ourport->baudclk != clk) {
++		clk_prepare_enable(clk);
++
+ 		s3c24xx_serial_setsource(port, clk_sel);
+ 
+ 		if (!IS_ERR(ourport->baudclk)) {
+@@ -1278,8 +1280,6 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
+ 			ourport->baudclk = ERR_PTR(-EINVAL);
+ 		}
+ 
+-		clk_prepare_enable(clk);
+-
+ 		ourport->baudclk = clk;
+ 		ourport->baudclk_rate = clk ? clk_get_rate(clk) : 0;
+ 	}
+diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
+index a946e49a2626..aa80dc94ddc2 100644
+--- a/drivers/tty/tty_buffer.c
++++ b/drivers/tty/tty_buffer.c
+@@ -37,29 +37,6 @@
+ 
+ #define TTY_BUFFER_PAGE	(((PAGE_SIZE - sizeof(struct tty_buffer)) / 2) & ~0xFF)
+ 
+-/*
+- * If all tty flip buffers have been processed by flush_to_ldisc() or
+- * dropped by tty_buffer_flush(), check if the linked pty has been closed.
+- * If so, wake the reader/poll to process
+- */
+-static inline void check_other_closed(struct tty_struct *tty)
+-{
+-	unsigned long flags, old;
+-
+-	/* transition from TTY_OTHER_CLOSED => TTY_OTHER_DONE must be atomic */
+-	for (flags = ACCESS_ONCE(tty->flags);
+-	     test_bit(TTY_OTHER_CLOSED, &flags);
+-	     ) {
+-		old = flags;
+-		__set_bit(TTY_OTHER_DONE, &flags);
+-		flags = cmpxchg(&tty->flags, old, flags);
+-		if (old == flags) {
+-			wake_up_interruptible(&tty->read_wait);
+-			break;
+-		}
+-	}
+-}
+-
+ /**
+  *	tty_buffer_lock_exclusive	-	gain exclusive access to buffer
+  *	tty_buffer_unlock_exclusive	-	release exclusive access
+@@ -254,8 +231,6 @@ void tty_buffer_flush(struct tty_struct *tty, struct tty_ldisc *ld)
+ 	if (ld && ld->ops->flush_buffer)
+ 		ld->ops->flush_buffer(tty);
+ 
+-	check_other_closed(tty);
+-
+ 	atomic_dec(&buf->priority);
+ 	mutex_unlock(&buf->lock);
+ }
+@@ -522,10 +497,8 @@ static void flush_to_ldisc(struct work_struct *work)
+ 		 */
+ 		count = smp_load_acquire(&head->commit) - head->read;
+ 		if (!count) {
+-			if (next == NULL) {
+-				check_other_closed(tty);
++			if (next == NULL)
+ 				break;
+-			}
+ 			buf->head = next;
+ 			tty_buffer_free(port, head);
+ 			continue;
+@@ -614,3 +587,8 @@ bool tty_buffer_cancel_work(struct tty_port *port)
+ {
+ 	return cancel_work_sync(&port->buf.work);
+ }
++
++void tty_buffer_flush_work(struct tty_port *port)
++{
++	flush_work(&port->buf.work);
++}
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index 3e3c7575e92d..bd523adb9643 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -3583,9 +3583,10 @@ static int do_register_con_driver(const struct consw *csw, int first, int last)
+ 		goto err;
+ 
+ 	desc = csw->con_startup();
+-
+-	if (!desc)
++	if (!desc) {
++		retval = -ENODEV;
+ 		goto err;
++	}
+ 
+ 	retval = -EINVAL;
+ 
+diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
+index 2057d91d8336..dadd1e8dfe09 100644
+--- a/drivers/usb/core/driver.c
++++ b/drivers/usb/core/driver.c
+@@ -284,7 +284,7 @@ static int usb_probe_interface(struct device *dev)
+ 	struct usb_device *udev = interface_to_usbdev(intf);
+ 	const struct usb_device_id *id;
+ 	int error = -ENODEV;
+-	int lpm_disable_error;
++	int lpm_disable_error = -ENODEV;
+ 
+ 	dev_dbg(dev, "%s\n", __func__);
+ 
+@@ -336,12 +336,14 @@ static int usb_probe_interface(struct device *dev)
+ 	 * setting during probe, that should also be fine.  usb_set_interface()
+ 	 * will attempt to disable LPM, and fail if it can't disable it.
+ 	 */
+-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
+-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
+-		dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
+-				__func__, driver->name);
+-		error = lpm_disable_error;
+-		goto err;
++	if (driver->disable_hub_initiated_lpm) {
++		lpm_disable_error = usb_unlocked_disable_lpm(udev);
++		if (lpm_disable_error) {
++			dev_err(&intf->dev, "%s Failed to disable LPM for driver %s\n.",
++					__func__, driver->name);
++			error = lpm_disable_error;
++			goto err;
++		}
+ 	}
+ 
+ 	/* Carry out a deferred switch to altsetting 0 */
+@@ -391,7 +393,8 @@ static int usb_unbind_interface(struct device *dev)
+ 	struct usb_interface *intf = to_usb_interface(dev);
+ 	struct usb_host_endpoint *ep, **eps = NULL;
+ 	struct usb_device *udev;
+-	int i, j, error, r, lpm_disable_error;
++	int i, j, error, r;
++	int lpm_disable_error = -ENODEV;
+ 
+ 	intf->condition = USB_INTERFACE_UNBINDING;
+ 
+@@ -399,12 +402,13 @@ static int usb_unbind_interface(struct device *dev)
+ 	udev = interface_to_usbdev(intf);
+ 	error = usb_autoresume_device(udev);
+ 
+-	/* Hub-initiated LPM policy may change, so attempt to disable LPM until
++	/* If hub-initiated LPM policy may change, attempt to disable LPM until
+ 	 * the driver is unbound.  If LPM isn't disabled, that's fine because it
+ 	 * wouldn't be enabled unless all the bound interfaces supported
+ 	 * hub-initiated LPM.
+ 	 */
+-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
++	if (driver->disable_hub_initiated_lpm)
++		lpm_disable_error = usb_unlocked_disable_lpm(udev);
+ 
+ 	/*
+ 	 * Terminate all URBs for this interface unless the driver
+@@ -505,7 +509,7 @@ int usb_driver_claim_interface(struct usb_driver *driver,
+ 	struct device *dev;
+ 	struct usb_device *udev;
+ 	int retval = 0;
+-	int lpm_disable_error;
++	int lpm_disable_error = -ENODEV;
+ 
+ 	if (!iface)
+ 		return -ENODEV;
+@@ -526,12 +530,14 @@ int usb_driver_claim_interface(struct usb_driver *driver,
+ 
+ 	iface->condition = USB_INTERFACE_BOUND;
+ 
+-	/* Disable LPM until this driver is bound. */
+-	lpm_disable_error = usb_unlocked_disable_lpm(udev);
+-	if (lpm_disable_error && driver->disable_hub_initiated_lpm) {
+-		dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
+-				__func__, driver->name);
+-		return -ENOMEM;
++	/* See the comment about disabling LPM in usb_probe_interface(). */
++	if (driver->disable_hub_initiated_lpm) {
++		lpm_disable_error = usb_unlocked_disable_lpm(udev);
++		if (lpm_disable_error) {
++			dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n.",
++					__func__, driver->name);
++			return -ENOMEM;
++		}
+ 	}
+ 
+ 	/* Claimed interfaces are initially inactive (suspended) and
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 2ca2cef7f681..980fc5774151 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -994,7 +994,7 @@ static void usb_bus_init (struct usb_bus *bus)
+ 	bus->bandwidth_allocated = 0;
+ 	bus->bandwidth_int_reqs  = 0;
+ 	bus->bandwidth_isoc_reqs = 0;
+-	mutex_init(&bus->usb_address0_mutex);
++	mutex_init(&bus->devnum_next_mutex);
+ }
+ 
+ /*-------------------------------------------------------------------------*/
+@@ -2521,6 +2521,14 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
+ 		return NULL;
+ 	}
+ 	if (primary_hcd == NULL) {
++		hcd->address0_mutex = kmalloc(sizeof(*hcd->address0_mutex),
++				GFP_KERNEL);
++		if (!hcd->address0_mutex) {
++			kfree(hcd);
++			dev_dbg(dev, "hcd address0 mutex alloc failed\n");
++			return NULL;
++		}
++		mutex_init(hcd->address0_mutex);
+ 		hcd->bandwidth_mutex = kmalloc(sizeof(*hcd->bandwidth_mutex),
+ 				GFP_KERNEL);
+ 		if (!hcd->bandwidth_mutex) {
+@@ -2532,6 +2540,7 @@ struct usb_hcd *usb_create_shared_hcd(const struct hc_driver *driver,
+ 		dev_set_drvdata(dev, hcd);
+ 	} else {
+ 		mutex_lock(&usb_port_peer_mutex);
++		hcd->address0_mutex = primary_hcd->address0_mutex;
+ 		hcd->bandwidth_mutex = primary_hcd->bandwidth_mutex;
+ 		hcd->primary_hcd = primary_hcd;
+ 		primary_hcd->primary_hcd = primary_hcd;
+@@ -2598,8 +2607,10 @@ static void hcd_release(struct kref *kref)
+ 	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);
+ 
+ 	mutex_lock(&usb_port_peer_mutex);
+-	if (usb_hcd_is_primary_hcd(hcd))
++	if (usb_hcd_is_primary_hcd(hcd)) {
++		kfree(hcd->address0_mutex);
+ 		kfree(hcd->bandwidth_mutex);
++	}
+ 	if (hcd->shared_hcd) {
+ 		struct usb_hcd *peer = hcd->shared_hcd;
+ 
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
+index 38cc4bae0a82..1ab42bfbecaf 100644
+--- a/drivers/usb/core/hub.c
++++ b/drivers/usb/core/hub.c
+@@ -2080,7 +2080,7 @@ static void choose_devnum(struct usb_device *udev)
+ 	struct usb_bus	*bus = udev->bus;
+ 
+ 	/* be safe when more hub events are proceed in parallel */
+-	mutex_lock(&bus->usb_address0_mutex);
++	mutex_lock(&bus->devnum_next_mutex);
+ 	if (udev->wusb) {
+ 		devnum = udev->portnum + 1;
+ 		BUG_ON(test_bit(devnum, bus->devmap.devicemap));
+@@ -2098,7 +2098,7 @@ static void choose_devnum(struct usb_device *udev)
+ 		set_bit(devnum, bus->devmap.devicemap);
+ 		udev->devnum = devnum;
+ 	}
+-	mutex_unlock(&bus->usb_address0_mutex);
++	mutex_unlock(&bus->devnum_next_mutex);
+ }
+ 
+ static void release_devnum(struct usb_device *udev)
+@@ -4364,7 +4364,7 @@ hub_port_init(struct usb_hub *hub, struct usb_device *udev, int port1,
+ 	if (oldspeed == USB_SPEED_LOW)
+ 		delay = HUB_LONG_RESET_TIME;
+ 
+-	mutex_lock(&hdev->bus->usb_address0_mutex);
++	mutex_lock(hcd->address0_mutex);
+ 
+ 	/* Reset the device; full speed may morph to high speed */
+ 	/* FIXME a USB 2.0 device may morph into SuperSpeed on reset. */
+@@ -4650,7 +4650,7 @@ fail:
+ 		hub_port_disable(hub, port1, 0);
+ 		update_devnum(udev, devnum);	/* for disconnect processing */
+ 	}
+-	mutex_unlock(&hdev->bus->usb_address0_mutex);
++	mutex_unlock(hcd->address0_mutex);
+ 	return retval;
+ }
+ 
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c
+index 15b648cbc75c..73515d54e1cc 100644
+--- a/drivers/usb/gadget/function/f_fs.c
++++ b/drivers/usb/gadget/function/f_fs.c
+@@ -651,7 +651,7 @@ static void ffs_user_copy_worker(struct work_struct *work)
+ 	if (io_data->read && ret > 0) {
+ 		use_mm(io_data->mm);
+ 		ret = copy_to_iter(io_data->buf, ret, &io_data->data);
+-		if (iov_iter_count(&io_data->data))
++		if (ret != io_data->req->actual && iov_iter_count(&io_data->data))
+ 			ret = -EFAULT;
+ 		unuse_mm(io_data->mm);
+ 	}
+diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
+index acf210f16328..5c6d4d7ca605 100644
+--- a/drivers/usb/gadget/function/f_mass_storage.c
++++ b/drivers/usb/gadget/function/f_mass_storage.c
+@@ -2977,25 +2977,6 @@ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+ }
+ EXPORT_SYMBOL_GPL(fsg_common_set_inquiry_string);
+ 
+-int fsg_common_run_thread(struct fsg_common *common)
+-{
+-	common->state = FSG_STATE_IDLE;
+-	/* Tell the thread to start working */
+-	common->thread_task =
+-		kthread_create(fsg_main_thread, common, "file-storage");
+-	if (IS_ERR(common->thread_task)) {
+-		common->state = FSG_STATE_TERMINATED;
+-		return PTR_ERR(common->thread_task);
+-	}
+-
+-	DBG(common, "I/O thread pid: %d\n", task_pid_nr(common->thread_task));
+-
+-	wake_up_process(common->thread_task);
+-
+-	return 0;
+-}
+-EXPORT_SYMBOL_GPL(fsg_common_run_thread);
+-
+ static void fsg_common_release(struct kref *ref)
+ {
+ 	struct fsg_common *common = container_of(ref, struct fsg_common, ref);
+@@ -3005,6 +2986,7 @@ static void fsg_common_release(struct kref *ref)
+ 	if (common->state != FSG_STATE_TERMINATED) {
+ 		raise_exception(common, FSG_STATE_EXIT);
+ 		wait_for_completion(&common->thread_notifier);
++		common->thread_task = NULL;
+ 	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE(common->luns); ++i) {
+@@ -3050,9 +3032,21 @@ static int fsg_bind(struct usb_configuration *c, struct usb_function *f)
+ 		if (ret)
+ 			return ret;
+ 		fsg_common_set_inquiry_string(fsg->common, NULL, NULL);
+-		ret = fsg_common_run_thread(fsg->common);
+-		if (ret)
++	}
++
++	if (!common->thread_task) {
++		common->state = FSG_STATE_IDLE;
++		common->thread_task =
++			kthread_create(fsg_main_thread, common, "file-storage");
++		if (IS_ERR(common->thread_task)) {
++			int ret = PTR_ERR(common->thread_task);
++			common->thread_task = NULL;
++			common->state = FSG_STATE_TERMINATED;
+ 			return ret;
++		}
++		DBG(common, "I/O thread pid: %d\n",
++		    task_pid_nr(common->thread_task));
++		wake_up_process(common->thread_task);
+ 	}
+ 
+ 	fsg->gadget = gadget;
+diff --git a/drivers/usb/gadget/function/f_mass_storage.h b/drivers/usb/gadget/function/f_mass_storage.h
+index 445df6775609..b6a9918eaefb 100644
+--- a/drivers/usb/gadget/function/f_mass_storage.h
++++ b/drivers/usb/gadget/function/f_mass_storage.h
+@@ -153,8 +153,6 @@ int fsg_common_create_luns(struct fsg_common *common, struct fsg_config *cfg);
+ void fsg_common_set_inquiry_string(struct fsg_common *common, const char *vn,
+ 				   const char *pn);
+ 
+-int fsg_common_run_thread(struct fsg_common *common);
+-
+ void fsg_config_from_params(struct fsg_config *cfg,
+ 			    const struct fsg_module_parameters *params,
+ 			    unsigned int fsg_num_buffers);
+diff --git a/drivers/usb/gadget/legacy/acm_ms.c b/drivers/usb/gadget/legacy/acm_ms.c
+index c16089efc322..c39de65a448b 100644
+--- a/drivers/usb/gadget/legacy/acm_ms.c
++++ b/drivers/usb/gadget/legacy/acm_ms.c
+@@ -133,10 +133,6 @@ static int acm_ms_do_config(struct usb_configuration *c)
+ 	if (status < 0)
+ 		goto put_msg;
+ 
+-	status = fsg_common_run_thread(opts->common);
+-	if (status)
+-		goto remove_acm;
+-
+ 	status = usb_add_function(c, f_msg);
+ 	if (status)
+ 		goto remove_acm;
+diff --git a/drivers/usb/gadget/legacy/mass_storage.c b/drivers/usb/gadget/legacy/mass_storage.c
+index e61af53c7d2b..125974f32f50 100644
+--- a/drivers/usb/gadget/legacy/mass_storage.c
++++ b/drivers/usb/gadget/legacy/mass_storage.c
+@@ -132,10 +132,6 @@ static int msg_do_config(struct usb_configuration *c)
+ 	if (IS_ERR(f_msg))
+ 		return PTR_ERR(f_msg);
+ 
+-	ret = fsg_common_run_thread(opts->common);
+-	if (ret)
+-		goto put_func;
+-
+ 	ret = usb_add_function(c, f_msg);
+ 	if (ret)
+ 		goto put_func;
+diff --git a/drivers/usb/gadget/legacy/multi.c b/drivers/usb/gadget/legacy/multi.c
+index 229d704a620b..a70a406580ea 100644
+--- a/drivers/usb/gadget/legacy/multi.c
++++ b/drivers/usb/gadget/legacy/multi.c
+@@ -137,7 +137,6 @@ static struct usb_function *f_msg_rndis;
+ 
+ static int rndis_do_config(struct usb_configuration *c)
+ {
+-	struct fsg_opts *fsg_opts;
+ 	int ret;
+ 
+ 	if (gadget_is_otg(c->cdev->gadget)) {
+@@ -169,11 +168,6 @@ static int rndis_do_config(struct usb_configuration *c)
+ 		goto err_fsg;
+ 	}
+ 
+-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
+-	ret = fsg_common_run_thread(fsg_opts->common);
+-	if (ret)
+-		goto err_run;
+-
+ 	ret = usb_add_function(c, f_msg_rndis);
+ 	if (ret)
+ 		goto err_run;
+@@ -225,7 +219,6 @@ static struct usb_function *f_msg_multi;
+ 
+ static int cdc_do_config(struct usb_configuration *c)
+ {
+-	struct fsg_opts *fsg_opts;
+ 	int ret;
+ 
+ 	if (gadget_is_otg(c->cdev->gadget)) {
+@@ -258,11 +251,6 @@ static int cdc_do_config(struct usb_configuration *c)
+ 		goto err_fsg;
+ 	}
+ 
+-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
+-	ret = fsg_common_run_thread(fsg_opts->common);
+-	if (ret)
+-		goto err_run;
+-
+ 	ret = usb_add_function(c, f_msg_multi);
+ 	if (ret)
+ 		goto err_run;
+diff --git a/drivers/usb/gadget/legacy/nokia.c b/drivers/usb/gadget/legacy/nokia.c
+index 09975046c694..b1e535f4022e 100644
+--- a/drivers/usb/gadget/legacy/nokia.c
++++ b/drivers/usb/gadget/legacy/nokia.c
+@@ -152,7 +152,6 @@ static int nokia_bind_config(struct usb_configuration *c)
+ 	struct usb_function *f_ecm;
+ 	struct usb_function *f_obex2 = NULL;
+ 	struct usb_function *f_msg;
+-	struct fsg_opts *fsg_opts;
+ 	int status = 0;
+ 	int obex1_stat = -1;
+ 	int obex2_stat = -1;
+@@ -222,12 +221,6 @@ static int nokia_bind_config(struct usb_configuration *c)
+ 		goto err_ecm;
+ 	}
+ 
+-	fsg_opts = fsg_opts_from_func_inst(fi_msg);
+-
+-	status = fsg_common_run_thread(fsg_opts->common);
+-	if (status)
+-		goto err_msg;
+-
+ 	status = usb_add_function(c, f_msg);
+ 	if (status)
+ 		goto err_msg;
+diff --git a/drivers/usb/gadget/udc/udc-core.c b/drivers/usb/gadget/udc/udc-core.c
+index e4e70e11d0f6..c6e76465065a 100644
+--- a/drivers/usb/gadget/udc/udc-core.c
++++ b/drivers/usb/gadget/udc/udc-core.c
+@@ -75,7 +75,7 @@ int usb_gadget_map_request(struct usb_gadget *gadget,
+ 		mapped = dma_map_sg(dev, req->sg, req->num_sgs,
+ 				is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
+ 		if (mapped == 0) {
+-			dev_err(&gadget->dev, "failed to map SGs\n");
++			dev_err(dev, "failed to map SGs\n");
+ 			return -EFAULT;
+ 		}
+ 
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 3050b18b2447..e9d4dde3e9b3 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -35,6 +35,7 @@ config USB_XHCI_PCI
+ 
+ config USB_XHCI_PLATFORM
+ 	tristate "Generic xHCI driver for a platform device"
++	select USB_XHCI_RCAR if ARCH_RENESAS
+ 	---help---
+ 	  Adds an xHCI host driver for a generic platform device, which
+ 	  provides a memory space and an irq.
+@@ -63,7 +64,7 @@ config USB_XHCI_MVEBU
+ 
+ config USB_XHCI_RCAR
+ 	tristate "xHCI support for Renesas R-Car SoCs"
+-	select USB_XHCI_PLATFORM
++	depends on USB_XHCI_PLATFORM
+ 	depends on ARCH_RENESAS || COMPILE_TEST
+ 	---help---
+ 	  Say 'Y' to enable the support for the xHCI host controller
+diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
+index 92fdb6e9faff..c78ff95a43be 100644
+--- a/drivers/usb/misc/usbtest.c
++++ b/drivers/usb/misc/usbtest.c
+@@ -529,6 +529,7 @@ static struct scatterlist *
+ alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
+ {
+ 	struct scatterlist	*sg;
++	unsigned int		n_size = 0;
+ 	unsigned		i;
+ 	unsigned		size = max;
+ 	unsigned		maxpacket =
+@@ -561,7 +562,8 @@ alloc_sglist(int nents, int max, int vary, struct usbtest_dev *dev, int pipe)
+ 			break;
+ 		case 1:
+ 			for (j = 0; j < size; j++)
+-				*buf++ = (u8) ((j % maxpacket) % 63);
++				*buf++ = (u8) (((j + n_size) % maxpacket) % 63);
++			n_size += size;
+ 			break;
+ 		}
+ 
+diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
+index 7c9f25e9c422..a7c8d26a322b 100644
+--- a/drivers/usb/serial/cp210x.c
++++ b/drivers/usb/serial/cp210x.c
+@@ -971,8 +971,7 @@ static void cp210x_set_termios(struct tty_struct *tty,
+ 		} else {
+ 			modem_ctl[0] &= ~0x7B;
+ 			modem_ctl[0] |= 0x01;
+-			/* FIXME - OR here instead of assignment looks wrong */
+-			modem_ctl[4] |= 0x40;
++			modem_ctl[4] = 0x40;
+ 			dev_dbg(dev, "%s - flow control = NONE\n", __func__);
+ 		}
+ 
+diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c
+index f3007ecdd1b4..11c05ce2f35f 100644
+--- a/drivers/usb/serial/io_edgeport.c
++++ b/drivers/usb/serial/io_edgeport.c
+@@ -2849,14 +2849,16 @@ static int edge_startup(struct usb_serial *serial)
+ 				/* not set up yet, so do it now */
+ 				edge_serial->interrupt_read_urb =
+ 						usb_alloc_urb(0, GFP_KERNEL);
+-				if (!edge_serial->interrupt_read_urb)
+-					return -ENOMEM;
++				if (!edge_serial->interrupt_read_urb) {
++					response = -ENOMEM;
++					break;
++				}
+ 
+ 				edge_serial->interrupt_in_buffer =
+ 					kmalloc(buffer_size, GFP_KERNEL);
+ 				if (!edge_serial->interrupt_in_buffer) {
+-					usb_free_urb(edge_serial->interrupt_read_urb);
+-					return -ENOMEM;
++					response = -ENOMEM;
++					break;
+ 				}
+ 				edge_serial->interrupt_in_endpoint =
+ 						endpoint->bEndpointAddress;
+@@ -2884,14 +2886,16 @@ static int edge_startup(struct usb_serial *serial)
+ 				/* not set up yet, so do it now */
+ 				edge_serial->read_urb =
+ 						usb_alloc_urb(0, GFP_KERNEL);
+-				if (!edge_serial->read_urb)
+-					return -ENOMEM;
++				if (!edge_serial->read_urb) {
++					response = -ENOMEM;
++					break;
++				}
+ 
+ 				edge_serial->bulk_in_buffer =
+ 					kmalloc(buffer_size, GFP_KERNEL);
+ 				if (!edge_serial->bulk_in_buffer) {
+-					usb_free_urb(edge_serial->read_urb);
+-					return -ENOMEM;
++					response = -ENOMEM;
++					break;
+ 				}
+ 				edge_serial->bulk_in_endpoint =
+ 						endpoint->bEndpointAddress;
+@@ -2917,9 +2921,22 @@ static int edge_startup(struct usb_serial *serial)
+ 			}
+ 		}
+ 
+-		if (!interrupt_in_found || !bulk_in_found || !bulk_out_found) {
+-			dev_err(ddev, "Error - the proper endpoints were not found!\n");
+-			return -ENODEV;
++		if (response || !interrupt_in_found || !bulk_in_found ||
++							!bulk_out_found) {
++			if (!response) {
++				dev_err(ddev, "expected endpoints not found\n");
++				response = -ENODEV;
++			}
++
++			usb_free_urb(edge_serial->interrupt_read_urb);
++			kfree(edge_serial->interrupt_in_buffer);
++
++			usb_free_urb(edge_serial->read_urb);
++			kfree(edge_serial->bulk_in_buffer);
++
++			kfree(edge_serial);
++
++			return response;
+ 		}
+ 
+ 		/* start interrupt read for this edgeport this interrupt will
+@@ -2942,16 +2959,9 @@ static void edge_disconnect(struct usb_serial *serial)
+ {
+ 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+ 
+-	/* stop reads and writes on all ports */
+-	/* free up our endpoint stuff */
+ 	if (edge_serial->is_epic) {
+ 		usb_kill_urb(edge_serial->interrupt_read_urb);
+-		usb_free_urb(edge_serial->interrupt_read_urb);
+-		kfree(edge_serial->interrupt_in_buffer);
+-
+ 		usb_kill_urb(edge_serial->read_urb);
+-		usb_free_urb(edge_serial->read_urb);
+-		kfree(edge_serial->bulk_in_buffer);
+ 	}
+ }
+ 
+@@ -2964,6 +2974,16 @@ static void edge_release(struct usb_serial *serial)
+ {
+ 	struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
+ 
++	if (edge_serial->is_epic) {
++		usb_kill_urb(edge_serial->interrupt_read_urb);
++		usb_free_urb(edge_serial->interrupt_read_urb);
++		kfree(edge_serial->interrupt_in_buffer);
++
++		usb_kill_urb(edge_serial->read_urb);
++		usb_free_urb(edge_serial->read_urb);
++		kfree(edge_serial->bulk_in_buffer);
++	}
++
+ 	kfree(edge_serial);
+ }
+ 
+diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
+index b6bd8e4a6486..1cf05883f48c 100644
+--- a/drivers/usb/serial/keyspan.c
++++ b/drivers/usb/serial/keyspan.c
+@@ -2376,6 +2376,10 @@ static void keyspan_release(struct usb_serial *serial)
+ 
+ 	s_priv = usb_get_serial_data(serial);
+ 
++	/* Make sure to unlink the URBs submitted in attach. */
++	usb_kill_urb(s_priv->instat_urb);
++	usb_kill_urb(s_priv->indat_urb);
++
+ 	usb_free_urb(s_priv->instat_urb);
+ 	usb_free_urb(s_priv->indat_urb);
+ 	usb_free_urb(s_priv->glocont_urb);
+diff --git a/drivers/usb/serial/mxuport.c b/drivers/usb/serial/mxuport.c
+index 31a8b47f1ac6..c6596cbcc4b6 100644
+--- a/drivers/usb/serial/mxuport.c
++++ b/drivers/usb/serial/mxuport.c
+@@ -1259,6 +1259,15 @@ static int mxuport_attach(struct usb_serial *serial)
+ 	return 0;
+ }
+ 
++static void mxuport_release(struct usb_serial *serial)
++{
++	struct usb_serial_port *port0 = serial->port[0];
++	struct usb_serial_port *port1 = serial->port[1];
++
++	usb_serial_generic_close(port1);
++	usb_serial_generic_close(port0);
++}
++
+ static int mxuport_open(struct tty_struct *tty, struct usb_serial_port *port)
+ {
+ 	struct mxuport_port *mxport = usb_get_serial_port_data(port);
+@@ -1361,6 +1370,7 @@ static struct usb_serial_driver mxuport_device = {
+ 	.probe			= mxuport_probe,
+ 	.port_probe		= mxuport_port_probe,
+ 	.attach			= mxuport_attach,
++	.release		= mxuport_release,
+ 	.calc_num_ports		= mxuport_calc_num_ports,
+ 	.open			= mxuport_open,
+ 	.close			= mxuport_close,
+diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
+index c6f497f16526..d96d423d00e6 100644
+--- a/drivers/usb/serial/option.c
++++ b/drivers/usb/serial/option.c
+@@ -375,18 +375,22 @@ static void option_instat_callback(struct urb *urb);
+ #define HAIER_PRODUCT_CE81B			0x10f8
+ #define HAIER_PRODUCT_CE100			0x2009
+ 
+-/* Cinterion (formerly Siemens) products */
+-#define SIEMENS_VENDOR_ID				0x0681
+-#define CINTERION_VENDOR_ID				0x1e2d
++/* Gemalto's Cinterion products (formerly Siemens) */
++#define SIEMENS_VENDOR_ID			0x0681
++#define CINTERION_VENDOR_ID			0x1e2d
++#define CINTERION_PRODUCT_HC25_MDMNET		0x0040
+ #define CINTERION_PRODUCT_HC25_MDM		0x0047
+-#define CINTERION_PRODUCT_HC25_MDMNET	0x0040
++#define CINTERION_PRODUCT_HC28_MDMNET		0x004A /* same for HC28J */
+ #define CINTERION_PRODUCT_HC28_MDM		0x004C
+-#define CINTERION_PRODUCT_HC28_MDMNET	0x004A /* same for HC28J */
+ #define CINTERION_PRODUCT_EU3_E			0x0051
+ #define CINTERION_PRODUCT_EU3_P			0x0052
+ #define CINTERION_PRODUCT_PH8			0x0053
+ #define CINTERION_PRODUCT_AHXX			0x0055
+ #define CINTERION_PRODUCT_PLXX			0x0060
++#define CINTERION_PRODUCT_PH8_2RMNET		0x0082
++#define CINTERION_PRODUCT_PH8_AUDIO		0x0083
++#define CINTERION_PRODUCT_AHXX_2RMNET		0x0084
++#define CINTERION_PRODUCT_AHXX_AUDIO		0x0085
+ 
+ /* Olivetti products */
+ #define OLIVETTI_VENDOR_ID			0x0b3c
+@@ -633,6 +637,10 @@ static const struct option_blacklist_info telit_le922_blacklist_usbcfg3 = {
+ 	.reserved = BIT(1) | BIT(2) | BIT(3),
+ };
+ 
++static const struct option_blacklist_info cinterion_rmnet2_blacklist = {
++	.reserved = BIT(4) | BIT(5),
++};
++
+ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
+ 	{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
+@@ -1602,7 +1610,79 @@ static const struct usb_device_id option_ids[] = {
+ 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
+ 		.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
+-	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff42, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff43, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff44, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff45, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff46, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff47, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff48, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff49, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4a, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4b, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4c, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4d, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4e, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff4f, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff50, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff51, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff52, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff53, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff54, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff55, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff56, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff57, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff58, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff59, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5a, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5b, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5c, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5d, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5e, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff5f, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff60, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff61, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff62, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff63, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff64, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff65, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff66, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff67, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff68, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff69, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6a, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6b, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6c, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6d, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6e, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff6f, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff70, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff71, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff72, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff73, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff74, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff75, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff76, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff77, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff78, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff79, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7a, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7b, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7c, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7d, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7e, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff7f, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff80, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff81, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff82, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff83, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff84, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff85, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff86, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff87, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff88, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff89, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8a, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8b, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8c, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff8d, 0xff, 0xff, 0xff) },
+@@ -1613,6 +1693,61 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff92, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff93, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff94, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xff9f, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa0, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa1, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa2, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa3, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa4, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa5, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa6, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa7, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa8, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffa9, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaa, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffab, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffac, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffae, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffaf, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb0, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb1, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb2, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb3, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb4, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb5, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb6, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb7, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb8, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffb9, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffba, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbb, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbc, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbd, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbe, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffbf, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc0, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc1, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc2, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc3, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc4, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc5, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc6, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc7, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc8, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffc9, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffca, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcb, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcc, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcd, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffce, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffcf, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd0, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd1, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd2, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd3, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd4, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffd5, 0xff, 0xff, 0xff) },
++	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffe9, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffec, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xffee, 0xff, 0xff, 0xff) },
+ 	{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0xfff6, 0xff, 0xff, 0xff) },
+@@ -1712,7 +1847,13 @@ static const struct usb_device_id option_ids[] = {
+ 	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX, 0xff) },
+ 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PLXX),
+ 		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
+-	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) }, 
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_2RMNET, 0xff),
++		.driver_info = (kernel_ulong_t)&cinterion_rmnet2_blacklist },
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_PH8_AUDIO, 0xff),
++		.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_2RMNET, 0xff) },
++	{ USB_DEVICE_INTERFACE_CLASS(CINTERION_VENDOR_ID, CINTERION_PRODUCT_AHXX_AUDIO, 0xff) },
++	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDM) },
+ 	{ USB_DEVICE(CINTERION_VENDOR_ID, CINTERION_PRODUCT_HC28_MDMNET) },
+ 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDM) },
+ 	{ USB_DEVICE(SIEMENS_VENDOR_ID, CINTERION_PRODUCT_HC25_MDMNET) },
+diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c
+index 2df8ad5ede89..85acb50a7ee2 100644
+--- a/drivers/usb/serial/quatech2.c
++++ b/drivers/usb/serial/quatech2.c
+@@ -141,6 +141,7 @@ static void qt2_release(struct usb_serial *serial)
+ 
+ 	serial_priv = usb_get_serial_data(serial);
+ 
++	usb_kill_urb(serial_priv->read_urb);
+ 	usb_free_urb(serial_priv->read_urb);
+ 	kfree(serial_priv->read_buffer);
+ 	kfree(serial_priv);
+diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c
+index 6467b91f2245..028618c5eeba 100644
+--- a/drivers/watchdog/sp5100_tco.c
++++ b/drivers/watchdog/sp5100_tco.c
+@@ -73,6 +73,13 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started."
+ /*
+  * Some TCO specific functions
+  */
++
++static bool tco_has_sp5100_reg_layout(struct pci_dev *dev)
++{
++	return dev->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
++	       dev->revision < 0x40;
++}
++
+ static void tco_timer_start(void)
+ {
+ 	u32 val;
+@@ -129,7 +136,7 @@ static void tco_timer_enable(void)
+ {
+ 	int val;
+ 
+-	if (sp5100_tco_pci->revision >= 0x40) {
++	if (!tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+ 		/* For SB800 or later */
+ 		/* Set the Watchdog timer resolution to 1 sec */
+ 		outb(SB800_PM_WATCHDOG_CONFIG, SB800_IO_PM_INDEX_REG);
+@@ -342,8 +349,7 @@ static unsigned char sp5100_tco_setupdevice(void)
+ 	/*
+ 	 * Determine type of southbridge chipset.
+ 	 */
+-	if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
+-	    sp5100_tco_pci->revision < 0x40) {
++	if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+ 		dev_name = SP5100_DEVNAME;
+ 		index_reg = SP5100_IO_PM_INDEX_REG;
+ 		data_reg = SP5100_IO_PM_DATA_REG;
+@@ -388,8 +394,7 @@ static unsigned char sp5100_tco_setupdevice(void)
+ 	 * Secondly, Find the watchdog timer MMIO address
+ 	 * from SBResource_MMIO register.
+ 	 */
+-	if (sp5100_tco_pci->device == PCI_DEVICE_ID_ATI_SBX00_SMBUS &&
+-	    sp5100_tco_pci->revision < 0x40) {
++	if (tco_has_sp5100_reg_layout(sp5100_tco_pci)) {
+ 		/* Read SBResource_MMIO from PCI config(PCI_Reg: 9Ch) */
+ 		pci_read_config_dword(sp5100_tco_pci,
+ 				      SP5100_SB_RESOURCE_MMIO_BASE, &val);
+diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c
+index e2c5abbb45ff..3595cffa24ea 100644
+--- a/drivers/watchdog/watchdog_dev.c
++++ b/drivers/watchdog/watchdog_dev.c
+@@ -736,7 +736,6 @@ static int watchdog_release(struct inode *inode, struct file *file)
+ 		watchdog_ping(wdd);
+ 	}
+ 
+-	cancel_delayed_work_sync(&wd_data->work);
+ 	watchdog_update_worker(wdd);
+ 
+ 	/* make sure that /dev/watchdog can be re-opened */
+diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
+index 84a6a5b3384a..208d19938fdf 100644
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -4122,6 +4122,7 @@ void btrfs_test_inode_set_ops(struct inode *inode);
+ 
+ /* ioctl.c */
+ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
++long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
+ int btrfs_ioctl_get_supported_features(void __user *arg);
+ void btrfs_update_iflags(struct inode *inode);
+ void btrfs_inherit_iflags(struct inode *inode, struct inode *dir);
+diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
+index 8d7b5a45c005..af5c7fa22e0e 100644
+--- a/fs/btrfs/file.c
++++ b/fs/btrfs/file.c
+@@ -1596,6 +1596,13 @@ again:
+ 
+ 		copied = btrfs_copy_from_user(pos, write_bytes, pages, i);
+ 
++		num_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
++						reserve_bytes);
++		dirty_sectors = round_up(copied + sector_offset,
++					root->sectorsize);
++		dirty_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
++						dirty_sectors);
++
+ 		/*
+ 		 * if we have trouble faulting in the pages, fall
+ 		 * back to one page at a time
+@@ -1605,6 +1612,7 @@ again:
+ 
+ 		if (copied == 0) {
+ 			force_page_uptodate = true;
++			dirty_sectors = 0;
+ 			dirty_pages = 0;
+ 		} else {
+ 			force_page_uptodate = false;
+@@ -1615,20 +1623,19 @@ again:
+ 		/*
+ 		 * If we had a short copy we need to release the excess delaloc
+ 		 * bytes we reserved.  We need to increment outstanding_extents
+-		 * because btrfs_delalloc_release_space will decrement it, but
++		 * because btrfs_delalloc_release_space and
++		 * btrfs_delalloc_release_metadata will decrement it, but
+ 		 * we still have an outstanding extent for the chunk we actually
+ 		 * managed to copy.
+ 		 */
+-		num_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
+-						reserve_bytes);
+-		dirty_sectors = round_up(copied + sector_offset,
+-					root->sectorsize);
+-		dirty_sectors = BTRFS_BYTES_TO_BLKS(root->fs_info,
+-						dirty_sectors);
+-
+ 		if (num_sectors > dirty_sectors) {
+-			release_bytes = (write_bytes - copied)
+-				& ~((u64)root->sectorsize - 1);
++			/*
++			 * we round down because we don't want to count
++			 * any partial blocks actually sent through the
++			 * IO machines
++			 */
++			release_bytes = round_down(release_bytes - copied,
++				      root->sectorsize);
+ 			if (copied > 0) {
+ 				spin_lock(&BTRFS_I(inode)->lock);
+ 				BTRFS_I(inode)->outstanding_extents++;
+@@ -2956,7 +2963,7 @@ const struct file_operations btrfs_file_operations = {
+ 	.fallocate	= btrfs_fallocate,
+ 	.unlocked_ioctl	= btrfs_ioctl,
+ #ifdef CONFIG_COMPAT
+-	.compat_ioctl	= btrfs_ioctl,
++	.compat_ioctl	= btrfs_compat_ioctl,
+ #endif
+ 	.copy_file_range = btrfs_copy_file_range,
+ 	.clone_file_range = btrfs_clone_file_range,
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 2aaba58b4856..167fc3d49450 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -10184,7 +10184,7 @@ static const struct file_operations btrfs_dir_file_operations = {
+ 	.iterate	= btrfs_real_readdir,
+ 	.unlocked_ioctl	= btrfs_ioctl,
+ #ifdef CONFIG_COMPAT
+-	.compat_ioctl	= btrfs_ioctl,
++	.compat_ioctl	= btrfs_compat_ioctl,
+ #endif
+ 	.release        = btrfs_release_file,
+ 	.fsync		= btrfs_sync_file,
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 5a23806ae418..f545f81f642d 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -5552,3 +5552,24 @@ long btrfs_ioctl(struct file *file, unsigned int
+ 
+ 	return -ENOTTY;
+ }
++
++#ifdef CONFIG_COMPAT
++long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++	switch (cmd) {
++	case FS_IOC32_GETFLAGS:
++		cmd = FS_IOC_GETFLAGS;
++		break;
++	case FS_IOC32_SETFLAGS:
++		cmd = FS_IOC_SETFLAGS;
++		break;
++	case FS_IOC32_GETVERSION:
++		cmd = FS_IOC_GETVERSION;
++		break;
++	default:
++		return -ENOIOCTLCMD;
++	}
++
++	return btrfs_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
++}
++#endif
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index 59727e32ed0f..af0ec2d5ad0e 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -400,19 +400,27 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 	sec_blob->LmChallengeResponse.MaximumLength = 0;
+ 
+ 	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
+-	rc = setup_ntlmv2_rsp(ses, nls_cp);
+-	if (rc) {
+-		cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
+-		goto setup_ntlmv2_ret;
++	if (ses->user_name != NULL) {
++		rc = setup_ntlmv2_rsp(ses, nls_cp);
++		if (rc) {
++			cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
++			goto setup_ntlmv2_ret;
++		}
++		memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
++				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++		tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
++
++		sec_blob->NtChallengeResponse.Length =
++				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++		sec_blob->NtChallengeResponse.MaximumLength =
++				cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++	} else {
++		/*
++		 * don't send an NT Response for anonymous access
++		 */
++		sec_blob->NtChallengeResponse.Length = 0;
++		sec_blob->NtChallengeResponse.MaximumLength = 0;
+ 	}
+-	memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+-			ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+-	tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+-
+-	sec_blob->NtChallengeResponse.Length =
+-			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+-	sec_blob->NtChallengeResponse.MaximumLength =
+-			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+ 
+ 	if (ses->domainName == NULL) {
+ 		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
+@@ -670,20 +678,24 @@ sess_auth_lanman(struct sess_data *sess_data)
+ 
+ 	pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
+ 
+-	/* no capabilities flags in old lanman negotiation */
+-	pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+-
+-	/* Calculate hash with password and copy into bcc_ptr.
+-	 * Encryption Key (stored as in cryptkey) gets used if the
+-	 * security mode bit in Negottiate Protocol response states
+-	 * to use challenge/response method (i.e. Password bit is 1).
+-	 */
+-	rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
+-			      ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
+-			      true : false, lnm_session_key);
+-
+-	memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
+-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
++	if (ses->user_name != NULL) {
++		/* no capabilities flags in old lanman negotiation */
++		pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
++
++		/* Calculate hash with password and copy into bcc_ptr.
++		 * Encryption Key (stored as in cryptkey) gets used if the
++		 * security mode bit in Negottiate Protocol response states
++		 * to use challenge/response method (i.e. Password bit is 1).
++		 */
++		rc = calc_lanman_hash(ses->password, ses->server->cryptkey,
++				      ses->server->sec_mode & SECMODE_PW_ENCRYPT ?
++				      true : false, lnm_session_key);
++
++		memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
++		bcc_ptr += CIFS_AUTH_RESP_SIZE;
++	} else {
++		pSMB->old_req.PasswordLength = 0;
++	}
+ 
+ 	/*
+ 	 * can not sign if LANMAN negotiated so no need
+@@ -769,26 +781,31 @@ sess_auth_ntlm(struct sess_data *sess_data)
+ 	capabilities = cifs_ssetup_hdr(ses, pSMB);
+ 
+ 	pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
+-	pSMB->req_no_secext.CaseInsensitivePasswordLength =
+-			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+-	pSMB->req_no_secext.CaseSensitivePasswordLength =
+-			cpu_to_le16(CIFS_AUTH_RESP_SIZE);
+-
+-	/* calculate ntlm response and session key */
+-	rc = setup_ntlm_response(ses, sess_data->nls_cp);
+-	if (rc) {
+-		cifs_dbg(VFS, "Error %d during NTLM authentication\n",
+-				 rc);
+-		goto out;
+-	}
++	if (ses->user_name != NULL) {
++		pSMB->req_no_secext.CaseInsensitivePasswordLength =
++				cpu_to_le16(CIFS_AUTH_RESP_SIZE);
++		pSMB->req_no_secext.CaseSensitivePasswordLength =
++				cpu_to_le16(CIFS_AUTH_RESP_SIZE);
++
++		/* calculate ntlm response and session key */
++		rc = setup_ntlm_response(ses, sess_data->nls_cp);
++		if (rc) {
++			cifs_dbg(VFS, "Error %d during NTLM authentication\n",
++					 rc);
++			goto out;
++		}
+ 
+-	/* copy ntlm response */
+-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+-			CIFS_AUTH_RESP_SIZE);
+-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
+-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+-			CIFS_AUTH_RESP_SIZE);
+-	bcc_ptr += CIFS_AUTH_RESP_SIZE;
++		/* copy ntlm response */
++		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
++				CIFS_AUTH_RESP_SIZE);
++		bcc_ptr += CIFS_AUTH_RESP_SIZE;
++		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
++				CIFS_AUTH_RESP_SIZE);
++		bcc_ptr += CIFS_AUTH_RESP_SIZE;
++	} else {
++		pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
++		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
++	}
+ 
+ 	if (ses->capabilities & CAP_UNICODE) {
+ 		/* unicode strings must be word aligned */
+@@ -878,22 +895,26 @@ sess_auth_ntlmv2(struct sess_data *sess_data)
+ 	/* LM2 password would be here if we supported it */
+ 	pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+ 
+-	/* calculate nlmv2 response and session key */
+-	rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
+-	if (rc) {
+-		cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
+-		goto out;
+-	}
++	if (ses->user_name != NULL) {
++		/* calculate nlmv2 response and session key */
++		rc = setup_ntlmv2_rsp(ses, sess_data->nls_cp);
++		if (rc) {
++			cifs_dbg(VFS, "Error %d during NTLMv2 authentication\n", rc);
++			goto out;
++		}
+ 
+-	memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+-			ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+-	bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
++		memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
++				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++		bcc_ptr += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+ 
+-	/* set case sensitive password length after tilen may get
+-	 * assigned, tilen is 0 otherwise.
+-	 */
+-	pSMB->req_no_secext.CaseSensitivePasswordLength =
+-		cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++		/* set case sensitive password length after tilen may get
++		 * assigned, tilen is 0 otherwise.
++		 */
++		pSMB->req_no_secext.CaseSensitivePasswordLength =
++			cpu_to_le16(ses->auth_key.len - CIFS_SESS_KEY_SIZE);
++	} else {
++		pSMB->req_no_secext.CaseSensitivePasswordLength = 0;
++	}
+ 
+ 	if (ses->capabilities & CAP_UNICODE) {
+ 		if (sess_data->iov[0].iov_len % 2) {
+diff --git a/fs/cifs/smb2glob.h b/fs/cifs/smb2glob.h
+index bc0bb9c34f72..0ffa18094335 100644
+--- a/fs/cifs/smb2glob.h
++++ b/fs/cifs/smb2glob.h
+@@ -44,6 +44,7 @@
+ #define SMB2_OP_DELETE 7
+ #define SMB2_OP_HARDLINK 8
+ #define SMB2_OP_SET_EOF 9
++#define SMB2_OP_RMDIR 10
+ 
+ /* Used when constructing chained read requests. */
+ #define CHAINED_REQUEST 1
+diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c
+index 899bbc86f73e..4f0231e685a9 100644
+--- a/fs/cifs/smb2inode.c
++++ b/fs/cifs/smb2inode.c
+@@ -80,6 +80,10 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon,
+ 		 * SMB2_open() call.
+ 		 */
+ 		break;
++	case SMB2_OP_RMDIR:
++		tmprc = SMB2_rmdir(xid, tcon, fid.persistent_fid,
++				   fid.volatile_fid);
++		break;
+ 	case SMB2_OP_RENAME:
+ 		tmprc = SMB2_rename(xid, tcon, fid.persistent_fid,
+ 				    fid.volatile_fid, (__le16 *)data);
+@@ -191,8 +195,8 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
+ 	   struct cifs_sb_info *cifs_sb)
+ {
+ 	return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
+-				  CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE,
+-				  NULL, SMB2_OP_DELETE);
++				  CREATE_NOT_FILE,
++				  NULL, SMB2_OP_RMDIR);
+ }
+ 
+ int
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 42e1f440eb1e..8f38e33d365b 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -2575,6 +2575,22 @@ SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
+ }
+ 
+ int
++SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
++		  u64 persistent_fid, u64 volatile_fid)
++{
++	__u8 delete_pending = 1;
++	void *data;
++	unsigned int size;
++
++	data = &delete_pending;
++	size = 1; /* sizeof __u8 */
++
++	return send_set_info(xid, tcon, persistent_fid, volatile_fid,
++			current->tgid, FILE_DISPOSITION_INFORMATION, 1, &data,
++			&size);
++}
++
++int
+ SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
+ 		  u64 persistent_fid, u64 volatile_fid, __le16 *target_file)
+ {
+diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h
+index 4f07dc93608d..eb2cde2f64ba 100644
+--- a/fs/cifs/smb2proto.h
++++ b/fs/cifs/smb2proto.h
+@@ -141,6 +141,8 @@ extern int SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon,
+ extern int SMB2_rename(const unsigned int xid, struct cifs_tcon *tcon,
+ 		       u64 persistent_fid, u64 volatile_fid,
+ 		       __le16 *target_file);
++extern int SMB2_rmdir(const unsigned int xid, struct cifs_tcon *tcon,
++		      u64 persistent_fid, u64 volatile_fid);
+ extern int SMB2_set_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
+ 			     u64 persistent_fid, u64 volatile_fid,
+ 			     __le16 *target_file);
+diff --git a/fs/crypto/keyinfo.c b/fs/crypto/keyinfo.c
+index 06f5aa478bf2..1ac263eddc4e 100644
+--- a/fs/crypto/keyinfo.c
++++ b/fs/crypto/keyinfo.c
+@@ -78,6 +78,67 @@ out:
+ 	return res;
+ }
+ 
++static int validate_user_key(struct fscrypt_info *crypt_info,
++			struct fscrypt_context *ctx, u8 *raw_key,
++			u8 *prefix, int prefix_size)
++{
++	u8 *full_key_descriptor;
++	struct key *keyring_key;
++	struct fscrypt_key *master_key;
++	const struct user_key_payload *ukp;
++	int full_key_len = prefix_size + (FS_KEY_DESCRIPTOR_SIZE * 2) + 1;
++	int res;
++
++	full_key_descriptor = kmalloc(full_key_len, GFP_NOFS);
++	if (!full_key_descriptor)
++		return -ENOMEM;
++
++	memcpy(full_key_descriptor, prefix, prefix_size);
++	sprintf(full_key_descriptor + prefix_size,
++			"%*phN", FS_KEY_DESCRIPTOR_SIZE,
++			ctx->master_key_descriptor);
++	full_key_descriptor[full_key_len - 1] = '\0';
++	keyring_key = request_key(&key_type_logon, full_key_descriptor, NULL);
++	kfree(full_key_descriptor);
++	if (IS_ERR(keyring_key))
++		return PTR_ERR(keyring_key);
++
++	if (keyring_key->type != &key_type_logon) {
++		printk_once(KERN_WARNING
++				"%s: key type must be logon\n", __func__);
++		res = -ENOKEY;
++		goto out;
++	}
++	down_read(&keyring_key->sem);
++	ukp = user_key_payload(keyring_key);
++	if (ukp->datalen != sizeof(struct fscrypt_key)) {
++		res = -EINVAL;
++		up_read(&keyring_key->sem);
++		goto out;
++	}
++	master_key = (struct fscrypt_key *)ukp->data;
++	BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE);
++
++	if (master_key->size != FS_AES_256_XTS_KEY_SIZE) {
++		printk_once(KERN_WARNING
++				"%s: key size incorrect: %d\n",
++				__func__, master_key->size);
++		res = -ENOKEY;
++		up_read(&keyring_key->sem);
++		goto out;
++	}
++	res = derive_key_aes(ctx->nonce, master_key->raw, raw_key);
++	up_read(&keyring_key->sem);
++	if (res)
++		goto out;
++
++	crypt_info->ci_keyring_key = keyring_key;
++	return 0;
++out:
++	key_put(keyring_key);
++	return res;
++}
++
+ static void put_crypt_info(struct fscrypt_info *ci)
+ {
+ 	if (!ci)
+@@ -91,12 +152,7 @@ static void put_crypt_info(struct fscrypt_info *ci)
+ int get_crypt_info(struct inode *inode)
+ {
+ 	struct fscrypt_info *crypt_info;
+-	u8 full_key_descriptor[FS_KEY_DESC_PREFIX_SIZE +
+-				(FS_KEY_DESCRIPTOR_SIZE * 2) + 1];
+-	struct key *keyring_key = NULL;
+-	struct fscrypt_key *master_key;
+ 	struct fscrypt_context ctx;
+-	const struct user_key_payload *ukp;
+ 	struct crypto_skcipher *ctfm;
+ 	const char *cipher_str;
+ 	u8 raw_key[FS_MAX_KEY_SIZE];
+@@ -167,48 +223,24 @@ retry:
+ 		memset(raw_key, 0x42, FS_AES_256_XTS_KEY_SIZE);
+ 		goto got_key;
+ 	}
+-	memcpy(full_key_descriptor, FS_KEY_DESC_PREFIX,
+-					FS_KEY_DESC_PREFIX_SIZE);
+-	sprintf(full_key_descriptor + FS_KEY_DESC_PREFIX_SIZE,
+-					"%*phN", FS_KEY_DESCRIPTOR_SIZE,
+-					ctx.master_key_descriptor);
+-	full_key_descriptor[FS_KEY_DESC_PREFIX_SIZE +
+-					(2 * FS_KEY_DESCRIPTOR_SIZE)] = '\0';
+-	keyring_key = request_key(&key_type_logon, full_key_descriptor, NULL);
+-	if (IS_ERR(keyring_key)) {
+-		res = PTR_ERR(keyring_key);
+-		keyring_key = NULL;
+-		goto out;
+-	}
+-	crypt_info->ci_keyring_key = keyring_key;
+-	if (keyring_key->type != &key_type_logon) {
+-		printk_once(KERN_WARNING
+-				"%s: key type must be logon\n", __func__);
+-		res = -ENOKEY;
+-		goto out;
+-	}
+-	down_read(&keyring_key->sem);
+-	ukp = user_key_payload(keyring_key);
+-	if (ukp->datalen != sizeof(struct fscrypt_key)) {
+-		res = -EINVAL;
+-		up_read(&keyring_key->sem);
+-		goto out;
+-	}
+-	master_key = (struct fscrypt_key *)ukp->data;
+-	BUILD_BUG_ON(FS_AES_128_ECB_KEY_SIZE != FS_KEY_DERIVATION_NONCE_SIZE);
+ 
+-	if (master_key->size != FS_AES_256_XTS_KEY_SIZE) {
+-		printk_once(KERN_WARNING
+-				"%s: key size incorrect: %d\n",
+-				__func__, master_key->size);
+-		res = -ENOKEY;
+-		up_read(&keyring_key->sem);
++	res = validate_user_key(crypt_info, &ctx, raw_key,
++			FS_KEY_DESC_PREFIX, FS_KEY_DESC_PREFIX_SIZE);
++	if (res && inode->i_sb->s_cop->key_prefix) {
++		u8 *prefix = NULL;
++		int prefix_size, res2;
++
++		prefix_size = inode->i_sb->s_cop->key_prefix(inode, &prefix);
++		res2 = validate_user_key(crypt_info, &ctx, raw_key,
++							prefix, prefix_size);
++		if (res2) {
++			if (res2 == -ENOKEY)
++				res = -ENOKEY;
++			goto out;
++		}
++	} else if (res) {
+ 		goto out;
+ 	}
+-	res = derive_key_aes(ctx.nonce, master_key->raw, raw_key);
+-	up_read(&keyring_key->sem);
+-	if (res)
+-		goto out;
+ got_key:
+ 	ctfm = crypto_alloc_skcipher(cipher_str, 0, 0);
+ 	if (!ctfm || IS_ERR(ctfm)) {
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
+index 7a4558d17f36..2effb79b5f3e 100644
+--- a/fs/f2fs/f2fs.h
++++ b/fs/f2fs/f2fs.h
+@@ -680,6 +680,10 @@ enum {
+ 	MAX_TIME,
+ };
+ 
++#ifdef CONFIG_F2FS_FS_ENCRYPTION
++#define F2FS_KEY_DESC_PREFIX "f2fs:"
++#define F2FS_KEY_DESC_PREFIX_SIZE 5
++#endif
+ struct f2fs_sb_info {
+ 	struct super_block *sb;			/* pointer to VFS super block */
+ 	struct proc_dir_entry *s_proc;		/* proc entry */
+@@ -687,6 +691,10 @@ struct f2fs_sb_info {
+ 	int valid_super_block;			/* valid super block no */
+ 	int s_flag;				/* flags for sbi */
+ 
++#ifdef CONFIG_F2FS_FS_ENCRYPTION
++	u8 key_prefix[F2FS_KEY_DESC_PREFIX_SIZE];
++	u8 key_prefix_size;
++#endif
+ 	/* for node-related operations */
+ 	struct f2fs_nm_info *nm_info;		/* node manager */
+ 	struct inode *node_inode;		/* cache node blocks */
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
+index 006f87d69921..e11385bbd4c6 100644
+--- a/fs/f2fs/super.c
++++ b/fs/f2fs/super.c
+@@ -893,6 +893,12 @@ static int f2fs_get_context(struct inode *inode, void *ctx, size_t len)
+ 				ctx, len, NULL);
+ }
+ 
++static int f2fs_key_prefix(struct inode *inode, u8 **key)
++{
++	*key = F2FS_I_SB(inode)->key_prefix;
++	return F2FS_I_SB(inode)->key_prefix_size;
++}
++
+ static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
+ 							void *fs_data)
+ {
+@@ -909,6 +915,7 @@ static unsigned f2fs_max_namelen(struct inode *inode)
+ 
+ static struct fscrypt_operations f2fs_cryptops = {
+ 	.get_context	= f2fs_get_context,
++	.key_prefix	= f2fs_key_prefix,
+ 	.set_context	= f2fs_set_context,
+ 	.is_encrypted	= f2fs_encrypted_inode,
+ 	.empty_dir	= f2fs_empty_dir,
+@@ -1231,6 +1238,12 @@ static void init_sb_info(struct f2fs_sb_info *sbi)
+ 
+ 	INIT_LIST_HEAD(&sbi->s_list);
+ 	mutex_init(&sbi->umount_mutex);
++
++#ifdef CONFIG_F2FS_FS_ENCRYPTION
++	memcpy(sbi->key_prefix, F2FS_KEY_DESC_PREFIX,
++				F2FS_KEY_DESC_PREFIX_SIZE);
++	sbi->key_prefix_size = F2FS_KEY_DESC_PREFIX_SIZE;
++#endif
+ }
+ 
+ /*
+diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
+index 458cf463047b..82067ca22f2b 100644
+--- a/fs/hpfs/super.c
++++ b/fs/hpfs/super.c
+@@ -15,6 +15,7 @@
+ #include <linux/sched.h>
+ #include <linux/bitmap.h>
+ #include <linux/slab.h>
++#include <linux/seq_file.h>
+ 
+ /* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
+ 
+@@ -453,10 +454,6 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
+ 	int lowercase, eas, chk, errs, chkdsk, timeshift;
+ 	int o;
+ 	struct hpfs_sb_info *sbi = hpfs_sb(s);
+-	char *new_opts = kstrdup(data, GFP_KERNEL);
+-
+-	if (!new_opts)
+-		return -ENOMEM;
+ 
+ 	sync_filesystem(s);
+ 
+@@ -493,17 +490,44 @@ static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
+ 
+ 	if (!(*flags & MS_RDONLY)) mark_dirty(s, 1);
+ 
+-	replace_mount_options(s, new_opts);
+-
+ 	hpfs_unlock(s);
+ 	return 0;
+ 
+ out_err:
+ 	hpfs_unlock(s);
+-	kfree(new_opts);
+ 	return -EINVAL;
+ }
+ 
++static int hpfs_show_options(struct seq_file *seq, struct dentry *root)
++{
++	struct hpfs_sb_info *sbi = hpfs_sb(root->d_sb);
++
++	seq_printf(seq, ",uid=%u", from_kuid_munged(&init_user_ns, sbi->sb_uid));
++	seq_printf(seq, ",gid=%u", from_kgid_munged(&init_user_ns, sbi->sb_gid));
++	seq_printf(seq, ",umask=%03o", (~sbi->sb_mode & 0777));
++	if (sbi->sb_lowercase)
++		seq_printf(seq, ",case=lower");
++	if (!sbi->sb_chk)
++		seq_printf(seq, ",check=none");
++	if (sbi->sb_chk == 2)
++		seq_printf(seq, ",check=strict");
++	if (!sbi->sb_err)
++		seq_printf(seq, ",errors=continue");
++	if (sbi->sb_err == 2)
++		seq_printf(seq, ",errors=panic");
++	if (!sbi->sb_chkdsk)
++		seq_printf(seq, ",chkdsk=no");
++	if (sbi->sb_chkdsk == 2)
++		seq_printf(seq, ",chkdsk=always");
++	if (!sbi->sb_eas)
++		seq_printf(seq, ",eas=no");
++	if (sbi->sb_eas == 1)
++		seq_printf(seq, ",eas=ro");
++	if (sbi->sb_timeshift)
++		seq_printf(seq, ",timeshift=%d", sbi->sb_timeshift);
++	return 0;
++}
++
+ /* Super operations */
+ 
+ static const struct super_operations hpfs_sops =
+@@ -514,7 +538,7 @@ static const struct super_operations hpfs_sops =
+ 	.put_super	= hpfs_put_super,
+ 	.statfs		= hpfs_statfs,
+ 	.remount_fs	= hpfs_remount_fs,
+-	.show_options	= generic_show_options,
++	.show_options	= hpfs_show_options,
+ };
+ 
+ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
+@@ -537,8 +561,6 @@ static int hpfs_fill_super(struct super_block *s, void *options, int silent)
+ 
+ 	int o;
+ 
+-	save_mount_options(s, options);
+-
+ 	sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+ 	if (!sbi) {
+ 		return -ENOMEM;
+diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
+index 618ced381a14..7c9fbf504f07 100644
+--- a/fs/nfs/callback_proc.c
++++ b/fs/nfs/callback_proc.c
+@@ -500,8 +500,10 @@ __be32 nfs4_callback_sequence(struct cb_sequenceargs *args,
+ 	cps->slot = slot;
+ 
+ 	/* The ca_maxresponsesize_cached is 0 with no DRC */
+-	if (args->csa_cachethis != 0)
+-		return htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE);
++	if (args->csa_cachethis != 0) {
++		status = htonl(NFS4ERR_REP_TOO_BIG_TO_CACHE);
++		goto out_unlock;
++	}
+ 
+ 	/*
+ 	 * Check for pending referring calls.  If a match is found, a
+diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
+index 35a52a880b2f..6bd05700d8c9 100644
+--- a/include/asm-generic/qspinlock.h
++++ b/include/asm-generic/qspinlock.h
+@@ -28,7 +28,30 @@
+  */
+ static __always_inline int queued_spin_is_locked(struct qspinlock *lock)
+ {
+-	return atomic_read(&lock->val);
++	/*
++	 * queued_spin_lock_slowpath() can ACQUIRE the lock before
++	 * issuing the unordered store that sets _Q_LOCKED_VAL.
++	 *
++	 * See both smp_cond_acquire() sites for more detail.
++	 *
++	 * This however means that in code like:
++	 *
++	 *   spin_lock(A)		spin_lock(B)
++	 *   spin_unlock_wait(B)	spin_is_locked(A)
++	 *   do_something()		do_something()
++	 *
++	 * Both CPUs can end up running do_something() because the store
++	 * setting _Q_LOCKED_VAL will pass through the loads in
++	 * spin_unlock_wait() and/or spin_is_locked().
++	 *
++	 * Avoid this by issuing a full memory barrier between the spin_lock()
++	 * and the loads in spin_unlock_wait() and spin_is_locked().
++	 *
++	 * Note that regular mutual exclusion doesn't care about this
++	 * delayed store.
++	 */
++	smp_mb();
++	return atomic_read(&lock->val) & _Q_LOCKED_MASK;
+ }
+ 
+ /**
+@@ -108,6 +131,8 @@ static __always_inline void queued_spin_unlock(struct qspinlock *lock)
+  */
+ static inline void queued_spin_unlock_wait(struct qspinlock *lock)
+ {
++	/* See queued_spin_is_locked() */
++	smp_mb();
+ 	while (atomic_read(&lock->val) & _Q_LOCKED_MASK)
+ 		cpu_relax();
+ }
+diff --git a/include/asm-generic/siginfo.h b/include/asm-generic/siginfo.h
+index 3d1a3af5cf59..a2508a8f9a9c 100644
+--- a/include/asm-generic/siginfo.h
++++ b/include/asm-generic/siginfo.h
+@@ -17,21 +17,6 @@
+ struct siginfo;
+ void do_schedule_next_timer(struct siginfo *info);
+ 
+-#ifndef HAVE_ARCH_COPY_SIGINFO
+-
+-#include <linux/string.h>
+-
+-static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
+-{
+-	if (from->si_code < 0)
+-		memcpy(to, from, sizeof(*to));
+-	else
+-		/* _sigchld is currently the largest know union member */
+-		memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
+-}
+-
+-#endif
+-
+ extern int copy_siginfo_to_user(struct siginfo __user *to, const struct siginfo *from);
+ 
+ #endif
+diff --git a/include/linux/can/dev.h b/include/linux/can/dev.h
+index 735f9f8c4e43..5261751f6bd4 100644
+--- a/include/linux/can/dev.h
++++ b/include/linux/can/dev.h
+@@ -40,8 +40,11 @@ struct can_priv {
+ 	struct can_clock clock;
+ 
+ 	enum can_state state;
+-	u32 ctrlmode;
+-	u32 ctrlmode_supported;
++
++	/* CAN controller features - see include/uapi/linux/can/netlink.h */
++	u32 ctrlmode;		/* current options setting */
++	u32 ctrlmode_supported;	/* options that can be modified by netlink */
++	u32 ctrlmode_static;	/* static enabled options for driver/hardware */
+ 
+ 	int restart_ms;
+ 	struct timer_list restart_timer;
+@@ -108,6 +111,21 @@ static inline bool can_is_canfd_skb(const struct sk_buff *skb)
+ 	return skb->len == CANFD_MTU;
+ }
+ 
++/* helper to define static CAN controller features at device creation time */
++static inline void can_set_static_ctrlmode(struct net_device *dev,
++					   u32 static_mode)
++{
++	struct can_priv *priv = netdev_priv(dev);
++
++	/* alloc_candev() succeeded => netdev_priv() is valid at this point */
++	priv->ctrlmode = static_mode;
++	priv->ctrlmode_static = static_mode;
++
++	/* override MTU which was set by default in can_setup()? */
++	if (static_mode & CAN_CTRLMODE_FD)
++		dev->mtu = CANFD_MTU;
++}
++
+ /* get data length from can_dlc with sanitized can_dlc */
+ u8 can_dlc2len(u8 can_dlc);
+ 
+diff --git a/include/linux/fscrypto.h b/include/linux/fscrypto.h
+index 6027f6bbb061..cfa6cde25f8e 100644
+--- a/include/linux/fscrypto.h
++++ b/include/linux/fscrypto.h
+@@ -175,6 +175,7 @@ struct fscrypt_name {
+  */
+ struct fscrypt_operations {
+ 	int (*get_context)(struct inode *, void *, size_t);
++	int (*key_prefix)(struct inode *, u8 **);
+ 	int (*prepare_context)(struct inode *);
+ 	int (*set_context)(struct inode *, const void *, size_t, void *);
+ 	int (*dummy_context)(struct inode *);
+diff --git a/include/linux/signal.h b/include/linux/signal.h
+index 92557bbce7e7..d80259afb9e5 100644
+--- a/include/linux/signal.h
++++ b/include/linux/signal.h
+@@ -28,6 +28,21 @@ struct sigpending {
+ 	sigset_t signal;
+ };
+ 
++#ifndef HAVE_ARCH_COPY_SIGINFO
++
++#include <linux/string.h>
++
++static inline void copy_siginfo(struct siginfo *to, struct siginfo *from)
++{
++	if (from->si_code < 0)
++		memcpy(to, from, sizeof(*to));
++	else
++		/* _sigchld is currently the largest know union member */
++		memcpy(to, from, __ARCH_SI_PREAMBLE_SIZE + sizeof(from->_sifields._sigchld));
++}
++
++#endif
++
+ /*
+  * Define some primitives to manipulate sigset_t.
+  */
+diff --git a/include/linux/tty.h b/include/linux/tty.h
+index 3b09f235db66..a34442031aae 100644
+--- a/include/linux/tty.h
++++ b/include/linux/tty.h
+@@ -338,7 +338,6 @@ struct tty_file_private {
+ #define TTY_OTHER_CLOSED 	2	/* Other side (if any) has closed */
+ #define TTY_EXCLUSIVE 		3	/* Exclusive open mode */
+ #define TTY_DO_WRITE_WAKEUP 	5	/* Call write_wakeup after queuing new */
+-#define TTY_OTHER_DONE		6	/* Closed pty has completed input processing */
+ #define TTY_LDISC_OPEN	 	11	/* Line discipline is open */
+ #define TTY_PTY_LOCK 		16	/* pty private */
+ #define TTY_NO_WRITE_SPLIT 	17	/* Preserve write boundaries to driver */
+@@ -457,6 +456,7 @@ extern void tty_buffer_init(struct tty_port *port);
+ extern void tty_buffer_set_lock_subclass(struct tty_port *port);
+ extern bool tty_buffer_restart_work(struct tty_port *port);
+ extern bool tty_buffer_cancel_work(struct tty_port *port);
++extern void tty_buffer_flush_work(struct tty_port *port);
+ extern speed_t tty_termios_baud_rate(struct ktermios *termios);
+ extern speed_t tty_termios_input_baud_rate(struct ktermios *termios);
+ extern void tty_termios_encode_baud_rate(struct ktermios *termios,
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 6a9a0c28415d..818bf7087996 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -374,13 +374,12 @@ struct usb_bus {
+ 
+ 	int devnum_next;		/* Next open device number in
+ 					 * round-robin allocation */
++	struct mutex devnum_next_mutex; /* devnum_next mutex */
+ 
+ 	struct usb_devmap devmap;	/* device address allocation map */
+ 	struct usb_device *root_hub;	/* Root hub */
+ 	struct usb_bus *hs_companion;	/* Companion EHCI bus, if any */
+ 
+-	struct mutex usb_address0_mutex; /* unaddressed device mutex */
+-
+ 	int bandwidth_allocated;	/* on this bus: how much of the time
+ 					 * reserved for periodic (intr/iso)
+ 					 * requests is used, on average?
+@@ -1069,7 +1068,7 @@ struct usbdrv_wrap {
+  *	for interfaces bound to this driver.
+  * @soft_unbind: if set to 1, the USB core will not kill URBs and disable
+  *	endpoints before calling the driver's disconnect method.
+- * @disable_hub_initiated_lpm: if set to 0, the USB core will not allow hubs
++ * @disable_hub_initiated_lpm: if set to 1, the USB core will not allow hubs
+  *	to initiate lower power link state transitions when an idle timeout
+  *	occurs.  Device-initiated USB 3.0 link PM will still be allowed.
+  *
+diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h
+index b98f831dcda3..66fc13705ab7 100644
+--- a/include/linux/usb/hcd.h
++++ b/include/linux/usb/hcd.h
+@@ -181,6 +181,7 @@ struct usb_hcd {
+ 	 * bandwidth_mutex should be dropped after a successful control message
+ 	 * to the device, or resetting the bandwidth after a failed attempt.
+ 	 */
++	struct mutex		*address0_mutex;
+ 	struct mutex		*bandwidth_mutex;
+ 	struct usb_hcd		*shared_hcd;
+ 	struct usb_hcd		*primary_hcd;
+diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
+index 74d79bde7075..a505079dcf88 100644
+--- a/include/scsi/scsi_device.h
++++ b/include/scsi/scsi_device.h
+@@ -242,6 +242,7 @@ scmd_printk(const char *, const struct scsi_cmnd *, const char *, ...);
+ enum scsi_target_state {
+ 	STARGET_CREATED = 1,
+ 	STARGET_RUNNING,
++	STARGET_REMOVE,
+ 	STARGET_DEL,
+ };
+ 
+diff --git a/kernel/sched/loadavg.c b/kernel/sched/loadavg.c
+index ef7159012cf3..b0b93fd33af9 100644
+--- a/kernel/sched/loadavg.c
++++ b/kernel/sched/loadavg.c
+@@ -99,10 +99,13 @@ long calc_load_fold_active(struct rq *this_rq)
+ static unsigned long
+ calc_load(unsigned long load, unsigned long exp, unsigned long active)
+ {
+-	load *= exp;
+-	load += active * (FIXED_1 - exp);
+-	load += 1UL << (FSHIFT - 1);
+-	return load >> FSHIFT;
++	unsigned long newload;
++
++	newload = load * exp + active * (FIXED_1 - exp);
++	if (active >= load)
++		newload += FIXED_1-1;
++
++	return newload / FIXED_1;
+ }
+ 
+ #ifdef CONFIG_NO_HZ_COMMON
+diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
+index 95181e36891a..9c143739b8d7 100644
+--- a/kernel/trace/ring_buffer.c
++++ b/kernel/trace/ring_buffer.c
+@@ -437,7 +437,7 @@ struct ring_buffer_per_cpu {
+ 	raw_spinlock_t			reader_lock;	/* serialize readers */
+ 	arch_spinlock_t			lock;
+ 	struct lock_class_key		lock_key;
+-	unsigned int			nr_pages;
++	unsigned long			nr_pages;
+ 	unsigned int			current_context;
+ 	struct list_head		*pages;
+ 	struct buffer_page		*head_page;	/* read from head */
+@@ -458,7 +458,7 @@ struct ring_buffer_per_cpu {
+ 	u64				write_stamp;
+ 	u64				read_stamp;
+ 	/* ring buffer pages to update, > 0 to add, < 0 to remove */
+-	int				nr_pages_to_update;
++	long				nr_pages_to_update;
+ 	struct list_head		new_pages; /* new pages to add */
+ 	struct work_struct		update_pages_work;
+ 	struct completion		update_done;
+@@ -1128,10 +1128,10 @@ static int rb_check_pages(struct ring_buffer_per_cpu *cpu_buffer)
+ 	return 0;
+ }
+ 
+-static int __rb_allocate_pages(int nr_pages, struct list_head *pages, int cpu)
++static int __rb_allocate_pages(long nr_pages, struct list_head *pages, int cpu)
+ {
+-	int i;
+ 	struct buffer_page *bpage, *tmp;
++	long i;
+ 
+ 	for (i = 0; i < nr_pages; i++) {
+ 		struct page *page;
+@@ -1168,7 +1168,7 @@ free_pages:
+ }
+ 
+ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
+-			     unsigned nr_pages)
++			     unsigned long nr_pages)
+ {
+ 	LIST_HEAD(pages);
+ 
+@@ -1193,7 +1193,7 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
+ }
+ 
+ static struct ring_buffer_per_cpu *
+-rb_allocate_cpu_buffer(struct ring_buffer *buffer, int nr_pages, int cpu)
++rb_allocate_cpu_buffer(struct ring_buffer *buffer, long nr_pages, int cpu)
+ {
+ 	struct ring_buffer_per_cpu *cpu_buffer;
+ 	struct buffer_page *bpage;
+@@ -1293,8 +1293,9 @@ struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
+ 					struct lock_class_key *key)
+ {
+ 	struct ring_buffer *buffer;
++	long nr_pages;
+ 	int bsize;
+-	int cpu, nr_pages;
++	int cpu;
+ 
+ 	/* keep it in its own cache line */
+ 	buffer = kzalloc(ALIGN(sizeof(*buffer), cache_line_size()),
+@@ -1420,12 +1421,12 @@ static inline unsigned long rb_page_write(struct buffer_page *bpage)
+ }
+ 
+ static int
+-rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned int nr_pages)
++rb_remove_pages(struct ring_buffer_per_cpu *cpu_buffer, unsigned long nr_pages)
+ {
+ 	struct list_head *tail_page, *to_remove, *next_page;
+ 	struct buffer_page *to_remove_page, *tmp_iter_page;
+ 	struct buffer_page *last_page, *first_page;
+-	unsigned int nr_removed;
++	unsigned long nr_removed;
+ 	unsigned long head_bit;
+ 	int page_entries;
+ 
+@@ -1642,7 +1643,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
+ 			int cpu_id)
+ {
+ 	struct ring_buffer_per_cpu *cpu_buffer;
+-	unsigned nr_pages;
++	unsigned long nr_pages;
+ 	int cpu, err = 0;
+ 
+ 	/*
+@@ -1656,14 +1657,13 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
+ 	    !cpumask_test_cpu(cpu_id, buffer->cpumask))
+ 		return size;
+ 
+-	size = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+-	size *= BUF_PAGE_SIZE;
++	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
+ 
+ 	/* we need a minimum of two pages */
+-	if (size < BUF_PAGE_SIZE * 2)
+-		size = BUF_PAGE_SIZE * 2;
++	if (nr_pages < 2)
++		nr_pages = 2;
+ 
+-	nr_pages = DIV_ROUND_UP(size, BUF_PAGE_SIZE);
++	size = nr_pages * BUF_PAGE_SIZE;
+ 
+ 	/*
+ 	 * Don't succeed if resizing is disabled, as a reader might be
+@@ -4640,8 +4640,9 @@ static int rb_cpu_notify(struct notifier_block *self,
+ 	struct ring_buffer *buffer =
+ 		container_of(self, struct ring_buffer, cpu_notify);
+ 	long cpu = (long)hcpu;
+-	int cpu_i, nr_pages_same;
+-	unsigned int nr_pages;
++	long nr_pages_same;
++	int cpu_i;
++	unsigned long nr_pages;
+ 
+ 	switch (action) {
+ 	case CPU_UP_PREPARE:
+diff --git a/scripts/Makefile.extrawarn b/scripts/Makefile.extrawarn
+index f9e47a70509c..53449a6ff6aa 100644
+--- a/scripts/Makefile.extrawarn
++++ b/scripts/Makefile.extrawarn
+@@ -24,6 +24,7 @@ warning-1 += $(call cc-option, -Wmissing-prototypes)
+ warning-1 += -Wold-style-definition
+ warning-1 += $(call cc-option, -Wmissing-include-dirs)
+ warning-1 += $(call cc-option, -Wunused-but-set-variable)
++warning-1 += $(call cc-option, -Wunused-const-variable)
+ warning-1 += $(call cc-disable-warning, missing-field-initializers)
+ warning-1 += $(call cc-disable-warning, sign-compare)
+ 
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 4918ffa5ba68..d53c25e7a1c1 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -335,6 +335,7 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ 	case 0x10ec0283:
+ 	case 0x10ec0286:
+ 	case 0x10ec0288:
++	case 0x10ec0295:
+ 	case 0x10ec0298:
+ 		alc_update_coef_idx(codec, 0x10, 1<<9, 0);
+ 		break;
+@@ -342,6 +343,11 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ 	case 0x10ec0293:
+ 		alc_update_coef_idx(codec, 0xa, 1<<13, 0);
+ 		break;
++	case 0x10ec0234:
++	case 0x10ec0274:
++	case 0x10ec0294:
++		alc_update_coef_idx(codec, 0x10, 1<<15, 0);
++		break;
+ 	case 0x10ec0662:
+ 		if ((coef & 0x00f0) == 0x0030)
+ 			alc_update_coef_idx(codec, 0x4, 1<<10, 0); /* EAPD Ctrl */
+@@ -902,6 +908,7 @@ static struct alc_codec_rename_pci_table rename_pci_tbl[] = {
+ 	{ 0x10ec0298, 0x1028, 0, "ALC3266" },
+ 	{ 0x10ec0256, 0x1028, 0, "ALC3246" },
+ 	{ 0x10ec0225, 0x1028, 0, "ALC3253" },
++	{ 0x10ec0295, 0x1028, 0, "ALC3254" },
+ 	{ 0x10ec0670, 0x1025, 0, "ALC669X" },
+ 	{ 0x10ec0676, 0x1025, 0, "ALC679X" },
+ 	{ 0x10ec0282, 0x1043, 0, "ALC3229" },
+@@ -2647,6 +2654,7 @@ enum {
+ 	ALC269_TYPE_ALC255,
+ 	ALC269_TYPE_ALC256,
+ 	ALC269_TYPE_ALC225,
++	ALC269_TYPE_ALC294,
+ };
+ 
+ /*
+@@ -2677,6 +2685,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+ 	case ALC269_TYPE_ALC255:
+ 	case ALC269_TYPE_ALC256:
+ 	case ALC269_TYPE_ALC225:
++	case ALC269_TYPE_ALC294:
+ 		ssids = alc269_ssids;
+ 		break;
+ 	default:
+@@ -3690,6 +3699,7 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+ 		alc_process_coef_fw(codec, coef0668);
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_process_coef_fw(codec, coef0225);
+ 		break;
+ 	}
+@@ -3790,6 +3800,7 @@ static void alc_headset_mode_mic_in(struct hda_codec *codec, hda_nid_t hp_pin,
+ 		snd_hda_set_pin_ctl_cache(codec, mic_pin, PIN_VREF50);
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_update_coef_idx(codec, 0x45, 0x3f<<10, 0x31<<10);
+ 		snd_hda_set_pin_ctl_cache(codec, hp_pin, 0);
+ 		alc_process_coef_fw(codec, coef0225);
+@@ -3847,6 +3858,7 @@ static void alc_headset_mode_default(struct hda_codec *codec)
+ 
+ 	switch (codec->core.vendor_id) {
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_process_coef_fw(codec, coef0225);
+ 		break;
+ 	case 0x10ec0255:
+@@ -3950,6 +3962,7 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
+ 		alc_process_coef_fw(codec, coef0688);
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_process_coef_fw(codec, coef0225);
+ 		break;
+ 	}
+@@ -4031,6 +4044,7 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
+ 		alc_process_coef_fw(codec, coef0688);
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_process_coef_fw(codec, coef0225);
+ 		break;
+ 	}
+@@ -4114,6 +4128,7 @@ static void alc_determine_headset_type(struct hda_codec *codec)
+ 		is_ctia = (val & 0x1c02) == 0x1c02;
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		alc_process_coef_fw(codec, coef0225);
+ 		msleep(800);
+ 		val = alc_read_coef_idx(codec, 0x46);
+@@ -5459,8 +5474,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1028, 0x06de, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+ 	SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+ 	SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+-	SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
++	SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13 9350", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+ 	SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
++	SND_PCI_QUIRK(0x1028, 0x075b, "Dell XPS 13 9360", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
+ 	SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ 	SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
+@@ -5704,6 +5720,9 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x14, 0x90170110},
+ 		{0x21, 0x02211020}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x14, 0x90170130},
++		{0x21, 0x02211040}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x12, 0x90a60140},
+ 		{0x14, 0x90170110},
+ 		{0x21, 0x02211020}),
+@@ -6026,8 +6045,14 @@ static int patch_alc269(struct hda_codec *codec)
+ 		alc_update_coef_idx(codec, 0x36, 1 << 13, 1 << 5); /* Switch pcbeep path to Line in path*/
+ 		break;
+ 	case 0x10ec0225:
++	case 0x10ec0295:
+ 		spec->codec_variant = ALC269_TYPE_ALC225;
+ 		break;
++	case 0x10ec0234:
++	case 0x10ec0274:
++	case 0x10ec0294:
++		spec->codec_variant = ALC269_TYPE_ALC294;
++		break;
+ 	}
+ 
+ 	if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
+@@ -6942,6 +6967,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
+ 	HDA_CODEC_ENTRY(0x10ec0225, "ALC225", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0231, "ALC231", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0233, "ALC233", patch_alc269),
++	HDA_CODEC_ENTRY(0x10ec0234, "ALC234", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0235, "ALC233", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0255, "ALC255", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0256, "ALC256", patch_alc269),
+@@ -6952,6 +6978,7 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
+ 	HDA_CODEC_ENTRY(0x10ec0269, "ALC269", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0270, "ALC270", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0272, "ALC272", patch_alc662),
++	HDA_CODEC_ENTRY(0x10ec0274, "ALC274", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0275, "ALC275", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0276, "ALC276", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0280, "ALC280", patch_alc269),
+@@ -6964,6 +6991,8 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
+ 	HDA_CODEC_ENTRY(0x10ec0290, "ALC290", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0292, "ALC292", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0293, "ALC293", patch_alc269),
++	HDA_CODEC_ENTRY(0x10ec0294, "ALC294", patch_alc269),
++	HDA_CODEC_ENTRY(0x10ec0295, "ALC295", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0298, "ALC298", patch_alc269),
+ 	HDA_CODEC_REV_ENTRY(0x10ec0861, 0x100340, "ALC660", patch_alc861),
+ 	HDA_CODEC_ENTRY(0x10ec0660, "ALC660-VD", patch_alc861vd),
+diff --git a/tools/objtool/Makefile b/tools/objtool/Makefile
+index 6765c7e949f3..f094f3c4ed84 100644
+--- a/tools/objtool/Makefile
++++ b/tools/objtool/Makefile
+@@ -30,6 +30,10 @@ INCLUDES := -I$(srctree)/tools/include
+ CFLAGS   += -Wall -Werror $(EXTRA_WARNINGS) -fomit-frame-pointer -O2 -g $(INCLUDES)
+ LDFLAGS  += -lelf $(LIBSUBCMD)
+ 
++# Allow old libelf to be used:
++elfshdr := $(shell echo '\#include <libelf.h>' | $(CC) $(CFLAGS) -x c -E - | grep elf_getshdr)
++CFLAGS += $(if $(elfshdr),,-DLIBELF_USE_DEPRECATED)
++
+ AWK = awk
+ export srctree OUTPUT CFLAGS ARCH AWK
+ include $(srctree)/tools/build/Makefile.include
+diff --git a/tools/objtool/elf.h b/tools/objtool/elf.h
+index 7f3e00a2f907..aa1ff6596684 100644
+--- a/tools/objtool/elf.h
++++ b/tools/objtool/elf.h
+@@ -23,6 +23,11 @@
+ #include <linux/list.h>
+ #include <linux/hashtable.h>
+ 
++#ifdef LIBELF_USE_DEPRECATED
++# define elf_getshdrnum    elf_getshnum
++# define elf_getshdrstrndx elf_getshstrndx
++#endif
++
+ struct section {
+ 	struct list_head list;
+ 	GElf_Shdr sh;


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

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

commit:     2c441aecc4fae188c2eb290024668d79d0b1a51e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Jun  8 10:09:35 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Jun  8 10:09:35 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=2c441aec

Linux patch 4.6.2

 0000_README            |    4 +
 1001_linux-4.6.2.patch | 4710 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4714 insertions(+)

diff --git a/0000_README b/0000_README
index 220d627..61071b1 100644
--- a/0000_README
+++ b/0000_README
@@ -47,6 +47,10 @@ Patch:  1000_linux-4.6.1.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.1
 
+Patch:  1001_linux-4.6.2.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.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.6.2.patch b/1001_linux-4.6.2.patch
new file mode 100644
index 0000000..2da7598
--- /dev/null
+++ b/1001_linux-4.6.2.patch
@@ -0,0 +1,4710 @@
+diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
+index 1692c4dd5487..ab037f6fa2ee 100644
+--- a/Documentation/DocBook/gpu.tmpl
++++ b/Documentation/DocBook/gpu.tmpl
+@@ -1623,6 +1623,12 @@ void intel_crt_init(struct drm_device *dev)
+ !Edrivers/gpu/drm/drm_dp_helper.c
+     </sect2>
+     <sect2>
++      <title>Display Port Dual Mode Adaptor Helper Functions Reference</title>
++!Pdrivers/gpu/drm/drm_dp_dual_mode_helper.c dp dual mode helpers
++!Iinclude/drm/drm_dp_dual_mode_helper.h
++!Edrivers/gpu/drm/drm_dp_dual_mode_helper.c
++    </sect2>
++    <sect2>
+       <title>Display Port MST Helper Functions Reference</title>
+ !Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper
+ !Iinclude/drm/drm_dp_mst_helper.h
+diff --git a/Documentation/devicetree/bindings/clock/imx35-clock.txt b/Documentation/devicetree/bindings/clock/imx35-clock.txt
+index a70356452a82..f49783213c56 100644
+--- a/Documentation/devicetree/bindings/clock/imx35-clock.txt
++++ b/Documentation/devicetree/bindings/clock/imx35-clock.txt
+@@ -94,6 +94,7 @@ clocks and IDs.
+ 	csi_sel			79
+ 	iim_gate		80
+ 	gpu2d_gate		81
++	ckli_gate		82
+ 
+ Examples:
+ 
+diff --git a/Makefile b/Makefile
+index 2fcc41ea99a3..93068c2d0656 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 1
++SUBLEVEL = 2
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+@@ -364,7 +364,7 @@ AFLAGS_MODULE   =
+ LDFLAGS_MODULE  =
+ CFLAGS_KERNEL	=
+ AFLAGS_KERNEL	=
+-CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage
++CFLAGS_GCOV	= -fprofile-arcs -ftest-coverage -fno-tree-loop-im
+ CFLAGS_KCOV	= -fsanitize-coverage=trace-pc
+ 
+ 
+diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
+index 85d2c377c332..8450944b28e6 100644
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -245,7 +245,7 @@
+ 		button@2 {
+ 			label = "Factory Reset Button";
+ 			linux,code = <KEY_RESTART>;
+-			gpios = <&gpio1 15 GPIO_ACTIVE_LOW>;
++			gpios = <&gpio0 29 GPIO_ACTIVE_LOW>;
+ 		};
+ 	};
+ 
+@@ -260,7 +260,7 @@
+ 		};
+ 
+ 		sata {
+-			gpios = <&gpio1 22 GPIO_ACTIVE_HIGH>;
++			gpios = <&gpio1 22 GPIO_ACTIVE_LOW>;
+ 			default-state = "off";
+ 		};
+ 	};
+@@ -313,7 +313,7 @@
+ 
+ &pinctrl {
+ 	keys_pin: keys-pin {
+-		marvell,pins = "mpp24", "mpp47";
++		marvell,pins = "mpp24", "mpp29";
+ 		marvell,function = "gpio";
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+index b89e6cf1271a..7a461541ce50 100644
+--- a/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
++++ b/arch/arm/boot/dts/armada-xp-linksys-mamba.dts
+@@ -304,13 +304,13 @@
+ 		button@1 {
+ 			label = "WPS";
+ 			linux,code = <KEY_WPS_BUTTON>;
+-			gpios = <&gpio1 0 GPIO_ACTIVE_HIGH>;
++			gpios = <&gpio1 0 GPIO_ACTIVE_LOW>;
+ 		};
+ 
+ 		button@2 {
+ 			label = "Factory Reset Button";
+ 			linux,code = <KEY_RESTART>;
+-			gpios = <&gpio1 1 GPIO_ACTIVE_HIGH>;
++			gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+ 		};
+ 	};
+ 
+diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
+index 1df2f0bc1d76..a9fae910bb15 100644
+--- a/arch/arm/boot/dts/exynos4210-trats.dts
++++ b/arch/arm/boot/dts/exynos4210-trats.dts
+@@ -298,6 +298,8 @@
+ 		compatible = "maxim,max8997-pmic";
+ 
+ 		reg = <0x66>;
++		interrupt-parent = <&gpx0>;
++		interrupts = <7 0>;
+ 
+ 		max8997,pmic-buck1-uses-gpio-dvs;
+ 		max8997,pmic-buck2-uses-gpio-dvs;
+diff --git a/arch/arm/boot/dts/sama5d2-pinfunc.h b/arch/arm/boot/dts/sama5d2-pinfunc.h
+index b0c912feaa2f..8a394f336003 100644
+--- a/arch/arm/boot/dts/sama5d2-pinfunc.h
++++ b/arch/arm/boot/dts/sama5d2-pinfunc.h
+@@ -837,8 +837,8 @@
+ #define PIN_PD23__ISC_FIELD		PINMUX_PIN(PIN_PD23, 6, 4)
+ #define PIN_PD24			120
+ #define PIN_PD24__GPIO			PINMUX_PIN(PIN_PD24, 0, 0)
+-#define PIN_PD24__UTXD2			PINMUX_PIN(PIN_PD23, 1, 2)
+-#define PIN_PD24__FLEXCOM4_IO3		PINMUX_PIN(PIN_PD23, 3, 3)
++#define PIN_PD24__UTXD2			PINMUX_PIN(PIN_PD24, 1, 2)
++#define PIN_PD24__FLEXCOM4_IO3		PINMUX_PIN(PIN_PD24, 3, 3)
+ #define PIN_PD25			121
+ #define PIN_PD25__GPIO			PINMUX_PIN(PIN_PD25, 0, 0)
+ #define PIN_PD25__SPI1_SPCK		PINMUX_PIN(PIN_PD25, 1, 3)
+diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
+index 2c8f5e6ad905..bf70d0ae93ce 100644
+--- a/arch/arm/boot/dts/sun4i-a10.dtsi
++++ b/arch/arm/boot/dts/sun4i-a10.dtsi
+@@ -96,7 +96,7 @@
+ 			allwinner,pipeline = "de_fe0-de_be0-lcd0-tve0";
+ 			clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+ 				 <&ahb_gates 44>, <&ahb_gates 46>,
+-				 <&dram_gates 25>, <&dram_gates 26>;
++				 <&dram_gates 5>, <&dram_gates 25>, <&dram_gates 26>;
+ 			status = "disabled";
+ 		};
+ 	};
+diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
+index 0940a788f824..ee4e8e7d3e30 100644
+--- a/arch/arm/boot/dts/sun7i-a20.dtsi
++++ b/arch/arm/boot/dts/sun7i-a20.dtsi
+@@ -85,8 +85,9 @@
+ 			compatible = "allwinner,simple-framebuffer",
+ 				     "simple-framebuffer";
+ 			allwinner,pipeline = "de_be0-lcd0-tve0";
+-			clocks = <&pll5 1>, <&ahb_gates 34>, <&ahb_gates 36>,
+-				 <&ahb_gates 44>, <&dram_gates 26>;
++			clocks = <&pll5 1>,
++				 <&ahb_gates 34>, <&ahb_gates 36>, <&ahb_gates 44>,
++				 <&dram_gates 5>, <&dram_gates 26>;
+ 			status = "disabled";
+ 		};
+ 	};
+diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
+index b955fafc58ba..d1adc59af5bf 100644
+--- a/arch/mips/ath79/early_printk.c
++++ b/arch/mips/ath79/early_printk.c
+@@ -31,13 +31,15 @@ static inline void prom_putchar_wait(void __iomem *reg, u32 mask, u32 val)
+ 	} while (1);
+ }
+ 
++#define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
++
+ static void prom_putchar_ar71xx(unsigned char ch)
+ {
+ 	void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+ 
+-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
++	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
+ 	__raw_writel(ch, base + UART_TX * 4);
+-	prom_putchar_wait(base + UART_LSR * 4, UART_LSR_THRE, UART_LSR_THRE);
++	prom_putchar_wait(base + UART_LSR * 4, BOTH_EMPTY, BOTH_EMPTY);
+ }
+ 
+ static void prom_putchar_ar933x(unsigned char ch)
+diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h
+index 867f924b05c7..e689b894353c 100644
+--- a/arch/mips/include/asm/asmmacro.h
++++ b/arch/mips/include/asm/asmmacro.h
+@@ -298,21 +298,21 @@
+ 	.set	pop
+ 	.endm
+ 
+-	.macro	copy_u_w	ws, n
++	.macro	copy_s_w	ws, n
+ 	.set	push
+ 	.set	mips32r2
+ 	.set	fp=64
+ 	.set	msa
+-	copy_u.w $1, $w\ws[\n]
++	copy_s.w $1, $w\ws[\n]
+ 	.set	pop
+ 	.endm
+ 
+-	.macro	copy_u_d	ws, n
++	.macro	copy_s_d	ws, n
+ 	.set	push
+ 	.set	mips64r2
+ 	.set	fp=64
+ 	.set	msa
+-	copy_u.d $1, $w\ws[\n]
++	copy_s.d $1, $w\ws[\n]
+ 	.set	pop
+ 	.endm
+ 
+@@ -346,8 +346,8 @@
+ #define STH_MSA_INSN		0x5800081f
+ #define STW_MSA_INSN		0x5800082f
+ #define STD_MSA_INSN		0x5800083f
+-#define COPY_UW_MSA_INSN	0x58f00056
+-#define COPY_UD_MSA_INSN	0x58f80056
++#define COPY_SW_MSA_INSN	0x58b00056
++#define COPY_SD_MSA_INSN	0x58b80056
+ #define INSERT_W_MSA_INSN	0x59300816
+ #define INSERT_D_MSA_INSN	0x59380816
+ #else
+@@ -361,8 +361,8 @@
+ #define STH_MSA_INSN		0x78000825
+ #define STW_MSA_INSN		0x78000826
+ #define STD_MSA_INSN		0x78000827
+-#define COPY_UW_MSA_INSN	0x78f00059
+-#define COPY_UD_MSA_INSN	0x78f80059
++#define COPY_SW_MSA_INSN	0x78b00059
++#define COPY_SD_MSA_INSN	0x78b80059
+ #define INSERT_W_MSA_INSN	0x79300819
+ #define INSERT_D_MSA_INSN	0x79380819
+ #endif
+@@ -393,7 +393,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	LDB_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -402,7 +402,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	LDH_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -411,7 +411,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	LDW_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -420,7 +420,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	LDD_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -429,7 +429,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	STB_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -438,7 +438,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	STH_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -447,7 +447,7 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	STW_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+@@ -456,26 +456,26 @@
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+-	addu	$1, \base, \off
++	PTR_ADDU $1, \base, \off
+ 	.word	STD_MSA_INSN | (\wd << 6)
+ 	.set	pop
+ 	.endm
+ 
+-	.macro	copy_u_w	ws, n
++	.macro	copy_s_w	ws, n
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+ 	.insn
+-	.word	COPY_UW_MSA_INSN | (\n << 16) | (\ws << 11)
++	.word	COPY_SW_MSA_INSN | (\n << 16) | (\ws << 11)
+ 	.set	pop
+ 	.endm
+ 
+-	.macro	copy_u_d	ws, n
++	.macro	copy_s_d	ws, n
+ 	.set	push
+ 	.set	noat
+ 	SET_HARDFLOAT
+ 	.insn
+-	.word	COPY_UD_MSA_INSN | (\n << 16) | (\ws << 11)
++	.word	COPY_SD_MSA_INSN | (\n << 16) | (\ws << 11)
+ 	.set	pop
+ 	.endm
+ 
+diff --git a/arch/mips/include/asm/cacheflush.h b/arch/mips/include/asm/cacheflush.h
+index 723229f4cf27..176de586a71a 100644
+--- a/arch/mips/include/asm/cacheflush.h
++++ b/arch/mips/include/asm/cacheflush.h
+@@ -51,7 +51,6 @@ extern void (*flush_cache_range)(struct vm_area_struct *vma,
+ 	unsigned long start, unsigned long end);
+ extern void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page, unsigned long pfn);
+ extern void __flush_dcache_page(struct page *page);
+-extern void __flush_icache_page(struct vm_area_struct *vma, struct page *page);
+ 
+ #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1
+ static inline void flush_dcache_page(struct page *page)
+@@ -77,11 +76,6 @@ static inline void flush_anon_page(struct vm_area_struct *vma,
+ static inline void flush_icache_page(struct vm_area_struct *vma,
+ 	struct page *page)
+ {
+-	if (!cpu_has_ic_fills_f_dc && (vma->vm_flags & VM_EXEC) &&
+-	    Page_dcache_dirty(page)) {
+-		__flush_icache_page(vma, page);
+-		ClearPageDcacheDirty(page);
+-	}
+ }
+ 
+ extern void (*flush_icache_range)(unsigned long start, unsigned long end);
+diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h
+index bbb85fe21642..6e4effa6f626 100644
+--- a/arch/mips/include/asm/msa.h
++++ b/arch/mips/include/asm/msa.h
+@@ -147,6 +147,19 @@ static inline void restore_msa(struct task_struct *t)
+ 		_restore_msa(t);
+ }
+ 
++static inline void init_msa_upper(void)
++{
++	/*
++	 * Check cpu_has_msa only if it's a constant. This will allow the
++	 * compiler to optimise out code for CPUs without MSA without adding
++	 * an extra redundant check for CPUs with MSA.
++	 */
++	if (__builtin_constant_p(cpu_has_msa) && !cpu_has_msa)
++		return;
++
++	_init_msa_upper();
++}
++
+ #ifdef TOOLCHAIN_SUPPORTS_MSA
+ 
+ #define __BUILD_MSA_CTL_REG(name, cs)				\
+diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
+index 9a4fe0133ff1..65bf2c065db5 100644
+--- a/arch/mips/include/asm/pgtable.h
++++ b/arch/mips/include/asm/pgtable.h
+@@ -127,10 +127,14 @@ do {									\
+ 	}								\
+ } while(0)
+ 
++static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
++			      pte_t *ptep, pte_t pteval);
++
+ #if defined(CONFIG_PHYS_ADDR_T_64BIT) && defined(CONFIG_CPU_MIPS32)
+ 
+ #define pte_none(pte)		(!(((pte).pte_high) & ~_PAGE_GLOBAL))
+ #define pte_present(pte)	((pte).pte_low & _PAGE_PRESENT)
++#define pte_no_exec(pte)	((pte).pte_low & _PAGE_NO_EXEC)
+ 
+ static inline void set_pte(pte_t *ptep, pte_t pte)
+ {
+@@ -148,7 +152,6 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
+ 			buddy->pte_high |= _PAGE_GLOBAL;
+ 	}
+ }
+-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+ 
+ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ {
+@@ -166,6 +169,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
+ 
+ #define pte_none(pte)		(!(pte_val(pte) & ~_PAGE_GLOBAL))
+ #define pte_present(pte)	(pte_val(pte) & _PAGE_PRESENT)
++#define pte_no_exec(pte)	(pte_val(pte) & _PAGE_NO_EXEC)
+ 
+ /*
+  * Certain architectures need to do special things when pte's
+@@ -218,7 +222,6 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
+ 	}
+ #endif
+ }
+-#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+ 
+ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep)
+ {
+@@ -234,6 +237,22 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
+ }
+ #endif
+ 
++static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
++			      pte_t *ptep, pte_t pteval)
++{
++	extern void __update_cache(unsigned long address, pte_t pte);
++
++	if (!pte_present(pteval))
++		goto cache_sync_done;
++
++	if (pte_present(*ptep) && (pte_pfn(*ptep) == pte_pfn(pteval)))
++		goto cache_sync_done;
++
++	__update_cache(addr, pteval);
++cache_sync_done:
++	set_pte(ptep, pteval);
++}
++
+ /*
+  * (pmds are folded into puds so this doesn't get actually called,
+  * but the define is needed for a generic inline function.)
+@@ -430,15 +449,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
+ 
+ extern void __update_tlb(struct vm_area_struct *vma, unsigned long address,
+ 	pte_t pte);
+-extern void __update_cache(struct vm_area_struct *vma, unsigned long address,
+-	pte_t pte);
+ 
+ static inline void update_mmu_cache(struct vm_area_struct *vma,
+ 	unsigned long address, pte_t *ptep)
+ {
+ 	pte_t pte = *ptep;
+ 	__update_tlb(vma, address, pte);
+-	__update_cache(vma, address, pte);
+ }
+ 
+ static inline void update_mmu_cache_pmd(struct vm_area_struct *vma,
+diff --git a/arch/mips/include/asm/switch_to.h b/arch/mips/include/asm/switch_to.h
+index 28b5d84a5022..ebb5c0f2f90d 100644
+--- a/arch/mips/include/asm/switch_to.h
++++ b/arch/mips/include/asm/switch_to.h
+@@ -105,7 +105,7 @@ do {									\
+ 	__clear_software_ll_bit();					\
+ 	if (cpu_has_userlocal)						\
+ 		write_c0_userlocal(task_thread_info(next)->tp_value);	\
+-	__restore_watch();						\
++	__restore_watch(next);						\
+ 	(last) = resume(prev, next, task_thread_info(next));		\
+ } while (0)
+ 
+diff --git a/arch/mips/include/asm/watch.h b/arch/mips/include/asm/watch.h
+index 20126ec79359..6ffe3eadf105 100644
+--- a/arch/mips/include/asm/watch.h
++++ b/arch/mips/include/asm/watch.h
+@@ -12,21 +12,21 @@
+ 
+ #include <asm/mipsregs.h>
+ 
+-void mips_install_watch_registers(void);
++void mips_install_watch_registers(struct task_struct *t);
+ void mips_read_watch_registers(void);
+ void mips_clear_watch_registers(void);
+ void mips_probe_watch_registers(struct cpuinfo_mips *c);
+ 
+ #ifdef CONFIG_HARDWARE_WATCHPOINTS
+-#define __restore_watch() do {						\
++#define __restore_watch(task) do {					\
+ 	if (unlikely(test_bit(TIF_LOAD_WATCH,				\
+-			      &current_thread_info()->flags))) {	\
+-		mips_install_watch_registers();				\
++			      &task_thread_info(task)->flags))) {	\
++		mips_install_watch_registers(task);			\
+ 	}								\
+ } while (0)
+ 
+ #else
+-#define __restore_watch() do {} while (0)
++#define __restore_watch(task) do {} while (0)
+ #endif
+ 
+ #endif /* _ASM_WATCH_H */
+diff --git a/arch/mips/include/uapi/asm/siginfo.h b/arch/mips/include/uapi/asm/siginfo.h
+index cc49dc240d67..8069cf766603 100644
+--- a/arch/mips/include/uapi/asm/siginfo.h
++++ b/arch/mips/include/uapi/asm/siginfo.h
+@@ -28,7 +28,7 @@
+ 
+ #define __ARCH_SIGSYS
+ 
+-#include <uapi/asm-generic/siginfo.h>
++#include <asm-generic/siginfo.h>
+ 
+ /* We can't use generic siginfo_t, because our si_code and si_errno are swapped */
+ typedef struct siginfo {
+@@ -42,13 +42,13 @@ typedef struct siginfo {
+ 
+ 		/* kill() */
+ 		struct {
+-			pid_t _pid;		/* sender's pid */
++			__kernel_pid_t _pid;	/* sender's pid */
+ 			__ARCH_SI_UID_T _uid;	/* sender's uid */
+ 		} _kill;
+ 
+ 		/* POSIX.1b timers */
+ 		struct {
+-			timer_t _tid;		/* timer id */
++			__kernel_timer_t _tid;	/* timer id */
+ 			int _overrun;		/* overrun count */
+ 			char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
+ 			sigval_t _sigval;	/* same as below */
+@@ -57,26 +57,26 @@ typedef struct siginfo {
+ 
+ 		/* POSIX.1b signals */
+ 		struct {
+-			pid_t _pid;		/* sender's pid */
++			__kernel_pid_t _pid;	/* sender's pid */
+ 			__ARCH_SI_UID_T _uid;	/* sender's uid */
+ 			sigval_t _sigval;
+ 		} _rt;
+ 
+ 		/* SIGCHLD */
+ 		struct {
+-			pid_t _pid;		/* which child */
++			__kernel_pid_t _pid;	/* which child */
+ 			__ARCH_SI_UID_T _uid;	/* sender's uid */
+ 			int _status;		/* exit code */
+-			clock_t _utime;
+-			clock_t _stime;
++			__kernel_clock_t _utime;
++			__kernel_clock_t _stime;
+ 		} _sigchld;
+ 
+ 		/* IRIX SIGCHLD */
+ 		struct {
+-			pid_t _pid;		/* which child */
+-			clock_t _utime;
++			__kernel_pid_t _pid;	/* which child */
++			__kernel_clock_t _utime;
+ 			int _status;		/* exit code */
+-			clock_t _stime;
++			__kernel_clock_t _stime;
+ 		} _irix_sigchld;
+ 
+ 		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+@@ -123,6 +123,4 @@ typedef struct siginfo {
+ #define SI_TIMER __SI_CODE(__SI_TIMER, -3) /* sent by timer expiration */
+ #define SI_MESGQ __SI_CODE(__SI_MESGQ, -4) /* sent by real time mesq state change */
+ 
+-#include <asm-generic/siginfo.h>
+-
+ #endif /* _UAPI_ASM_SIGINFO_H */
+diff --git a/arch/mips/kernel/mips-r2-to-r6-emul.c b/arch/mips/kernel/mips-r2-to-r6-emul.c
+index 3fff89ae760b..625ee770b1aa 100644
+--- a/arch/mips/kernel/mips-r2-to-r6-emul.c
++++ b/arch/mips/kernel/mips-r2-to-r6-emul.c
+@@ -28,6 +28,7 @@
+ #include <asm/inst.h>
+ #include <asm/mips-r2-to-r6-emul.h>
+ #include <asm/local.h>
++#include <asm/mipsregs.h>
+ #include <asm/ptrace.h>
+ #include <asm/uaccess.h>
+ 
+@@ -1251,10 +1252,10 @@ fpu_emul:
+ 			"	j	10b\n"
+ 			"	.previous\n"
+ 			"	.section	__ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1326,10 +1327,10 @@ fpu_emul:
+ 			"	j	10b\n"
+ 			"       .previous\n"
+ 			"	.section	__ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1397,10 +1398,10 @@ fpu_emul:
+ 			"	j	9b\n"
+ 			"	.previous\n"
+ 			"	.section        __ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1467,10 +1468,10 @@ fpu_emul:
+ 			"	j	9b\n"
+ 			"	.previous\n"
+ 			"	.section        __ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1582,14 +1583,14 @@ fpu_emul:
+ 			"	j	9b\n"
+ 			"	.previous\n"
+ 			"	.section        __ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
+-			"	.word	5b,8b\n"
+-			"	.word	6b,8b\n"
+-			"	.word	7b,8b\n"
+-			"	.word	0b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
++			STR(PTR) " 5b,8b\n"
++			STR(PTR) " 6b,8b\n"
++			STR(PTR) " 7b,8b\n"
++			STR(PTR) " 0b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1701,14 +1702,14 @@ fpu_emul:
+ 			"	j      9b\n"
+ 			"	.previous\n"
+ 			"	.section        __ex_table,\"a\"\n"
+-			"	.word  1b,8b\n"
+-			"	.word  2b,8b\n"
+-			"	.word  3b,8b\n"
+-			"	.word  4b,8b\n"
+-			"	.word  5b,8b\n"
+-			"	.word  6b,8b\n"
+-			"	.word  7b,8b\n"
+-			"	.word  0b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
++			STR(PTR) " 5b,8b\n"
++			STR(PTR) " 6b,8b\n"
++			STR(PTR) " 7b,8b\n"
++			STR(PTR) " 0b,8b\n"
+ 			"	.previous\n"
+ 			"	.set    pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1820,14 +1821,14 @@ fpu_emul:
+ 			"	j	9b\n"
+ 			"	.previous\n"
+ 			"	.section        __ex_table,\"a\"\n"
+-			"	.word	1b,8b\n"
+-			"	.word	2b,8b\n"
+-			"	.word	3b,8b\n"
+-			"	.word	4b,8b\n"
+-			"	.word	5b,8b\n"
+-			"	.word	6b,8b\n"
+-			"	.word	7b,8b\n"
+-			"	.word	0b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
++			STR(PTR) " 5b,8b\n"
++			STR(PTR) " 6b,8b\n"
++			STR(PTR) " 7b,8b\n"
++			STR(PTR) " 0b,8b\n"
+ 			"	.previous\n"
+ 			"	.set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -1938,14 +1939,14 @@ fpu_emul:
+ 			"       j	9b\n"
+ 			"       .previous\n"
+ 			"       .section        __ex_table,\"a\"\n"
+-			"       .word	1b,8b\n"
+-			"       .word	2b,8b\n"
+-			"       .word	3b,8b\n"
+-			"       .word	4b,8b\n"
+-			"       .word	5b,8b\n"
+-			"       .word	6b,8b\n"
+-			"       .word	7b,8b\n"
+-			"       .word	0b,8b\n"
++			STR(PTR) " 1b,8b\n"
++			STR(PTR) " 2b,8b\n"
++			STR(PTR) " 3b,8b\n"
++			STR(PTR) " 4b,8b\n"
++			STR(PTR) " 5b,8b\n"
++			STR(PTR) " 6b,8b\n"
++			STR(PTR) " 7b,8b\n"
++			STR(PTR) " 0b,8b\n"
+ 			"       .previous\n"
+ 			"       .set	pop\n"
+ 			: "+&r"(rt), "=&r"(rs),
+@@ -2000,7 +2001,7 @@ fpu_emul:
+ 			"j	2b\n"
+ 			".previous\n"
+ 			".section        __ex_table,\"a\"\n"
+-			".word  1b, 3b\n"
++			STR(PTR) " 1b,3b\n"
+ 			".previous\n"
+ 			: "=&r"(res), "+&r"(err)
+ 			: "r"(vaddr), "i"(SIGSEGV)
+@@ -2058,7 +2059,7 @@ fpu_emul:
+ 			"j	2b\n"
+ 			".previous\n"
+ 			".section        __ex_table,\"a\"\n"
+-			".word	1b, 3b\n"
++			STR(PTR) " 1b,3b\n"
+ 			".previous\n"
+ 			: "+&r"(res), "+&r"(err)
+ 			: "r"(vaddr), "i"(SIGSEGV));
+@@ -2119,7 +2120,7 @@ fpu_emul:
+ 			"j	2b\n"
+ 			".previous\n"
+ 			".section        __ex_table,\"a\"\n"
+-			".word  1b, 3b\n"
++			STR(PTR) " 1b,3b\n"
+ 			".previous\n"
+ 			: "=&r"(res), "+&r"(err)
+ 			: "r"(vaddr), "i"(SIGSEGV)
+@@ -2182,7 +2183,7 @@ fpu_emul:
+ 			"j	2b\n"
+ 			".previous\n"
+ 			".section        __ex_table,\"a\"\n"
+-			".word	1b, 3b\n"
++			STR(PTR) " 1b,3b\n"
+ 			".previous\n"
+ 			: "+&r"(res), "+&r"(err)
+ 			: "r"(vaddr), "i"(SIGSEGV));
+diff --git a/arch/mips/kernel/pm.c b/arch/mips/kernel/pm.c
+index fefdf39d3df3..dc814892133c 100644
+--- a/arch/mips/kernel/pm.c
++++ b/arch/mips/kernel/pm.c
+@@ -56,7 +56,7 @@ static void mips_cpu_restore(void)
+ 		write_c0_userlocal(current_thread_info()->tp_value);
+ 
+ 	/* Restore watch registers */
+-	__restore_watch();
++	__restore_watch(current);
+ }
+ 
+ /**
+diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c
+index 92880cee449e..d83730cd2719 100644
+--- a/arch/mips/kernel/process.c
++++ b/arch/mips/kernel/process.c
+@@ -455,7 +455,7 @@ unsigned long notrace unwind_stack_by_address(unsigned long stack_page,
+ 		    *sp + sizeof(*regs) <= stack_page + THREAD_SIZE - 32) {
+ 			regs = (struct pt_regs *)*sp;
+ 			pc = regs->cp0_epc;
+-			if (__kernel_text_address(pc)) {
++			if (!user_mode(regs) && __kernel_text_address(pc)) {
+ 				*sp = regs->regs[29];
+ 				*ra = regs->regs[31];
+ 				return pc;
+@@ -580,11 +580,19 @@ int mips_get_process_fp_mode(struct task_struct *task)
+ 	return value;
+ }
+ 
++static void prepare_for_fp_mode_switch(void *info)
++{
++	struct mm_struct *mm = info;
++
++	if (current->mm == mm)
++		lose_fpu(1);
++}
++
+ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ {
+ 	const unsigned int known_bits = PR_FP_MODE_FR | PR_FP_MODE_FRE;
+-	unsigned long switch_count;
+ 	struct task_struct *t;
++	int max_users;
+ 
+ 	/* Check the value is valid */
+ 	if (value & ~known_bits)
+@@ -601,6 +609,9 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 	if (!(value & PR_FP_MODE_FR) && cpu_has_fpu && cpu_has_mips_r6)
+ 		return -EOPNOTSUPP;
+ 
++	/* Proceed with the mode switch */
++	preempt_disable();
++
+ 	/* Save FP & vector context, then disable FPU & MSA */
+ 	if (task->signal == current->signal)
+ 		lose_fpu(1);
+@@ -610,31 +621,17 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 	smp_mb__after_atomic();
+ 
+ 	/*
+-	 * If there are multiple online CPUs then wait until all threads whose
+-	 * FP mode is about to change have been context switched. This approach
+-	 * allows us to only worry about whether an FP mode switch is in
+-	 * progress when FP is first used in a tasks time slice. Pretty much all
+-	 * of the mode switch overhead can thus be confined to cases where mode
+-	 * switches are actually occurring. That is, to here. However for the
+-	 * thread performing the mode switch it may take a while...
++	 * If there are multiple online CPUs then force any which are running
++	 * threads in this process to lose their FPU context, which they can't
++	 * regain until fp_mode_switching is cleared later.
+ 	 */
+ 	if (num_online_cpus() > 1) {
+-		spin_lock_irq(&task->sighand->siglock);
+-
+-		for_each_thread(task, t) {
+-			if (t == current)
+-				continue;
+-
+-			switch_count = t->nvcsw + t->nivcsw;
++		/* No need to send an IPI for the local CPU */
++		max_users = (task->mm == current->mm) ? 1 : 0;
+ 
+-			do {
+-				spin_unlock_irq(&task->sighand->siglock);
+-				cond_resched();
+-				spin_lock_irq(&task->sighand->siglock);
+-			} while ((t->nvcsw + t->nivcsw) == switch_count);
+-		}
+-
+-		spin_unlock_irq(&task->sighand->siglock);
++		if (atomic_read(&current->mm->mm_users) > max_users)
++			smp_call_function(prepare_for_fp_mode_switch,
++					  (void *)current->mm, 1);
+ 	}
+ 
+ 	/*
+@@ -659,6 +656,7 @@ int mips_set_process_fp_mode(struct task_struct *task, unsigned int value)
+ 
+ 	/* Allow threads to use FP again */
+ 	atomic_set(&task->mm->context.fp_mode_switching, 0);
++	preempt_enable();
+ 
+ 	return 0;
+ }
+diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
+index a5279b2f3198..4285d8b7c566 100644
+--- a/arch/mips/kernel/ptrace.c
++++ b/arch/mips/kernel/ptrace.c
+@@ -57,8 +57,7 @@ static void init_fp_ctx(struct task_struct *target)
+ 	/* Begin with data registers set to all 1s... */
+ 	memset(&target->thread.fpu.fpr, ~0, sizeof(target->thread.fpu.fpr));
+ 
+-	/* ...and FCSR zeroed */
+-	target->thread.fpu.fcr31 = 0;
++	/* FCSR has been preset by `mips_set_personality_nan'.  */
+ 
+ 	/*
+ 	 * Record that the target has "used" math, such that the context
+@@ -80,6 +79,22 @@ void ptrace_disable(struct task_struct *child)
+ }
+ 
+ /*
++ * Poke at FCSR according to its mask.  Don't set the cause bits as
++ * this is currently not handled correctly in FP context restoration
++ * and will cause an oops if a corresponding enable bit is set.
++ */
++static void ptrace_setfcr31(struct task_struct *child, u32 value)
++{
++	u32 fcr31;
++	u32 mask;
++
++	value &= ~FPU_CSR_ALL_X;
++	fcr31 = child->thread.fpu.fcr31;
++	mask = boot_cpu_data.fpu_msk31;
++	child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
++}
++
++/*
+  * Read a general register set.	 We always use the 64-bit format, even
+  * for 32-bit kernels and for 32-bit processes on a 64-bit kernel.
+  * Registers are sign extended to fill the available space.
+@@ -159,9 +174,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
+ {
+ 	union fpureg *fregs;
+ 	u64 fpr_val;
+-	u32 fcr31;
+ 	u32 value;
+-	u32 mask;
+ 	int i;
+ 
+ 	if (!access_ok(VERIFY_READ, data, 33 * 8))
+@@ -176,9 +189,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data)
+ 	}
+ 
+ 	__get_user(value, data + 64);
+-	fcr31 = child->thread.fpu.fcr31;
+-	mask = boot_cpu_data.fpu_msk31;
+-	child->thread.fpu.fcr31 = (value & ~mask) | (fcr31 & mask);
++	ptrace_setfcr31(child, value);
+ 
+ 	/* FIR may not be written.  */
+ 
+@@ -805,7 +816,7 @@ long arch_ptrace(struct task_struct *child, long request,
+ 			break;
+ #endif
+ 		case FPC_CSR:
+-			child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X;
++			ptrace_setfcr31(child, data);
+ 			break;
+ 		case DSP_BASE ... DSP_BASE + 5: {
+ 			dspreg_t *dregs;
+diff --git a/arch/mips/kernel/r4k_fpu.S b/arch/mips/kernel/r4k_fpu.S
+index 17732f876eff..56d86b09c917 100644
+--- a/arch/mips/kernel/r4k_fpu.S
++++ b/arch/mips/kernel/r4k_fpu.S
+@@ -244,17 +244,17 @@ LEAF(\name)
+ 	.set	push
+ 	.set	noat
+ #ifdef CONFIG_64BIT
+-	copy_u_d \wr, 1
++	copy_s_d \wr, 1
+ 	EX sd	$1, \off(\base)
+ #elif defined(CONFIG_CPU_LITTLE_ENDIAN)
+-	copy_u_w \wr, 2
++	copy_s_w \wr, 2
+ 	EX sw	$1, \off(\base)
+-	copy_u_w \wr, 3
++	copy_s_w \wr, 3
+ 	EX sw	$1, (\off+4)(\base)
+ #else /* CONFIG_CPU_BIG_ENDIAN */
+-	copy_u_w \wr, 2
++	copy_s_w \wr, 2
+ 	EX sw	$1, (\off+4)(\base)
+-	copy_u_w \wr, 3
++	copy_s_w \wr, 3
+ 	EX sw	$1, \off(\base)
+ #endif
+ 	.set	pop
+diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
+index 4f607341a793..d20caacfdbd3 100644
+--- a/arch/mips/kernel/setup.c
++++ b/arch/mips/kernel/setup.c
+@@ -706,6 +706,9 @@ static void __init arch_mem_init(char **cmdline_p)
+ 	for_each_memblock(reserved, reg)
+ 		if (reg->size != 0)
+ 			reserve_bootmem(reg->base, reg->size, BOOTMEM_DEFAULT);
++
++	reserve_bootmem_region(__pa_symbol(&__nosave_begin),
++			__pa_symbol(&__nosave_end)); /* Reserve for hibernation */
+ }
+ 
+ static void __init resource_init(void)
+diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
+index bf792e2839a6..9e35b6b26aa8 100644
+--- a/arch/mips/kernel/signal.c
++++ b/arch/mips/kernel/signal.c
+@@ -195,6 +195,9 @@ static int restore_msa_extcontext(void __user *buf, unsigned int size)
+ 	unsigned int csr;
+ 	int i, err;
+ 
++	if (!config_enabled(CONFIG_CPU_HAS_MSA))
++		return SIGSYS;
++
+ 	if (size != sizeof(*msa))
+ 		return -EINVAL;
+ 
+@@ -398,8 +401,8 @@ int protected_restore_fp_context(void __user *sc)
+ 	}
+ 
+ fp_done:
+-	if (used & USED_EXTCONTEXT)
+-		err |= restore_extcontext(sc_to_extcontext(sc));
++	if (!err && (used & USED_EXTCONTEXT))
++		err = restore_extcontext(sc_to_extcontext(sc));
+ 
+ 	return err ?: sig;
+ }
+@@ -767,15 +770,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
+ 	sigset_t *oldset = sigmask_to_save();
+ 	int ret;
+ 	struct mips_abi *abi = current->thread.abi;
+-#ifdef CONFIG_CPU_MICROMIPS
+-	void *vdso;
+-	unsigned long tmp = (unsigned long)current->mm->context.vdso;
+-
+-	set_isa16_mode(tmp);
+-	vdso = (void *)tmp;
+-#else
+ 	void *vdso = current->mm->context.vdso;
+-#endif
+ 
+ 	if (regs->regs[0]) {
+ 		switch(regs->regs[2]) {
+diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
+index ae0c89d23ad7..5aa1d5c2659a 100644
+--- a/arch/mips/kernel/traps.c
++++ b/arch/mips/kernel/traps.c
+@@ -145,7 +145,7 @@ static void show_backtrace(struct task_struct *task, const struct pt_regs *regs)
+ 	if (!task)
+ 		task = current;
+ 
+-	if (raw_show_trace || !__kernel_text_address(pc)) {
++	if (raw_show_trace || user_mode(regs) || !__kernel_text_address(pc)) {
+ 		show_raw_backtrace(sp);
+ 		return;
+ 	}
+@@ -1249,7 +1249,7 @@ static int enable_restore_fp_context(int msa)
+ 		err = init_fpu();
+ 		if (msa && !err) {
+ 			enable_msa();
+-			_init_msa_upper();
++			init_msa_upper();
+ 			set_thread_flag(TIF_USEDMSA);
+ 			set_thread_flag(TIF_MSA_CTX_LIVE);
+ 		}
+@@ -1312,7 +1312,7 @@ static int enable_restore_fp_context(int msa)
+ 	 */
+ 	prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE);
+ 	if (!prior_msa && was_fpu_owner) {
+-		_init_msa_upper();
++		init_msa_upper();
+ 
+ 		goto out;
+ 	}
+@@ -1329,7 +1329,7 @@ static int enable_restore_fp_context(int msa)
+ 		 * of each vector register such that it cannot see data left
+ 		 * behind by another task.
+ 		 */
+-		_init_msa_upper();
++		init_msa_upper();
+ 	} else {
+ 		/* We need to restore the vector context. */
+ 		restore_msa(current);
+diff --git a/arch/mips/kernel/watch.c b/arch/mips/kernel/watch.c
+index 2a03abb5bd2c..9b78e375118e 100644
+--- a/arch/mips/kernel/watch.c
++++ b/arch/mips/kernel/watch.c
+@@ -15,10 +15,9 @@
+  * Install the watch registers for the current thread.	A maximum of
+  * four registers are installed although the machine may have more.
+  */
+-void mips_install_watch_registers(void)
++void mips_install_watch_registers(struct task_struct *t)
+ {
+-	struct mips3264_watch_reg_state *watches =
+-		&current->thread.watch.mips3264;
++	struct mips3264_watch_reg_state *watches = &t->thread.watch.mips3264;
+ 	switch (current_cpu_data.watch_reg_use_cnt) {
+ 	default:
+ 		BUG();
+diff --git a/arch/mips/lib/ashldi3.c b/arch/mips/lib/ashldi3.c
+index beb80f316095..927dc94a030f 100644
+--- a/arch/mips/lib/ashldi3.c
++++ b/arch/mips/lib/ashldi3.c
+@@ -2,7 +2,7 @@
+ 
+ #include "libgcc.h"
+ 
+-long long __ashldi3(long long u, word_type b)
++long long notrace __ashldi3(long long u, word_type b)
+ {
+ 	DWunion uu, w;
+ 	word_type bm;
+diff --git a/arch/mips/lib/ashrdi3.c b/arch/mips/lib/ashrdi3.c
+index c884a912b660..9fdf1a598428 100644
+--- a/arch/mips/lib/ashrdi3.c
++++ b/arch/mips/lib/ashrdi3.c
+@@ -2,7 +2,7 @@
+ 
+ #include "libgcc.h"
+ 
+-long long __ashrdi3(long long u, word_type b)
++long long notrace __ashrdi3(long long u, word_type b)
+ {
+ 	DWunion uu, w;
+ 	word_type bm;
+diff --git a/arch/mips/lib/bswapdi.c b/arch/mips/lib/bswapdi.c
+index 77e5f9c1f005..e3e77aa52c95 100644
+--- a/arch/mips/lib/bswapdi.c
++++ b/arch/mips/lib/bswapdi.c
+@@ -1,6 +1,6 @@
+ #include <linux/module.h>
+ 
+-unsigned long long __bswapdi2(unsigned long long u)
++unsigned long long notrace __bswapdi2(unsigned long long u)
+ {
+ 	return (((u) & 0xff00000000000000ull) >> 56) |
+ 	       (((u) & 0x00ff000000000000ull) >> 40) |
+diff --git a/arch/mips/lib/bswapsi.c b/arch/mips/lib/bswapsi.c
+index 2b302ff121d2..530a8afe6fda 100644
+--- a/arch/mips/lib/bswapsi.c
++++ b/arch/mips/lib/bswapsi.c
+@@ -1,6 +1,6 @@
+ #include <linux/module.h>
+ 
+-unsigned int __bswapsi2(unsigned int u)
++unsigned int notrace __bswapsi2(unsigned int u)
+ {
+ 	return (((u) & 0xff000000) >> 24) |
+ 	       (((u) & 0x00ff0000) >>  8) |
+diff --git a/arch/mips/lib/cmpdi2.c b/arch/mips/lib/cmpdi2.c
+index 8c1306437ed1..06857da96993 100644
+--- a/arch/mips/lib/cmpdi2.c
++++ b/arch/mips/lib/cmpdi2.c
+@@ -2,7 +2,7 @@
+ 
+ #include "libgcc.h"
+ 
+-word_type __cmpdi2(long long a, long long b)
++word_type notrace __cmpdi2(long long a, long long b)
+ {
+ 	const DWunion au = {
+ 		.ll = a
+diff --git a/arch/mips/lib/lshrdi3.c b/arch/mips/lib/lshrdi3.c
+index dcf8d6810b7c..364547449c65 100644
+--- a/arch/mips/lib/lshrdi3.c
++++ b/arch/mips/lib/lshrdi3.c
+@@ -2,7 +2,7 @@
+ 
+ #include "libgcc.h"
+ 
+-long long __lshrdi3(long long u, word_type b)
++long long notrace __lshrdi3(long long u, word_type b)
+ {
+ 	DWunion uu, w;
+ 	word_type bm;
+diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c
+index bb4cb2f828ea..bd599f58234c 100644
+--- a/arch/mips/lib/ucmpdi2.c
++++ b/arch/mips/lib/ucmpdi2.c
+@@ -2,7 +2,7 @@
+ 
+ #include "libgcc.h"
+ 
+-word_type __ucmpdi2(unsigned long long a, unsigned long long b)
++word_type notrace __ucmpdi2(unsigned long long a, unsigned long long b)
+ {
+ 	const DWunion au = {.ll = a};
+ 	const DWunion bu = {.ll = b};
+diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
+index 85d808924c94..0fce4608aa88 100644
+--- a/arch/mips/loongson64/Platform
++++ b/arch/mips/loongson64/Platform
+@@ -31,7 +31,7 @@ cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
+ # can't easily be used safely within the kbuild framework.
+ #
+ ifeq ($(call cc-ifversion, -ge, 0409, y), y)
+-  ifeq ($(call ld-ifversion, -ge, 22500000, y), y)
++  ifeq ($(call ld-ifversion, -ge, 225000000, y), y)
+     cflags-$(CONFIG_CPU_LOONGSON3)  += \
+       $(call cc-option,-march=loongson3a -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64)
+   else
+diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c
+index 6f9e010cec4d..282c5a8c2fcd 100644
+--- a/arch/mips/loongson64/loongson-3/numa.c
++++ b/arch/mips/loongson64/loongson-3/numa.c
+@@ -213,10 +213,10 @@ static void __init node_mem_init(unsigned int node)
+ 		BOOTMEM_DEFAULT);
+ 
+ 	if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) {
+-		/* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */
++		/* Reserve 0xfe000000~0xffffffff for RS780E integrated GPU */
+ 		reserve_bootmem_node(NODE_DATA(node),
+-				(node_addrspace_offset | 0xff800000),
+-				8 << 20, BOOTMEM_DEFAULT);
++				(node_addrspace_offset | 0xfe000000),
++				32 << 20, BOOTMEM_DEFAULT);
+ 	}
+ 
+ 	sparse_memory_present_with_active_regions(node);
+diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c
+index cdfd44ffa51c..41d3e0e7defa 100644
+--- a/arch/mips/math-emu/cp1emu.c
++++ b/arch/mips/math-emu/cp1emu.c
+@@ -445,9 +445,11 @@ static int isBranchInstr(struct pt_regs *regs, struct mm_decoded_insn dec_insn,
+ 	case spec_op:
+ 		switch (insn.r_format.func) {
+ 		case jalr_op:
+-			regs->regs[insn.r_format.rd] =
+-				regs->cp0_epc + dec_insn.pc_inc +
+-				dec_insn.next_pc_inc;
++			if (insn.r_format.rd != 0) {
++				regs->regs[insn.r_format.rd] =
++					regs->cp0_epc + dec_insn.pc_inc +
++					dec_insn.next_pc_inc;
++			}
+ 			/* Fall through */
+ 		case jr_op:
+ 			/* For R6, JR already emulated in jalr_op */
+diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
+index 3f159caf6dbc..bf04c6c479a4 100644
+--- a/arch/mips/mm/cache.c
++++ b/arch/mips/mm/cache.c
+@@ -16,6 +16,7 @@
+ #include <linux/mm.h>
+ 
+ #include <asm/cacheflush.h>
++#include <asm/highmem.h>
+ #include <asm/processor.h>
+ #include <asm/cpu.h>
+ #include <asm/cpu-features.h>
+@@ -83,8 +84,6 @@ void __flush_dcache_page(struct page *page)
+ 	struct address_space *mapping = page_mapping(page);
+ 	unsigned long addr;
+ 
+-	if (PageHighMem(page))
+-		return;
+ 	if (mapping && !mapping_mapped(mapping)) {
+ 		SetPageDcacheDirty(page);
+ 		return;
+@@ -95,8 +94,15 @@ void __flush_dcache_page(struct page *page)
+ 	 * case is for exec env/arg pages and those are %99 certainly going to
+ 	 * get faulted into the tlb (and thus flushed) anyways.
+ 	 */
+-	addr = (unsigned long) page_address(page);
++	if (PageHighMem(page))
++		addr = (unsigned long)kmap_atomic(page);
++	else
++		addr = (unsigned long)page_address(page);
++
+ 	flush_data_cache_page(addr);
++
++	if (PageHighMem(page))
++		__kunmap_atomic((void *)addr);
+ }
+ 
+ EXPORT_SYMBOL(__flush_dcache_page);
+@@ -119,33 +125,28 @@ void __flush_anon_page(struct page *page, unsigned long vmaddr)
+ 
+ EXPORT_SYMBOL(__flush_anon_page);
+ 
+-void __flush_icache_page(struct vm_area_struct *vma, struct page *page)
+-{
+-	unsigned long addr;
+-
+-	if (PageHighMem(page))
+-		return;
+-
+-	addr = (unsigned long) page_address(page);
+-	flush_data_cache_page(addr);
+-}
+-EXPORT_SYMBOL_GPL(__flush_icache_page);
+-
+-void __update_cache(struct vm_area_struct *vma, unsigned long address,
+-	pte_t pte)
++void __update_cache(unsigned long address, pte_t pte)
+ {
+ 	struct page *page;
+ 	unsigned long pfn, addr;
+-	int exec = (vma->vm_flags & VM_EXEC) && !cpu_has_ic_fills_f_dc;
++	int exec = !pte_no_exec(pte) && !cpu_has_ic_fills_f_dc;
+ 
+ 	pfn = pte_pfn(pte);
+ 	if (unlikely(!pfn_valid(pfn)))
+ 		return;
+ 	page = pfn_to_page(pfn);
+-	if (page_mapping(page) && Page_dcache_dirty(page)) {
+-		addr = (unsigned long) page_address(page);
++	if (Page_dcache_dirty(page)) {
++		if (PageHighMem(page))
++			addr = (unsigned long)kmap_atomic(page);
++		else
++			addr = (unsigned long)page_address(page);
++
+ 		if (exec || pages_do_alias(addr, address & PAGE_MASK))
+ 			flush_data_cache_page(addr);
++
++		if (PageHighMem(page))
++			__kunmap_atomic((void *)addr);
++
+ 		ClearPageDcacheDirty(page);
+ 	}
+ }
+diff --git a/arch/mips/vdso/Makefile b/arch/mips/vdso/Makefile
+index ee3617c0c5e2..f37e6ba40f52 100644
+--- a/arch/mips/vdso/Makefile
++++ b/arch/mips/vdso/Makefile
+@@ -5,10 +5,12 @@ obj-vdso-y := elf.o gettimeofday.o sigreturn.o
+ ccflags-vdso := \
+ 	$(filter -I%,$(KBUILD_CFLAGS)) \
+ 	$(filter -E%,$(KBUILD_CFLAGS)) \
++	$(filter -mmicromips,$(KBUILD_CFLAGS)) \
+ 	$(filter -march=%,$(KBUILD_CFLAGS))
+ cflags-vdso := $(ccflags-vdso) \
+ 	$(filter -W%,$(filter-out -Wa$(comma)%,$(KBUILD_CFLAGS))) \
+-	-O2 -g -fPIC -fno-common -fno-builtin -G 0 -DDISABLE_BRANCH_PROFILING \
++	-O2 -g -fPIC -fno-strict-aliasing -fno-common -fno-builtin -G 0 \
++	-DDISABLE_BRANCH_PROFILING \
+ 	$(call cc-option, -fno-stack-protector)
+ aflags-vdso := $(ccflags-vdso) \
+ 	$(filter -I%,$(KBUILD_CFLAGS)) \
+diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
+index 6544017eb90b..67584847973a 100644
+--- a/arch/powerpc/kernel/eeh.c
++++ b/arch/powerpc/kernel/eeh.c
+@@ -1068,7 +1068,7 @@ void eeh_add_device_early(struct pci_dn *pdn)
+ 	struct pci_controller *phb;
+ 	struct eeh_dev *edev = pdn_to_eeh_dev(pdn);
+ 
+-	if (!edev || !eeh_enabled())
++	if (!edev)
+ 		return;
+ 
+ 	if (!eeh_has_flag(EEH_PROBE_MODE_DEVTREE))
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index fb6207d2c604..31e4c7e1a4b4 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -171,6 +171,16 @@ static void *eeh_dev_save_state(void *data, void *userdata)
+ 	if (!edev)
+ 		return NULL;
+ 
++	/*
++	 * We cannot access the config space on some adapters.
++	 * Otherwise, it will cause fenced PHB. We don't save
++	 * the content in their config space and will restore
++	 * from the initial config space saved when the EEH
++	 * device is created.
++	 */
++	if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED))
++		return NULL;
++
+ 	pdev = eeh_dev_to_pci_dev(edev);
+ 	if (!pdev)
+ 		return NULL;
+@@ -312,6 +322,19 @@ static void *eeh_dev_restore_state(void *data, void *userdata)
+ 	if (!edev)
+ 		return NULL;
+ 
++	/*
++	 * The content in the config space isn't saved because
++	 * the blocked config space on some adapters. We have
++	 * to restore the initial saved config space when the
++	 * EEH device is created.
++	 */
++	if (edev->pe && (edev->pe->state & EEH_PE_CFG_RESTRICTED)) {
++		if (list_is_last(&edev->list, &edev->pe->edevs))
++			eeh_pe_restore_bars(edev->pe);
++
++		return NULL;
++	}
++
+ 	pdev = eeh_dev_to_pci_dev(edev);
+ 	if (!pdev)
+ 		return NULL;
+@@ -564,9 +587,6 @@ int eeh_pe_reset_and_recover(struct eeh_pe *pe)
+ 	/* Save states */
+ 	eeh_pe_dev_traverse(pe, eeh_dev_save_state, NULL);
+ 
+-	/* Report error */
+-	eeh_pe_dev_traverse(pe, eeh_report_error, &result);
+-
+ 	/* Issue reset */
+ 	ret = eeh_reset_pe(pe);
+ 	if (ret) {
+diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
+index 7716cebf4b8e..2b66f25d40db 100644
+--- a/arch/powerpc/kernel/exceptions-64s.S
++++ b/arch/powerpc/kernel/exceptions-64s.S
+@@ -953,11 +953,6 @@ hv_facility_unavailable_relon_trampoline:
+ #endif
+ 	STD_RELON_EXCEPTION_PSERIES(0x5700, 0x1700, altivec_assist)
+ 
+-	/* Other future vectors */
+-	.align	7
+-	.globl	__end_interrupts
+-__end_interrupts:
+-
+ 	.align	7
+ system_call_entry:
+ 	b	system_call_common
+@@ -1244,6 +1239,17 @@ __end_handlers:
+ 	STD_RELON_EXCEPTION_PSERIES_OOL(0xf60, facility_unavailable)
+ 	STD_RELON_EXCEPTION_HV_OOL(0xf80, hv_facility_unavailable)
+ 
++	/*
++	 * The __end_interrupts marker must be past the out-of-line (OOL)
++	 * handlers, so that they are copied to real address 0x100 when running
++	 * a relocatable kernel. This ensures they can be reached from the short
++	 * trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch
++	 * directly, without using LOAD_HANDLER().
++	 */
++	.align	7
++	.globl	__end_interrupts
++__end_interrupts:
++
+ #if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV)
+ /*
+  * Data area reserved for FWNMI option.
+diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
+index 7ab29518a3b9..e345891450c3 100644
+--- a/arch/x86/xen/setup.c
++++ b/arch/x86/xen/setup.c
+@@ -393,6 +393,9 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
+ 	unsigned long i = 0;
+ 	unsigned long n = end_pfn - start_pfn;
+ 
++	if (remap_pfn == 0)
++		remap_pfn = nr_pages;
++
+ 	while (i < n) {
+ 		unsigned long cur_pfn = start_pfn + i;
+ 		unsigned long left = n - i;
+@@ -438,17 +441,29 @@ static unsigned long __init xen_set_identity_and_remap_chunk(
+ 	return remap_pfn;
+ }
+ 
+-static void __init xen_set_identity_and_remap(unsigned long nr_pages)
++static unsigned long __init xen_count_remap_pages(
++	unsigned long start_pfn, unsigned long end_pfn, unsigned long nr_pages,
++	unsigned long remap_pages)
++{
++	if (start_pfn >= nr_pages)
++		return remap_pages;
++
++	return remap_pages + min(end_pfn, nr_pages) - start_pfn;
++}
++
++static unsigned long __init xen_foreach_remap_area(unsigned long nr_pages,
++	unsigned long (*func)(unsigned long start_pfn, unsigned long end_pfn,
++			      unsigned long nr_pages, unsigned long last_val))
+ {
+ 	phys_addr_t start = 0;
+-	unsigned long last_pfn = nr_pages;
++	unsigned long ret_val = 0;
+ 	const struct e820entry *entry = xen_e820_map;
+ 	int i;
+ 
+ 	/*
+ 	 * Combine non-RAM regions and gaps until a RAM region (or the
+-	 * end of the map) is reached, then set the 1:1 map and
+-	 * remap the memory in those non-RAM regions.
++	 * end of the map) is reached, then call the provided function
++	 * to perform its duty on the non-RAM region.
+ 	 *
+ 	 * The combined non-RAM regions are rounded to a whole number
+ 	 * of pages so any partial pages are accessible via the 1:1
+@@ -466,14 +481,13 @@ static void __init xen_set_identity_and_remap(unsigned long nr_pages)
+ 				end_pfn = PFN_UP(entry->addr);
+ 
+ 			if (start_pfn < end_pfn)
+-				last_pfn = xen_set_identity_and_remap_chunk(
+-						start_pfn, end_pfn, nr_pages,
+-						last_pfn);
++				ret_val = func(start_pfn, end_pfn, nr_pages,
++					       ret_val);
+ 			start = end;
+ 		}
+ 	}
+ 
+-	pr_info("Released %ld page(s)\n", xen_released_pages);
++	return ret_val;
+ }
+ 
+ /*
+@@ -596,35 +610,6 @@ static void __init xen_ignore_unusable(void)
+ 	}
+ }
+ 
+-static unsigned long __init xen_count_remap_pages(unsigned long max_pfn)
+-{
+-	unsigned long extra = 0;
+-	unsigned long start_pfn, end_pfn;
+-	const struct e820entry *entry = xen_e820_map;
+-	int i;
+-
+-	end_pfn = 0;
+-	for (i = 0; i < xen_e820_map_entries; i++, entry++) {
+-		start_pfn = PFN_DOWN(entry->addr);
+-		/* Adjacent regions on non-page boundaries handling! */
+-		end_pfn = min(end_pfn, start_pfn);
+-
+-		if (start_pfn >= max_pfn)
+-			return extra + max_pfn - end_pfn;
+-
+-		/* Add any holes in map to result. */
+-		extra += start_pfn - end_pfn;
+-
+-		end_pfn = PFN_UP(entry->addr + entry->size);
+-		end_pfn = min(end_pfn, max_pfn);
+-
+-		if (entry->type != E820_RAM)
+-			extra += end_pfn - start_pfn;
+-	}
+-
+-	return extra;
+-}
+-
+ bool __init xen_is_e820_reserved(phys_addr_t start, phys_addr_t size)
+ {
+ 	struct e820entry *entry;
+@@ -804,7 +789,7 @@ char * __init xen_memory_setup(void)
+ 	max_pages = xen_get_max_pages();
+ 
+ 	/* How many extra pages do we need due to remapping? */
+-	max_pages += xen_count_remap_pages(max_pfn);
++	max_pages += xen_foreach_remap_area(max_pfn, xen_count_remap_pages);
+ 
+ 	if (max_pages > max_pfn)
+ 		extra_pages += max_pages - max_pfn;
+@@ -922,7 +907,9 @@ char * __init xen_memory_setup(void)
+ 	 * Set identity map on non-RAM pages and prepare remapping the
+ 	 * underlying RAM.
+ 	 */
+-	xen_set_identity_and_remap(max_pfn);
++	xen_foreach_remap_area(max_pfn, xen_set_identity_and_remap_chunk);
++
++	pr_info("Released %ld page(s)\n", xen_released_pages);
+ 
+ 	return "Xen";
+ }
+diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c
+index 40de03f49ff8..bdd0d753ce5d 100644
+--- a/crypto/asymmetric_keys/pkcs7_parser.c
++++ b/crypto/asymmetric_keys/pkcs7_parser.c
+@@ -237,6 +237,7 @@ int pkcs7_sig_note_digest_algo(void *context, size_t hdrlen,
+ 		break;
+ 	case OID_sha224:
+ 		ctx->sinfo->sig.hash_algo = "sha224";
++		break;
+ 	default:
+ 		printk("Unsupported digest algo: %u\n", ctx->last_oid);
+ 		return -ENOPKG;
+diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
+index 6e7c3ccea24b..27aea96036c4 100644
+--- a/drivers/base/power/main.c
++++ b/drivers/base/power/main.c
+@@ -1267,14 +1267,15 @@ int dpm_suspend_late(pm_message_t state)
+ 		error = device_suspend_late(dev);
+ 
+ 		mutex_lock(&dpm_list_mtx);
++		if (!list_empty(&dev->power.entry))
++			list_move(&dev->power.entry, &dpm_late_early_list);
++
+ 		if (error) {
+ 			pm_dev_err(dev, state, " late", error);
+ 			dpm_save_failed_dev(dev_name(dev));
+ 			put_device(dev);
+ 			break;
+ 		}
+-		if (!list_empty(&dev->power.entry))
+-			list_move(&dev->power.entry, &dpm_late_early_list);
+ 		put_device(dev);
+ 
+ 		if (async_error)
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c
+index 4c7055009bd6..b74690418504 100644
+--- a/drivers/base/power/runtime.c
++++ b/drivers/base/power/runtime.c
+@@ -1506,11 +1506,16 @@ int pm_runtime_force_resume(struct device *dev)
+ 		goto out;
+ 	}
+ 
+-	ret = callback(dev);
++	ret = pm_runtime_set_active(dev);
+ 	if (ret)
+ 		goto out;
+ 
+-	pm_runtime_set_active(dev);
++	ret = callback(dev);
++	if (ret) {
++		pm_runtime_set_suspended(dev);
++		goto out;
++	}
++
+ 	pm_runtime_mark_last_busy(dev);
+ out:
+ 	pm_runtime_enable(dev);
+diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c
+index ada081232528..b98a141ea89c 100644
+--- a/drivers/char/hw_random/exynos-rng.c
++++ b/drivers/char/hw_random/exynos-rng.c
+@@ -89,6 +89,7 @@ static int exynos_read(struct hwrng *rng, void *buf,
+ 						struct exynos_rng, rng);
+ 	u32 *data = buf;
+ 	int retry = 100;
++	int ret = 4;
+ 
+ 	pm_runtime_get_sync(exynos_rng->dev);
+ 
+@@ -97,17 +98,20 @@ static int exynos_read(struct hwrng *rng, void *buf,
+ 	while (!(exynos_rng_readl(exynos_rng,
+ 			EXYNOS_PRNG_STATUS_OFFSET) & PRNG_DONE) && --retry)
+ 		cpu_relax();
+-	if (!retry)
+-		return -ETIMEDOUT;
++	if (!retry) {
++		ret = -ETIMEDOUT;
++		goto out;
++	}
+ 
+ 	exynos_rng_writel(exynos_rng, PRNG_DONE, EXYNOS_PRNG_STATUS_OFFSET);
+ 
+ 	*data = exynos_rng_readl(exynos_rng, EXYNOS_PRNG_OUT1_OFFSET);
+ 
++out:
+ 	pm_runtime_mark_last_busy(exynos_rng->dev);
+ 	pm_runtime_put_sync_autosuspend(exynos_rng->dev);
+ 
+-	return 4;
++	return ret;
+ }
+ 
+ static int exynos_rng_probe(struct platform_device *pdev)
+diff --git a/drivers/clk/at91/clk-h32mx.c b/drivers/clk/at91/clk-h32mx.c
+index 819f5842fa66..8e20c8a76db7 100644
+--- a/drivers/clk/at91/clk-h32mx.c
++++ b/drivers/clk/at91/clk-h32mx.c
+@@ -114,7 +114,7 @@ static void __init of_sama5d4_clk_h32mx_setup(struct device_node *np)
+ 	h32mxclk->regmap = regmap;
+ 
+ 	clk = clk_register(NULL, &h32mxclk->hw);
+-	if (!clk) {
++	if (IS_ERR(clk)) {
+ 		kfree(h32mxclk);
+ 		return;
+ 	}
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c
+index 90338c38e38a..1f79f48d5adc 100644
+--- a/drivers/clk/bcm/clk-bcm2835.c
++++ b/drivers/clk/bcm/clk-bcm2835.c
+@@ -51,6 +51,7 @@
+ #define CM_GNRICCTL		0x000
+ #define CM_GNRICDIV		0x004
+ # define CM_DIV_FRAC_BITS	12
++# define CM_DIV_FRAC_MASK	GENMASK(CM_DIV_FRAC_BITS - 1, 0)
+ 
+ #define CM_VPUCTL		0x008
+ #define CM_VPUDIV		0x00c
+@@ -128,6 +129,7 @@
+ # define CM_GATE			BIT(CM_GATE_BIT)
+ # define CM_BUSY			BIT(7)
+ # define CM_BUSYD			BIT(8)
++# define CM_FRAC			BIT(9)
+ # define CM_SRC_SHIFT			0
+ # define CM_SRC_BITS			4
+ # define CM_SRC_MASK			0xf
+@@ -644,6 +646,7 @@ struct bcm2835_clock_data {
+ 	u32 frac_bits;
+ 
+ 	bool is_vpu_clock;
++	bool is_mash_clock;
+ };
+ 
+ static const char *const bcm2835_clock_per_parents[] = {
+@@ -825,6 +828,7 @@ static const struct bcm2835_clock_data bcm2835_clock_pwm_data = {
+ 	.div_reg = CM_PWMDIV,
+ 	.int_bits = 12,
+ 	.frac_bits = 12,
++	.is_mash_clock = true,
+ };
+ 
+ struct bcm2835_pll {
+@@ -910,8 +914,14 @@ static void bcm2835_pll_off(struct clk_hw *hw)
+ 	struct bcm2835_cprman *cprman = pll->cprman;
+ 	const struct bcm2835_pll_data *data = pll->data;
+ 
+-	cprman_write(cprman, data->cm_ctrl_reg, CM_PLL_ANARST);
+-	cprman_write(cprman, data->a2w_ctrl_reg, A2W_PLL_CTRL_PWRDN);
++	spin_lock(&cprman->regs_lock);
++	cprman_write(cprman, data->cm_ctrl_reg,
++		     cprman_read(cprman, data->cm_ctrl_reg) |
++		     CM_PLL_ANARST);
++	cprman_write(cprman, data->a2w_ctrl_reg,
++		     cprman_read(cprman, data->a2w_ctrl_reg) |
++		     A2W_PLL_CTRL_PWRDN);
++	spin_unlock(&cprman->regs_lock);
+ }
+ 
+ static int bcm2835_pll_on(struct clk_hw *hw)
+@@ -921,6 +931,10 @@ static int bcm2835_pll_on(struct clk_hw *hw)
+ 	const struct bcm2835_pll_data *data = pll->data;
+ 	ktime_t timeout;
+ 
++	cprman_write(cprman, data->a2w_ctrl_reg,
++		     cprman_read(cprman, data->a2w_ctrl_reg) &
++		     ~A2W_PLL_CTRL_PWRDN);
++
+ 	/* Take the PLL out of reset. */
+ 	cprman_write(cprman, data->cm_ctrl_reg,
+ 		     cprman_read(cprman, data->cm_ctrl_reg) & ~CM_PLL_ANARST);
+@@ -1174,7 +1188,7 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+ 		GENMASK(CM_DIV_FRAC_BITS - data->frac_bits, 0) >> 1;
+ 	u64 temp = (u64)parent_rate << CM_DIV_FRAC_BITS;
+ 	u64 rem;
+-	u32 div;
++	u32 div, mindiv, maxdiv;
+ 
+ 	rem = do_div(temp, rate);
+ 	div = temp;
+@@ -1184,10 +1198,23 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw,
+ 		div += unused_frac_mask + 1;
+ 	div &= ~unused_frac_mask;
+ 
+-	/* Clamp to the limits. */
+-	div = max(div, unused_frac_mask + 1);
+-	div = min_t(u32, div, GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
+-				      CM_DIV_FRAC_BITS - data->frac_bits));
++	/* different clamping limits apply for a mash clock */
++	if (data->is_mash_clock) {
++		/* clamp to min divider of 2 */
++		mindiv = 2 << CM_DIV_FRAC_BITS;
++		/* clamp to the highest possible integer divider */
++		maxdiv = (BIT(data->int_bits) - 1) << CM_DIV_FRAC_BITS;
++	} else {
++		/* clamp to min divider of 1 */
++		mindiv = 1 << CM_DIV_FRAC_BITS;
++		/* clamp to the highest possible fractional divider */
++		maxdiv = GENMASK(data->int_bits + CM_DIV_FRAC_BITS - 1,
++				 CM_DIV_FRAC_BITS - data->frac_bits);
++	}
++
++	/* apply the clamping  limits */
++	div = max_t(u32, div, mindiv);
++	div = min_t(u32, div, maxdiv);
+ 
+ 	return div;
+ }
+@@ -1281,9 +1308,26 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw,
+ 	struct bcm2835_cprman *cprman = clock->cprman;
+ 	const struct bcm2835_clock_data *data = clock->data;
+ 	u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false);
++	u32 ctl;
++
++	spin_lock(&cprman->regs_lock);
++
++	/*
++	 * Setting up frac support
++	 *
++	 * In principle it is recommended to stop/start the clock first,
++	 * but as we set CLK_SET_RATE_GATE during registration of the
++	 * clock this requirement should be take care of by the
++	 * clk-framework.
++	 */
++	ctl = cprman_read(cprman, data->ctl_reg) & ~CM_FRAC;
++	ctl |= (div & CM_DIV_FRAC_MASK) ? CM_FRAC : 0;
++	cprman_write(cprman, data->ctl_reg, ctl);
+ 
+ 	cprman_write(cprman, data->div_reg, div);
+ 
++	spin_unlock(&cprman->regs_lock);
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/clk/imx/clk-imx35.c b/drivers/clk/imx/clk-imx35.c
+index a71d24cb4c06..b0978d3b83e2 100644
+--- a/drivers/clk/imx/clk-imx35.c
++++ b/drivers/clk/imx/clk-imx35.c
+@@ -66,7 +66,7 @@ static const char *std_sel[] = {"ppll", "arm"};
+ static const char *ipg_per_sel[] = {"ahb_per_div", "arm_per_div"};
+ 
+ enum mx35_clks {
+-	ckih, ckil, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
++	ckih, mpll, ppll, mpll_075, arm, hsp, hsp_div, hsp_sel, ahb, ipg,
+ 	arm_per_div, ahb_per_div, ipg_per, uart_sel, uart_div, esdhc_sel,
+ 	esdhc1_div, esdhc2_div, esdhc3_div, spdif_sel, spdif_div_pre,
+ 	spdif_div_post, ssi_sel, ssi1_div_pre, ssi1_div_post, ssi2_div_pre,
+@@ -79,7 +79,7 @@ enum mx35_clks {
+ 	rtc_gate, rtic_gate, scc_gate, sdma_gate, spba_gate, spdif_gate,
+ 	ssi1_gate, ssi2_gate, uart1_gate, uart2_gate, uart3_gate, usbotg_gate,
+ 	wdog_gate, max_gate, admux_gate, csi_gate, csi_div, csi_sel, iim_gate,
+-	gpu2d_gate, clk_max
++	gpu2d_gate, ckil, clk_max
+ };
+ 
+ static struct clk *clk[clk_max];
+diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
+index f996efc56605..0db185762a10 100644
+--- a/drivers/cpuidle/cpuidle.c
++++ b/drivers/cpuidle/cpuidle.c
+@@ -214,7 +214,7 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
+ 		tick_broadcast_exit();
+ 	}
+ 
+-	if (!cpuidle_state_is_coupled(drv, entered_state))
++	if (!cpuidle_state_is_coupled(drv, index))
+ 		local_irq_enable();
+ 
+ 	diff = ktime_to_us(ktime_sub(time_end, time_start));
+@@ -433,6 +433,8 @@ static void __cpuidle_unregister_device(struct cpuidle_device *dev)
+ 	list_del(&dev->device_list);
+ 	per_cpu(cpuidle_devices, dev->cpu) = NULL;
+ 	module_put(drv->owner);
++
++	dev->registered = 0;
+ }
+ 
+ static void __cpuidle_device_init(struct cpuidle_device *dev)
+diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
+index 6eb94fc561dc..22228ef50f36 100644
+--- a/drivers/gpu/drm/Makefile
++++ b/drivers/gpu/drm/Makefile
+@@ -23,7 +23,7 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o
+ 
+ drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
+ 		drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
+-		drm_kms_helper_common.o
++		drm_kms_helper_common.o drm_dp_dual_mode_helper.o
+ 
+ drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
+ drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+index 119cdc2c43e7..7ef2c13921b4 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
+@@ -194,12 +194,12 @@ int amdgpu_connector_get_monitor_bpc(struct drm_connector *connector)
+ 				bpc = 8;
+ 				DRM_DEBUG("%s: HDMI deep color 10 bpc exceeds max tmds clock. Using %d bpc.\n",
+ 					  connector->name, bpc);
+-			} else if (bpc > 8) {
+-				/* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
+-				DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
+-					  connector->name);
+-				bpc = 8;
+ 			}
++		} else if (bpc > 8) {
++			/* max_tmds_clock missing, but hdmi spec mandates it for deep color. */
++			DRM_DEBUG("%s: Required max tmds clock for HDMI deep color missing. Using 8 bpc.\n",
++				  connector->name);
++			bpc = 8;
+ 		}
+ 	}
+ 
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+index 7b7f4aba60c0..fe36caf1b7d7 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
+@@ -150,7 +150,7 @@ u32 amdgpu_dpm_get_vrefresh(struct amdgpu_device *adev)
+ 		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) {
+-				vrefresh = amdgpu_crtc->hw_mode.vrefresh;
++				vrefresh = drm_mode_vrefresh(&amdgpu_crtc->hw_mode);
+ 				break;
+ 			}
+ 		}
+diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
+index 8ee1db866e80..d307d9627887 100644
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -139,7 +139,7 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
+ 	for (i = 0; i < state->num_connector; i++) {
+ 		struct drm_connector *connector = state->connectors[i];
+ 
+-		if (!connector)
++		if (!connector || !connector->funcs)
+ 			continue;
+ 
+ 		/*
+diff --git a/drivers/gpu/drm/drm_dp_dual_mode_helper.c b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
+new file mode 100644
+index 000000000000..a7b2a751f6fe
+--- /dev/null
++++ b/drivers/gpu/drm/drm_dp_dual_mode_helper.c
+@@ -0,0 +1,366 @@
++/*
++ * Copyright © 2016 Intel Corporation
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#include <linux/errno.h>
++#include <linux/export.h>
++#include <linux/i2c.h>
++#include <linux/slab.h>
++#include <linux/string.h>
++#include <drm/drm_dp_dual_mode_helper.h>
++#include <drm/drmP.h>
++
++/**
++ * DOC: dp dual mode helpers
++ *
++ * Helper functions to deal with DP dual mode (aka. DP++) adaptors.
++ *
++ * Type 1:
++ * Adaptor registers (if any) and the sink DDC bus may be accessed via I2C.
++ *
++ * Type 2:
++ * Adaptor registers and sink DDC bus can be accessed either via I2C or
++ * I2C-over-AUX. Source devices may choose to implement either of these
++ * access methods.
++ */
++
++#define DP_DUAL_MODE_SLAVE_ADDRESS 0x40
++
++/**
++ * drm_dp_dual_mode_read - Read from the DP dual mode adaptor register(s)
++ * @adapter: I2C adapter for the DDC bus
++ * @offset: register offset
++ * @buffer: buffer for return data
++ * @size: sizo of the buffer
++ *
++ * Reads @size bytes from the DP dual mode adaptor registers
++ * starting at @offset.
++ *
++ * Returns:
++ * 0 on success, negative error code on failure
++ */
++ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
++			      u8 offset, void *buffer, size_t size)
++{
++	struct i2c_msg msgs[] = {
++		{
++			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
++			.flags = 0,
++			.len = 1,
++			.buf = &offset,
++		},
++		{
++			.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
++			.flags = I2C_M_RD,
++			.len = size,
++			.buf = buffer,
++		},
++	};
++	int ret;
++
++	ret = i2c_transfer(adapter, msgs, ARRAY_SIZE(msgs));
++	if (ret < 0)
++		return ret;
++	if (ret != ARRAY_SIZE(msgs))
++		return -EPROTO;
++
++	return 0;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_read);
++
++/**
++ * drm_dp_dual_mode_write - Write to the DP dual mode adaptor register(s)
++ * @adapter: I2C adapter for the DDC bus
++ * @offset: register offset
++ * @buffer: buffer for write data
++ * @size: sizo of the buffer
++ *
++ * Writes @size bytes to the DP dual mode adaptor registers
++ * starting at @offset.
++ *
++ * Returns:
++ * 0 on success, negative error code on failure
++ */
++ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
++			       u8 offset, const void *buffer, size_t size)
++{
++	struct i2c_msg msg = {
++		.addr = DP_DUAL_MODE_SLAVE_ADDRESS,
++		.flags = 0,
++		.len = 1 + size,
++		.buf = NULL,
++	};
++	void *data;
++	int ret;
++
++	data = kmalloc(msg.len, GFP_TEMPORARY);
++	if (!data)
++		return -ENOMEM;
++
++	msg.buf = data;
++
++	memcpy(data, &offset, 1);
++	memcpy(data + 1, buffer, size);
++
++	ret = i2c_transfer(adapter, &msg, 1);
++
++	kfree(data);
++
++	if (ret < 0)
++		return ret;
++	if (ret != 1)
++		return -EPROTO;
++
++	return 0;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_write);
++
++static bool is_hdmi_adaptor(const char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN])
++{
++	static const char dp_dual_mode_hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] =
++		"DP-HDMI ADAPTOR\x04";
++
++	return memcmp(hdmi_id, dp_dual_mode_hdmi_id,
++		      sizeof(dp_dual_mode_hdmi_id)) == 0;
++}
++
++static bool is_type2_adaptor(uint8_t adaptor_id)
++{
++	return adaptor_id == (DP_DUAL_MODE_TYPE_TYPE2 |
++			      DP_DUAL_MODE_REV_TYPE2);
++}
++
++/**
++ * drm_dp_dual_mode_detect - Identify the DP dual mode adaptor
++ * @adapter: I2C adapter for the DDC bus
++ *
++ * Attempt to identify the type of the DP dual mode adaptor used.
++ *
++ * Note that when the answer is @DRM_DP_DUAL_MODE_UNKNOWN it's not
++ * certain whether we're dealing with a native HDMI port or
++ * a type 1 DVI dual mode adaptor. The driver will have to use
++ * some other hardware/driver specific mechanism to make that
++ * distinction.
++ *
++ * Returns:
++ * The type of the DP dual mode adaptor used
++ */
++enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter)
++{
++	char hdmi_id[DP_DUAL_MODE_HDMI_ID_LEN] = {};
++	uint8_t adaptor_id = 0x00;
++	ssize_t ret;
++
++	/*
++	 * Let's see if the adaptor is there the by reading the
++	 * HDMI ID registers.
++	 *
++	 * Note that type 1 DVI adaptors are not required to implemnt
++	 * any registers, and that presents a problem for detection.
++	 * If the i2c transfer is nacked, we may or may not be dealing
++	 * with a type 1 DVI adaptor. Some other mechanism of detecting
++	 * the presence of the adaptor is required. One way would be
++	 * to check the state of the CONFIG1 pin, Another method would
++	 * simply require the driver to know whether the port is a DP++
++	 * port or a native HDMI port. Both of these methods are entirely
++	 * hardware/driver specific so we can't deal with them here.
++	 */
++	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_HDMI_ID,
++				    hdmi_id, sizeof(hdmi_id));
++	if (ret)
++		return DRM_DP_DUAL_MODE_UNKNOWN;
++
++	/*
++	 * Sigh. Some (maybe all?) type 1 adaptors are broken and ack
++	 * the offset but ignore it, and instead they just always return
++	 * data from the start of the HDMI ID buffer. So for a broken
++	 * type 1 HDMI adaptor a single byte read will always give us
++	 * 0x44, and for a type 1 DVI adaptor it should give 0x00
++	 * (assuming it implements any registers). Fortunately neither
++	 * of those values will match the type 2 signature of the
++	 * DP_DUAL_MODE_ADAPTOR_ID register so we can proceed with
++	 * the type 2 adaptor detection safely even in the presence
++	 * of broken type 1 adaptors.
++	 */
++	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_ADAPTOR_ID,
++				    &adaptor_id, sizeof(adaptor_id));
++	if (ret == 0) {
++		if (is_type2_adaptor(adaptor_id)) {
++			if (is_hdmi_adaptor(hdmi_id))
++				return DRM_DP_DUAL_MODE_TYPE2_HDMI;
++			else
++				return DRM_DP_DUAL_MODE_TYPE2_DVI;
++		}
++	}
++
++	if (is_hdmi_adaptor(hdmi_id))
++		return DRM_DP_DUAL_MODE_TYPE1_HDMI;
++	else
++		return DRM_DP_DUAL_MODE_TYPE1_DVI;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_detect);
++
++/**
++ * drm_dp_dual_mode_max_tmds_clock - Max TMDS clock for DP dual mode adaptor
++ * @type: DP dual mode adaptor type
++ * @adapter: I2C adapter for the DDC bus
++ *
++ * Determine the max TMDS clock the adaptor supports based on the
++ * type of the dual mode adaptor and the DP_DUAL_MODE_MAX_TMDS_CLOCK
++ * register (on type2 adaptors). As some type 1 adaptors have
++ * problems with registers (see comments in drm_dp_dual_mode_detect())
++ * we don't read the register on those, instead we simply assume
++ * a 165 MHz limit based on the specification.
++ *
++ * Returns:
++ * Maximum supported TMDS clock rate for the DP dual mode adaptor in kHz.
++ */
++int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
++				    struct i2c_adapter *adapter)
++{
++	uint8_t max_tmds_clock;
++	ssize_t ret;
++
++	/* native HDMI so no limit */
++	if (type == DRM_DP_DUAL_MODE_NONE)
++		return 0;
++
++	/*
++	 * Type 1 adaptors are limited to 165MHz
++	 * Type 2 adaptors can tells us their limit
++	 */
++	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
++		return 165000;
++
++	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_MAX_TMDS_CLOCK,
++				    &max_tmds_clock, sizeof(max_tmds_clock));
++	if (ret || max_tmds_clock == 0x00 || max_tmds_clock == 0xff) {
++		DRM_DEBUG_KMS("Failed to query max TMDS clock\n");
++		return 165000;
++	}
++
++	return max_tmds_clock * 5000 / 2;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_max_tmds_clock);
++
++/**
++ * drm_dp_dual_mode_get_tmds_output - Get the state of the TMDS output buffers in the DP dual mode adaptor
++ * @type: DP dual mode adaptor type
++ * @adapter: I2C adapter for the DDC bus
++ * @enabled: current state of the TMDS output buffers
++ *
++ * Get the state of the TMDS output buffers in the adaptor. For
++ * type2 adaptors this is queried from the DP_DUAL_MODE_TMDS_OEN
++ * register. As some type 1 adaptors have problems with registers
++ * (see comments in drm_dp_dual_mode_detect()) we don't read the
++ * register on those, instead we simply assume that the buffers
++ * are always enabled.
++ *
++ * Returns:
++ * 0 on success, negative error code on failure
++ */
++int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
++				     struct i2c_adapter *adapter,
++				     bool *enabled)
++{
++	uint8_t tmds_oen;
++	ssize_t ret;
++
++	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI) {
++		*enabled = true;
++		return 0;
++	}
++
++	ret = drm_dp_dual_mode_read(adapter, DP_DUAL_MODE_TMDS_OEN,
++				    &tmds_oen, sizeof(tmds_oen));
++	if (ret) {
++		DRM_DEBUG_KMS("Failed to query state of TMDS output buffers\n");
++		return ret;
++	}
++
++	*enabled = !(tmds_oen & DP_DUAL_MODE_TMDS_DISABLE);
++
++	return 0;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_get_tmds_output);
++
++/**
++ * drm_dp_dual_mode_set_tmds_output - Enable/disable TMDS output buffers in the DP dual mode adaptor
++ * @type: DP dual mode adaptor type
++ * @adapter: I2C adapter for the DDC bus
++ * @enable: enable (as opposed to disable) the TMDS output buffers
++ *
++ * Set the state of the TMDS output buffers in the adaptor. For
++ * type2 this is set via the DP_DUAL_MODE_TMDS_OEN register. As
++ * some type 1 adaptors have problems with registers (see comments
++ * in drm_dp_dual_mode_detect()) we avoid touching the register,
++ * making this function a no-op on type 1 adaptors.
++ *
++ * Returns:
++ * 0 on success, negative error code on failure
++ */
++int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
++				     struct i2c_adapter *adapter, bool enable)
++{
++	uint8_t tmds_oen = enable ? 0 : DP_DUAL_MODE_TMDS_DISABLE;
++	ssize_t ret;
++
++	if (type < DRM_DP_DUAL_MODE_TYPE2_DVI)
++		return 0;
++
++	ret = drm_dp_dual_mode_write(adapter, DP_DUAL_MODE_TMDS_OEN,
++				     &tmds_oen, sizeof(tmds_oen));
++	if (ret) {
++		DRM_DEBUG_KMS("Failed to %s TMDS output buffers\n",
++			      enable ? "enable" : "disable");
++		return ret;
++	}
++
++	return 0;
++}
++EXPORT_SYMBOL(drm_dp_dual_mode_set_tmds_output);
++
++/**
++ * drm_dp_get_dual_mode_type_name - Get the name of the DP dual mode adaptor type as a string
++ * @type: DP dual mode adaptor type
++ *
++ * Returns:
++ * String representation of the DP dual mode adaptor type
++ */
++const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type)
++{
++	switch (type) {
++	case DRM_DP_DUAL_MODE_NONE:
++		return "none";
++	case DRM_DP_DUAL_MODE_TYPE1_DVI:
++		return "type 1 DVI";
++	case DRM_DP_DUAL_MODE_TYPE1_HDMI:
++		return "type 1 HDMI";
++	case DRM_DP_DUAL_MODE_TYPE2_DVI:
++		return "type 2 DVI";
++	case DRM_DP_DUAL_MODE_TYPE2_HDMI:
++		return "type 2 HDMI";
++	default:
++		WARN_ON(type != DRM_DP_DUAL_MODE_UNKNOWN);
++		return "unknown";
++	}
++}
++EXPORT_SYMBOL(drm_dp_get_dual_mode_type_name);
+diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
+index 855108e6e1bd..fe4df976f0b8 100644
+--- a/drivers/gpu/drm/drm_fb_helper.c
++++ b/drivers/gpu/drm/drm_fb_helper.c
+@@ -1895,7 +1895,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
+ 			  int n, int width, int height)
+ {
+ 	int c, o;
+-	struct drm_device *dev = fb_helper->dev;
+ 	struct drm_connector *connector;
+ 	const struct drm_connector_helper_funcs *connector_funcs;
+ 	struct drm_encoder *encoder;
+@@ -1914,7 +1913,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
+ 	if (modes[n] == NULL)
+ 		return best_score;
+ 
+-	crtcs = kzalloc(dev->mode_config.num_connector *
++	crtcs = kzalloc(fb_helper->connector_count *
+ 			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
+ 	if (!crtcs)
+ 		return best_score;
+@@ -1960,7 +1959,7 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
+ 		if (score > best_score) {
+ 			best_score = score;
+ 			memcpy(best_crtcs, crtcs,
+-			       dev->mode_config.num_connector *
++			       fb_helper->connector_count *
+ 			       sizeof(struct drm_fb_helper_crtc *));
+ 		}
+ 	}
+diff --git a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+index 6b43ae3ffd73..1616af209bfc 100644
+--- a/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
++++ b/drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c
+@@ -72,7 +72,7 @@ static const char *const dsi_errors[] = {
+ 	"RX Prot Violation",
+ 	"HS Generic Write FIFO Full",
+ 	"LP Generic Write FIFO Full",
+-	"Generic Read Data Avail"
++	"Generic Read Data Avail",
+ 	"Special Packet Sent",
+ 	"Tearing Effect",
+ };
+diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
+index 8e579a8505ac..e7c1686e479c 100644
+--- a/drivers/gpu/drm/i915/intel_atomic.c
++++ b/drivers/gpu/drm/i915/intel_atomic.c
+@@ -96,7 +96,8 @@ intel_crtc_duplicate_state(struct drm_crtc *crtc)
+ 	crtc_state->update_pipe = false;
+ 	crtc_state->disable_lp_wm = false;
+ 	crtc_state->disable_cxsr = false;
+-	crtc_state->wm_changed = false;
++	crtc_state->update_wm_pre = false;
++	crtc_state->update_wm_post = false;
+ 	crtc_state->fb_changed = false;
+ 
+ 	return &crtc_state->base;
+diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c
+index e0b851a0004a..7de7721f65bc 100644
+--- a/drivers/gpu/drm/i915/intel_atomic_plane.c
++++ b/drivers/gpu/drm/i915/intel_atomic_plane.c
+@@ -195,12 +195,10 @@ static void intel_plane_atomic_update(struct drm_plane *plane,
+ 	struct intel_plane_state *intel_state =
+ 		to_intel_plane_state(plane->state);
+ 	struct drm_crtc *crtc = plane->state->crtc ?: old_state->crtc;
+-	struct drm_crtc_state *crtc_state =
+-		drm_atomic_get_existing_crtc_state(old_state->state, crtc);
+ 
+ 	if (intel_state->visible)
+ 		intel_plane->update_plane(plane,
+-					  to_intel_crtc_state(crtc_state),
++					  to_intel_crtc_state(crtc->state),
+ 					  intel_state);
+ 	else
+ 		intel_plane->disable_plane(plane, crtc);
+diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
+index 96ffcc541e17..50f5b0c975e3 100644
+--- a/drivers/gpu/drm/i915/intel_ddi.c
++++ b/drivers/gpu/drm/i915/intel_ddi.c
+@@ -2309,6 +2309,12 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
+ 	enum port port = intel_ddi_get_encoder_port(intel_encoder);
+ 	int type = intel_encoder->type;
+ 
++	if (type == INTEL_OUTPUT_HDMI) {
++		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
++
++		intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
++	}
++
+ 	intel_prepare_ddi_buffer(intel_encoder);
+ 
+ 	if (type == INTEL_OUTPUT_EDP) {
+@@ -2375,6 +2381,12 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder)
+ 					DPLL_CTRL2_DDI_CLK_OFF(port)));
+ 	else if (INTEL_INFO(dev)->gen < 9)
+ 		I915_WRITE(PORT_CLK_SEL(port), PORT_CLK_SEL_NONE);
++
++	if (type == INTEL_OUTPUT_HDMI) {
++		struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder);
++
++		intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
++	}
+ }
+ 
+ static void intel_enable_ddi(struct intel_encoder *intel_encoder)
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 0104a06d01fd..7741efbd5e57 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -4796,7 +4796,7 @@ static void intel_post_plane_update(struct intel_crtc *crtc)
+ 
+ 	crtc->wm.cxsr_allowed = true;
+ 
+-	if (pipe_config->wm_changed && pipe_config->base.active)
++	if (pipe_config->update_wm_post && pipe_config->base.active)
+ 		intel_update_watermarks(&crtc->base);
+ 
+ 	if (atomic->update_fbc)
+@@ -4843,7 +4843,7 @@ static void intel_pre_plane_update(struct intel_crtc_state *old_crtc_state)
+ 			intel_set_memory_cxsr(dev_priv, false);
+ 	}
+ 
+-	if (!needs_modeset(&pipe_config->base) && pipe_config->wm_changed)
++	if (!needs_modeset(&pipe_config->base) && pipe_config->update_wm_pre)
+ 		intel_update_watermarks(&crtc->base);
+ }
+ 
+@@ -6210,6 +6210,7 @@ static void valleyview_crtc_enable(struct drm_crtc *crtc)
+ 
+ 	intel_crtc_load_lut(crtc);
+ 
++	intel_update_watermarks(crtc);
+ 	intel_enable_pipe(intel_crtc);
+ 
+ 	assert_vblank_disabled(crtc);
+@@ -11833,14 +11834,22 @@ int intel_plane_atomic_calc_changes(struct drm_crtc_state *crtc_state,
+ 			 plane->base.id, was_visible, visible,
+ 			 turn_off, turn_on, mode_changed);
+ 
+-	if (turn_on || turn_off) {
+-		pipe_config->wm_changed = true;
++	if (turn_on) {
++		pipe_config->update_wm_pre = true;
++
++		/* must disable cxsr around plane enable/disable */
++		if (plane->type != DRM_PLANE_TYPE_CURSOR)
++			pipe_config->disable_cxsr = true;
++	} else if (turn_off) {
++		pipe_config->update_wm_post = true;
+ 
+ 		/* must disable cxsr around plane enable/disable */
+ 		if (plane->type != DRM_PLANE_TYPE_CURSOR)
+ 			pipe_config->disable_cxsr = true;
+ 	} else if (intel_wm_need_update(plane, plane_state)) {
+-		pipe_config->wm_changed = true;
++		/* FIXME bollocks */
++		pipe_config->update_wm_pre = true;
++		pipe_config->update_wm_post = true;
+ 	}
+ 
+ 	if (visible || was_visible)
+@@ -11940,7 +11949,7 @@ static int intel_crtc_atomic_check(struct drm_crtc *crtc,
+ 	}
+ 
+ 	if (mode_changed && !crtc_state->active)
+-		pipe_config->wm_changed = true;
++		pipe_config->update_wm_post = true;
+ 
+ 	if (mode_changed && crtc_state->enable &&
+ 	    dev_priv->display.crtc_compute_clock &&
+@@ -13453,12 +13462,12 @@ static bool needs_vblank_wait(struct intel_crtc_state *crtc_state)
+ 		return true;
+ 
+ 	/* wm changes, need vblank before final wm's */
+-	if (crtc_state->wm_changed)
++	if (crtc_state->update_wm_post)
+ 		return true;
+ 
+ 	/*
+ 	 * cxsr is re-enabled after vblank.
+-	 * This is already handled by crtc_state->wm_changed,
++	 * This is already handled by crtc_state->update_wm_post,
+ 	 * but added for clarity.
+ 	 */
+ 	if (crtc_state->disable_cxsr)
+@@ -15958,6 +15967,18 @@ void intel_display_resume(struct drm_device *dev)
+ retry:
+ 	ret = drm_modeset_lock_all_ctx(dev, &ctx);
+ 
++	/*
++	 * With MST, the number of connectors can change between suspend and
++	 * resume, which means that the state we want to restore might now be
++	 * impossible to use since it'll be pointing to non-existant
++	 * connectors.
++	 */
++	if (ret == 0 && state &&
++	    state->num_connector != dev->mode_config.num_connector) {
++		drm_atomic_state_free(state);
++		state = NULL;
++	}
++
+ 	if (ret == 0 && !setup) {
+ 		setup = true;
+ 
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 9d0770c23fde..3a30b37d6885 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -33,6 +33,7 @@
+ #include <drm/drm_crtc.h>
+ #include <drm/drm_crtc_helper.h>
+ #include <drm/drm_fb_helper.h>
++#include <drm/drm_dp_dual_mode_helper.h>
+ #include <drm/drm_dp_mst_helper.h>
+ #include <drm/drm_rect.h>
+ #include <drm/drm_atomic.h>
+@@ -378,7 +379,7 @@ struct intel_crtc_state {
+ 
+ 	bool update_pipe; /* can a fast modeset be performed? */
+ 	bool disable_cxsr;
+-	bool wm_changed; /* watermarks are updated */
++	bool update_wm_pre, update_wm_post; /* watermarks are updated */
+ 	bool fb_changed; /* fb on any of the planes is changed */
+ 
+ 	/* Pipe source size (ie. panel fitter input size)
+@@ -703,6 +704,10 @@ struct cxsr_latency {
+ struct intel_hdmi {
+ 	i915_reg_t hdmi_reg;
+ 	int ddc_bus;
++	struct {
++		enum drm_dp_dual_mode_type type;
++		int max_tmds_clock;
++	} dp_dual_mode;
+ 	bool limited_color_range;
+ 	bool color_range_auto;
+ 	bool has_hdmi_sink;
+@@ -1351,6 +1356,7 @@ void intel_hdmi_init_connector(struct intel_digital_port *intel_dig_port,
+ struct intel_hdmi *enc_to_intel_hdmi(struct drm_encoder *encoder);
+ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+ 			       struct intel_crtc_state *pipe_config);
++void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable);
+ 
+ 
+ /* intel_lvds.c */
+diff --git a/drivers/gpu/drm/i915/intel_fbdev.c b/drivers/gpu/drm/i915/intel_fbdev.c
+index 97a91e631915..c607217c13ea 100644
+--- a/drivers/gpu/drm/i915/intel_fbdev.c
++++ b/drivers/gpu/drm/i915/intel_fbdev.c
+@@ -366,12 +366,12 @@ static bool intel_fb_initial_config(struct drm_fb_helper *fb_helper,
+ 	uint64_t conn_configured = 0, mask;
+ 	int pass = 0;
+ 
+-	save_enabled = kcalloc(dev->mode_config.num_connector, sizeof(bool),
++	save_enabled = kcalloc(fb_helper->connector_count, sizeof(bool),
+ 			       GFP_KERNEL);
+ 	if (!save_enabled)
+ 		return false;
+ 
+-	memcpy(save_enabled, enabled, dev->mode_config.num_connector);
++	memcpy(save_enabled, enabled, fb_helper->connector_count);
+ 	mask = (1 << fb_helper->connector_count) - 1;
+ retry:
+ 	for (i = 0; i < fb_helper->connector_count; i++) {
+@@ -510,7 +510,7 @@ retry:
+ 	if (fallback) {
+ bail:
+ 		DRM_DEBUG_KMS("Not using firmware configuration\n");
+-		memcpy(enabled, save_enabled, dev->mode_config.num_connector);
++		memcpy(enabled, save_enabled, fb_helper->connector_count);
+ 		kfree(save_enabled);
+ 		return false;
+ 	}
+diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c
+index 1ab6f687f640..3ddb4fac53fa 100644
+--- a/drivers/gpu/drm/i915/intel_hdmi.c
++++ b/drivers/gpu/drm/i915/intel_hdmi.c
+@@ -836,6 +836,22 @@ static void hsw_set_infoframes(struct drm_encoder *encoder,
+ 	intel_hdmi_set_hdmi_infoframe(encoder, adjusted_mode);
+ }
+ 
++void intel_dp_dual_mode_set_tmds_output(struct intel_hdmi *hdmi, bool enable)
++{
++	struct drm_i915_private *dev_priv = to_i915(intel_hdmi_to_dev(hdmi));
++	struct i2c_adapter *adapter =
++		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
++
++	if (hdmi->dp_dual_mode.type < DRM_DP_DUAL_MODE_TYPE2_DVI)
++		return;
++
++	DRM_DEBUG_KMS("%s DP dual mode adaptor TMDS output\n",
++		      enable ? "Enabling" : "Disabling");
++
++	drm_dp_dual_mode_set_tmds_output(hdmi->dp_dual_mode.type,
++					 adapter, enable);
++}
++
+ static void intel_hdmi_prepare(struct intel_encoder *encoder)
+ {
+ 	struct drm_device *dev = encoder->base.dev;
+@@ -845,6 +861,8 @@ static void intel_hdmi_prepare(struct intel_encoder *encoder)
+ 	const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
+ 	u32 hdmi_val;
+ 
++	intel_dp_dual_mode_set_tmds_output(intel_hdmi, true);
++
+ 	hdmi_val = SDVO_ENCODING_HDMI;
+ 	if (!HAS_PCH_SPLIT(dev) && crtc->config->limited_color_range)
+ 		hdmi_val |= HDMI_COLOR_RANGE_16_235;
+@@ -1143,6 +1161,8 @@ static void intel_disable_hdmi(struct intel_encoder *encoder)
+ 	}
+ 
+ 	intel_hdmi->set_infoframes(&encoder->base, false, NULL);
++
++	intel_dp_dual_mode_set_tmds_output(intel_hdmi, false);
+ }
+ 
+ static void g4x_disable_hdmi(struct intel_encoder *encoder)
+@@ -1168,27 +1188,42 @@ static void pch_post_disable_hdmi(struct intel_encoder *encoder)
+ 	intel_disable_hdmi(encoder);
+ }
+ 
+-static int hdmi_port_clock_limit(struct intel_hdmi *hdmi, bool respect_dvi_limit)
++static int intel_hdmi_source_max_tmds_clock(struct drm_i915_private *dev_priv)
+ {
+-	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+-
+-	if ((respect_dvi_limit && !hdmi->has_hdmi_sink) || IS_G4X(dev))
++	if (IS_G4X(dev_priv))
+ 		return 165000;
+-	else if (IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8)
++	else if (IS_HASWELL(dev_priv) || INTEL_INFO(dev_priv)->gen >= 8)
+ 		return 300000;
+ 	else
+ 		return 225000;
+ }
+ 
++static int hdmi_port_clock_limit(struct intel_hdmi *hdmi,
++				 bool respect_downstream_limits)
++{
++	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
++	int max_tmds_clock = intel_hdmi_source_max_tmds_clock(to_i915(dev));
++
++	if (respect_downstream_limits) {
++		if (hdmi->dp_dual_mode.max_tmds_clock)
++			max_tmds_clock = min(max_tmds_clock,
++					     hdmi->dp_dual_mode.max_tmds_clock);
++		if (!hdmi->has_hdmi_sink)
++			max_tmds_clock = min(max_tmds_clock, 165000);
++	}
++
++	return max_tmds_clock;
++}
++
+ static enum drm_mode_status
+ hdmi_port_clock_valid(struct intel_hdmi *hdmi,
+-		      int clock, bool respect_dvi_limit)
++		      int clock, bool respect_downstream_limits)
+ {
+ 	struct drm_device *dev = intel_hdmi_to_dev(hdmi);
+ 
+ 	if (clock < 25000)
+ 		return MODE_CLOCK_LOW;
+-	if (clock > hdmi_port_clock_limit(hdmi, respect_dvi_limit))
++	if (clock > hdmi_port_clock_limit(hdmi, respect_downstream_limits))
+ 		return MODE_CLOCK_HIGH;
+ 
+ 	/* BXT DPLL can't generate 223-240 MHz */
+@@ -1312,7 +1347,7 @@ bool intel_hdmi_compute_config(struct intel_encoder *encoder,
+ 	 * within limits.
+ 	 */
+ 	if (pipe_config->pipe_bpp > 8*3 && pipe_config->has_hdmi_sink &&
+-	    hdmi_port_clock_valid(intel_hdmi, clock_12bpc, false) == MODE_OK &&
++	    hdmi_port_clock_valid(intel_hdmi, clock_12bpc, true) == MODE_OK &&
+ 	    hdmi_12bpc_possible(pipe_config)) {
+ 		DRM_DEBUG_KMS("picking bpc to 12 for HDMI output\n");
+ 		desired_bpp = 12*3;
+@@ -1352,10 +1387,35 @@ intel_hdmi_unset_edid(struct drm_connector *connector)
+ 	intel_hdmi->has_audio = false;
+ 	intel_hdmi->rgb_quant_range_selectable = false;
+ 
++	intel_hdmi->dp_dual_mode.type = DRM_DP_DUAL_MODE_NONE;
++	intel_hdmi->dp_dual_mode.max_tmds_clock = 0;
++
+ 	kfree(to_intel_connector(connector)->detect_edid);
+ 	to_intel_connector(connector)->detect_edid = NULL;
+ }
+ 
++static void
++intel_hdmi_dp_dual_mode_detect(struct drm_connector *connector)
++{
++	struct drm_i915_private *dev_priv = to_i915(connector->dev);
++	struct intel_hdmi *hdmi = intel_attached_hdmi(connector);
++	struct i2c_adapter *adapter =
++		intel_gmbus_get_adapter(dev_priv, hdmi->ddc_bus);
++	enum drm_dp_dual_mode_type type = drm_dp_dual_mode_detect(adapter);
++
++	if (type == DRM_DP_DUAL_MODE_NONE ||
++	    type == DRM_DP_DUAL_MODE_UNKNOWN)
++		return;
++
++	hdmi->dp_dual_mode.type = type;
++	hdmi->dp_dual_mode.max_tmds_clock =
++		drm_dp_dual_mode_max_tmds_clock(type, adapter);
++
++	DRM_DEBUG_KMS("DP dual mode adaptor (%s) detected (max TMDS clock: %d kHz)\n",
++		      drm_dp_get_dual_mode_type_name(type),
++		      hdmi->dp_dual_mode.max_tmds_clock);
++}
++
+ static bool
+ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
+ {
+@@ -1371,6 +1431,8 @@ intel_hdmi_set_edid(struct drm_connector *connector, bool force)
+ 				    intel_gmbus_get_adapter(dev_priv,
+ 				    intel_hdmi->ddc_bus));
+ 
++		intel_hdmi_dp_dual_mode_detect(connector);
++
+ 		intel_display_power_put(dev_priv, POWER_DOMAIN_GMBUS);
+ 	}
+ 
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 3425d8e737b3..54ab023427c7 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -3845,6 +3845,8 @@ static void ilk_pipe_wm_get_hw_state(struct drm_crtc *crtc)
+ 	if (IS_HASWELL(dev) || IS_BROADWELL(dev))
+ 		hw->wm_linetime[pipe] = I915_READ(PIPE_WM_LINETIME(pipe));
+ 
++	memset(active, 0, sizeof(*active));
++
+ 	active->pipe_enabled = intel_crtc->active;
+ 
+ 	if (active->pipe_enabled) {
+diff --git a/drivers/gpu/drm/i915/intel_psr.c b/drivers/gpu/drm/i915/intel_psr.c
+index 0b42ada338c8..bd322d8fba40 100644
+--- a/drivers/gpu/drm/i915/intel_psr.c
++++ b/drivers/gpu/drm/i915/intel_psr.c
+@@ -280,7 +280,10 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
+ 	 * with the 5 or 6 idle patterns.
+ 	 */
+ 	uint32_t idle_frames = max(6, dev_priv->vbt.psr.idle_frames);
+-	uint32_t val = 0x0;
++	uint32_t val = EDP_PSR_ENABLE;
++
++	val |= max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT;
++	val |= idle_frames << EDP_PSR_IDLE_FRAME_SHIFT;
+ 
+ 	if (IS_HASWELL(dev))
+ 		val |= EDP_PSR_MIN_LINK_ENTRY_TIME_8_LINES;
+@@ -288,14 +291,50 @@ static void hsw_psr_enable_source(struct intel_dp *intel_dp)
+ 	if (dev_priv->psr.link_standby)
+ 		val |= EDP_PSR_LINK_STANDBY;
+ 
+-	I915_WRITE(EDP_PSR_CTL, val |
+-		   max_sleep_time << EDP_PSR_MAX_SLEEP_TIME_SHIFT |
+-		   idle_frames << EDP_PSR_IDLE_FRAME_SHIFT |
+-		   EDP_PSR_ENABLE);
++	if (dev_priv->vbt.psr.tp1_wakeup_time > 5)
++		val |= EDP_PSR_TP1_TIME_2500us;
++	else if (dev_priv->vbt.psr.tp1_wakeup_time > 1)
++		val |= EDP_PSR_TP1_TIME_500us;
++	else if (dev_priv->vbt.psr.tp1_wakeup_time > 0)
++		val |= EDP_PSR_TP1_TIME_100us;
++	else
++		val |= EDP_PSR_TP1_TIME_0us;
++
++	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
++		val |= EDP_PSR_TP2_TP3_TIME_2500us;
++	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
++		val |= EDP_PSR_TP2_TP3_TIME_500us;
++	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
++		val |= EDP_PSR_TP2_TP3_TIME_100us;
++	else
++		val |= EDP_PSR_TP2_TP3_TIME_0us;
++
++	if (intel_dp_source_supports_hbr2(intel_dp) &&
++	    drm_dp_tps3_supported(intel_dp->dpcd))
++		val |= EDP_PSR_TP1_TP3_SEL;
++	else
++		val |= EDP_PSR_TP1_TP2_SEL;
++
++	I915_WRITE(EDP_PSR_CTL, val);
++
++	if (!dev_priv->psr.psr2_support)
++		return;
++
++	/* FIXME: selective update is probably totally broken because it doesn't
++	 * mesh at all with our frontbuffer tracking. And the hw alone isn't
++	 * good enough. */
++	val = EDP_PSR2_ENABLE | EDP_SU_TRACK_ENABLE;
++
++	if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 5)
++		val |= EDP_PSR2_TP2_TIME_2500;
++	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 1)
++		val |= EDP_PSR2_TP2_TIME_500;
++	else if (dev_priv->vbt.psr.tp2_tp3_wakeup_time > 0)
++		val |= EDP_PSR2_TP2_TIME_100;
++	else
++		val |= EDP_PSR2_TP2_TIME_50;
+ 
+-	if (dev_priv->psr.psr2_support)
+-		I915_WRITE(EDP_PSR2_CTL, EDP_PSR2_ENABLE |
+-				EDP_SU_TRACK_ENABLE | EDP_PSR2_TP2_TIME_100);
++	I915_WRITE(EDP_PSR2_CTL, val);
+ }
+ 
+ static bool intel_psr_match_conditions(struct intel_dp *intel_dp)
+diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
+index e26dcdec2aba..05229b960e0c 100644
+--- a/drivers/gpu/drm/imx/imx-drm-core.c
++++ b/drivers/gpu/drm/imx/imx-drm-core.c
+@@ -25,6 +25,7 @@
+ #include <drm/drm_fb_cma_helper.h>
+ #include <drm/drm_plane_helper.h>
+ #include <drm/drm_of.h>
++#include <video/imx-ipu-v3.h>
+ 
+ #include "imx-drm.h"
+ 
+@@ -444,6 +445,13 @@ static int compare_of(struct device *dev, void *data)
+ {
+ 	struct device_node *np = data;
+ 
++	/* Special case for DI, dev->of_node may not be set yet */
++	if (strcmp(dev->driver->name, "imx-ipuv3-crtc") == 0) {
++		struct ipu_client_platformdata *pdata = dev->platform_data;
++
++		return pdata->of_node == np;
++	}
++
+ 	/* Special case for LDB, one device for two channels */
+ 	if (of_node_cmp(np->name, "lvds-channel") == 0) {
+ 		np = of_get_parent(np);
+diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c
+index dee8e8b3523b..b2c30b8d9816 100644
+--- a/drivers/gpu/drm/imx/ipuv3-crtc.c
++++ b/drivers/gpu/drm/imx/ipuv3-crtc.c
+@@ -473,7 +473,7 @@ static int ipu_crtc_init(struct ipu_crtc *ipu_crtc,
+ 
+ 	ret = imx_drm_add_crtc(drm, &ipu_crtc->base, &ipu_crtc->imx_crtc,
+ 			&ipu_crtc->plane[0]->base, &ipu_crtc_helper_funcs,
+-			ipu_crtc->dev->of_node);
++			pdata->of_node);
+ 	if (ret) {
+ 		dev_err(ipu_crtc->dev, "adding crtc failed with %d.\n", ret);
+ 		goto err_put_resources;
+diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
+index c03b96709179..701c51ed3e7c 100644
+--- a/drivers/gpu/drm/msm/msm_drv.c
++++ b/drivers/gpu/drm/msm/msm_drv.c
+@@ -465,7 +465,6 @@ static void msm_preclose(struct drm_device *dev, struct drm_file *file)
+ {
+ 	struct msm_drm_private *priv = dev->dev_private;
+ 	struct msm_file_private *ctx = file->driver_priv;
+-	struct msm_kms *kms = priv->kms;
+ 
+ 	mutex_lock(&dev->struct_mutex);
+ 	if (ctx == priv->lastctx)
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index 6cbb7d4bdd11..f2cf9231872a 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -628,6 +628,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
+ 	mutex_init(&dev_priv->cmdbuf_mutex);
+ 	mutex_init(&dev_priv->release_mutex);
+ 	mutex_init(&dev_priv->binding_mutex);
++	mutex_init(&dev_priv->global_kms_state_mutex);
+ 	rwlock_init(&dev_priv->resource_lock);
+ 	ttm_lock_init(&dev_priv->reservation_sem);
+ 	spin_lock_init(&dev_priv->hw_lock);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index 019a6ca3e8e9..6db358a85b46 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -412,6 +412,7 @@ struct vmw_private {
+ 	struct drm_property *implicit_placement_property;
+ 	unsigned num_implicit;
+ 	struct vmw_framebuffer *implicit_fb;
++	struct mutex global_kms_state_mutex;
+ 
+ 	/*
+ 	 * Context and surface management.
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index 4742ec4ead27..b07543b5cea4 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -2143,13 +2143,13 @@ int vmw_kms_fbdev_init_data(struct vmw_private *dev_priv,
+ void vmw_kms_del_active(struct vmw_private *dev_priv,
+ 			struct vmw_display_unit *du)
+ {
+-	lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+-
++	mutex_lock(&dev_priv->global_kms_state_mutex);
+ 	if (du->active_implicit) {
+ 		if (--(dev_priv->num_implicit) == 0)
+ 			dev_priv->implicit_fb = NULL;
+ 		du->active_implicit = false;
+ 	}
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ }
+ 
+ /**
+@@ -2165,8 +2165,7 @@ void vmw_kms_add_active(struct vmw_private *dev_priv,
+ 			struct vmw_display_unit *du,
+ 			struct vmw_framebuffer *vfb)
+ {
+-	lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+-
++	mutex_lock(&dev_priv->global_kms_state_mutex);
+ 	WARN_ON_ONCE(!dev_priv->num_implicit && dev_priv->implicit_fb);
+ 
+ 	if (!du->active_implicit && du->is_implicit) {
+@@ -2174,6 +2173,7 @@ void vmw_kms_add_active(struct vmw_private *dev_priv,
+ 		du->active_implicit = true;
+ 		dev_priv->num_implicit++;
+ 	}
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ }
+ 
+ /**
+@@ -2190,16 +2190,13 @@ bool vmw_kms_crtc_flippable(struct vmw_private *dev_priv,
+ 			    struct drm_crtc *crtc)
+ {
+ 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
++	bool ret;
+ 
+-	lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
+-
+-	if (!du->is_implicit)
+-		return true;
+-
+-	if (dev_priv->num_implicit != 1)
+-		return false;
++	mutex_lock(&dev_priv->global_kms_state_mutex);
++	ret = !du->is_implicit || dev_priv->num_implicit == 1;
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ 
+-	return true;
++	return ret;
+ }
+ 
+ /**
+@@ -2214,16 +2211,18 @@ void vmw_kms_update_implicit_fb(struct vmw_private *dev_priv,
+ 	struct vmw_display_unit *du = vmw_crtc_to_du(crtc);
+ 	struct vmw_framebuffer *vfb;
+ 
+-	lockdep_assert_held_once(&dev_priv->dev->mode_config.mutex);
++	mutex_lock(&dev_priv->global_kms_state_mutex);
+ 
+ 	if (!du->is_implicit)
+-		return;
++		goto out_unlock;
+ 
+ 	vfb = vmw_framebuffer_to_vfb(crtc->primary->fb);
+ 	WARN_ON_ONCE(dev_priv->num_implicit != 1 &&
+ 		     dev_priv->implicit_fb != vfb);
+ 
+ 	dev_priv->implicit_fb = vfb;
++out_unlock:
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ }
+ 
+ /**
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+index 0ea22fd112c9..b74eae2b8594 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
+@@ -285,14 +285,17 @@ static int vmw_sou_crtc_set_config(struct drm_mode_set *set)
+ 	}
+ 
+ 	/* Only one active implicit frame-buffer at a time. */
++	mutex_lock(&dev_priv->global_kms_state_mutex);
+ 	if (sou->base.is_implicit &&
+ 	    dev_priv->implicit_fb && vfb &&
+ 	    !(dev_priv->num_implicit == 1 &&
+ 	      sou->base.active_implicit) &&
+ 	    dev_priv->implicit_fb != vfb) {
++		mutex_unlock(&dev_priv->global_kms_state_mutex);
+ 		DRM_ERROR("Multiple implicit framebuffers not supported.\n");
+ 		return -EINVAL;
+ 	}
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ 
+ 	/* since they always map one to one these are safe */
+ 	connector = &sou->base.connector;
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+index b949102ad864..9ca818fb034c 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+@@ -553,12 +553,15 @@ static int vmw_stdu_crtc_set_config(struct drm_mode_set *set)
+ 	}
+ 
+ 	/* Only one active implicit frame-buffer at a time. */
++	mutex_lock(&dev_priv->global_kms_state_mutex);
+ 	if (!turning_off && stdu->base.is_implicit && dev_priv->implicit_fb &&
+ 	    !(dev_priv->num_implicit == 1 && stdu->base.active_implicit)
+ 	    && dev_priv->implicit_fb != vfb) {
++		mutex_unlock(&dev_priv->global_kms_state_mutex);
+ 		DRM_ERROR("Multiple implicit framebuffers not supported.\n");
+ 		return -EINVAL;
+ 	}
++	mutex_unlock(&dev_priv->global_kms_state_mutex);
+ 
+ 	/* Since they always map one to one these are safe */
+ 	connector = &stdu->base.connector;
+diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c
+index abb98c77bad2..99dcacf05b99 100644
+--- a/drivers/gpu/ipu-v3/ipu-common.c
++++ b/drivers/gpu/ipu-v3/ipu-common.c
+@@ -997,7 +997,7 @@ struct ipu_platform_reg {
+ };
+ 
+ /* These must be in the order of the corresponding device tree port nodes */
+-static const struct ipu_platform_reg client_reg[] = {
++static struct ipu_platform_reg client_reg[] = {
+ 	{
+ 		.pdata = {
+ 			.csi = 0,
+@@ -1048,7 +1048,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
+ 	mutex_unlock(&ipu_client_id_mutex);
+ 
+ 	for (i = 0; i < ARRAY_SIZE(client_reg); i++) {
+-		const struct ipu_platform_reg *reg = &client_reg[i];
++		struct ipu_platform_reg *reg = &client_reg[i];
+ 		struct platform_device *pdev;
+ 		struct device_node *of_node;
+ 
+@@ -1070,6 +1070,7 @@ static int ipu_add_client_devices(struct ipu_soc *ipu, unsigned long ipu_base)
+ 
+ 		pdev->dev.parent = dev;
+ 
++		reg->pdata.of_node = of_node;
+ 		ret = platform_device_add_data(pdev, &reg->pdata,
+ 					       sizeof(reg->pdata));
+ 		if (!ret)
+diff --git a/drivers/hwmon/ads7828.c b/drivers/hwmon/ads7828.c
+index 6c99ee7bafa3..ee396ff167d9 100644
+--- a/drivers/hwmon/ads7828.c
++++ b/drivers/hwmon/ads7828.c
+@@ -120,6 +120,7 @@ static int ads7828_probe(struct i2c_client *client,
+ 	unsigned int vref_mv = ADS7828_INT_VREF_MV;
+ 	bool diff_input = false;
+ 	bool ext_vref = false;
++	unsigned int regval;
+ 
+ 	data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
+ 	if (!data)
+@@ -154,6 +155,15 @@ static int ads7828_probe(struct i2c_client *client,
+ 	if (!diff_input)
+ 		data->cmd_byte |= ADS7828_CMD_SD_SE;
+ 
++	/*
++	 * Datasheet specifies internal reference voltage is disabled by
++	 * default. The internal reference voltage needs to be enabled and
++	 * voltage needs to settle before getting valid ADC data. So perform a
++	 * dummy read to enable the internal reference voltage.
++	 */
++	if (!ext_vref)
++		regmap_read(data->regmap, data->cmd_byte, &regval);
++
+ 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+ 							   data,
+ 							   ads7828_groups);
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index 1142a93dd90b..ca62a6e11846 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -457,6 +457,10 @@ static void xpad_process_packet(struct usb_xpad *xpad, u16 cmd, unsigned char *d
+ static void xpad360_process_packet(struct usb_xpad *xpad, struct input_dev *dev,
+ 				   u16 cmd, unsigned char *data)
+ {
++	/* valid pad data */
++	if (data[0] != 0x00)
++		return;
++
+ 	/* digital pad */
+ 	if (xpad->mapping & MAP_DPAD_TO_BUTTONS) {
+ 		/* dpad as buttons (left, right, up, down) */
+@@ -756,6 +760,7 @@ static bool xpad_prepare_next_out_packet(struct usb_xpad *xpad)
+ 	if (packet) {
+ 		memcpy(xpad->odata, packet->data, packet->len);
+ 		xpad->irq_out->transfer_buffer_length = packet->len;
++		packet->pending = false;
+ 		return true;
+ 	}
+ 
+@@ -797,7 +802,6 @@ static void xpad_irq_out(struct urb *urb)
+ 	switch (status) {
+ 	case 0:
+ 		/* success */
+-		xpad->out_packets[xpad->last_out_packet].pending = false;
+ 		xpad->irq_out_active = xpad_prepare_next_out_packet(xpad);
+ 		break;
+ 
+diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
+index abe1a927b332..65ebbd111702 100644
+--- a/drivers/input/misc/uinput.c
++++ b/drivers/input/misc/uinput.c
+@@ -981,9 +981,15 @@ static long uinput_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+ }
+ 
+ #ifdef CONFIG_COMPAT
++
++#define UI_SET_PHYS_COMPAT	_IOW(UINPUT_IOCTL_BASE, 108, compat_uptr_t)
++
+ static long uinput_compat_ioctl(struct file *file,
+ 				unsigned int cmd, unsigned long arg)
+ {
++	if (cmd == UI_SET_PHYS_COMPAT)
++		cmd = UI_SET_PHYS;
++
+ 	return uinput_ioctl_handler(file, cmd, arg, compat_ptr(arg));
+ }
+ #endif
+diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+index 019644ff627d..bacecbd68a6d 100644
+--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
++++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
+@@ -280,7 +280,8 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
+ static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
+ {
+ 	if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
+-	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)))
++	    copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format)) ||
++	    copy_to_user(up->reserved, kp->reserved, sizeof(kp->reserved)))
+ 		return -EFAULT;
+ 	return __put_v4l2_format32(&kp->format, &up->format);
+ }
+diff --git a/drivers/mfd/intel-lpss.c b/drivers/mfd/intel-lpss.c
+index 1bbbe877ba7e..807a3e3ec29a 100644
+--- a/drivers/mfd/intel-lpss.c
++++ b/drivers/mfd/intel-lpss.c
+@@ -34,6 +34,7 @@
+ #define LPSS_DEV_SIZE		0x200
+ #define LPSS_PRIV_OFFSET	0x200
+ #define LPSS_PRIV_SIZE		0x100
++#define LPSS_PRIV_REG_COUNT	(LPSS_PRIV_SIZE / 4)
+ #define LPSS_IDMA64_OFFSET	0x800
+ #define LPSS_IDMA64_SIZE	0x800
+ 
+@@ -76,6 +77,7 @@ struct intel_lpss {
+ 	struct mfd_cell *cell;
+ 	struct device *dev;
+ 	void __iomem *priv;
++	u32 priv_ctx[LPSS_PRIV_REG_COUNT];
+ 	int devid;
+ 	u32 caps;
+ 	u32 active_ltr;
+@@ -493,6 +495,16 @@ EXPORT_SYMBOL_GPL(intel_lpss_prepare);
+ 
+ int intel_lpss_suspend(struct device *dev)
+ {
++	struct intel_lpss *lpss = dev_get_drvdata(dev);
++	unsigned int i;
++
++	/* Save device context */
++	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);
+@@ -500,8 +512,13 @@ EXPORT_SYMBOL_GPL(intel_lpss_suspend);
+ int intel_lpss_resume(struct device *dev)
+ {
+ 	struct intel_lpss *lpss = dev_get_drvdata(dev);
++	unsigned int i;
+ 
+-	intel_lpss_init_dev(lpss);
++	intel_lpss_deassert_reset(lpss);
++
++	/* Restore device context */
++	for (i = 0; i < LPSS_PRIV_REG_COUNT; i++)
++		writel(lpss->priv_ctx[i], lpss->priv + i * 4);
+ 
+ 	return 0;
+ }
+diff --git a/drivers/mfd/intel_quark_i2c_gpio.c b/drivers/mfd/intel_quark_i2c_gpio.c
+index bdc5e27222c0..7450f5d8770c 100644
+--- a/drivers/mfd/intel_quark_i2c_gpio.c
++++ b/drivers/mfd/intel_quark_i2c_gpio.c
+@@ -139,6 +139,7 @@ static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
+ 						INTEL_QUARK_I2C_CONTROLLER_CLK);
+ 
+ 	if (!quark_mfd->i2c_clk_lookup) {
++		clk_unregister(quark_mfd->i2c_clk);
+ 		dev_err(&pdev->dev, "Fixed clk register failed\n");
+ 		return -ENOMEM;
+ 	}
+@@ -150,7 +151,7 @@ static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
+ {
+ 	struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
+ 
+-	if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup)
++	if (!quark_mfd->i2c_clk_lookup)
+ 		return;
+ 
+ 	clkdev_drop(quark_mfd->i2c_clk_lookup);
+@@ -246,25 +247,33 @@ static int intel_quark_mfd_probe(struct pci_dev *pdev,
+ 	quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
+ 	if (!quark_mfd)
+ 		return -ENOMEM;
++
+ 	quark_mfd->pdev = pdev;
++	dev_set_drvdata(&pdev->dev, quark_mfd);
+ 
+ 	ret = intel_quark_register_i2c_clk(quark_mfd);
+ 	if (ret)
+ 		return ret;
+ 
+-	dev_set_drvdata(&pdev->dev, quark_mfd);
+-
+ 	ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[1]);
+ 	if (ret)
+-		return ret;
++		goto err_unregister_i2c_clk;
+ 
+ 	ret = intel_quark_gpio_setup(pdev, &intel_quark_mfd_cells[0]);
+ 	if (ret)
+-		return ret;
++		goto err_unregister_i2c_clk;
+ 
+-	return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
+-			       ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
+-			       NULL);
++	ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
++			      ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
++			      NULL);
++	if (ret)
++		goto err_unregister_i2c_clk;
++
++	return 0;
++
++err_unregister_i2c_clk:
++	intel_quark_unregister_i2c_clk(pdev);
++	return ret;
+ }
+ 
+ static void intel_quark_mfd_remove(struct pci_dev *pdev)
+diff --git a/drivers/mfd/intel_soc_pmic_core.c b/drivers/mfd/intel_soc_pmic_core.c
+index d9e15cf7c6c8..12d6ebb4ae5d 100644
+--- a/drivers/mfd/intel_soc_pmic_core.c
++++ b/drivers/mfd/intel_soc_pmic_core.c
+@@ -35,6 +35,7 @@ static struct gpiod_lookup_table panel_gpio_table = {
+ 	.table = {
+ 		/* Panel EN/DISABLE */
+ 		GPIO_LOOKUP("gpio_crystalcove", 94, "panel", GPIO_ACTIVE_HIGH),
++		{ },
+ 	},
+ };
+ 
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c
+index c84c2d30ef1f..fb793612c7bd 100644
+--- a/drivers/net/wireless/ath/ath10k/core.c
++++ b/drivers/net/wireless/ath/ath10k/core.c
+@@ -1723,6 +1723,10 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
+ 		goto err_hif_stop;
+ 	}
+ 
++	ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
++
++	INIT_LIST_HEAD(&ar->arvifs);
++
+ 	/* we don't care about HTT in UTF mode */
+ 	if (mode == ATH10K_FIRMWARE_MODE_NORMAL) {
+ 		status = ath10k_htt_setup(&ar->htt);
+@@ -1736,10 +1740,6 @@ int ath10k_core_start(struct ath10k *ar, enum ath10k_firmware_mode mode)
+ 	if (status)
+ 		goto err_hif_stop;
+ 
+-	ar->free_vdev_map = (1LL << ar->max_num_vdevs) - 1;
+-
+-	INIT_LIST_HEAD(&ar->arvifs);
+-
+ 	return 0;
+ 
+ err_hif_stop:
+diff --git a/drivers/net/wireless/ath/ath10k/debug.c b/drivers/net/wireless/ath/ath10k/debug.c
+index 076d29b53ddf..0f834646e6a7 100644
+--- a/drivers/net/wireless/ath/ath10k/debug.c
++++ b/drivers/net/wireless/ath/ath10k/debug.c
+@@ -2019,7 +2019,12 @@ static ssize_t ath10k_write_pktlog_filter(struct file *file,
+ 		goto out;
+ 	}
+ 
+-	if (filter && (filter != ar->debug.pktlog_filter)) {
++	if (filter == ar->debug.pktlog_filter) {
++		ret = count;
++		goto out;
++	}
++
++	if (filter) {
+ 		ret = ath10k_wmi_pdev_pktlog_enable(ar, filter);
+ 		if (ret) {
+ 			ath10k_warn(ar, "failed to enable pktlog filter %x: %d\n",
+diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
+index 78999c9de23b..e11160ab44bb 100644
+--- a/drivers/net/wireless/ath/ath10k/mac.c
++++ b/drivers/net/wireless/ath/ath10k/mac.c
+@@ -4489,7 +4489,10 @@ static int ath10k_add_interface(struct ieee80211_hw *hw,
+ 		goto err_vdev_delete;
+ 	}
+ 
+-	if (ar->cfg_tx_chainmask) {
++	/* Configuring number of spatial stream for monitor interface is causing
++	 * target assert in qca9888 and qca6174.
++	 */
++	if (ar->cfg_tx_chainmask && (vif->type != NL80211_IFTYPE_MONITOR)) {
+ 		u16 nss = get_nss_from_chainmask(ar->cfg_tx_chainmask);
+ 
+ 		vdev_param = ar->wmi.vdev_param->nss;
+@@ -6450,7 +6453,13 @@ ath10k_mac_update_rx_channel(struct ath10k *ar,
+ 			def = &vifs[0].new_ctx->def;
+ 
+ 		ar->rx_channel = def->chan;
+-	} else if (ctx && ath10k_mac_num_chanctxs(ar) == 0) {
++	} else if ((ctx && ath10k_mac_num_chanctxs(ar) == 0) ||
++		   (ctx && (ar->state == ATH10K_STATE_RESTARTED))) {
++		/* During driver restart due to firmware assert, since mac80211
++		 * already has valid channel context for given radio, channel
++		 * context iteration return num_chanctx > 0. So fix rx_channel
++		 * when restart is in progress.
++		 */
+ 		ar->rx_channel = ctx->def.chan;
+ 	} else {
+ 		ar->rx_channel = NULL;
+diff --git a/drivers/net/wireless/ath/ath5k/led.c b/drivers/net/wireless/ath/ath5k/led.c
+index 803030fd17d3..6a2a16856763 100644
+--- a/drivers/net/wireless/ath/ath5k/led.c
++++ b/drivers/net/wireless/ath/ath5k/led.c
+@@ -77,7 +77,7 @@ static const struct pci_device_id ath5k_led_devices[] = {
+ 	/* HP Compaq CQ60-206US (ddreggors@jumptv.com) */
+ 	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137a), ATH_LED(3, 1) },
+ 	/* HP Compaq C700 (nitrousnrg@gmail.com) */
+-	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 1) },
++	{ ATH_SDEVICE(PCI_VENDOR_ID_HP, 0x0137b), ATH_LED(3, 0) },
+ 	/* LiteOn AR5BXB63 (magooz@salug.it) */
+ 	{ ATH_SDEVICE(PCI_VENDOR_ID_ATHEROS, 0x3067), ATH_LED(3, 0) },
+ 	/* IBM-specific AR5212 (all others) */
+diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
+index 1c226d63bb03..deded2a9a860 100644
+--- a/drivers/net/wireless/ath/ath9k/init.c
++++ b/drivers/net/wireless/ath/ath9k/init.c
+@@ -49,6 +49,10 @@ int ath9k_led_blink;
+ module_param_named(blink, ath9k_led_blink, int, 0444);
+ MODULE_PARM_DESC(blink, "Enable LED blink on activity");
+ 
++static int ath9k_led_active_high = -1;
++module_param_named(led_active_high, ath9k_led_active_high, int, 0444);
++MODULE_PARM_DESC(led_active_high, "Invert LED polarity");
++
+ static int ath9k_btcoex_enable;
+ module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
+ MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
+@@ -600,6 +604,9 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
+ 	if (ret)
+ 		return ret;
+ 
++	if (ath9k_led_active_high != -1)
++		ah->config.led_active_high = ath9k_led_active_high == 1;
++
+ 	/*
+ 	 * Enable WLAN/BT RX Antenna diversity only when:
+ 	 *
+diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
+index e6fef1be9977..7cdaf40c3057 100644
+--- a/drivers/net/wireless/ath/ath9k/pci.c
++++ b/drivers/net/wireless/ath/ath9k/pci.c
+@@ -28,6 +28,16 @@ static const struct pci_device_id ath_pci_id_table[] = {
+ 	{ 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 */
++	{ PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
++			 0x0029,
++			 PCI_VENDOR_ID_ATHEROS,
++			 0x2096),
++	  .driver_data = ATH9K_PCI_LED_ACT_HI },
++#endif
++
+ 	{ PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
+ 
+ #ifdef CONFIG_ATH9K_PCOEM
+diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c b/drivers/net/wireless/realtek/rtlwifi/base.c
+index 0517a4f2d3f2..7a40d8dffa36 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/base.c
++++ b/drivers/net/wireless/realtek/rtlwifi/base.c
+@@ -1660,9 +1660,9 @@ void rtl_watchdog_wq_callback(void *data)
+ 		if (((rtlpriv->link_info.num_rx_inperiod +
+ 		      rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ 		    (rtlpriv->link_info.num_rx_inperiod > 2))
+-			rtl_lps_enter(hw);
+-		else
+ 			rtl_lps_leave(hw);
++		else
++			rtl_lps_enter(hw);
+ 	}
+ 
+ 	rtlpriv->link_info.num_rx_inperiod = 0;
+diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
+index c43ab59a690a..77cbd10e807d 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
++++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtc8723b2ant.c
+@@ -1203,7 +1203,6 @@ static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist,
+ 
+ 		/* Force GNT_BT to low */
+ 		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
+-		btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+ 
+ 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
+ 			/* tell firmware "no antenna inverse" */
+@@ -1211,19 +1210,25 @@ static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist,
+ 			h2c_parameter[1] = 1;  /* ext switch type */
+ 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+ 						h2c_parameter);
++			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
+ 		} else {
+ 			/* tell firmware "antenna inverse" */
+ 			h2c_parameter[0] = 1;
+ 			h2c_parameter[1] = 1;  /* ext switch type */
+ 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
+ 						h2c_parameter);
++			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
+ 		}
+ 	}
+ 
+ 	/* ext switch setting */
+ 	if (use_ext_switch) {
+ 		/* fixed internal switch S1->WiFi, S0->BT */
+-		btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
++		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
++			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
++		else
++			btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
++
+ 		switch (antpos_type) {
+ 		case BTC_ANT_WIFI_AT_MAIN:
+ 			/* ext switch main at wifi */
+diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+index b2791c893417..babd1490f20c 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
++++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.c
+@@ -965,13 +965,38 @@ void exhalbtc_set_chip_type(u8 chip_type)
+ 	}
+ }
+ 
+-void exhalbtc_set_ant_num(u8 type, u8 ant_num)
++void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num)
+ {
+ 	if (BT_COEX_ANT_TYPE_PG == type) {
+ 		gl_bt_coexist.board_info.pg_ant_num = ant_num;
+ 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
++		/* The antenna position:
++		 * Main (default) or Aux for pgAntNum=2 && btdmAntNum =1.
++		 * The antenna position should be determined by
++		 * auto-detect mechanism.
++		 * The following is assumed to main,
++		 * and those must be modified
++		 * if y auto-detect mechanism is ready
++		 */
++		if ((gl_bt_coexist.board_info.pg_ant_num == 2) &&
++		    (gl_bt_coexist.board_info.btdm_ant_num == 1))
++			gl_bt_coexist.board_info.btdm_ant_pos =
++						       BTC_ANTENNA_AT_MAIN_PORT;
++		else
++			gl_bt_coexist.board_info.btdm_ant_pos =
++						       BTC_ANTENNA_AT_MAIN_PORT;
+ 	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
+ 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
++		gl_bt_coexist.board_info.btdm_ant_pos =
++						       BTC_ANTENNA_AT_MAIN_PORT;
++	} else if (type == BT_COEX_ANT_TYPE_DETECTED) {
++		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
++		if (rtlpriv->cfg->mod_params->ant_sel == 1)
++			gl_bt_coexist.board_info.btdm_ant_pos =
++				BTC_ANTENNA_AT_AUX_PORT;
++		else
++			gl_bt_coexist.board_info.btdm_ant_pos =
++				BTC_ANTENNA_AT_MAIN_PORT;
+ 	}
+ }
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+index 0a903ea179ef..f41ca57dd8a7 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
++++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/halbtcoutsrc.h
+@@ -535,7 +535,7 @@ void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version);
+ void exhalbtc_update_min_bt_rssi(char bt_rssi);
+ void exhalbtc_set_bt_exist(bool bt_exist);
+ void exhalbtc_set_chip_type(u8 chip_type);
+-void exhalbtc_set_ant_num(u8 type, u8 ant_num);
++void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num);
+ void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist);
+ void exhalbtc_signal_compensation(struct btc_coexist *btcoexist,
+ 				  u8 *rssi_wifi, u8 *rssi_bt);
+diff --git a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
+index b9b0cb7af8ea..d3fd9211b3a4 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
++++ b/drivers/net/wireless/realtek/rtlwifi/btcoexist/rtl_btc.c
+@@ -72,7 +72,10 @@ void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv)
+ 		 __func__, bt_type);
+ 	exhalbtc_set_chip_type(bt_type);
+ 
+-	exhalbtc_set_ant_num(BT_COEX_ANT_TYPE_PG, ant_num);
++	if (rtlpriv->cfg->mod_params->ant_sel == 1)
++		exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_DETECTED, 1);
++	else
++		exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
+ }
+ 
+ void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv)
+diff --git a/drivers/net/wireless/realtek/rtlwifi/pci.c b/drivers/net/wireless/realtek/rtlwifi/pci.c
+index 283d608b9973..e5037d13b772 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/pci.c
++++ b/drivers/net/wireless/realtek/rtlwifi/pci.c
+@@ -1573,7 +1573,7 @@ int rtl_pci_reset_trx_ring(struct ieee80211_hw *hw)
+ 							 true,
+ 							 HW_DESC_TXBUFF_ADDR),
+ 						 skb->len, PCI_DMA_TODEVICE);
+-				kfree_skb(skb);
++				dev_kfree_skb_irq(skb);
+ 				ring->idx = (ring->idx + 1) % ring->entries;
+ 			}
+ 			ring->idx = 0;
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+index c983d2fe147f..5a3df9198ddf 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/hw.c
+@@ -2684,6 +2684,7 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ 					      bool auto_load_fail, u8 *hwinfo)
+ {
+ 	struct rtl_priv *rtlpriv = rtl_priv(hw);
++	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
+ 	u8 value;
+ 	u32 tmpu_32;
+ 
+@@ -2702,6 +2703,10 @@ void rtl8723be_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw,
+ 		rtlpriv->btcoexist.btc_info.ant_num = ANT_X2;
+ 	}
+ 
++	/* override ant_num / ant_path */
++	if (mod_params->ant_sel)
++		rtlpriv->btcoexist.btc_info.ant_num =
++			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
+ }
+ 
+ void rtl8723be_bt_reg_init(struct ieee80211_hw *hw)
+diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
+index a78eaeda0008..2101793438ed 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
++++ b/drivers/net/wireless/realtek/rtlwifi/rtl8723be/sw.c
+@@ -273,6 +273,7 @@ static struct rtl_mod_params rtl8723be_mod_params = {
+ 	.msi_support = false,
+ 	.disable_watchdog = false,
+ 	.debug = DBG_EMERG,
++	.ant_sel = 0,
+ };
+ 
+ static struct rtl_hal_cfg rtl8723be_hal_cfg = {
+@@ -394,6 +395,7 @@ module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
+ module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444);
+ module_param_named(disable_watchdog, rtl8723be_mod_params.disable_watchdog,
+ 		   bool, 0444);
++module_param_named(ant_sel, rtl8723be_mod_params.ant_sel, int, 0444);
+ MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
+ MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
+ MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
+@@ -402,6 +404,7 @@ MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
+ MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
+ MODULE_PARM_DESC(disable_watchdog,
+ 		 "Set to 1 to disable the watchdog (default 0)\n");
++MODULE_PARM_DESC(ant_sel, "Set to 1 or 2 to force antenna number (default 0)\n");
+ 
+ static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/wifi.h b/drivers/net/wireless/realtek/rtlwifi/wifi.h
+index 554d81420f19..93bd7fcd2b61 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/wifi.h
++++ b/drivers/net/wireless/realtek/rtlwifi/wifi.h
+@@ -2246,6 +2246,9 @@ struct rtl_mod_params {
+ 
+ 	/* default 0: 1 means do not disable interrupts */
+ 	bool int_clear;
++
++	/* select antenna */
++	int ant_sel;
+ };
+ 
+ struct rtl_hal_usbint_cfg {
+diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
+index 8004f67c57ec..bf8405fb4ace 100644
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -179,9 +179,6 @@ int __pci_read_base(struct pci_dev *dev, enum pci_bar_type type,
+ 	u16 orig_cmd;
+ 	struct pci_bus_region region, inverted_region;
+ 
+-	if (dev->non_compliant_bars)
+-		return 0;
+-
+ 	mask = type ? PCI_ROM_ADDRESS_MASK : ~0;
+ 
+ 	/* No printks while decoding is disabled! */
+@@ -322,6 +319,9 @@ static void pci_read_bases(struct pci_dev *dev, unsigned int howmany, int rom)
+ {
+ 	unsigned int pos, reg;
+ 
++	if (dev->non_compliant_bars)
++		return;
++
+ 	for (pos = 0; pos < howmany; pos++) {
+ 		struct resource *res = &dev->resource[pos];
+ 		reg = PCI_BASE_ADDRESS_0 + (pos << 2);
+diff --git a/drivers/pinctrl/samsung/pinctrl-exynos5440.c b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
+index 00ab63abf1d9..dbbdf652c34a 100644
+--- a/drivers/pinctrl/samsung/pinctrl-exynos5440.c
++++ b/drivers/pinctrl/samsung/pinctrl-exynos5440.c
+@@ -107,6 +107,7 @@ struct exynos5440_pmx_func {
+  * @nr_groups: number of pin groups available.
+  * @pmx_functions: list of pin functions parsed from device tree.
+  * @nr_functions: number of pin functions available.
++ * @range: gpio range to register with pinctrl
+  */
+ struct exynos5440_pinctrl_priv_data {
+ 	void __iomem			*reg_base;
+@@ -117,6 +118,7 @@ struct exynos5440_pinctrl_priv_data {
+ 	unsigned int			nr_groups;
+ 	const struct exynos5440_pmx_func	*pmx_functions;
+ 	unsigned int			nr_functions;
++	struct pinctrl_gpio_range	range;
+ };
+ 
+ /**
+@@ -742,7 +744,6 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev,
+ 	struct pinctrl_desc *ctrldesc;
+ 	struct pinctrl_dev *pctl_dev;
+ 	struct pinctrl_pin_desc *pindesc, *pdesc;
+-	struct pinctrl_gpio_range grange;
+ 	char *pin_names;
+ 	int pin, ret;
+ 
+@@ -794,12 +795,12 @@ static int exynos5440_pinctrl_register(struct platform_device *pdev,
+ 		return PTR_ERR(pctl_dev);
+ 	}
+ 
+-	grange.name = "exynos5440-pctrl-gpio-range";
+-	grange.id = 0;
+-	grange.base = 0;
+-	grange.npins = EXYNOS5440_MAX_PINS;
+-	grange.gc = priv->gc;
+-	pinctrl_add_gpio_range(pctl_dev, &grange);
++	priv->range.name = "exynos5440-pctrl-gpio-range";
++	priv->range.id = 0;
++	priv->range.base = 0;
++	priv->range.npins = EXYNOS5440_MAX_PINS;
++	priv->range.gc = priv->gc;
++	pinctrl_add_gpio_range(pctl_dev, &priv->range);
+ 	return 0;
+ }
+ 
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index e0b764284773..fd0e4e37f4e1 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -3840,6 +3840,11 @@ static void rdev_init_debugfs(struct regulator_dev *rdev)
+ 			   &rdev->bypass_count);
+ }
+ 
++static int regulator_register_resolve_supply(struct device *dev, void *data)
++{
++	return regulator_resolve_supply(dev_to_rdev(dev));
++}
++
+ /**
+  * regulator_register - register regulator
+  * @regulator_desc: regulator to register
+@@ -3986,8 +3991,11 @@ regulator_register(const struct regulator_desc *regulator_desc,
+ 	}
+ 
+ 	rdev_init_debugfs(rdev);
+-out:
+ 	mutex_unlock(&regulator_list_mutex);
++
++	/* try to resolve regulators supply since a new one was registered */
++	class_for_each_device(&regulator_class, NULL, NULL,
++			      regulator_register_resolve_supply);
+ 	kfree(config);
+ 	return rdev;
+ 
+@@ -3998,15 +4006,16 @@ scrub:
+ 	regulator_ena_gpio_free(rdev);
+ 	device_unregister(&rdev->dev);
+ 	/* device core frees rdev */
+-	rdev = ERR_PTR(ret);
+ 	goto out;
+ 
+ wash:
+ 	regulator_ena_gpio_free(rdev);
+ clean:
+ 	kfree(rdev);
+-	rdev = ERR_PTR(ret);
+-	goto out;
++out:
++	mutex_unlock(&regulator_list_mutex);
++	kfree(config);
++	return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(regulator_register);
+ 
+diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h
+index efa493cf1bc6..edc2643df4d6 100644
+--- a/drivers/scsi/aacraid/aacraid.h
++++ b/drivers/scsi/aacraid/aacraid.h
+@@ -29,6 +29,7 @@ enum {
+ #define AAC_INT_MODE_MSI		(1<<1)
+ #define AAC_INT_MODE_AIF		(1<<2)
+ #define AAC_INT_MODE_SYNC		(1<<3)
++#define AAC_INT_MODE_MSIX		(1<<16)
+ 
+ #define AAC_INT_ENABLE_TYPE1_INTX	0xfffffffb
+ #define AAC_INT_ENABLE_TYPE1_MSIX	0xfffffffa
+diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
+index 2b4e75380ae6..87397deffb1f 100644
+--- a/drivers/scsi/aacraid/comminit.c
++++ b/drivers/scsi/aacraid/comminit.c
+@@ -37,6 +37,7 @@
+ #include <linux/spinlock.h>
+ #include <linux/slab.h>
+ #include <linux/blkdev.h>
++#include <linux/delay.h>
+ #include <linux/completion.h>
+ #include <linux/mm.h>
+ #include <scsi/scsi_host.h>
+@@ -47,6 +48,20 @@ struct aac_common aac_config = {
+ 	.irq_mod = 1
+ };
+ 
++static inline int aac_is_msix_mode(struct aac_dev *dev)
++{
++	u32 status;
++
++	status = src_readl(dev, MUnit.OMR);
++	return (status & AAC_INT_MODE_MSIX);
++}
++
++static inline void aac_change_to_intx(struct aac_dev *dev)
++{
++	aac_src_access_devreg(dev, AAC_DISABLE_MSIX);
++	aac_src_access_devreg(dev, AAC_ENABLE_INTX);
++}
++
+ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long commsize, unsigned long commalign)
+ {
+ 	unsigned char *base;
+@@ -427,6 +442,15 @@ struct aac_dev *aac_init_adapter(struct aac_dev *dev)
+ 	dev->comm_interface = AAC_COMM_PRODUCER;
+ 	dev->raw_io_interface = dev->raw_io_64 = 0;
+ 
++
++	/*
++	 * Enable INTX mode, if not done already Enabled
++	 */
++	if (aac_is_msix_mode(dev)) {
++		aac_change_to_intx(dev);
++		dev_info(&dev->pdev->dev, "Changed firmware to INTX mode");
++	}
++
+ 	if ((!aac_adapter_sync_cmd(dev, GET_ADAPTER_PROPERTIES,
+ 		0, 0, 0, 0, 0, 0,
+ 		status+0, status+1, status+2, status+3, NULL)) &&
+diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
+index 511bbc575062..bb7988d53216 100644
+--- a/drivers/scsi/aacraid/commsup.c
++++ b/drivers/scsi/aacraid/commsup.c
+@@ -637,10 +637,10 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
+ 					}
+ 					return -EFAULT;
+ 				}
+-				/* We used to udelay() here but that absorbed
+-				 * a CPU when a timeout occured. Not very
+-				 * useful. */
+-				cpu_relax();
++				/*
++				 * Allow other processes / CPUS to use core
++				 */
++				schedule();
+ 			}
+ 		} else if (down_interruptible(&fibptr->event_wait)) {
+ 			/* Do nothing ... satisfy
+@@ -1996,6 +1996,10 @@ int aac_command_thread(void *data)
+ 		if (difference <= 0)
+ 			difference = 1;
+ 		set_current_state(TASK_INTERRUPTIBLE);
++
++		if (kthread_should_stop())
++			break;
++
+ 		schedule_timeout(difference);
+ 
+ 		if (kthread_should_stop())
+diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
+index ff6caab8cc8b..79a1cec1a51f 100644
+--- a/drivers/scsi/aacraid/linit.c
++++ b/drivers/scsi/aacraid/linit.c
+@@ -1431,8 +1431,8 @@ static int aac_acquire_resources(struct aac_dev *dev)
+ 		/* After EEH recovery or suspend resume, max_msix count
+ 		 * may change, therfore updating in init as well.
+ 		 */
+-		aac_adapter_start(dev);
+ 		dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix);
++		aac_adapter_start(dev);
+ 	}
+ 	return 0;
+ 
+diff --git a/drivers/scsi/lpfc/lpfc_mem.c b/drivers/scsi/lpfc/lpfc_mem.c
+index 4fb3581d4614..3fa65338d3f5 100644
+--- a/drivers/scsi/lpfc/lpfc_mem.c
++++ b/drivers/scsi/lpfc/lpfc_mem.c
+@@ -231,13 +231,15 @@ lpfc_mem_free(struct lpfc_hba *phba)
+ 	if (phba->lpfc_hbq_pool)
+ 		pci_pool_destroy(phba->lpfc_hbq_pool);
+ 	phba->lpfc_hbq_pool = NULL;
+-	mempool_destroy(phba->rrq_pool);
++
++	if (phba->rrq_pool)
++		mempool_destroy(phba->rrq_pool);
+ 	phba->rrq_pool = NULL;
+ 
+ 	/* Free NLP memory pool */
+ 	mempool_destroy(phba->nlp_mem_pool);
+ 	phba->nlp_mem_pool = NULL;
+-	if (phba->sli_rev == LPFC_SLI_REV4) {
++	if (phba->sli_rev == LPFC_SLI_REV4 && phba->active_rrq_pool) {
+ 		mempool_destroy(phba->active_rrq_pool);
+ 		phba->active_rrq_pool = NULL;
+ 	}
+diff --git a/drivers/staging/rdma/hfi1/qp.c b/drivers/staging/rdma/hfi1/qp.c
+index dc9119e1b458..0401955b3b04 100644
+--- a/drivers/staging/rdma/hfi1/qp.c
++++ b/drivers/staging/rdma/hfi1/qp.c
+@@ -512,6 +512,7 @@ static void iowait_wakeup(struct iowait *wait, int reason)
+ static void iowait_sdma_drained(struct iowait *wait)
+ {
+ 	struct rvt_qp *qp = iowait_to_qp(wait);
++	unsigned long flags;
+ 
+ 	/*
+ 	 * This happens when the send engine notes
+@@ -519,12 +520,12 @@ static void iowait_sdma_drained(struct iowait *wait)
+ 	 * do the flush work until that QP's
+ 	 * sdma work has finished.
+ 	 */
+-	spin_lock(&qp->s_lock);
++	spin_lock_irqsave(&qp->s_lock, flags);
+ 	if (qp->s_flags & RVT_S_WAIT_DMA) {
+ 		qp->s_flags &= ~RVT_S_WAIT_DMA;
+ 		hfi1_schedule_send(qp);
+ 	}
+-	spin_unlock(&qp->s_lock);
++	spin_unlock_irqrestore(&qp->s_lock, flags);
+ }
+ 
+ /**
+diff --git a/drivers/tty/serial/ucc_uart.c b/drivers/tty/serial/ucc_uart.c
+index 1a7dc3c590b1..481eb2989a1e 100644
+--- a/drivers/tty/serial/ucc_uart.c
++++ b/drivers/tty/serial/ucc_uart.c
+@@ -1478,6 +1478,9 @@ static const struct of_device_id ucc_uart_match[] = {
+ 		.type = "serial",
+ 		.compatible = "ucc_uart",
+ 	},
++	{
++		.compatible = "fsl,t1040-ucc-uart",
++	},
+ 	{},
+ };
+ MODULE_DEVICE_TABLE(of, ucc_uart_match);
+diff --git a/drivers/xen/events/events_base.c b/drivers/xen/events/events_base.c
+index cb7138c97c69..71d49a95f8c0 100644
+--- a/drivers/xen/events/events_base.c
++++ b/drivers/xen/events/events_base.c
+@@ -487,7 +487,8 @@ static void eoi_pirq(struct irq_data *data)
+ 	if (!VALID_EVTCHN(evtchn))
+ 		return;
+ 
+-	if (unlikely(irqd_is_setaffinity_pending(data))) {
++	if (unlikely(irqd_is_setaffinity_pending(data)) &&
++	    likely(!irqd_irq_disabled(data))) {
+ 		int masked = test_and_set_mask(evtchn);
+ 
+ 		clear_evtchn(evtchn);
+@@ -1370,7 +1371,8 @@ static void ack_dynirq(struct irq_data *data)
+ 	if (!VALID_EVTCHN(evtchn))
+ 		return;
+ 
+-	if (unlikely(irqd_is_setaffinity_pending(data))) {
++	if (unlikely(irqd_is_setaffinity_pending(data)) &&
++	    likely(!irqd_irq_disabled(data))) {
+ 		int masked = test_and_set_mask(evtchn);
+ 
+ 		clear_evtchn(evtchn);
+diff --git a/fs/affs/super.c b/fs/affs/super.c
+index 2a6713b6b9f4..d6384863192c 100644
+--- a/fs/affs/super.c
++++ b/fs/affs/super.c
+@@ -528,7 +528,7 @@ affs_remount(struct super_block *sb, int *flags, char *data)
+ 	char			*prefix = NULL;
+ 
+ 	new_opts = kstrdup(data, GFP_KERNEL);
+-	if (!new_opts)
++	if (data && !new_opts)
+ 		return -ENOMEM;
+ 
+ 	pr_debug("%s(flags=0x%x,opts=\"%s\")\n", __func__, *flags, data);
+@@ -546,7 +546,8 @@ affs_remount(struct super_block *sb, int *flags, char *data)
+ 	}
+ 
+ 	flush_delayed_work(&sbi->sb_work);
+-	replace_mount_options(sb, new_opts);
++	if (new_opts)
++		replace_mount_options(sb, new_opts);
+ 
+ 	sbi->s_flags = mount_flags;
+ 	sbi->s_mode  = mode;
+diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
+index 237b877d316d..3da4cf8d18b6 100644
+--- a/fs/ext4/ialloc.c
++++ b/fs/ext4/ialloc.c
+@@ -1150,25 +1150,20 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
+ 	unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
+ 	ext4_group_t block_group;
+ 	int bit;
+-	struct buffer_head *bitmap_bh;
++	struct buffer_head *bitmap_bh = NULL;
+ 	struct inode *inode = NULL;
+-	long err = -EIO;
++	int err = -EFSCORRUPTED;
+ 
+-	/* Error cases - e2fsck has already cleaned up for us */
+-	if (ino > max_ino) {
+-		ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
+-		err = -EFSCORRUPTED;
+-		goto error;
+-	}
++	if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
++		goto bad_orphan;
+ 
+ 	block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
+ 	bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
+ 	bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
+ 	if (IS_ERR(bitmap_bh)) {
+-		err = PTR_ERR(bitmap_bh);
+-		ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
+-			     ino, err);
+-		goto error;
++		ext4_error(sb, "inode bitmap error %ld for orphan %lu",
++			   ino, PTR_ERR(bitmap_bh));
++		return (struct inode *) bitmap_bh;
+ 	}
+ 
+ 	/* Having the inode bit set should be a 100% indicator that this
+@@ -1179,15 +1174,21 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
+ 		goto bad_orphan;
+ 
+ 	inode = ext4_iget(sb, ino);
+-	if (IS_ERR(inode))
+-		goto iget_failed;
++	if (IS_ERR(inode)) {
++		err = PTR_ERR(inode);
++		ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
++			   ino, err);
++		return inode;
++	}
+ 
+ 	/*
+-	 * If the orphans has i_nlinks > 0 then it should be able to be
+-	 * truncated, otherwise it won't be removed from the orphan list
+-	 * during processing and an infinite loop will result.
++	 * If the orphans has i_nlinks > 0 then it should be able to
++	 * be truncated, otherwise it won't be removed from the orphan
++	 * list during processing and an infinite loop will result.
++	 * Similarly, it must not be a bad inode.
+ 	 */
+-	if (inode->i_nlink && !ext4_can_truncate(inode))
++	if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
++	    is_bad_inode(inode))
+ 		goto bad_orphan;
+ 
+ 	if (NEXT_ORPHAN(inode) > max_ino)
+@@ -1195,29 +1196,25 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
+ 	brelse(bitmap_bh);
+ 	return inode;
+ 
+-iget_failed:
+-	err = PTR_ERR(inode);
+-	inode = NULL;
+ bad_orphan:
+-	ext4_warning(sb, "bad orphan inode %lu!  e2fsck was run?", ino);
+-	printk(KERN_WARNING "ext4_test_bit(bit=%d, block=%llu) = %d\n",
+-	       bit, (unsigned long long)bitmap_bh->b_blocknr,
+-	       ext4_test_bit(bit, bitmap_bh->b_data));
+-	printk(KERN_WARNING "inode=%p\n", inode);
++	ext4_error(sb, "bad orphan inode %lu", ino);
++	if (bitmap_bh)
++		printk(KERN_ERR "ext4_test_bit(bit=%d, block=%llu) = %d\n",
++		       bit, (unsigned long long)bitmap_bh->b_blocknr,
++		       ext4_test_bit(bit, bitmap_bh->b_data));
+ 	if (inode) {
+-		printk(KERN_WARNING "is_bad_inode(inode)=%d\n",
++		printk(KERN_ERR "is_bad_inode(inode)=%d\n",
+ 		       is_bad_inode(inode));
+-		printk(KERN_WARNING "NEXT_ORPHAN(inode)=%u\n",
++		printk(KERN_ERR "NEXT_ORPHAN(inode)=%u\n",
+ 		       NEXT_ORPHAN(inode));
+-		printk(KERN_WARNING "max_ino=%lu\n", max_ino);
+-		printk(KERN_WARNING "i_nlink=%u\n", inode->i_nlink);
++		printk(KERN_ERR "max_ino=%lu\n", max_ino);
++		printk(KERN_ERR "i_nlink=%u\n", inode->i_nlink);
+ 		/* Avoid freeing blocks if we got a bad deleted inode */
+ 		if (inode->i_nlink == 0)
+ 			inode->i_blocks = 0;
+ 		iput(inode);
+ 	}
+ 	brelse(bitmap_bh);
+-error:
+ 	return ERR_PTR(err);
+ }
+ 
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 981a1fc30eaa..250c2df04a92 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -684,6 +684,21 @@ out_sem:
+ 		ret = check_block_validity(inode, map);
+ 		if (ret != 0)
+ 			return ret;
++
++		/*
++		 * Inodes with freshly allocated blocks where contents will be
++		 * visible after transaction commit must be on transaction's
++		 * ordered data list.
++		 */
++		if (map->m_flags & EXT4_MAP_NEW &&
++		    !(map->m_flags & EXT4_MAP_UNWRITTEN) &&
++		    !(flags & EXT4_GET_BLOCKS_ZERO) &&
++		    !IS_NOQUOTA(inode) &&
++		    ext4_should_order_data(inode)) {
++			ret = ext4_jbd2_file_inode(handle, inode);
++			if (ret)
++				return ret;
++		}
+ 	}
+ 	return retval;
+ }
+@@ -1289,15 +1304,6 @@ static int ext4_write_end(struct file *file,
+ 	int i_size_changed = 0;
+ 
+ 	trace_ext4_write_end(inode, pos, len, copied);
+-	if (ext4_test_inode_state(inode, EXT4_STATE_ORDERED_MODE)) {
+-		ret = ext4_jbd2_file_inode(handle, inode);
+-		if (ret) {
+-			unlock_page(page);
+-			put_page(page);
+-			goto errout;
+-		}
+-	}
+-
+ 	if (ext4_has_inline_data(inode)) {
+ 		ret = ext4_write_inline_data_end(inode, pos, len,
+ 						 copied, page);
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
+index eae5917c534e..0acf8cacb2be 100644
+--- a/fs/ext4/ioctl.c
++++ b/fs/ext4/ioctl.c
+@@ -365,7 +365,7 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid)
+ 		struct dquot *transfer_to[MAXQUOTAS] = { };
+ 
+ 		transfer_to[PRJQUOTA] = dqget(sb, make_kqid_projid(kprojid));
+-		if (transfer_to[PRJQUOTA]) {
++		if (!IS_ERR(transfer_to[PRJQUOTA])) {
+ 			err = __dquot_transfer(inode, transfer_to);
+ 			dqput(transfer_to[PRJQUOTA]);
+ 			if (err)
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index eeeade76012e..9d26fa2188f6 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -1266,6 +1266,7 @@ static void ext4_mb_unload_buddy(struct ext4_buddy *e4b)
+ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
+ {
+ 	int order = 1;
++	int bb_incr = 1 << (e4b->bd_blkbits - 1);
+ 	void *bb;
+ 
+ 	BUG_ON(e4b->bd_bitmap == e4b->bd_buddy);
+@@ -1278,7 +1279,8 @@ static int mb_find_order_for_block(struct ext4_buddy *e4b, int block)
+ 			/* this block is part of buddy of order 'order' */
+ 			return order;
+ 		}
+-		bb += 1 << (e4b->bd_blkbits - order);
++		bb += bb_incr;
++		bb_incr >>= 1;
+ 		order++;
+ 	}
+ 	return 0;
+@@ -2583,7 +2585,7 @@ int ext4_mb_init(struct super_block *sb)
+ {
+ 	struct ext4_sb_info *sbi = EXT4_SB(sb);
+ 	unsigned i, j;
+-	unsigned offset;
++	unsigned offset, offset_incr;
+ 	unsigned max;
+ 	int ret;
+ 
+@@ -2612,11 +2614,13 @@ int ext4_mb_init(struct super_block *sb)
+ 
+ 	i = 1;
+ 	offset = 0;
++	offset_incr = 1 << (sb->s_blocksize_bits - 1);
+ 	max = sb->s_blocksize << 2;
+ 	do {
+ 		sbi->s_mb_offsets[i] = offset;
+ 		sbi->s_mb_maxs[i] = max;
+-		offset += 1 << (sb->s_blocksize_bits - i);
++		offset += offset_incr;
++		offset_incr = offset_incr >> 1;
+ 		max = max >> 1;
+ 		i++;
+ 	} while (i <= sb->s_blocksize_bits + 1);
+diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
+index 48e4b8907826..fdd151f91522 100644
+--- a/fs/ext4/namei.c
++++ b/fs/ext4/namei.c
+@@ -2828,7 +2828,7 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode)
+ 			 * list entries can cause panics at unmount time.
+ 			 */
+ 			mutex_lock(&sbi->s_orphan_lock);
+-			list_del(&EXT4_I(inode)->i_orphan);
++			list_del_init(&EXT4_I(inode)->i_orphan);
+ 			mutex_unlock(&sbi->s_orphan_lock);
+ 		}
+ 	}
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
+index 5dafb9cef12e..1ca31c8e27ed 100644
+--- a/fs/f2fs/data.c
++++ b/fs/f2fs/data.c
+@@ -1480,7 +1480,8 @@ restart:
+ 		if (pos + len <= MAX_INLINE_DATA) {
+ 			read_inline_data(page, ipage);
+ 			set_inode_flag(F2FS_I(inode), FI_DATA_EXIST);
+-			set_inline_node(ipage);
++			if (inode->i_nlink)
++				set_inline_node(ipage);
+ 		} else {
+ 			err = f2fs_convert_inline_page(&dn, page);
+ 			if (err)
+diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
+index 4aaed890048f..776dccbc306d 100644
+--- a/fs/nfs/pnfs_nfs.c
++++ b/fs/nfs/pnfs_nfs.c
+@@ -246,6 +246,23 @@ void pnfs_fetch_commit_bucket_list(struct list_head *pages,
+ 
+ }
+ 
++/* Helper function for pnfs_generic_commit_pagelist to catch an empty
++ * page list. This can happen when two commits race. */
++static bool
++pnfs_generic_commit_cancel_empty_pagelist(struct list_head *pages,
++					  struct nfs_commit_data *data,
++					  struct nfs_commit_info *cinfo)
++{
++	if (list_empty(pages)) {
++		if (atomic_dec_and_test(&cinfo->mds->rpcs_out))
++			wake_up_atomic_t(&cinfo->mds->rpcs_out);
++		nfs_commitdata_release(data);
++		return true;
++	}
++
++	return false;
++}
++
+ /* This follows nfs_commit_list pretty closely */
+ int
+ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
+@@ -280,6 +297,11 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
+ 	list_for_each_entry_safe(data, tmp, &list, pages) {
+ 		list_del_init(&data->pages);
+ 		if (data->ds_commit_index < 0) {
++			/* another commit raced with us */
++			if (pnfs_generic_commit_cancel_empty_pagelist(mds_pages,
++				data, cinfo))
++				continue;
++
+ 			nfs_init_commit(data, mds_pages, NULL, cinfo);
+ 			nfs_initiate_commit(NFS_CLIENT(inode), data,
+ 					    NFS_PROTO(data->inode),
+@@ -288,6 +310,12 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
+ 			LIST_HEAD(pages);
+ 
+ 			pnfs_fetch_commit_bucket_list(&pages, data, cinfo);
++
++			/* another commit raced with us */
++			if (pnfs_generic_commit_cancel_empty_pagelist(&pages,
++				data, cinfo))
++				continue;
++
+ 			nfs_init_commit(data, &pages, data->lseg, cinfo);
+ 			initiate_commit(data, how);
+ 		}
+diff --git a/fs/nfs/write.c b/fs/nfs/write.c
+index 5f4fd53e5764..f5e613395fc2 100644
+--- a/fs/nfs/write.c
++++ b/fs/nfs/write.c
+@@ -1709,6 +1709,10 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
+ {
+ 	struct nfs_commit_data	*data;
+ 
++	/* another commit raced with us */
++	if (list_empty(head))
++		return 0;
++
+ 	data = nfs_commitdata_alloc();
+ 
+ 	if (!data)
+diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
+index ee3aaa0a5317..ca0d3eb44925 100644
+--- a/fs/xfs/xfs_fsops.c
++++ b/fs/xfs/xfs_fsops.c
+@@ -243,8 +243,8 @@ xfs_growfs_data_private(
+ 		agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
+ 		agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
+ 		agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
+-		agf->agf_flfirst = 0;
+-		agf->agf_fllast = cpu_to_be32(XFS_AGFL_SIZE(mp) - 1);
++		agf->agf_flfirst = cpu_to_be32(1);
++		agf->agf_fllast = 0;
+ 		agf->agf_flcount = 0;
+ 		tmpsize = agsize - XFS_PREALLOC_BLOCKS(mp);
+ 		agf->agf_freeblks = cpu_to_be32(tmpsize);
+diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
+index 96f606deee31..3cbc9031731b 100644
+--- a/fs/xfs/xfs_inode.c
++++ b/fs/xfs/xfs_inode.c
+@@ -3205,13 +3205,14 @@ xfs_iflush_cluster(
+ 		 * We need to check under the i_flags_lock for a valid inode
+ 		 * here. Skip it if it is not valid or the wrong inode.
+ 		 */
+-		spin_lock(&ip->i_flags_lock);
+-		if (!ip->i_ino ||
++		spin_lock(&iq->i_flags_lock);
++		if (!iq->i_ino ||
++		    __xfs_iflags_test(iq, XFS_ISTALE) ||
+ 		    (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) {
+-			spin_unlock(&ip->i_flags_lock);
++			spin_unlock(&iq->i_flags_lock);
+ 			continue;
+ 		}
+-		spin_unlock(&ip->i_flags_lock);
++		spin_unlock(&iq->i_flags_lock);
+ 
+ 		/*
+ 		 * Do an un-protected check to see if the inode is dirty and
+@@ -3327,7 +3328,7 @@ xfs_iflush(
+ 	struct xfs_buf		**bpp)
+ {
+ 	struct xfs_mount	*mp = ip->i_mount;
+-	struct xfs_buf		*bp;
++	struct xfs_buf		*bp = NULL;
+ 	struct xfs_dinode	*dip;
+ 	int			error;
+ 
+@@ -3369,14 +3370,22 @@ xfs_iflush(
+ 	}
+ 
+ 	/*
+-	 * Get the buffer containing the on-disk inode.
++	 * Get the buffer containing the on-disk inode. We are doing a try-lock
++	 * operation here, so we may get  an EAGAIN error. In that case, we
++	 * simply want to return with the inode still dirty.
++	 *
++	 * If we get any other error, we effectively have a corruption situation
++	 * and we cannot flush the inode, so we treat it the same as failing
++	 * xfs_iflush_int().
+ 	 */
+ 	error = xfs_imap_to_bp(mp, NULL, &ip->i_imap, &dip, &bp, XBF_TRYLOCK,
+ 			       0);
+-	if (error || !bp) {
++	if (error == -EAGAIN) {
+ 		xfs_ifunlock(ip);
+ 		return error;
+ 	}
++	if (error)
++		goto corrupt_out;
+ 
+ 	/*
+ 	 * First flush out the inode that xfs_iflush was called with.
+@@ -3404,7 +3413,8 @@ xfs_iflush(
+ 	return 0;
+ 
+ corrupt_out:
+-	xfs_buf_relse(bp);
++	if (bp)
++		xfs_buf_relse(bp);
+ 	xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
+ cluster_corrupt_out:
+ 	error = -EFSCORRUPTED;
+diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
+index 187e14b696c2..cedf601ca0fe 100644
+--- a/fs/xfs/xfs_super.c
++++ b/fs/xfs/xfs_super.c
+@@ -928,7 +928,7 @@ xfs_fs_alloc_inode(
+ 
+ /*
+  * Now that the generic code is guaranteed not to be accessing
+- * the linux inode, we can reclaim the inode.
++ * the linux inode, we can inactivate and reclaim the inode.
+  */
+ STATIC void
+ xfs_fs_destroy_inode(
+@@ -938,9 +938,14 @@ xfs_fs_destroy_inode(
+ 
+ 	trace_xfs_destroy_inode(ip);
+ 
+-	XFS_STATS_INC(ip->i_mount, vn_reclaim);
++	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
++	XFS_STATS_INC(ip->i_mount, vn_rele);
++	XFS_STATS_INC(ip->i_mount, vn_remove);
++
++	xfs_inactive(ip);
+ 
+ 	ASSERT(XFS_FORCED_SHUTDOWN(ip->i_mount) || ip->i_delayed_blks == 0);
++	XFS_STATS_INC(ip->i_mount, vn_reclaim);
+ 
+ 	/*
+ 	 * We should never get here with one of the reclaim flags already set.
+@@ -987,24 +992,6 @@ xfs_fs_inode_init_once(
+ 		     "xfsino", ip->i_ino);
+ }
+ 
+-STATIC void
+-xfs_fs_evict_inode(
+-	struct inode		*inode)
+-{
+-	xfs_inode_t		*ip = XFS_I(inode);
+-
+-	ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock));
+-
+-	trace_xfs_evict_inode(ip);
+-
+-	truncate_inode_pages_final(&inode->i_data);
+-	clear_inode(inode);
+-	XFS_STATS_INC(ip->i_mount, vn_rele);
+-	XFS_STATS_INC(ip->i_mount, vn_remove);
+-
+-	xfs_inactive(ip);
+-}
+-
+ /*
+  * We do an unlocked check for XFS_IDONTCACHE here because we are already
+  * serialised against cache hits here via the inode->i_lock and igrab() in
+@@ -1276,6 +1263,16 @@ xfs_fs_remount(
+ 			return -EINVAL;
+ 		}
+ 
++		if (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
++		    xfs_sb_has_ro_compat_feature(sbp,
++					XFS_SB_FEAT_RO_COMPAT_UNKNOWN)) {
++			xfs_warn(mp,
++"ro->rw transition prohibited on unknown (0x%x) ro-compat filesystem",
++				(sbp->sb_features_ro_compat &
++					XFS_SB_FEAT_RO_COMPAT_UNKNOWN));
++			return -EINVAL;
++		}
++
+ 		mp->m_flags &= ~XFS_MOUNT_RDONLY;
+ 
+ 		/*
+@@ -1663,7 +1660,6 @@ xfs_fs_free_cached_objects(
+ static const struct super_operations xfs_super_operations = {
+ 	.alloc_inode		= xfs_fs_alloc_inode,
+ 	.destroy_inode		= xfs_fs_destroy_inode,
+-	.evict_inode		= xfs_fs_evict_inode,
+ 	.drop_inode		= xfs_fs_drop_inode,
+ 	.put_super		= xfs_fs_put_super,
+ 	.sync_fs		= xfs_fs_sync_fs,
+diff --git a/include/drm/drm_dp_dual_mode_helper.h b/include/drm/drm_dp_dual_mode_helper.h
+new file mode 100644
+index 000000000000..e8a9dfd0e055
+--- /dev/null
++++ b/include/drm/drm_dp_dual_mode_helper.h
+@@ -0,0 +1,92 @@
++/*
++ * Copyright © 2016 Intel Corporation
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++#ifndef DRM_DP_DUAL_MODE_HELPER_H
++#define DRM_DP_DUAL_MODE_HELPER_H
++
++#include <linux/types.h>
++
++/*
++ * Optional for type 1 DVI adaptors
++ * Mandatory for type 1 HDMI and type 2 adaptors
++ */
++#define DP_DUAL_MODE_HDMI_ID 0x00 /* 00-0f */
++#define  DP_DUAL_MODE_HDMI_ID_LEN 16
++/*
++ * Optional for type 1 adaptors
++ * Mandatory for type 2 adaptors
++ */
++#define DP_DUAL_MODE_ADAPTOR_ID 0x10
++#define  DP_DUAL_MODE_REV_MASK 0x07
++#define  DP_DUAL_MODE_REV_TYPE2 0x00
++#define  DP_DUAL_MODE_TYPE_MASK 0xf0
++#define  DP_DUAL_MODE_TYPE_TYPE2 0xa0
++#define DP_DUAL_MODE_IEEE_OUI 0x11 /* 11-13*/
++#define  DP_DUAL_IEEE_OUI_LEN 3
++#define DP_DUAL_DEVICE_ID 0x14 /* 14-19 */
++#define  DP_DUAL_DEVICE_ID_LEN 6
++#define DP_DUAL_MODE_HARDWARE_REV 0x1a
++#define DP_DUAL_MODE_FIRMWARE_MAJOR_REV 0x1b
++#define DP_DUAL_MODE_FIRMWARE_MINOR_REV 0x1c
++#define DP_DUAL_MODE_MAX_TMDS_CLOCK 0x1d
++#define DP_DUAL_MODE_I2C_SPEED_CAP 0x1e
++#define DP_DUAL_MODE_TMDS_OEN 0x20
++#define  DP_DUAL_MODE_TMDS_DISABLE 0x01
++#define DP_DUAL_MODE_HDMI_PIN_CTRL 0x21
++#define  DP_DUAL_MODE_CEC_ENABLE 0x01
++#define DP_DUAL_MODE_I2C_SPEED_CTRL 0x22
++
++struct i2c_adapter;
++
++ssize_t drm_dp_dual_mode_read(struct i2c_adapter *adapter,
++			      u8 offset, void *buffer, size_t size);
++ssize_t drm_dp_dual_mode_write(struct i2c_adapter *adapter,
++			       u8 offset, const void *buffer, size_t size);
++
++/**
++ * enum drm_dp_dual_mode_type - Type of the DP dual mode adaptor
++ * @DRM_DP_DUAL_MODE_NONE: No DP dual mode adaptor
++ * @DRM_DP_DUAL_MODE_UNKNOWN: Could be either none or type 1 DVI adaptor
++ * @DRM_DP_DUAL_MODE_TYPE1_DVI: Type 1 DVI adaptor
++ * @DRM_DP_DUAL_MODE_TYPE1_HDMI: Type 1 HDMI adaptor
++ * @DRM_DP_DUAL_MODE_TYPE2_DVI: Type 2 DVI adaptor
++ * @DRM_DP_DUAL_MODE_TYPE2_HDMI: Type 2 HDMI adaptor
++ */
++enum drm_dp_dual_mode_type {
++	DRM_DP_DUAL_MODE_NONE,
++	DRM_DP_DUAL_MODE_UNKNOWN,
++	DRM_DP_DUAL_MODE_TYPE1_DVI,
++	DRM_DP_DUAL_MODE_TYPE1_HDMI,
++	DRM_DP_DUAL_MODE_TYPE2_DVI,
++	DRM_DP_DUAL_MODE_TYPE2_HDMI,
++};
++
++enum drm_dp_dual_mode_type drm_dp_dual_mode_detect(struct i2c_adapter *adapter);
++int drm_dp_dual_mode_max_tmds_clock(enum drm_dp_dual_mode_type type,
++				    struct i2c_adapter *adapter);
++int drm_dp_dual_mode_get_tmds_output(enum drm_dp_dual_mode_type type,
++				     struct i2c_adapter *adapter, bool *enabled);
++int drm_dp_dual_mode_set_tmds_output(enum drm_dp_dual_mode_type type,
++				     struct i2c_adapter *adapter, bool enable);
++const char *drm_dp_get_dual_mode_type_name(enum drm_dp_dual_mode_type type);
++
++#endif
+diff --git a/include/linux/mm.h b/include/linux/mm.h
+index 8f468e0d2534..02f7f31e540f 100644
+--- a/include/linux/mm.h
++++ b/include/linux/mm.h
+@@ -1782,7 +1782,7 @@ extern void free_highmem_page(struct page *page);
+ extern void adjust_managed_page_count(struct page *page, long count);
+ extern void mem_init_print_info(const char *str);
+ 
+-extern void reserve_bootmem_region(unsigned long start, unsigned long end);
++extern void reserve_bootmem_region(phys_addr_t start, phys_addr_t end);
+ 
+ /* Free the reserved page into the buddy system, so it gets managed. */
+ static inline void __free_reserved_page(struct page *page)
+diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h
+index ad66589f2ae6..3a2a79401789 100644
+--- a/include/video/imx-ipu-v3.h
++++ b/include/video/imx-ipu-v3.h
+@@ -16,6 +16,7 @@
+ #include <linux/videodev2.h>
+ #include <linux/bitmap.h>
+ #include <linux/fb.h>
++#include <linux/of.h>
+ #include <media/v4l2-mediabus.h>
+ #include <video/videomode.h>
+ 
+@@ -345,6 +346,7 @@ struct ipu_client_platformdata {
+ 	int dc;
+ 	int dp;
+ 	int dma[2];
++	struct device_node *of_node;
+ };
+ 
+ #endif /* __DRM_IPU_H__ */
+diff --git a/kernel/exit.c b/kernel/exit.c
+index fd90195667e1..79c7e38a203b 100644
+--- a/kernel/exit.c
++++ b/kernel/exit.c
+@@ -918,17 +918,28 @@ static int eligible_pid(struct wait_opts *wo, struct task_struct *p)
+ 		task_pid_type(p, wo->wo_type) == wo->wo_pid;
+ }
+ 
+-static int eligible_child(struct wait_opts *wo, struct task_struct *p)
++static int
++eligible_child(struct wait_opts *wo, bool ptrace, struct task_struct *p)
+ {
+ 	if (!eligible_pid(wo, p))
+ 		return 0;
+-	/* Wait for all children (clone and not) if __WALL is set;
+-	 * otherwise, wait for clone children *only* if __WCLONE is
+-	 * set; otherwise, wait for non-clone children *only*.  (Note:
+-	 * A "clone" child here is one that reports to its parent
+-	 * using a signal other than SIGCHLD.) */
+-	if (((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE))
+-	    && !(wo->wo_flags & __WALL))
++
++	/*
++	 * Wait for all children (clone and not) if __WALL is set or
++	 * if it is traced by us.
++	 */
++	if (ptrace || (wo->wo_flags & __WALL))
++		return 1;
++
++	/*
++	 * Otherwise, wait for clone children *only* if __WCLONE is set;
++	 * otherwise, wait for non-clone children *only*.
++	 *
++	 * Note: a "clone" child here is one that reports to its parent
++	 * using a signal other than SIGCHLD, or a non-leader thread which
++	 * we can only see if it is traced by us.
++	 */
++	if ((p->exit_signal != SIGCHLD) ^ !!(wo->wo_flags & __WCLONE))
+ 		return 0;
+ 
+ 	return 1;
+@@ -1300,7 +1311,7 @@ static int wait_consider_task(struct wait_opts *wo, int ptrace,
+ 	if (unlikely(exit_state == EXIT_DEAD))
+ 		return 0;
+ 
+-	ret = eligible_child(wo, p);
++	ret = eligible_child(wo, ptrace, p);
+ 	if (!ret)
+ 		return ret;
+ 
+diff --git a/lib/dma-debug.c b/lib/dma-debug.c
+index 4a1515f4b452..51a76af25c66 100644
+--- a/lib/dma-debug.c
++++ b/lib/dma-debug.c
+@@ -657,9 +657,9 @@ static struct dma_debug_entry *dma_entry_alloc(void)
+ 	spin_lock_irqsave(&free_entries_lock, flags);
+ 
+ 	if (list_empty(&free_entries)) {
+-		pr_err("DMA-API: debugging out of memory - disabling\n");
+ 		global_disable = true;
+ 		spin_unlock_irqrestore(&free_entries_lock, flags);
++		pr_err("DMA-API: debugging out of memory - disabling\n");
+ 		return NULL;
+ 	}
+ 
+diff --git a/mm/compaction.c b/mm/compaction.c
+index 8fa254043801..f8e925eb479b 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -1742,7 +1742,7 @@ static bool kcompactd_node_suitable(pg_data_t *pgdat)
+ 	struct zone *zone;
+ 	enum zone_type classzone_idx = pgdat->kcompactd_classzone_idx;
+ 
+-	for (zoneid = 0; zoneid < classzone_idx; zoneid++) {
++	for (zoneid = 0; zoneid <= classzone_idx; zoneid++) {
+ 		zone = &pgdat->node_zones[zoneid];
+ 
+ 		if (!populated_zone(zone))
+@@ -1777,7 +1777,7 @@ static void kcompactd_do_work(pg_data_t *pgdat)
+ 							cc.classzone_idx);
+ 	count_vm_event(KCOMPACTD_WAKE);
+ 
+-	for (zoneid = 0; zoneid < cc.classzone_idx; zoneid++) {
++	for (zoneid = 0; zoneid <= cc.classzone_idx; zoneid++) {
+ 		int status;
+ 
+ 		zone = &pgdat->node_zones[zoneid];
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index c1069efcc4d7..898fe3f909f9 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -1003,7 +1003,7 @@ static inline void init_reserved_page(unsigned long pfn)
+  * marks the pages PageReserved. The remaining valid pages are later
+  * sent to the buddy page allocator.
+  */
+-void __meminit reserve_bootmem_region(unsigned long start, unsigned long end)
++void __meminit reserve_bootmem_region(phys_addr_t start, phys_addr_t end)
+ {
+ 	unsigned long start_pfn = PFN_DOWN(start);
+ 	unsigned long end_pfn = PFN_UP(end);
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 307b555024ef..3ebf9c4c2f4d 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -1098,6 +1098,8 @@ void page_move_anon_rmap(struct page *page,
+ 
+ 	VM_BUG_ON_PAGE(!PageLocked(page), page);
+ 	VM_BUG_ON_VMA(!anon_vma, vma);
++	if (IS_ENABLED(CONFIG_DEBUG_VM) && PageTransHuge(page))
++		address &= HPAGE_PMD_MASK;
+ 	VM_BUG_ON_PAGE(page->index != linear_page_index(vma, address), page);
+ 
+ 	anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
+diff --git a/net/batman-adv/bat_v_ogm.c b/net/batman-adv/bat_v_ogm.c
+index d9bcbe6e7d65..91df28a100f9 100644
+--- a/net/batman-adv/bat_v_ogm.c
++++ b/net/batman-adv/bat_v_ogm.c
+@@ -529,8 +529,10 @@ static void batadv_v_ogm_route_update(struct batadv_priv *bat_priv,
+ 		goto out;
+ 	}
+ 
+-	if (router)
++	if (router) {
+ 		batadv_neigh_node_put(router);
++		router = NULL;
++	}
+ 
+ 	/* Update routes, and check if the OGM is from the best next hop */
+ 	batadv_v_ogm_orig_update(bat_priv, orig_node, neigh_node, ogm2,
+diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
+index 8a4cc2f7f0db..e45cb9155039 100644
+--- a/net/bluetooth/6lowpan.c
++++ b/net/bluetooth/6lowpan.c
+@@ -431,15 +431,18 @@ static int setup_header(struct sk_buff *skb, struct net_device *netdev,
+ 			bdaddr_t *peer_addr, u8 *peer_addr_type)
+ {
+ 	struct in6_addr ipv6_daddr;
++	struct ipv6hdr *hdr;
+ 	struct lowpan_dev *dev;
+ 	struct lowpan_peer *peer;
+ 	bdaddr_t addr, *any = BDADDR_ANY;
+ 	u8 *daddr = any->b;
+ 	int err, status = 0;
+ 
++	hdr = ipv6_hdr(skb);
++
+ 	dev = lowpan_dev(netdev);
+ 
+-	memcpy(&ipv6_daddr, &lowpan_cb(skb)->addr, sizeof(ipv6_daddr));
++	memcpy(&ipv6_daddr, &hdr->daddr, sizeof(ipv6_daddr));
+ 
+ 	if (ipv6_addr_is_multicast(&ipv6_daddr)) {
+ 		lowpan_cb(skb)->chan = NULL;
+@@ -489,15 +492,9 @@ static int header_create(struct sk_buff *skb, struct net_device *netdev,
+ 			 unsigned short type, const void *_daddr,
+ 			 const void *_saddr, unsigned int len)
+ {
+-	struct ipv6hdr *hdr;
+-
+ 	if (type != ETH_P_IPV6)
+ 		return -EINVAL;
+ 
+-	hdr = ipv6_hdr(skb);
+-
+-	memcpy(&lowpan_cb(skb)->addr, &hdr->daddr, sizeof(struct in6_addr));
+-
+ 	return 0;
+ }
+ 
+diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
+index 1095be9c80ab..4605dc73def6 100644
+--- a/net/sunrpc/auth_gss/svcauth_gss.c
++++ b/net/sunrpc/auth_gss/svcauth_gss.c
+@@ -857,8 +857,8 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g
+ 		goto out;
+ 	if (svc_getnl(&buf->head[0]) != seq)
+ 		goto out;
+-	/* trim off the mic at the end before returning */
+-	xdr_buf_trim(buf, mic.len + 4);
++	/* trim off the mic and padding at the end before returning */
++	xdr_buf_trim(buf, round_up_to_quad(mic.len) + 4);
+ 	stat = 0;
+ out:
+ 	kfree(mic.data);
+diff --git a/scripts/package/Makefile b/scripts/package/Makefile
+index c2c7389bfbab..71b4a8af9d4d 100644
+--- a/scripts/package/Makefile
++++ b/scripts/package/Makefile
+@@ -52,7 +52,7 @@ rpm-pkg rpm: FORCE
+ 	$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
+ 	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
+ 	mv -f $(objtree)/.tmp_version $(objtree)/.version
+-	rpmbuild --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
++	rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
+ 	rm $(KERNELPATH).tar.gz kernel.spec
+ 
+ # binrpm-pkg
+@@ -63,7 +63,7 @@ binrpm-pkg: FORCE
+ 	$(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version
+ 	mv -f $(objtree)/.tmp_version $(objtree)/.version
+ 
+-	rpmbuild --define "_builddir $(objtree)" --target \
++	rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
+ 		$(UTS_MACHINE) -bb $(objtree)/binkernel.spec
+ 	rm binkernel.spec
+ 
+diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c
+index cda27c22812a..eb8fe212e163 100644
+--- a/sound/soc/codecs/ak4642.c
++++ b/sound/soc/codecs/ak4642.c
+@@ -560,6 +560,7 @@ static const struct regmap_config ak4642_regmap = {
+ 	.max_register		= FIL1_3,
+ 	.reg_defaults		= ak4642_reg,
+ 	.num_reg_defaults	= NUM_AK4642_REG_DEFAULTS,
++	.cache_type		= REGCACHE_RBTREE,
+ };
+ 
+ static const struct regmap_config ak4643_regmap = {
+@@ -568,6 +569,7 @@ static const struct regmap_config ak4643_regmap = {
+ 	.max_register		= SPK_MS,
+ 	.reg_defaults		= ak4643_reg,
+ 	.num_reg_defaults	= ARRAY_SIZE(ak4643_reg),
++	.cache_type		= REGCACHE_RBTREE,
+ };
+ 
+ static const struct regmap_config ak4648_regmap = {
+@@ -576,6 +578,7 @@ static const struct regmap_config ak4648_regmap = {
+ 	.max_register		= EQ_FBEQE,
+ 	.reg_defaults		= ak4648_reg,
+ 	.num_reg_defaults	= ARRAY_SIZE(ak4648_reg),
++	.cache_type		= REGCACHE_RBTREE,
+ };
+ 
+ static const struct ak4642_drvdata ak4642_drvdata = {


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

* [gentoo-commits] proj/linux-patches:4.6 commit in: /
@ 2016-06-24 20:41 Mike Pagano
  0 siblings, 0 replies; 12+ messages in thread
From: Mike Pagano @ 2016-06-24 20:41 UTC (permalink / raw
  To: gentoo-commits

commit:     a36656eef665f797c9827b7866e5c9894656770c
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Jun 24 20:41:39 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Jun 24 20:41:39 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=a36656ee

Linux patch 4.6.3

 0000_README            |    4 +
 1002_linux-4.6.3.patch | 4713 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 4717 insertions(+)

diff --git a/0000_README b/0000_README
index 61071b1..8feba45 100644
--- a/0000_README
+++ b/0000_README
@@ -51,6 +51,10 @@ Patch:  1001_linux-4.6.2.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.2
 
+Patch:  1002_linux-4.6.3.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.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.6.3.patch b/1002_linux-4.6.3.patch
new file mode 100644
index 0000000..e81ef72
--- /dev/null
+++ b/1002_linux-4.6.3.patch
@@ -0,0 +1,4713 @@
+diff --git a/Makefile b/Makefile
+index 93068c2d0656..c62b531d5a85 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 2
++SUBLEVEL = 3
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
+index ef9119f7462e..4d9375814b53 100644
+--- a/arch/arm/kernel/ptrace.c
++++ b/arch/arm/kernel/ptrace.c
+@@ -733,8 +733,8 @@ static int vfp_set(struct task_struct *target,
+ 	if (ret)
+ 		return ret;
+ 
+-	vfp_flush_hwstate(thread);
+ 	thread->vfpstate.hard = new_vfp;
++	vfp_flush_hwstate(thread);
+ 
+ 	return 0;
+ }
+diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
+index 24ed037f09fd..83d48a599f69 100644
+--- a/arch/arm64/include/asm/elf.h
++++ b/arch/arm64/include/asm/elf.h
+@@ -160,14 +160,14 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
+ #define STACK_RND_MASK			(0x3ffff >> (PAGE_SHIFT - 12))
+ #endif
+ 
+-#ifdef CONFIG_COMPAT
+-
+ #ifdef __AARCH64EB__
+ #define COMPAT_ELF_PLATFORM		("v8b")
+ #else
+ #define COMPAT_ELF_PLATFORM		("v8l")
+ #endif
+ 
++#ifdef CONFIG_COMPAT
++
+ #define COMPAT_ELF_ET_DYN_BASE		(2 * TASK_SIZE_32 / 3)
+ 
+ /* AArch32 registers. */
+diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c
+index f0c3fb7ec8cf..2d2d7cb04a5d 100644
+--- a/arch/arm64/kernel/cpuinfo.c
++++ b/arch/arm64/kernel/cpuinfo.c
+@@ -22,6 +22,8 @@
+ 
+ #include <linux/bitops.h>
+ #include <linux/bug.h>
++#include <linux/compat.h>
++#include <linux/elf.h>
+ #include <linux/init.h>
+ #include <linux/kernel.h>
+ #include <linux/personality.h>
+@@ -104,6 +106,7 @@ static const char *const compat_hwcap2_str[] = {
+ static int c_show(struct seq_file *m, void *v)
+ {
+ 	int i, j;
++	bool compat = personality(current->personality) == PER_LINUX32;
+ 
+ 	for_each_online_cpu(i) {
+ 		struct cpuinfo_arm64 *cpuinfo = &per_cpu(cpu_data, i);
+@@ -115,6 +118,9 @@ static int c_show(struct seq_file *m, void *v)
+ 		 * "processor".  Give glibc what it expects.
+ 		 */
+ 		seq_printf(m, "processor\t: %d\n", i);
++		if (compat)
++			seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n",
++				   MIDR_REVISION(midr), COMPAT_ELF_PLATFORM);
+ 
+ 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
+ 			   loops_per_jiffy / (500000UL/HZ),
+@@ -127,7 +133,7 @@ static int c_show(struct seq_file *m, void *v)
+ 		 * software which does already (at least for 32-bit).
+ 		 */
+ 		seq_puts(m, "Features\t:");
+-		if (personality(current->personality) == PER_LINUX32) {
++		if (compat) {
+ #ifdef CONFIG_COMPAT
+ 			for (j = 0; compat_hwcap_str[j]; j++)
+ 				if (compat_elf_hwcap & (1 << j))
+diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
+index fff7cd42b3a3..3129df9d3a73 100644
+--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
++++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
+@@ -190,12 +190,11 @@ void __hyp_text __vgic_v3_save_state(struct kvm_vcpu *vcpu)
+ 			if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
+ 				continue;
+ 
+-			if (cpu_if->vgic_elrsr & (1 << i)) {
++			if (cpu_if->vgic_elrsr & (1 << i))
+ 				cpu_if->vgic_lr[i] &= ~ICH_LR_STATE;
+-				continue;
+-			}
++			else
++				cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
+ 
+-			cpu_if->vgic_lr[i] = __gic_v3_get_lr(i);
+ 			__gic_v3_set_lr(0, i);
+ 		}
+ 
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index 3ae4a28c4aed..10b79e9e87d1 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -109,7 +109,7 @@ int ptep_set_access_flags(struct vm_area_struct *vma,
+ 	 * PTE_RDONLY is cleared by default in the asm below, so set it in
+ 	 * back if necessary (read-only or clean PTE).
+ 	 */
+-	if (!pte_write(entry) || !dirty)
++	if (!pte_write(entry) || !pte_sw_dirty(entry))
+ 		pte_val(entry) |= PTE_RDONLY;
+ 
+ 	/*
+diff --git a/arch/parisc/kernel/unaligned.c b/arch/parisc/kernel/unaligned.c
+index d7c0acb35ec2..8d49614d600d 100644
+--- a/arch/parisc/kernel/unaligned.c
++++ b/arch/parisc/kernel/unaligned.c
+@@ -666,7 +666,7 @@ void handle_unaligned(struct pt_regs *regs)
+ 		break;
+ 	}
+ 
+-	if (modify && R1(regs->iir))
++	if (ret == 0 && modify && R1(regs->iir))
+ 		regs->gr[R1(regs->iir)] = newbase;
+ 
+ 
+@@ -677,6 +677,14 @@ void handle_unaligned(struct pt_regs *regs)
+ 
+ 	if (ret)
+ 	{
++		/*
++		 * The unaligned handler failed.
++		 * If we were called by __get_user() or __put_user() jump
++		 * to it's exception fixup handler instead of crashing.
++		 */
++		if (!user_mode(regs) && fixup_exception(regs))
++			return;
++
+ 		printk(KERN_CRIT "Unaligned handler failed, ret = %d\n", ret);
+ 		die_if_kernel("Unaligned data reference", regs, 28);
+ 
+diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
+index f5f4c66bbbc9..166d8631747f 100644
+--- a/arch/powerpc/include/asm/reg.h
++++ b/arch/powerpc/include/asm/reg.h
+@@ -715,7 +715,7 @@
+ #define   MMCR0_FCWAIT	0x00000002UL /* freeze counter in WAIT state */
+ #define   MMCR0_FCHV	0x00000001UL /* freeze conditions in hypervisor mode */
+ #define SPRN_MMCR1	798
+-#define SPRN_MMCR2	769
++#define SPRN_MMCR2	785
+ #define SPRN_MMCRA	0x312
+ #define   MMCRA_SDSYNC	0x80000000UL /* SDAR synced with SIAR */
+ #define   MMCRA_SDAR_DCACHE_MISS 0x40000000UL
+@@ -752,13 +752,13 @@
+ #define SPRN_PMC6	792
+ #define SPRN_PMC7	793
+ #define SPRN_PMC8	794
+-#define SPRN_SIAR	780
+-#define SPRN_SDAR	781
+ #define SPRN_SIER	784
+ #define   SIER_SIPR		0x2000000	/* Sampled MSR_PR */
+ #define   SIER_SIHV		0x1000000	/* Sampled MSR_HV */
+ #define   SIER_SIAR_VALID	0x0400000	/* SIAR contents valid */
+ #define   SIER_SDAR_VALID	0x0200000	/* SDAR contents valid */
++#define SPRN_SIAR	796
++#define SPRN_SDAR	797
+ #define SPRN_TACR	888
+ #define SPRN_TCSCR	889
+ #define SPRN_CSIGR	890
+diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
+index da5192590c44..ccd2037c797f 100644
+--- a/arch/powerpc/kernel/prom_init.c
++++ b/arch/powerpc/kernel/prom_init.c
+@@ -656,6 +656,7 @@ unsigned char ibm_architecture_vec[] = {
+ 	W(0xffff0000), W(0x003e0000),	/* POWER6 */
+ 	W(0xffff0000), W(0x003f0000),	/* POWER7 */
+ 	W(0xffff0000), W(0x004b0000),	/* POWER8E */
++	W(0xffff0000), W(0x004c0000),   /* POWER8NVL */
+ 	W(0xffff0000), W(0x004d0000),	/* POWER8 */
+ 	W(0xffffffff), W(0x0f000004),	/* all 2.07-compliant */
+ 	W(0xffffffff), W(0x0f000003),	/* all 2.06-compliant */
+diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
+index 7635b1c6b5da..f4acba25fa5e 100644
+--- a/arch/powerpc/mm/hash_utils_64.c
++++ b/arch/powerpc/mm/hash_utils_64.c
+@@ -159,6 +159,19 @@ static struct mmu_psize_def mmu_psize_defaults_gp[] = {
+ 	},
+ };
+ 
++/*
++ * 'R' and 'C' update notes:
++ *  - Under pHyp or KVM, the updatepp path will not set C, thus it *will*
++ *     create writeable HPTEs without C set, because the hcall H_PROTECT
++ *     that we use in that case will not update C
++ *  - The above is however not a problem, because we also don't do that
++ *     fancy "no flush" variant of eviction and we use H_REMOVE which will
++ *     do the right thing and thus we don't have the race I described earlier
++ *
++ *    - Under bare metal,  we do have the race, so we need R and C set
++ *    - We make sure R is always set and never lost
++ *    - C is _PAGE_DIRTY, and *should* always be set for a writeable mapping
++ */
+ unsigned long htab_convert_pte_flags(unsigned long pteflags)
+ {
+ 	unsigned long rflags = 0;
+@@ -180,9 +193,14 @@ unsigned long htab_convert_pte_flags(unsigned long pteflags)
+ 			rflags |= 0x1;
+ 	}
+ 	/*
+-	 * Always add "C" bit for perf. Memory coherence is always enabled
++	 * We can't allow hardware to update hpte bits. Hence always
++	 * set 'R' bit and set 'C' if it is a write fault
++	 * Memory coherence is always enabled
+ 	 */
+-	rflags |=  HPTE_R_C | HPTE_R_M;
++	rflags |=  HPTE_R_R | HPTE_R_M;
++
++	if (pteflags & _PAGE_DIRTY)
++		rflags |= HPTE_R_C;
+ 	/*
+ 	 * Add in WIG bits
+ 	 */
+diff --git a/arch/powerpc/platforms/pseries/eeh_pseries.c b/arch/powerpc/platforms/pseries/eeh_pseries.c
+index ac3ffd97e059..405baaf96864 100644
+--- a/arch/powerpc/platforms/pseries/eeh_pseries.c
++++ b/arch/powerpc/platforms/pseries/eeh_pseries.c
+@@ -615,29 +615,50 @@ static int pseries_eeh_configure_bridge(struct eeh_pe *pe)
+ {
+ 	int config_addr;
+ 	int ret;
++	/* Waiting 0.2s maximum before skipping configuration */
++	int max_wait = 200;
+ 
+ 	/* Figure out the PE address */
+ 	config_addr = pe->config_addr;
+ 	if (pe->addr)
+ 		config_addr = pe->addr;
+ 
+-	/* Use new configure-pe function, if supported */
+-	if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
+-		ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
+-				config_addr, BUID_HI(pe->phb->buid),
+-				BUID_LO(pe->phb->buid));
+-	} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
+-		ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
+-				config_addr, BUID_HI(pe->phb->buid),
+-				BUID_LO(pe->phb->buid));
+-	} else {
+-		return -EFAULT;
+-	}
++	while (max_wait > 0) {
++		/* Use new configure-pe function, if supported */
++		if (ibm_configure_pe != RTAS_UNKNOWN_SERVICE) {
++			ret = rtas_call(ibm_configure_pe, 3, 1, NULL,
++					config_addr, BUID_HI(pe->phb->buid),
++					BUID_LO(pe->phb->buid));
++		} else if (ibm_configure_bridge != RTAS_UNKNOWN_SERVICE) {
++			ret = rtas_call(ibm_configure_bridge, 3, 1, NULL,
++					config_addr, BUID_HI(pe->phb->buid),
++					BUID_LO(pe->phb->buid));
++		} else {
++			return -EFAULT;
++		}
+ 
+-	if (ret)
+-		pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
+-			__func__, pe->phb->global_number, pe->addr, ret);
++		if (!ret)
++			return ret;
++
++		/*
++		 * If RTAS returns a delay value that's above 100ms, cut it
++		 * down to 100ms in case firmware made a mistake.  For more
++		 * on how these delay values work see rtas_busy_delay_time
++		 */
++		if (ret > RTAS_EXTENDED_DELAY_MIN+2 &&
++		    ret <= RTAS_EXTENDED_DELAY_MAX)
++			ret = RTAS_EXTENDED_DELAY_MIN+2;
++
++		max_wait -= rtas_busy_delay_time(ret);
++
++		if (max_wait < 0)
++			break;
++
++		rtas_busy_delay(ret);
++	}
+ 
++	pr_warn("%s: Unable to configure bridge PHB#%d-PE#%x (%d)\n",
++		__func__, pe->phb->global_number, pe->addr, ret);
+ 	return ret;
+ }
+ 
+diff --git a/arch/s390/net/bpf_jit.h b/arch/s390/net/bpf_jit.h
+index f010c93a88b1..fda605dbc1b4 100644
+--- a/arch/s390/net/bpf_jit.h
++++ b/arch/s390/net/bpf_jit.h
+@@ -37,7 +37,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
+  *	      |		      |     |
+  *	      +---------------+     |
+  *	      | 8 byte skbp   |     |
+- * R15+170 -> +---------------+     |
++ * R15+176 -> +---------------+     |
+  *	      | 8 byte hlen   |     |
+  * R15+168 -> +---------------+     |
+  *	      | 4 byte align  |     |
+@@ -58,7 +58,7 @@ extern u8 sk_load_word[], sk_load_half[], sk_load_byte[];
+ #define STK_OFF		(STK_SPACE - STK_160_UNUSED)
+ #define STK_OFF_TMP	160	/* Offset of tmp buffer on stack */
+ #define STK_OFF_HLEN	168	/* Offset of SKB header length on stack */
+-#define STK_OFF_SKBP	170	/* Offset of SKB pointer on stack */
++#define STK_OFF_SKBP	176	/* Offset of SKB pointer on stack */
+ 
+ #define STK_OFF_R6	(160 - 11 * 8)	/* Offset of r6 on stack */
+ #define STK_OFF_TCCNT	(160 - 12 * 8)	/* Offset of tail_call_cnt on stack */
+diff --git a/arch/s390/net/bpf_jit_comp.c b/arch/s390/net/bpf_jit_comp.c
+index 3c0bfc1f2694..2662fcc67f8d 100644
+--- a/arch/s390/net/bpf_jit_comp.c
++++ b/arch/s390/net/bpf_jit_comp.c
+@@ -45,7 +45,7 @@ struct bpf_jit {
+ 	int labels[1];		/* Labels for local jumps */
+ };
+ 
+-#define BPF_SIZE_MAX	0x7ffff	/* Max size for program (20 bit signed displ) */
++#define BPF_SIZE_MAX	0xffff	/* Max size for program (16 bit branches) */
+ 
+ #define SEEN_SKB	1	/* skb access */
+ #define SEEN_MEM	2	/* use mem[] for temporary storage */
+@@ -446,7 +446,7 @@ static void bpf_jit_prologue(struct bpf_jit *jit)
+ 		emit_load_skb_data_hlen(jit);
+ 	if (jit->seen & SEEN_SKB_CHANGE)
+ 		/* stg %b1,ST_OFF_SKBP(%r0,%r15) */
+-		EMIT6_DISP_LH(0xe3000000, 0x0024, REG_W1, REG_0, REG_15,
++		EMIT6_DISP_LH(0xe3000000, 0x0024, BPF_REG_1, REG_0, REG_15,
+ 			      STK_OFF_SKBP);
+ }
+ 
+diff --git a/arch/sparc/include/asm/head_64.h b/arch/sparc/include/asm/head_64.h
+index 10e9dabc4c41..f0700cfeedd7 100644
+--- a/arch/sparc/include/asm/head_64.h
++++ b/arch/sparc/include/asm/head_64.h
+@@ -15,6 +15,10 @@
+ 
+ #define	PTREGS_OFF	(STACK_BIAS + STACKFRAME_SZ)
+ 
++#define	RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
++#define	RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
++#define RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
++
+ #define __CHEETAH_ID	0x003e0014
+ #define __JALAPENO_ID	0x003e0016
+ #define __SERRANO_ID	0x003e0022
+diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h
+index f089cfa249f3..5a189bf3c8ac 100644
+--- a/arch/sparc/include/asm/pgtable_64.h
++++ b/arch/sparc/include/asm/pgtable_64.h
+@@ -375,7 +375,7 @@ static inline pgprot_t pgprot_noncached(pgprot_t prot)
+ #define pgprot_noncached pgprot_noncached
+ 
+ #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+-static inline pte_t pte_mkhuge(pte_t pte)
++static inline unsigned long __pte_huge_mask(void)
+ {
+ 	unsigned long mask;
+ 
+@@ -390,8 +390,19 @@ static inline pte_t pte_mkhuge(pte_t pte)
+ 	: "=r" (mask)
+ 	: "i" (_PAGE_SZHUGE_4U), "i" (_PAGE_SZHUGE_4V));
+ 
+-	return __pte(pte_val(pte) | mask);
++	return mask;
++}
++
++static inline pte_t pte_mkhuge(pte_t pte)
++{
++	return __pte(pte_val(pte) | __pte_huge_mask());
++}
++
++static inline bool is_hugetlb_pte(pte_t pte)
++{
++	return !!(pte_val(pte) & __pte_huge_mask());
+ }
++
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+ static inline pmd_t pmd_mkhuge(pmd_t pmd)
+ {
+@@ -403,6 +414,11 @@ static inline pmd_t pmd_mkhuge(pmd_t pmd)
+ 	return __pmd(pte_val(pte));
+ }
+ #endif
++#else
++static inline bool is_hugetlb_pte(pte_t pte)
++{
++	return false;
++}
+ #endif
+ 
+ static inline pte_t pte_mkdirty(pte_t pte)
+@@ -858,6 +874,19 @@ static inline unsigned long pud_pfn(pud_t pud)
+ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+ 		   pte_t *ptep, pte_t orig, int fullmm);
+ 
++static void maybe_tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
++				pte_t *ptep, pte_t orig, int fullmm)
++{
++	/* It is more efficient to let flush_tlb_kernel_range()
++	 * handle init_mm tlb flushes.
++	 *
++	 * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
++	 *             and SUN4V pte layout, so this inline test is fine.
++	 */
++	if (likely(mm != &init_mm) && pte_accessible(mm, orig))
++		tlb_batch_add(mm, vaddr, ptep, orig, fullmm);
++}
++
+ #define __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
+ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
+ 					    unsigned long addr,
+@@ -874,15 +903,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
+ 	pte_t orig = *ptep;
+ 
+ 	*ptep = pte;
+-
+-	/* It is more efficient to let flush_tlb_kernel_range()
+-	 * handle init_mm tlb flushes.
+-	 *
+-	 * SUN4V NOTE: _PAGE_VALID is the same value in both the SUN4U
+-	 *             and SUN4V pte layout, so this inline test is fine.
+-	 */
+-	if (likely(mm != &init_mm) && pte_accessible(mm, orig))
+-		tlb_batch_add(mm, addr, ptep, orig, fullmm);
++	maybe_tlb_batch_add(mm, addr, ptep, orig, fullmm);
+ }
+ 
+ #define set_pte_at(mm,addr,ptep,pte)	\
+diff --git a/arch/sparc/include/asm/tlbflush_64.h b/arch/sparc/include/asm/tlbflush_64.h
+index dea1cfa2122b..a8e192e90700 100644
+--- a/arch/sparc/include/asm/tlbflush_64.h
++++ b/arch/sparc/include/asm/tlbflush_64.h
+@@ -8,6 +8,7 @@
+ #define TLB_BATCH_NR	192
+ 
+ struct tlb_batch {
++	bool huge;
+ 	struct mm_struct *mm;
+ 	unsigned long tlb_nr;
+ 	unsigned long active;
+@@ -16,7 +17,7 @@ struct tlb_batch {
+ 
+ void flush_tsb_kernel_range(unsigned long start, unsigned long end);
+ void flush_tsb_user(struct tlb_batch *tb);
+-void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr);
++void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge);
+ 
+ /* TLB flush operations. */
+ 
+diff --git a/arch/sparc/include/asm/ttable.h b/arch/sparc/include/asm/ttable.h
+index 71b5a67522ab..781b9f1dbdc2 100644
+--- a/arch/sparc/include/asm/ttable.h
++++ b/arch/sparc/include/asm/ttable.h
+@@ -589,8 +589,8 @@ user_rtt_fill_64bit:					\
+ 	 restored;					\
+ 	nop; nop; nop; nop; nop; nop;			\
+ 	nop; nop; nop; nop; nop;			\
+-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
++	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
++	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
+ 	ba,a,pt	%xcc, user_rtt_fill_fixup;
+ 
+ 
+@@ -652,8 +652,8 @@ user_rtt_fill_32bit:					\
+ 	 restored;					\
+ 	nop; nop; nop; nop; nop;			\
+ 	nop; nop; nop;					\
+-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
+-	ba,a,pt	%xcc, user_rtt_fill_fixup;		\
++	ba,a,pt	%xcc, user_rtt_fill_fixup_dax;		\
++	ba,a,pt	%xcc, user_rtt_fill_fixup_mna;		\
+ 	ba,a,pt	%xcc, user_rtt_fill_fixup;
+ 
+ 
+diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile
+index 7cf9c6ea3f1f..fdb13327fded 100644
+--- a/arch/sparc/kernel/Makefile
++++ b/arch/sparc/kernel/Makefile
+@@ -21,6 +21,7 @@ CFLAGS_REMOVE_perf_event.o := -pg
+ CFLAGS_REMOVE_pcr.o := -pg
+ endif
+ 
++obj-$(CONFIG_SPARC64)   += urtt_fill.o
+ obj-$(CONFIG_SPARC32)   += entry.o wof.o wuf.o
+ obj-$(CONFIG_SPARC32)   += etrap_32.o
+ obj-$(CONFIG_SPARC32)   += rtrap_32.o
+diff --git a/arch/sparc/kernel/rtrap_64.S b/arch/sparc/kernel/rtrap_64.S
+index d08bdaffdbfc..216948ca4382 100644
+--- a/arch/sparc/kernel/rtrap_64.S
++++ b/arch/sparc/kernel/rtrap_64.S
+@@ -14,10 +14,6 @@
+ #include <asm/visasm.h>
+ #include <asm/processor.h>
+ 
+-#define		RTRAP_PSTATE		(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE)
+-#define		RTRAP_PSTATE_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV)
+-#define		RTRAP_PSTATE_AG_IRQOFF	(PSTATE_TSO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG)
+-
+ #ifdef CONFIG_CONTEXT_TRACKING
+ # define SCHEDULE_USER schedule_user
+ #else
+@@ -242,52 +238,17 @@ rt_continue:	ldx			[%sp + PTREGS_OFF + PT_V9_G1], %g1
+ 		 wrpr			%g1, %cwp
+ 		ba,a,pt			%xcc, user_rtt_fill_64bit
+ 
+-user_rtt_fill_fixup:
+-		rdpr	%cwp, %g1
+-		add	%g1, 1, %g1
+-		wrpr	%g1, 0x0, %cwp
+-
+-		rdpr	%wstate, %g2
+-		sll	%g2, 3, %g2
+-		wrpr	%g2, 0x0, %wstate
+-
+-		/* We know %canrestore and %otherwin are both zero.  */
+-
+-		sethi	%hi(sparc64_kern_pri_context), %g2
+-		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
+-		mov	PRIMARY_CONTEXT, %g1
+-
+-661:		stxa	%g2, [%g1] ASI_DMMU
+-		.section .sun4v_1insn_patch, "ax"
+-		.word	661b
+-		stxa	%g2, [%g1] ASI_MMU
+-		.previous
+-
+-		sethi	%hi(KERNBASE), %g1
+-		flush	%g1
++user_rtt_fill_fixup_dax:
++		ba,pt	%xcc, user_rtt_fill_fixup_common
++		 mov	1, %g3
+ 
+-		or	%g4, FAULT_CODE_WINFIXUP, %g4
+-		stb	%g4, [%g6 + TI_FAULT_CODE]
+-		stx	%g5, [%g6 + TI_FAULT_ADDR]
++user_rtt_fill_fixup_mna:
++		ba,pt	%xcc, user_rtt_fill_fixup_common
++		 mov	2, %g3
+ 
+-		mov	%g6, %l1
+-		wrpr	%g0, 0x0, %tl
+-
+-661:		nop
+-		.section		.sun4v_1insn_patch, "ax"
+-		.word			661b
+-		SET_GL(0)
+-		.previous
+-
+-		wrpr	%g0, RTRAP_PSTATE, %pstate
+-
+-		mov	%l1, %g6
+-		ldx	[%g6 + TI_TASK], %g4
+-		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
+-		call	do_sparc64_fault
+-		 add	%sp, PTREGS_OFF, %o0
+-		ba,pt	%xcc, rtrap
+-		 nop
++user_rtt_fill_fixup:
++		ba,pt	%xcc, user_rtt_fill_fixup_common
++		 clr	%g3
+ 
+ user_rtt_pre_restore:
+ 		add			%g1, 1, %g1
+diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
+index 3c25241fa5cb..ebd0bfe25a72 100644
+--- a/arch/sparc/kernel/signal32.c
++++ b/arch/sparc/kernel/signal32.c
+@@ -138,12 +138,24 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
+ 	return 0;
+ }
+ 
++/* Checks if the fp is valid.  We always build signal frames which are
++ * 16-byte aligned, therefore we can always enforce that the restore
++ * frame has that property as well.
++ */
++static bool invalid_frame_pointer(void __user *fp, int fplen)
++{
++	if ((((unsigned long) fp) & 15) ||
++	    ((unsigned long)fp) > 0x100000000ULL - fplen)
++		return true;
++	return false;
++}
++
+ void do_sigreturn32(struct pt_regs *regs)
+ {
+ 	struct signal_frame32 __user *sf;
+ 	compat_uptr_t fpu_save;
+ 	compat_uptr_t rwin_save;
+-	unsigned int psr;
++	unsigned int psr, ufp;
+ 	unsigned int pc, npc;
+ 	sigset_t set;
+ 	compat_sigset_t seta;
+@@ -158,11 +170,16 @@ void do_sigreturn32(struct pt_regs *regs)
+ 	sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
+ 
+ 	/* 1. Make sure we are not getting garbage from the user */
+-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
+-	    (((unsigned long) sf) & 3))
++	if (invalid_frame_pointer(sf, sizeof(*sf)))
++		goto segv;
++
++	if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
++		goto segv;
++
++	if (ufp & 0x7)
+ 		goto segv;
+ 
+-	if (get_user(pc, &sf->info.si_regs.pc) ||
++	if (__get_user(pc, &sf->info.si_regs.pc) ||
+ 	    __get_user(npc, &sf->info.si_regs.npc))
+ 		goto segv;
+ 
+@@ -227,7 +244,7 @@ segv:
+ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
+ {
+ 	struct rt_signal_frame32 __user *sf;
+-	unsigned int psr, pc, npc;
++	unsigned int psr, pc, npc, ufp;
+ 	compat_uptr_t fpu_save;
+ 	compat_uptr_t rwin_save;
+ 	sigset_t set;
+@@ -242,11 +259,16 @@ asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
+ 	sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
+ 
+ 	/* 1. Make sure we are not getting garbage from the user */
+-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
+-	    (((unsigned long) sf) & 3))
++	if (invalid_frame_pointer(sf, sizeof(*sf)))
+ 		goto segv;
+ 
+-	if (get_user(pc, &sf->regs.pc) || 
++	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
++		goto segv;
++
++	if (ufp & 0x7)
++		goto segv;
++
++	if (__get_user(pc, &sf->regs.pc) ||
+ 	    __get_user(npc, &sf->regs.npc))
+ 		goto segv;
+ 
+@@ -307,14 +329,6 @@ segv:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-/* Checks if the fp is valid */
+-static int invalid_frame_pointer(void __user *fp, int fplen)
+-{
+-	if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
+-		return 1;
+-	return 0;
+-}
+-
+ static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
+ {
+ 	unsigned long sp;
+diff --git a/arch/sparc/kernel/signal_32.c b/arch/sparc/kernel/signal_32.c
+index 52aa5e4ce5e7..c3c12efe0bc0 100644
+--- a/arch/sparc/kernel/signal_32.c
++++ b/arch/sparc/kernel/signal_32.c
+@@ -60,10 +60,22 @@ struct rt_signal_frame {
+ #define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
+ #define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
+ 
++/* Checks if the fp is valid.  We always build signal frames which are
++ * 16-byte aligned, therefore we can always enforce that the restore
++ * frame has that property as well.
++ */
++static inline bool invalid_frame_pointer(void __user *fp, int fplen)
++{
++	if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
++		return true;
++
++	return false;
++}
++
+ asmlinkage void do_sigreturn(struct pt_regs *regs)
+ {
++	unsigned long up_psr, pc, npc, ufp;
+ 	struct signal_frame __user *sf;
+-	unsigned long up_psr, pc, npc;
+ 	sigset_t set;
+ 	__siginfo_fpu_t __user *fpu_save;
+ 	__siginfo_rwin_t __user *rwin_save;
+@@ -77,10 +89,13 @@ 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 (!access_ok(VERIFY_READ, 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]))
+ 		goto segv_and_exit;
+ 
+-	if (((unsigned long) sf) & 3)
++	if (ufp & 0x7)
+ 		goto segv_and_exit;
+ 
+ 	err = __get_user(pc,  &sf->info.si_regs.pc);
+@@ -127,7 +142,7 @@ segv_and_exit:
+ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
+ {
+ 	struct rt_signal_frame __user *sf;
+-	unsigned int psr, pc, npc;
++	unsigned int psr, pc, npc, ufp;
+ 	__siginfo_fpu_t __user *fpu_save;
+ 	__siginfo_rwin_t __user *rwin_save;
+ 	sigset_t set;
+@@ -135,8 +150,13 @@ asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
+ 
+ 	synchronize_user_stack();
+ 	sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
+-	if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
+-	    (((unsigned long) sf) & 0x03))
++	if (!invalid_frame_pointer(sf, sizeof(*sf)))
++		goto segv;
++
++	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
++		goto segv;
++
++	if (ufp & 0x7)
+ 		goto segv;
+ 
+ 	err = __get_user(pc, &sf->regs.pc);
+@@ -178,15 +198,6 @@ segv:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-/* Checks if the fp is valid */
+-static inline int invalid_frame_pointer(void __user *fp, int fplen)
+-{
+-	if ((((unsigned long) fp) & 7) || !__access_ok((unsigned long)fp, fplen))
+-		return 1;
+-
+-	return 0;
+-}
+-
+ static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
+ {
+ 	unsigned long sp = regs->u_regs[UREG_FP];
+diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
+index 39aaec173f66..5ee930c48f4c 100644
+--- a/arch/sparc/kernel/signal_64.c
++++ b/arch/sparc/kernel/signal_64.c
+@@ -234,6 +234,17 @@ do_sigsegv:
+ 	goto out;
+ }
+ 
++/* Checks if the fp is valid.  We always build rt signal frames which
++ * are 16-byte aligned, therefore we can always enforce that the
++ * restore frame has that property as well.
++ */
++static bool invalid_frame_pointer(void __user *fp)
++{
++	if (((unsigned long) fp) & 15)
++		return true;
++	return false;
++}
++
+ struct rt_signal_frame {
+ 	struct sparc_stackf	ss;
+ 	siginfo_t		info;
+@@ -246,8 +257,8 @@ struct rt_signal_frame {
+ 
+ void do_rt_sigreturn(struct pt_regs *regs)
+ {
++	unsigned long tpc, tnpc, tstate, ufp;
+ 	struct rt_signal_frame __user *sf;
+-	unsigned long tpc, tnpc, tstate;
+ 	__siginfo_fpu_t __user *fpu_save;
+ 	__siginfo_rwin_t __user *rwin_save;
+ 	sigset_t set;
+@@ -261,10 +272,16 @@ void do_rt_sigreturn(struct pt_regs *regs)
+ 		(regs->u_regs [UREG_FP] + STACK_BIAS);
+ 
+ 	/* 1. Make sure we are not getting garbage from the user */
+-	if (((unsigned long) sf) & 3)
++	if (invalid_frame_pointer(sf))
++		goto segv;
++
++	if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
+ 		goto segv;
+ 
+-	err = get_user(tpc, &sf->regs.tpc);
++	if ((ufp + STACK_BIAS) & 0x7)
++		goto segv;
++
++	err = __get_user(tpc, &sf->regs.tpc);
+ 	err |= __get_user(tnpc, &sf->regs.tnpc);
+ 	if (test_thread_flag(TIF_32BIT)) {
+ 		tpc &= 0xffffffff;
+@@ -308,14 +325,6 @@ segv:
+ 	force_sig(SIGSEGV, current);
+ }
+ 
+-/* Checks if the fp is valid */
+-static int invalid_frame_pointer(void __user *fp)
+-{
+-	if (((unsigned long) fp) & 15)
+-		return 1;
+-	return 0;
+-}
+-
+ static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
+ {
+ 	unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
+diff --git a/arch/sparc/kernel/sigutil_32.c b/arch/sparc/kernel/sigutil_32.c
+index 0f6eebe71e6c..e5fe8cef9a69 100644
+--- a/arch/sparc/kernel/sigutil_32.c
++++ b/arch/sparc/kernel/sigutil_32.c
+@@ -48,6 +48,10 @@ int save_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+ {
+ 	int err;
++
++	if (((unsigned long) fpu) & 3)
++		return -EFAULT;
++
+ #ifdef CONFIG_SMP
+ 	if (test_tsk_thread_flag(current, TIF_USEDFPU))
+ 		regs->psr &= ~PSR_EF;
+@@ -97,7 +101,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
+ 	struct thread_info *t = current_thread_info();
+ 	int i, wsaved, err;
+ 
+-	__get_user(wsaved, &rp->wsaved);
++	if (((unsigned long) rp) & 3)
++		return -EFAULT;
++
++	get_user(wsaved, &rp->wsaved);
+ 	if (wsaved > NSWINS)
+ 		return -EFAULT;
+ 
+diff --git a/arch/sparc/kernel/sigutil_64.c b/arch/sparc/kernel/sigutil_64.c
+index 387834a9c56a..36aadcbeac69 100644
+--- a/arch/sparc/kernel/sigutil_64.c
++++ b/arch/sparc/kernel/sigutil_64.c
+@@ -37,7 +37,10 @@ int restore_fpu_state(struct pt_regs *regs, __siginfo_fpu_t __user *fpu)
+ 	unsigned long fprs;
+ 	int err;
+ 
+-	err = __get_user(fprs, &fpu->si_fprs);
++	if (((unsigned long) fpu) & 7)
++		return -EFAULT;
++
++	err = get_user(fprs, &fpu->si_fprs);
+ 	fprs_write(0);
+ 	regs->tstate &= ~TSTATE_PEF;
+ 	if (fprs & FPRS_DL)
+@@ -72,7 +75,10 @@ int restore_rwin_state(__siginfo_rwin_t __user *rp)
+ 	struct thread_info *t = current_thread_info();
+ 	int i, wsaved, err;
+ 
+-	__get_user(wsaved, &rp->wsaved);
++	if (((unsigned long) rp) & 7)
++		return -EFAULT;
++
++	get_user(wsaved, &rp->wsaved);
+ 	if (wsaved > NSWINS)
+ 		return -EFAULT;
+ 
+diff --git a/arch/sparc/kernel/urtt_fill.S b/arch/sparc/kernel/urtt_fill.S
+new file mode 100644
+index 000000000000..5604a2b051d4
+--- /dev/null
++++ b/arch/sparc/kernel/urtt_fill.S
+@@ -0,0 +1,98 @@
++#include <asm/thread_info.h>
++#include <asm/trap_block.h>
++#include <asm/spitfire.h>
++#include <asm/ptrace.h>
++#include <asm/head.h>
++
++		.text
++		.align	8
++		.globl	user_rtt_fill_fixup_common
++user_rtt_fill_fixup_common:
++		rdpr	%cwp, %g1
++		add	%g1, 1, %g1
++		wrpr	%g1, 0x0, %cwp
++
++		rdpr	%wstate, %g2
++		sll	%g2, 3, %g2
++		wrpr	%g2, 0x0, %wstate
++
++		/* We know %canrestore and %otherwin are both zero.  */
++
++		sethi	%hi(sparc64_kern_pri_context), %g2
++		ldx	[%g2 + %lo(sparc64_kern_pri_context)], %g2
++		mov	PRIMARY_CONTEXT, %g1
++
++661:		stxa	%g2, [%g1] ASI_DMMU
++		.section .sun4v_1insn_patch, "ax"
++		.word	661b
++		stxa	%g2, [%g1] ASI_MMU
++		.previous
++
++		sethi	%hi(KERNBASE), %g1
++		flush	%g1
++
++		mov	%g4, %l4
++		mov	%g5, %l5
++		brnz,pn	%g3, 1f
++		 mov	%g3, %l3
++
++		or	%g4, FAULT_CODE_WINFIXUP, %g4
++		stb	%g4, [%g6 + TI_FAULT_CODE]
++		stx	%g5, [%g6 + TI_FAULT_ADDR]
++1:
++		mov	%g6, %l1
++		wrpr	%g0, 0x0, %tl
++
++661:		nop
++		.section		.sun4v_1insn_patch, "ax"
++		.word			661b
++		SET_GL(0)
++		.previous
++
++		wrpr	%g0, RTRAP_PSTATE, %pstate
++
++		mov	%l1, %g6
++		ldx	[%g6 + TI_TASK], %g4
++		LOAD_PER_CPU_BASE(%g5, %g6, %g1, %g2, %g3)
++
++		brnz,pn	%l3, 1f
++		 nop
++
++		call	do_sparc64_fault
++		 add	%sp, PTREGS_OFF, %o0
++		ba,pt	%xcc, rtrap
++		 nop
++
++1:		cmp	%g3, 2
++		bne,pn	%xcc, 2f
++		 nop
++
++		sethi	%hi(tlb_type), %g1
++		lduw	[%g1 + %lo(tlb_type)], %g1
++		cmp	%g1, 3
++		bne,pt	%icc, 1f
++		 add	%sp, PTREGS_OFF, %o0
++		mov	%l4, %o2
++		call	sun4v_do_mna
++		 mov	%l5, %o1
++		ba,a,pt	%xcc, rtrap
++1:		mov	%l4, %o1
++		mov	%l5, %o2
++		call	mem_address_unaligned
++		 nop
++		ba,a,pt	%xcc, rtrap
++
++2:		sethi	%hi(tlb_type), %g1
++		mov	%l4, %o1
++		lduw	[%g1 + %lo(tlb_type)], %g1
++		mov	%l5, %o2
++		cmp	%g1, 3
++		bne,pt	%icc, 1f
++		 add	%sp, PTREGS_OFF, %o0
++		call	sun4v_data_access_exception
++		 nop
++		ba,a,pt	%xcc, rtrap
++
++1:		call	spitfire_data_access_exception
++		 nop
++		ba,a,pt	%xcc, rtrap
+diff --git a/arch/sparc/mm/hugetlbpage.c b/arch/sparc/mm/hugetlbpage.c
+index 4977800e9770..ba52e6466a82 100644
+--- a/arch/sparc/mm/hugetlbpage.c
++++ b/arch/sparc/mm/hugetlbpage.c
+@@ -176,17 +176,31 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long addr,
+ 		     pte_t *ptep, pte_t entry)
+ {
+ 	int i;
++	pte_t orig[2];
++	unsigned long nptes;
+ 
+ 	if (!pte_present(*ptep) && pte_present(entry))
+ 		mm->context.huge_pte_count++;
+ 
+ 	addr &= HPAGE_MASK;
+-	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-		set_pte_at(mm, addr, ptep, entry);
++
++	nptes = 1 << HUGETLB_PAGE_ORDER;
++	orig[0] = *ptep;
++	orig[1] = *(ptep + nptes / 2);
++	for (i = 0; i < nptes; i++) {
++		*ptep = entry;
+ 		ptep++;
+ 		addr += PAGE_SIZE;
+ 		pte_val(entry) += PAGE_SIZE;
+ 	}
++
++	/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
++	addr -= REAL_HPAGE_SIZE;
++	ptep -= nptes / 2;
++	maybe_tlb_batch_add(mm, addr, ptep, orig[1], 0);
++	addr -= REAL_HPAGE_SIZE;
++	ptep -= nptes / 2;
++	maybe_tlb_batch_add(mm, addr, ptep, orig[0], 0);
+ }
+ 
+ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+@@ -194,19 +208,28 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
+ {
+ 	pte_t entry;
+ 	int i;
++	unsigned long nptes;
+ 
+ 	entry = *ptep;
+ 	if (pte_present(entry))
+ 		mm->context.huge_pte_count--;
+ 
+ 	addr &= HPAGE_MASK;
+-
+-	for (i = 0; i < (1 << HUGETLB_PAGE_ORDER); i++) {
+-		pte_clear(mm, addr, ptep);
++	nptes = 1 << HUGETLB_PAGE_ORDER;
++	for (i = 0; i < nptes; i++) {
++		*ptep = __pte(0UL);
+ 		addr += PAGE_SIZE;
+ 		ptep++;
+ 	}
+ 
++	/* Issue TLB flush at REAL_HPAGE_SIZE boundaries */
++	addr -= REAL_HPAGE_SIZE;
++	ptep -= nptes / 2;
++	maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
++	addr -= REAL_HPAGE_SIZE;
++	ptep -= nptes / 2;
++	maybe_tlb_batch_add(mm, addr, ptep, entry, 0);
++
+ 	return entry;
+ }
+ 
+diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
+index 09e838801e39..14bb0d5ed3c6 100644
+--- a/arch/sparc/mm/init_64.c
++++ b/arch/sparc/mm/init_64.c
+@@ -324,18 +324,6 @@ static void __update_mmu_tsb_insert(struct mm_struct *mm, unsigned long tsb_inde
+ 	tsb_insert(tsb, tag, tte);
+ }
+ 
+-#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+-static inline bool is_hugetlb_pte(pte_t pte)
+-{
+-	if ((tlb_type == hypervisor &&
+-	     (pte_val(pte) & _PAGE_SZALL_4V) == _PAGE_SZHUGE_4V) ||
+-	    (tlb_type != hypervisor &&
+-	     (pte_val(pte) & _PAGE_SZALL_4U) == _PAGE_SZHUGE_4U))
+-		return true;
+-	return false;
+-}
+-#endif
+-
+ void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
+ {
+ 	struct mm_struct *mm;
+@@ -2836,9 +2824,10 @@ void hugetlb_setup(struct pt_regs *regs)
+ 	 * the Data-TLB for huge pages.
+ 	 */
+ 	if (tlb_type == cheetah_plus) {
++		bool need_context_reload = false;
+ 		unsigned long ctx;
+ 
+-		spin_lock(&ctx_alloc_lock);
++		spin_lock_irq(&ctx_alloc_lock);
+ 		ctx = mm->context.sparc64_ctx_val;
+ 		ctx &= ~CTX_PGSZ_MASK;
+ 		ctx |= CTX_PGSZ_BASE << CTX_PGSZ0_SHIFT;
+@@ -2857,9 +2846,12 @@ void hugetlb_setup(struct pt_regs *regs)
+ 			 * also executing in this address space.
+ 			 */
+ 			mm->context.sparc64_ctx_val = ctx;
+-			on_each_cpu(context_reload, mm, 0);
++			need_context_reload = true;
+ 		}
+-		spin_unlock(&ctx_alloc_lock);
++		spin_unlock_irq(&ctx_alloc_lock);
++
++		if (need_context_reload)
++			on_each_cpu(context_reload, mm, 0);
+ 	}
+ }
+ #endif
+diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c
+index 9df2190c097e..f81cd9736700 100644
+--- a/arch/sparc/mm/tlb.c
++++ b/arch/sparc/mm/tlb.c
+@@ -67,7 +67,7 @@ void arch_leave_lazy_mmu_mode(void)
+ }
+ 
+ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
+-			      bool exec)
++			      bool exec, bool huge)
+ {
+ 	struct tlb_batch *tb = &get_cpu_var(tlb_batch);
+ 	unsigned long nr;
+@@ -84,13 +84,21 @@ static void tlb_batch_add_one(struct mm_struct *mm, unsigned long vaddr,
+ 	}
+ 
+ 	if (!tb->active) {
+-		flush_tsb_user_page(mm, vaddr);
++		flush_tsb_user_page(mm, vaddr, huge);
+ 		global_flush_tlb_page(mm, vaddr);
+ 		goto out;
+ 	}
+ 
+-	if (nr == 0)
++	if (nr == 0) {
+ 		tb->mm = mm;
++		tb->huge = huge;
++	}
++
++	if (tb->huge != huge) {
++		flush_tlb_pending();
++		tb->huge = huge;
++		nr = 0;
++	}
+ 
+ 	tb->vaddrs[nr] = vaddr;
+ 	tb->tlb_nr = ++nr;
+@@ -104,6 +112,8 @@ out:
+ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+ 		   pte_t *ptep, pte_t orig, int fullmm)
+ {
++	bool huge = is_hugetlb_pte(orig);
++
+ 	if (tlb_type != hypervisor &&
+ 	    pte_dirty(orig)) {
+ 		unsigned long paddr, pfn = pte_pfn(orig);
+@@ -129,7 +139,7 @@ void tlb_batch_add(struct mm_struct *mm, unsigned long vaddr,
+ 
+ no_cache_flush:
+ 	if (!fullmm)
+-		tlb_batch_add_one(mm, vaddr, pte_exec(orig));
++		tlb_batch_add_one(mm, vaddr, pte_exec(orig), huge);
+ }
+ 
+ #ifdef CONFIG_TRANSPARENT_HUGEPAGE
+@@ -145,7 +155,7 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr,
+ 		if (pte_val(*pte) & _PAGE_VALID) {
+ 			bool exec = pte_exec(*pte);
+ 
+-			tlb_batch_add_one(mm, vaddr, exec);
++			tlb_batch_add_one(mm, vaddr, exec, false);
+ 		}
+ 		pte++;
+ 		vaddr += PAGE_SIZE;
+@@ -185,8 +195,9 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr,
+ 			pte_t orig_pte = __pte(pmd_val(orig));
+ 			bool exec = pte_exec(orig_pte);
+ 
+-			tlb_batch_add_one(mm, addr, exec);
+-			tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec);
++			tlb_batch_add_one(mm, addr, exec, true);
++			tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec,
++					true);
+ 		} else {
+ 			tlb_batch_pmd_scan(mm, addr, orig);
+ 		}
+diff --git a/arch/sparc/mm/tsb.c b/arch/sparc/mm/tsb.c
+index a06576683c38..a0604a493a36 100644
+--- a/arch/sparc/mm/tsb.c
++++ b/arch/sparc/mm/tsb.c
+@@ -76,14 +76,15 @@ void flush_tsb_user(struct tlb_batch *tb)
+ 
+ 	spin_lock_irqsave(&mm->context.lock, flags);
+ 
+-	base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
+-	nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
+-	if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+-		base = __pa(base);
+-	__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
+-
++	if (!tb->huge) {
++		base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
++		nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
++		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
++			base = __pa(base);
++		__flush_tsb_one(tb, PAGE_SHIFT, base, nentries);
++	}
+ #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+-	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
++	if (tb->huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
+ 		base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
+ 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
+ 		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+@@ -94,20 +95,21 @@ void flush_tsb_user(struct tlb_batch *tb)
+ 	spin_unlock_irqrestore(&mm->context.lock, flags);
+ }
+ 
+-void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr)
++void flush_tsb_user_page(struct mm_struct *mm, unsigned long vaddr, bool huge)
+ {
+ 	unsigned long nentries, base, flags;
+ 
+ 	spin_lock_irqsave(&mm->context.lock, flags);
+ 
+-	base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
+-	nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
+-	if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+-		base = __pa(base);
+-	__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
+-
++	if (!huge) {
++		base = (unsigned long) mm->context.tsb_block[MM_TSB_BASE].tsb;
++		nentries = mm->context.tsb_block[MM_TSB_BASE].tsb_nentries;
++		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
++			base = __pa(base);
++		__flush_tsb_one_entry(base, vaddr, PAGE_SHIFT, nentries);
++	}
+ #if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
+-	if (mm->context.tsb_block[MM_TSB_HUGE].tsb) {
++	if (huge && mm->context.tsb_block[MM_TSB_HUGE].tsb) {
+ 		base = (unsigned long) mm->context.tsb_block[MM_TSB_HUGE].tsb;
+ 		nentries = mm->context.tsb_block[MM_TSB_HUGE].tsb_nentries;
+ 		if (tlb_type == cheetah_plus || tlb_type == hypervisor)
+diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
+index 06cbe25861f1..87bd6b6bf5bd 100644
+--- a/arch/x86/kernel/traps.c
++++ b/arch/x86/kernel/traps.c
+@@ -95,6 +95,12 @@ static inline void cond_local_irq_disable(struct pt_regs *regs)
+ 		local_irq_disable();
+ }
+ 
++/*
++ * In IST context, we explicitly disable preemption.  This serves two
++ * purposes: it makes it much less likely that we would accidentally
++ * schedule in IST context and it will force a warning if we somehow
++ * manage to schedule by accident.
++ */
+ void ist_enter(struct pt_regs *regs)
+ {
+ 	if (user_mode(regs)) {
+@@ -109,13 +115,7 @@ void ist_enter(struct pt_regs *regs)
+ 		rcu_nmi_enter();
+ 	}
+ 
+-	/*
+-	 * We are atomic because we're on the IST stack; or we're on
+-	 * x86_32, in which case we still shouldn't schedule; or we're
+-	 * on x86_64 and entered from user mode, in which case we're
+-	 * still atomic unless ist_begin_non_atomic is called.
+-	 */
+-	preempt_count_add(HARDIRQ_OFFSET);
++	preempt_disable();
+ 
+ 	/* This code is a bit fragile.  Test it. */
+ 	RCU_LOCKDEP_WARN(!rcu_is_watching(), "ist_enter didn't work");
+@@ -123,7 +123,7 @@ void ist_enter(struct pt_regs *regs)
+ 
+ void ist_exit(struct pt_regs *regs)
+ {
+-	preempt_count_sub(HARDIRQ_OFFSET);
++	preempt_enable_no_resched();
+ 
+ 	if (!user_mode(regs))
+ 		rcu_nmi_exit();
+@@ -154,7 +154,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
+ 	BUG_ON((unsigned long)(current_top_of_stack() -
+ 			       current_stack_pointer()) >= THREAD_SIZE);
+ 
+-	preempt_count_sub(HARDIRQ_OFFSET);
++	preempt_enable_no_resched();
+ }
+ 
+ /**
+@@ -164,7 +164,7 @@ void ist_begin_non_atomic(struct pt_regs *regs)
+  */
+ void ist_end_non_atomic(void)
+ {
+-	preempt_count_add(HARDIRQ_OFFSET);
++	preempt_disable();
+ }
+ 
+ static nokprobe_inline int
+diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
+index 9b7798c7b210..6b9701babaa1 100644
+--- a/arch/x86/kvm/x86.c
++++ b/arch/x86/kvm/x86.c
+@@ -3032,6 +3032,11 @@ static int kvm_vcpu_ioctl_x86_set_debugregs(struct kvm_vcpu *vcpu,
+ 	if (dbgregs->flags)
+ 		return -EINVAL;
+ 
++	if (dbgregs->dr6 & ~0xffffffffull)
++		return -EINVAL;
++	if (dbgregs->dr7 & ~0xffffffffull)
++		return -EINVAL;
++
+ 	memcpy(vcpu->arch.db, dbgregs->db, sizeof(vcpu->arch.db));
+ 	kvm_update_dr0123(vcpu);
+ 	vcpu->arch.dr6 = dbgregs->dr6;
+diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig
+index 91a7e047a765..477cbf39e0fb 100644
+--- a/crypto/asymmetric_keys/Kconfig
++++ b/crypto/asymmetric_keys/Kconfig
+@@ -13,6 +13,7 @@ config ASYMMETRIC_PUBLIC_KEY_SUBTYPE
+ 	tristate "Asymmetric public-key crypto algorithm subtype"
+ 	select MPILIB
+ 	select CRYPTO_HASH_INFO
++	select CRYPTO_AKCIPHER
+ 	help
+ 	  This option provides support for asymmetric public key type handling.
+ 	  If signature generation and/or verification are to be used,
+diff --git a/drivers/crypto/ccp/ccp-crypto-aes-xts.c b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+index 52c7395cb8d8..0d0d4529ee36 100644
+--- a/drivers/crypto/ccp/ccp-crypto-aes-xts.c
++++ b/drivers/crypto/ccp/ccp-crypto-aes-xts.c
+@@ -122,6 +122,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
+ 	struct ccp_ctx *ctx = crypto_tfm_ctx(req->base.tfm);
+ 	struct ccp_aes_req_ctx *rctx = ablkcipher_request_ctx(req);
+ 	unsigned int unit;
++	u32 unit_size;
+ 	int ret;
+ 
+ 	if (!ctx->u.aes.key_len)
+@@ -133,11 +134,17 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
+ 	if (!req->info)
+ 		return -EINVAL;
+ 
+-	for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++)
+-		if (!(req->nbytes & (unit_size_map[unit].size - 1)))
+-			break;
++	unit_size = CCP_XTS_AES_UNIT_SIZE__LAST;
++	if (req->nbytes <= unit_size_map[0].size) {
++		for (unit = 0; unit < ARRAY_SIZE(unit_size_map); unit++) {
++			if (!(req->nbytes & (unit_size_map[unit].size - 1))) {
++				unit_size = unit_size_map[unit].value;
++				break;
++			}
++		}
++	}
+ 
+-	if ((unit_size_map[unit].value == CCP_XTS_AES_UNIT_SIZE__LAST) ||
++	if ((unit_size == CCP_XTS_AES_UNIT_SIZE__LAST) ||
+ 	    (ctx->u.aes.key_len != AES_KEYSIZE_128)) {
+ 		/* Use the fallback to process the request for any
+ 		 * unsupported unit sizes or key sizes
+@@ -158,7 +165,7 @@ static int ccp_aes_xts_crypt(struct ablkcipher_request *req,
+ 	rctx->cmd.engine = CCP_ENGINE_XTS_AES_128;
+ 	rctx->cmd.u.xts.action = (encrypt) ? CCP_AES_ACTION_ENCRYPT
+ 					   : CCP_AES_ACTION_DECRYPT;
+-	rctx->cmd.u.xts.unit_size = unit_size_map[unit].value;
++	rctx->cmd.u.xts.unit_size = unit_size;
+ 	rctx->cmd.u.xts.key = &ctx->u.aes.key_sg;
+ 	rctx->cmd.u.xts.key_len = ctx->u.aes.key_len;
+ 	rctx->cmd.u.xts.iv = &rctx->iv_sg;
+diff --git a/drivers/gpio/gpio-bcm-kona.c b/drivers/gpio/gpio-bcm-kona.c
+index 2fd38d598f3d..3c5e83263fe0 100644
+--- a/drivers/gpio/gpio-bcm-kona.c
++++ b/drivers/gpio/gpio-bcm-kona.c
+@@ -546,11 +546,11 @@ static void bcm_kona_gpio_reset(struct bcm_kona_gpio *kona_gpio)
+ 	/* disable interrupts and clear status */
+ 	for (i = 0; i < kona_gpio->num_bank; i++) {
+ 		/* Unlock the entire bank first */
+-		bcm_kona_gpio_write_lock_regs(kona_gpio, i, UNLOCK_CODE);
++		bcm_kona_gpio_write_lock_regs(reg_base, i, UNLOCK_CODE);
+ 		writel(0xffffffff, reg_base + GPIO_INT_MASK(i));
+ 		writel(0xffffffff, reg_base + GPIO_INT_STATUS(i));
+ 		/* Now re-lock the bank */
+-		bcm_kona_gpio_write_lock_regs(kona_gpio, i, LOCK_CODE);
++		bcm_kona_gpio_write_lock_regs(reg_base, i, LOCK_CODE);
+ 	}
+ }
+ 
+diff --git a/drivers/gpio/gpio-zynq.c b/drivers/gpio/gpio-zynq.c
+index 66d3d247d76d..e72794e463aa 100644
+--- a/drivers/gpio/gpio-zynq.c
++++ b/drivers/gpio/gpio-zynq.c
+@@ -709,11 +709,17 @@ static int zynq_gpio_probe(struct platform_device *pdev)
+ 		dev_err(&pdev->dev, "input clock not found.\n");
+ 		return PTR_ERR(gpio->clk);
+ 	}
++	ret = clk_prepare_enable(gpio->clk);
++	if (ret) {
++		dev_err(&pdev->dev, "Unable to enable clock.\n");
++		return ret;
++	}
+ 
++	pm_runtime_set_active(&pdev->dev);
+ 	pm_runtime_enable(&pdev->dev);
+ 	ret = pm_runtime_get_sync(&pdev->dev);
+ 	if (ret < 0)
+-		return ret;
++		goto err_pm_dis;
+ 
+ 	/* report a bug if gpio chip registration fails */
+ 	ret = gpiochip_add_data(chip, gpio);
+@@ -745,6 +751,9 @@ err_rm_gpiochip:
+ 	gpiochip_remove(chip);
+ err_pm_put:
+ 	pm_runtime_put(&pdev->dev);
++err_pm_dis:
++	pm_runtime_disable(&pdev->dev);
++	clk_disable_unprepare(gpio->clk);
+ 
+ 	return ret;
+ }
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index b747c76fd2b1..cf3e71243d6d 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -438,7 +438,6 @@ static void gpiodevice_release(struct device *dev)
+ {
+ 	struct gpio_device *gdev = dev_get_drvdata(dev);
+ 
+-	cdev_del(&gdev->chrdev);
+ 	list_del(&gdev->list);
+ 	ida_simple_remove(&gpio_ida, gdev->id);
+ 	kfree(gdev->label);
+@@ -471,7 +470,6 @@ static int gpiochip_setup_dev(struct gpio_device *gdev)
+ 
+ 	/* From this point, the .release() function cleans up gpio_device */
+ 	gdev->dev.release = gpiodevice_release;
+-	get_device(&gdev->dev);
+ 	pr_debug("%s: registered GPIOs %d to %d on device: %s (%s)\n",
+ 		 __func__, gdev->base, gdev->base + gdev->ngpio - 1,
+ 		 dev_name(&gdev->dev), gdev->chip->label ? : "generic");
+@@ -742,6 +740,8 @@ void gpiochip_remove(struct gpio_chip *chip)
+ 	 * be removed, else it will be dangling until the last user is
+ 	 * gone.
+ 	 */
++	cdev_del(&gdev->chrdev);
++	device_del(&gdev->dev);
+ 	put_device(&gdev->dev);
+ }
+ EXPORT_SYMBOL_GPL(gpiochip_remove);
+@@ -841,7 +841,7 @@ struct gpio_chip *gpiochip_find(void *data,
+ 
+ 	spin_lock_irqsave(&gpio_lock, flags);
+ 	list_for_each_entry(gdev, &gpio_devices, list)
+-		if (match(gdev->chip, data))
++		if (gdev->chip && match(gdev->chip, data))
+ 			break;
+ 
+ 	/* No match? */
+@@ -1339,10 +1339,13 @@ done:
+ /*
+  * This descriptor validation needs to be inserted verbatim into each
+  * function taking a descriptor, so we need to use a preprocessor
+- * macro to avoid endless duplication.
++ * macro to avoid endless duplication. If the desc is NULL it is an
++ * optional GPIO and calls should just bail out.
+  */
+ #define VALIDATE_DESC(desc) do { \
+-	if (!desc || !desc->gdev) { \
++	if (!desc) \
++		return 0; \
++	if (!desc->gdev) { \
+ 		pr_warn("%s: invalid GPIO\n", __func__); \
+ 		return -EINVAL; \
+ 	} \
+@@ -1353,7 +1356,9 @@ done:
+ 	} } while (0)
+ 
+ #define VALIDATE_DESC_VOID(desc) do { \
+-	if (!desc || !desc->gdev) { \
++	if (!desc) \
++		return; \
++	if (!desc->gdev) { \
+ 		pr_warn("%s: invalid GPIO\n", __func__); \
+ 		return; \
+ 	} \
+@@ -2001,7 +2006,14 @@ int gpiod_to_irq(const struct gpio_desc *desc)
+ 	struct gpio_chip	*chip;
+ 	int			offset;
+ 
+-	VALIDATE_DESC(desc);
++	/*
++	 * Cannot VALIDATE_DESC() here as gpiod_to_irq() consumer semantics
++	 * requires this function to not return zero on an invalid descriptor
++	 * but rather a negative error number.
++	 */
++	if (!desc || !desc->gdev || !desc->gdev->chip)
++		return -EINVAL;
++
+ 	chip = desc->gdev->chip;
+ 	offset = gpio_chip_hwgpio(desc);
+ 	return chip->to_irq ? chip->to_irq(chip, offset) : -ENXIO;
+diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
+index e08f962288d9..f30de8053545 100644
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -3434,6 +3434,24 @@ int drm_mode_addfb2(struct drm_device *dev,
+ 	return 0;
+ }
+ 
++struct drm_mode_rmfb_work {
++	struct work_struct work;
++	struct list_head fbs;
++};
++
++static void drm_mode_rmfb_work_fn(struct work_struct *w)
++{
++	struct drm_mode_rmfb_work *arg = container_of(w, typeof(*arg), work);
++
++	while (!list_empty(&arg->fbs)) {
++		struct drm_framebuffer *fb =
++			list_first_entry(&arg->fbs, typeof(*fb), filp_head);
++
++		list_del_init(&fb->filp_head);
++		drm_framebuffer_remove(fb);
++	}
++}
++
+ /**
+  * drm_mode_rmfb - remove an FB from the configuration
+  * @dev: drm device for the ioctl
+@@ -3474,7 +3492,25 @@ int drm_mode_rmfb(struct drm_device *dev,
+ 	mutex_unlock(&dev->mode_config.fb_lock);
+ 	mutex_unlock(&file_priv->fbs_lock);
+ 
+-	drm_framebuffer_unreference(fb);
++	/*
++	 * we now own the reference that was stored in the fbs list
++	 *
++	 * drm_framebuffer_remove may fail with -EINTR on pending signals,
++	 * so run this in a separate stack as there's no way to correctly
++	 * handle this after the fb is already removed from the lookup table.
++	 */
++	if (atomic_read(&fb->refcount.refcount) > 1) {
++		struct drm_mode_rmfb_work arg;
++
++		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
++		INIT_LIST_HEAD(&arg.fbs);
++		list_add_tail(&fb->filp_head, &arg.fbs);
++
++		schedule_work(&arg.work);
++		flush_work(&arg.work);
++		destroy_work_on_stack(&arg.work);
++	} else
++		drm_framebuffer_unreference(fb);
+ 
+ 	return 0;
+ 
+@@ -3627,7 +3663,6 @@ out_err1:
+ 	return ret;
+ }
+ 
+-
+ /**
+  * drm_fb_release - remove and free the FBs on this file
+  * @priv: drm file for the ioctl
+@@ -3642,6 +3677,9 @@ out_err1:
+ void drm_fb_release(struct drm_file *priv)
+ {
+ 	struct drm_framebuffer *fb, *tfb;
++	struct drm_mode_rmfb_work arg;
++
++	INIT_LIST_HEAD(&arg.fbs);
+ 
+ 	/*
+ 	 * When the file gets released that means no one else can access the fb
+@@ -3654,10 +3692,22 @@ void drm_fb_release(struct drm_file *priv)
+ 	 * at it any more.
+ 	 */
+ 	list_for_each_entry_safe(fb, tfb, &priv->fbs, filp_head) {
+-		list_del_init(&fb->filp_head);
++		if (atomic_read(&fb->refcount.refcount) > 1) {
++			list_move_tail(&fb->filp_head, &arg.fbs);
++		} else {
++			list_del_init(&fb->filp_head);
+ 
+-		/* This drops the fpriv->fbs reference. */
+-		drm_framebuffer_unreference(fb);
++			/* This drops the fpriv->fbs reference. */
++			drm_framebuffer_unreference(fb);
++		}
++	}
++
++	if (!list_empty(&arg.fbs)) {
++		INIT_WORK_ONSTACK(&arg.work, drm_mode_rmfb_work_fn);
++
++		schedule_work(&arg.work);
++		flush_work(&arg.work);
++		destroy_work_on_stack(&arg.work);
+ 	}
+ }
+ 
+diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
+index 1c212205d0e7..d1a46ef5ab3f 100644
+--- a/drivers/gpu/drm/i915/i915_irq.c
++++ b/drivers/gpu/drm/i915/i915_irq.c
+@@ -1829,7 +1829,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
+ 	/* IRQs are synced during runtime_suspend, we don't require a wakeref */
+ 	disable_rpm_wakeref_asserts(dev_priv);
+ 
+-	do {
++	for (;;) {
+ 		master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
+ 		iir = I915_READ(VLV_IIR);
+ 
+@@ -1857,7 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
+ 
+ 		I915_WRITE(GEN8_MASTER_IRQ, DE_MASTER_IRQ_CONTROL);
+ 		POSTING_READ(GEN8_MASTER_IRQ);
+-	} while (0);
++	}
+ 
+ 	enable_rpm_wakeref_asserts(dev_priv);
+ 
+diff --git a/drivers/net/ethernet/atheros/alx/alx.h b/drivers/net/ethernet/atheros/alx/alx.h
+index 8fc93c5f6abc..d02c4240b7df 100644
+--- a/drivers/net/ethernet/atheros/alx/alx.h
++++ b/drivers/net/ethernet/atheros/alx/alx.h
+@@ -96,6 +96,10 @@ struct alx_priv {
+ 	unsigned int rx_ringsz;
+ 	unsigned int rxbuf_size;
+ 
++	struct page  *rx_page;
++	unsigned int rx_page_offset;
++	unsigned int rx_frag_size;
++
+ 	struct napi_struct napi;
+ 	struct alx_tx_queue txq;
+ 	struct alx_rx_queue rxq;
+diff --git a/drivers/net/ethernet/atheros/alx/main.c b/drivers/net/ethernet/atheros/alx/main.c
+index 55b118e876fd..8611811fbf88 100644
+--- a/drivers/net/ethernet/atheros/alx/main.c
++++ b/drivers/net/ethernet/atheros/alx/main.c
+@@ -70,6 +70,35 @@ static void alx_free_txbuf(struct alx_priv *alx, int entry)
+ 	}
+ }
+ 
++static struct sk_buff *alx_alloc_skb(struct alx_priv *alx, gfp_t gfp)
++{
++	struct sk_buff *skb;
++	struct page *page;
++
++	if (alx->rx_frag_size > PAGE_SIZE)
++		return __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
++
++	page = alx->rx_page;
++	if (!page) {
++		alx->rx_page = page = alloc_page(gfp);
++		if (unlikely(!page))
++			return NULL;
++		alx->rx_page_offset = 0;
++	}
++
++	skb = build_skb(page_address(page) + alx->rx_page_offset,
++			alx->rx_frag_size);
++	if (likely(skb)) {
++		alx->rx_page_offset += alx->rx_frag_size;
++		if (alx->rx_page_offset >= PAGE_SIZE)
++			alx->rx_page = NULL;
++		else
++			get_page(page);
++	}
++	return skb;
++}
++
++
+ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
+ {
+ 	struct alx_rx_queue *rxq = &alx->rxq;
+@@ -86,7 +115,7 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
+ 	while (!cur_buf->skb && next != rxq->read_idx) {
+ 		struct alx_rfd *rfd = &rxq->rfd[cur];
+ 
+-		skb = __netdev_alloc_skb(alx->dev, alx->rxbuf_size, gfp);
++		skb = alx_alloc_skb(alx, gfp);
+ 		if (!skb)
+ 			break;
+ 		dma = dma_map_single(&alx->hw.pdev->dev,
+@@ -124,6 +153,7 @@ static int alx_refill_rx_ring(struct alx_priv *alx, gfp_t gfp)
+ 		alx_write_mem16(&alx->hw, ALX_RFD_PIDX, cur);
+ 	}
+ 
++
+ 	return count;
+ }
+ 
+@@ -592,6 +622,11 @@ static void alx_free_rings(struct alx_priv *alx)
+ 	kfree(alx->txq.bufs);
+ 	kfree(alx->rxq.bufs);
+ 
++	if (alx->rx_page) {
++		put_page(alx->rx_page);
++		alx->rx_page = NULL;
++	}
++
+ 	dma_free_coherent(&alx->hw.pdev->dev,
+ 			  alx->descmem.size,
+ 			  alx->descmem.virt,
+@@ -646,6 +681,7 @@ static int alx_request_irq(struct alx_priv *alx)
+ 				  alx->dev->name, alx);
+ 		if (!err)
+ 			goto out;
++
+ 		/* fall back to legacy interrupt */
+ 		pci_disable_msi(alx->hw.pdev);
+ 	}
+@@ -689,6 +725,7 @@ static int alx_init_sw(struct alx_priv *alx)
+ 	struct pci_dev *pdev = alx->hw.pdev;
+ 	struct alx_hw *hw = &alx->hw;
+ 	int err;
++	unsigned int head_size;
+ 
+ 	err = alx_identify_hw(alx);
+ 	if (err) {
+@@ -704,7 +741,12 @@ static int alx_init_sw(struct alx_priv *alx)
+ 
+ 	hw->smb_timer = 400;
+ 	hw->mtu = alx->dev->mtu;
++
+ 	alx->rxbuf_size = ALX_MAX_FRAME_LEN(hw->mtu);
++	head_size = SKB_DATA_ALIGN(alx->rxbuf_size + NET_SKB_PAD) +
++		    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++	alx->rx_frag_size = roundup_pow_of_two(head_size);
++
+ 	alx->tx_ringsz = 256;
+ 	alx->rx_ringsz = 512;
+ 	hw->imt = 200;
+@@ -806,6 +848,7 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
+ {
+ 	struct alx_priv *alx = netdev_priv(netdev);
+ 	int max_frame = ALX_MAX_FRAME_LEN(mtu);
++	unsigned int head_size;
+ 
+ 	if ((max_frame < ALX_MIN_FRAME_SIZE) ||
+ 	    (max_frame > ALX_MAX_FRAME_SIZE))
+@@ -817,6 +860,9 @@ static int alx_change_mtu(struct net_device *netdev, int mtu)
+ 	netdev->mtu = mtu;
+ 	alx->hw.mtu = mtu;
+ 	alx->rxbuf_size = max(max_frame, ALX_DEF_RXBUF_SIZE);
++	head_size = SKB_DATA_ALIGN(alx->rxbuf_size + NET_SKB_PAD) +
++		    SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
++	alx->rx_frag_size = roundup_pow_of_two(head_size);
+ 	netdev_update_features(netdev);
+ 	if (netif_running(netdev))
+ 		alx_reinit(alx);
+diff --git a/drivers/net/ethernet/ezchip/nps_enet.c b/drivers/net/ethernet/ezchip/nps_enet.c
+index 085f9125cf42..06f031715b57 100644
+--- a/drivers/net/ethernet/ezchip/nps_enet.c
++++ b/drivers/net/ethernet/ezchip/nps_enet.c
+@@ -205,8 +205,10 @@ static int nps_enet_poll(struct napi_struct *napi, int budget)
+ 		 * re-adding ourselves to the poll list.
+ 		 */
+ 
+-		if (priv->tx_skb && !tx_ctrl_ct)
++		if (priv->tx_skb && !tx_ctrl_ct) {
++			nps_enet_reg_set(priv, NPS_ENET_REG_BUF_INT_ENABLE, 0);
+ 			napi_reschedule(napi);
++		}
+ 	}
+ 
+ 	return work_done;
+diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c
+index 01fccec632ec..466939f8f0cf 100644
+--- a/drivers/net/ethernet/marvell/mvneta_bm.c
++++ b/drivers/net/ethernet/marvell/mvneta_bm.c
+@@ -189,6 +189,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,
+ 			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+ 		hwbm_pool->construct = mvneta_bm_construct;
+ 		hwbm_pool->priv = new_pool;
++		spin_lock_init(&hwbm_pool->lock);
+ 
+ 		/* Create new pool */
+ 		err = mvneta_bm_pool_create(priv, new_pool);
+diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c
+index 0e758bcb26b0..1ca796316173 100644
+--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c
++++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c
+@@ -2727,7 +2727,7 @@ static int ofdpa_port_obj_fib4_add(struct rocker_port *rocker_port,
+ 
+ 	return ofdpa_port_fib_ipv4(ofdpa_port, trans,
+ 				   htonl(fib4->dst), fib4->dst_len,
+-				   &fib4->fi, fib4->tb_id, 0);
++				   fib4->fi, fib4->tb_id, 0);
+ }
+ 
+ static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
+@@ -2737,7 +2737,7 @@ static int ofdpa_port_obj_fib4_del(struct rocker_port *rocker_port,
+ 
+ 	return ofdpa_port_fib_ipv4(ofdpa_port, NULL,
+ 				   htonl(fib4->dst), fib4->dst_len,
+-				   &fib4->fi, fib4->tb_id,
++				   fib4->fi, fib4->tb_id,
+ 				   OFDPA_OP_FLAG_REMOVE);
+ }
+ 
+diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c
+index 1681084cc96f..1f309127457d 100644
+--- a/drivers/net/ethernet/sfc/ef10.c
++++ b/drivers/net/ethernet/sfc/ef10.c
+@@ -619,6 +619,17 @@ fail:
+ 	return rc;
+ }
+ 
++static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
++{
++	struct efx_channel *channel;
++	struct efx_tx_queue *tx_queue;
++
++	/* All our existing PIO buffers went away */
++	efx_for_each_channel(channel, efx)
++		efx_for_each_channel_tx_queue(tx_queue, channel)
++			tx_queue->piobuf = NULL;
++}
++
+ #else /* !EFX_USE_PIO */
+ 
+ static int efx_ef10_alloc_piobufs(struct efx_nic *efx, unsigned int n)
+@@ -635,6 +646,10 @@ static void efx_ef10_free_piobufs(struct efx_nic *efx)
+ {
+ }
+ 
++static void efx_ef10_forget_old_piobufs(struct efx_nic *efx)
++{
++}
++
+ #endif /* EFX_USE_PIO */
+ 
+ static void efx_ef10_remove(struct efx_nic *efx)
+@@ -1018,6 +1033,7 @@ static void efx_ef10_reset_mc_allocations(struct efx_nic *efx)
+ 	nic_data->must_realloc_vis = true;
+ 	nic_data->must_restore_filters = true;
+ 	nic_data->must_restore_piobufs = true;
++	efx_ef10_forget_old_piobufs(efx);
+ 	nic_data->rx_rss_context = EFX_EF10_RSS_CONTEXT_INVALID;
+ 
+ 	/* Driver-created vswitches and vports must be re-created */
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+index 06704ca6f9ca..8683a21690b5 100644
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+@@ -209,7 +209,7 @@ int stmmac_mdio_register(struct net_device *ndev)
+ 		return -ENOMEM;
+ 
+ 	if (mdio_bus_data->irqs)
+-		memcpy(new_bus->irq, mdio_bus_data, sizeof(new_bus->irq));
++		memcpy(new_bus->irq, mdio_bus_data->irqs, sizeof(new_bus->irq));
+ 
+ #ifdef CONFIG_OF
+ 	if (priv->device->of_node)
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 7b0a644122eb..9fcb4898fb68 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -336,15 +336,15 @@ static int geneve_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
+ 
+ 	/* Need Geneve and inner Ethernet header to be present */
+ 	if (unlikely(!pskb_may_pull(skb, GENEVE_BASE_HLEN)))
+-		goto error;
++		goto drop;
+ 
+ 	/* Return packets with reserved bits set */
+ 	geneveh = geneve_hdr(skb);
+ 	if (unlikely(geneveh->ver != GENEVE_VER))
+-		goto error;
++		goto drop;
+ 
+ 	if (unlikely(geneveh->proto_type != htons(ETH_P_TEB)))
+-		goto error;
++		goto drop;
+ 
+ 	gs = rcu_dereference_sk_user_data(sk);
+ 	if (!gs)
+@@ -367,10 +367,6 @@ drop:
+ 	/* Consume bad packet */
+ 	kfree_skb(skb);
+ 	return 0;
+-
+-error:
+-	/* Let the UDP layer deal with the skb */
+-	return 1;
+ }
+ 
+ static struct socket *geneve_create_sock(struct net *net, bool ipv6,
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 92eaab95ae2b..9e803bbcc0b6 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -1645,7 +1645,7 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info)
+ 	if (tb_sa[MACSEC_SA_ATTR_ACTIVE])
+ 		rx_sa->active = !!nla_get_u8(tb_sa[MACSEC_SA_ATTR_ACTIVE]);
+ 
+-	nla_memcpy(rx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEY], MACSEC_KEYID_LEN);
++	nla_memcpy(rx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN);
+ 	rx_sa->sc = rx_sc;
+ 	rcu_assign_pointer(rx_sc->sa[assoc_num], rx_sa);
+ 
+@@ -1784,7 +1784,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info)
+ 		return -ENOMEM;
+ 	}
+ 
+-	nla_memcpy(tx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEY], MACSEC_KEYID_LEN);
++	nla_memcpy(tx_sa->key.id, tb_sa[MACSEC_SA_ATTR_KEYID], MACSEC_KEYID_LEN);
+ 
+ 	spin_lock_bh(&tx_sa->lock);
+ 	tx_sa->next_pn = nla_get_u32(tb_sa[MACSEC_SA_ATTR_PN]);
+diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
+index a0f64cba86ba..2ace126533cd 100644
+--- a/drivers/net/team/team.c
++++ b/drivers/net/team/team.c
+@@ -990,7 +990,7 @@ static void team_port_disable(struct team *team,
+ #define TEAM_ENC_FEATURES	(NETIF_F_HW_CSUM | NETIF_F_SG | \
+ 				 NETIF_F_RXCSUM | NETIF_F_ALL_TSO)
+ 
+-static void __team_compute_features(struct team *team)
++static void ___team_compute_features(struct team *team)
+ {
+ 	struct team_port *port;
+ 	u32 vlan_features = TEAM_VLAN_FEATURES & NETIF_F_ALL_FOR_ALL;
+@@ -1021,15 +1021,20 @@ static void __team_compute_features(struct team *team)
+ 	team->dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+ 	if (dst_release_flag == (IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM))
+ 		team->dev->priv_flags |= IFF_XMIT_DST_RELEASE;
++}
+ 
++static void __team_compute_features(struct team *team)
++{
++	___team_compute_features(team);
+ 	netdev_change_features(team->dev);
+ }
+ 
+ static void team_compute_features(struct team *team)
+ {
+ 	mutex_lock(&team->lock);
+-	__team_compute_features(team);
++	___team_compute_features(team);
+ 	mutex_unlock(&team->lock);
++	netdev_change_features(team->dev);
+ }
+ 
+ static int team_port_enter(struct team *team, struct team_port *port)
+diff --git a/drivers/net/tun.c b/drivers/net/tun.c
+index 2c9e45f50edb..dda490542624 100644
+--- a/drivers/net/tun.c
++++ b/drivers/net/tun.c
+@@ -568,11 +568,13 @@ static void tun_detach_all(struct net_device *dev)
+ 	for (i = 0; i < n; i++) {
+ 		tfile = rtnl_dereference(tun->tfiles[i]);
+ 		BUG_ON(!tfile);
++		tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
+ 		tfile->socket.sk->sk_data_ready(tfile->socket.sk);
+ 		RCU_INIT_POINTER(tfile->tun, NULL);
+ 		--tun->numqueues;
+ 	}
+ 	list_for_each_entry(tfile, &tun->disabled, next) {
++		tfile->socket.sk->sk_shutdown = RCV_SHUTDOWN;
+ 		tfile->socket.sk->sk_data_ready(tfile->socket.sk);
+ 		RCU_INIT_POINTER(tfile->tun, NULL);
+ 	}
+@@ -628,6 +630,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file, bool skip_filte
+ 			goto out;
+ 	}
+ 	tfile->queue_index = tun->numqueues;
++	tfile->socket.sk->sk_shutdown &= ~RCV_SHUTDOWN;
+ 	rcu_assign_pointer(tfile->tun, tun);
+ 	rcu_assign_pointer(tun->tfiles[tun->numqueues], tfile);
+ 	tun->numqueues++;
+@@ -1425,9 +1428,6 @@ static ssize_t tun_do_read(struct tun_struct *tun, struct tun_file *tfile,
+ 	if (!iov_iter_count(to))
+ 		return 0;
+ 
+-	if (tun->dev->reg_state != NETREG_REGISTERED)
+-		return -EIO;
+-
+ 	/* Read frames from queue */
+ 	skb = __skb_recv_datagram(tfile->socket.sk, noblock ? MSG_DONTWAIT : 0,
+ 				  &peeked, &off, &err);
+diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
+index 8ac261ab7d7d..7e29b55015d0 100644
+--- a/drivers/net/vxlan.c
++++ b/drivers/net/vxlan.c
+@@ -1262,7 +1262,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
+ 
+ 	/* Need Vxlan and inner Ethernet header to be present */
+ 	if (!pskb_may_pull(skb, VXLAN_HLEN))
+-		return 1;
++		goto drop;
+ 
+ 	unparsed = *vxlan_hdr(skb);
+ 	/* VNI flag always required to be set */
+@@ -1271,7 +1271,7 @@ static int vxlan_rcv(struct sock *sk, struct sk_buff *skb)
+ 			   ntohl(vxlan_hdr(skb)->vx_flags),
+ 			   ntohl(vxlan_hdr(skb)->vx_vni));
+ 		/* Return non vxlan pkt */
+-		return 1;
++		goto drop;
+ 	}
+ 	unparsed.vx_flags &= ~VXLAN_HF_VNI;
+ 	unparsed.vx_vni &= ~VXLAN_VNI_MASK;
+@@ -2959,6 +2959,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
+ 	if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
+ 		conf.flags |= VXLAN_F_REMCSUM_NOPARTIAL;
+ 
++	if (tb[IFLA_MTU])
++		conf.mtu = nla_get_u32(tb[IFLA_MTU]);
++
+ 	err = vxlan_dev_configure(src_net, dev, &conf);
+ 	switch (err) {
+ 	case -ENODEV:
+diff --git a/drivers/perf/arm_pmu.c b/drivers/perf/arm_pmu.c
+index f70090897fdf..0e537fdc1d08 100644
+--- a/drivers/perf/arm_pmu.c
++++ b/drivers/perf/arm_pmu.c
+@@ -987,9 +987,6 @@ int arm_pmu_device_probe(struct platform_device *pdev,
+ 
+ 	armpmu_init(pmu);
+ 
+-	if (!__oprofile_cpu_pmu)
+-		__oprofile_cpu_pmu = pmu;
+-
+ 	pmu->plat_device = pdev;
+ 
+ 	if (node && (of_id = of_match_node(of_table, pdev->dev.of_node))) {
+@@ -1025,6 +1022,9 @@ int arm_pmu_device_probe(struct platform_device *pdev,
+ 	if (ret)
+ 		goto out_destroy;
+ 
++	if (!__oprofile_cpu_pmu)
++		__oprofile_cpu_pmu = pmu;
++
+ 	pr_info("enabled with %s PMU driver, %d counters available\n",
+ 			pmu->name, pmu->num_events);
+ 
+diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+index 6ab8c3ccdeea..fba2dd99ee95 100644
+--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c
+@@ -1256,9 +1256,10 @@ static void mtk_eint_irq_handler(struct irq_desc *desc)
+ 	const struct mtk_desc_pin *pin;
+ 
+ 	chained_irq_enter(chip, desc);
+-	for (eint_num = 0; eint_num < pctl->devdata->ap_num; eint_num += 32) {
++	for (eint_num = 0;
++	     eint_num < pctl->devdata->ap_num;
++	     eint_num += 32, reg += 4) {
+ 		status = readl(reg);
+-		reg += 4;
+ 		while (status) {
+ 			offset = __ffs(status);
+ 			index = eint_num + offset;
+diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
+index 3408578b08d6..ff41c310c900 100644
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -230,6 +230,7 @@ static struct {
+ 	{"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ 	{"Promise", "VTrak E610f", NULL, BLIST_SPARSELUN | BLIST_NO_RSOC},
+ 	{"Promise", "", NULL, BLIST_SPARSELUN},
++	{"QEMU", "QEMU CD-ROM", NULL, BLIST_SKIP_VPD_PAGES},
+ 	{"QNAP", "iSCSI Storage", NULL, BLIST_MAX_1024},
+ 	{"SYNOLOGY", "iSCSI Storage", NULL, BLIST_MAX_1024},
+ 	{"QUANTUM", "XP34301", "1071", BLIST_NOTQ},
+diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
+index 8106515d1df8..f704d02645f1 100644
+--- a/drivers/scsi/scsi_lib.c
++++ b/drivers/scsi/scsi_lib.c
+@@ -911,9 +911,12 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
+ 	}
+ 
+ 	/*
+-	 * If we finished all bytes in the request we are done now.
++	 * special case: failed zero length commands always need to
++	 * drop down into the retry code. Otherwise, if we finished
++	 * all bytes in the request we are done now.
+ 	 */
+-	if (!scsi_end_request(req, error, good_bytes, 0))
++	if (!(blk_rq_bytes(req) == 0 && error) &&
++	    !scsi_end_request(req, error, good_bytes, 0))
+ 		return;
+ 
+ 	/*
+diff --git a/fs/dcache.c b/fs/dcache.c
+index d5ecc6e477da..44008e3fafc4 100644
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1619,7 +1619,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
+ 	struct dentry *dentry = __d_alloc(parent->d_sb, name);
+ 	if (!dentry)
+ 		return NULL;
+-
++	dentry->d_flags |= DCACHE_RCUACCESS;
+ 	spin_lock(&parent->d_lock);
+ 	/*
+ 	 * don't need child lock because it is not subject
+@@ -2338,7 +2338,6 @@ static void __d_rehash(struct dentry * entry, struct hlist_bl_head *b)
+ {
+ 	BUG_ON(!d_unhashed(entry));
+ 	hlist_bl_lock(b);
+-	entry->d_flags |= DCACHE_RCUACCESS;
+ 	hlist_bl_add_head_rcu(&entry->d_hash, b);
+ 	hlist_bl_unlock(b);
+ }
+@@ -2637,6 +2636,7 @@ static void __d_move(struct dentry *dentry, struct dentry *target,
+ 	/* ... and switch them in the tree */
+ 	if (IS_ROOT(dentry)) {
+ 		/* splicing a tree */
++		dentry->d_flags |= DCACHE_RCUACCESS;
+ 		dentry->d_parent = target->d_parent;
+ 		target->d_parent = target;
+ 		list_del_init(&target->d_child);
+diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
+index 866bb18efefe..e818f5ac7a26 100644
+--- a/fs/ecryptfs/kthread.c
++++ b/fs/ecryptfs/kthread.c
+@@ -25,6 +25,7 @@
+ #include <linux/slab.h>
+ #include <linux/wait.h>
+ #include <linux/mount.h>
++#include <linux/file.h>
+ #include "ecryptfs_kernel.h"
+ 
+ struct ecryptfs_open_req {
+@@ -147,7 +148,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ 	flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
+ 	(*lower_file) = dentry_open(&req.path, flags, cred);
+ 	if (!IS_ERR(*lower_file))
+-		goto out;
++		goto have_file;
+ 	if ((flags & O_ACCMODE) == O_RDONLY) {
+ 		rc = PTR_ERR((*lower_file));
+ 		goto out;
+@@ -165,8 +166,16 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ 	mutex_unlock(&ecryptfs_kthread_ctl.mux);
+ 	wake_up(&ecryptfs_kthread_ctl.wait);
+ 	wait_for_completion(&req.done);
+-	if (IS_ERR(*lower_file))
++	if (IS_ERR(*lower_file)) {
+ 		rc = PTR_ERR(*lower_file);
++		goto out;
++	}
++have_file:
++	if ((*lower_file)->f_op->mmap == NULL) {
++		fput(*lower_file);
++		*lower_file = NULL;
++		rc = -EMEDIUMTYPE;
++	}
+ out:
+ 	return rc;
+ }
+diff --git a/fs/proc/root.c b/fs/proc/root.c
+index 361ab4ee42fc..ec649c92d270 100644
+--- a/fs/proc/root.c
++++ b/fs/proc/root.c
+@@ -121,6 +121,13 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
+ 	if (IS_ERR(sb))
+ 		return ERR_CAST(sb);
+ 
++	/*
++	 * procfs isn't actually a stacking filesystem; however, there is
++	 * too much magic going on inside it to permit stacking things on
++	 * top of it
++	 */
++	sb->s_stack_depth = FILESYSTEM_MAX_STACK_DEPTH;
++
+ 	if (!proc_parse_options(options, ns)) {
+ 		deactivate_locked_super(sb);
+ 		return ERR_PTR(-EINVAL);
+diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h
+index d5d798b35c1f..e98425058f20 100644
+--- a/include/linux/irqchip/arm-gic-v3.h
++++ b/include/linux/irqchip/arm-gic-v3.h
+@@ -301,7 +301,7 @@
+ #define ICC_SGI1R_AFFINITY_1_SHIFT	16
+ #define ICC_SGI1R_AFFINITY_1_MASK	(0xff << ICC_SGI1R_AFFINITY_1_SHIFT)
+ #define ICC_SGI1R_SGI_ID_SHIFT		24
+-#define ICC_SGI1R_SGI_ID_MASK		(0xff << ICC_SGI1R_SGI_ID_SHIFT)
++#define ICC_SGI1R_SGI_ID_MASK		(0xfULL << ICC_SGI1R_SGI_ID_SHIFT)
+ #define ICC_SGI1R_AFFINITY_2_SHIFT	32
+ #define ICC_SGI1R_AFFINITY_2_MASK	(0xffULL << ICC_SGI1R_AFFINITY_1_SHIFT)
+ #define ICC_SGI1R_IRQ_ROUTING_MODE_BIT	40
+diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
+index 80a305b85323..4dd9306c9d56 100644
+--- a/include/linux/netfilter/x_tables.h
++++ b/include/linux/netfilter/x_tables.h
+@@ -242,11 +242,18 @@ void xt_unregister_match(struct xt_match *target);
+ int xt_register_matches(struct xt_match *match, unsigned int n);
+ void xt_unregister_matches(struct xt_match *match, unsigned int n);
+ 
++int xt_check_entry_offsets(const void *base, const char *elems,
++			   unsigned int target_offset,
++			   unsigned int next_offset);
++
+ int xt_check_match(struct xt_mtchk_param *, unsigned int size, u_int8_t proto,
+ 		   bool inv_proto);
+ int xt_check_target(struct xt_tgchk_param *, unsigned int size, u_int8_t proto,
+ 		    bool inv_proto);
+ 
++void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
++				 struct xt_counters_info *info, bool compat);
++
+ struct xt_table *xt_register_table(struct net *net,
+ 				   const struct xt_table *table,
+ 				   struct xt_table_info *bootstrap,
+@@ -480,7 +487,7 @@ void xt_compat_init_offsets(u_int8_t af, unsigned int number);
+ int xt_compat_calc_jump(u_int8_t af, unsigned int offset);
+ 
+ int xt_compat_match_offset(const struct xt_match *match);
+-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
++void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+ 			      unsigned int *size);
+ int xt_compat_match_to_user(const struct xt_entry_match *m,
+ 			    void __user **dstptr, unsigned int *size);
+@@ -490,6 +497,9 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
+ 				unsigned int *size);
+ int xt_compat_target_to_user(const struct xt_entry_target *t,
+ 			     void __user **dstptr, unsigned int *size);
++int xt_compat_check_entry_offsets(const void *base, const char *elems,
++				  unsigned int target_offset,
++				  unsigned int next_offset);
+ 
+ #endif /* CONFIG_COMPAT */
+ #endif /* _X_TABLES_H */
+diff --git a/include/net/switchdev.h b/include/net/switchdev.h
+index 51d77b2ce2b2..985619a59323 100644
+--- a/include/net/switchdev.h
++++ b/include/net/switchdev.h
+@@ -97,7 +97,7 @@ struct switchdev_obj_ipv4_fib {
+ 	struct switchdev_obj obj;
+ 	u32 dst;
+ 	int dst_len;
+-	struct fib_info fi;
++	struct fib_info *fi;
+ 	u8 tos;
+ 	u8 type;
+ 	u32 nlflags;
+diff --git a/include/uapi/linux/libc-compat.h b/include/uapi/linux/libc-compat.h
+index d5e38c73377c..e4f048ee7043 100644
+--- a/include/uapi/linux/libc-compat.h
++++ b/include/uapi/linux/libc-compat.h
+@@ -52,7 +52,7 @@
+ #if defined(__GLIBC__)
+ 
+ /* Coordinate with glibc net/if.h header. */
+-#if defined(_NET_IF_H)
++#if defined(_NET_IF_H) && defined(__USE_MISC)
+ 
+ /* GLIBC headers included first so don't define anything
+  * that would already be defined. */
+diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c
+index 8f94ca1860cf..b2aefa2d123a 100644
+--- a/kernel/bpf/inode.c
++++ b/kernel/bpf/inode.c
+@@ -378,7 +378,7 @@ static int bpf_fill_super(struct super_block *sb, void *data, int silent)
+ static struct dentry *bpf_mount(struct file_system_type *type, int flags,
+ 				const char *dev_name, void *data)
+ {
+-	return mount_ns(type, flags, current->nsproxy->mnt_ns, bpf_fill_super);
++	return mount_nodev(type, flags, data, bpf_fill_super);
+ }
+ 
+ static struct file_system_type bpf_fs_type = {
+@@ -386,7 +386,6 @@ static struct file_system_type bpf_fs_type = {
+ 	.name		= "bpf",
+ 	.mount		= bpf_mount,
+ 	.kill_sb	= kill_litter_super,
+-	.fs_flags	= FS_USERNS_MOUNT,
+ };
+ 
+ MODULE_ALIAS_FS("bpf");
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index d1f7149f8704..11546a6ed5df 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -3047,7 +3047,8 @@ static noinline void __schedule_bug(struct task_struct *prev)
+ static inline void schedule_debug(struct task_struct *prev)
+ {
+ #ifdef CONFIG_SCHED_STACK_END_CHECK
+-	BUG_ON(task_stack_end_corrupted(prev));
++	if (task_stack_end_corrupted(prev))
++		panic("corrupted stack end detected inside scheduler\n");
+ #endif
+ 
+ 	if (unlikely(in_atomic_preempt_off())) {
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
+index 3e4ffb3ace5f..d0289414cdeb 100644
+--- a/kernel/trace/bpf_trace.c
++++ b/kernel/trace/bpf_trace.c
+@@ -194,7 +194,7 @@ static u64 bpf_perf_event_read(u64 r1, u64 index, u64 r3, u64 r4, u64 r5)
+ 	if (unlikely(index >= array->map.max_entries))
+ 		return -E2BIG;
+ 
+-	file = (struct file *)array->ptrs[index];
++	file = READ_ONCE(array->ptrs[index]);
+ 	if (unlikely(!file))
+ 		return -ENOENT;
+ 
+@@ -238,7 +238,7 @@ static u64 bpf_perf_event_output(u64 r1, u64 r2, u64 index, u64 r4, u64 size)
+ 	if (unlikely(index >= array->map.max_entries))
+ 		return -E2BIG;
+ 
+-	file = (struct file *)array->ptrs[index];
++	file = READ_ONCE(array->ptrs[index]);
+ 	if (unlikely(!file))
+ 		return -ENOENT;
+ 
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index fe787f5c41bd..a2e79b83920f 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -2877,6 +2877,7 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
+ 	 * ordering is imposed by list_lru_node->lock taken by
+ 	 * memcg_drain_all_list_lrus().
+ 	 */
++	rcu_read_lock(); /* can be called from css_free w/o cgroup_mutex */
+ 	css_for_each_descendant_pre(css, &memcg->css) {
+ 		child = mem_cgroup_from_css(css);
+ 		BUG_ON(child->kmemcg_id != kmemcg_id);
+@@ -2884,6 +2885,8 @@ static void memcg_offline_kmem(struct mem_cgroup *memcg)
+ 		if (!memcg->use_hierarchy)
+ 			break;
+ 	}
++	rcu_read_unlock();
++
+ 	memcg_drain_all_list_lrus(kmemcg_id, parent->kmemcg_id);
+ 
+ 	memcg_free_cache_id(kmemcg_id);
+diff --git a/mm/swap_state.c b/mm/swap_state.c
+index 366ce3518703..1155a6831a3d 100644
+--- a/mm/swap_state.c
++++ b/mm/swap_state.c
+@@ -252,7 +252,10 @@ static inline void free_swap_cache(struct page *page)
+ void free_page_and_swap_cache(struct page *page)
+ {
+ 	free_swap_cache(page);
+-	put_page(page);
++	if (is_huge_zero_page(page))
++		put_huge_zero_page();
++	else
++		put_page(page);
+ }
+ 
+ /*
+diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c
+index dcea4f4c62b3..c18080ad4085 100644
+--- a/net/bridge/br_fdb.c
++++ b/net/bridge/br_fdb.c
+@@ -279,6 +279,8 @@ void br_fdb_change_mac_address(struct net_bridge *br, const u8 *newaddr)
+ 	 * change from under us.
+ 	 */
+ 	list_for_each_entry(v, &vg->vlan_list, vlist) {
++		if (!br_vlan_should_use(v))
++			continue;
+ 		f = __br_fdb_get(br, br->dev->dev_addr, v->vid);
+ 		if (f && f->is_local && !f->dst)
+ 			fdb_delete_local(br, NULL, f);
+diff --git a/net/core/hwbm.c b/net/core/hwbm.c
+index 941c28486896..2cab489ae62e 100644
+--- a/net/core/hwbm.c
++++ b/net/core/hwbm.c
+@@ -55,18 +55,21 @@ int hwbm_pool_add(struct hwbm_pool *bm_pool, unsigned int buf_num, gfp_t gfp)
+ 	spin_lock_irqsave(&bm_pool->lock, flags);
+ 	if (bm_pool->buf_num == bm_pool->size) {
+ 		pr_warn("pool already filled\n");
++		spin_unlock_irqrestore(&bm_pool->lock, flags);
+ 		return bm_pool->buf_num;
+ 	}
+ 
+ 	if (buf_num + bm_pool->buf_num > bm_pool->size) {
+ 		pr_warn("cannot allocate %d buffers for pool\n",
+ 			buf_num);
++		spin_unlock_irqrestore(&bm_pool->lock, flags);
+ 		return 0;
+ 	}
+ 
+ 	if ((buf_num + bm_pool->buf_num) < bm_pool->buf_num) {
+ 		pr_warn("Adding %d buffers to the %d current buffers will overflow\n",
+ 			buf_num,  bm_pool->buf_num);
++		spin_unlock_irqrestore(&bm_pool->lock, flags);
+ 		return 0;
+ 	}
+ 
+diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
+index 9e481992dbae..7ad0e567cf10 100644
+--- a/net/ipv4/af_inet.c
++++ b/net/ipv4/af_inet.c
+@@ -1660,6 +1660,14 @@ static __net_init int inet_init_net(struct net *net)
+ 	 */
+ 	net->ipv4.ping_group_range.range[0] = make_kgid(&init_user_ns, 1);
+ 	net->ipv4.ping_group_range.range[1] = make_kgid(&init_user_ns, 0);
++
++	/* Default values for sysctl-controlled parameters.
++	 * We set them here, in case sysctl is not compiled.
++	 */
++	net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
++	net->ipv4.sysctl_ip_dynaddr = 0;
++	net->ipv4.sysctl_ip_early_demux = 1;
++
+ 	return 0;
+ }
+ 
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index 4133b0f513af..85d60c69bfe3 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -367,6 +367,18 @@ static inline bool unconditional(const struct arpt_entry *e)
+ 	       memcmp(&e->arp, &uncond, sizeof(uncond)) == 0;
+ }
+ 
++static bool find_jump_target(const struct xt_table_info *t,
++			     const struct arpt_entry *target)
++{
++	struct arpt_entry *iter;
++
++	xt_entry_foreach(iter, t->entries, t->size) {
++		 if (iter == target)
++			return true;
++	}
++	return false;
++}
++
+ /* Figures out from what hook each rule can be called: returns 0 if
+  * there are loops.  Puts hook bitmask in comefrom.
+  */
+@@ -439,6 +451,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
+ 				size = e->next_offset;
+ 				e = (struct arpt_entry *)
+ 					(entry0 + pos + size);
++				if (pos + size >= newinfo->size)
++					return 0;
+ 				e->counters.pcnt = pos;
+ 				pos += size;
+ 			} else {
+@@ -458,9 +472,15 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
+ 					/* This a jump; chase it. */
+ 					duprintf("Jump rule %u -> %u\n",
+ 						 pos, newpos);
++					e = (struct arpt_entry *)
++						(entry0 + newpos);
++					if (!find_jump_target(newinfo, e))
++						return 0;
+ 				} else {
+ 					/* ... this is a fallthru */
+ 					newpos = pos + e->next_offset;
++					if (newpos >= newinfo->size)
++						return 0;
+ 				}
+ 				e = (struct arpt_entry *)
+ 					(entry0 + newpos);
+@@ -474,23 +494,6 @@ next:
+ 	return 1;
+ }
+ 
+-static inline int check_entry(const struct arpt_entry *e)
+-{
+-	const struct xt_entry_target *t;
+-
+-	if (!arp_checkentry(&e->arp))
+-		return -EINVAL;
+-
+-	if (e->target_offset + sizeof(struct xt_entry_target) > e->next_offset)
+-		return -EINVAL;
+-
+-	t = arpt_get_target_c(e);
+-	if (e->target_offset + t->u.target_size > e->next_offset)
+-		return -EINVAL;
+-
+-	return 0;
+-}
+-
+ static inline int check_target(struct arpt_entry *e, const char *name)
+ {
+ 	struct xt_entry_target *t = arpt_get_target(e);
+@@ -586,7 +589,11 @@ static inline int check_entry_size_and_hooks(struct arpt_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	err = check_entry(e);
++	if (!arp_checkentry(&e->arp))
++		return -EINVAL;
++
++	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
++				     e->next_offset);
+ 	if (err)
+ 		return err;
+ 
+@@ -691,10 +698,8 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
+ 		}
+ 	}
+ 
+-	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) {
+-		duprintf("Looping hook\n");
++	if (!mark_source_chains(newinfo, repl->valid_hooks, entry0))
+ 		return -ELOOP;
+-	}
+ 
+ 	/* Finally, each sanity check must pass */
+ 	i = 0;
+@@ -1126,55 +1131,17 @@ static int do_add_counters(struct net *net, const void __user *user,
+ 	unsigned int i;
+ 	struct xt_counters_info tmp;
+ 	struct xt_counters *paddc;
+-	unsigned int num_counters;
+-	const char *name;
+-	int size;
+-	void *ptmp;
+ 	struct xt_table *t;
+ 	const struct xt_table_info *private;
+ 	int ret = 0;
+ 	struct arpt_entry *iter;
+ 	unsigned int addend;
+-#ifdef CONFIG_COMPAT
+-	struct compat_xt_counters_info compat_tmp;
+ 
+-	if (compat) {
+-		ptmp = &compat_tmp;
+-		size = sizeof(struct compat_xt_counters_info);
+-	} else
+-#endif
+-	{
+-		ptmp = &tmp;
+-		size = sizeof(struct xt_counters_info);
+-	}
++	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
++	if (IS_ERR(paddc))
++		return PTR_ERR(paddc);
+ 
+-	if (copy_from_user(ptmp, user, size) != 0)
+-		return -EFAULT;
+-
+-#ifdef CONFIG_COMPAT
+-	if (compat) {
+-		num_counters = compat_tmp.num_counters;
+-		name = compat_tmp.name;
+-	} else
+-#endif
+-	{
+-		num_counters = tmp.num_counters;
+-		name = tmp.name;
+-	}
+-
+-	if (len != size + num_counters * sizeof(struct xt_counters))
+-		return -EINVAL;
+-
+-	paddc = vmalloc(len - size);
+-	if (!paddc)
+-		return -ENOMEM;
+-
+-	if (copy_from_user(paddc, user + size, len - size) != 0) {
+-		ret = -EFAULT;
+-		goto free;
+-	}
+-
+-	t = xt_find_table_lock(net, NFPROTO_ARP, name);
++	t = xt_find_table_lock(net, NFPROTO_ARP, tmp.name);
+ 	if (IS_ERR_OR_NULL(t)) {
+ 		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free;
+@@ -1182,7 +1149,7 @@ static int do_add_counters(struct net *net, const void __user *user,
+ 
+ 	local_bh_disable();
+ 	private = t->private;
+-	if (private->number != num_counters) {
++	if (private->number != tmp.num_counters) {
+ 		ret = -EINVAL;
+ 		goto unlock_up_free;
+ 	}
+@@ -1209,6 +1176,18 @@ static int do_add_counters(struct net *net, const void __user *user,
+ }
+ 
+ #ifdef CONFIG_COMPAT
++struct compat_arpt_replace {
++	char				name[XT_TABLE_MAXNAMELEN];
++	u32				valid_hooks;
++	u32				num_entries;
++	u32				size;
++	u32				hook_entry[NF_ARP_NUMHOOKS];
++	u32				underflow[NF_ARP_NUMHOOKS];
++	u32				num_counters;
++	compat_uptr_t			counters;
++	struct compat_arpt_entry	entries[0];
++};
++
+ static inline void compat_release_entry(struct compat_arpt_entry *e)
+ {
+ 	struct xt_entry_target *t;
+@@ -1217,20 +1196,17 @@ static inline void compat_release_entry(struct compat_arpt_entry *e)
+ 	module_put(t->u.kernel.target->me);
+ }
+ 
+-static inline int
++static int
+ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
+ 				  struct xt_table_info *newinfo,
+ 				  unsigned int *size,
+ 				  const unsigned char *base,
+-				  const unsigned char *limit,
+-				  const unsigned int *hook_entries,
+-				  const unsigned int *underflows,
+-				  const char *name)
++				  const unsigned char *limit)
+ {
+ 	struct xt_entry_target *t;
+ 	struct xt_target *target;
+ 	unsigned int entry_offset;
+-	int ret, off, h;
++	int ret, off;
+ 
+ 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
+ 	if ((unsigned long)e % __alignof__(struct compat_arpt_entry) != 0 ||
+@@ -1247,8 +1223,11 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	/* For purposes of check_entry casting the compat entry is fine */
+-	ret = check_entry((struct arpt_entry *)e);
++	if (!arp_checkentry(&e->arp))
++		return -EINVAL;
++
++	ret = xt_compat_check_entry_offsets(e, e->elems, e->target_offset,
++					    e->next_offset);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -1272,17 +1251,6 @@ check_compat_entry_size_and_hooks(struct compat_arpt_entry *e,
+ 	if (ret)
+ 		goto release_target;
+ 
+-	/* Check hooks & underflows */
+-	for (h = 0; h < NF_ARP_NUMHOOKS; h++) {
+-		if ((unsigned char *)e - base == hook_entries[h])
+-			newinfo->hook_entry[h] = hook_entries[h];
+-		if ((unsigned char *)e - base == underflows[h])
+-			newinfo->underflow[h] = underflows[h];
+-	}
+-
+-	/* Clear counters and comefrom */
+-	memset(&e->counters, 0, sizeof(e->counters));
+-	e->comefrom = 0;
+ 	return 0;
+ 
+ release_target:
+@@ -1291,18 +1259,17 @@ out:
+ 	return ret;
+ }
+ 
+-static int
++static void
+ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
+-			    unsigned int *size, const char *name,
++			    unsigned int *size,
+ 			    struct xt_table_info *newinfo, unsigned char *base)
+ {
+ 	struct xt_entry_target *t;
+ 	struct xt_target *target;
+ 	struct arpt_entry *de;
+ 	unsigned int origsize;
+-	int ret, h;
++	int h;
+ 
+-	ret = 0;
+ 	origsize = *size;
+ 	de = (struct arpt_entry *)*dstptr;
+ 	memcpy(de, e, sizeof(struct arpt_entry));
+@@ -1323,148 +1290,82 @@ compat_copy_entry_from_user(struct compat_arpt_entry *e, void **dstptr,
+ 		if ((unsigned char *)de - base < newinfo->underflow[h])
+ 			newinfo->underflow[h] -= origsize - *size;
+ 	}
+-	return ret;
+ }
+ 
+-static int translate_compat_table(const char *name,
+-				  unsigned int valid_hooks,
+-				  struct xt_table_info **pinfo,
++static int translate_compat_table(struct xt_table_info **pinfo,
+ 				  void **pentry0,
+-				  unsigned int total_size,
+-				  unsigned int number,
+-				  unsigned int *hook_entries,
+-				  unsigned int *underflows)
++				  const struct compat_arpt_replace *compatr)
+ {
+ 	unsigned int i, j;
+ 	struct xt_table_info *newinfo, *info;
+ 	void *pos, *entry0, *entry1;
+ 	struct compat_arpt_entry *iter0;
+-	struct arpt_entry *iter1;
++	struct arpt_replace repl;
+ 	unsigned int size;
+ 	int ret = 0;
+ 
+ 	info = *pinfo;
+ 	entry0 = *pentry0;
+-	size = total_size;
+-	info->number = number;
+-
+-	/* Init all hooks to impossible value. */
+-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+-		info->hook_entry[i] = 0xFFFFFFFF;
+-		info->underflow[i] = 0xFFFFFFFF;
+-	}
++	size = compatr->size;
++	info->number = compatr->num_entries;
+ 
+ 	duprintf("translate_compat_table: size %u\n", info->size);
+ 	j = 0;
+ 	xt_compat_lock(NFPROTO_ARP);
+-	xt_compat_init_offsets(NFPROTO_ARP, number);
++	xt_compat_init_offsets(NFPROTO_ARP, compatr->num_entries);
+ 	/* Walk through entries, checking offsets. */
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+ 							entry0,
+-							entry0 + total_size,
+-							hook_entries,
+-							underflows,
+-							name);
++							entry0 + compatr->size);
+ 		if (ret != 0)
+ 			goto out_unlock;
+ 		++j;
+ 	}
+ 
+ 	ret = -EINVAL;
+-	if (j != number) {
++	if (j != compatr->num_entries) {
+ 		duprintf("translate_compat_table: %u not %u entries\n",
+-			 j, number);
++			 j, compatr->num_entries);
+ 		goto out_unlock;
+ 	}
+ 
+-	/* Check hooks all assigned */
+-	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+-		/* Only hooks which are valid */
+-		if (!(valid_hooks & (1 << i)))
+-			continue;
+-		if (info->hook_entry[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid hook entry %u %u\n",
+-				 i, hook_entries[i]);
+-			goto out_unlock;
+-		}
+-		if (info->underflow[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid underflow %u %u\n",
+-				 i, underflows[i]);
+-			goto out_unlock;
+-		}
+-	}
+-
+ 	ret = -ENOMEM;
+ 	newinfo = xt_alloc_table_info(size);
+ 	if (!newinfo)
+ 		goto out_unlock;
+ 
+-	newinfo->number = number;
++	newinfo->number = compatr->num_entries;
+ 	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
+ 		newinfo->hook_entry[i] = info->hook_entry[i];
+ 		newinfo->underflow[i] = info->underflow[i];
+ 	}
+ 	entry1 = newinfo->entries;
+ 	pos = entry1;
+-	size = total_size;
+-	xt_entry_foreach(iter0, entry0, total_size) {
+-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
+-						  name, newinfo, entry1);
+-		if (ret != 0)
+-			break;
+-	}
++	size = compatr->size;
++	xt_entry_foreach(iter0, entry0, compatr->size)
++		compat_copy_entry_from_user(iter0, &pos, &size,
++					    newinfo, entry1);
++
++	/* all module references in entry0 are now gone */
++
+ 	xt_compat_flush_offsets(NFPROTO_ARP);
+ 	xt_compat_unlock(NFPROTO_ARP);
+-	if (ret)
+-		goto free_newinfo;
+ 
+-	ret = -ELOOP;
+-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+-		goto free_newinfo;
++	memcpy(&repl, compatr, sizeof(*compatr));
+ 
+-	i = 0;
+-	xt_entry_foreach(iter1, entry1, newinfo->size) {
+-		iter1->counters.pcnt = xt_percpu_counter_alloc();
+-		if (IS_ERR_VALUE(iter1->counters.pcnt)) {
+-			ret = -ENOMEM;
+-			break;
+-		}
+-
+-		ret = check_target(iter1, name);
+-		if (ret != 0) {
+-			xt_percpu_counter_free(iter1->counters.pcnt);
+-			break;
+-		}
+-		++i;
+-		if (strcmp(arpt_get_target(iter1)->u.user.name,
+-		    XT_ERROR_TARGET) == 0)
+-			++newinfo->stacksize;
+-	}
+-	if (ret) {
+-		/*
+-		 * The first i matches need cleanup_entry (calls ->destroy)
+-		 * because they had called ->check already. The other j-i
+-		 * entries need only release.
+-		 */
+-		int skip = i;
+-		j -= i;
+-		xt_entry_foreach(iter0, entry0, newinfo->size) {
+-			if (skip-- > 0)
+-				continue;
+-			if (j-- == 0)
+-				break;
+-			compat_release_entry(iter0);
+-		}
+-		xt_entry_foreach(iter1, entry1, newinfo->size) {
+-			if (i-- == 0)
+-				break;
+-			cleanup_entry(iter1);
+-		}
+-		xt_free_table_info(newinfo);
+-		return ret;
++	for (i = 0; i < NF_ARP_NUMHOOKS; i++) {
++		repl.hook_entry[i] = newinfo->hook_entry[i];
++		repl.underflow[i] = newinfo->underflow[i];
+ 	}
+ 
++	repl.num_counters = 0;
++	repl.counters = NULL;
++	repl.size = newinfo->size;
++	ret = translate_table(newinfo, entry1, &repl);
++	if (ret)
++		goto free_newinfo;
++
+ 	*pinfo = newinfo;
+ 	*pentry0 = entry1;
+ 	xt_free_table_info(info);
+@@ -1472,31 +1373,18 @@ static int translate_compat_table(const char *name,
+ 
+ free_newinfo:
+ 	xt_free_table_info(newinfo);
+-out:
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	return ret;
++out_unlock:
++	xt_compat_flush_offsets(NFPROTO_ARP);
++	xt_compat_unlock(NFPROTO_ARP);
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		if (j-- == 0)
+ 			break;
+ 		compat_release_entry(iter0);
+ 	}
+ 	return ret;
+-out_unlock:
+-	xt_compat_flush_offsets(NFPROTO_ARP);
+-	xt_compat_unlock(NFPROTO_ARP);
+-	goto out;
+ }
+ 
+-struct compat_arpt_replace {
+-	char				name[XT_TABLE_MAXNAMELEN];
+-	u32				valid_hooks;
+-	u32				num_entries;
+-	u32				size;
+-	u32				hook_entry[NF_ARP_NUMHOOKS];
+-	u32				underflow[NF_ARP_NUMHOOKS];
+-	u32				num_counters;
+-	compat_uptr_t			counters;
+-	struct compat_arpt_entry	entries[0];
+-};
+-
+ static int compat_do_replace(struct net *net, void __user *user,
+ 			     unsigned int len)
+ {
+@@ -1529,10 +1417,7 @@ static int compat_do_replace(struct net *net, void __user *user,
+ 		goto free_newinfo;
+ 	}
+ 
+-	ret = translate_compat_table(tmp.name, tmp.valid_hooks,
+-				     &newinfo, &loc_cpu_entry, tmp.size,
+-				     tmp.num_entries, tmp.hook_entry,
+-				     tmp.underflow);
++	ret = translate_compat_table(&newinfo, &loc_cpu_entry, &tmp);
+ 	if (ret != 0)
+ 		goto free_newinfo;
+ 
+diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
+index 631c100a1338..0984ea3fcf14 100644
+--- a/net/ipv4/netfilter/ip_tables.c
++++ b/net/ipv4/netfilter/ip_tables.c
+@@ -443,6 +443,18 @@ ipt_do_table(struct sk_buff *skb,
+ #endif
+ }
+ 
++static bool find_jump_target(const struct xt_table_info *t,
++			     const struct ipt_entry *target)
++{
++	struct ipt_entry *iter;
++
++	xt_entry_foreach(iter, t->entries, t->size) {
++		 if (iter == target)
++			return true;
++	}
++	return false;
++}
++
+ /* Figures out from what hook each rule can be called: returns 0 if
+    there are loops.  Puts hook bitmask in comefrom. */
+ static int
+@@ -520,6 +532,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
+ 				size = e->next_offset;
+ 				e = (struct ipt_entry *)
+ 					(entry0 + pos + size);
++				if (pos + size >= newinfo->size)
++					return 0;
+ 				e->counters.pcnt = pos;
+ 				pos += size;
+ 			} else {
+@@ -538,9 +552,15 @@ mark_source_chains(const struct xt_table_info *newinfo,
+ 					/* This a jump; chase it. */
+ 					duprintf("Jump rule %u -> %u\n",
+ 						 pos, newpos);
++					e = (struct ipt_entry *)
++						(entry0 + newpos);
++					if (!find_jump_target(newinfo, e))
++						return 0;
+ 				} else {
+ 					/* ... this is a fallthru */
+ 					newpos = pos + e->next_offset;
++					if (newpos >= newinfo->size)
++						return 0;
+ 				}
+ 				e = (struct ipt_entry *)
+ 					(entry0 + newpos);
+@@ -568,25 +588,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
+ }
+ 
+ static int
+-check_entry(const struct ipt_entry *e)
+-{
+-	const struct xt_entry_target *t;
+-
+-	if (!ip_checkentry(&e->ip))
+-		return -EINVAL;
+-
+-	if (e->target_offset + sizeof(struct xt_entry_target) >
+-	    e->next_offset)
+-		return -EINVAL;
+-
+-	t = ipt_get_target_c(e);
+-	if (e->target_offset + t->u.target_size > e->next_offset)
+-		return -EINVAL;
+-
+-	return 0;
+-}
+-
+-static int
+ check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
+ {
+ 	const struct ipt_ip *ip = par->entryinfo;
+@@ -750,7 +751,11 @@ check_entry_size_and_hooks(struct ipt_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	err = check_entry(e);
++	if (!ip_checkentry(&e->ip))
++		return -EINVAL;
++
++	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
++				     e->next_offset);
+ 	if (err)
+ 		return err;
+ 
+@@ -1309,55 +1314,17 @@ do_add_counters(struct net *net, const void __user *user,
+ 	unsigned int i;
+ 	struct xt_counters_info tmp;
+ 	struct xt_counters *paddc;
+-	unsigned int num_counters;
+-	const char *name;
+-	int size;
+-	void *ptmp;
+ 	struct xt_table *t;
+ 	const struct xt_table_info *private;
+ 	int ret = 0;
+ 	struct ipt_entry *iter;
+ 	unsigned int addend;
+-#ifdef CONFIG_COMPAT
+-	struct compat_xt_counters_info compat_tmp;
+ 
+-	if (compat) {
+-		ptmp = &compat_tmp;
+-		size = sizeof(struct compat_xt_counters_info);
+-	} else
+-#endif
+-	{
+-		ptmp = &tmp;
+-		size = sizeof(struct xt_counters_info);
+-	}
+-
+-	if (copy_from_user(ptmp, user, size) != 0)
+-		return -EFAULT;
+-
+-#ifdef CONFIG_COMPAT
+-	if (compat) {
+-		num_counters = compat_tmp.num_counters;
+-		name = compat_tmp.name;
+-	} else
+-#endif
+-	{
+-		num_counters = tmp.num_counters;
+-		name = tmp.name;
+-	}
++	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
++	if (IS_ERR(paddc))
++		return PTR_ERR(paddc);
+ 
+-	if (len != size + num_counters * sizeof(struct xt_counters))
+-		return -EINVAL;
+-
+-	paddc = vmalloc(len - size);
+-	if (!paddc)
+-		return -ENOMEM;
+-
+-	if (copy_from_user(paddc, user + size, len - size) != 0) {
+-		ret = -EFAULT;
+-		goto free;
+-	}
+-
+-	t = xt_find_table_lock(net, AF_INET, name);
++	t = xt_find_table_lock(net, AF_INET, tmp.name);
+ 	if (IS_ERR_OR_NULL(t)) {
+ 		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free;
+@@ -1365,7 +1332,7 @@ do_add_counters(struct net *net, const void __user *user,
+ 
+ 	local_bh_disable();
+ 	private = t->private;
+-	if (private->number != num_counters) {
++	if (private->number != tmp.num_counters) {
+ 		ret = -EINVAL;
+ 		goto unlock_up_free;
+ 	}
+@@ -1444,7 +1411,6 @@ compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr,
+ 
+ static int
+ compat_find_calc_match(struct xt_entry_match *m,
+-		       const char *name,
+ 		       const struct ipt_ip *ip,
+ 		       int *size)
+ {
+@@ -1479,17 +1445,14 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
+ 				  struct xt_table_info *newinfo,
+ 				  unsigned int *size,
+ 				  const unsigned char *base,
+-				  const unsigned char *limit,
+-				  const unsigned int *hook_entries,
+-				  const unsigned int *underflows,
+-				  const char *name)
++				  const unsigned char *limit)
+ {
+ 	struct xt_entry_match *ematch;
+ 	struct xt_entry_target *t;
+ 	struct xt_target *target;
+ 	unsigned int entry_offset;
+ 	unsigned int j;
+-	int ret, off, h;
++	int ret, off;
+ 
+ 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
+ 	if ((unsigned long)e % __alignof__(struct compat_ipt_entry) != 0 ||
+@@ -1506,8 +1469,11 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	/* For purposes of check_entry casting the compat entry is fine */
+-	ret = check_entry((struct ipt_entry *)e);
++	if (!ip_checkentry(&e->ip))
++		return -EINVAL;
++
++	ret = xt_compat_check_entry_offsets(e, e->elems,
++					    e->target_offset, e->next_offset);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -1515,7 +1481,7 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
+ 	entry_offset = (void *)e - (void *)base;
+ 	j = 0;
+ 	xt_ematch_foreach(ematch, e) {
+-		ret = compat_find_calc_match(ematch, name, &e->ip, &off);
++		ret = compat_find_calc_match(ematch, &e->ip, &off);
+ 		if (ret != 0)
+ 			goto release_matches;
+ 		++j;
+@@ -1538,17 +1504,6 @@ check_compat_entry_size_and_hooks(struct compat_ipt_entry *e,
+ 	if (ret)
+ 		goto out;
+ 
+-	/* Check hooks & underflows */
+-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+-		if ((unsigned char *)e - base == hook_entries[h])
+-			newinfo->hook_entry[h] = hook_entries[h];
+-		if ((unsigned char *)e - base == underflows[h])
+-			newinfo->underflow[h] = underflows[h];
+-	}
+-
+-	/* Clear counters and comefrom */
+-	memset(&e->counters, 0, sizeof(e->counters));
+-	e->comefrom = 0;
+ 	return 0;
+ 
+ out:
+@@ -1562,19 +1517,18 @@ release_matches:
+ 	return ret;
+ }
+ 
+-static int
++static void
+ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
+-			    unsigned int *size, const char *name,
++			    unsigned int *size,
+ 			    struct xt_table_info *newinfo, unsigned char *base)
+ {
+ 	struct xt_entry_target *t;
+ 	struct xt_target *target;
+ 	struct ipt_entry *de;
+ 	unsigned int origsize;
+-	int ret, h;
++	int h;
+ 	struct xt_entry_match *ematch;
+ 
+-	ret = 0;
+ 	origsize = *size;
+ 	de = (struct ipt_entry *)*dstptr;
+ 	memcpy(de, e, sizeof(struct ipt_entry));
+@@ -1583,201 +1537,105 @@ compat_copy_entry_from_user(struct compat_ipt_entry *e, void **dstptr,
+ 	*dstptr += sizeof(struct ipt_entry);
+ 	*size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry);
+ 
+-	xt_ematch_foreach(ematch, e) {
+-		ret = xt_compat_match_from_user(ematch, dstptr, size);
+-		if (ret != 0)
+-			return ret;
+-	}
++	xt_ematch_foreach(ematch, e)
++		xt_compat_match_from_user(ematch, dstptr, size);
++
+ 	de->target_offset = e->target_offset - (origsize - *size);
+ 	t = compat_ipt_get_target(e);
+ 	target = t->u.kernel.target;
+ 	xt_compat_target_from_user(t, dstptr, size);
+ 
+ 	de->next_offset = e->next_offset - (origsize - *size);
++
+ 	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+ 		if ((unsigned char *)de - base < newinfo->hook_entry[h])
+ 			newinfo->hook_entry[h] -= origsize - *size;
+ 		if ((unsigned char *)de - base < newinfo->underflow[h])
+ 			newinfo->underflow[h] -= origsize - *size;
+ 	}
+-	return ret;
+-}
+-
+-static int
+-compat_check_entry(struct ipt_entry *e, struct net *net, const char *name)
+-{
+-	struct xt_entry_match *ematch;
+-	struct xt_mtchk_param mtpar;
+-	unsigned int j;
+-	int ret = 0;
+-
+-	e->counters.pcnt = xt_percpu_counter_alloc();
+-	if (IS_ERR_VALUE(e->counters.pcnt))
+-		return -ENOMEM;
+-
+-	j = 0;
+-	mtpar.net	= net;
+-	mtpar.table     = name;
+-	mtpar.entryinfo = &e->ip;
+-	mtpar.hook_mask = e->comefrom;
+-	mtpar.family    = NFPROTO_IPV4;
+-	xt_ematch_foreach(ematch, e) {
+-		ret = check_match(ematch, &mtpar);
+-		if (ret != 0)
+-			goto cleanup_matches;
+-		++j;
+-	}
+-
+-	ret = check_target(e, net, name);
+-	if (ret)
+-		goto cleanup_matches;
+-	return 0;
+-
+- cleanup_matches:
+-	xt_ematch_foreach(ematch, e) {
+-		if (j-- == 0)
+-			break;
+-		cleanup_match(ematch, net);
+-	}
+-
+-	xt_percpu_counter_free(e->counters.pcnt);
+-
+-	return ret;
+ }
+ 
+ static int
+ translate_compat_table(struct net *net,
+-		       const char *name,
+-		       unsigned int valid_hooks,
+ 		       struct xt_table_info **pinfo,
+ 		       void **pentry0,
+-		       unsigned int total_size,
+-		       unsigned int number,
+-		       unsigned int *hook_entries,
+-		       unsigned int *underflows)
++		       const struct compat_ipt_replace *compatr)
+ {
+ 	unsigned int i, j;
+ 	struct xt_table_info *newinfo, *info;
+ 	void *pos, *entry0, *entry1;
+ 	struct compat_ipt_entry *iter0;
+-	struct ipt_entry *iter1;
++	struct ipt_replace repl;
+ 	unsigned int size;
+ 	int ret;
+ 
+ 	info = *pinfo;
+ 	entry0 = *pentry0;
+-	size = total_size;
+-	info->number = number;
+-
+-	/* Init all hooks to impossible value. */
+-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		info->hook_entry[i] = 0xFFFFFFFF;
+-		info->underflow[i] = 0xFFFFFFFF;
+-	}
++	size = compatr->size;
++	info->number = compatr->num_entries;
+ 
+ 	duprintf("translate_compat_table: size %u\n", info->size);
+ 	j = 0;
+ 	xt_compat_lock(AF_INET);
+-	xt_compat_init_offsets(AF_INET, number);
++	xt_compat_init_offsets(AF_INET, compatr->num_entries);
+ 	/* Walk through entries, checking offsets. */
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+ 							entry0,
+-							entry0 + total_size,
+-							hook_entries,
+-							underflows,
+-							name);
++							entry0 + compatr->size);
+ 		if (ret != 0)
+ 			goto out_unlock;
+ 		++j;
+ 	}
+ 
+ 	ret = -EINVAL;
+-	if (j != number) {
++	if (j != compatr->num_entries) {
+ 		duprintf("translate_compat_table: %u not %u entries\n",
+-			 j, number);
++			 j, compatr->num_entries);
+ 		goto out_unlock;
+ 	}
+ 
+-	/* Check hooks all assigned */
+-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		/* Only hooks which are valid */
+-		if (!(valid_hooks & (1 << i)))
+-			continue;
+-		if (info->hook_entry[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid hook entry %u %u\n",
+-				 i, hook_entries[i]);
+-			goto out_unlock;
+-		}
+-		if (info->underflow[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid underflow %u %u\n",
+-				 i, underflows[i]);
+-			goto out_unlock;
+-		}
+-	}
+-
+ 	ret = -ENOMEM;
+ 	newinfo = xt_alloc_table_info(size);
+ 	if (!newinfo)
+ 		goto out_unlock;
+ 
+-	newinfo->number = number;
++	newinfo->number = compatr->num_entries;
+ 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		newinfo->hook_entry[i] = info->hook_entry[i];
+-		newinfo->underflow[i] = info->underflow[i];
++		newinfo->hook_entry[i] = compatr->hook_entry[i];
++		newinfo->underflow[i] = compatr->underflow[i];
+ 	}
+ 	entry1 = newinfo->entries;
+ 	pos = entry1;
+-	size = total_size;
+-	xt_entry_foreach(iter0, entry0, total_size) {
+-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
+-						  name, newinfo, entry1);
+-		if (ret != 0)
+-			break;
+-	}
++	size = compatr->size;
++	xt_entry_foreach(iter0, entry0, compatr->size)
++		compat_copy_entry_from_user(iter0, &pos, &size,
++					    newinfo, entry1);
++
++	/* all module references in entry0 are now gone.
++	 * entry1/newinfo contains a 64bit ruleset that looks exactly as
++	 * generated by 64bit userspace.
++	 *
++	 * Call standard translate_table() to validate all hook_entrys,
++	 * underflows, check for loops, etc.
++	 */
+ 	xt_compat_flush_offsets(AF_INET);
+ 	xt_compat_unlock(AF_INET);
+-	if (ret)
+-		goto free_newinfo;
+ 
+-	ret = -ELOOP;
+-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+-		goto free_newinfo;
++	memcpy(&repl, compatr, sizeof(*compatr));
+ 
+-	i = 0;
+-	xt_entry_foreach(iter1, entry1, newinfo->size) {
+-		ret = compat_check_entry(iter1, net, name);
+-		if (ret != 0)
+-			break;
+-		++i;
+-		if (strcmp(ipt_get_target(iter1)->u.user.name,
+-		    XT_ERROR_TARGET) == 0)
+-			++newinfo->stacksize;
+-	}
+-	if (ret) {
+-		/*
+-		 * The first i matches need cleanup_entry (calls ->destroy)
+-		 * because they had called ->check already. The other j-i
+-		 * entries need only release.
+-		 */
+-		int skip = i;
+-		j -= i;
+-		xt_entry_foreach(iter0, entry0, newinfo->size) {
+-			if (skip-- > 0)
+-				continue;
+-			if (j-- == 0)
+-				break;
+-			compat_release_entry(iter0);
+-		}
+-		xt_entry_foreach(iter1, entry1, newinfo->size) {
+-			if (i-- == 0)
+-				break;
+-			cleanup_entry(iter1, net);
+-		}
+-		xt_free_table_info(newinfo);
+-		return ret;
++	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
++		repl.hook_entry[i] = newinfo->hook_entry[i];
++		repl.underflow[i] = newinfo->underflow[i];
+ 	}
+ 
++	repl.num_counters = 0;
++	repl.counters = NULL;
++	repl.size = newinfo->size;
++	ret = translate_table(net, newinfo, entry1, &repl);
++	if (ret)
++		goto free_newinfo;
++
+ 	*pinfo = newinfo;
+ 	*pentry0 = entry1;
+ 	xt_free_table_info(info);
+@@ -1785,17 +1643,16 @@ translate_compat_table(struct net *net,
+ 
+ free_newinfo:
+ 	xt_free_table_info(newinfo);
+-out:
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	return ret;
++out_unlock:
++	xt_compat_flush_offsets(AF_INET);
++	xt_compat_unlock(AF_INET);
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		if (j-- == 0)
+ 			break;
+ 		compat_release_entry(iter0);
+ 	}
+ 	return ret;
+-out_unlock:
+-	xt_compat_flush_offsets(AF_INET);
+-	xt_compat_unlock(AF_INET);
+-	goto out;
+ }
+ 
+ static int
+@@ -1831,10 +1688,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
+ 		goto free_newinfo;
+ 	}
+ 
+-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
+-				     &newinfo, &loc_cpu_entry, tmp.size,
+-				     tmp.num_entries, tmp.hook_entry,
+-				     tmp.underflow);
++	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
+ 	if (ret != 0)
+ 		goto free_newinfo;
+ 
+diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
+index 1e1fe6086dd9..03112a3106ab 100644
+--- a/net/ipv4/sysctl_net_ipv4.c
++++ b/net/ipv4/sysctl_net_ipv4.c
+@@ -988,10 +988,6 @@ static __net_init int ipv4_sysctl_init_net(struct net *net)
+ 	if (!net->ipv4.sysctl_local_reserved_ports)
+ 		goto err_ports;
+ 
+-	net->ipv4.sysctl_ip_default_ttl = IPDEFTTL;
+-	net->ipv4.sysctl_ip_dynaddr = 0;
+-	net->ipv4.sysctl_ip_early_demux = 1;
+-
+ 	return 0;
+ 
+ err_ports:
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index a2e7f55a1f61..e9853dff7b52 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -1616,7 +1616,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ 
+ 		/* if we're overly short, let UDP handle it */
+ 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
+-		if (skb->len > sizeof(struct udphdr) && encap_rcv) {
++		if (encap_rcv) {
+ 			int ret;
+ 
+ 			/* Verify checksum before giving to encap */
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index bc972e7152c7..da88de82b3b8 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -1071,17 +1071,12 @@ struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
+ 					 const struct in6_addr *final_dst)
+ {
+ 	struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
+-	int err;
+ 
+ 	dst = ip6_sk_dst_check(sk, dst, fl6);
++	if (!dst)
++		dst = ip6_dst_lookup_flow(sk, fl6, final_dst);
+ 
+-	err = ip6_dst_lookup_tail(sock_net(sk), sk, &dst, fl6);
+-	if (err)
+-		return ERR_PTR(err);
+-	if (final_dst)
+-		fl6->daddr = *final_dst;
+-
+-	return xfrm_lookup_route(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
++	return dst;
+ }
+ EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
+ 
+diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
+index 86b67b70b626..9021b435506d 100644
+--- a/net/ipv6/netfilter/ip6_tables.c
++++ b/net/ipv6/netfilter/ip6_tables.c
+@@ -455,6 +455,18 @@ ip6t_do_table(struct sk_buff *skb,
+ #endif
+ }
+ 
++static bool find_jump_target(const struct xt_table_info *t,
++			     const struct ip6t_entry *target)
++{
++	struct ip6t_entry *iter;
++
++	xt_entry_foreach(iter, t->entries, t->size) {
++		 if (iter == target)
++			return true;
++	}
++	return false;
++}
++
+ /* Figures out from what hook each rule can be called: returns 0 if
+    there are loops.  Puts hook bitmask in comefrom. */
+ static int
+@@ -532,6 +544,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
+ 				size = e->next_offset;
+ 				e = (struct ip6t_entry *)
+ 					(entry0 + pos + size);
++				if (pos + size >= newinfo->size)
++					return 0;
+ 				e->counters.pcnt = pos;
+ 				pos += size;
+ 			} else {
+@@ -550,9 +564,15 @@ mark_source_chains(const struct xt_table_info *newinfo,
+ 					/* This a jump; chase it. */
+ 					duprintf("Jump rule %u -> %u\n",
+ 						 pos, newpos);
++					e = (struct ip6t_entry *)
++						(entry0 + newpos);
++					if (!find_jump_target(newinfo, e))
++						return 0;
+ 				} else {
+ 					/* ... this is a fallthru */
+ 					newpos = pos + e->next_offset;
++					if (newpos >= newinfo->size)
++						return 0;
+ 				}
+ 				e = (struct ip6t_entry *)
+ 					(entry0 + newpos);
+@@ -579,25 +599,6 @@ static void cleanup_match(struct xt_entry_match *m, struct net *net)
+ 	module_put(par.match->me);
+ }
+ 
+-static int
+-check_entry(const struct ip6t_entry *e)
+-{
+-	const struct xt_entry_target *t;
+-
+-	if (!ip6_checkentry(&e->ipv6))
+-		return -EINVAL;
+-
+-	if (e->target_offset + sizeof(struct xt_entry_target) >
+-	    e->next_offset)
+-		return -EINVAL;
+-
+-	t = ip6t_get_target_c(e);
+-	if (e->target_offset + t->u.target_size > e->next_offset)
+-		return -EINVAL;
+-
+-	return 0;
+-}
+-
+ static int check_match(struct xt_entry_match *m, struct xt_mtchk_param *par)
+ {
+ 	const struct ip6t_ip6 *ipv6 = par->entryinfo;
+@@ -762,7 +763,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	err = check_entry(e);
++	if (!ip6_checkentry(&e->ipv6))
++		return -EINVAL;
++
++	err = xt_check_entry_offsets(e, e->elems, e->target_offset,
++				     e->next_offset);
+ 	if (err)
+ 		return err;
+ 
+@@ -1321,55 +1326,16 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
+ 	unsigned int i;
+ 	struct xt_counters_info tmp;
+ 	struct xt_counters *paddc;
+-	unsigned int num_counters;
+-	char *name;
+-	int size;
+-	void *ptmp;
+ 	struct xt_table *t;
+ 	const struct xt_table_info *private;
+ 	int ret = 0;
+ 	struct ip6t_entry *iter;
+ 	unsigned int addend;
+-#ifdef CONFIG_COMPAT
+-	struct compat_xt_counters_info compat_tmp;
+-
+-	if (compat) {
+-		ptmp = &compat_tmp;
+-		size = sizeof(struct compat_xt_counters_info);
+-	} else
+-#endif
+-	{
+-		ptmp = &tmp;
+-		size = sizeof(struct xt_counters_info);
+-	}
+-
+-	if (copy_from_user(ptmp, user, size) != 0)
+-		return -EFAULT;
+-
+-#ifdef CONFIG_COMPAT
+-	if (compat) {
+-		num_counters = compat_tmp.num_counters;
+-		name = compat_tmp.name;
+-	} else
+-#endif
+-	{
+-		num_counters = tmp.num_counters;
+-		name = tmp.name;
+-	}
+-
+-	if (len != size + num_counters * sizeof(struct xt_counters))
+-		return -EINVAL;
+-
+-	paddc = vmalloc(len - size);
+-	if (!paddc)
+-		return -ENOMEM;
+ 
+-	if (copy_from_user(paddc, user + size, len - size) != 0) {
+-		ret = -EFAULT;
+-		goto free;
+-	}
+-
+-	t = xt_find_table_lock(net, AF_INET6, name);
++	paddc = xt_copy_counters_from_user(user, len, &tmp, compat);
++	if (IS_ERR(paddc))
++		return PTR_ERR(paddc);
++	t = xt_find_table_lock(net, AF_INET6, tmp.name);
+ 	if (IS_ERR_OR_NULL(t)) {
+ 		ret = t ? PTR_ERR(t) : -ENOENT;
+ 		goto free;
+@@ -1377,7 +1343,7 @@ do_add_counters(struct net *net, const void __user *user, unsigned int len,
+ 
+ 	local_bh_disable();
+ 	private = t->private;
+-	if (private->number != num_counters) {
++	if (private->number != tmp.num_counters) {
+ 		ret = -EINVAL;
+ 		goto unlock_up_free;
+ 	}
+@@ -1456,7 +1422,6 @@ compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr,
+ 
+ static int
+ compat_find_calc_match(struct xt_entry_match *m,
+-		       const char *name,
+ 		       const struct ip6t_ip6 *ipv6,
+ 		       int *size)
+ {
+@@ -1491,17 +1456,14 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
+ 				  struct xt_table_info *newinfo,
+ 				  unsigned int *size,
+ 				  const unsigned char *base,
+-				  const unsigned char *limit,
+-				  const unsigned int *hook_entries,
+-				  const unsigned int *underflows,
+-				  const char *name)
++				  const unsigned char *limit)
+ {
+ 	struct xt_entry_match *ematch;
+ 	struct xt_entry_target *t;
+ 	struct xt_target *target;
+ 	unsigned int entry_offset;
+ 	unsigned int j;
+-	int ret, off, h;
++	int ret, off;
+ 
+ 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
+ 	if ((unsigned long)e % __alignof__(struct compat_ip6t_entry) != 0 ||
+@@ -1518,8 +1480,11 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
+ 		return -EINVAL;
+ 	}
+ 
+-	/* For purposes of check_entry casting the compat entry is fine */
+-	ret = check_entry((struct ip6t_entry *)e);
++	if (!ip6_checkentry(&e->ipv6))
++		return -EINVAL;
++
++	ret = xt_compat_check_entry_offsets(e, e->elems,
++					    e->target_offset, e->next_offset);
+ 	if (ret)
+ 		return ret;
+ 
+@@ -1527,7 +1492,7 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
+ 	entry_offset = (void *)e - (void *)base;
+ 	j = 0;
+ 	xt_ematch_foreach(ematch, e) {
+-		ret = compat_find_calc_match(ematch, name, &e->ipv6, &off);
++		ret = compat_find_calc_match(ematch, &e->ipv6, &off);
+ 		if (ret != 0)
+ 			goto release_matches;
+ 		++j;
+@@ -1550,17 +1515,6 @@ check_compat_entry_size_and_hooks(struct compat_ip6t_entry *e,
+ 	if (ret)
+ 		goto out;
+ 
+-	/* Check hooks & underflows */
+-	for (h = 0; h < NF_INET_NUMHOOKS; h++) {
+-		if ((unsigned char *)e - base == hook_entries[h])
+-			newinfo->hook_entry[h] = hook_entries[h];
+-		if ((unsigned char *)e - base == underflows[h])
+-			newinfo->underflow[h] = underflows[h];
+-	}
+-
+-	/* Clear counters and comefrom */
+-	memset(&e->counters, 0, sizeof(e->counters));
+-	e->comefrom = 0;
+ 	return 0;
+ 
+ out:
+@@ -1574,18 +1528,17 @@ release_matches:
+ 	return ret;
+ }
+ 
+-static int
++static void
+ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
+-			    unsigned int *size, const char *name,
++			    unsigned int *size,
+ 			    struct xt_table_info *newinfo, unsigned char *base)
+ {
+ 	struct xt_entry_target *t;
+ 	struct ip6t_entry *de;
+ 	unsigned int origsize;
+-	int ret, h;
++	int h;
+ 	struct xt_entry_match *ematch;
+ 
+-	ret = 0;
+ 	origsize = *size;
+ 	de = (struct ip6t_entry *)*dstptr;
+ 	memcpy(de, e, sizeof(struct ip6t_entry));
+@@ -1594,11 +1547,9 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
+ 	*dstptr += sizeof(struct ip6t_entry);
+ 	*size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry);
+ 
+-	xt_ematch_foreach(ematch, e) {
+-		ret = xt_compat_match_from_user(ematch, dstptr, size);
+-		if (ret != 0)
+-			return ret;
+-	}
++	xt_ematch_foreach(ematch, e)
++		xt_compat_match_from_user(ematch, dstptr, size);
++
+ 	de->target_offset = e->target_offset - (origsize - *size);
+ 	t = compat_ip6t_get_target(e);
+ 	xt_compat_target_from_user(t, dstptr, size);
+@@ -1610,183 +1561,83 @@ compat_copy_entry_from_user(struct compat_ip6t_entry *e, void **dstptr,
+ 		if ((unsigned char *)de - base < newinfo->underflow[h])
+ 			newinfo->underflow[h] -= origsize - *size;
+ 	}
+-	return ret;
+-}
+-
+-static int compat_check_entry(struct ip6t_entry *e, struct net *net,
+-			      const char *name)
+-{
+-	unsigned int j;
+-	int ret = 0;
+-	struct xt_mtchk_param mtpar;
+-	struct xt_entry_match *ematch;
+-
+-	e->counters.pcnt = xt_percpu_counter_alloc();
+-	if (IS_ERR_VALUE(e->counters.pcnt))
+-		return -ENOMEM;
+-	j = 0;
+-	mtpar.net	= net;
+-	mtpar.table     = name;
+-	mtpar.entryinfo = &e->ipv6;
+-	mtpar.hook_mask = e->comefrom;
+-	mtpar.family    = NFPROTO_IPV6;
+-	xt_ematch_foreach(ematch, e) {
+-		ret = check_match(ematch, &mtpar);
+-		if (ret != 0)
+-			goto cleanup_matches;
+-		++j;
+-	}
+-
+-	ret = check_target(e, net, name);
+-	if (ret)
+-		goto cleanup_matches;
+-	return 0;
+-
+- cleanup_matches:
+-	xt_ematch_foreach(ematch, e) {
+-		if (j-- == 0)
+-			break;
+-		cleanup_match(ematch, net);
+-	}
+-
+-	xt_percpu_counter_free(e->counters.pcnt);
+-
+-	return ret;
+ }
+ 
+ static int
+ translate_compat_table(struct net *net,
+-		       const char *name,
+-		       unsigned int valid_hooks,
+ 		       struct xt_table_info **pinfo,
+ 		       void **pentry0,
+-		       unsigned int total_size,
+-		       unsigned int number,
+-		       unsigned int *hook_entries,
+-		       unsigned int *underflows)
++		       const struct compat_ip6t_replace *compatr)
+ {
+ 	unsigned int i, j;
+ 	struct xt_table_info *newinfo, *info;
+ 	void *pos, *entry0, *entry1;
+ 	struct compat_ip6t_entry *iter0;
+-	struct ip6t_entry *iter1;
++	struct ip6t_replace repl;
+ 	unsigned int size;
+ 	int ret = 0;
+ 
+ 	info = *pinfo;
+ 	entry0 = *pentry0;
+-	size = total_size;
+-	info->number = number;
+-
+-	/* Init all hooks to impossible value. */
+-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		info->hook_entry[i] = 0xFFFFFFFF;
+-		info->underflow[i] = 0xFFFFFFFF;
+-	}
++	size = compatr->size;
++	info->number = compatr->num_entries;
+ 
+ 	duprintf("translate_compat_table: size %u\n", info->size);
+ 	j = 0;
+ 	xt_compat_lock(AF_INET6);
+-	xt_compat_init_offsets(AF_INET6, number);
++	xt_compat_init_offsets(AF_INET6, compatr->num_entries);
+ 	/* Walk through entries, checking offsets. */
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		ret = check_compat_entry_size_and_hooks(iter0, info, &size,
+ 							entry0,
+-							entry0 + total_size,
+-							hook_entries,
+-							underflows,
+-							name);
++							entry0 + compatr->size);
+ 		if (ret != 0)
+ 			goto out_unlock;
+ 		++j;
+ 	}
+ 
+ 	ret = -EINVAL;
+-	if (j != number) {
++	if (j != compatr->num_entries) {
+ 		duprintf("translate_compat_table: %u not %u entries\n",
+-			 j, number);
++			 j, compatr->num_entries);
+ 		goto out_unlock;
+ 	}
+ 
+-	/* Check hooks all assigned */
+-	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		/* Only hooks which are valid */
+-		if (!(valid_hooks & (1 << i)))
+-			continue;
+-		if (info->hook_entry[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid hook entry %u %u\n",
+-				 i, hook_entries[i]);
+-			goto out_unlock;
+-		}
+-		if (info->underflow[i] == 0xFFFFFFFF) {
+-			duprintf("Invalid underflow %u %u\n",
+-				 i, underflows[i]);
+-			goto out_unlock;
+-		}
+-	}
+-
+ 	ret = -ENOMEM;
+ 	newinfo = xt_alloc_table_info(size);
+ 	if (!newinfo)
+ 		goto out_unlock;
+ 
+-	newinfo->number = number;
++	newinfo->number = compatr->num_entries;
+ 	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
+-		newinfo->hook_entry[i] = info->hook_entry[i];
+-		newinfo->underflow[i] = info->underflow[i];
++		newinfo->hook_entry[i] = compatr->hook_entry[i];
++		newinfo->underflow[i] = compatr->underflow[i];
+ 	}
+ 	entry1 = newinfo->entries;
+ 	pos = entry1;
+-	size = total_size;
+-	xt_entry_foreach(iter0, entry0, total_size) {
+-		ret = compat_copy_entry_from_user(iter0, &pos, &size,
+-						  name, newinfo, entry1);
+-		if (ret != 0)
+-			break;
+-	}
++	size = compatr->size;
++	xt_entry_foreach(iter0, entry0, compatr->size)
++		compat_copy_entry_from_user(iter0, &pos, &size,
++					    newinfo, entry1);
++
++	/* all module references in entry0 are now gone. */
+ 	xt_compat_flush_offsets(AF_INET6);
+ 	xt_compat_unlock(AF_INET6);
+-	if (ret)
+-		goto free_newinfo;
+ 
+-	ret = -ELOOP;
+-	if (!mark_source_chains(newinfo, valid_hooks, entry1))
+-		goto free_newinfo;
++	memcpy(&repl, compatr, sizeof(*compatr));
+ 
+-	i = 0;
+-	xt_entry_foreach(iter1, entry1, newinfo->size) {
+-		ret = compat_check_entry(iter1, net, name);
+-		if (ret != 0)
+-			break;
+-		++i;
+-		if (strcmp(ip6t_get_target(iter1)->u.user.name,
+-		    XT_ERROR_TARGET) == 0)
+-			++newinfo->stacksize;
+-	}
+-	if (ret) {
+-		/*
+-		 * The first i matches need cleanup_entry (calls ->destroy)
+-		 * because they had called ->check already. The other j-i
+-		 * entries need only release.
+-		 */
+-		int skip = i;
+-		j -= i;
+-		xt_entry_foreach(iter0, entry0, newinfo->size) {
+-			if (skip-- > 0)
+-				continue;
+-			if (j-- == 0)
+-				break;
+-			compat_release_entry(iter0);
+-		}
+-		xt_entry_foreach(iter1, entry1, newinfo->size) {
+-			if (i-- == 0)
+-				break;
+-			cleanup_entry(iter1, net);
+-		}
+-		xt_free_table_info(newinfo);
+-		return ret;
++	for (i = 0; i < NF_INET_NUMHOOKS; i++) {
++		repl.hook_entry[i] = newinfo->hook_entry[i];
++		repl.underflow[i] = newinfo->underflow[i];
+ 	}
+ 
++	repl.num_counters = 0;
++	repl.counters = NULL;
++	repl.size = newinfo->size;
++	ret = translate_table(net, newinfo, entry1, &repl);
++	if (ret)
++		goto free_newinfo;
++
+ 	*pinfo = newinfo;
+ 	*pentry0 = entry1;
+ 	xt_free_table_info(info);
+@@ -1794,17 +1645,16 @@ translate_compat_table(struct net *net,
+ 
+ free_newinfo:
+ 	xt_free_table_info(newinfo);
+-out:
+-	xt_entry_foreach(iter0, entry0, total_size) {
++	return ret;
++out_unlock:
++	xt_compat_flush_offsets(AF_INET6);
++	xt_compat_unlock(AF_INET6);
++	xt_entry_foreach(iter0, entry0, compatr->size) {
+ 		if (j-- == 0)
+ 			break;
+ 		compat_release_entry(iter0);
+ 	}
+ 	return ret;
+-out_unlock:
+-	xt_compat_flush_offsets(AF_INET6);
+-	xt_compat_unlock(AF_INET6);
+-	goto out;
+ }
+ 
+ static int
+@@ -1840,10 +1690,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len)
+ 		goto free_newinfo;
+ 	}
+ 
+-	ret = translate_compat_table(net, tmp.name, tmp.valid_hooks,
+-				     &newinfo, &loc_cpu_entry, tmp.size,
+-				     tmp.num_entries, tmp.hook_entry,
+-				     tmp.underflow);
++	ret = translate_compat_table(net, &newinfo, &loc_cpu_entry, &tmp);
+ 	if (ret != 0)
+ 		goto free_newinfo;
+ 
+diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
+index f443c6b0ce16..f6d7516eeb8a 100644
+--- a/net/ipv6/tcp_ipv6.c
++++ b/net/ipv6/tcp_ipv6.c
+@@ -1717,7 +1717,9 @@ static void get_tcp6_sock(struct seq_file *seq, struct sock *sp, int i)
+ 	destp = ntohs(inet->inet_dport);
+ 	srcp  = ntohs(inet->inet_sport);
+ 
+-	if (icsk->icsk_pending == ICSK_TIME_RETRANS) {
++	if (icsk->icsk_pending == ICSK_TIME_RETRANS ||
++	    icsk->icsk_pending == ICSK_TIME_EARLY_RETRANS ||
++	    icsk->icsk_pending == ICSK_TIME_LOSS_PROBE) {
+ 		timer_active	= 1;
+ 		timer_expires	= icsk->icsk_timeout;
+ 	} else if (icsk->icsk_pending == ICSK_TIME_PROBE0) {
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
+index 6bc5c664fa46..f96831d9d419 100644
+--- a/net/ipv6/udp.c
++++ b/net/ipv6/udp.c
+@@ -653,7 +653,7 @@ int udpv6_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
+ 
+ 		/* if we're overly short, let UDP handle it */
+ 		encap_rcv = ACCESS_ONCE(up->encap_rcv);
+-		if (skb->len > sizeof(struct udphdr) && encap_rcv) {
++		if (encap_rcv) {
+ 			int ret;
+ 
+ 			/* Verify checksum before giving to encap */
+diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
+index 6edfa9980314..1e40dacaa137 100644
+--- a/net/l2tp/l2tp_core.c
++++ b/net/l2tp/l2tp_core.c
+@@ -1581,7 +1581,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
+ 	/* Mark socket as an encapsulation socket. See net/ipv4/udp.c */
+ 	tunnel->encap = encap;
+ 	if (encap == L2TP_ENCAPTYPE_UDP) {
+-		struct udp_tunnel_sock_cfg udp_cfg;
++		struct udp_tunnel_sock_cfg udp_cfg = { };
+ 
+ 		udp_cfg.sk_user_data = tunnel;
+ 		udp_cfg.encap_type = UDP_ENCAP_L2TPINUDP;
+diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
+index 582c9cfd6567..2675d580c490 100644
+--- a/net/netfilter/x_tables.c
++++ b/net/netfilter/x_tables.c
+@@ -416,6 +416,47 @@ int xt_check_match(struct xt_mtchk_param *par,
+ }
+ EXPORT_SYMBOL_GPL(xt_check_match);
+ 
++/** xt_check_entry_match - check that matches end before start of target
++ *
++ * @match: beginning of xt_entry_match
++ * @target: beginning of this rules target (alleged end of matches)
++ * @alignment: alignment requirement of match structures
++ *
++ * Validates that all matches add up to the beginning of the target,
++ * and that each match covers at least the base structure size.
++ *
++ * Return: 0 on success, negative errno on failure.
++ */
++static int xt_check_entry_match(const char *match, const char *target,
++				const size_t alignment)
++{
++	const struct xt_entry_match *pos;
++	int length = target - match;
++
++	if (length == 0) /* no matches */
++		return 0;
++
++	pos = (struct xt_entry_match *)match;
++	do {
++		if ((unsigned long)pos % alignment)
++			return -EINVAL;
++
++		if (length < (int)sizeof(struct xt_entry_match))
++			return -EINVAL;
++
++		if (pos->u.match_size < sizeof(struct xt_entry_match))
++			return -EINVAL;
++
++		if (pos->u.match_size > length)
++			return -EINVAL;
++
++		length -= pos->u.match_size;
++		pos = ((void *)((char *)(pos) + (pos)->u.match_size));
++	} while (length > 0);
++
++	return 0;
++}
++
+ #ifdef CONFIG_COMPAT
+ int xt_compat_add_offset(u_int8_t af, unsigned int offset, int delta)
+ {
+@@ -485,13 +526,14 @@ int xt_compat_match_offset(const struct xt_match *match)
+ }
+ EXPORT_SYMBOL_GPL(xt_compat_match_offset);
+ 
+-int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+-			      unsigned int *size)
++void xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
++			       unsigned int *size)
+ {
+ 	const struct xt_match *match = m->u.kernel.match;
+ 	struct compat_xt_entry_match *cm = (struct compat_xt_entry_match *)m;
+ 	int pad, off = xt_compat_match_offset(match);
+ 	u_int16_t msize = cm->u.user.match_size;
++	char name[sizeof(m->u.user.name)];
+ 
+ 	m = *dstptr;
+ 	memcpy(m, cm, sizeof(*cm));
+@@ -505,10 +547,12 @@ int xt_compat_match_from_user(struct xt_entry_match *m, void **dstptr,
+ 
+ 	msize += off;
+ 	m->u.user.match_size = msize;
++	strlcpy(name, match->name, sizeof(name));
++	module_put(match->me);
++	strncpy(m->u.user.name, name, sizeof(m->u.user.name));
+ 
+ 	*size += off;
+ 	*dstptr += msize;
+-	return 0;
+ }
+ EXPORT_SYMBOL_GPL(xt_compat_match_from_user);
+ 
+@@ -539,8 +583,125 @@ int xt_compat_match_to_user(const struct xt_entry_match *m,
+ 	return 0;
+ }
+ EXPORT_SYMBOL_GPL(xt_compat_match_to_user);
++
++/* non-compat version may have padding after verdict */
++struct compat_xt_standard_target {
++	struct compat_xt_entry_target t;
++	compat_uint_t verdict;
++};
++
++int xt_compat_check_entry_offsets(const void *base, const char *elems,
++				  unsigned int target_offset,
++				  unsigned int next_offset)
++{
++	long size_of_base_struct = elems - (const char *)base;
++	const struct compat_xt_entry_target *t;
++	const char *e = base;
++
++	if (target_offset < size_of_base_struct)
++		return -EINVAL;
++
++	if (target_offset + sizeof(*t) > next_offset)
++		return -EINVAL;
++
++	t = (void *)(e + target_offset);
++	if (t->u.target_size < sizeof(*t))
++		return -EINVAL;
++
++	if (target_offset + t->u.target_size > next_offset)
++		return -EINVAL;
++
++	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
++	    COMPAT_XT_ALIGN(target_offset + sizeof(struct compat_xt_standard_target)) != next_offset)
++		return -EINVAL;
++
++	/* compat_xt_entry match has less strict aligment requirements,
++	 * otherwise they are identical.  In case of padding differences
++	 * we need to add compat version of xt_check_entry_match.
++	 */
++	BUILD_BUG_ON(sizeof(struct compat_xt_entry_match) != sizeof(struct xt_entry_match));
++
++	return xt_check_entry_match(elems, base + target_offset,
++				    __alignof__(struct compat_xt_entry_match));
++}
++EXPORT_SYMBOL(xt_compat_check_entry_offsets);
+ #endif /* CONFIG_COMPAT */
+ 
++/**
++ * xt_check_entry_offsets - validate arp/ip/ip6t_entry
++ *
++ * @base: pointer to arp/ip/ip6t_entry
++ * @elems: pointer to first xt_entry_match, i.e. ip(6)t_entry->elems
++ * @target_offset: the arp/ip/ip6_t->target_offset
++ * @next_offset: the arp/ip/ip6_t->next_offset
++ *
++ * validates that target_offset and next_offset are sane and that all
++ * match sizes (if any) align with the target offset.
++ *
++ * This function does not validate the targets or matches themselves, it
++ * only tests that all the offsets and sizes are correct, that all
++ * match structures are aligned, and that the last structure ends where
++ * the target structure begins.
++ *
++ * Also see xt_compat_check_entry_offsets for CONFIG_COMPAT version.
++ *
++ * The arp/ip/ip6t_entry structure @base must have passed following tests:
++ * - it must point to a valid memory location
++ * - base to base + next_offset must be accessible, i.e. not exceed allocated
++ *   length.
++ *
++ * A well-formed entry looks like this:
++ *
++ * ip(6)t_entry   match [mtdata]  match [mtdata] target [tgdata] ip(6)t_entry
++ * e->elems[]-----'                              |               |
++ *                matchsize                      |               |
++ *                                matchsize      |               |
++ *                                               |               |
++ * target_offset---------------------------------'               |
++ * next_offset---------------------------------------------------'
++ *
++ * elems[]: flexible array member at end of ip(6)/arpt_entry struct.
++ *          This is where matches (if any) and the target reside.
++ * target_offset: beginning of target.
++ * next_offset: start of the next rule; also: size of this rule.
++ * Since targets have a minimum size, target_offset + minlen <= next_offset.
++ *
++ * Every match stores its size, sum of sizes must not exceed target_offset.
++ *
++ * Return: 0 on success, negative errno on failure.
++ */
++int xt_check_entry_offsets(const void *base,
++			   const char *elems,
++			   unsigned int target_offset,
++			   unsigned int next_offset)
++{
++	long size_of_base_struct = elems - (const char *)base;
++	const struct xt_entry_target *t;
++	const char *e = base;
++
++	/* target start is within the ip/ip6/arpt_entry struct */
++	if (target_offset < size_of_base_struct)
++		return -EINVAL;
++
++	if (target_offset + sizeof(*t) > next_offset)
++		return -EINVAL;
++
++	t = (void *)(e + target_offset);
++	if (t->u.target_size < sizeof(*t))
++		return -EINVAL;
++
++	if (target_offset + t->u.target_size > next_offset)
++		return -EINVAL;
++
++	if (strcmp(t->u.user.name, XT_STANDARD_TARGET) == 0 &&
++	    XT_ALIGN(target_offset + sizeof(struct xt_standard_target)) != next_offset)
++		return -EINVAL;
++
++	return xt_check_entry_match(elems, base + target_offset,
++				    __alignof__(struct xt_entry_match));
++}
++EXPORT_SYMBOL(xt_check_entry_offsets);
++
+ int xt_check_target(struct xt_tgchk_param *par,
+ 		    unsigned int size, u_int8_t proto, bool inv_proto)
+ {
+@@ -591,6 +752,80 @@ int xt_check_target(struct xt_tgchk_param *par,
+ }
+ EXPORT_SYMBOL_GPL(xt_check_target);
+ 
++/**
++ * xt_copy_counters_from_user - copy counters and metadata from userspace
++ *
++ * @user: src pointer to userspace memory
++ * @len: alleged size of userspace memory
++ * @info: where to store the xt_counters_info metadata
++ * @compat: true if we setsockopt call is done by 32bit task on 64bit kernel
++ *
++ * Copies counter meta data from @user and stores it in @info.
++ *
++ * vmallocs memory to hold the counters, then copies the counter data
++ * from @user to the new memory and returns a pointer to it.
++ *
++ * If @compat is true, @info gets converted automatically to the 64bit
++ * representation.
++ *
++ * The metadata associated with the counters is stored in @info.
++ *
++ * Return: returns pointer that caller has to test via IS_ERR().
++ * If IS_ERR is false, caller has to vfree the pointer.
++ */
++void *xt_copy_counters_from_user(const void __user *user, unsigned int len,
++				 struct xt_counters_info *info, bool compat)
++{
++	void *mem;
++	u64 size;
++
++#ifdef CONFIG_COMPAT
++	if (compat) {
++		/* structures only differ in size due to alignment */
++		struct compat_xt_counters_info compat_tmp;
++
++		if (len <= sizeof(compat_tmp))
++			return ERR_PTR(-EINVAL);
++
++		len -= sizeof(compat_tmp);
++		if (copy_from_user(&compat_tmp, user, sizeof(compat_tmp)) != 0)
++			return ERR_PTR(-EFAULT);
++
++		strlcpy(info->name, compat_tmp.name, sizeof(info->name));
++		info->num_counters = compat_tmp.num_counters;
++		user += sizeof(compat_tmp);
++	} else
++#endif
++	{
++		if (len <= sizeof(*info))
++			return ERR_PTR(-EINVAL);
++
++		len -= sizeof(*info);
++		if (copy_from_user(info, user, sizeof(*info)) != 0)
++			return ERR_PTR(-EFAULT);
++
++		info->name[sizeof(info->name) - 1] = '\0';
++		user += sizeof(*info);
++	}
++
++	size = sizeof(struct xt_counters);
++	size *= info->num_counters;
++
++	if (size != (u64)len)
++		return ERR_PTR(-EINVAL);
++
++	mem = vmalloc(len);
++	if (!mem)
++		return ERR_PTR(-ENOMEM);
++
++	if (copy_from_user(mem, user, len) == 0)
++		return mem;
++
++	vfree(mem);
++	return ERR_PTR(-EFAULT);
++}
++EXPORT_SYMBOL_GPL(xt_copy_counters_from_user);
++
+ #ifdef CONFIG_COMPAT
+ int xt_compat_target_offset(const struct xt_target *target)
+ {
+@@ -606,6 +841,7 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
+ 	struct compat_xt_entry_target *ct = (struct compat_xt_entry_target *)t;
+ 	int pad, off = xt_compat_target_offset(target);
+ 	u_int16_t tsize = ct->u.user.target_size;
++	char name[sizeof(t->u.user.name)];
+ 
+ 	t = *dstptr;
+ 	memcpy(t, ct, sizeof(*ct));
+@@ -619,6 +855,9 @@ void xt_compat_target_from_user(struct xt_entry_target *t, void **dstptr,
+ 
+ 	tsize += off;
+ 	t->u.user.target_size = tsize;
++	strlcpy(name, target->name, sizeof(name));
++	module_put(target->me);
++	strncpy(t->u.user.name, name, sizeof(t->u.user.name));
+ 
+ 	*size += off;
+ 	*dstptr += tsize;
+diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
+index 330ebd600f25..f48e3b3aedd5 100644
+--- a/net/netlink/af_netlink.c
++++ b/net/netlink/af_netlink.c
+@@ -2059,6 +2059,7 @@ static int netlink_dump(struct sock *sk)
+ 	struct netlink_callback *cb;
+ 	struct sk_buff *skb = NULL;
+ 	struct nlmsghdr *nlh;
++	struct module *module;
+ 	int len, err = -ENOBUFS;
+ 	int alloc_min_size;
+ 	int alloc_size;
+@@ -2134,9 +2135,11 @@ static int netlink_dump(struct sock *sk)
+ 		cb->done(cb);
+ 
+ 	nlk->cb_running = false;
++	module = cb->module;
++	skb = cb->skb;
+ 	mutex_unlock(nlk->cb_mutex);
+-	module_put(cb->module);
+-	consume_skb(cb->skb);
++	module_put(module);
++	consume_skb(skb);
+ 	return 0;
+ 
+ errout_skb:
+diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
+index b7e01d88bdc5..59658b2e9cdf 100644
+--- a/net/switchdev/switchdev.c
++++ b/net/switchdev/switchdev.c
+@@ -1188,6 +1188,7 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
+ 		.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
+ 		.dst = dst,
+ 		.dst_len = dst_len,
++		.fi = fi,
+ 		.tos = tos,
+ 		.type = type,
+ 		.nlflags = nlflags,
+@@ -1196,8 +1197,6 @@ int switchdev_fib_ipv4_add(u32 dst, int dst_len, struct fib_info *fi,
+ 	struct net_device *dev;
+ 	int err = 0;
+ 
+-	memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
+-
+ 	/* Don't offload route if using custom ip rules or if
+ 	 * IPv4 FIB offloading has been disabled completely.
+ 	 */
+@@ -1242,6 +1241,7 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
+ 		.obj.id = SWITCHDEV_OBJ_ID_IPV4_FIB,
+ 		.dst = dst,
+ 		.dst_len = dst_len,
++		.fi = fi,
+ 		.tos = tos,
+ 		.type = type,
+ 		.nlflags = 0,
+@@ -1250,8 +1250,6 @@ int switchdev_fib_ipv4_del(u32 dst, int dst_len, struct fib_info *fi,
+ 	struct net_device *dev;
+ 	int err = 0;
+ 
+-	memcpy(&ipv4_fib.fi, fi, sizeof(ipv4_fib.fi));
+-
+ 	if (!(fi->fib_flags & RTNH_F_OFFLOAD))
+ 		return 0;
+ 
+diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
+index d7d050f44fc1..4dfc5c14f8c3 100644
+--- a/net/tipc/netlink_compat.c
++++ b/net/tipc/netlink_compat.c
+@@ -802,7 +802,7 @@ static int tipc_nl_compat_name_table_dump(struct tipc_nl_compat_msg *msg,
+ 		goto out;
+ 
+ 	tipc_tlv_sprintf(msg->rep, "%-10u %s",
+-			 nla_get_u32(publ[TIPC_NLA_PUBL_REF]),
++			 nla_get_u32(publ[TIPC_NLA_PUBL_KEY]),
+ 			 scope_str[nla_get_u32(publ[TIPC_NLA_PUBL_SCOPE])]);
+ out:
+ 	tipc_tlv_sprintf(msg->rep, "\n");
+diff --git a/net/tipc/socket.c b/net/tipc/socket.c
+index 3eeb50a27b89..5f80d3fa9c85 100644
+--- a/net/tipc/socket.c
++++ b/net/tipc/socket.c
+@@ -2807,6 +2807,9 @@ int tipc_nl_publ_dump(struct sk_buff *skb, struct netlink_callback *cb)
+ 		if (err)
+ 			return err;
+ 
++		if (!attrs[TIPC_NLA_SOCK])
++			return -EINVAL;
++
+ 		err = nla_parse_nested(sock, TIPC_NLA_SOCK_MAX,
+ 				       attrs[TIPC_NLA_SOCK],
+ 				       tipc_nl_sock_policy);
+diff --git a/net/wireless/wext-core.c b/net/wireless/wext-core.c
+index b50ee5d622e1..c753211cb83f 100644
+--- a/net/wireless/wext-core.c
++++ b/net/wireless/wext-core.c
+@@ -955,8 +955,29 @@ static int wireless_process_ioctl(struct net *net, struct ifreq *ifr,
+ 			return private(dev, iwr, cmd, info, handler);
+ 	}
+ 	/* Old driver API : call driver ioctl handler */
+-	if (dev->netdev_ops->ndo_do_ioctl)
+-		return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
++	if (dev->netdev_ops->ndo_do_ioctl) {
++#ifdef CONFIG_COMPAT
++		if (info->flags & IW_REQUEST_FLAG_COMPAT) {
++			int ret = 0;
++			struct iwreq iwr_lcl;
++			struct compat_iw_point *iwp_compat = (void *) &iwr->u.data;
++
++			memcpy(&iwr_lcl, iwr, sizeof(struct iwreq));
++			iwr_lcl.u.data.pointer = compat_ptr(iwp_compat->pointer);
++			iwr_lcl.u.data.length = iwp_compat->length;
++			iwr_lcl.u.data.flags = iwp_compat->flags;
++
++			ret = dev->netdev_ops->ndo_do_ioctl(dev, (void *) &iwr_lcl, cmd);
++
++			iwp_compat->pointer = ptr_to_compat(iwr_lcl.u.data.pointer);
++			iwp_compat->length = iwr_lcl.u.data.length;
++			iwp_compat->flags = iwr_lcl.u.data.flags;
++
++			return ret;
++		} else
++#endif
++			return dev->netdev_ops->ndo_do_ioctl(dev, ifr, cmd);
++	}
+ 	return -EOPNOTSUPP;
+ }
+ 
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 9a0d1445ca5c..94089fc71884 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -365,8 +365,11 @@ enum {
+ 
+ #define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+ #define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
++#define IS_KBL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171)
++#define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
+ #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+-#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
++#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
++			IS_KBL(pci) || IS_KBL_LP(pci)
+ 
+ static char *driver_short_names[] = {
+ 	[AZX_DRIVER_ICH] = "HDA Intel",
+@@ -2181,6 +2184,12 @@ static const struct pci_device_id azx_ids[] = {
+ 	/* Sunrise Point-LP */
+ 	{ PCI_DEVICE(0x8086, 0x9d70),
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
++	/* Kabylake */
++	{ PCI_DEVICE(0x8086, 0xa171),
++	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
++	/* Kabylake-LP */
++	{ PCI_DEVICE(0x8086, 0x9d71),
++	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ 	/* Broxton-P(Apollolake) */
+ 	{ PCI_DEVICE(0x8086, 0x5a98),
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index d53c25e7a1c1..0fe18ede3e85 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -346,6 +346,9 @@ static void alc_fill_eapd_coef(struct hda_codec *codec)
+ 	case 0x10ec0234:
+ 	case 0x10ec0274:
+ 	case 0x10ec0294:
++	case 0x10ec0700:
++	case 0x10ec0701:
++	case 0x10ec0703:
+ 		alc_update_coef_idx(codec, 0x10, 1<<15, 0);
+ 		break;
+ 	case 0x10ec0662:
+@@ -2655,6 +2658,7 @@ enum {
+ 	ALC269_TYPE_ALC256,
+ 	ALC269_TYPE_ALC225,
+ 	ALC269_TYPE_ALC294,
++	ALC269_TYPE_ALC700,
+ };
+ 
+ /*
+@@ -2686,6 +2690,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
+ 	case ALC269_TYPE_ALC256:
+ 	case ALC269_TYPE_ALC225:
+ 	case ALC269_TYPE_ALC294:
++	case ALC269_TYPE_ALC700:
+ 		ssids = alc269_ssids;
+ 		break;
+ 	default:
+@@ -3618,13 +3623,20 @@ static void alc269_fixup_hp_line1_mic1_led(struct hda_codec *codec,
+ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+ {
+ 	static struct coef_fw coef0255[] = {
+-		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
+ 		WRITE_COEF(0x45, 0xd089), /* UAJ function set to menual mode */
+ 		UPDATE_COEFEX(0x57, 0x05, 1<<14, 0), /* Direct Drive HP Amp control(Set to verb control)*/
+ 		WRITE_COEF(0x06, 0x6104), /* Set MIC2 Vref gate with HP */
+ 		WRITE_COEFEX(0x57, 0x03, 0x8aa6), /* Direct Drive HP Amp control */
+ 		{}
+ 	};
++	static struct coef_fw coef0255_1[] = {
++		WRITE_COEF(0x1b, 0x0c0b), /* LDO and MISC control */
++		{}
++	};
++	static struct coef_fw coef0256[] = {
++		WRITE_COEF(0x1b, 0x0c4b), /* LDO and MISC control */
++		{}
++	};
+ 	static struct coef_fw coef0233[] = {
+ 		WRITE_COEF(0x1b, 0x0c0b),
+ 		WRITE_COEF(0x45, 0xc429),
+@@ -3677,7 +3689,11 @@ static void alc_headset_mode_unplugged(struct hda_codec *codec)
+ 
+ 	switch (codec->core.vendor_id) {
+ 	case 0x10ec0255:
++		alc_process_coef_fw(codec, coef0255_1);
++		alc_process_coef_fw(codec, coef0255);
++		break;
+ 	case 0x10ec0256:
++		alc_process_coef_fw(codec, coef0256);
+ 		alc_process_coef_fw(codec, coef0255);
+ 		break;
+ 	case 0x10ec0233:
+@@ -3896,6 +3912,12 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
+ 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+ 		{}
+ 	};
++	static struct coef_fw coef0256[] = {
++		WRITE_COEF(0x45, 0xd489), /* Set to CTIA type */
++		WRITE_COEF(0x1b, 0x0c6b),
++		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
++		{}
++	};
+ 	static struct coef_fw coef0233[] = {
+ 		WRITE_COEF(0x45, 0xd429),
+ 		WRITE_COEF(0x1b, 0x0c2b),
+@@ -3936,9 +3958,11 @@ static void alc_headset_mode_ctia(struct hda_codec *codec)
+ 
+ 	switch (codec->core.vendor_id) {
+ 	case 0x10ec0255:
+-	case 0x10ec0256:
+ 		alc_process_coef_fw(codec, coef0255);
+ 		break;
++	case 0x10ec0256:
++		alc_process_coef_fw(codec, coef0256);
++		break;
+ 	case 0x10ec0233:
+ 	case 0x10ec0283:
+ 		alc_process_coef_fw(codec, coef0233);
+@@ -3978,6 +4002,12 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
+ 		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
+ 		{}
+ 	};
++	static struct coef_fw coef0256[] = {
++		WRITE_COEF(0x45, 0xe489), /* Set to OMTP Type */
++		WRITE_COEF(0x1b, 0x0c6b),
++		WRITE_COEFEX(0x57, 0x03, 0x8ea6),
++		{}
++	};
+ 	static struct coef_fw coef0233[] = {
+ 		WRITE_COEF(0x45, 0xe429),
+ 		WRITE_COEF(0x1b, 0x0c2b),
+@@ -4018,9 +4048,11 @@ static void alc_headset_mode_omtp(struct hda_codec *codec)
+ 
+ 	switch (codec->core.vendor_id) {
+ 	case 0x10ec0255:
+-	case 0x10ec0256:
+ 		alc_process_coef_fw(codec, coef0255);
+ 		break;
++	case 0x10ec0256:
++		alc_process_coef_fw(codec, coef0256);
++		break;
+ 	case 0x10ec0233:
+ 	case 0x10ec0283:
+ 		alc_process_coef_fw(codec, coef0233);
+@@ -4266,7 +4298,7 @@ static void alc_fixup_headset_mode_no_hp_mic(struct hda_codec *codec,
+ static void alc255_set_default_jack_type(struct hda_codec *codec)
+ {
+ 	/* Set to iphone type */
+-	static struct coef_fw fw[] = {
++	static struct coef_fw alc255fw[] = {
+ 		WRITE_COEF(0x1b, 0x880b),
+ 		WRITE_COEF(0x45, 0xd089),
+ 		WRITE_COEF(0x1b, 0x080b),
+@@ -4274,7 +4306,22 @@ static void alc255_set_default_jack_type(struct hda_codec *codec)
+ 		WRITE_COEF(0x1b, 0x0c0b),
+ 		{}
+ 	};
+-	alc_process_coef_fw(codec, fw);
++	static struct coef_fw alc256fw[] = {
++		WRITE_COEF(0x1b, 0x884b),
++		WRITE_COEF(0x45, 0xd089),
++		WRITE_COEF(0x1b, 0x084b),
++		WRITE_COEF(0x46, 0x0004),
++		WRITE_COEF(0x1b, 0x0c4b),
++		{}
++	};
++	switch (codec->core.vendor_id) {
++	case 0x10ec0255:
++		alc_process_coef_fw(codec, alc255fw);
++		break;
++	case 0x10ec0256:
++		alc_process_coef_fw(codec, alc256fw);
++		break;
++	}
+ 	msleep(30);
+ }
+ 
+@@ -5587,6 +5634,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x17aa, 0x2218, "Thinkpad X1 Carbon 2nd", ALC292_FIXUP_TPT440_DOCK),
+ 	SND_PCI_QUIRK(0x17aa, 0x2223, "ThinkPad T550", ALC292_FIXUP_TPT440_DOCK),
+ 	SND_PCI_QUIRK(0x17aa, 0x2226, "ThinkPad X250", ALC292_FIXUP_TPT440_DOCK),
++	SND_PCI_QUIRK(0x17aa, 0x2231, "Thinkpad T560", ALC292_FIXUP_TPT460),
+ 	SND_PCI_QUIRK(0x17aa, 0x2233, "Thinkpad", ALC292_FIXUP_TPT460),
+ 	SND_PCI_QUIRK(0x17aa, 0x30bb, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+ 	SND_PCI_QUIRK(0x17aa, 0x30e2, "ThinkCentre AIO", ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY),
+@@ -5775,6 +5823,10 @@ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 		{0x12, 0x90a60180},
+ 		{0x14, 0x90170130},
+ 		{0x21, 0x02211040}),
++	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell Inspiron 5565", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
++		{0x12, 0x90a60180},
++		{0x14, 0x90170120},
++		{0x21, 0x02211030}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0256, 0x1028, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		{0x12, 0x90a60160},
+ 		{0x14, 0x90170120},
+@@ -6053,6 +6105,14 @@ static int patch_alc269(struct hda_codec *codec)
+ 	case 0x10ec0294:
+ 		spec->codec_variant = ALC269_TYPE_ALC294;
+ 		break;
++	case 0x10ec0700:
++	case 0x10ec0701:
++	case 0x10ec0703:
++		spec->codec_variant = ALC269_TYPE_ALC700;
++		spec->gen.mixer_nid = 0; /* ALC700 does not have any loopback mixer path */
++		alc_update_coef_idx(codec, 0x4a, 0, 1 << 15); /* Combo jack auto trigger control */
++		break;
++
+ 	}
+ 
+ 	if (snd_hda_codec_read(codec, 0x51, 0, AC_VERB_PARAMETERS, 0) == 0x10ec5505) {
+@@ -7008,6 +7068,9 @@ static const struct hda_device_id snd_hda_id_realtek[] = {
+ 	HDA_CODEC_ENTRY(0x10ec0670, "ALC670", patch_alc662),
+ 	HDA_CODEC_ENTRY(0x10ec0671, "ALC671", patch_alc662),
+ 	HDA_CODEC_ENTRY(0x10ec0680, "ALC680", patch_alc680),
++	HDA_CODEC_ENTRY(0x10ec0700, "ALC700", patch_alc269),
++	HDA_CODEC_ENTRY(0x10ec0701, "ALC701", patch_alc269),
++	HDA_CODEC_ENTRY(0x10ec0703, "ALC703", patch_alc269),
+ 	HDA_CODEC_ENTRY(0x10ec0867, "ALC891", patch_alc882),
+ 	HDA_CODEC_ENTRY(0x10ec0880, "ALC880", patch_alc880),
+ 	HDA_CODEC_ENTRY(0x10ec0882, "ALC882", patch_alc882),
+diff --git a/virt/kvm/arm/hyp/vgic-v2-sr.c b/virt/kvm/arm/hyp/vgic-v2-sr.c
+index 674bdf8ecf4f..501849ad0b60 100644
+--- a/virt/kvm/arm/hyp/vgic-v2-sr.c
++++ b/virt/kvm/arm/hyp/vgic-v2-sr.c
+@@ -93,12 +93,11 @@ static void __hyp_text save_lrs(struct kvm_vcpu *vcpu, void __iomem *base)
+ 		if (!(vcpu->arch.vgic_cpu.live_lrs & (1UL << i)))
+ 			continue;
+ 
+-		if (cpu_if->vgic_elrsr & (1UL << i)) {
++		if (cpu_if->vgic_elrsr & (1UL << i))
+ 			cpu_if->vgic_lr[i] &= ~GICH_LR_STATE;
+-			continue;
+-		}
++		else
++			cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
+ 
+-		cpu_if->vgic_lr[i] = readl_relaxed(base + GICH_LR0 + (i * 4));
+ 		writel_relaxed(0, base + GICH_LR0 + (i * 4));
+ 	}
+ }
+diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c
+index fe84e1a95dd5..8db197bb6c7a 100644
+--- a/virt/kvm/irqchip.c
++++ b/virt/kvm/irqchip.c
+@@ -40,7 +40,7 @@ int kvm_irq_map_gsi(struct kvm *kvm,
+ 
+ 	irq_rt = srcu_dereference_check(kvm->irq_routing, &kvm->irq_srcu,
+ 					lockdep_is_held(&kvm->irq_lock));
+-	if (gsi < irq_rt->nr_rt_entries) {
++	if (irq_rt && gsi < irq_rt->nr_rt_entries) {
+ 		hlist_for_each_entry(e, &irq_rt->map[gsi], link) {
+ 			entries[n] = *e;
+ 			++n;


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

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

commit:     fd28e3ad763ea79a262ca9d96d6d812817ec60fe
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Jul  1 00:31:10 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Jul  1 00:31:10 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=fd28e3ad

Update gcc 4.9+ optimization patch. Bug #587578

 ...-additional-cpu-optimizations-for-gcc-4.9.patch | 90 ++++++++++++++--------
 1 file changed, 57 insertions(+), 33 deletions(-)

diff --git a/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch b/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
index 418201d..d9729b2 100644
--- a/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
+++ b/5010_enable-additional-cpu-optimizations-for-gcc-4.9.patch
@@ -21,11 +21,12 @@ bug report to see if I'm right: https://bugzilla.kernel.org/show_bug.cgi?id=7746
 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 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.
+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.
@@ -37,9 +38,9 @@ REQUIREMENTS
 linux version >=3.15
 gcc version >=4.9
 
---- a/arch/x86/include/asm/module.h	2014-06-16 16:44:27.000000000 -0400
-+++ b/arch/x86/include/asm/module.h	2015-03-07 03:27:32.556672424 -0500
-@@ -15,6 +15,22 @@
+--- 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 "
@@ -59,10 +60,12 @@ gcc version >=4.9
 +#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 +49,20 @@
+@@ -33,6 +51,22 @@
  #define MODULE_PROC_FAMILY "K7 "
  #elif defined CONFIG_MK8
  #define MODULE_PROC_FAMILY "K8 "
@@ -77,14 +80,16 @@ gcc version >=4.9
 +#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	2014-06-16 16:44:27.000000000 -0400
-+++ b/arch/x86/Kconfig.cpu	2015-03-07 03:32:14.337713226 -0500
+--- 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
@@ -105,7 +110,7 @@ gcc version >=4.9
  	depends on X86_32
  	---help---
  	  Select this for an AMD Athlon K7-family processor.  Enables use of
-@@ -155,12 +154,62 @@ config MK7
+@@ -155,12 +154,69 @@ config MK7
  	  flags to GCC.
  
  config MK8
@@ -159,6 +164,13 @@ gcc version >=4.9
 +
 +	  Enables -march=bdver2
 +
++config MSTEAMROLLER
++	bool "AMD Steamroller"
++	---help---
++	  Select this for AMD Steamroller processors.
++
++	  Enables -march=bdver3
++
 +config MJAGUAR
 +	bool "AMD Jaguar"
 +	---help---
@@ -169,7 +181,7 @@ gcc version >=4.9
  config MCRUSOE
  	bool "Crusoe"
  	depends on X86_32
-@@ -251,8 +300,17 @@ config MPSC
+@@ -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.
  
@@ -188,7 +200,7 @@ gcc version >=4.9
  	---help---
  
  	  Select this for Intel Core 2 and newer Core 2 Xeons (Xeon 51xx and
-@@ -260,14 +318,63 @@ config MCORE2
+@@ -260,14 +325,71 @@ config MCORE2
  	  family in /proc/cpuinfo. Newer ones have 6 and older ones 15
  	  (not a typo)
  
@@ -255,10 +267,18 @@ gcc version >=4.9
 +	  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 +383,19 @@ config GENERIC_CPU
+@@ -276,6 +398,19 @@ config GENERIC_CPU
  	  Generic x86-64 CPU.
  	  Run equally well on all x86-64 CPUs.
  
@@ -278,54 +298,54 @@ gcc version >=4.9
  endchoice
  
  config X86_GENERIC
-@@ -300,7 +420,7 @@ config X86_INTERNODE_CACHE_SHIFT
+@@ -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 || MJAGUAR || MPENTIUMM || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MNATIVE || 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 +451,11 @@ config X86_ALIGNMENT_16
+@@ -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 || MNATIVE
++	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 || MATOM || MNATIVE
++	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 +479,17 @@ config X86_P6_NOP
+@@ -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 || MNATIVE || 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 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MATOM || MNATIVE
++	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 || MJAGUAR || MK7 || MCORE2 || MNEHALEM || MWESTMERE || MSILVERMONT || MSANDYBRIDGE || MIVYBRIDGE || MHASWELL || MBROADWELL || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || MVIAC3_2 || MVIAC7 || MCRUSOE || MEFFICEON || X86_64 || MNATIVE || 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	2014-06-16 16:44:27.000000000 -0400
-+++ b/arch/x86/Makefile	2015-03-07 03:33:27.650843211 -0500
-@@ -92,13 +92,35 @@ else
- 	KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=3)
+--- 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)
@@ -336,6 +356,7 @@ gcc version >=4.9
 +        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)
  
@@ -358,14 +379,16 @@ gcc version >=4.9
 +                $(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	2014-06-16 16:44:27.000000000 -0400
-+++ b/arch/x86/Makefile_32.cpu	2015-03-07 03:34:15.203586024 -0500
-@@ -23,7 +23,15 @@ cflags-$(CONFIG_MK6)		+= -march=k6
+--- 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
@@ -377,11 +400,12 @@ gcc version >=4.9
 +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 +40,15 @@ cflags-$(CONFIG_MCYRIXIII)	+= $(call cc-
+@@ -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)
@@ -394,9 +418,9 @@ gcc version >=4.9
 +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] 12+ messages in thread

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

commit:     e85cf895cefab29ae83391390c84229cb7830c88
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Jul  2 15:27:20 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Jul  2 15:27:20 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=e85cf895

Select SYSVIPC when GENTOO_LINUX_PORTAGE is selected. Dependency of IPC_NS. See bug #587736.

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

diff --git a/4567_distro-Gentoo-Kconfig.patch b/4567_distro-Gentoo-Kconfig.patch
index c7af596..499b21f 100644
--- a/4567_distro-Gentoo-Kconfig.patch
+++ b/4567_distro-Gentoo-Kconfig.patch
@@ -1,5 +1,5 @@
---- a/Kconfig
-+++ b/Kconfig
+--- 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"
@@ -7,9 +7,9 @@
 +source "distro/Kconfig"
 +
  source "arch/$SRCARCH/Kconfig"
---- /dev/null
-+++ b/distro/Kconfig
-@@ -0,0 +1,131 @@
+--- /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 @@
 +menu "Gentoo Linux"
 +
 +config GENTOO_LINUX
@@ -63,6 +63,7 @@
 +	select NAMESPACES
 +	select IPC_NS
 +	select NET_NS
++	select SYSVIPC
 +
 +	help
 +		This enables options required by various Portage FEATURES.
@@ -71,6 +72,8 @@
 +		CGROUPS     (required for FEATURES=cgroup)
 +		IPC_NS      (required for FEATURES=ipc-sandbox)
 +		NET_NS      (required for FEATURES=network-sandbox)
++		SYSVIPC     (required by IPC_NS)
++   
 +
 +		It is highly recommended that you leave this enabled as these FEATURES
 +		are, or will soon be, enabled by default.


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

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

commit:     04d89d0f4edaf324768e6d860f4ec6546d043725
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 11 19:56:55 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Jul 11 19:57:24 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=04d89d0f

Linux patch 4.6.4

 0000_README            |    4 +
 1003_linux-4.6.4.patch | 1008 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 1012 insertions(+)

diff --git a/0000_README b/0000_README
index 8feba45..5c841a9 100644
--- a/0000_README
+++ b/0000_README
@@ -55,6 +55,10 @@ Patch:  1002_linux-4.6.3.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.3
 
+Patch:  1003_linux-4.6.4.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.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.6.4.patch b/1003_linux-4.6.4.patch
new file mode 100644
index 0000000..5c5a062
--- /dev/null
+++ b/1003_linux-4.6.4.patch
@@ -0,0 +1,1008 @@
+diff --git a/Makefile b/Makefile
+index c62b531d5a85..cd374426114a 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 3
++SUBLEVEL = 4
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
+index 43fe85f20d57..7097a3395b25 100644
+--- a/crypto/crypto_user.c
++++ b/crypto/crypto_user.c
+@@ -455,6 +455,7 @@ static const int crypto_msg_min[CRYPTO_NR_MSGTYPES] = {
+ 	[CRYPTO_MSG_NEWALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+ 	[CRYPTO_MSG_DELALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+ 	[CRYPTO_MSG_UPDATEALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
++	[CRYPTO_MSG_GETALG	- CRYPTO_MSG_BASE] = MSGSIZE(crypto_user_alg),
+ 	[CRYPTO_MSG_DELRNG	- CRYPTO_MSG_BASE] = 0,
+ };
+ 
+diff --git a/drivers/crypto/ux500/hash/hash_core.c b/drivers/crypto/ux500/hash/hash_core.c
+index 574e87c7f2b8..9acccad26928 100644
+--- a/drivers/crypto/ux500/hash/hash_core.c
++++ b/drivers/crypto/ux500/hash/hash_core.c
+@@ -781,7 +781,7 @@ static int hash_process_data(struct hash_device_data *device_data,
+ 						&device_data->state);
+ 				memmove(req_ctx->state.buffer,
+ 					device_data->state.buffer,
+-					HASH_BLOCK_SIZE / sizeof(u32));
++					HASH_BLOCK_SIZE);
+ 				if (ret) {
+ 					dev_err(device_data->dev,
+ 						"%s: hash_resume_state() failed!\n",
+@@ -832,7 +832,7 @@ static int hash_process_data(struct hash_device_data *device_data,
+ 
+ 			memmove(device_data->state.buffer,
+ 				req_ctx->state.buffer,
+-				HASH_BLOCK_SIZE / sizeof(u32));
++				HASH_BLOCK_SIZE);
+ 			if (ret) {
+ 				dev_err(device_data->dev, "%s: hash_save_state() failed!\n",
+ 					__func__);
+diff --git a/drivers/crypto/vmx/aes_cbc.c b/drivers/crypto/vmx/aes_cbc.c
+index 495577b6d31b..94ad5c0adbcb 100644
+--- a/drivers/crypto/vmx/aes_cbc.c
++++ b/drivers/crypto/vmx/aes_cbc.c
+@@ -182,7 +182,7 @@ struct crypto_alg p8_aes_cbc_alg = {
+ 	.cra_name = "cbc(aes)",
+ 	.cra_driver_name = "p8_aes_cbc",
+ 	.cra_module = THIS_MODULE,
+-	.cra_priority = 1000,
++	.cra_priority = 2000,
+ 	.cra_type = &crypto_blkcipher_type,
+ 	.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
+ 	.cra_alignmask = 0,
+diff --git a/drivers/crypto/vmx/aes_ctr.c b/drivers/crypto/vmx/aes_ctr.c
+index 0a3c1b04cf3c..38ed10d761d0 100644
+--- a/drivers/crypto/vmx/aes_ctr.c
++++ b/drivers/crypto/vmx/aes_ctr.c
+@@ -166,7 +166,7 @@ struct crypto_alg p8_aes_ctr_alg = {
+ 	.cra_name = "ctr(aes)",
+ 	.cra_driver_name = "p8_aes_ctr",
+ 	.cra_module = THIS_MODULE,
+-	.cra_priority = 1000,
++	.cra_priority = 2000,
+ 	.cra_type = &crypto_blkcipher_type,
+ 	.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER | CRYPTO_ALG_NEED_FALLBACK,
+ 	.cra_alignmask = 0,
+diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c
+index 6dc810bce295..944a6dca0fcb 100644
+--- a/drivers/usb/core/quirks.c
++++ b/drivers/usb/core/quirks.c
+@@ -44,6 +44,9 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* Creative SB Audigy 2 NX */
+ 	{ USB_DEVICE(0x041e, 0x3020), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
++	/* USB3503 */
++	{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	/* Microsoft Wireless Laser Mouse 6000 Receiver */
+ 	{ USB_DEVICE(0x045e, 0x00e1), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
+@@ -173,6 +176,10 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	/* MAYA44USB sound device */
+ 	{ USB_DEVICE(0x0a92, 0x0091), .driver_info = USB_QUIRK_RESET_RESUME },
+ 
++	/* ASUS Base Station(T100) */
++	{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
++			USB_QUIRK_IGNORE_REMOTE_WAKEUP },
++
+ 	/* Action Semiconductor flash disk */
+ 	{ USB_DEVICE(0x10d6, 0x2200), .driver_info =
+ 			USB_QUIRK_STRING_FETCH_255 },
+@@ -188,26 +195,22 @@ static const struct usb_device_id usb_quirk_list[] = {
+ 	{ USB_DEVICE(0x1908, 0x1315), .driver_info =
+ 			USB_QUIRK_HONOR_BNUMINTERFACES },
+ 
+-	/* INTEL VALUE SSD */
+-	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* USB3503 */
+-	{ USB_DEVICE(0x0424, 0x3503), .driver_info = USB_QUIRK_RESET_RESUME },
+-
+-	/* ASUS Base Station(T100) */
+-	{ USB_DEVICE(0x0b05, 0x17e0), .driver_info =
+-			USB_QUIRK_IGNORE_REMOTE_WAKEUP },
+-
+ 	/* Protocol and OTG Electrical Test Device */
+ 	{ USB_DEVICE(0x1a0a, 0x0200), .driver_info =
+ 			USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL },
+ 
++	/* Acer C120 LED Projector */
++	{ USB_DEVICE(0x1de1, 0xc102), .driver_info = USB_QUIRK_NO_LPM },
++
+ 	/* Blackmagic Design Intensity Shuttle */
+ 	{ USB_DEVICE(0x1edb, 0xbd3b), .driver_info = USB_QUIRK_NO_LPM },
+ 
+ 	/* Blackmagic Design UltraStudio SDI */
+ 	{ USB_DEVICE(0x1edb, 0xbd4f), .driver_info = USB_QUIRK_NO_LPM },
+ 
++	/* INTEL VALUE SSD */
++	{ USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME },
++
+ 	{ }  /* terminating entry must be last */
+ };
+ 
+diff --git a/drivers/usb/dwc3/dwc3-exynos.c b/drivers/usb/dwc3/dwc3-exynos.c
+index dd5cb5577dca..2f1fb7e7aa54 100644
+--- a/drivers/usb/dwc3/dwc3-exynos.c
++++ b/drivers/usb/dwc3/dwc3-exynos.c
+@@ -128,12 +128,6 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
+ 
+ 	platform_set_drvdata(pdev, exynos);
+ 
+-	ret = dwc3_exynos_register_phys(exynos);
+-	if (ret) {
+-		dev_err(dev, "couldn't register PHYs\n");
+-		return ret;
+-	}
+-
+ 	exynos->dev	= dev;
+ 
+ 	exynos->clk = devm_clk_get(dev, "usbdrd30");
+@@ -183,20 +177,29 @@ static int dwc3_exynos_probe(struct platform_device *pdev)
+ 		goto err3;
+ 	}
+ 
++	ret = dwc3_exynos_register_phys(exynos);
++	if (ret) {
++		dev_err(dev, "couldn't register PHYs\n");
++		goto err4;
++	}
++
+ 	if (node) {
+ 		ret = of_platform_populate(node, NULL, NULL, dev);
+ 		if (ret) {
+ 			dev_err(dev, "failed to add dwc3 core\n");
+-			goto err4;
++			goto err5;
+ 		}
+ 	} else {
+ 		dev_err(dev, "no device node, failed to add dwc3 core\n");
+ 		ret = -ENODEV;
+-		goto err4;
++		goto err5;
+ 	}
+ 
+ 	return 0;
+ 
++err5:
++	platform_device_unregister(exynos->usb2_phy);
++	platform_device_unregister(exynos->usb3_phy);
+ err4:
+ 	regulator_disable(exynos->vdd10);
+ err3:
+diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c
+index e64479f882a5..aa3707bdebb4 100644
+--- a/drivers/usb/gadget/legacy/inode.c
++++ b/drivers/usb/gadget/legacy/inode.c
+@@ -938,8 +938,11 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr)
+ 			struct usb_ep		*ep = dev->gadget->ep0;
+ 			struct usb_request	*req = dev->req;
+ 
+-			if ((retval = setup_req (ep, req, 0)) == 0)
+-				retval = usb_ep_queue (ep, req, GFP_ATOMIC);
++			if ((retval = setup_req (ep, req, 0)) == 0) {
++				spin_unlock_irq (&dev->lock);
++				retval = usb_ep_queue (ep, req, GFP_KERNEL);
++				spin_lock_irq (&dev->lock);
++			}
+ 			dev->state = STATE_DEV_CONNECTED;
+ 
+ 			/* assume that was SET_CONFIGURATION */
+@@ -1457,8 +1460,11 @@ delegate:
+ 							w_length);
+ 				if (value < 0)
+ 					break;
++
++				spin_unlock (&dev->lock);
+ 				value = usb_ep_queue (gadget->ep0, dev->req,
+-							GFP_ATOMIC);
++							GFP_KERNEL);
++				spin_lock (&dev->lock);
+ 				if (value < 0) {
+ 					clean_req (gadget->ep0, dev->req);
+ 					break;
+@@ -1481,11 +1487,14 @@ delegate:
+ 	if (value >= 0 && dev->state != STATE_DEV_SETUP) {
+ 		req->length = value;
+ 		req->zero = value < w_length;
+-		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
++
++		spin_unlock (&dev->lock);
++		value = usb_ep_queue (gadget->ep0, req, GFP_KERNEL);
+ 		if (value < 0) {
+ 			DBG (dev, "ep_queue --> %d\n", value);
+ 			req->status = 0;
+ 		}
++		return value;
+ 	}
+ 
+ 	/* device stalls when value < 0 */
+diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
+index 4031b372008e..c1c1024a054c 100644
+--- a/drivers/usb/host/ehci-tegra.c
++++ b/drivers/usb/host/ehci-tegra.c
+@@ -89,7 +89,7 @@ static int tegra_reset_usb_controller(struct platform_device *pdev)
+ 	if (!usb1_reset_attempted) {
+ 		struct reset_control *usb1_reset;
+ 
+-		usb1_reset = of_reset_control_get(phy_np, "usb");
++		usb1_reset = of_reset_control_get(phy_np, "utmi-pads");
+ 		if (IS_ERR(usb1_reset)) {
+ 			dev_warn(&pdev->dev,
+ 				 "can't get utmi-pads reset from the PHY\n");
+diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c
+index 48672fac7ff3..c10972fcc8e4 100644
+--- a/drivers/usb/host/xhci-pci.c
++++ b/drivers/usb/host/xhci-pci.c
+@@ -37,6 +37,7 @@
+ /* Device for a quirk */
+ #define PCI_VENDOR_ID_FRESCO_LOGIC	0x1b73
+ #define PCI_DEVICE_ID_FRESCO_LOGIC_PDK	0x1000
++#define PCI_DEVICE_ID_FRESCO_LOGIC_FL1009	0x1009
+ #define PCI_DEVICE_ID_FRESCO_LOGIC_FL1400	0x1400
+ 
+ #define PCI_VENDOR_ID_ETRON		0x1b6f
+@@ -114,6 +115,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci)
+ 		xhci->quirks |= XHCI_TRUST_TX_LENGTH;
+ 	}
+ 
++	if (pdev->vendor == PCI_VENDOR_ID_FRESCO_LOGIC &&
++			pdev->device == PCI_DEVICE_ID_FRESCO_LOGIC_FL1009)
++		xhci->quirks |= XHCI_BROKEN_STREAMS;
++
+ 	if (pdev->vendor == PCI_VENDOR_ID_NEC)
+ 		xhci->quirks |= XHCI_NEC_HOST;
+ 
+diff --git a/drivers/usb/host/xhci-plat.c b/drivers/usb/host/xhci-plat.c
+index 474b5fa14900..d6e2b2751e50 100644
+--- a/drivers/usb/host/xhci-plat.c
++++ b/drivers/usb/host/xhci-plat.c
+@@ -194,6 +194,9 @@ static int xhci_plat_probe(struct platform_device *pdev)
+ 		ret = clk_prepare_enable(clk);
+ 		if (ret)
+ 			goto put_hcd;
++	} else if (PTR_ERR(clk) == -EPROBE_DEFER) {
++		ret = -EPROBE_DEFER;
++		goto put_hcd;
+ 	}
+ 
+ 	xhci = hcd_to_xhci(hcd);
+diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
+index 99b4ff42f7a0..8b5b2aca277d 100644
+--- a/drivers/usb/host/xhci-ring.c
++++ b/drivers/usb/host/xhci-ring.c
+@@ -290,6 +290,14 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
+ 
+ 	temp_64 = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ 	xhci->cmd_ring_state = CMD_RING_STATE_ABORTED;
++
++	/*
++	 * Writing the CMD_RING_ABORT bit should cause a cmd completion event,
++	 * however on some host hw the CMD_RING_RUNNING bit is correctly cleared
++	 * but the completion event in never sent. Use the cmd timeout timer to
++	 * handle those cases. Use twice the time to cover the bit polling retry
++	 */
++	mod_timer(&xhci->cmd_timer, jiffies + (2 * XHCI_CMD_DEFAULT_TIMEOUT));
+ 	xhci_write_64(xhci, temp_64 | CMD_RING_ABORT,
+ 			&xhci->op_regs->cmd_ring);
+ 
+@@ -314,6 +322,7 @@ static int xhci_abort_cmd_ring(struct xhci_hcd *xhci)
+ 
+ 		xhci_err(xhci, "Stopped the command ring failed, "
+ 				"maybe the host is dead\n");
++		del_timer(&xhci->cmd_timer);
+ 		xhci->xhc_state |= XHCI_STATE_DYING;
+ 		xhci_quiesce(xhci);
+ 		xhci_halt(xhci);
+@@ -1253,22 +1262,21 @@ void xhci_handle_command_timeout(unsigned long data)
+ 	int ret;
+ 	unsigned long flags;
+ 	u64 hw_ring_state;
+-	struct xhci_command *cur_cmd = NULL;
++	bool second_timeout = false;
+ 	xhci = (struct xhci_hcd *) data;
+ 
+ 	/* mark this command to be cancelled */
+ 	spin_lock_irqsave(&xhci->lock, flags);
+ 	if (xhci->current_cmd) {
+-		cur_cmd = xhci->current_cmd;
+-		cur_cmd->status = COMP_CMD_ABORT;
++		if (xhci->current_cmd->status == COMP_CMD_ABORT)
++			second_timeout = true;
++		xhci->current_cmd->status = COMP_CMD_ABORT;
+ 	}
+ 
+-
+ 	/* Make sure command ring is running before aborting it */
+ 	hw_ring_state = xhci_read_64(xhci, &xhci->op_regs->cmd_ring);
+ 	if ((xhci->cmd_ring_state & CMD_RING_STATE_RUNNING) &&
+ 	    (hw_ring_state & CMD_RING_RUNNING))  {
+-
+ 		spin_unlock_irqrestore(&xhci->lock, flags);
+ 		xhci_dbg(xhci, "Command timeout\n");
+ 		ret = xhci_abort_cmd_ring(xhci);
+@@ -1280,6 +1288,15 @@ void xhci_handle_command_timeout(unsigned long data)
+ 		}
+ 		return;
+ 	}
++
++	/* command ring failed to restart, or host removed. Bail out */
++	if (second_timeout || xhci->xhc_state & XHCI_STATE_REMOVING) {
++		spin_unlock_irqrestore(&xhci->lock, flags);
++		xhci_dbg(xhci, "command timed out twice, ring start fail?\n");
++		xhci_cleanup_command_queue(xhci);
++		return;
++	}
++
+ 	/* command timeout on stopped ring, ring can't be aborted */
+ 	xhci_dbg(xhci, "Command timeout on stopped ring\n");
+ 	xhci_handle_stopped_cmd_ring(xhci, xhci->current_cmd);
+@@ -2728,7 +2745,8 @@ hw_died:
+ 		writel(irq_pending, &xhci->ir_set->irq_pending);
+ 	}
+ 
+-	if (xhci->xhc_state & XHCI_STATE_DYING) {
++	if (xhci->xhc_state & XHCI_STATE_DYING ||
++	    xhci->xhc_state & XHCI_STATE_HALTED) {
+ 		xhci_dbg(xhci, "xHCI dying, ignoring interrupt. "
+ 				"Shouldn't IRQs be disabled?\n");
+ 		/* Clear the event handler busy flag (RW1C);
+diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
+index 9e71c96ad74a..327280535848 100644
+--- a/drivers/usb/host/xhci.c
++++ b/drivers/usb/host/xhci.c
+@@ -685,20 +685,23 @@ void xhci_stop(struct usb_hcd *hcd)
+ 	u32 temp;
+ 	struct xhci_hcd *xhci = hcd_to_xhci(hcd);
+ 
+-	if (xhci->xhc_state & XHCI_STATE_HALTED)
+-		return;
+-
+ 	mutex_lock(&xhci->mutex);
+-	spin_lock_irq(&xhci->lock);
+-	xhci->xhc_state |= XHCI_STATE_HALTED;
+-	xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
+ 
+-	/* Make sure the xHC is halted for a USB3 roothub
+-	 * (xhci_stop() could be called as part of failed init).
+-	 */
+-	xhci_halt(xhci);
+-	xhci_reset(xhci);
+-	spin_unlock_irq(&xhci->lock);
++	if (!(xhci->xhc_state & XHCI_STATE_HALTED)) {
++		spin_lock_irq(&xhci->lock);
++
++		xhci->xhc_state |= XHCI_STATE_HALTED;
++		xhci->cmd_ring_state = CMD_RING_STATE_STOPPED;
++		xhci_halt(xhci);
++		xhci_reset(xhci);
++
++		spin_unlock_irq(&xhci->lock);
++	}
++
++	if (!usb_hcd_is_primary_hcd(hcd)) {
++		mutex_unlock(&xhci->mutex);
++		return;
++	}
+ 
+ 	xhci_cleanup_msix(xhci);
+ 
+diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
+index 39fd95833eb8..c84f4d0816e5 100644
+--- a/drivers/usb/musb/musb_core.c
++++ b/drivers/usb/musb/musb_core.c
+@@ -2429,7 +2429,8 @@ static void musb_restore_context(struct musb *musb)
+ 	musb_writew(musb_base, MUSB_INTRTXE, musb->intrtxe);
+ 	musb_writew(musb_base, MUSB_INTRRXE, musb->intrrxe);
+ 	musb_writeb(musb_base, MUSB_INTRUSBE, musb->context.intrusbe);
+-	musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
++	if (musb->context.devctl & MUSB_DEVCTL_SESSION)
++		musb_writeb(musb_base, MUSB_DEVCTL, musb->context.devctl);
+ 
+ 	for (i = 0; i < musb->config->num_eps; ++i) {
+ 		struct musb_hw_ep	*hw_ep;
+diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
+index 2f8ad7f1f482..8ff03228540a 100644
+--- a/drivers/usb/musb/musb_host.c
++++ b/drivers/usb/musb/musb_host.c
+@@ -594,14 +594,13 @@ musb_rx_reinit(struct musb *musb, struct musb_qh *qh, u8 epnum)
+ 		musb_writew(ep->regs, MUSB_TXCSR, 0);
+ 
+ 	/* scrub all previous state, clearing toggle */
+-	} else {
+-		csr = musb_readw(ep->regs, MUSB_RXCSR);
+-		if (csr & MUSB_RXCSR_RXPKTRDY)
+-			WARNING("rx%d, packet/%d ready?\n", ep->epnum,
+-				musb_readw(ep->regs, MUSB_RXCOUNT));
+-
+-		musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
+ 	}
++	csr = musb_readw(ep->regs, MUSB_RXCSR);
++	if (csr & MUSB_RXCSR_RXPKTRDY)
++		WARNING("rx%d, packet/%d ready?\n", ep->epnum,
++			musb_readw(ep->regs, MUSB_RXCOUNT));
++
++	musb_h_flush_rxfifo(ep, MUSB_RXCSR_CLRDATATOG);
+ 
+ 	/* target addr and (for multipoint) hub addr/port */
+ 	if (musb->is_multipoint) {
+@@ -995,9 +994,15 @@ static void musb_bulk_nak_timeout(struct musb *musb, struct musb_hw_ep *ep,
+ 	if (is_in) {
+ 		dma = is_dma_capable() ? ep->rx_channel : NULL;
+ 
+-		/* clear nak timeout bit */
++		/*
++		 * Need to stop the transaction by clearing REQPKT first
++		 * then the NAK Timeout bit ref MUSBMHDRC USB 2.0 HIGH-SPEED
++		 * DUAL-ROLE CONTROLLER Programmer's Guide, section 9.2.2
++		 */
+ 		rx_csr = musb_readw(epio, MUSB_RXCSR);
+ 		rx_csr |= MUSB_RXCSR_H_WZC_BITS;
++		rx_csr &= ~MUSB_RXCSR_H_REQPKT;
++		musb_writew(epio, MUSB_RXCSR, rx_csr);
+ 		rx_csr &= ~MUSB_RXCSR_DATAERROR;
+ 		musb_writew(epio, MUSB_RXCSR, rx_csr);
+ 
+@@ -1551,7 +1556,7 @@ static int musb_rx_dma_iso_cppi41(struct dma_controller *dma,
+ 				  struct urb *urb,
+ 				  size_t len)
+ {
+-	struct dma_channel *channel = hw_ep->tx_channel;
++	struct dma_channel *channel = hw_ep->rx_channel;
+ 	void __iomem *epio = hw_ep->regs;
+ 	dma_addr_t *buf;
+ 	u32 length, res;
+diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c
+index 2eddbe538cda..5608af4a369d 100644
+--- a/drivers/usb/serial/mos7720.c
++++ b/drivers/usb/serial/mos7720.c
+@@ -2007,6 +2007,7 @@ static void mos7720_release(struct usb_serial *serial)
+ 				    urblist_entry)
+ 			usb_unlink_urb(urbtrack->urb);
+ 		spin_unlock_irqrestore(&mos_parport->listlock, flags);
++		parport_del_port(mos_parport->pp);
+ 
+ 		kref_put(&mos_parport->ref_count, destroy_mos_parport);
+ 	}
+diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
+index 16bc679dc2fc..ecc7d4b1dfa3 100644
+--- a/drivers/usb/storage/uas.c
++++ b/drivers/usb/storage/uas.c
+@@ -835,6 +835,7 @@ static int uas_slave_configure(struct scsi_device *sdev)
+ 	if (devinfo->flags & US_FL_BROKEN_FUA)
+ 		sdev->broken_fua = 1;
+ 
++	scsi_change_queue_depth(sdev, devinfo->qdepth - 2);
+ 	return 0;
+ }
+ 
+diff --git a/include/linux/bpf.h b/include/linux/bpf.h
+index f1d5c5acc8dd..ca80d5830bfd 100644
+--- a/include/linux/bpf.h
++++ b/include/linux/bpf.h
+@@ -229,6 +229,10 @@ static inline struct bpf_prog *bpf_prog_get(u32 ufd)
+ static inline void bpf_prog_put(struct bpf_prog *prog)
+ {
+ }
++
++static inline void bpf_prog_put_rcu(struct bpf_prog *prog)
++{
++}
+ #endif /* CONFIG_BPF_SYSCALL */
+ 
+ /* verifier prototypes for helper functions called from eBPF programs */
+diff --git a/include/linux/net.h b/include/linux/net.h
+index f840d77c6c31..9d90efe6a708 100644
+--- a/include/linux/net.h
++++ b/include/linux/net.h
+@@ -252,7 +252,8 @@ do {									\
+ 	DEFINE_DYNAMIC_DEBUG_METADATA(descriptor, fmt);			\
+ 	if (unlikely(descriptor.flags & _DPRINTK_FLAGS_PRINT) &&	\
+ 	    net_ratelimit())						\
+-		__dynamic_pr_debug(&descriptor, fmt, ##__VA_ARGS__);	\
++		__dynamic_pr_debug(&descriptor, pr_fmt(fmt),		\
++		                   ##__VA_ARGS__);			\
+ } while (0)
+ #elif defined(DEBUG)
+ #define net_dbg_ratelimited(fmt, ...)				\
+diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
+index 4018b48f2b3b..a0596ca0e80a 100644
+--- a/include/linux/sock_diag.h
++++ b/include/linux/sock_diag.h
+@@ -36,6 +36,9 @@ enum sknetlink_groups sock_diag_destroy_group(const struct sock *sk)
+ {
+ 	switch (sk->sk_family) {
+ 	case AF_INET:
++		if (sk->sk_type == SOCK_RAW)
++			return SKNLGRP_NONE;
++
+ 		switch (sk->sk_protocol) {
+ 		case IPPROTO_TCP:
+ 			return SKNLGRP_INET_TCP_DESTROY;
+@@ -45,6 +48,9 @@ enum sknetlink_groups sock_diag_destroy_group(const struct sock *sk)
+ 			return SKNLGRP_NONE;
+ 		}
+ 	case AF_INET6:
++		if (sk->sk_type == SOCK_RAW)
++			return SKNLGRP_NONE;
++
+ 		switch (sk->sk_protocol) {
+ 		case IPPROTO_TCP:
+ 			return SKNLGRP_INET6_TCP_DESTROY;
+diff --git a/kernel/events/core.c b/kernel/events/core.c
+index c0ded2416615..a69c90cea05d 100644
+--- a/kernel/events/core.c
++++ b/kernel/events/core.c
+@@ -7143,7 +7143,7 @@ static void perf_event_free_bpf_prog(struct perf_event *event)
+ 	prog = event->tp_event->prog;
+ 	if (prog) {
+ 		event->tp_event->prog = NULL;
+-		bpf_prog_put(prog);
++		bpf_prog_put_rcu(prog);
+ 	}
+ }
+ 
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
+index fbd0acf80b13..2fdebabbfacd 100644
+--- a/net/ax25/af_ax25.c
++++ b/net/ax25/af_ax25.c
+@@ -976,7 +976,8 @@ static int ax25_release(struct socket *sock)
+ 			release_sock(sk);
+ 			ax25_disconnect(ax25, 0);
+ 			lock_sock(sk);
+-			ax25_destroy_socket(ax25);
++			if (!sock_flag(ax25->sk, SOCK_DESTROY))
++				ax25_destroy_socket(ax25);
+ 			break;
+ 
+ 		case AX25_STATE_3:
+diff --git a/net/ax25/ax25_ds_timer.c b/net/ax25/ax25_ds_timer.c
+index 951cd57bb07d..5237dff6941d 100644
+--- a/net/ax25/ax25_ds_timer.c
++++ b/net/ax25/ax25_ds_timer.c
+@@ -102,6 +102,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
+ 	switch (ax25->state) {
+ 
+ 	case AX25_STATE_0:
++	case AX25_STATE_2:
+ 		/* Magic here: If we listen() and a new link dies before it
+ 		   is accepted() it isn't 'dead' so doesn't get removed. */
+ 		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
+@@ -111,6 +112,7 @@ void ax25_ds_heartbeat_expiry(ax25_cb *ax25)
+ 				sock_hold(sk);
+ 				ax25_destroy_socket(ax25);
+ 				bh_unlock_sock(sk);
++				/* Ungrab socket and destroy it */
+ 				sock_put(sk);
+ 			} else
+ 				ax25_destroy_socket(ax25);
+@@ -213,7 +215,8 @@ void ax25_ds_t1_timeout(ax25_cb *ax25)
+ 	case AX25_STATE_2:
+ 		if (ax25->n2count == ax25->n2) {
+ 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
+-			ax25_disconnect(ax25, ETIMEDOUT);
++			if (!sock_flag(ax25->sk, SOCK_DESTROY))
++				ax25_disconnect(ax25, ETIMEDOUT);
+ 			return;
+ 		} else {
+ 			ax25->n2count++;
+diff --git a/net/ax25/ax25_std_timer.c b/net/ax25/ax25_std_timer.c
+index 004467c9e6e1..2c0d6ef66f9d 100644
+--- a/net/ax25/ax25_std_timer.c
++++ b/net/ax25/ax25_std_timer.c
+@@ -38,6 +38,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
+ 
+ 	switch (ax25->state) {
+ 	case AX25_STATE_0:
++	case AX25_STATE_2:
+ 		/* Magic here: If we listen() and a new link dies before it
+ 		   is accepted() it isn't 'dead' so doesn't get removed. */
+ 		if (!sk || sock_flag(sk, SOCK_DESTROY) ||
+@@ -47,6 +48,7 @@ void ax25_std_heartbeat_expiry(ax25_cb *ax25)
+ 				sock_hold(sk);
+ 				ax25_destroy_socket(ax25);
+ 				bh_unlock_sock(sk);
++				/* Ungrab socket and destroy it */
+ 				sock_put(sk);
+ 			} else
+ 				ax25_destroy_socket(ax25);
+@@ -144,7 +146,8 @@ void ax25_std_t1timer_expiry(ax25_cb *ax25)
+ 	case AX25_STATE_2:
+ 		if (ax25->n2count == ax25->n2) {
+ 			ax25_send_control(ax25, AX25_DISC, AX25_POLLON, AX25_COMMAND);
+-			ax25_disconnect(ax25, ETIMEDOUT);
++			if (!sock_flag(ax25->sk, SOCK_DESTROY))
++				ax25_disconnect(ax25, ETIMEDOUT);
+ 			return;
+ 		} else {
+ 			ax25->n2count++;
+diff --git a/net/ax25/ax25_subr.c b/net/ax25/ax25_subr.c
+index 3b78e8473a01..655a7d4c96e1 100644
+--- a/net/ax25/ax25_subr.c
++++ b/net/ax25/ax25_subr.c
+@@ -264,7 +264,8 @@ void ax25_disconnect(ax25_cb *ax25, int reason)
+ {
+ 	ax25_clear_queues(ax25);
+ 
+-	ax25_stop_heartbeat(ax25);
++	if (!sock_flag(ax25->sk, SOCK_DESTROY))
++		ax25_stop_heartbeat(ax25);
+ 	ax25_stop_t1timer(ax25);
+ 	ax25_stop_t2timer(ax25);
+ 	ax25_stop_t3timer(ax25);
+diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
+index 6852f3c7009c..43844144c9c4 100644
+--- a/net/bridge/br_multicast.c
++++ b/net/bridge/br_multicast.c
+@@ -464,8 +464,11 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
+ 	if (ipv6_dev_get_saddr(dev_net(br->dev), br->dev, &ip6h->daddr, 0,
+ 			       &ip6h->saddr)) {
+ 		kfree_skb(skb);
++		br->has_ipv6_addr = 0;
+ 		return NULL;
+ 	}
++
++	br->has_ipv6_addr = 1;
+ 	ipv6_eth_mc_map(&ip6h->daddr, eth->h_dest);
+ 
+ 	hopopt = (u8 *)(ip6h + 1);
+@@ -1745,6 +1748,7 @@ void br_multicast_init(struct net_bridge *br)
+ 	br->ip6_other_query.delay_time = 0;
+ 	br->ip6_querier.port = NULL;
+ #endif
++	br->has_ipv6_addr = 1;
+ 
+ 	spin_lock_init(&br->multicast_lock);
+ 	setup_timer(&br->multicast_router_timer,
+diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
+index d9da857182ef..f516c53bafb6 100644
+--- a/net/bridge/br_private.h
++++ b/net/bridge/br_private.h
+@@ -304,6 +304,7 @@ struct net_bridge
+ 	u8				multicast_disabled:1;
+ 	u8				multicast_querier:1;
+ 	u8				multicast_query_use_ifaddr:1;
++	u8				has_ipv6_addr:1;
+ 
+ 	u32				hash_elasticity;
+ 	u32				hash_max;
+@@ -577,10 +578,22 @@ static inline bool br_multicast_is_router(struct net_bridge *br)
+ 
+ static inline bool
+ __br_multicast_querier_exists(struct net_bridge *br,
+-			      struct bridge_mcast_other_query *querier)
++				struct bridge_mcast_other_query *querier,
++				const bool is_ipv6)
+ {
++	bool own_querier_enabled;
++
++	if (br->multicast_querier) {
++		if (is_ipv6 && !br->has_ipv6_addr)
++			own_querier_enabled = false;
++		else
++			own_querier_enabled = true;
++	} else {
++		own_querier_enabled = false;
++	}
++
+ 	return time_is_before_jiffies(querier->delay_time) &&
+-	       (br->multicast_querier || timer_pending(&querier->timer));
++	       (own_querier_enabled || timer_pending(&querier->timer));
+ }
+ 
+ static inline bool br_multicast_querier_exists(struct net_bridge *br,
+@@ -588,10 +601,12 @@ static inline bool br_multicast_querier_exists(struct net_bridge *br,
+ {
+ 	switch (eth->h_proto) {
+ 	case (htons(ETH_P_IP)):
+-		return __br_multicast_querier_exists(br, &br->ip4_other_query);
++		return __br_multicast_querier_exists(br,
++			&br->ip4_other_query, false);
+ #if IS_ENABLED(CONFIG_IPV6)
+ 	case (htons(ETH_P_IPV6)):
+-		return __br_multicast_querier_exists(br, &br->ip6_other_query);
++		return __br_multicast_querier_exists(br,
++			&br->ip6_other_query, true);
+ #endif
+ 	default:
+ 		return false;
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index f18ae91b652e..769cece9b00b 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -2467,13 +2467,17 @@ int neigh_xmit(int index, struct net_device *dev,
+ 		tbl = neigh_tables[index];
+ 		if (!tbl)
+ 			goto out;
++		rcu_read_lock_bh();
+ 		neigh = __neigh_lookup_noref(tbl, addr, dev);
+ 		if (!neigh)
+ 			neigh = __neigh_create(tbl, addr, dev, false);
+ 		err = PTR_ERR(neigh);
+-		if (IS_ERR(neigh))
++		if (IS_ERR(neigh)) {
++			rcu_read_unlock_bh();
+ 			goto out_kfree_skb;
++		}
+ 		err = neigh->output(neigh, skb);
++		rcu_read_unlock_bh();
+ 	}
+ 	else if (index == NEIGH_LINK_TABLE) {
+ 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
+index 477937465a20..d95631d09248 100644
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -23,6 +23,11 @@ struct esp_skb_cb {
+ 	void *tmp;
+ };
+ 
++struct esp_output_extra {
++	__be32 seqhi;
++	u32 esphoff;
++};
++
+ #define ESP_SKB_CB(__skb) ((struct esp_skb_cb *)&((__skb)->cb[0]))
+ 
+ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
+@@ -35,11 +40,11 @@ static u32 esp4_get_mtu(struct xfrm_state *x, int mtu);
+  *
+  * TODO: Use spare space in skb for this where possible.
+  */
+-static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen)
++static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int extralen)
+ {
+ 	unsigned int len;
+ 
+-	len = seqhilen;
++	len = extralen;
+ 
+ 	len += crypto_aead_ivsize(aead);
+ 
+@@ -57,15 +62,16 @@ static void *esp_alloc_tmp(struct crypto_aead *aead, int nfrags, int seqhilen)
+ 	return kmalloc(len, GFP_ATOMIC);
+ }
+ 
+-static inline __be32 *esp_tmp_seqhi(void *tmp)
++static inline void *esp_tmp_extra(void *tmp)
+ {
+-	return PTR_ALIGN((__be32 *)tmp, __alignof__(__be32));
++	return PTR_ALIGN(tmp, __alignof__(struct esp_output_extra));
+ }
+-static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int seqhilen)
++
++static inline u8 *esp_tmp_iv(struct crypto_aead *aead, void *tmp, int extralen)
+ {
+ 	return crypto_aead_ivsize(aead) ?
+-	       PTR_ALIGN((u8 *)tmp + seqhilen,
+-			 crypto_aead_alignmask(aead) + 1) : tmp + seqhilen;
++	       PTR_ALIGN((u8 *)tmp + extralen,
++			 crypto_aead_alignmask(aead) + 1) : tmp + extralen;
+ }
+ 
+ static inline struct aead_request *esp_tmp_req(struct crypto_aead *aead, u8 *iv)
+@@ -99,7 +105,7 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset)
+ {
+ 	struct ip_esp_hdr *esph = (void *)(skb->data + offset);
+ 	void *tmp = ESP_SKB_CB(skb)->tmp;
+-	__be32 *seqhi = esp_tmp_seqhi(tmp);
++	__be32 *seqhi = esp_tmp_extra(tmp);
+ 
+ 	esph->seq_no = esph->spi;
+ 	esph->spi = *seqhi;
+@@ -107,7 +113,11 @@ static void esp_restore_header(struct sk_buff *skb, unsigned int offset)
+ 
+ static void esp_output_restore_header(struct sk_buff *skb)
+ {
+-	esp_restore_header(skb, skb_transport_offset(skb) - sizeof(__be32));
++	void *tmp = ESP_SKB_CB(skb)->tmp;
++	struct esp_output_extra *extra = esp_tmp_extra(tmp);
++
++	esp_restore_header(skb, skb_transport_offset(skb) + extra->esphoff -
++				sizeof(__be32));
+ }
+ 
+ static void esp_output_done_esn(struct crypto_async_request *base, int err)
+@@ -121,6 +131,7 @@ static void esp_output_done_esn(struct crypto_async_request *base, int err)
+ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
+ {
+ 	int err;
++	struct esp_output_extra *extra;
+ 	struct ip_esp_hdr *esph;
+ 	struct crypto_aead *aead;
+ 	struct aead_request *req;
+@@ -137,8 +148,7 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
+ 	int tfclen;
+ 	int nfrags;
+ 	int assoclen;
+-	int seqhilen;
+-	__be32 *seqhi;
++	int extralen;
+ 	__be64 seqno;
+ 
+ 	/* skb is pure payload to encrypt */
+@@ -166,21 +176,21 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
+ 	nfrags = err;
+ 
+ 	assoclen = sizeof(*esph);
+-	seqhilen = 0;
++	extralen = 0;
+ 
+ 	if (x->props.flags & XFRM_STATE_ESN) {
+-		seqhilen += sizeof(__be32);
+-		assoclen += seqhilen;
++		extralen += sizeof(*extra);
++		assoclen += sizeof(__be32);
+ 	}
+ 
+-	tmp = esp_alloc_tmp(aead, nfrags, seqhilen);
++	tmp = esp_alloc_tmp(aead, nfrags, extralen);
+ 	if (!tmp) {
+ 		err = -ENOMEM;
+ 		goto error;
+ 	}
+ 
+-	seqhi = esp_tmp_seqhi(tmp);
+-	iv = esp_tmp_iv(aead, tmp, seqhilen);
++	extra = esp_tmp_extra(tmp);
++	iv = esp_tmp_iv(aead, tmp, extralen);
+ 	req = esp_tmp_req(aead, iv);
+ 	sg = esp_req_sg(aead, req);
+ 
+@@ -247,8 +257,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
+ 	 * encryption.
+ 	 */
+ 	if ((x->props.flags & XFRM_STATE_ESN)) {
+-		esph = (void *)(skb_transport_header(skb) - sizeof(__be32));
+-		*seqhi = esph->spi;
++		extra->esphoff = (unsigned char *)esph -
++				 skb_transport_header(skb);
++		esph = (struct ip_esp_hdr *)((unsigned char *)esph - 4);
++		extra->seqhi = esph->spi;
+ 		esph->seq_no = htonl(XFRM_SKB_CB(skb)->seq.output.hi);
+ 		aead_request_set_callback(req, 0, esp_output_done_esn, skb);
+ 	}
+@@ -445,7 +457,7 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
+ 		goto out;
+ 
+ 	ESP_SKB_CB(skb)->tmp = tmp;
+-	seqhi = esp_tmp_seqhi(tmp);
++	seqhi = esp_tmp_extra(tmp);
+ 	iv = esp_tmp_iv(aead, tmp, seqhilen);
+ 	req = esp_tmp_req(aead, iv);
+ 	sg = esp_req_sg(aead, req);
+diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
+index 395e2814a46d..a42dd8021b6b 100644
+--- a/net/ipv4/ipmr.c
++++ b/net/ipv4/ipmr.c
+@@ -891,8 +891,10 @@ static struct mfc_cache *ipmr_cache_alloc(void)
+ {
+ 	struct mfc_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
+ 
+-	if (c)
++	if (c) {
++		c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
+ 		c->mfc_un.res.minvif = MAXVIFS;
++	}
+ 	return c;
+ }
+ 
+diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
+index a10e77103c88..e207cb2468da 100644
+--- a/net/ipv6/ip6mr.c
++++ b/net/ipv6/ip6mr.c
+@@ -1074,6 +1074,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
+ 	struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
+ 	if (!c)
+ 		return NULL;
++	c->mfc_un.res.last_assert = jiffies - MFC_ASSERT_THRESH - 1;
+ 	c->mfc_un.res.minvif = MAXMIFS;
+ 	return c;
+ }
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index 83384308d032..6c53e4eb0f09 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -560,13 +560,13 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
+ 
+ 	if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
+ 		ipv4_update_pmtu(skb, dev_net(skb->dev), info,
+-				 t->parms.link, 0, IPPROTO_IPV6, 0);
++				 t->parms.link, 0, iph->protocol, 0);
+ 		err = 0;
+ 		goto out;
+ 	}
+ 	if (type == ICMP_REDIRECT) {
+ 		ipv4_redirect(skb, dev_net(skb->dev), t->parms.link, 0,
+-			      IPPROTO_IPV6, 0);
++			      iph->protocol, 0);
+ 		err = 0;
+ 		goto out;
+ 	}
+diff --git a/net/kcm/kcmproc.c b/net/kcm/kcmproc.c
+index 738008726cc6..fda7f4715c58 100644
+--- a/net/kcm/kcmproc.c
++++ b/net/kcm/kcmproc.c
+@@ -241,6 +241,7 @@ static const struct file_operations kcm_seq_fops = {
+ 	.open		= kcm_seq_open,
+ 	.read		= seq_read,
+ 	.llseek		= seq_lseek,
++	.release	= seq_release_net,
+ };
+ 
+ static struct kcm_seq_muxinfo kcm_seq_muxinfo = {
+diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c
+index 8b5270008a6e..606323339e1f 100644
+--- a/net/sched/act_ipt.c
++++ b/net/sched/act_ipt.c
+@@ -121,10 +121,13 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla,
+ 	}
+ 
+ 	td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]);
+-	if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size)
++	if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) {
++		if (exists)
++			tcf_hash_release(a, bind);
+ 		return -EINVAL;
++	}
+ 
+-	if (!tcf_hash_check(tn, index, a, bind)) {
++	if (!exists) {
+ 		ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind,
+ 				      false);
+ 		if (ret)
+diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
+index 2177eac0a61e..2e4bd2c0a50c 100644
+--- a/net/sched/sch_fifo.c
++++ b/net/sched/sch_fifo.c
+@@ -37,14 +37,18 @@ static int pfifo_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+ 
+ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+ {
++	unsigned int prev_backlog;
++
+ 	if (likely(skb_queue_len(&sch->q) < sch->limit))
+ 		return qdisc_enqueue_tail(skb, sch);
+ 
++	prev_backlog = sch->qstats.backlog;
+ 	/* queue full, remove one skb to fulfill the limit */
+ 	__qdisc_queue_drop_head(sch, &sch->q);
+ 	qdisc_qstats_drop(sch);
+ 	qdisc_enqueue_tail(skb, sch);
+ 
++	qdisc_tree_reduce_backlog(sch, 0, prev_backlog - sch->qstats.backlog);
+ 	return NET_XMIT_CN;
+ }
+ 
+diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c
+index 4befe97a9034..b7c29d5b6f04 100644
+--- a/net/sched/sch_netem.c
++++ b/net/sched/sch_netem.c
+@@ -650,14 +650,14 @@ deliver:
+ #endif
+ 
+ 			if (q->qdisc) {
++				unsigned int pkt_len = qdisc_pkt_len(skb);
+ 				int err = qdisc_enqueue(skb, q->qdisc);
+ 
+-				if (unlikely(err != NET_XMIT_SUCCESS)) {
+-					if (net_xmit_drop_count(err)) {
+-						qdisc_qstats_drop(sch);
+-						qdisc_tree_reduce_backlog(sch, 1,
+-									  qdisc_pkt_len(skb));
+-					}
++				if (err != NET_XMIT_SUCCESS &&
++				    net_xmit_drop_count(err)) {
++					qdisc_qstats_drop(sch);
++					qdisc_tree_reduce_backlog(sch, 1,
++								  pkt_len);
+ 				}
+ 				goto tfifo_dequeue;
+ 			}


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

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

commit:     221739056950edff86a332751f03ac75fb232f2e
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 27 19:23:26 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Jul 27 19:23:26 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=22173905

Linux patch 4.6.5

 0000_README            |    4 +
 1004_linux-4.6.5.patch | 7262 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 7266 insertions(+)

diff --git a/0000_README b/0000_README
index 5c841a9..67da565 100644
--- a/0000_README
+++ b/0000_README
@@ -59,6 +59,10 @@ Patch:  1003_linux-4.6.4.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.4
 
+Patch:  1004_linux-4.6.5.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.5
+
 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.6.5.patch b/1004_linux-4.6.5.patch
new file mode 100644
index 0000000..21cc942
--- /dev/null
+++ b/1004_linux-4.6.5.patch
@@ -0,0 +1,7262 @@
+diff --git a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935 b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
+index 6708c5e264aa..33e96f740639 100644
+--- a/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
++++ b/Documentation/ABI/testing/sysfs-bus-iio-proximity-as3935
+@@ -1,4 +1,4 @@
+-What		/sys/bus/iio/devices/iio:deviceX/in_proximity_raw
++What		/sys/bus/iio/devices/iio:deviceX/in_proximity_input
+ Date:		March 2014
+ KernelVersion:	3.15
+ Contact:	Matt Ranostay <mranostay@gmail.com>
+diff --git a/Documentation/scsi/scsi_eh.txt b/Documentation/scsi/scsi_eh.txt
+index 8638f61c8c9d..37eca00796ee 100644
+--- a/Documentation/scsi/scsi_eh.txt
++++ b/Documentation/scsi/scsi_eh.txt
+@@ -263,19 +263,23 @@ scmd->allowed.
+ 
+  3. scmd recovered
+     ACTION: scsi_eh_finish_cmd() is invoked to EH-finish scmd
+-	- shost->host_failed--
+ 	- clear scmd->eh_eflags
+ 	- scsi_setup_cmd_retry()
+ 	- move from local eh_work_q to local eh_done_q
+     LOCKING: none
++    CONCURRENCY: at most one thread per separate eh_work_q to
++		 keep queue manipulation lockless
+ 
+  4. EH completes
+     ACTION: scsi_eh_flush_done_q() retries scmds or notifies upper
+-	    layer of failure.
++	    layer of failure. May be called concurrently but must have
++	    a no more than one thread per separate eh_work_q to
++	    manipulate the queue locklessly
+ 	- scmd is removed from eh_done_q and scmd->eh_entry is cleared
+ 	- if retry is necessary, scmd is requeued using
+           scsi_queue_insert()
+ 	- otherwise, scsi_finish_command() is invoked for scmd
++	- zero shost->host_failed
+     LOCKING: queue or finish function performs appropriate locking
+ 
+ 
+diff --git a/Makefile b/Makefile
+index cd374426114a..7d693a825fc7 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 4
++SUBLEVEL = 5
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+diff --git a/arch/arm/boot/dts/armada-385-linksys.dtsi b/arch/arm/boot/dts/armada-385-linksys.dtsi
+index 8450944b28e6..22f7a13e20b4 100644
+--- a/arch/arm/boot/dts/armada-385-linksys.dtsi
++++ b/arch/arm/boot/dts/armada-385-linksys.dtsi
+@@ -58,8 +58,8 @@
+ 	soc {
+ 		ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+ 			  MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+-			  MBUS_ID(0x09, 0x09) 0 0xf1100000 0x10000
+-			  MBUS_ID(0x09, 0x05) 0 0xf1110000 0x10000>;
++			  MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
++			  MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000>;
+ 
+ 		internal-regs {
+ 
+diff --git a/arch/arm/boot/dts/sun5i-r8-chip.dts b/arch/arm/boot/dts/sun5i-r8-chip.dts
+index f6898c6b84d4..c937c85ffb45 100644
+--- a/arch/arm/boot/dts/sun5i-r8-chip.dts
++++ b/arch/arm/boot/dts/sun5i-r8-chip.dts
+@@ -52,7 +52,7 @@
+ 
+ / {
+ 	model = "NextThing C.H.I.P.";
+-	compatible = "nextthing,chip", "allwinner,sun5i-r8";
++	compatible = "nextthing,chip", "allwinner,sun5i-r8", "allwinner,sun5i-a13";
+ 
+ 	aliases {
+ 		i2c0 = &i2c0;
+diff --git a/arch/arm/boot/dts/sun6i-a31s-primo81.dts b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+index 68b479b8772c..73c133f5e79c 100644
+--- a/arch/arm/boot/dts/sun6i-a31s-primo81.dts
++++ b/arch/arm/boot/dts/sun6i-a31s-primo81.dts
+@@ -176,8 +176,6 @@
+ };
+ 
+ &reg_dc1sw {
+-	regulator-min-microvolt = <3000000>;
+-	regulator-max-microvolt = <3000000>;
+ 	regulator-name = "vcc-lcd";
+ };
+ 
+diff --git a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
+index 360adfb1e9ca..d6ad6196a768 100644
+--- a/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
++++ b/arch/arm/boot/dts/sun6i-a31s-yones-toptech-bs1078-v2.dts
+@@ -135,8 +135,6 @@
+ 
+ &reg_dc1sw {
+ 	regulator-name = "vcc-lcd-usb2";
+-	regulator-min-microvolt = <3000000>;
+-	regulator-max-microvolt = <3000000>;
+ };
+ 
+ &reg_dc5ldo {
+diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
+index aeddd28b3595..92fd2c8a9af0 100644
+--- a/arch/arm/include/asm/pgtable-2level.h
++++ b/arch/arm/include/asm/pgtable-2level.h
+@@ -193,6 +193,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+ 
+ #define pmd_large(pmd)		(pmd_val(pmd) & 2)
+ #define pmd_bad(pmd)		(pmd_val(pmd) & 2)
++#define pmd_present(pmd)	(pmd_val(pmd))
+ 
+ #define copy_pmd(pmdpd,pmdps)		\
+ 	do {				\
+diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
+index dc46398bc3a5..74114667d116 100644
+--- a/arch/arm/include/asm/pgtable-3level.h
++++ b/arch/arm/include/asm/pgtable-3level.h
+@@ -211,6 +211,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
+ 						: !!(pmd_val(pmd) & (val)))
+ #define pmd_isclear(pmd, val)	(!(pmd_val(pmd) & (val)))
+ 
++#define pmd_present(pmd)	(pmd_isset((pmd), L_PMD_SECT_VALID))
+ #define pmd_young(pmd)		(pmd_isset((pmd), PMD_SECT_AF))
+ #define pte_special(pte)	(pte_isset((pte), L_PTE_SPECIAL))
+ static inline pte_t pte_mkspecial(pte_t pte)
+@@ -249,10 +250,10 @@ PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
+ #define pfn_pmd(pfn,prot)	(__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
+ #define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
+ 
+-/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
++/* represent a notpresent pmd by faulting entry, this is used by pmdp_invalidate */
+ static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+ {
+-	return __pmd(0);
++	return __pmd(pmd_val(pmd) & ~L_PMD_SECT_VALID);
+ }
+ 
+ static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
+diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
+index 348caabb7625..d62204060cbe 100644
+--- a/arch/arm/include/asm/pgtable.h
++++ b/arch/arm/include/asm/pgtable.h
+@@ -182,7 +182,6 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
+ #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
+ 
+ #define pmd_none(pmd)		(!pmd_val(pmd))
+-#define pmd_present(pmd)	(pmd_val(pmd))
+ 
+ static inline pte_t *pmd_page_vaddr(pmd_t pmd)
+ {
+diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
+index dded1b763c16..72b11d91ede2 100644
+--- a/arch/arm/kvm/arm.c
++++ b/arch/arm/kvm/arm.c
+@@ -267,6 +267,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
+ 	kvm_timer_vcpu_terminate(vcpu);
+ 	kvm_vgic_vcpu_destroy(vcpu);
+ 	kvm_pmu_vcpu_destroy(vcpu);
++	kvm_vcpu_uninit(vcpu);
+ 	kmem_cache_free(kvm_vcpu_cache, vcpu);
+ }
+ 
+diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c
+index a38b16b69923..b56de4b8cdf2 100644
+--- a/arch/arm/mach-imx/mach-imx6ul.c
++++ b/arch/arm/mach-imx/mach-imx6ul.c
+@@ -46,7 +46,7 @@ static int ksz8081_phy_fixup(struct phy_device *dev)
+ static void __init imx6ul_enet_phy_init(void)
+ {
+ 	if (IS_BUILTIN(CONFIG_PHYLIB))
+-		phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff,
++		phy_register_fixup_for_uid(PHY_ID_KSZ8081, MICREL_PHY_ID_MASK,
+ 					   ksz8081_phy_fixup);
+ }
+ 
+diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
+index 7e989d61159c..474abff7e855 100644
+--- a/arch/arm/mach-mvebu/coherency.c
++++ b/arch/arm/mach-mvebu/coherency.c
+@@ -162,22 +162,16 @@ exit:
+ }
+ 
+ /*
+- * This ioremap hook is used on Armada 375/38x to ensure that PCIe
+- * memory areas are mapped as MT_UNCACHED instead of MT_DEVICE. This
+- * is needed as a workaround for a deadlock issue between the PCIe
+- * interface and the cache controller.
++ * This ioremap hook is used on Armada 375/38x to ensure that all MMIO
++ * areas are mapped as MT_UNCACHED instead of MT_DEVICE. This is
++ * needed for the HW I/O coherency mechanism to work properly without
++ * deadlock.
+  */
+ static void __iomem *
+-armada_pcie_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
+-			      unsigned int mtype, void *caller)
++armada_wa_ioremap_caller(phys_addr_t phys_addr, size_t size,
++			 unsigned int mtype, void *caller)
+ {
+-	struct resource pcie_mem;
+-
+-	mvebu_mbus_get_pcie_mem_aperture(&pcie_mem);
+-
+-	if (pcie_mem.start <= phys_addr && (phys_addr + size) <= pcie_mem.end)
+-		mtype = MT_UNCACHED;
+-
++	mtype = MT_UNCACHED;
+ 	return __arm_ioremap_caller(phys_addr, size, mtype, caller);
+ }
+ 
+@@ -186,7 +180,7 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
+ 	struct device_node *cache_dn;
+ 
+ 	coherency_cpu_base = of_iomap(np, 0);
+-	arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
++	arch_ioremap_caller = armada_wa_ioremap_caller;
+ 
+ 	/*
+ 	 * We should switch the PL310 to I/O coherency mode only if
+diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h
+index a307eb6e7fa8..7f94755089e2 100644
+--- a/arch/arm64/include/asm/ptrace.h
++++ b/arch/arm64/include/asm/ptrace.h
+@@ -117,6 +117,8 @@ struct pt_regs {
+ 	};
+ 	u64 orig_x0;
+ 	u64 syscallno;
++	u64 orig_addr_limit;
++	u64 unused;	// maintain 16 byte alignment
+ };
+ 
+ #define arch_has_single_step()	(1)
+diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c
+index 3ae6b310ac9b..1abcd8829f3b 100644
+--- a/arch/arm64/kernel/asm-offsets.c
++++ b/arch/arm64/kernel/asm-offsets.c
+@@ -59,6 +59,7 @@ int main(void)
+   DEFINE(S_PC,			offsetof(struct pt_regs, pc));
+   DEFINE(S_ORIG_X0,		offsetof(struct pt_regs, orig_x0));
+   DEFINE(S_SYSCALLNO,		offsetof(struct pt_regs, syscallno));
++  DEFINE(S_ORIG_ADDR_LIMIT,	offsetof(struct pt_regs, orig_addr_limit));
+   DEFINE(S_FRAME_SIZE,		sizeof(struct pt_regs));
+   BLANK();
+   DEFINE(MM_CONTEXT_ID,		offsetof(struct mm_struct, context.id.counter));
+diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S
+index 12e8d2bcb3f9..6c3b7345a6c4 100644
+--- a/arch/arm64/kernel/entry.S
++++ b/arch/arm64/kernel/entry.S
+@@ -28,6 +28,7 @@
+ #include <asm/errno.h>
+ #include <asm/esr.h>
+ #include <asm/irq.h>
++#include <asm/memory.h>
+ #include <asm/thread_info.h>
+ #include <asm/unistd.h>
+ 
+@@ -97,7 +98,14 @@
+ 	mov	x29, xzr			// fp pointed to user-space
+ 	.else
+ 	add	x21, sp, #S_FRAME_SIZE
+-	.endif
++	get_thread_info tsk
++	/* Save the task's original addr_limit and set USER_DS (TASK_SIZE_64) */
++	ldr	x20, [tsk, #TI_ADDR_LIMIT]
++	str	x20, [sp, #S_ORIG_ADDR_LIMIT]
++	mov	x20, #TASK_SIZE_64
++	str	x20, [tsk, #TI_ADDR_LIMIT]
++	ALTERNATIVE(nop, SET_PSTATE_UAO(0), ARM64_HAS_UAO, CONFIG_ARM64_UAO)
++	.endif /* \el == 0 */
+ 	mrs	x22, elr_el1
+ 	mrs	x23, spsr_el1
+ 	stp	lr, x21, [sp, #S_LR]
+@@ -128,6 +136,14 @@
+ 	.endm
+ 
+ 	.macro	kernel_exit, el
++	.if	\el != 0
++	/* Restore the task's original addr_limit. */
++	ldr	x20, [sp, #S_ORIG_ADDR_LIMIT]
++	str	x20, [tsk, #TI_ADDR_LIMIT]
++
++	/* No need to restore UAO, it will be restored from SPSR_EL1 */
++	.endif
++
+ 	ldp	x21, x22, [sp, #S_PC]		// load ELR, SPSR
+ 	.if	\el == 0
+ 	ct_user_enter
+@@ -406,7 +422,6 @@ el1_irq:
+ 	bl	trace_hardirqs_off
+ #endif
+ 
+-	get_thread_info tsk
+ 	irq_handler
+ 
+ #ifdef CONFIG_PREEMPT
+diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
+index c5392081b49b..58651a9dfcf8 100644
+--- a/arch/arm64/kernel/traps.c
++++ b/arch/arm64/kernel/traps.c
+@@ -64,8 +64,7 @@ static void dump_mem(const char *lvl, const char *str, unsigned long bottom,
+ 
+ 	/*
+ 	 * We need to switch to kernel mode so that we can use __get_user
+-	 * to safely read from kernel space.  Note that we now dump the
+-	 * code first, just in case the backtrace kills us.
++	 * to safely read from kernel space.
+ 	 */
+ 	fs = get_fs();
+ 	set_fs(KERNEL_DS);
+@@ -111,21 +110,12 @@ static void dump_backtrace_entry(unsigned long where)
+ 	print_ip_sym(where);
+ }
+ 
+-static void dump_instr(const char *lvl, struct pt_regs *regs)
++static void __dump_instr(const char *lvl, struct pt_regs *regs)
+ {
+ 	unsigned long addr = instruction_pointer(regs);
+-	mm_segment_t fs;
+ 	char str[sizeof("00000000 ") * 5 + 2 + 1], *p = str;
+ 	int i;
+ 
+-	/*
+-	 * We need to switch to kernel mode so that we can use __get_user
+-	 * to safely read from kernel space.  Note that we now dump the
+-	 * code first, just in case the backtrace kills us.
+-	 */
+-	fs = get_fs();
+-	set_fs(KERNEL_DS);
+-
+ 	for (i = -4; i < 1; i++) {
+ 		unsigned int val, bad;
+ 
+@@ -139,8 +129,18 @@ static void dump_instr(const char *lvl, struct pt_regs *regs)
+ 		}
+ 	}
+ 	printk("%sCode: %s\n", lvl, str);
++}
+ 
+-	set_fs(fs);
++static void dump_instr(const char *lvl, struct pt_regs *regs)
++{
++	if (!user_mode(regs)) {
++		mm_segment_t fs = get_fs();
++		set_fs(KERNEL_DS);
++		__dump_instr(lvl, regs);
++		set_fs(fs);
++	} else {
++		__dump_instr(lvl, regs);
++	}
+ }
+ 
+ static void dump_backtrace(struct pt_regs *regs, struct task_struct *tsk)
+diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
+index 10b79e9e87d1..e22849a90557 100644
+--- a/arch/arm64/mm/fault.c
++++ b/arch/arm64/mm/fault.c
+@@ -284,7 +284,8 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr,
+ 	}
+ 
+ 	if (permission_fault(esr) && (addr < USER_DS)) {
+-		if (get_fs() == KERNEL_DS)
++		/* regs->orig_addr_limit may be 0 if we entered from EL0 */
++		if (regs->orig_addr_limit == KERNEL_DS)
+ 			die("Accessing user space memory with fs=KERNEL_DS", regs, esr);
+ 
+ 		if (!search_exception_tables(regs->pc))
+diff --git a/arch/arm64/mm/flush.c b/arch/arm64/mm/flush.c
+index dbd12ea8ce68..43a76b07eb32 100644
+--- a/arch/arm64/mm/flush.c
++++ b/arch/arm64/mm/flush.c
+@@ -71,10 +71,6 @@ void __sync_icache_dcache(pte_t pte, unsigned long addr)
+ {
+ 	struct page *page = pte_page(pte);
+ 
+-	/* no flushing needed for anonymous pages */
+-	if (!page_mapping(page))
+-		return;
+-
+ 	if (!test_and_set_bit(PG_dcache_clean, &page->flags))
+ 		sync_icache_aliases(page_address(page),
+ 				    PAGE_SIZE << compound_order(page));
+diff --git a/arch/mips/include/asm/kvm_host.h b/arch/mips/include/asm/kvm_host.h
+index 942b8f6bf35b..1907ab379fad 100644
+--- a/arch/mips/include/asm/kvm_host.h
++++ b/arch/mips/include/asm/kvm_host.h
+@@ -336,6 +336,7 @@ struct kvm_mips_tlb {
+ #define KVM_MIPS_GUEST_TLB_SIZE	64
+ struct kvm_vcpu_arch {
+ 	void *host_ebase, *guest_ebase;
++	int (*vcpu_run)(struct kvm_run *run, struct kvm_vcpu *vcpu);
+ 	unsigned long host_stack;
+ 	unsigned long host_gp;
+ 
+diff --git a/arch/mips/kvm/interrupt.h b/arch/mips/kvm/interrupt.h
+index 4ab4bdfad703..2143884709e4 100644
+--- a/arch/mips/kvm/interrupt.h
++++ b/arch/mips/kvm/interrupt.h
+@@ -28,6 +28,7 @@
+ #define MIPS_EXC_MAX                12
+ /* XXXSL More to follow */
+ 
++extern char __kvm_mips_vcpu_run_end[];
+ extern char mips32_exception[], mips32_exceptionEnd[];
+ extern char mips32_GuestException[], mips32_GuestExceptionEnd[];
+ 
+diff --git a/arch/mips/kvm/locore.S b/arch/mips/kvm/locore.S
+index 81687ab1b523..fc93a08b6954 100644
+--- a/arch/mips/kvm/locore.S
++++ b/arch/mips/kvm/locore.S
+@@ -227,6 +227,7 @@ FEXPORT(__kvm_mips_load_k0k1)
+ 
+ 	/* Jump to guest */
+ 	eret
++EXPORT(__kvm_mips_vcpu_run_end)
+ 
+ VECTOR(MIPSX(exception), unknown)
+ /* Find out what mode we came from and jump to the proper handler. */
+diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
+index 70ef1a43c114..e223cb3d9e81 100644
+--- a/arch/mips/kvm/mips.c
++++ b/arch/mips/kvm/mips.c
+@@ -314,6 +314,15 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
+ 	memcpy(gebase + offset, mips32_GuestException,
+ 	       mips32_GuestExceptionEnd - mips32_GuestException);
+ 
++#ifdef MODULE
++	offset += mips32_GuestExceptionEnd - mips32_GuestException;
++	memcpy(gebase + offset, (char *)__kvm_mips_vcpu_run,
++	       __kvm_mips_vcpu_run_end - (char *)__kvm_mips_vcpu_run);
++	vcpu->arch.vcpu_run = gebase + offset;
++#else
++	vcpu->arch.vcpu_run = __kvm_mips_vcpu_run;
++#endif
++
+ 	/* Invalidate the icache for these ranges */
+ 	local_flush_icache_range((unsigned long)gebase,
+ 				(unsigned long)gebase + ALIGN(size, PAGE_SIZE));
+@@ -403,7 +412,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
+ 	/* Disable hardware page table walking while in guest */
+ 	htw_stop();
+ 
+-	r = __kvm_mips_vcpu_run(run, vcpu);
++	r = vcpu->arch.vcpu_run(run, vcpu);
+ 
+ 	/* Re-enable HTW before enabling interrupts */
+ 	htw_start();
+diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
+index b8500b4ac7fe..bec85055fc42 100644
+--- a/arch/powerpc/kernel/process.c
++++ b/arch/powerpc/kernel/process.c
+@@ -1501,6 +1501,16 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
+ 		current->thread.regs = regs - 1;
+ 	}
+ 
++#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
++	/*
++	 * Clear any transactional state, we're exec()ing. The cause is
++	 * not important as there will never be a recheckpoint so it's not
++	 * user visible.
++	 */
++	if (MSR_TM_SUSPENDED(mfmsr()))
++		tm_reclaim_current(0);
++#endif
++
+ 	memset(regs->gpr, 0, sizeof(regs->gpr));
+ 	regs->ctr = 0;
+ 	regs->link = 0;
+diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
+index ccd2037c797f..6ee4b72cda42 100644
+--- a/arch/powerpc/kernel/prom_init.c
++++ b/arch/powerpc/kernel/prom_init.c
+@@ -719,7 +719,7 @@ unsigned char ibm_architecture_vec[] = {
+ 	 * must match by the macro below. Update the definition if
+ 	 * the structure layout changes.
+ 	 */
+-#define IBM_ARCH_VEC_NRCORES_OFFSET	125
++#define IBM_ARCH_VEC_NRCORES_OFFSET	133
+ 	W(NR_CPUS),			/* number of cores supported */
+ 	0,
+ 	0,
+diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
+index bd98ce2be17b..3e8865b187de 100644
+--- a/arch/powerpc/platforms/pseries/iommu.c
++++ b/arch/powerpc/platforms/pseries/iommu.c
+@@ -912,7 +912,8 @@ machine_arch_initcall(pseries, find_existing_ddw_windows);
+ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
+ 			struct ddw_query_response *query)
+ {
+-	struct eeh_dev *edev;
++	struct device_node *dn;
++	struct pci_dn *pdn;
+ 	u32 cfg_addr;
+ 	u64 buid;
+ 	int ret;
+@@ -923,11 +924,10 @@ static int query_ddw(struct pci_dev *dev, const u32 *ddw_avail,
+ 	 * Retrieve them from the pci device, not the node with the
+ 	 * dma-window property
+ 	 */
+-	edev = pci_dev_to_eeh_dev(dev);
+-	cfg_addr = edev->config_addr;
+-	if (edev->pe_config_addr)
+-		cfg_addr = edev->pe_config_addr;
+-	buid = edev->phb->buid;
++	dn = pci_device_to_OF_node(dev);
++	pdn = PCI_DN(dn);
++	buid = pdn->phb->buid;
++	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
+ 
+ 	ret = rtas_call(ddw_avail[0], 3, 5, (u32 *)query,
+ 		  cfg_addr, BUID_HI(buid), BUID_LO(buid));
+@@ -941,7 +941,8 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
+ 			struct ddw_create_response *create, int page_shift,
+ 			int window_shift)
+ {
+-	struct eeh_dev *edev;
++	struct device_node *dn;
++	struct pci_dn *pdn;
+ 	u32 cfg_addr;
+ 	u64 buid;
+ 	int ret;
+@@ -952,11 +953,10 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
+ 	 * Retrieve them from the pci device, not the node with the
+ 	 * dma-window property
+ 	 */
+-	edev = pci_dev_to_eeh_dev(dev);
+-	cfg_addr = edev->config_addr;
+-	if (edev->pe_config_addr)
+-		cfg_addr = edev->pe_config_addr;
+-	buid = edev->phb->buid;
++	dn = pci_device_to_OF_node(dev);
++	pdn = PCI_DN(dn);
++	buid = pdn->phb->buid;
++	cfg_addr = ((pdn->busno << 16) | (pdn->devfn << 8));
+ 
+ 	do {
+ 		/* extra outputs are LIOBN and dma-addr (hi, lo) */
+diff --git a/arch/s390/include/asm/fpu/api.h b/arch/s390/include/asm/fpu/api.h
+index 5e04f3cbd320..8ae236b0f80b 100644
+--- a/arch/s390/include/asm/fpu/api.h
++++ b/arch/s390/include/asm/fpu/api.h
+@@ -22,7 +22,7 @@ static inline int test_fp_ctl(u32 fpc)
+ 		"	la	%0,0\n"
+ 		"1:\n"
+ 		EX_TABLE(0b,1b)
+-		: "=d" (rc), "=d" (orig_fpc)
++		: "=d" (rc), "=&d" (orig_fpc)
+ 		: "d" (fpc), "0" (-EINVAL));
+ 	return rc;
+ }
+diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
+index f20abdb5630a..d14069d4b88d 100644
+--- a/arch/s390/kernel/ipl.c
++++ b/arch/s390/kernel/ipl.c
+@@ -2064,12 +2064,5 @@ void s390_reset_system(void)
+ 	S390_lowcore.program_new_psw.addr =
+ 		(unsigned long) s390_base_pgm_handler;
+ 
+-	/*
+-	 * Clear subchannel ID and number to signal new kernel that no CCW or
+-	 * SCSI IPL has been done (for kexec and kdump)
+-	 */
+-	S390_lowcore.subchannel_id = 0;
+-	S390_lowcore.subchannel_nr = 0;
+-
+ 	do_reset_calls();
+ }
+diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
+index 4324b87f9398..9f0ce0e6eeb4 100644
+--- a/arch/s390/mm/pgtable.c
++++ b/arch/s390/mm/pgtable.c
+@@ -437,7 +437,7 @@ void ptep_zap_unused(struct mm_struct *mm, unsigned long addr,
+ 	pgste = pgste_get_lock(ptep);
+ 	pgstev = pgste_val(pgste);
+ 	pte = *ptep;
+-	if (pte_swap(pte) &&
++	if (!reset && pte_swap(pte) &&
+ 	    ((pgstev & _PGSTE_GPS_USAGE_MASK) == _PGSTE_GPS_USAGE_UNUSED ||
+ 	     (pgstev & _PGSTE_GPS_ZERO))) {
+ 		ptep_zap_swap_entry(mm, pte_to_swp_entry(pte));
+diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile
+index b1ef9e489084..b67f9e8b93a6 100644
+--- a/arch/x86/boot/Makefile
++++ b/arch/x86/boot/Makefile
+@@ -171,6 +171,9 @@ isoimage: $(obj)/bzImage
+ 	for i in lib lib64 share end ; do \
+ 		if [ -f /usr/$$i/syslinux/isolinux.bin ] ; then \
+ 			cp /usr/$$i/syslinux/isolinux.bin $(obj)/isoimage ; \
++			if [ -f /usr/$$i/syslinux/ldlinux.c32 ]; then \
++				cp /usr/$$i/syslinux/ldlinux.c32 $(obj)/isoimage ; \
++			fi ; \
+ 			break ; \
+ 		fi ; \
+ 		if [ $$i = end ] ; then exit 1 ; fi ; \
+diff --git a/arch/x86/events/core.c b/arch/x86/events/core.c
+index 041e442a3e28..7eb806ca6b03 100644
+--- a/arch/x86/events/core.c
++++ b/arch/x86/events/core.c
+@@ -2313,7 +2313,7 @@ void
+ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+ {
+ 	struct stack_frame frame;
+-	const void __user *fp;
++	const unsigned long __user *fp;
+ 
+ 	if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) {
+ 		/* TODO: We don't support guest os callchain now */
+@@ -2326,7 +2326,7 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+ 	if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM))
+ 		return;
+ 
+-	fp = (void __user *)regs->bp;
++	fp = (unsigned long __user *)regs->bp;
+ 
+ 	perf_callchain_store(entry, regs->ip);
+ 
+@@ -2339,16 +2339,17 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs)
+ 	pagefault_disable();
+ 	while (entry->nr < PERF_MAX_STACK_DEPTH) {
+ 		unsigned long bytes;
++
+ 		frame.next_frame	     = NULL;
+ 		frame.return_address = 0;
+ 
+-		if (!access_ok(VERIFY_READ, fp, 16))
++		if (!access_ok(VERIFY_READ, fp, sizeof(*fp) * 2))
+ 			break;
+ 
+-		bytes = __copy_from_user_nmi(&frame.next_frame, fp, 8);
++		bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp));
+ 		if (bytes != 0)
+ 			break;
+-		bytes = __copy_from_user_nmi(&frame.return_address, fp+8, 8);
++		bytes = __copy_from_user_nmi(&frame.return_address, fp + 1, sizeof(*fp));
+ 		if (bytes != 0)
+ 			break;
+ 
+diff --git a/arch/x86/events/intel/rapl.c b/arch/x86/events/intel/rapl.c
+index 1705c9d75e44..78ee9ebe38dd 100644
+--- a/arch/x86/events/intel/rapl.c
++++ b/arch/x86/events/intel/rapl.c
+@@ -665,7 +665,7 @@ static void __init cleanup_rapl_pmus(void)
+ 	int i;
+ 
+ 	for (i = 0; i < rapl_pmus->maxpkg; i++)
+-		kfree(rapl_pmus->pmus + i);
++		kfree(rapl_pmus->pmus[i]);
+ 	kfree(rapl_pmus);
+ }
+ 
+diff --git a/arch/x86/include/asm/msr.h b/arch/x86/include/asm/msr.h
+index 7a79ee2778b3..33c709ca2666 100644
+--- a/arch/x86/include/asm/msr.h
++++ b/arch/x86/include/asm/msr.h
+@@ -112,7 +112,7 @@ static inline void native_write_msr(unsigned int msr,
+ 				    unsigned low, unsigned high)
+ {
+ 	asm volatile("wrmsr" : : "c" (msr), "a"(low), "d" (high) : "memory");
+-	if (msr_tracepoint_active(__tracepoint_read_msr))
++	if (msr_tracepoint_active(__tracepoint_write_msr))
+ 		do_trace_write_msr(msr, ((u64)high << 32 | low), 0);
+ }
+ 
+@@ -131,7 +131,7 @@ notrace static inline int native_write_msr_safe(unsigned int msr,
+ 		     : "c" (msr), "0" (low), "d" (high),
+ 		       [fault] "i" (-EIO)
+ 		     : "memory");
+-	if (msr_tracepoint_active(__tracepoint_read_msr))
++	if (msr_tracepoint_active(__tracepoint_write_msr))
+ 		do_trace_write_msr(msr, ((u64)high << 32 | low), err);
+ 	return err;
+ }
+diff --git a/arch/x86/kernel/amd_nb.c b/arch/x86/kernel/amd_nb.c
+index a147e676fc7b..e991d5c8bb3a 100644
+--- a/arch/x86/kernel/amd_nb.c
++++ b/arch/x86/kernel/amd_nb.c
+@@ -71,8 +71,8 @@ int amd_cache_northbridges(void)
+ 	while ((misc = next_northbridge(misc, amd_nb_misc_ids)) != NULL)
+ 		i++;
+ 
+-	if (i == 0)
+-		return 0;
++	if (!i)
++		return -ENODEV;
+ 
+ 	nb = kzalloc(i * sizeof(struct amd_northbridge), GFP_KERNEL);
+ 	if (!nb)
+diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
+index ae703acb85c1..44bcd5779ec1 100644
+--- a/arch/x86/kernel/kprobes/core.c
++++ b/arch/x86/kernel/kprobes/core.c
+@@ -960,7 +960,19 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+ 		 * normal page fault.
+ 		 */
+ 		regs->ip = (unsigned long)cur->addr;
++		/*
++		 * Trap flag (TF) has been set here because this fault
++		 * happened where the single stepping will be done.
++		 * So clear it by resetting the current kprobe:
++		 */
++		regs->flags &= ~X86_EFLAGS_TF;
++
++		/*
++		 * If the TF flag was set before the kprobe hit,
++		 * don't touch it:
++		 */
+ 		regs->flags |= kcb->kprobe_old_flags;
++
+ 		if (kcb->kprobe_status == KPROBE_REENTER)
+ 			restore_previous_kprobe(kcb);
+ 		else
+diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
+index faf52bac1416..c4217a23a98d 100644
+--- a/arch/x86/kvm/vmx.c
++++ b/arch/x86/kvm/vmx.c
+@@ -2072,7 +2072,8 @@ static void vmx_vcpu_pi_load(struct kvm_vcpu *vcpu, int cpu)
+ 	unsigned int dest;
+ 
+ 	if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-		!irq_remapping_cap(IRQ_POSTING_CAP))
++		!irq_remapping_cap(IRQ_POSTING_CAP)  ||
++		!kvm_vcpu_apicv_active(vcpu))
+ 		return;
+ 
+ 	do {
+@@ -2180,7 +2181,8 @@ static void vmx_vcpu_pi_put(struct kvm_vcpu *vcpu)
+ 	struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+ 
+ 	if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-		!irq_remapping_cap(IRQ_POSTING_CAP))
++		!irq_remapping_cap(IRQ_POSTING_CAP)  ||
++		!kvm_vcpu_apicv_active(vcpu))
+ 		return;
+ 
+ 	/* Set SN when the vCPU is preempted */
+@@ -6657,7 +6659,13 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
+ 
+ 	/* Checks for #GP/#SS exceptions. */
+ 	exn = false;
+-	if (is_protmode(vcpu)) {
++	if (is_long_mode(vcpu)) {
++		/* Long mode: #GP(0)/#SS(0) if the memory address is in a
++		 * non-canonical form. This is the only check on the memory
++		 * destination for long mode!
++		 */
++		exn = is_noncanonical_address(*ret);
++	} else if (is_protmode(vcpu)) {
+ 		/* Protected mode: apply checks for segment validity in the
+ 		 * following order:
+ 		 * - segment type check (#GP(0) may be thrown)
+@@ -6674,17 +6682,10 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
+ 			 * execute-only code segment
+ 			 */
+ 			exn = ((s.type & 0xa) == 8);
+-	}
+-	if (exn) {
+-		kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
+-		return 1;
+-	}
+-	if (is_long_mode(vcpu)) {
+-		/* Long mode: #GP(0)/#SS(0) if the memory address is in a
+-		 * non-canonical form. This is an only check for long mode.
+-		 */
+-		exn = is_noncanonical_address(*ret);
+-	} else if (is_protmode(vcpu)) {
++		if (exn) {
++			kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
++			return 1;
++		}
+ 		/* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
+ 		 */
+ 		exn = (s.unusable != 0);
+@@ -10702,7 +10703,8 @@ static int vmx_pre_block(struct kvm_vcpu *vcpu)
+ 	struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu);
+ 
+ 	if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-		!irq_remapping_cap(IRQ_POSTING_CAP))
++		!irq_remapping_cap(IRQ_POSTING_CAP)  ||
++		!kvm_vcpu_apicv_active(vcpu))
+ 		return 0;
+ 
+ 	vcpu->pre_pcpu = vcpu->cpu;
+@@ -10768,7 +10770,8 @@ static void vmx_post_block(struct kvm_vcpu *vcpu)
+ 	unsigned long flags;
+ 
+ 	if (!kvm_arch_has_assigned_device(vcpu->kvm) ||
+-		!irq_remapping_cap(IRQ_POSTING_CAP))
++		!irq_remapping_cap(IRQ_POSTING_CAP)  ||
++		!kvm_vcpu_apicv_active(vcpu))
+ 		return;
+ 
+ 	do {
+@@ -10821,7 +10824,8 @@ static int vmx_update_pi_irte(struct kvm *kvm, unsigned int host_irq,
+ 	int idx, ret = -EINVAL;
+ 
+ 	if (!kvm_arch_has_assigned_device(kvm) ||
+-		!irq_remapping_cap(IRQ_POSTING_CAP))
++		!irq_remapping_cap(IRQ_POSTING_CAP) ||
++		!kvm_vcpu_apicv_active(kvm->vcpus[0]))
+ 		return 0;
+ 
+ 	idx = srcu_read_lock(&kvm->irq_srcu);
+diff --git a/crypto/rsa-pkcs1pad.c b/crypto/rsa-pkcs1pad.c
+index ead8dc0d084e..8ba426635b1b 100644
+--- a/crypto/rsa-pkcs1pad.c
++++ b/crypto/rsa-pkcs1pad.c
+@@ -102,10 +102,10 @@ struct pkcs1pad_inst_ctx {
+ };
+ 
+ struct pkcs1pad_request {
+-	struct akcipher_request child_req;
+-
+ 	struct scatterlist in_sg[3], out_sg[2];
+ 	uint8_t *in_buf, *out_buf;
++
++	struct akcipher_request child_req;
+ };
+ 
+ static int pkcs1pad_set_pub_key(struct crypto_akcipher *tfm, const void *key,
+diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
+index 961acc788f44..91a9e6af2ec4 100644
+--- a/drivers/ata/libata-eh.c
++++ b/drivers/ata/libata-eh.c
+@@ -606,7 +606,7 @@ void ata_scsi_error(struct Scsi_Host *host)
+ 	ata_scsi_port_error_handler(host, ap);
+ 
+ 	/* finish or retry handled scmd's and clean up */
+-	WARN_ON(host->host_failed || !list_empty(&eh_work_q));
++	WARN_ON(!list_empty(&eh_work_q));
+ 
+ 	DPRINTK("EXIT\n");
+ }
+diff --git a/drivers/base/module.c b/drivers/base/module.c
+index db930d3ee312..2a215780eda2 100644
+--- a/drivers/base/module.c
++++ b/drivers/base/module.c
+@@ -24,10 +24,12 @@ static char *make_driver_name(struct device_driver *drv)
+ 
+ static void module_create_drivers_dir(struct module_kobject *mk)
+ {
+-	if (!mk || mk->drivers_dir)
+-		return;
++	static DEFINE_MUTEX(drivers_dir_mutex);
+ 
+-	mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
++	mutex_lock(&drivers_dir_mutex);
++	if (mk && !mk->drivers_dir)
++		mk->drivers_dir = kobject_create_and_add("drivers", &mk->kobj);
++	mutex_unlock(&drivers_dir_mutex);
+ }
+ 
+ void module_add_driver(struct module *mod, struct device_driver *drv)
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 94fb407d8561..44b1bd6baa38 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -3820,6 +3820,7 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
+ 	while (!list_empty(&intf->waiting_rcv_msgs)) {
+ 		smi_msg = list_entry(intf->waiting_rcv_msgs.next,
+ 				     struct ipmi_smi_msg, link);
++		list_del(&smi_msg->link);
+ 		if (!run_to_completion)
+ 			spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
+ 					       flags);
+@@ -3829,11 +3830,14 @@ static void handle_new_recv_msgs(ipmi_smi_t intf)
+ 		if (rv > 0) {
+ 			/*
+ 			 * To preserve message order, quit if we
+-			 * can't handle a message.
++			 * can't handle a message.  Add the message
++			 * back at the head, this is safe because this
++			 * tasklet is the only thing that pulls the
++			 * messages.
+ 			 */
++			list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
+ 			break;
+ 		} else {
+-			list_del(&smi_msg->link);
+ 			if (rv == 0)
+ 				/* Message handled */
+ 				ipmi_free_smi_msg(smi_msg);
+diff --git a/drivers/crypto/qat/qat_common/Makefile b/drivers/crypto/qat/qat_common/Makefile
+index 29c7c53d2845..92561c87f349 100644
+--- a/drivers/crypto/qat/qat_common/Makefile
++++ b/drivers/crypto/qat/qat_common/Makefile
+@@ -2,6 +2,7 @@ $(obj)/qat_rsapubkey-asn1.o: $(obj)/qat_rsapubkey-asn1.c \
+ 			     $(obj)/qat_rsapubkey-asn1.h
+ $(obj)/qat_rsaprivkey-asn1.o: $(obj)/qat_rsaprivkey-asn1.c \
+ 			      $(obj)/qat_rsaprivkey-asn1.h
++$(obj)/qat_asym_algs.o: $(obj)/qat_rsapubkey-asn1.h $(obj)/qat_rsaprivkey-asn1.h
+ 
+ clean-files += qat_rsapubkey-asn1.c qat_rsapubkey-asn1.h
+ clean-files += qat_rsaprivkey-asn1.c qat_rsaprivkey-asn1.h
+diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c
+index 1472f48c8ac6..ff51b51d2fd4 100644
+--- a/drivers/edac/edac_mc.c
++++ b/drivers/edac/edac_mc.c
+@@ -565,7 +565,8 @@ void edac_mc_reset_delay_period(unsigned long value)
+ 	list_for_each(item, &mc_devices) {
+ 		mci = list_entry(item, struct mem_ctl_info, link);
+ 
+-		edac_mod_work(&mci->work, value);
++		if (mci->op_state == OP_RUNNING_POLL)
++			edac_mod_work(&mci->work, value);
+ 	}
+ 	mutex_unlock(&mem_ctls_mutex);
+ }
+diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c
+index 8bf745d2da7e..b274fa2ffdec 100644
+--- a/drivers/edac/sb_edac.c
++++ b/drivers/edac/sb_edac.c
+@@ -239,8 +239,11 @@ static const u32 rir_offset[MAX_RIR_RANGES][MAX_RIR_WAY] = {
+ 	{ 0x1a0, 0x1a4, 0x1a8, 0x1ac, 0x1b0, 0x1b4, 0x1b8, 0x1bc },
+ };
+ 
+-#define RIR_RNK_TGT(reg)		GET_BITFIELD(reg, 16, 19)
+-#define RIR_OFFSET(reg)		GET_BITFIELD(reg,  2, 14)
++#define RIR_RNK_TGT(type, reg) (((type) == BROADWELL) ? \
++	GET_BITFIELD(reg, 20, 23) : GET_BITFIELD(reg, 16, 19))
++
++#define RIR_OFFSET(type, reg) (((type) == HASWELL || (type) == BROADWELL) ? \
++	GET_BITFIELD(reg,  2, 15) : GET_BITFIELD(reg,  2, 14))
+ 
+ /* Device 16, functions 2-7 */
+ 
+@@ -1916,14 +1919,14 @@ static void get_memory_layout(const struct mem_ctl_info *mci)
+ 				pci_read_config_dword(pvt->pci_tad[i],
+ 						      rir_offset[j][k],
+ 						      &reg);
+-				tmp_mb = RIR_OFFSET(reg) << 6;
++				tmp_mb = RIR_OFFSET(pvt->info.type, reg) << 6;
+ 
+ 				gb = div_u64_rem(tmp_mb, 1024, &mb);
+ 				edac_dbg(0, "CH#%d RIR#%d INTL#%d, offset %u.%03u GB (0x%016Lx), tgt: %d, reg=0x%08x\n",
+ 					 i, j, k,
+ 					 gb, (mb*1000)/1024,
+ 					 ((u64)tmp_mb) << 20L,
+-					 (u32)RIR_RNK_TGT(reg),
++					 (u32)RIR_RNK_TGT(pvt->info.type, reg),
+ 					 reg);
+ 			}
+ 		}
+@@ -2256,7 +2259,7 @@ static int get_memory_error_data(struct mem_ctl_info *mci,
+ 	pci_read_config_dword(pvt->pci_tad[ch_add + base_ch],
+ 			      rir_offset[n_rir][idx],
+ 			      &reg);
+-	*rank = RIR_RNK_TGT(reg);
++	*rank = RIR_RNK_TGT(pvt->info.type, reg);
+ 
+ 	edac_dbg(0, "RIR#%d: channel address 0x%08Lx < 0x%08Lx, RIR interleave %d, index %d\n",
+ 		 n_rir,
+diff --git a/drivers/extcon/extcon-palmas.c b/drivers/extcon/extcon-palmas.c
+index 8b3226dca1d9..caff46c0e214 100644
+--- a/drivers/extcon/extcon-palmas.c
++++ b/drivers/extcon/extcon-palmas.c
+@@ -360,6 +360,8 @@ static int palmas_usb_probe(struct platform_device *pdev)
+ 
+ 	palmas_enable_irq(palmas_usb);
+ 	/* perform initial detection */
++	if (palmas_usb->enable_gpio_vbus_detection)
++		palmas_vbus_irq_handler(palmas_usb->gpio_vbus_irq, palmas_usb);
+ 	palmas_gpio_id_detect(&palmas_usb->wq_detectid.work);
+ 	device_set_wakeup_capable(&pdev->dev, true);
+ 	return 0;
+diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c
+index e85e7539cf5d..eb43ae4835c1 100644
+--- a/drivers/gpio/gpio-sch.c
++++ b/drivers/gpio/gpio-sch.c
+@@ -61,9 +61,8 @@ static unsigned sch_gpio_bit(struct sch_gpio *sch, unsigned gpio)
+ 	return gpio % 8;
+ }
+ 
+-static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
++static int sch_gpio_reg_get(struct sch_gpio *sch, unsigned gpio, unsigned reg)
+ {
+-	struct sch_gpio *sch = gpiochip_get_data(gc);
+ 	unsigned short offset, bit;
+ 	u8 reg_val;
+ 
+@@ -75,10 +74,9 @@ static int sch_gpio_reg_get(struct gpio_chip *gc, unsigned gpio, unsigned reg)
+ 	return reg_val;
+ }
+ 
+-static void sch_gpio_reg_set(struct gpio_chip *gc, unsigned gpio, unsigned reg,
++static void sch_gpio_reg_set(struct sch_gpio *sch, unsigned gpio, unsigned reg,
+ 			     int val)
+ {
+-	struct sch_gpio *sch = gpiochip_get_data(gc);
+ 	unsigned short offset, bit;
+ 	u8 reg_val;
+ 
+@@ -98,14 +96,15 @@ static int sch_gpio_direction_in(struct gpio_chip *gc, unsigned gpio_num)
+ 	struct sch_gpio *sch = gpiochip_get_data(gc);
+ 
+ 	spin_lock(&sch->lock);
+-	sch_gpio_reg_set(gc, gpio_num, GIO, 1);
++	sch_gpio_reg_set(sch, gpio_num, GIO, 1);
+ 	spin_unlock(&sch->lock);
+ 	return 0;
+ }
+ 
+ static int sch_gpio_get(struct gpio_chip *gc, unsigned gpio_num)
+ {
+-	return sch_gpio_reg_get(gc, gpio_num, GLV);
++	struct sch_gpio *sch = gpiochip_get_data(gc);
++	return sch_gpio_reg_get(sch, gpio_num, GLV);
+ }
+ 
+ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+@@ -113,7 +112,7 @@ static void sch_gpio_set(struct gpio_chip *gc, unsigned gpio_num, int val)
+ 	struct sch_gpio *sch = gpiochip_get_data(gc);
+ 
+ 	spin_lock(&sch->lock);
+-	sch_gpio_reg_set(gc, gpio_num, GLV, val);
++	sch_gpio_reg_set(sch, gpio_num, GLV, val);
+ 	spin_unlock(&sch->lock);
+ }
+ 
+@@ -123,7 +122,7 @@ static int sch_gpio_direction_out(struct gpio_chip *gc, unsigned gpio_num,
+ 	struct sch_gpio *sch = gpiochip_get_data(gc);
+ 
+ 	spin_lock(&sch->lock);
+-	sch_gpio_reg_set(gc, gpio_num, GIO, 0);
++	sch_gpio_reg_set(sch, gpio_num, GIO, 0);
+ 	spin_unlock(&sch->lock);
+ 
+ 	/*
+@@ -182,13 +181,13 @@ static int sch_gpio_probe(struct platform_device *pdev)
+ 		 * GPIO7 is configured by the CMC as SLPIOVR
+ 		 * Enable GPIO[9:8] core powered gpios explicitly
+ 		 */
+-		sch_gpio_reg_set(&sch->chip, 8, GEN, 1);
+-		sch_gpio_reg_set(&sch->chip, 9, GEN, 1);
++		sch_gpio_reg_set(sch, 8, GEN, 1);
++		sch_gpio_reg_set(sch, 9, GEN, 1);
+ 		/*
+ 		 * SUS_GPIO[2:0] enabled by default
+ 		 * Enable SUS_GPIO3 resume powered gpio explicitly
+ 		 */
+-		sch_gpio_reg_set(&sch->chip, 13, GEN, 1);
++		sch_gpio_reg_set(sch, 13, GEN, 1);
+ 		break;
+ 
+ 	case PCI_DEVICE_ID_INTEL_ITC_LPC:
+diff --git a/drivers/gpio/gpiolib-legacy.c b/drivers/gpio/gpiolib-legacy.c
+index 3a5c7011ad3b..8b830996fe02 100644
+--- a/drivers/gpio/gpiolib-legacy.c
++++ b/drivers/gpio/gpiolib-legacy.c
+@@ -28,6 +28,10 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+ 	if (!desc && gpio_is_valid(gpio))
+ 		return -EPROBE_DEFER;
+ 
++	err = gpiod_request(desc, label);
++	if (err)
++		return err;
++
+ 	if (flags & GPIOF_OPEN_DRAIN)
+ 		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+ 
+@@ -37,10 +41,6 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label)
+ 	if (flags & GPIOF_ACTIVE_LOW)
+ 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+ 
+-	err = gpiod_request(desc, label);
+-	if (err)
+-		return err;
+-
+ 	if (flags & GPIOF_DIR_IN)
+ 		err = gpiod_direction_input(desc);
+ 	else
+diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
+index cf3e71243d6d..996a73390bba 100644
+--- a/drivers/gpio/gpiolib.c
++++ b/drivers/gpio/gpiolib.c
+@@ -1324,14 +1324,6 @@ static int __gpiod_request(struct gpio_desc *desc, const char *label)
+ 		spin_lock_irqsave(&gpio_lock, flags);
+ 	}
+ done:
+-	if (status < 0) {
+-		/* Clear flags that might have been set by the caller before
+-		 * requesting the GPIO.
+-		 */
+-		clear_bit(FLAG_ACTIVE_LOW, &desc->flags);
+-		clear_bit(FLAG_OPEN_DRAIN, &desc->flags);
+-		clear_bit(FLAG_OPEN_SOURCE, &desc->flags);
+-	}
+ 	spin_unlock_irqrestore(&gpio_lock, flags);
+ 	return status;
+ }
+@@ -1345,8 +1337,12 @@ done:
+ #define VALIDATE_DESC(desc) do { \
+ 	if (!desc) \
+ 		return 0; \
++	if (IS_ERR(desc)) {						\
++		pr_warn("%s: invalid GPIO (errorpointer)\n", __func__); \
++		return PTR_ERR(desc); \
++	} \
+ 	if (!desc->gdev) { \
+-		pr_warn("%s: invalid GPIO\n", __func__); \
++		pr_warn("%s: invalid GPIO (no device)\n", __func__); \
+ 		return -EINVAL; \
+ 	} \
+ 	if ( !desc->gdev->chip ) { \
+@@ -1358,8 +1354,12 @@ done:
+ #define VALIDATE_DESC_VOID(desc) do { \
+ 	if (!desc) \
+ 		return; \
++	if (IS_ERR(desc)) {						\
++		pr_warn("%s: invalid GPIO (errorpointer)\n", __func__); \
++		return; \
++	} \
+ 	if (!desc->gdev) { \
+-		pr_warn("%s: invalid GPIO\n", __func__); \
++		pr_warn("%s: invalid GPIO (no device)\n", __func__); \
+ 		return; \
+ 	} \
+ 	if (!desc->gdev->chip) { \
+@@ -2011,7 +2011,7 @@ int gpiod_to_irq(const struct gpio_desc *desc)
+ 	 * requires this function to not return zero on an invalid descriptor
+ 	 * but rather a negative error number.
+ 	 */
+-	if (!desc || !desc->gdev || !desc->gdev->chip)
++	if (!desc || IS_ERR(desc) || !desc->gdev || !desc->gdev->chip)
+ 		return -EINVAL;
+ 
+ 	chip = desc->gdev->chip;
+@@ -2507,28 +2507,13 @@ struct gpio_desc *__must_check gpiod_get_optional(struct device *dev,
+ }
+ EXPORT_SYMBOL_GPL(gpiod_get_optional);
+ 
+-/**
+- * gpiod_parse_flags - helper function to parse GPIO lookup flags
+- * @desc:	gpio to be setup
+- * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
+- *		of_get_gpio_hog()
+- *
+- * Set the GPIO descriptor flags based on the given GPIO lookup flags.
+- */
+-static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
+-{
+-	if (lflags & GPIO_ACTIVE_LOW)
+-		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+-	if (lflags & GPIO_OPEN_DRAIN)
+-		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
+-	if (lflags & GPIO_OPEN_SOURCE)
+-		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
+-}
+ 
+ /**
+  * gpiod_configure_flags - helper function to configure a given GPIO
+  * @desc:	gpio whose value will be assigned
+  * @con_id:	function within the GPIO consumer
++ * @lflags:	gpio_lookup_flags - returned from of_find_gpio() or
++ *		of_get_gpio_hog()
+  * @dflags:	gpiod_flags - optional GPIO initialization flags
+  *
+  * Return 0 on success, -ENOENT if no GPIO has been assigned to the
+@@ -2536,10 +2521,17 @@ static void gpiod_parse_flags(struct gpio_desc *desc, unsigned long lflags)
+  * occurred while trying to acquire the GPIO.
+  */
+ static int gpiod_configure_flags(struct gpio_desc *desc, const char *con_id,
+-				 enum gpiod_flags dflags)
++		unsigned long lflags, enum gpiod_flags dflags)
+ {
+ 	int status;
+ 
++	if (lflags & GPIO_ACTIVE_LOW)
++		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
++	if (lflags & GPIO_OPEN_DRAIN)
++		set_bit(FLAG_OPEN_DRAIN, &desc->flags);
++	if (lflags & GPIO_OPEN_SOURCE)
++		set_bit(FLAG_OPEN_SOURCE, &desc->flags);
++
+ 	/* No particular flag request, return here... */
+ 	if (!(dflags & GPIOD_FLAGS_BIT_DIR_SET)) {
+ 		pr_debug("no flags found for %s\n", con_id);
+@@ -2606,13 +2598,11 @@ struct gpio_desc *__must_check gpiod_get_index(struct device *dev,
+ 		return desc;
+ 	}
+ 
+-	gpiod_parse_flags(desc, lookupflags);
+-
+ 	status = gpiod_request(desc, con_id);
+ 	if (status < 0)
+ 		return ERR_PTR(status);
+ 
+-	status = gpiod_configure_flags(desc, con_id, flags);
++	status = gpiod_configure_flags(desc, con_id, lookupflags, flags);
+ 	if (status < 0) {
+ 		dev_dbg(dev, "setup of GPIO %s failed\n", con_id);
+ 		gpiod_put(desc);
+@@ -2668,6 +2658,10 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
+ 	if (IS_ERR(desc))
+ 		return desc;
+ 
++	ret = gpiod_request(desc, NULL);
++	if (ret)
++		return ERR_PTR(ret);
++
+ 	if (active_low)
+ 		set_bit(FLAG_ACTIVE_LOW, &desc->flags);
+ 
+@@ -2678,10 +2672,6 @@ struct gpio_desc *fwnode_get_named_gpiod(struct fwnode_handle *fwnode,
+ 			set_bit(FLAG_OPEN_SOURCE, &desc->flags);
+ 	}
+ 
+-	ret = gpiod_request(desc, NULL);
+-	if (ret)
+-		return ERR_PTR(ret);
+-
+ 	return desc;
+ }
+ EXPORT_SYMBOL_GPL(fwnode_get_named_gpiod);
+@@ -2734,8 +2724,6 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
+ 	chip = gpiod_to_chip(desc);
+ 	hwnum = gpio_chip_hwgpio(desc);
+ 
+-	gpiod_parse_flags(desc, lflags);
+-
+ 	local_desc = gpiochip_request_own_desc(chip, hwnum, name);
+ 	if (IS_ERR(local_desc)) {
+ 		pr_err("requesting hog GPIO %s (chip %s, offset %d) failed\n",
+@@ -2743,7 +2731,7 @@ int gpiod_hog(struct gpio_desc *desc, const char *name,
+ 		return PTR_ERR(local_desc);
+ 	}
+ 
+-	status = gpiod_configure_flags(desc, name, dflags);
++	status = gpiod_configure_flags(desc, name, lflags, dflags);
+ 	if (status < 0) {
+ 		pr_err("setup of hog GPIO %s (chip %s, offset %d) failed\n",
+ 		       name, chip->label, hwnum);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+index 6043dc7c3a94..3e21732f22e3 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c
+@@ -880,7 +880,7 @@ static int amdgpu_cgs_acpi_eval_object(void *cgs_device,
+ 	struct cgs_acpi_method_argument *argument = NULL;
+ 	uint32_t i, count;
+ 	acpi_status status;
+-	int result;
++	int result = 0;
+ 	uint32_t func_no = 0xFFFFFFFF;
+ 
+ 	handle = ACPI_HANDLE(&adev->pdev->dev);
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+index b04337de65d1..d78739d2952d 100644
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+@@ -448,7 +448,8 @@ static int amdgpu_info_ioctl(struct drm_device *dev, void *data, struct drm_file
+ 			dev_info.max_memory_clock = adev->pm.default_mclk * 10;
+ 		}
+ 		dev_info.enabled_rb_pipes_mask = adev->gfx.config.backend_enable_mask;
+-		dev_info.num_rb_pipes = adev->gfx.config.num_rbs;
++		dev_info.num_rb_pipes = adev->gfx.config.max_backends_per_se *
++			adev->gfx.config.max_shader_engines;
+ 		dev_info.num_hw_gfx_contexts = adev->gfx.config.max_hw_contexts;
+ 		dev_info._pad = 0;
+ 		dev_info.ids_flags = 0;
+diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+index bb8709066fd8..d2216f83bd7a 100644
+--- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
++++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
+@@ -5074,7 +5074,7 @@ static int gfx_v7_0_eop_irq(struct amdgpu_device *adev,
+ 	case 2:
+ 		for (i = 0; i < adev->gfx.num_compute_rings; i++) {
+ 			ring = &adev->gfx.compute_ring[i];
+-			if ((ring->me == me_id) & (ring->pipe == pipe_id))
++			if ((ring->me == me_id) && (ring->pipe == pipe_id))
+ 				amdgpu_fence_process(ring);
+ 		}
+ 		break;
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+index ac005796b71c..7708d90b9da9 100644
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+@@ -242,13 +242,19 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn,
+ 	pqm_uninit(&p->pqm);
+ 
+ 	/* Iterate over all process device data structure and check
+-	 * if we should reset all wavefronts */
+-	list_for_each_entry(pdd, &p->per_device_data, per_device_list)
++	 * if we should delete debug managers and reset all wavefronts
++	 */
++	list_for_each_entry(pdd, &p->per_device_data, per_device_list) {
++		if ((pdd->dev->dbgmgr) &&
++				(pdd->dev->dbgmgr->pasid == p->pasid))
++			kfd_dbgmgr_destroy(pdd->dev->dbgmgr);
++
+ 		if (pdd->reset_wavefronts) {
+ 			pr_warn("amdkfd: Resetting all wave fronts\n");
+ 			dbgdev_wave_reset_wavefronts(pdd->dev, p);
+ 			pdd->reset_wavefronts = false;
+ 		}
++	}
+ 
+ 	mutex_unlock(&p->mutex);
+ 
+@@ -404,42 +410,52 @@ void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
+ 
+ 	idx = srcu_read_lock(&kfd_processes_srcu);
+ 
++	/*
++	 * Look for the process that matches the pasid. If there is no such
++	 * process, we either released it in amdkfd's own notifier, or there
++	 * is a bug. Unfortunately, there is no way to tell...
++	 */
+ 	hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
+-		if (p->pasid == pasid)
+-			break;
++		if (p->pasid == pasid) {
+ 
+-	srcu_read_unlock(&kfd_processes_srcu, idx);
++			srcu_read_unlock(&kfd_processes_srcu, idx);
+ 
+-	BUG_ON(p->pasid != pasid);
++			pr_debug("Unbinding process %d from IOMMU\n", pasid);
+ 
+-	mutex_lock(&p->mutex);
++			mutex_lock(&p->mutex);
+ 
+-	if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
+-		kfd_dbgmgr_destroy(dev->dbgmgr);
++			if ((dev->dbgmgr) && (dev->dbgmgr->pasid == p->pasid))
++				kfd_dbgmgr_destroy(dev->dbgmgr);
+ 
+-	pqm_uninit(&p->pqm);
++			pqm_uninit(&p->pqm);
+ 
+-	pdd = kfd_get_process_device_data(dev, p);
++			pdd = kfd_get_process_device_data(dev, p);
+ 
+-	if (!pdd) {
+-		mutex_unlock(&p->mutex);
+-		return;
+-	}
++			if (!pdd) {
++				mutex_unlock(&p->mutex);
++				return;
++			}
+ 
+-	if (pdd->reset_wavefronts) {
+-		dbgdev_wave_reset_wavefronts(pdd->dev, p);
+-		pdd->reset_wavefronts = false;
+-	}
++			if (pdd->reset_wavefronts) {
++				dbgdev_wave_reset_wavefronts(pdd->dev, p);
++				pdd->reset_wavefronts = false;
++			}
+ 
+-	/*
+-	 * Just mark pdd as unbound, because we still need it to call
+-	 * amd_iommu_unbind_pasid() in when the process exits.
+-	 * We don't call amd_iommu_unbind_pasid() here
+-	 * because the IOMMU called us.
+-	 */
+-	pdd->bound = false;
++			/*
++			 * Just mark pdd as unbound, because we still need it
++			 * to call amd_iommu_unbind_pasid() in when the
++			 * process exits.
++			 * We don't call amd_iommu_unbind_pasid() here
++			 * because the IOMMU called us.
++			 */
++			pdd->bound = false;
+ 
+-	mutex_unlock(&p->mutex);
++			mutex_unlock(&p->mutex);
++
++			return;
++		}
++
++	srcu_read_unlock(&kfd_processes_srcu, idx);
+ }
+ 
+ struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+index fa208ada6892..efb77eda7508 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/hardwaremanager.c
+@@ -306,10 +306,14 @@ int phm_store_dal_configuration_data(struct pp_hwmgr *hwmgr,
+ {
+ 	PHM_FUNC_CHECK(hwmgr);
+ 
+-	if (hwmgr->hwmgr_func->store_cc6_data == NULL)
++	if (display_config == NULL)
+ 		return -EINVAL;
+ 
+ 	hwmgr->display_config = *display_config;
++
++	if (hwmgr->hwmgr_func->store_cc6_data == NULL)
++		return -EINVAL;
++
+ 	/* to do pass other display configuration in furture */
+ 
+ 	if (hwmgr->hwmgr_func->store_cc6_data)
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
+index 7b2d5000292d..7cce483b0859 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/pp_acpi.c
+@@ -21,6 +21,20 @@ bool acpi_atcs_functions_supported(void *device, uint32_t index)
+ 	return result == 0 ? (output_buf.function_bits & (1 << (index - 1))) != 0 : false;
+ }
+ 
++bool acpi_atcs_notify_pcie_device_ready(void *device)
++{
++	int32_t temp_buffer = 1;
++
++	return cgs_call_acpi_method(device, CGS_ACPI_METHOD_ATCS,
++				ATCS_FUNCTION_PCIE_DEVICE_READY_NOTIFICATION,
++						&temp_buffer,
++						NULL,
++						0,
++						sizeof(temp_buffer),
++						0);
++}
++
++
+ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
+ {
+ 	struct atcs_pref_req_input atcs_input;
+@@ -29,7 +43,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
+ 	int result;
+ 	struct cgs_system_info info = {0};
+ 
+-	if (!acpi_atcs_functions_supported(device, ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST))
++	if( 0 != acpi_atcs_notify_pcie_device_ready(device))
+ 		return -EINVAL;
+ 
+ 	info.size = sizeof(struct cgs_system_info);
+@@ -54,7 +68,7 @@ int acpi_pcie_perf_request(void *device, uint8_t perf_req, bool advertise)
+ 						ATCS_FUNCTION_PCIE_PERFORMANCE_REQUEST,
+ 						&atcs_input,
+ 						&atcs_output,
+-						0,
++						1,
+ 						sizeof(atcs_input),
+ 						sizeof(atcs_output));
+ 		if (result != 0)
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+index 0d5d8372953e..aae2e8ec0542 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_hwmgr.c
+@@ -1298,7 +1298,7 @@ static int tonga_populate_smc_mvdd_table(struct pp_hwmgr *hwmgr,
+ 			table->Smio[count] |=
+ 				data->mvdd_voltage_table.entries[count].smio_low;
+ 		}
+-		table->SmioMask2 = data->vddci_voltage_table.mask_low;
++		table->SmioMask2 = data->mvdd_voltage_table.mask_low;
+ 
+ 		CONVERT_FROM_HOST_TO_SMC_UL(table->MvddLevelCount);
+ 	}
+diff --git a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
+index b156481b50e8..17766e8da0ca 100644
+--- a/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
++++ b/drivers/gpu/drm/amd/powerplay/hwmgr/tonga_processpptables.c
+@@ -299,7 +299,7 @@ static int init_dpm_2_parameters(
+ 			(((unsigned long)powerplay_table) + le16_to_cpu(powerplay_table->usPPMTableOffset));
+ 
+ 		if (0 != powerplay_table->usPPMTableOffset) {
+-			if (1 == get_platform_power_management_table(hwmgr, atom_ppm_table)) {
++			if (get_platform_power_management_table(hwmgr, atom_ppm_table) == 0) {
+ 				phm_cap_set(hwmgr->platform_descriptor.platformCaps,
+ 					PHM_PlatformCaps_EnablePlatformPowerManagement);
+ 			}
+diff --git a/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h b/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
+index 3bd5e69b9045..3df5de2cdab0 100644
+--- a/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
++++ b/drivers/gpu/drm/amd/powerplay/inc/pp_acpi.h
+@@ -26,3 +26,4 @@ extern bool acpi_atcs_functions_supported(void *device,
+ extern int acpi_pcie_perf_request(void *device,
+ 						uint8_t perf_req,
+ 						bool advertise);
++extern bool acpi_atcs_notify_pcie_device_ready(void *device);
+diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+index d65dcaee3832..6d9c0f5bcba6 100644
+--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
++++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c
+@@ -335,6 +335,8 @@ atmel_hlcdc_plane_update_pos_and_size(struct atmel_hlcdc_plane *plane,
+ 
+ 		atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff,
+ 					     factor_reg);
++	} else {
++		atmel_hlcdc_layer_update_cfg(&plane->layer, 13, 0xffffffff, 0);
+ 	}
+ }
+ 
+diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
+index d307d9627887..080a09014580 100644
+--- a/drivers/gpu/drm/drm_atomic.c
++++ b/drivers/gpu/drm/drm_atomic.c
+@@ -354,6 +354,8 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
+ 	drm_property_unreference_blob(state->mode_blob);
+ 	state->mode_blob = NULL;
+ 
++	memset(&state->mode, 0, sizeof(state->mode));
++
+ 	if (blob) {
+ 		if (blob->length != sizeof(struct drm_mode_modeinfo) ||
+ 		    drm_mode_convert_umode(&state->mode,
+@@ -366,7 +368,6 @@ int drm_atomic_set_mode_prop_for_crtc(struct drm_crtc_state *state,
+ 		DRM_DEBUG_ATOMIC("Set [MODE:%s] for CRTC state %p\n",
+ 				 state->mode.name, state);
+ 	} else {
+-		memset(&state->mode, 0, sizeof(state->mode));
+ 		state->enable = false;
+ 		DRM_DEBUG_ATOMIC("Set [NOMODE] for CRTC state %p\n",
+ 				 state);
+@@ -1287,14 +1288,39 @@ EXPORT_SYMBOL(drm_atomic_add_affected_planes);
+  */
+ void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
+ {
++	struct drm_device *dev = state->dev;
++	unsigned crtc_mask = 0;
++	struct drm_crtc *crtc;
+ 	int ret;
++	bool global = false;
++
++	drm_for_each_crtc(crtc, dev) {
++		if (crtc->acquire_ctx != state->acquire_ctx)
++			continue;
++
++		crtc_mask |= drm_crtc_mask(crtc);
++		crtc->acquire_ctx = NULL;
++	}
++
++	if (WARN_ON(dev->mode_config.acquire_ctx == state->acquire_ctx)) {
++		global = true;
++
++		dev->mode_config.acquire_ctx = NULL;
++	}
+ 
+ retry:
+ 	drm_modeset_backoff(state->acquire_ctx);
+ 
+-	ret = drm_modeset_lock_all_ctx(state->dev, state->acquire_ctx);
++	ret = drm_modeset_lock_all_ctx(dev, state->acquire_ctx);
+ 	if (ret)
+ 		goto retry;
++
++	drm_for_each_crtc(crtc, dev)
++		if (drm_crtc_mask(crtc) & crtc_mask)
++			crtc->acquire_ctx = state->acquire_ctx;
++
++	if (global)
++		dev->mode_config.acquire_ctx = state->acquire_ctx;
+ }
+ EXPORT_SYMBOL(drm_atomic_legacy_backoff);
+ 
+diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
+index f30de8053545..691a1b939c1c 100644
+--- a/drivers/gpu/drm/drm_crtc.c
++++ b/drivers/gpu/drm/drm_crtc.c
+@@ -2800,8 +2800,6 @@ int drm_mode_setcrtc(struct drm_device *dev, void *data,
+ 			goto out;
+ 		}
+ 
+-		drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+-
+ 		/*
+ 		 * Check whether the primary plane supports the fb pixel format.
+ 		 * Drivers not implementing the universal planes API use a
+diff --git a/drivers/gpu/drm/drm_dp_mst_topology.c b/drivers/gpu/drm/drm_dp_mst_topology.c
+index 71ea0521ea96..ccfe7e72d8fc 100644
+--- a/drivers/gpu/drm/drm_dp_mst_topology.c
++++ b/drivers/gpu/drm/drm_dp_mst_topology.c
+@@ -2908,11 +2908,9 @@ static void drm_dp_destroy_connector_work(struct work_struct *work)
+ 		drm_dp_port_teardown_pdt(port, port->pdt);
+ 
+ 		if (!port->input && port->vcpi.vcpi > 0) {
+-			if (mgr->mst_state) {
+-				drm_dp_mst_reset_vcpi_slots(mgr, port);
+-				drm_dp_update_payload_part1(mgr);
+-				drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+-			}
++			drm_dp_mst_reset_vcpi_slots(mgr, port);
++			drm_dp_update_payload_part1(mgr);
++			drm_dp_mst_put_payload_id(mgr, port->vcpi.vcpi);
+ 		}
+ 
+ 		kref_put(&port->kref, drm_dp_free_mst_port);
+diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
+index bb88e3df9257..e619b00c7343 100644
+--- a/drivers/gpu/drm/drm_fb_cma_helper.c
++++ b/drivers/gpu/drm/drm_fb_cma_helper.c
+@@ -301,7 +301,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
+ err_fb_info_destroy:
+ 	drm_fb_helper_release_fbi(helper);
+ err_gem_free_object:
+-	dev->driver->gem_free_object(&obj->base);
++	drm_gem_object_unreference_unlocked(&obj->base);
+ 	return ret;
+ }
+ 
+diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
+index 1f500a1b9969..d988ca0b597a 100644
+--- a/drivers/gpu/drm/drm_gem_cma_helper.c
++++ b/drivers/gpu/drm/drm_gem_cma_helper.c
+@@ -121,7 +121,7 @@ struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
+ 	return cma_obj;
+ 
+ error:
+-	drm->driver->gem_free_object(&cma_obj->base);
++	drm_gem_object_unreference_unlocked(&cma_obj->base);
+ 	return ERR_PTR(ret);
+ }
+ EXPORT_SYMBOL_GPL(drm_gem_cma_create);
+@@ -162,18 +162,12 @@ drm_gem_cma_create_with_handle(struct drm_file *file_priv,
+ 	 * and handle has the id what user can see.
+ 	 */
+ 	ret = drm_gem_handle_create(file_priv, gem_obj, handle);
+-	if (ret)
+-		goto err_handle_create;
+-
+ 	/* drop reference from allocate - handle holds it now. */
+ 	drm_gem_object_unreference_unlocked(gem_obj);
++	if (ret)
++		return ERR_PTR(ret);
+ 
+ 	return cma_obj;
+-
+-err_handle_create:
+-	drm->driver->gem_free_object(gem_obj);
+-
+-	return ERR_PTR(ret);
+ }
+ 
+ /**
+diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
+index f7448a5e95a9..5d0fc2644352 100644
+--- a/drivers/gpu/drm/drm_modes.c
++++ b/drivers/gpu/drm/drm_modes.c
+@@ -1518,6 +1518,8 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
+ 	if (out->status != MODE_OK)
+ 		goto out;
+ 
++	drm_mode_set_crtcinfo(out, CRTC_INTERLACE_HALVE_V);
++
+ 	ret = 0;
+ 
+ out:
+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 e8d9337a66d8..77886f1182f1 100644
+--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
++++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+@@ -40,9 +40,10 @@ static const struct regmap_config fsl_dcu_regmap_config = {
+ 	.reg_bits = 32,
+ 	.reg_stride = 4,
+ 	.val_bits = 32,
+-	.cache_type = REGCACHE_RBTREE,
++	.cache_type = REGCACHE_FLAT,
+ 
+ 	.volatile_reg = fsl_dcu_drm_is_volatile_reg,
++	.max_register = 0x11fc,
+ };
+ 
+ static int fsl_dcu_drm_irq_init(struct drm_device *dev)
+diff --git a/drivers/gpu/drm/i915/i915_gem_shrinker.c b/drivers/gpu/drm/i915/i915_gem_shrinker.c
+index d3c473ffb90a..3af40616bf8b 100644
+--- a/drivers/gpu/drm/i915/i915_gem_shrinker.c
++++ b/drivers/gpu/drm/i915/i915_gem_shrinker.c
+@@ -39,7 +39,7 @@ static bool mutex_is_locked_by(struct mutex *mutex, struct task_struct *task)
+ 	if (!mutex_is_locked(mutex))
+ 		return false;
+ 
+-#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_MUTEXES)
++#if defined(CONFIG_DEBUG_MUTEXES) || defined(CONFIG_MUTEX_SPIN_ON_OWNER)
+ 	return mutex->owner == task;
+ #else
+ 	/* Since UP may be pre-empted, we cannot assume that we own the lock */
+diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
+index 7741efbd5e57..e5db9e1f623f 100644
+--- a/drivers/gpu/drm/i915/intel_display.c
++++ b/drivers/gpu/drm/i915/intel_display.c
+@@ -8229,12 +8229,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
+ {
+ 	struct drm_i915_private *dev_priv = dev->dev_private;
+ 	struct intel_encoder *encoder;
++	int i;
+ 	u32 val, final;
+ 	bool has_lvds = false;
+ 	bool has_cpu_edp = false;
+ 	bool has_panel = false;
+ 	bool has_ck505 = false;
+ 	bool can_ssc = false;
++	bool using_ssc_source = false;
+ 
+ 	/* We need to take the global config into account */
+ 	for_each_intel_encoder(dev, encoder) {
+@@ -8261,8 +8263,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
+ 		can_ssc = true;
+ 	}
+ 
+-	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
+-		      has_panel, has_lvds, has_ck505);
++	/* Check if any DPLLs are using the SSC source */
++	for (i = 0; i < dev_priv->num_shared_dpll; i++) {
++		u32 temp = I915_READ(PCH_DPLL(i));
++
++		if (!(temp & DPLL_VCO_ENABLE))
++			continue;
++
++		if ((temp & PLL_REF_INPUT_MASK) ==
++		    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
++			using_ssc_source = true;
++			break;
++		}
++	}
++
++	DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
++		      has_panel, has_lvds, has_ck505, using_ssc_source);
+ 
+ 	/* Ironlake: try to setup display ref clock before DPLL
+ 	 * enabling. This is only under driver's control after
+@@ -8299,9 +8315,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
+ 				final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
+ 		} else
+ 			final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+-	} else {
+-		final |= DREF_SSC_SOURCE_DISABLE;
+-		final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
++	} else if (using_ssc_source) {
++		final |= DREF_SSC_SOURCE_ENABLE;
++		final |= DREF_SSC1_ENABLE;
+ 	}
+ 
+ 	if (final == val)
+@@ -8347,7 +8363,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
+ 		POSTING_READ(PCH_DREF_CONTROL);
+ 		udelay(200);
+ 	} else {
+-		DRM_DEBUG_KMS("Disabling SSC entirely\n");
++		DRM_DEBUG_KMS("Disabling CPU source output\n");
+ 
+ 		val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
+ 
+@@ -8358,16 +8374,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
+ 		POSTING_READ(PCH_DREF_CONTROL);
+ 		udelay(200);
+ 
+-		/* Turn off the SSC source */
+-		val &= ~DREF_SSC_SOURCE_MASK;
+-		val |= DREF_SSC_SOURCE_DISABLE;
++		if (!using_ssc_source) {
++			DRM_DEBUG_KMS("Disabling SSC source\n");
+ 
+-		/* Turn off SSC1 */
+-		val &= ~DREF_SSC1_ENABLE;
++			/* Turn off the SSC source */
++			val &= ~DREF_SSC_SOURCE_MASK;
++			val |= DREF_SSC_SOURCE_DISABLE;
+ 
+-		I915_WRITE(PCH_DREF_CONTROL, val);
+-		POSTING_READ(PCH_DREF_CONTROL);
+-		udelay(200);
++			/* Turn off SSC1 */
++			val &= ~DREF_SSC1_ENABLE;
++
++			I915_WRITE(PCH_DREF_CONTROL, val);
++			POSTING_READ(PCH_DREF_CONTROL);
++			udelay(200);
++		}
+ 	}
+ 
+ 	BUG_ON(val != final);
+diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
+index 412a34c39522..69054ef978fa 100644
+--- a/drivers/gpu/drm/i915/intel_dp.c
++++ b/drivers/gpu/drm/i915/intel_dp.c
+@@ -4942,13 +4942,15 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp)
+ 
+ void intel_dp_encoder_reset(struct drm_encoder *encoder)
+ {
+-	struct intel_dp *intel_dp;
++	struct drm_i915_private *dev_priv = to_i915(encoder->dev);
++	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
++
++	if (!HAS_DDI(dev_priv))
++		intel_dp->DP = I915_READ(intel_dp->output_reg);
+ 
+ 	if (to_intel_encoder(encoder)->type != INTEL_OUTPUT_EDP)
+ 		return;
+ 
+-	intel_dp = enc_to_intel_dp(encoder);
+-
+ 	pps_lock(intel_dp);
+ 
+ 	/*
+@@ -5020,9 +5022,6 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd)
+ 	intel_display_power_get(dev_priv, power_domain);
+ 
+ 	if (long_hpd) {
+-		/* indicate that we need to restart link training */
+-		intel_dp->train_set_valid = false;
+-
+ 		if (!intel_digital_port_connected(dev_priv, intel_dig_port))
+ 			goto mst_fail;
+ 
+diff --git a/drivers/gpu/drm/i915/intel_dp_link_training.c b/drivers/gpu/drm/i915/intel_dp_link_training.c
+index 0b8eefc2acc5..926a1e6ea2f6 100644
+--- a/drivers/gpu/drm/i915/intel_dp_link_training.c
++++ b/drivers/gpu/drm/i915/intel_dp_link_training.c
+@@ -85,8 +85,7 @@ static bool
+ intel_dp_reset_link_train(struct intel_dp *intel_dp,
+ 			uint8_t dp_train_pat)
+ {
+-	if (!intel_dp->train_set_valid)
+-		memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
++	memset(intel_dp->train_set, 0, sizeof(intel_dp->train_set));
+ 	intel_dp_set_signal_levels(intel_dp);
+ 	return intel_dp_set_link_train(intel_dp, dp_train_pat);
+ }
+@@ -161,22 +160,6 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp)
+ 			break;
+ 		}
+ 
+-		/*
+-		 * if we used previously trained voltage and pre-emphasis values
+-		 * and we don't get clock recovery, reset link training values
+-		 */
+-		if (intel_dp->train_set_valid) {
+-			DRM_DEBUG_KMS("clock recovery not ok, reset");
+-			/* clear the flag as we are not reusing train set */
+-			intel_dp->train_set_valid = false;
+-			if (!intel_dp_reset_link_train(intel_dp,
+-						       DP_TRAINING_PATTERN_1 |
+-						       DP_LINK_SCRAMBLING_DISABLE)) {
+-				DRM_ERROR("failed to enable link training\n");
+-				return;
+-			}
+-			continue;
+-		}
+ 
+ 		/* Check to see if we've tried the max voltage */
+ 		for (i = 0; i < intel_dp->lane_count; i++)
+@@ -284,7 +267,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+ 		/* Make sure clock is still ok */
+ 		if (!drm_dp_clock_recovery_ok(link_status,
+ 					      intel_dp->lane_count)) {
+-			intel_dp->train_set_valid = false;
+ 			intel_dp_link_training_clock_recovery(intel_dp);
+ 			intel_dp_set_link_train(intel_dp,
+ 						training_pattern |
+@@ -301,7 +283,6 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+ 
+ 		/* Try 5 times, then try clock recovery if that fails */
+ 		if (tries > 5) {
+-			intel_dp->train_set_valid = false;
+ 			intel_dp_link_training_clock_recovery(intel_dp);
+ 			intel_dp_set_link_train(intel_dp,
+ 						training_pattern |
+@@ -322,10 +303,8 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp)
+ 
+ 	intel_dp_set_idle_link_train(intel_dp);
+ 
+-	if (channel_eq) {
+-		intel_dp->train_set_valid = true;
++	if (channel_eq)
+ 		DRM_DEBUG_KMS("Channel EQ done. DP Training successful\n");
+-	}
+ }
+ 
+ void intel_dp_stop_link_train(struct intel_dp *intel_dp)
+diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h
+index 3a30b37d6885..8dd2cc56451f 100644
+--- a/drivers/gpu/drm/i915/intel_drv.h
++++ b/drivers/gpu/drm/i915/intel_drv.h
+@@ -811,8 +811,6 @@ struct intel_dp {
+ 	/* This is called before a link training is starterd */
+ 	void (*prepare_link_retrain)(struct intel_dp *intel_dp);
+ 
+-	bool train_set_valid;
+-
+ 	/* Displayport compliance testing */
+ 	unsigned long compliance_test_type;
+ 	unsigned long compliance_test_data;
+diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
+index 0f0492f4a357..28f4407722a1 100644
+--- a/drivers/gpu/drm/i915/intel_fbc.c
++++ b/drivers/gpu/drm/i915/intel_fbc.c
+@@ -823,8 +823,7 @@ static bool intel_fbc_can_choose(struct intel_crtc *crtc)
+ {
+ 	struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+ 	struct intel_fbc *fbc = &dev_priv->fbc;
+-	bool enable_by_default = IS_HASWELL(dev_priv) ||
+-				 IS_BROADWELL(dev_priv);
++	bool enable_by_default = IS_BROADWELL(dev_priv);
+ 
+ 	if (intel_vgpu_active(dev_priv->dev)) {
+ 		fbc->no_fbc_reason = "VGPU is active";
+diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
+index 14e64e08909e..d347dca17267 100644
+--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
++++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
+@@ -182,7 +182,7 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
+ 			}
+ 		}
+ 
+-		fvv = pllreffreq * testn / testm;
++		fvv = pllreffreq * (n + 1) / (m + 1);
+ 		fvv = (fvv - 800000) / 50000;
+ 
+ 		if (fvv > 15)
+@@ -202,6 +202,14 @@ static int mga_g200se_set_plls(struct mga_device *mdev, long clock)
+ 	WREG_DAC(MGA1064_PIX_PLLC_M, m);
+ 	WREG_DAC(MGA1064_PIX_PLLC_N, n);
+ 	WREG_DAC(MGA1064_PIX_PLLC_P, p);
++
++	if (mdev->unique_rev_id >= 0x04) {
++		WREG_DAC(0x1a, 0x09);
++		msleep(20);
++		WREG_DAC(0x1a, 0x01);
++
++	}
++
+ 	return 0;
+ }
+ 
+diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
+index db10c11f0595..c5a6ebd5a478 100644
+--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
++++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/disp.h
+@@ -25,7 +25,8 @@ u16 nvbios_outp_match(struct nvkm_bios *, u16 type, u16 mask,
+ 		      u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_outp *);
+ 
+ struct nvbios_ocfg {
+-	u16 match;
++	u8  proto;
++	u8  flags;
+ 	u16 clkcmp[2];
+ };
+ 
+@@ -33,7 +34,7 @@ u16 nvbios_ocfg_entry(struct nvkm_bios *, u16 outp, u8 idx,
+ 		      u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
+ u16 nvbios_ocfg_parse(struct nvkm_bios *, u16 outp, u8 idx,
+ 		      u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+-u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u16 type,
++u16 nvbios_ocfg_match(struct nvkm_bios *, u16 outp, u8 proto, u8 flags,
+ 		      u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *);
+ u16 nvbios_oclk_match(struct nvkm_bios *, u16 cmp, u32 khz);
+ #endif
+diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+index 59f27e774acb..e40a1b07a014 100644
+--- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c
+@@ -557,6 +557,8 @@ nouveau_fbcon_init(struct drm_device *dev)
+ 	if (ret)
+ 		goto fini;
+ 
++	if (fbcon->helper.fbdev)
++		fbcon->helper.fbdev->pixmap.buf_align = 4;
+ 	return 0;
+ 
+ fini:
+diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
+index 789dc2993b0d..8f715feadf56 100644
+--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
+@@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	uint32_t fg;
+ 	uint32_t bg;
+ 	uint32_t dsize;
+-	uint32_t width;
+ 	uint32_t *data = (uint32_t *)image->data;
+ 	int ret;
+ 
+@@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	if (ret)
+ 		return ret;
+ 
+-	width = ALIGN(image->width, 8);
+-	dsize = ALIGN(width * image->height, 32) >> 5;
+-
+ 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+ 		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
+@@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 			 ((image->dx + image->width) & 0xffff));
+ 	OUT_RING(chan, bg);
+ 	OUT_RING(chan, fg);
+-	OUT_RING(chan, (image->height << 16) | width);
++	OUT_RING(chan, (image->height << 16) | image->width);
+ 	OUT_RING(chan, (image->height << 16) | image->width);
+ 	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
+ 
++	dsize = ALIGN(image->width * image->height, 32) >> 5;
+ 	while (dsize) {
+ 		int iter_len = dsize > 128 ? 128 : dsize;
+ 
+diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c
+index e05499d6ed83..a4e259a00430 100644
+--- a/drivers/gpu/drm/nouveau/nv50_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c
+@@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	struct nouveau_fbdev *nfbdev = info->par;
+ 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ 	struct nouveau_channel *chan = drm->channel;
+-	uint32_t width, dwords, *data = (uint32_t *)image->data;
++	uint32_t dwords, *data = (uint32_t *)image->data;
+ 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ 	uint32_t *palette = info->pseudo_palette;
+ 	int ret;
+@@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	if (ret)
+ 		return ret;
+ 
+-	width = ALIGN(image->width, 32);
+-	dwords = (width * image->height) >> 5;
+-
+ 	BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
+ 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	OUT_RING(chan, 0);
+ 	OUT_RING(chan, image->dy);
+ 
++	dwords = ALIGN(image->width * image->height, 32) >> 5;
+ 	while (dwords) {
+ 		int push = dwords > 2047 ? 2047 : dwords;
+ 
+diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+index c97395b4a312..f28315e865a5 100644
+--- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c
++++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c
+@@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	struct nouveau_fbdev *nfbdev = info->par;
+ 	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
+ 	struct nouveau_channel *chan = drm->channel;
+-	uint32_t width, dwords, *data = (uint32_t *)image->data;
++	uint32_t dwords, *data = (uint32_t *)image->data;
+ 	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
+ 	uint32_t *palette = info->pseudo_palette;
+ 	int ret;
+@@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	if (ret)
+ 		return ret;
+ 
+-	width = ALIGN(image->width, 32);
+-	dwords = (width * image->height) >> 5;
+-
+ 	BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
+ 	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
+ 	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
+@@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
+ 	OUT_RING  (chan, 0);
+ 	OUT_RING  (chan, image->dy);
+ 
++	dwords = ALIGN(image->width * image->height, 32) >> 5;
+ 	while (dwords) {
+ 		int push = dwords > 2047 ? 2047 : dwords;
+ 
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+index 18fab3973ce5..62ad0300cfa5 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/pci.c
+@@ -1614,7 +1614,7 @@ nvkm_device_pci_func = {
+ 	.fini = nvkm_device_pci_fini,
+ 	.resource_addr = nvkm_device_pci_resource_addr,
+ 	.resource_size = nvkm_device_pci_resource_size,
+-	.cpu_coherent = !IS_ENABLED(CONFIG_ARM) && !IS_ENABLED(CONFIG_ARM64),
++	.cpu_coherent = !IS_ENABLED(CONFIG_ARM),
+ };
+ 
+ int
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+index a74c5dd27dc0..e2a64ed14b22 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/Kbuild
+@@ -18,6 +18,7 @@ nvkm-y += nvkm/engine/disp/piornv50.o
+ nvkm-y += nvkm/engine/disp/sornv50.o
+ nvkm-y += nvkm/engine/disp/sorg94.o
+ nvkm-y += nvkm/engine/disp/sorgf119.o
++nvkm-y += nvkm/engine/disp/sorgm107.o
+ nvkm-y += nvkm/engine/disp/sorgm200.o
+ nvkm-y += nvkm/engine/disp/dport.o
+ 
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+index f0314664349c..5dd34382f55a 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
+@@ -76,6 +76,7 @@ exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl,
+ 	mask |= 0x0001 << or;
+ 	mask |= 0x0100 << head;
+ 
++
+ 	list_for_each_entry(outp, &disp->base.outp, head) {
+ 		if ((outp->info.hasht & 0xff) == type &&
+ 		    (outp->info.hashm & mask) == mask) {
+@@ -155,25 +156,21 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
+ 	if (!outp)
+ 		return NULL;
+ 
++	*conf = (ctrl & 0x00000f00) >> 8;
+ 	switch (outp->info.type) {
+ 	case DCB_OUTPUT_TMDS:
+-		*conf = (ctrl & 0x00000f00) >> 8;
+ 		if (*conf == 5)
+ 			*conf |= 0x0100;
+ 		break;
+ 	case DCB_OUTPUT_LVDS:
+-		*conf = disp->sor.lvdsconf;
+-		break;
+-	case DCB_OUTPUT_DP:
+-		*conf = (ctrl & 0x00000f00) >> 8;
++		*conf |= disp->sor.lvdsconf;
+ 		break;
+-	case DCB_OUTPUT_ANALOG:
+ 	default:
+-		*conf = 0x00ff;
+ 		break;
+ 	}
+ 
+-	data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
++	data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8,
++				 &ver, &hdr, &cnt, &len, &info2);
+ 	if (data && id < 0xff) {
+ 		data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
+ 		if (data) {
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+index b6944142d616..f4b9cf8574be 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/gm107.c
+@@ -36,7 +36,7 @@ gm107_disp = {
+ 	.outp.internal.crt = nv50_dac_output_new,
+ 	.outp.internal.tmds = nv50_sor_output_new,
+ 	.outp.internal.lvds = nv50_sor_output_new,
+-	.outp.internal.dp = gf119_sor_dp_new,
++	.outp.internal.dp = gm107_sor_dp_new,
+ 	.dac.nr = 3,
+ 	.dac.power = nv50_dac_power,
+ 	.dac.sense = nv50_dac_sense,
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+index 4226d2153b9c..fcb1b0c46d64 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
+@@ -387,22 +387,17 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
+ 	if (!outp)
+ 		return NULL;
+ 
++	*conf = (ctrl & 0x00000f00) >> 8;
+ 	if (outp->info.location == 0) {
+ 		switch (outp->info.type) {
+ 		case DCB_OUTPUT_TMDS:
+-			*conf = (ctrl & 0x00000f00) >> 8;
+ 			if (*conf == 5)
+ 				*conf |= 0x0100;
+ 			break;
+ 		case DCB_OUTPUT_LVDS:
+-			*conf = disp->sor.lvdsconf;
++			*conf |= disp->sor.lvdsconf;
+ 			break;
+-		case DCB_OUTPUT_DP:
+-			*conf = (ctrl & 0x00000f00) >> 8;
+-			break;
+-		case DCB_OUTPUT_ANALOG:
+ 		default:
+-			*conf = 0x00ff;
+ 			break;
+ 		}
+ 	} else {
+@@ -410,7 +405,8 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
+ 		pclk = pclk / 2;
+ 	}
+ 
+-	data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
++	data = nvbios_ocfg_match(bios, data, *conf & 0xff, *conf >> 8,
++				 &ver, &hdr, &cnt, &len, &info2);
+ 	if (data && id < 0xff) {
+ 		data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
+ 		if (data) {
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
+index e9067ba4e179..4e983f6d7032 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
+@@ -62,7 +62,12 @@ int g94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
+ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+ 		     struct nvkm_output **);
+ int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
++int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int);
+ 
+-int  gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
+-		      struct nvkm_output **);
++int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++		     struct nvkm_output **);
++int gm107_sor_dp_pattern(struct nvkm_output_dp *, int);
++
++int gm200_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
++		     struct nvkm_output **);
+ #endif
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+index b4b41b135643..49bd5da194e1 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
+@@ -40,8 +40,8 @@ static int
+ gf119_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+ {
+ 	struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+-	const u32 loff = gf119_sor_loff(outp);
+-	nvkm_mask(device, 0x61c110 + loff, 0x0f0f0f0f, 0x01010101 * pattern);
++	const u32 soff = gf119_sor_soff(outp);
++	nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, 0x01010101 * pattern);
+ 	return 0;
+ }
+ 
+@@ -64,7 +64,7 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
+ 	return 0;
+ }
+ 
+-static int
++int
+ gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ 		     int ln, int vs, int pe, int pc)
+ {
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+new file mode 100644
+index 000000000000..37790b2617c5
+--- /dev/null
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
+@@ -0,0 +1,53 @@
++/*
++ * Copyright 2016 Red Hat Inc.
++ *
++ * Permission is hereby granted, free of charge, to any person obtaining a
++ * copy of this software and associated documentation files (the "Software"),
++ * to deal in the Software without restriction, including without limitation
++ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
++ * and/or sell copies of the Software, and to permit persons to whom the
++ * Software is furnished to do so, subject to the following conditions:
++ *
++ * The above copyright notice and this permission notice shall be included in
++ * all copies or substantial portions of the Software.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ * OTHER DEALINGS IN THE SOFTWARE.
++ *
++ * Authors: Ben Skeggs <bskeggs@redhat.com>
++ */
++#include "nv50.h"
++#include "outpdp.h"
++
++int
++gm107_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
++{
++	struct nvkm_device *device = outp->base.disp->engine.subdev.device;
++	const u32 soff = outp->base.or * 0x800;
++	const u32 data = 0x01010101 * pattern;
++	if (outp->base.info.sorconf.link & 1)
++		nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
++	else
++		nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
++	return 0;
++}
++
++static const struct nvkm_output_dp_func
++gm107_sor_dp_func = {
++	.pattern = gm107_sor_dp_pattern,
++	.lnk_pwr = g94_sor_dp_lnk_pwr,
++	.lnk_ctl = gf119_sor_dp_lnk_ctl,
++	.drv_ctl = gf119_sor_dp_drv_ctl,
++};
++
++int
++gm107_sor_dp_new(struct nvkm_disp *disp, int index,
++		 struct dcb_output *dcbE, struct nvkm_output **poutp)
++{
++	return nvkm_output_dp_new_(&gm107_sor_dp_func, disp, index, dcbE, poutp);
++}
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+index 2cfbef9c344f..c44fa7ea672a 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
+@@ -57,19 +57,6 @@ gm200_sor_dp_lane_map(struct nvkm_device *device, u8 lane)
+ }
+ 
+ static int
+-gm200_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
+-{
+-	struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+-	const u32 soff = gm200_sor_soff(outp);
+-	const u32 data = 0x01010101 * pattern;
+-	if (outp->base.info.sorconf.link & 1)
+-		nvkm_mask(device, 0x61c110 + soff, 0x0f0f0f0f, data);
+-	else
+-		nvkm_mask(device, 0x61c12c + soff, 0x0f0f0f0f, data);
+-	return 0;
+-}
+-
+-static int
+ gm200_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
+ {
+ 	struct nvkm_device *device = outp->base.disp->engine.subdev.device;
+@@ -129,7 +116,7 @@ gm200_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
+ 
+ static const struct nvkm_output_dp_func
+ gm200_sor_dp_func = {
+-	.pattern = gm200_sor_dp_pattern,
++	.pattern = gm107_sor_dp_pattern,
+ 	.lnk_pwr = gm200_sor_dp_lnk_pwr,
+ 	.lnk_ctl = gf119_sor_dp_lnk_ctl,
+ 	.drv_ctl = gm200_sor_dp_drv_ctl,
+diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+index b2de290da16f..b0c721616c4e 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
++++ b/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
+@@ -942,22 +942,41 @@ gf100_gr_trap_gpc_rop(struct gf100_gr *gr, int gpc)
+ }
+ 
+ static const struct nvkm_enum gf100_mp_warp_error[] = {
+-	{ 0x00, "NO_ERROR" },
+-	{ 0x01, "STACK_MISMATCH" },
++	{ 0x01, "STACK_ERROR" },
++	{ 0x02, "API_STACK_ERROR" },
++	{ 0x03, "RET_EMPTY_STACK_ERROR" },
++	{ 0x04, "PC_WRAP" },
+ 	{ 0x05, "MISALIGNED_PC" },
+-	{ 0x08, "MISALIGNED_GPR" },
+-	{ 0x09, "INVALID_OPCODE" },
+-	{ 0x0d, "GPR_OUT_OF_BOUNDS" },
+-	{ 0x0e, "MEM_OUT_OF_BOUNDS" },
+-	{ 0x0f, "UNALIGNED_MEM_ACCESS" },
++	{ 0x06, "PC_OVERFLOW" },
++	{ 0x07, "MISALIGNED_IMMC_ADDR" },
++	{ 0x08, "MISALIGNED_REG" },
++	{ 0x09, "ILLEGAL_INSTR_ENCODING" },
++	{ 0x0a, "ILLEGAL_SPH_INSTR_COMBO" },
++	{ 0x0b, "ILLEGAL_INSTR_PARAM" },
++	{ 0x0c, "INVALID_CONST_ADDR" },
++	{ 0x0d, "OOR_REG" },
++	{ 0x0e, "OOR_ADDR" },
++	{ 0x0f, "MISALIGNED_ADDR" },
+ 	{ 0x10, "INVALID_ADDR_SPACE" },
+-	{ 0x11, "INVALID_PARAM" },
++	{ 0x11, "ILLEGAL_INSTR_PARAM2" },
++	{ 0x12, "INVALID_CONST_ADDR_LDC" },
++	{ 0x13, "GEOMETRY_SM_ERROR" },
++	{ 0x14, "DIVERGENT" },
++	{ 0x15, "WARP_EXIT" },
+ 	{}
+ };
+ 
+ static const struct nvkm_bitfield gf100_mp_global_error[] = {
++	{ 0x00000001, "SM_TO_SM_FAULT" },
++	{ 0x00000002, "L1_ERROR" },
+ 	{ 0x00000004, "MULTIPLE_WARP_ERRORS" },
+-	{ 0x00000008, "OUT_OF_STACK_SPACE" },
++	{ 0x00000008, "PHYSICAL_STACK_OVERFLOW" },
++	{ 0x00000010, "BPT_INT" },
++	{ 0x00000020, "BPT_PAUSE" },
++	{ 0x00000040, "SINGLE_STEP_COMPLETE" },
++	{ 0x20000000, "ECC_SEC_ERROR" },
++	{ 0x40000000, "ECC_DED_ERROR" },
++	{ 0x80000000, "TIMEOUT" },
+ 	{}
+ };
+ 
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
+index a5e92135cd77..9efb1b48cd54 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/disp.c
+@@ -141,7 +141,8 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx,
+ {
+ 	u16 data = nvbios_ocfg_entry(bios, outp, idx, ver, hdr, cnt, len);
+ 	if (data) {
+-		info->match     = nvbios_rd16(bios, data + 0x00);
++		info->proto     = nvbios_rd08(bios, data + 0x00);
++		info->flags     = nvbios_rd16(bios, data + 0x01);
+ 		info->clkcmp[0] = nvbios_rd16(bios, data + 0x02);
+ 		info->clkcmp[1] = nvbios_rd16(bios, data + 0x04);
+ 	}
+@@ -149,12 +150,13 @@ nvbios_ocfg_parse(struct nvkm_bios *bios, u16 outp, u8 idx,
+ }
+ 
+ u16
+-nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u16 type,
++nvbios_ocfg_match(struct nvkm_bios *bios, u16 outp, u8 proto, u8 flags,
+ 		  u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_ocfg *info)
+ {
+ 	u16 data, idx = 0;
+ 	while ((data = nvbios_ocfg_parse(bios, outp, idx++, ver, hdr, cnt, len, info))) {
+-		if (info->match == type)
++		if ((info->proto == proto || info->proto == 0xff) &&
++		    (info->flags == flags))
+ 			break;
+ 	}
+ 	return data;
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
+index e292f5679418..389fb13a1998 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm107.c
+@@ -69,11 +69,11 @@ gm107_ltc_zbc_clear_depth(struct nvkm_ltc *ltc, int i, const u32 depth)
+ }
+ 
+ static void
+-gm107_ltc_lts_isr(struct nvkm_ltc *ltc, int c, int s)
++gm107_ltc_intr_lts(struct nvkm_ltc *ltc, int c, int s)
+ {
+ 	struct nvkm_subdev *subdev = &ltc->subdev;
+ 	struct nvkm_device *device = subdev->device;
+-	u32 base = 0x140000 + (c * 0x2000) + (s * 0x200);
++	u32 base = 0x140400 + (c * 0x2000) + (s * 0x200);
+ 	u32 stat = nvkm_rd32(device, base + 0x00c);
+ 
+ 	if (stat) {
+@@ -92,7 +92,7 @@ gm107_ltc_intr(struct nvkm_ltc *ltc)
+ 	while (mask) {
+ 		u32 s, c = __ffs(mask);
+ 		for (s = 0; s < ltc->lts_nr; s++)
+-			gm107_ltc_lts_isr(ltc, c, s);
++			gm107_ltc_intr_lts(ltc, c, s);
+ 		mask &= ~(1 << c);
+ 	}
+ }
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c
+index 2a29bfd5125a..e18e0dc19ec8 100644
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gm200.c
+@@ -46,7 +46,7 @@ static const struct nvkm_ltc_func
+ gm200_ltc = {
+ 	.oneinit = gm200_ltc_oneinit,
+ 	.init = gm200_ltc_init,
+-	.intr = gm107_ltc_intr, /*XXX: not validated */
++	.intr = gm107_ltc_intr,
+ 	.cbc_clear = gm107_ltc_cbc_clear,
+ 	.cbc_wait = gm107_ltc_cbc_wait,
+ 	.zbc = 16,
+diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
+index d0826fb0434c..cb2986876738 100644
+--- a/drivers/gpu/drm/radeon/radeon_device.c
++++ b/drivers/gpu/drm/radeon/radeon_device.c
+@@ -630,6 +630,23 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
+ /*
+  * GPU helpers function.
+  */
++
++/**
++ * radeon_device_is_virtual - check if we are running is a virtual environment
++ *
++ * Check if the asic has been passed through to a VM (all asics).
++ * Used at driver startup.
++ * Returns true if virtual or false if not.
++ */
++static bool radeon_device_is_virtual(void)
++{
++#ifdef CONFIG_X86
++	return boot_cpu_has(X86_FEATURE_HYPERVISOR);
++#else
++	return false;
++#endif
++}
++
+ /**
+  * radeon_card_posted - check if the hw has already been initialized
+  *
+@@ -643,6 +660,10 @@ bool radeon_card_posted(struct radeon_device *rdev)
+ {
+ 	uint32_t reg;
+ 
++	/* for pass through, always force asic_init */
++	if (radeon_device_is_virtual())
++		return false;
++
+ 	/* required for EFI mode on macbook2,1 which uses an r5xx asic */
+ 	if (efi_enabled(EFI_BOOT) &&
+ 	    (rdev->pdev->subsystem_vendor == PCI_VENDOR_ID_APPLE) &&
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
+index e3daafa1be13..3e7c9ac50ccd 100644
+--- a/drivers/gpu/drm/ttm/ttm_bo.c
++++ b/drivers/gpu/drm/ttm/ttm_bo.c
+@@ -1016,9 +1016,9 @@ out_unlock:
+ 	return ret;
+ }
+ 
+-static bool ttm_bo_mem_compat(struct ttm_placement *placement,
+-			      struct ttm_mem_reg *mem,
+-			      uint32_t *new_flags)
++bool ttm_bo_mem_compat(struct ttm_placement *placement,
++		       struct ttm_mem_reg *mem,
++		       uint32_t *new_flags)
+ {
+ 	int i;
+ 
+@@ -1050,6 +1050,7 @@ static bool ttm_bo_mem_compat(struct ttm_placement *placement,
+ 
+ 	return false;
+ }
++EXPORT_SYMBOL(ttm_bo_mem_compat);
+ 
+ int ttm_bo_validate(struct ttm_buffer_object *bo,
+ 			struct ttm_placement *placement,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+index 299925a1f6c6..eadc981ee79a 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_dmabuf.c
+@@ -49,6 +49,7 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
+ {
+ 	struct ttm_buffer_object *bo = &buf->base;
+ 	int ret;
++	uint32_t new_flags;
+ 
+ 	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
+ 	if (unlikely(ret != 0))
+@@ -60,7 +61,12 @@ int vmw_dmabuf_pin_in_placement(struct vmw_private *dev_priv,
+ 	if (unlikely(ret != 0))
+ 		goto err;
+ 
+-	ret = ttm_bo_validate(bo, placement, interruptible, false);
++	if (buf->pin_count > 0)
++		ret = ttm_bo_mem_compat(placement, &bo->mem,
++					&new_flags) == true ? 0 : -EINVAL;
++	else
++		ret = ttm_bo_validate(bo, placement, interruptible, false);
++
+ 	if (!ret)
+ 		vmw_bo_pin_reserved(buf, true);
+ 
+@@ -91,6 +97,7 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
+ {
+ 	struct ttm_buffer_object *bo = &buf->base;
+ 	int ret;
++	uint32_t new_flags;
+ 
+ 	ret = ttm_write_lock(&dev_priv->reservation_sem, interruptible);
+ 	if (unlikely(ret != 0))
+@@ -102,6 +109,12 @@ int vmw_dmabuf_pin_in_vram_or_gmr(struct vmw_private *dev_priv,
+ 	if (unlikely(ret != 0))
+ 		goto err;
+ 
++	if (buf->pin_count > 0) {
++		ret = ttm_bo_mem_compat(&vmw_vram_gmr_placement, &bo->mem,
++					&new_flags) == true ? 0 : -EINVAL;
++		goto out_unreserve;
++	}
++
+ 	ret = ttm_bo_validate(bo, &vmw_vram_gmr_placement, interruptible,
+ 			      false);
+ 	if (likely(ret == 0) || ret == -ERESTARTSYS)
+@@ -161,6 +174,7 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
+ 	struct ttm_placement placement;
+ 	struct ttm_place place;
+ 	int ret = 0;
++	uint32_t new_flags;
+ 
+ 	place = vmw_vram_placement.placement[0];
+ 	place.lpfn = bo->num_pages;
+@@ -185,10 +199,15 @@ int vmw_dmabuf_pin_in_start_of_vram(struct vmw_private *dev_priv,
+ 	 */
+ 	if (bo->mem.mem_type == TTM_PL_VRAM &&
+ 	    bo->mem.start < bo->num_pages &&
+-	    bo->mem.start > 0)
++	    bo->mem.start > 0 &&
++	    buf->pin_count == 0)
+ 		(void) ttm_bo_validate(bo, &vmw_sys_placement, false, false);
+ 
+-	ret = ttm_bo_validate(bo, &placement, interruptible, false);
++	if (buf->pin_count > 0)
++		ret = ttm_bo_mem_compat(&placement, &bo->mem,
++					&new_flags) == true ? 0 : -EINVAL;
++	else
++		ret = ttm_bo_validate(bo, &placement, interruptible, false);
+ 
+ 	/* For some reason we didn't end up at the start of vram */
+ 	WARN_ON(ret == 0 && bo->offset != 0);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+index f2cf9231872a..2a505464c50f 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
+@@ -227,6 +227,7 @@ static int vmw_force_iommu;
+ static int vmw_restrict_iommu;
+ static int vmw_force_coherent;
+ static int vmw_restrict_dma_mask;
++static int vmw_assume_16bpp;
+ 
+ static int vmw_probe(struct pci_dev *, const struct pci_device_id *);
+ static void vmw_master_init(struct vmw_master *);
+@@ -243,6 +244,8 @@ MODULE_PARM_DESC(force_coherent, "Force coherent TTM pages");
+ module_param_named(force_coherent, vmw_force_coherent, int, 0600);
+ MODULE_PARM_DESC(restrict_dma_mask, "Restrict DMA mask to 44 bits with IOMMU");
+ module_param_named(restrict_dma_mask, vmw_restrict_dma_mask, int, 0600);
++MODULE_PARM_DESC(assume_16bpp, "Assume 16-bpp when filtering modes");
++module_param_named(assume_16bpp, vmw_assume_16bpp, int, 0600);
+ 
+ 
+ static void vmw_print_capabilities(uint32_t capabilities)
+@@ -653,6 +656,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
+ 	dev_priv->vram_start = pci_resource_start(dev->pdev, 1);
+ 	dev_priv->mmio_start = pci_resource_start(dev->pdev, 2);
+ 
++	dev_priv->assume_16bpp = !!vmw_assume_16bpp;
++
+ 	dev_priv->enable_fb = enable_fbdev;
+ 
+ 	vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2);
+@@ -699,6 +704,13 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
+ 			vmw_read(dev_priv,
+ 				 SVGA_REG_SUGGESTED_GBOBJECT_MEM_SIZE_KB);
+ 
++		/*
++		 * Workaround for low memory 2D VMs to compensate for the
++		 * allocation taken by fbdev
++		 */
++		if (!(dev_priv->capabilities & SVGA_CAP_3D))
++			mem_size *= 2;
++
+ 		dev_priv->max_mob_pages = mem_size * 1024 / PAGE_SIZE;
+ 		dev_priv->prim_bb_mem =
+ 			vmw_read(dev_priv,
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+index 6db358a85b46..cab0c54b46ae 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
+@@ -386,6 +386,7 @@ struct vmw_private {
+ 	spinlock_t hw_lock;
+ 	spinlock_t cap_lock;
+ 	bool has_dx;
++	bool assume_16bpp;
+ 
+ 	/*
+ 	 * VGA registers.
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+index 679a4cb98ee3..d2d93959b119 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c
+@@ -517,28 +517,6 @@ static int vmw_fb_kms_framebuffer(struct fb_info *info)
+ 
+ 	par->set_fb = &vfb->base;
+ 
+-	if (!par->bo_ptr) {
+-		/*
+-		 * Pin before mapping. Since we don't know in what placement
+-		 * to pin, call into KMS to do it for us.
+-		 */
+-		ret = vfb->pin(vfb);
+-		if (ret) {
+-			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
+-			return ret;
+-		}
+-
+-		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
+-				  par->vmw_bo->base.num_pages, &par->map);
+-		if (ret) {
+-			vfb->unpin(vfb);
+-			DRM_ERROR("Could not map the fbdev framebuffer.\n");
+-			return ret;
+-		}
+-
+-		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
+-	}
+-
+ 	return 0;
+ }
+ 
+@@ -601,6 +579,31 @@ static int vmw_fb_set_par(struct fb_info *info)
+ 	if (ret)
+ 		goto out_unlock;
+ 
++	if (!par->bo_ptr) {
++		struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(set.fb);
++
++		/*
++		 * Pin before mapping. Since we don't know in what placement
++		 * to pin, call into KMS to do it for us.
++		 */
++		ret = vfb->pin(vfb);
++		if (ret) {
++			DRM_ERROR("Could not pin the fbdev framebuffer.\n");
++			goto out_unlock;
++		}
++
++		ret = ttm_bo_kmap(&par->vmw_bo->base, 0,
++				  par->vmw_bo->base.num_pages, &par->map);
++		if (ret) {
++			vfb->unpin(vfb);
++			DRM_ERROR("Could not map the fbdev framebuffer.\n");
++			goto out_unlock;
++		}
++
++		par->bo_ptr = ttm_kmap_obj_virtual(&par->map, &par->bo_iowrite);
++	}
++
++
+ 	vmw_fb_dirty_mark(par, par->fb_x, par->fb_y,
+ 			  par->set_fb->width, par->set_fb->height);
+ 
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+index b07543b5cea4..6ccd61d37b78 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+@@ -1553,14 +1553,10 @@ int vmw_du_connector_fill_modes(struct drm_connector *connector,
+ 		DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC)
+ 	};
+ 	int i;
+-	u32 assumed_bpp = 2;
++	u32 assumed_bpp = 4;
+ 
+-	/*
+-	 * If using screen objects, then assume 32-bpp because that's what the
+-	 * SVGA device is assuming
+-	 */
+-	if (dev_priv->active_display_unit == vmw_du_screen_object)
+-		assumed_bpp = 4;
++	if (dev_priv->assume_16bpp)
++		assumed_bpp = 2;
+ 
+ 	if (dev_priv->active_display_unit == vmw_du_screen_target) {
+ 		max_width  = min(max_width,  dev_priv->stdu_max_width);
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+index 9ca818fb034c..41932a7c4f79 100644
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
+@@ -399,8 +399,10 @@ static int vmw_stdu_bind_fb(struct vmw_private *dev_priv,
+ 
+ 	WARN_ON_ONCE(!stdu->defined);
+ 
+-	if (!vfb->dmabuf && new_fb->width == mode->hdisplay &&
+-	    new_fb->height == mode->vdisplay)
++	new_vfbs = (vfb->dmabuf) ? NULL : vmw_framebuffer_to_vfbs(new_fb);
++
++	if (new_vfbs && new_vfbs->surface->base_size.width == mode->hdisplay &&
++	    new_vfbs->surface->base_size.height == mode->vdisplay)
+ 		new_content_type = SAME_AS_DISPLAY;
+ 	else if (vfb->dmabuf)
+ 		new_content_type = SEPARATE_DMA;
+@@ -444,7 +446,6 @@ static int vmw_stdu_bind_fb(struct vmw_private *dev_priv,
+ 			content_srf.mip_levels[0]     = 1;
+ 			content_srf.multisample_count = 0;
+ 		} else {
+-			new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
+ 			content_srf = *new_vfbs->surface;
+ 		}
+ 
+@@ -464,7 +465,6 @@ static int vmw_stdu_bind_fb(struct vmw_private *dev_priv,
+ 			return ret;
+ 		}
+ 	} else if (new_content_type == SAME_AS_DISPLAY) {
+-		new_vfbs = vmw_framebuffer_to_vfbs(new_fb);
+ 		new_display_srf = vmw_surface_reference(new_vfbs->surface);
+ 	}
+ 
+diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c
+index aad8c162a825..0cd4f7216239 100644
+--- a/drivers/hid/hid-elo.c
++++ b/drivers/hid/hid-elo.c
+@@ -261,7 +261,7 @@ static void elo_remove(struct hid_device *hdev)
+ 	struct elo_priv *priv = hid_get_drvdata(hdev);
+ 
+ 	hid_hw_stop(hdev);
+-	flush_workqueue(wq);
++	cancel_delayed_work_sync(&priv->work);
+ 	kfree(priv);
+ }
+ 
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index c741f5e50a66..0088979f7281 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -61,6 +61,7 @@ MODULE_LICENSE("GPL");
+ #define MT_QUIRK_ALWAYS_VALID		(1 << 4)
+ #define MT_QUIRK_VALID_IS_INRANGE	(1 << 5)
+ #define MT_QUIRK_VALID_IS_CONFIDENCE	(1 << 6)
++#define MT_QUIRK_CONFIDENCE		(1 << 7)
+ #define MT_QUIRK_SLOT_IS_CONTACTID_MINUS_ONE	(1 << 8)
+ #define MT_QUIRK_NO_AREA		(1 << 9)
+ #define MT_QUIRK_IGNORE_DUPLICATES	(1 << 10)
+@@ -78,6 +79,7 @@ struct mt_slot {
+ 	__s32 contactid;	/* the device ContactID assigned to this slot */
+ 	bool touch_state;	/* is the touch valid? */
+ 	bool inrange_state;	/* is the finger in proximity of the sensor? */
++	bool confidence_state;  /* is the touch made by a finger? */
+ };
+ 
+ struct mt_class {
+@@ -503,10 +505,8 @@ static int mt_touch_input_mapping(struct hid_device *hdev, struct hid_input *hi,
+ 			return 1;
+ 		case HID_DG_CONFIDENCE:
+ 			if (cls->name == MT_CLS_WIN_8 &&
+-				field->application == HID_DG_TOUCHPAD) {
+-				cls->quirks &= ~MT_QUIRK_ALWAYS_VALID;
+-				cls->quirks |= MT_QUIRK_VALID_IS_CONFIDENCE;
+-			}
++				field->application == HID_DG_TOUCHPAD)
++				cls->quirks |= MT_QUIRK_CONFIDENCE;
+ 			mt_store_field(usage, td, hi);
+ 			return 1;
+ 		case HID_DG_TIPSWITCH:
+@@ -619,6 +619,7 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
+ 		return;
+ 
+ 	if (td->curvalid || (td->mtclass.quirks & MT_QUIRK_ALWAYS_VALID)) {
++		int active;
+ 		int slotnum = mt_compute_slot(td, input);
+ 		struct mt_slot *s = &td->curdata;
+ 		struct input_mt *mt = input->mt;
+@@ -633,10 +634,14 @@ static void mt_complete_slot(struct mt_device *td, struct input_dev *input)
+ 				return;
+ 		}
+ 
++		if (!(td->mtclass.quirks & MT_QUIRK_CONFIDENCE))
++			s->confidence_state = 1;
++		active = (s->touch_state || s->inrange_state) &&
++							s->confidence_state;
++
+ 		input_mt_slot(input, slotnum);
+-		input_mt_report_slot_state(input, MT_TOOL_FINGER,
+-			s->touch_state || s->inrange_state);
+-		if (s->touch_state || s->inrange_state) {
++		input_mt_report_slot_state(input, MT_TOOL_FINGER, active);
++		if (active) {
+ 			/* this finger is in proximity of the sensor */
+ 			int wide = (s->w > s->h);
+ 			/* divided by two to match visual scale of touch */
+@@ -701,6 +706,8 @@ static void mt_process_mt_event(struct hid_device *hid, struct hid_field *field,
+ 			td->curdata.touch_state = value;
+ 			break;
+ 		case HID_DG_CONFIDENCE:
++			if (quirks & MT_QUIRK_CONFIDENCE)
++				td->curdata.confidence_state = value;
+ 			if (quirks & MT_QUIRK_VALID_IS_CONFIDENCE)
+ 				td->curvalid = value;
+ 			break;
+diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
+index 2f1ddca6f2e0..700145b15088 100644
+--- a/drivers/hid/usbhid/hiddev.c
++++ b/drivers/hid/usbhid/hiddev.c
+@@ -516,13 +516,13 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
+ 					goto inval;
+ 			} else if (uref->usage_index >= field->report_count)
+ 				goto inval;
+-
+-			else if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
+-				 (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
+-				  uref->usage_index + uref_multi->num_values > field->report_count))
+-				goto inval;
+ 		}
+ 
++		if ((cmd == HIDIOCGUSAGES || cmd == HIDIOCSUSAGES) &&
++		    (uref_multi->num_values > HID_MAX_MULTI_USAGES ||
++		     uref->usage_index + uref_multi->num_values > field->report_count))
++			goto inval;
++
+ 		switch (cmd) {
+ 		case HIDIOCGUSAGE:
+ 			uref->value = field->value[uref->usage_index];
+diff --git a/drivers/hwmon/dell-smm-hwmon.c b/drivers/hwmon/dell-smm-hwmon.c
+index c43318d3416e..a9356a3dea92 100644
+--- a/drivers/hwmon/dell-smm-hwmon.c
++++ b/drivers/hwmon/dell-smm-hwmon.c
+@@ -66,11 +66,13 @@
+ 
+ static DEFINE_MUTEX(i8k_mutex);
+ static char bios_version[4];
++static char bios_machineid[16];
+ static struct device *i8k_hwmon_dev;
+ static u32 i8k_hwmon_flags;
+ static uint i8k_fan_mult = I8K_FAN_MULT;
+ static uint i8k_pwm_mult;
+ static uint i8k_fan_max = I8K_FAN_HIGH;
++static bool disallow_fan_type_call;
+ 
+ #define I8K_HWMON_HAVE_TEMP1	(1 << 0)
+ #define I8K_HWMON_HAVE_TEMP2	(1 << 1)
+@@ -94,13 +96,13 @@ module_param(ignore_dmi, bool, 0);
+ MODULE_PARM_DESC(ignore_dmi, "Continue probing hardware even if DMI data does not match");
+ 
+ #if IS_ENABLED(CONFIG_I8K)
+-static bool restricted;
++static bool restricted = true;
+ module_param(restricted, bool, 0);
+-MODULE_PARM_DESC(restricted, "Allow fan control if SYS_ADMIN capability set");
++MODULE_PARM_DESC(restricted, "Restrict fan control and serial number to CAP_SYS_ADMIN (default: 1)");
+ 
+ static bool power_status;
+ module_param(power_status, bool, 0600);
+-MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k");
++MODULE_PARM_DESC(power_status, "Report power status in /proc/i8k (default: 0)");
+ #endif
+ 
+ static uint fan_mult;
+@@ -235,14 +237,28 @@ static int i8k_get_fan_speed(int fan)
+ /*
+  * Read the fan type.
+  */
+-static int i8k_get_fan_type(int fan)
++static int _i8k_get_fan_type(int fan)
+ {
+ 	struct smm_regs regs = { .eax = I8K_SMM_GET_FAN_TYPE, };
+ 
++	if (disallow_fan_type_call)
++		return -EINVAL;
++
+ 	regs.ebx = fan & 0xff;
+ 	return i8k_smm(&regs) ? : regs.eax & 0xff;
+ }
+ 
++static int i8k_get_fan_type(int fan)
++{
++	/* I8K_SMM_GET_FAN_TYPE SMM call is expensive, so cache values */
++	static int types[2] = { INT_MIN, INT_MIN };
++
++	if (types[fan] == INT_MIN)
++		types[fan] = _i8k_get_fan_type(fan);
++
++	return types[fan];
++}
++
+ /*
+  * Read the fan nominal rpm for specific fan speed.
+  */
+@@ -392,9 +408,11 @@ i8k_ioctl_unlocked(struct file *fp, unsigned int cmd, unsigned long arg)
+ 		break;
+ 
+ 	case I8K_MACHINE_ID:
+-		memset(buff, 0, 16);
+-		strlcpy(buff, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
+-			sizeof(buff));
++		if (restricted && !capable(CAP_SYS_ADMIN))
++			return -EPERM;
++
++		memset(buff, 0, sizeof(buff));
++		strlcpy(buff, bios_machineid, sizeof(buff));
+ 		break;
+ 
+ 	case I8K_FN_STATUS:
+@@ -511,7 +529,7 @@ static int i8k_proc_show(struct seq_file *seq, void *offset)
+ 	seq_printf(seq, "%s %s %s %d %d %d %d %d %d %d\n",
+ 		   I8K_PROC_FMT,
+ 		   bios_version,
+-		   i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
++		   (restricted && !capable(CAP_SYS_ADMIN)) ? "-1" : bios_machineid,
+ 		   cpu_temp,
+ 		   left_fan, right_fan, left_speed, right_speed,
+ 		   ac_power, fn_key);
+@@ -718,6 +736,9 @@ static struct attribute *i8k_attrs[] = {
+ static umode_t i8k_is_visible(struct kobject *kobj, struct attribute *attr,
+ 			      int index)
+ {
++	if (disallow_fan_type_call &&
++	    (index == 9 || index == 12))
++		return 0;
+ 	if (index >= 0 && index <= 1 &&
+ 	    !(i8k_hwmon_flags & I8K_HWMON_HAVE_TEMP1))
+ 		return 0;
+@@ -767,13 +788,17 @@ static int __init i8k_init_hwmon(void)
+ 	if (err >= 0)
+ 		i8k_hwmon_flags |= I8K_HWMON_HAVE_TEMP4;
+ 
+-	/* First fan attributes, if fan type is OK */
+-	err = i8k_get_fan_type(0);
++	/* First fan attributes, if fan status or type is OK */
++	err = i8k_get_fan_status(0);
++	if (err < 0)
++		err = i8k_get_fan_type(0);
+ 	if (err >= 0)
+ 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN1;
+ 
+-	/* Second fan attributes, if fan type is OK */
+-	err = i8k_get_fan_type(1);
++	/* Second fan attributes, if fan status or type is OK */
++	err = i8k_get_fan_status(1);
++	if (err < 0)
++		err = i8k_get_fan_type(1);
+ 	if (err >= 0)
+ 		i8k_hwmon_flags |= I8K_HWMON_HAVE_FAN2;
+ 
+@@ -929,12 +954,14 @@ static struct dmi_system_id i8k_dmi_table[] __initdata = {
+ 
+ MODULE_DEVICE_TABLE(dmi, i8k_dmi_table);
+ 
+-static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
++/*
++ * On some machines once I8K_SMM_GET_FAN_TYPE is issued then CPU fan speed
++ * randomly going up and down due to bug in Dell SMM or BIOS. Here is blacklist
++ * of affected Dell machines for which we disallow I8K_SMM_GET_FAN_TYPE call.
++ * See bug: https://bugzilla.kernel.org/show_bug.cgi?id=100121
++ */
++static struct dmi_system_id i8k_blacklist_fan_type_dmi_table[] __initdata = {
+ 	{
+-		/*
+-		 * CPU fan speed going up and down on Dell Studio XPS 8000
+-		 * for unknown reasons.
+-		 */
+ 		.ident = "Dell Studio XPS 8000",
+ 		.matches = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+@@ -942,16 +969,19 @@ static struct dmi_system_id i8k_blacklist_dmi_table[] __initdata = {
+ 		},
+ 	},
+ 	{
+-		/*
+-		 * CPU fan speed going up and down on Dell Studio XPS 8100
+-		 * for unknown reasons.
+-		 */
+ 		.ident = "Dell Studio XPS 8100",
+ 		.matches = {
+ 			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ 			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Studio XPS 8100"),
+ 		},
+ 	},
++	{
++		.ident = "Dell Inspiron 580",
++		.matches = {
++			DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
++			DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Inspiron 580 "),
++		},
++	},
+ 	{ }
+ };
+ 
+@@ -966,8 +996,7 @@ static int __init i8k_probe(void)
+ 	/*
+ 	 * Get DMI information
+ 	 */
+-	if (!dmi_check_system(i8k_dmi_table) ||
+-	    dmi_check_system(i8k_blacklist_dmi_table)) {
++	if (!dmi_check_system(i8k_dmi_table)) {
+ 		if (!ignore_dmi && !force)
+ 			return -ENODEV;
+ 
+@@ -978,8 +1007,13 @@ static int __init i8k_probe(void)
+ 			i8k_get_dmi_data(DMI_BIOS_VERSION));
+ 	}
+ 
++	if (dmi_check_system(i8k_blacklist_fan_type_dmi_table))
++		disallow_fan_type_call = true;
++
+ 	strlcpy(bios_version, i8k_get_dmi_data(DMI_BIOS_VERSION),
+ 		sizeof(bios_version));
++	strlcpy(bios_machineid, i8k_get_dmi_data(DMI_PRODUCT_SERIAL),
++		sizeof(bios_machineid));
+ 
+ 	/*
+ 	 * Get SMM Dell signature
+diff --git a/drivers/iio/accel/kxsd9.c b/drivers/iio/accel/kxsd9.c
+index 923f56598d4b..3a9f106787d2 100644
+--- a/drivers/iio/accel/kxsd9.c
++++ b/drivers/iio/accel/kxsd9.c
+@@ -81,7 +81,7 @@ static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro)
+ 
+ 	mutex_lock(&st->buf_lock);
+ 	ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+-	if (ret)
++	if (ret < 0)
+ 		goto error_ret;
+ 	st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C);
+ 	st->tx[1] = (ret & ~KXSD9_FS_MASK) | i;
+@@ -163,7 +163,7 @@ static int kxsd9_read_raw(struct iio_dev *indio_dev,
+ 		break;
+ 	case IIO_CHAN_INFO_SCALE:
+ 		ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C));
+-		if (ret)
++		if (ret < 0)
+ 			goto error_ret;
+ 		*val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK];
+ 		ret = IIO_VAL_INT_PLUS_MICRO;
+diff --git a/drivers/iio/adc/ad7266.c b/drivers/iio/adc/ad7266.c
+index 21e19b60e2b9..2123f0ac2e2a 100644
+--- a/drivers/iio/adc/ad7266.c
++++ b/drivers/iio/adc/ad7266.c
+@@ -396,8 +396,8 @@ static int ad7266_probe(struct spi_device *spi)
+ 
+ 	st = iio_priv(indio_dev);
+ 
+-	st->reg = devm_regulator_get(&spi->dev, "vref");
+-	if (!IS_ERR_OR_NULL(st->reg)) {
++	st->reg = devm_regulator_get_optional(&spi->dev, "vref");
++	if (!IS_ERR(st->reg)) {
+ 		ret = regulator_enable(st->reg);
+ 		if (ret)
+ 			return ret;
+@@ -408,6 +408,9 @@ static int ad7266_probe(struct spi_device *spi)
+ 
+ 		st->vref_mv = ret / 1000;
+ 	} else {
++		/* Any other error indicates that the regulator does exist */
++		if (PTR_ERR(st->reg) != -ENODEV)
++			return PTR_ERR(st->reg);
+ 		/* Use internal reference */
+ 		st->vref_mv = 2500;
+ 	}
+diff --git a/drivers/iio/humidity/hdc100x.c b/drivers/iio/humidity/hdc100x.c
+index fa4767613173..a03832a5fc95 100644
+--- a/drivers/iio/humidity/hdc100x.c
++++ b/drivers/iio/humidity/hdc100x.c
+@@ -55,7 +55,7 @@ static const struct {
+ 	},
+ 	{ /* IIO_HUMIDITYRELATIVE channel */
+ 		.shift = 8,
+-		.mask = 2,
++		.mask = 3,
+ 	},
+ };
+ 
+@@ -164,14 +164,14 @@ static int hdc100x_get_measurement(struct hdc100x_data *data,
+ 		dev_err(&client->dev, "cannot read high byte measurement");
+ 		return ret;
+ 	}
+-	val = ret << 6;
++	val = ret << 8;
+ 
+ 	ret = i2c_smbus_read_byte(client);
+ 	if (ret < 0) {
+ 		dev_err(&client->dev, "cannot read low byte measurement");
+ 		return ret;
+ 	}
+-	val |= ret >> 2;
++	val |= ret;
+ 
+ 	return val;
+ }
+@@ -211,18 +211,18 @@ static int hdc100x_read_raw(struct iio_dev *indio_dev,
+ 		return IIO_VAL_INT_PLUS_MICRO;
+ 	case IIO_CHAN_INFO_SCALE:
+ 		if (chan->type == IIO_TEMP) {
+-			*val = 165;
+-			*val2 = 65536 >> 2;
++			*val = 165000;
++			*val2 = 65536;
+ 			return IIO_VAL_FRACTIONAL;
+ 		} else {
+-			*val = 0;
+-			*val2 = 10000;
+-			return IIO_VAL_INT_PLUS_MICRO;
++			*val = 100;
++			*val2 = 65536;
++			return IIO_VAL_FRACTIONAL;
+ 		}
+ 		break;
+ 	case IIO_CHAN_INFO_OFFSET:
+-		*val = -3971;
+-		*val2 = 879096;
++		*val = -15887;
++		*val2 = 515151;
+ 		return IIO_VAL_INT_PLUS_MICRO;
+ 	default:
+ 		return -EINVAL;
+diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c
+index ae2806aafb72..0c52dfe64977 100644
+--- a/drivers/iio/industrialio-trigger.c
++++ b/drivers/iio/industrialio-trigger.c
+@@ -210,22 +210,35 @@ static int iio_trigger_attach_poll_func(struct iio_trigger *trig,
+ 
+ 	/* Prevent the module from being removed whilst attached to a trigger */
+ 	__module_get(pf->indio_dev->info->driver_module);
++
++	/* Get irq number */
+ 	pf->irq = iio_trigger_get_irq(trig);
++	if (pf->irq < 0)
++		goto out_put_module;
++
++	/* Request irq */
+ 	ret = request_threaded_irq(pf->irq, pf->h, pf->thread,
+ 				   pf->type, pf->name,
+ 				   pf);
+-	if (ret < 0) {
+-		module_put(pf->indio_dev->info->driver_module);
+-		return ret;
+-	}
++	if (ret < 0)
++		goto out_put_irq;
+ 
++	/* Enable trigger in driver */
+ 	if (trig->ops && trig->ops->set_trigger_state && notinuse) {
+ 		ret = trig->ops->set_trigger_state(trig, true);
+ 		if (ret < 0)
+-			module_put(pf->indio_dev->info->driver_module);
++			goto out_free_irq;
+ 	}
+ 
+ 	return ret;
++
++out_free_irq:
++	free_irq(pf->irq, pf);
++out_put_irq:
++	iio_trigger_put_irq(trig, pf->irq);
++out_put_module:
++	module_put(pf->indio_dev->info->driver_module);
++	return ret;
+ }
+ 
+ static int iio_trigger_detach_poll_func(struct iio_trigger *trig,
+diff --git a/drivers/iio/light/apds9960.c b/drivers/iio/light/apds9960.c
+index a6af56ad10e1..6443aad809b2 100644
+--- a/drivers/iio/light/apds9960.c
++++ b/drivers/iio/light/apds9960.c
+@@ -1006,6 +1006,7 @@ static int apds9960_probe(struct i2c_client *client,
+ 
+ 	iio_device_attach_buffer(indio_dev, buffer);
+ 
++	indio_dev->dev.parent = &client->dev;
+ 	indio_dev->info = &apds9960_info;
+ 	indio_dev->name = APDS9960_DRV_NAME;
+ 	indio_dev->channels = apds9960_channels;
+diff --git a/drivers/iio/pressure/st_pressure_core.c b/drivers/iio/pressure/st_pressure_core.c
+index 172393ad34af..d3ca3207935d 100644
+--- a/drivers/iio/pressure/st_pressure_core.c
++++ b/drivers/iio/pressure/st_pressure_core.c
+@@ -28,15 +28,21 @@
+ #include <linux/iio/common/st_sensors.h>
+ #include "st_pressure.h"
+ 
++#define MCELSIUS_PER_CELSIUS			1000
++
++/* Default pressure sensitivity */
+ #define ST_PRESS_LSB_PER_MBAR			4096UL
+ #define ST_PRESS_KPASCAL_NANO_SCALE		(100000000UL / \
+ 						 ST_PRESS_LSB_PER_MBAR)
++
++/* Default temperature sensitivity */
+ #define ST_PRESS_LSB_PER_CELSIUS		480UL
+-#define ST_PRESS_CELSIUS_NANO_SCALE		(1000000000UL / \
+-						 ST_PRESS_LSB_PER_CELSIUS)
++#define ST_PRESS_MILLI_CELSIUS_OFFSET		42500UL
++
+ #define ST_PRESS_NUMBER_DATA_CHANNELS		1
+ 
+ /* FULLSCALE */
++#define ST_PRESS_FS_AVL_1100MB			1100
+ #define ST_PRESS_FS_AVL_1260MB			1260
+ 
+ #define ST_PRESS_1_OUT_XL_ADDR			0x28
+@@ -54,9 +60,6 @@
+ #define ST_PRESS_LPS331AP_PW_MASK		0x80
+ #define ST_PRESS_LPS331AP_FS_ADDR		0x23
+ #define ST_PRESS_LPS331AP_FS_MASK		0x30
+-#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL	0x00
+-#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN	ST_PRESS_KPASCAL_NANO_SCALE
+-#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN	ST_PRESS_CELSIUS_NANO_SCALE
+ #define ST_PRESS_LPS331AP_BDU_ADDR		0x20
+ #define ST_PRESS_LPS331AP_BDU_MASK		0x04
+ #define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR		0x22
+@@ -65,9 +68,14 @@
+ #define ST_PRESS_LPS331AP_IHL_IRQ_ADDR		0x22
+ #define ST_PRESS_LPS331AP_IHL_IRQ_MASK		0x80
+ #define ST_PRESS_LPS331AP_MULTIREAD_BIT		true
+-#define ST_PRESS_LPS331AP_TEMP_OFFSET		42500
+ 
+ /* CUSTOM VALUES FOR LPS001WP SENSOR */
++
++/* LPS001WP pressure resolution */
++#define ST_PRESS_LPS001WP_LSB_PER_MBAR		16UL
++/* LPS001WP temperature resolution */
++#define ST_PRESS_LPS001WP_LSB_PER_CELSIUS	64UL
++
+ #define ST_PRESS_LPS001WP_WAI_EXP		0xba
+ #define ST_PRESS_LPS001WP_ODR_ADDR		0x20
+ #define ST_PRESS_LPS001WP_ODR_MASK		0x30
+@@ -76,6 +84,8 @@
+ #define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL	0x03
+ #define ST_PRESS_LPS001WP_PW_ADDR		0x20
+ #define ST_PRESS_LPS001WP_PW_MASK		0x40
++#define ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN \
++	(100000000UL / ST_PRESS_LPS001WP_LSB_PER_MBAR)
+ #define ST_PRESS_LPS001WP_BDU_ADDR		0x20
+ #define ST_PRESS_LPS001WP_BDU_MASK		0x04
+ #define ST_PRESS_LPS001WP_MULTIREAD_BIT		true
+@@ -92,11 +102,6 @@
+ #define ST_PRESS_LPS25H_ODR_AVL_25HZ_VAL	0x04
+ #define ST_PRESS_LPS25H_PW_ADDR			0x20
+ #define ST_PRESS_LPS25H_PW_MASK			0x80
+-#define ST_PRESS_LPS25H_FS_ADDR			0x00
+-#define ST_PRESS_LPS25H_FS_MASK			0x00
+-#define ST_PRESS_LPS25H_FS_AVL_1260_VAL		0x00
+-#define ST_PRESS_LPS25H_FS_AVL_1260_GAIN	ST_PRESS_KPASCAL_NANO_SCALE
+-#define ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN	ST_PRESS_CELSIUS_NANO_SCALE
+ #define ST_PRESS_LPS25H_BDU_ADDR		0x20
+ #define ST_PRESS_LPS25H_BDU_MASK		0x04
+ #define ST_PRESS_LPS25H_DRDY_IRQ_ADDR		0x23
+@@ -105,7 +110,6 @@
+ #define ST_PRESS_LPS25H_IHL_IRQ_ADDR		0x22
+ #define ST_PRESS_LPS25H_IHL_IRQ_MASK		0x80
+ #define ST_PRESS_LPS25H_MULTIREAD_BIT		true
+-#define ST_PRESS_LPS25H_TEMP_OFFSET		42500
+ #define ST_PRESS_LPS25H_OUT_XL_ADDR		0x28
+ #define ST_TEMP_LPS25H_OUT_L_ADDR		0x2b
+ 
+@@ -157,7 +161,9 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
+ 			.storagebits = 16,
+ 			.endianness = IIO_LE,
+ 		},
+-		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
++		.info_mask_separate =
++			BIT(IIO_CHAN_INFO_RAW) |
++			BIT(IIO_CHAN_INFO_SCALE),
+ 		.modified = 0,
+ 	},
+ 	{
+@@ -173,7 +179,7 @@ static const struct iio_chan_spec st_press_lps001wp_channels[] = {
+ 		},
+ 		.info_mask_separate =
+ 			BIT(IIO_CHAN_INFO_RAW) |
+-			BIT(IIO_CHAN_INFO_OFFSET),
++			BIT(IIO_CHAN_INFO_SCALE),
+ 		.modified = 0,
+ 	},
+ 	IIO_CHAN_SOFT_TIMESTAMP(1)
+@@ -208,11 +214,14 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
+ 			.addr = ST_PRESS_LPS331AP_FS_ADDR,
+ 			.mask = ST_PRESS_LPS331AP_FS_MASK,
+ 			.fs_avl = {
++				/*
++				 * Pressure and temperature sensitivity values
++				 * as defined in table 3 of LPS331AP datasheet.
++				 */
+ 				[0] = {
+ 					.num = ST_PRESS_FS_AVL_1260MB,
+-					.value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
+-					.gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
+-					.gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
++					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
++					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
+ 				},
+ 			},
+ 		},
+@@ -254,7 +263,17 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
+ 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ 		},
+ 		.fs = {
+-			.addr = 0,
++			.fs_avl = {
++				/*
++				 * Pressure and temperature resolution values
++				 * as defined in table 3 of LPS001WP datasheet.
++				 */
++				[0] = {
++					.num = ST_PRESS_FS_AVL_1100MB,
++					.gain = ST_PRESS_LPS001WP_FS_AVL_PRESS_GAIN,
++					.gain2 = ST_PRESS_LPS001WP_LSB_PER_CELSIUS,
++				},
++			},
+ 		},
+ 		.bdu = {
+ 			.addr = ST_PRESS_LPS001WP_BDU_ADDR,
+@@ -291,14 +310,15 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
+ 			.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
+ 		},
+ 		.fs = {
+-			.addr = ST_PRESS_LPS25H_FS_ADDR,
+-			.mask = ST_PRESS_LPS25H_FS_MASK,
+ 			.fs_avl = {
++				/*
++				 * Pressure and temperature sensitivity values
++				 * as defined in table 3 of LPS25H datasheet.
++				 */
+ 				[0] = {
+ 					.num = ST_PRESS_FS_AVL_1260MB,
+-					.value = ST_PRESS_LPS25H_FS_AVL_1260_VAL,
+-					.gain = ST_PRESS_LPS25H_FS_AVL_1260_GAIN,
+-					.gain2 = ST_PRESS_LPS25H_FS_AVL_TEMP_GAIN,
++					.gain = ST_PRESS_KPASCAL_NANO_SCALE,
++					.gain2 = ST_PRESS_LSB_PER_CELSIUS,
+ 				},
+ 			},
+ 		},
+@@ -354,26 +374,26 @@ static int st_press_read_raw(struct iio_dev *indio_dev,
+ 
+ 		return IIO_VAL_INT;
+ 	case IIO_CHAN_INFO_SCALE:
+-		*val = 0;
+-
+ 		switch (ch->type) {
+ 		case IIO_PRESSURE:
++			*val = 0;
+ 			*val2 = press_data->current_fullscale->gain;
+-			break;
++			return IIO_VAL_INT_PLUS_NANO;
+ 		case IIO_TEMP:
++			*val = MCELSIUS_PER_CELSIUS;
+ 			*val2 = press_data->current_fullscale->gain2;
+-			break;
++			return IIO_VAL_FRACTIONAL;
+ 		default:
+ 			err = -EINVAL;
+ 			goto read_error;
+ 		}
+ 
+-		return IIO_VAL_INT_PLUS_NANO;
+ 	case IIO_CHAN_INFO_OFFSET:
+ 		switch (ch->type) {
+ 		case IIO_TEMP:
+-			*val = 425;
+-			*val2 = 10;
++			*val = ST_PRESS_MILLI_CELSIUS_OFFSET *
++			       press_data->current_fullscale->gain2;
++			*val2 = MCELSIUS_PER_CELSIUS;
+ 			break;
+ 		default:
+ 			err = -EINVAL;
+diff --git a/drivers/iio/proximity/as3935.c b/drivers/iio/proximity/as3935.c
+index f4d29d5dbd5f..e2f926cdcad2 100644
+--- a/drivers/iio/proximity/as3935.c
++++ b/drivers/iio/proximity/as3935.c
+@@ -64,6 +64,7 @@ struct as3935_state {
+ 	struct delayed_work work;
+ 
+ 	u32 tune_cap;
++	u8 buffer[16]; /* 8-bit data + 56-bit padding + 64-bit timestamp */
+ 	u8 buf[2] ____cacheline_aligned;
+ };
+ 
+@@ -72,7 +73,8 @@ static const struct iio_chan_spec as3935_channels[] = {
+ 		.type           = IIO_PROXIMITY,
+ 		.info_mask_separate =
+ 			BIT(IIO_CHAN_INFO_RAW) |
+-			BIT(IIO_CHAN_INFO_PROCESSED),
++			BIT(IIO_CHAN_INFO_PROCESSED) |
++			BIT(IIO_CHAN_INFO_SCALE),
+ 		.scan_index     = 0,
+ 		.scan_type = {
+ 			.sign           = 'u',
+@@ -181,7 +183,12 @@ static int as3935_read_raw(struct iio_dev *indio_dev,
+ 		/* storm out of range */
+ 		if (*val == AS3935_DATA_MASK)
+ 			return -EINVAL;
+-		*val *= 1000;
++
++		if (m == IIO_CHAN_INFO_PROCESSED)
++			*val *= 1000;
++		break;
++	case IIO_CHAN_INFO_SCALE:
++		*val = 1000;
+ 		break;
+ 	default:
+ 		return -EINVAL;
+@@ -206,10 +213,10 @@ static irqreturn_t as3935_trigger_handler(int irq, void *private)
+ 	ret = as3935_read(st, AS3935_DATA, &val);
+ 	if (ret)
+ 		goto err_read;
+-	val &= AS3935_DATA_MASK;
+-	val *= 1000;
+ 
+-	iio_push_to_buffers_with_timestamp(indio_dev, &val, pf->timestamp);
++	st->buffer[0] = val & AS3935_DATA_MASK;
++	iio_push_to_buffers_with_timestamp(indio_dev, &st->buffer,
++					   pf->timestamp);
+ err_read:
+ 	iio_trigger_notify_done(indio_dev->trig);
+ 
+diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
+index 1d92e091e22e..c99525512b34 100644
+--- a/drivers/infiniband/core/cm.c
++++ b/drivers/infiniband/core/cm.c
+@@ -3452,14 +3452,14 @@ static int cm_establish(struct ib_cm_id *cm_id)
+ 	work->cm_event.event = IB_CM_USER_ESTABLISHED;
+ 
+ 	/* Check if the device started its remove_one */
+-	spin_lock_irq(&cm.lock);
++	spin_lock_irqsave(&cm.lock, flags);
+ 	if (!cm_dev->going_down) {
+ 		queue_delayed_work(cm.wq, &work->work, 0);
+ 	} else {
+ 		kfree(work);
+ 		ret = -ENODEV;
+ 	}
+-	spin_unlock_irq(&cm.lock);
++	spin_unlock_irqrestore(&cm.lock, flags);
+ 
+ out:
+ 	return ret;
+diff --git a/drivers/infiniband/hw/mlx4/ah.c b/drivers/infiniband/hw/mlx4/ah.c
+index 105246fba2e7..5fc623362731 100644
+--- a/drivers/infiniband/hw/mlx4/ah.c
++++ b/drivers/infiniband/hw/mlx4/ah.c
+@@ -47,6 +47,7 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ 
+ 	ah->av.ib.port_pd = cpu_to_be32(to_mpd(pd)->pdn | (ah_attr->port_num << 24));
+ 	ah->av.ib.g_slid  = ah_attr->src_path_bits;
++	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
+ 	if (ah_attr->ah_flags & IB_AH_GRH) {
+ 		ah->av.ib.g_slid   |= 0x80;
+ 		ah->av.ib.gid_index = ah_attr->grh.sgid_index;
+@@ -64,7 +65,6 @@ static struct ib_ah *create_ib_ah(struct ib_pd *pd, struct ib_ah_attr *ah_attr,
+ 		       !(1 << ah->av.ib.stat_rate & dev->caps.stat_rate_support))
+ 			--ah->av.ib.stat_rate;
+ 	}
+-	ah->av.ib.sl_tclass_flowlabel = cpu_to_be32(ah_attr->sl << 28);
+ 
+ 	return &ah->ibah;
+ }
+diff --git a/drivers/infiniband/sw/rdmavt/qp.c b/drivers/infiniband/sw/rdmavt/qp.c
+index a9e3bcc522c4..a0ecf08b2b86 100644
+--- a/drivers/infiniband/sw/rdmavt/qp.c
++++ b/drivers/infiniband/sw/rdmavt/qp.c
+@@ -683,8 +683,10 @@ struct ib_qp *rvt_create_qp(struct ib_pd *ibpd,
+ 		 * initialization that is needed.
+ 		 */
+ 		priv = rdi->driver_f.qp_priv_alloc(rdi, qp, gfp);
+-		if (!priv)
++		if (IS_ERR(priv)) {
++			ret = priv;
+ 			goto bail_qp;
++		}
+ 		qp->priv = priv;
+ 		qp->timeout_jiffies =
+ 			usecs_to_jiffies((4096UL * (1UL << qp->timeout)) /
+diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
+index bf4959f4225b..94f1bf772ec9 100644
+--- a/drivers/iommu/amd_iommu_init.c
++++ b/drivers/iommu/amd_iommu_init.c
+@@ -1363,13 +1363,23 @@ static int __init amd_iommu_init_pci(void)
+ 			break;
+ 	}
+ 
++	/*
++	 * Order is important here to make sure any unity map requirements are
++	 * fulfilled. The unity mappings are created and written to the device
++	 * table during the amd_iommu_init_api() call.
++	 *
++	 * After that we call init_device_table_dma() to make sure any
++	 * uninitialized DTE will block DMA, and in the end we flush the caches
++	 * of all IOMMUs to make sure the changes to the device table are
++	 * active.
++	 */
++	ret = amd_iommu_init_api();
++
+ 	init_device_table_dma();
+ 
+ 	for_each_iommu(iommu)
+ 		iommu_flush_all_caches(iommu);
+ 
+-	ret = amd_iommu_init_api();
+-
+ 	if (!ret)
+ 		print_iommu_info();
+ 
+diff --git a/drivers/iommu/arm-smmu-v3.c b/drivers/iommu/arm-smmu-v3.c
+index 4ff73ff64e49..3e20208d6fdb 100644
+--- a/drivers/iommu/arm-smmu-v3.c
++++ b/drivers/iommu/arm-smmu-v3.c
+@@ -1942,6 +1942,7 @@ static struct iommu_ops arm_smmu_ops = {
+ 	.attach_dev		= arm_smmu_attach_dev,
+ 	.map			= arm_smmu_map,
+ 	.unmap			= arm_smmu_unmap,
++	.map_sg			= default_iommu_map_sg,
+ 	.iova_to_phys		= arm_smmu_iova_to_phys,
+ 	.add_device		= arm_smmu_add_device,
+ 	.remove_device		= arm_smmu_remove_device,
+diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
+index e1852e845d21..ae364e07840c 100644
+--- a/drivers/iommu/intel-iommu.c
++++ b/drivers/iommu/intel-iommu.c
+@@ -3169,11 +3169,6 @@ static int __init init_dmars(void)
+ 			}
+ 		}
+ 
+-		iommu_flush_write_buffer(iommu);
+-		iommu_set_root_entry(iommu);
+-		iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
+-		iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
+-
+ 		if (!ecap_pass_through(iommu->ecap))
+ 			hw_pass_through = 0;
+ #ifdef CONFIG_INTEL_IOMMU_SVM
+@@ -3182,6 +3177,18 @@ static int __init init_dmars(void)
+ #endif
+ 	}
+ 
++	/*
++	 * Now that qi is enabled on all iommus, set the root entry and flush
++	 * caches. This is required on some Intel X58 chipsets, otherwise the
++	 * flush_context function will loop forever and the boot hangs.
++	 */
++	for_each_active_iommu(iommu, drhd) {
++		iommu_flush_write_buffer(iommu);
++		iommu_set_root_entry(iommu);
++		iommu->flush.flush_context(iommu, 0, 0, 0, DMA_CCMD_GLOBAL_INVL);
++		iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
++	}
++
+ 	if (iommu_pass_through)
+ 		iommu_identity_mapping |= IDENTMAP_ALL;
+ 
+diff --git a/drivers/iommu/rockchip-iommu.c b/drivers/iommu/rockchip-iommu.c
+index 5710a06c3049..0ea8d9a24de0 100644
+--- a/drivers/iommu/rockchip-iommu.c
++++ b/drivers/iommu/rockchip-iommu.c
+@@ -815,7 +815,7 @@ static int rk_iommu_attach_device(struct iommu_domain *domain,
+ 	dte_addr = virt_to_phys(rk_domain->dt);
+ 	for (i = 0; i < iommu->num_mmu; i++) {
+ 		rk_iommu_write(iommu->bases[i], RK_MMU_DTE_ADDR, dte_addr);
+-		rk_iommu_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
++		rk_iommu_base_command(iommu->bases[i], RK_MMU_CMD_ZAP_CACHE);
+ 		rk_iommu_write(iommu->bases[i], RK_MMU_INT_MASK, RK_MMU_IRQ_MASK);
+ 	}
+ 
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 4dffccf532a2..40fb1209d512 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -734,6 +734,12 @@ static int gic_irq_domain_alloc(struct irq_domain *d, unsigned int virq,
+ 		/* verify that it doesn't conflict with an IPI irq */
+ 		if (test_bit(spec->hwirq, ipi_resrv))
+ 			return -EBUSY;
++
++		hwirq = GIC_SHARED_TO_HWIRQ(spec->hwirq);
++
++		return irq_domain_set_hwirq_and_chip(d, virq, hwirq,
++						     &gic_level_irq_controller,
++						     NULL);
+ 	} else {
+ 		base_hwirq = find_first_bit(ipi_resrv, gic_shared_intrs);
+ 		if (base_hwirq == gic_shared_intrs) {
+@@ -855,10 +861,14 @@ static int gic_dev_domain_alloc(struct irq_domain *d, unsigned int virq,
+ 						    &gic_level_irq_controller,
+ 						    NULL);
+ 		if (ret)
+-			return ret;
++			goto error;
+ 	}
+ 
+ 	return 0;
++
++error:
++	irq_domain_free_irqs_parent(d, virq, nr_irqs);
++	return ret;
+ }
+ 
+ void gic_dev_domain_free(struct irq_domain *d, unsigned int virq,
+diff --git a/drivers/media/usb/uvc/uvc_v4l2.c b/drivers/media/usb/uvc/uvc_v4l2.c
+index d7723ce772b3..12690c1ea8f8 100644
+--- a/drivers/media/usb/uvc/uvc_v4l2.c
++++ b/drivers/media/usb/uvc/uvc_v4l2.c
+@@ -1408,47 +1408,44 @@ static int uvc_v4l2_put_xu_query(const struct uvc_xu_control_query *kp,
+ static long uvc_v4l2_compat_ioctl32(struct file *file,
+ 		     unsigned int cmd, unsigned long arg)
+ {
++	struct uvc_fh *handle = file->private_data;
+ 	union {
+ 		struct uvc_xu_control_mapping xmap;
+ 		struct uvc_xu_control_query xqry;
+ 	} karg;
+ 	void __user *up = compat_ptr(arg);
+-	mm_segment_t old_fs;
+ 	long ret;
+ 
+ 	switch (cmd) {
+ 	case UVCIOC_CTRL_MAP32:
+-		cmd = UVCIOC_CTRL_MAP;
+ 		ret = uvc_v4l2_get_xu_mapping(&karg.xmap, up);
++		if (ret)
++			return ret;
++		ret = uvc_ioctl_ctrl_map(handle->chain, &karg.xmap);
++		if (ret)
++			return ret;
++		ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
++		if (ret)
++			return ret;
++
+ 		break;
+ 
+ 	case UVCIOC_CTRL_QUERY32:
+-		cmd = UVCIOC_CTRL_QUERY;
+ 		ret = uvc_v4l2_get_xu_query(&karg.xqry, up);
++		if (ret)
++			return ret;
++		ret = uvc_xu_ctrl_query(handle->chain, &karg.xqry);
++		if (ret)
++			return ret;
++		ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
++		if (ret)
++			return ret;
+ 		break;
+ 
+ 	default:
+ 		return -ENOIOCTLCMD;
+ 	}
+ 
+-	old_fs = get_fs();
+-	set_fs(KERNEL_DS);
+-	ret = video_ioctl2(file, cmd, (unsigned long)&karg);
+-	set_fs(old_fs);
+-
+-	if (ret < 0)
+-		return ret;
+-
+-	switch (cmd) {
+-	case UVCIOC_CTRL_MAP:
+-		ret = uvc_v4l2_put_xu_mapping(&karg.xmap, up);
+-		break;
+-
+-	case UVCIOC_CTRL_QUERY:
+-		ret = uvc_v4l2_put_xu_query(&karg.xqry, up);
+-		break;
+-	}
+-
+ 	return ret;
+ }
+ #endif
+diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c
+index 21825ddce4a3..859b4a1d11e4 100644
+--- a/drivers/memory/omap-gpmc.c
++++ b/drivers/memory/omap-gpmc.c
+@@ -394,7 +394,7 @@ static void gpmc_cs_bool_timings(int cs, const struct gpmc_bool_timings *p)
+ 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+ 			   GPMC_CONFIG4_OEEXTRADELAY, p->oe_extra_delay);
+ 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG4,
+-			   GPMC_CONFIG4_OEEXTRADELAY, p->we_extra_delay);
++			   GPMC_CONFIG4_WEEXTRADELAY, p->we_extra_delay);
+ 	gpmc_cs_modify_reg(cs, GPMC_CS_CONFIG6,
+ 			   GPMC_CONFIG6_CYCLE2CYCLESAMECSEN,
+ 			   p->cycle2cyclesamecsen);
+diff --git a/drivers/mtd/ubi/eba.c b/drivers/mtd/ubi/eba.c
+index 96fddb016bf1..4dd0391d2942 100644
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -575,6 +575,7 @@ static int recover_peb(struct ubi_device *ubi, int pnum, int vol_id, int lnum,
+ 	int err, idx = vol_id2idx(ubi, vol_id), new_pnum, data_size, tries = 0;
+ 	struct ubi_volume *vol = ubi->volumes[idx];
+ 	struct ubi_vid_hdr *vid_hdr;
++	uint32_t crc;
+ 
+ 	vid_hdr = ubi_zalloc_vid_hdr(ubi, GFP_NOFS);
+ 	if (!vid_hdr)
+@@ -599,14 +600,8 @@ retry:
+ 		goto out_put;
+ 	}
+ 
+-	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
+-	err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
+-	if (err) {
+-		up_read(&ubi->fm_eba_sem);
+-		goto write_error;
+-	}
++	ubi_assert(vid_hdr->vol_type == UBI_VID_DYNAMIC);
+ 
+-	data_size = offset + len;
+ 	mutex_lock(&ubi->buf_mutex);
+ 	memset(ubi->peb_buf + offset, 0xFF, len);
+ 
+@@ -621,6 +616,19 @@ retry:
+ 
+ 	memcpy(ubi->peb_buf + offset, buf, len);
+ 
++	data_size = offset + len;
++	crc = crc32(UBI_CRC32_INIT, ubi->peb_buf, data_size);
++	vid_hdr->sqnum = cpu_to_be64(ubi_next_sqnum(ubi));
++	vid_hdr->copy_flag = 1;
++	vid_hdr->data_size = cpu_to_be32(data_size);
++	vid_hdr->data_crc = cpu_to_be32(crc);
++	err = ubi_io_write_vid_hdr(ubi, new_pnum, vid_hdr);
++	if (err) {
++		mutex_unlock(&ubi->buf_mutex);
++		up_read(&ubi->fm_eba_sem);
++		goto write_error;
++	}
++
+ 	err = ubi_io_write_data(ubi, ubi->peb_buf, new_pnum, 0, data_size);
+ 	if (err) {
+ 		mutex_unlock(&ubi->buf_mutex);
+diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c
+index 9fcb4898fb68..c70e51567eed 100644
+--- a/drivers/net/geneve.c
++++ b/drivers/net/geneve.c
+@@ -1092,12 +1092,17 @@ static netdev_tx_t geneve_xmit(struct sk_buff *skb, struct net_device *dev)
+ 
+ static int __geneve_change_mtu(struct net_device *dev, int new_mtu, bool strict)
+ {
++	struct geneve_dev *geneve = netdev_priv(dev);
+ 	/* The max_mtu calculation does not take account of GENEVE
+ 	 * options, to avoid excluding potentially valid
+ 	 * configurations.
+ 	 */
+-	int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - sizeof(struct iphdr)
+-		- dev->hard_header_len;
++	int max_mtu = IP_MAX_MTU - GENEVE_BASE_HLEN - dev->hard_header_len;
++
++	if (geneve->remote.sa.sa_family == AF_INET6)
++		max_mtu -= sizeof(struct ipv6hdr);
++	else
++		max_mtu -= sizeof(struct iphdr);
+ 
+ 	if (new_mtu < 68)
+ 		return -EINVAL;
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 9e803bbcc0b6..8f3c55d03d5d 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -2564,6 +2564,7 @@ static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
+ 		u64_stats_update_begin(&secy_stats->syncp);
+ 		secy_stats->stats.OutPktsUntagged++;
+ 		u64_stats_update_end(&secy_stats->syncp);
++		skb->dev = macsec->real_dev;
+ 		len = skb->len;
+ 		ret = dev_queue_xmit(skb);
+ 		count_tx(dev, ret, len);
+diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c
+index 2fb31edab125..d4425c565839 100644
+--- a/drivers/net/usb/cdc_ncm.c
++++ b/drivers/net/usb/cdc_ncm.c
+@@ -852,6 +852,13 @@ int cdc_ncm_bind_common(struct usbnet *dev, struct usb_interface *intf, u8 data_
+ 	if (cdc_ncm_init(dev))
+ 		goto error2;
+ 
++	/* Some firmwares need a pause here or they will silently fail
++	 * to set up the interface properly.  This value was decided
++	 * empirically on a Sierra Wireless MC7455 running 02.08.02.00
++	 * firmware.
++	 */
++	usleep_range(10000, 20000);
++
+ 	/* configure data interface */
+ 	temp = usb_set_interface(dev->udev, iface_no, data_altsetting);
+ 	if (temp) {
+diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
+index e85e0737771c..06664baa43d9 100644
+--- a/drivers/net/wireless/mac80211_hwsim.c
++++ b/drivers/net/wireless/mac80211_hwsim.c
+@@ -2771,6 +2771,7 @@ static int hwsim_tx_info_frame_received_nl(struct sk_buff *skb_2,
+ 	if (!info->attrs[HWSIM_ATTR_ADDR_TRANSMITTER] ||
+ 	    !info->attrs[HWSIM_ATTR_FLAGS] ||
+ 	    !info->attrs[HWSIM_ATTR_COOKIE] ||
++	    !info->attrs[HWSIM_ATTR_SIGNAL] ||
+ 	    !info->attrs[HWSIM_ATTR_TX_INFO])
+ 		goto out;
+ 
+diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c b/drivers/net/wireless/realtek/rtlwifi/core.c
+index 0f48048b8654..3a0faa8fe9d4 100644
+--- a/drivers/net/wireless/realtek/rtlwifi/core.c
++++ b/drivers/net/wireless/realtek/rtlwifi/core.c
+@@ -54,7 +54,7 @@ EXPORT_SYMBOL(channel5g_80m);
+ void rtl_addr_delay(u32 addr)
+ {
+ 	if (addr == 0xfe)
+-		msleep(50);
++		mdelay(50);
+ 	else if (addr == 0xfd)
+ 		msleep(5);
+ 	else if (addr == 0xfc)
+@@ -75,7 +75,7 @@ void rtl_rfreg_delay(struct ieee80211_hw *hw, enum radio_path rfpath, u32 addr,
+ 		rtl_addr_delay(addr);
+ 	} else {
+ 		rtl_set_rfreg(hw, rfpath, addr, mask, data);
+-		usleep_range(1, 2);
++		udelay(1);
+ 	}
+ }
+ EXPORT_SYMBOL(rtl_rfreg_delay);
+@@ -86,7 +86,7 @@ void rtl_bb_delay(struct ieee80211_hw *hw, u32 addr, u32 data)
+ 		rtl_addr_delay(addr);
+ 	} else {
+ 		rtl_set_bbreg(hw, addr, MASKDWORD, data);
+-		usleep_range(1, 2);
++		udelay(1);
+ 	}
+ }
+ EXPORT_SYMBOL(rtl_bb_delay);
+diff --git a/drivers/of/irq.c b/drivers/of/irq.c
+index e7bfc175b8e1..6ec743faabe8 100644
+--- a/drivers/of/irq.c
++++ b/drivers/of/irq.c
+@@ -386,13 +386,13 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
+ EXPORT_SYMBOL_GPL(of_irq_to_resource);
+ 
+ /**
+- * of_irq_get - Decode a node's IRQ and return it as a Linux irq number
++ * of_irq_get - Decode a node's IRQ and return it as a Linux IRQ number
+  * @dev: pointer to device tree node
+- * @index: zero-based index of the irq
+- *
+- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
+- * is not yet created.
++ * @index: zero-based index of the IRQ
+  *
++ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
++ * of any other failure.
+  */
+ int of_irq_get(struct device_node *dev, int index)
+ {
+@@ -413,12 +413,13 @@ int of_irq_get(struct device_node *dev, int index)
+ EXPORT_SYMBOL_GPL(of_irq_get);
+ 
+ /**
+- * of_irq_get_byname - Decode a node's IRQ and return it as a Linux irq number
++ * of_irq_get_byname - Decode a node's IRQ and return it as a Linux IRQ number
+  * @dev: pointer to device tree node
+- * @name: irq name
++ * @name: IRQ name
+  *
+- * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
+- * is not yet created, or error code in case of any other failure.
++ * Returns Linux IRQ number on success, or 0 on the IRQ mapping failure, or
++ * -EPROBE_DEFER if the IRQ domain is not yet created, or error code in case
++ * of any other failure.
+  */
+ int of_irq_get_byname(struct device_node *dev, const char *name)
+ {
+diff --git a/drivers/pci/vc.c b/drivers/pci/vc.c
+index dfbab61a1b47..1fa3a3219c45 100644
+--- a/drivers/pci/vc.c
++++ b/drivers/pci/vc.c
+@@ -221,9 +221,9 @@ static int pci_vc_do_save_buffer(struct pci_dev *dev, int pos,
+ 		else
+ 			pci_write_config_word(dev, pos + PCI_VC_PORT_CTRL,
+ 					      *(u16 *)buf);
+-		buf += 2;
++		buf += 4;
+ 	}
+-	len += 2;
++	len += 4;
+ 
+ 	/*
+ 	 * If we have any Low Priority VCs and a VC Arbitration Table Offset
+diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
+index 56a17ec5b5ef..6c7fe4778793 100644
+--- a/drivers/regulator/qcom_smd-regulator.c
++++ b/drivers/regulator/qcom_smd-regulator.c
+@@ -140,6 +140,18 @@ static const struct regulator_ops rpm_smps_ldo_ops = {
+ 	.enable = rpm_reg_enable,
+ 	.disable = rpm_reg_disable,
+ 	.is_enabled = rpm_reg_is_enabled,
++	.list_voltage = regulator_list_voltage_linear_range,
++
++	.get_voltage = rpm_reg_get_voltage,
++	.set_voltage = rpm_reg_set_voltage,
++
++	.set_load = rpm_reg_set_load,
++};
++
++static const struct regulator_ops rpm_smps_ldo_ops_fixed = {
++	.enable = rpm_reg_enable,
++	.disable = rpm_reg_disable,
++	.is_enabled = rpm_reg_is_enabled,
+ 
+ 	.get_voltage = rpm_reg_get_voltage,
+ 	.set_voltage = rpm_reg_set_voltage,
+@@ -247,7 +259,7 @@ static const struct regulator_desc pm8941_nldo = {
+ static const struct regulator_desc pm8941_lnldo = {
+ 	.fixed_uV = 1740000,
+ 	.n_voltages = 1,
+-	.ops = &rpm_smps_ldo_ops,
++	.ops = &rpm_smps_ldo_ops_fixed,
+ };
+ 
+ static const struct regulator_desc pm8941_switch = {
+diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
+index d4c285688ce9..3ddc85e6efd6 100644
+--- a/drivers/scsi/53c700.c
++++ b/drivers/scsi/53c700.c
+@@ -1122,7 +1122,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp,
+ 		} else {
+ 			struct scsi_cmnd *SCp;
+ 
+-			SCp = scsi_host_find_tag(SDp->host, SCSI_NO_TAG);
++			SCp = SDp->current_cmnd;
+ 			if(unlikely(SCp == NULL)) {
+ 				sdev_printk(KERN_ERR, SDp,
+ 					"no saved request for untagged cmd\n");
+@@ -1826,7 +1826,7 @@ NCR_700_queuecommand_lck(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)
+ 		       slot->tag, slot);
+ 	} else {
+ 		slot->tag = SCSI_NO_TAG;
+-		/* must populate current_cmnd for scsi_host_find_tag to work */
++		/* save current command for reselection */
+ 		SCp->device->current_cmnd = SCp;
+ 	}
+ 	/* sanity check: some of the commands generated by the mid-layer
+diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
+index 984ddcb4786d..1b9c049bd5c5 100644
+--- a/drivers/scsi/scsi_error.c
++++ b/drivers/scsi/scsi_error.c
+@@ -1127,7 +1127,6 @@ static int scsi_eh_action(struct scsi_cmnd *scmd, int rtn)
+  */
+ void scsi_eh_finish_cmd(struct scsi_cmnd *scmd, struct list_head *done_q)
+ {
+-	scmd->device->host->host_failed--;
+ 	scmd->eh_eflags = 0;
+ 	list_move_tail(&scmd->eh_entry, done_q);
+ }
+@@ -2226,6 +2225,9 @@ int scsi_error_handler(void *data)
+ 		else
+ 			scsi_unjam_host(shost);
+ 
++		/* All scmds have been handled */
++		shost->host_failed = 0;
++
+ 		/*
+ 		 * Note - if the above fails completely, the action is to take
+ 		 * individual devices offline and flush the queue of any
+diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+index f52b74cf8d1e..41c3a2c4f112 100644
+--- a/drivers/scsi/sd.c
++++ b/drivers/scsi/sd.c
+@@ -2862,10 +2862,10 @@ static int sd_revalidate_disk(struct gendisk *disk)
+ 	if (sdkp->opt_xfer_blocks &&
+ 	    sdkp->opt_xfer_blocks <= dev_max &&
+ 	    sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS &&
+-	    sdkp->opt_xfer_blocks * sdp->sector_size >= PAGE_SIZE)
+-		rw_max = q->limits.io_opt =
+-			sdkp->opt_xfer_blocks * sdp->sector_size;
+-	else
++	    logical_to_bytes(sdp, sdkp->opt_xfer_blocks) >= PAGE_SIZE) {
++		q->limits.io_opt = logical_to_bytes(sdp, sdkp->opt_xfer_blocks);
++		rw_max = logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
++	} else
+ 		rw_max = BLK_DEF_MAX_SECTORS;
+ 
+ 	/* Combine with controller limits */
+diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
+index 654630bb7d0e..765a6f1ac1b7 100644
+--- a/drivers/scsi/sd.h
++++ b/drivers/scsi/sd.h
+@@ -151,6 +151,11 @@ static inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blo
+ 	return blocks << (ilog2(sdev->sector_size) - 9);
+ }
+ 
++static inline unsigned int logical_to_bytes(struct scsi_device *sdev, sector_t blocks)
++{
++	return blocks * sdev->sector_size;
++}
++
+ /*
+  * A DIF-capable target device can be formatted with different
+  * protection schemes.  Currently 0 through 3 are defined:
+diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c
+index a8f533af9eca..ec12181822e6 100644
+--- a/drivers/staging/iio/accel/sca3000_core.c
++++ b/drivers/staging/iio/accel/sca3000_core.c
+@@ -594,7 +594,7 @@ static ssize_t sca3000_read_frequency(struct device *dev,
+ 		goto error_ret_mut;
+ 	ret = sca3000_read_ctrl_reg(st, SCA3000_REG_CTRL_SEL_OUT_CTRL);
+ 	mutex_unlock(&st->lock);
+-	if (ret)
++	if (ret < 0)
+ 		goto error_ret;
+ 	val = ret;
+ 	if (base_freq > 0)
+diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
+index 6ceac4f2d4b2..5b4b47ed948b 100644
+--- a/drivers/thermal/cpu_cooling.c
++++ b/drivers/thermal/cpu_cooling.c
+@@ -857,14 +857,6 @@ __cpufreq_cooling_register(struct device_node *np,
+ 		goto free_power_table;
+ 	}
+ 
+-	snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
+-		 cpufreq_dev->id);
+-
+-	cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
+-						      &cpufreq_cooling_ops);
+-	if (IS_ERR(cool_dev))
+-		goto remove_idr;
+-
+ 	/* Fill freq-table in descending order of frequencies */
+ 	for (i = 0, freq = -1; i <= cpufreq_dev->max_level; i++) {
+ 		freq = find_next_max(table, freq);
+@@ -877,6 +869,14 @@ __cpufreq_cooling_register(struct device_node *np,
+ 			pr_debug("%s: freq:%u KHz\n", __func__, freq);
+ 	}
+ 
++	snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
++		 cpufreq_dev->id);
++
++	cool_dev = thermal_of_cooling_device_register(np, dev_name, cpufreq_dev,
++						      &cpufreq_cooling_ops);
++	if (IS_ERR(cool_dev))
++		goto remove_idr;
++
+ 	cpufreq_dev->clipped_freq = cpufreq_dev->freq_table[0];
+ 	cpufreq_dev->cool_dev = cool_dev;
+ 
+diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
+index f973bfce5d08..1e93a37e27f0 100644
+--- a/drivers/tty/vt/keyboard.c
++++ b/drivers/tty/vt/keyboard.c
+@@ -366,34 +366,22 @@ static void to_utf8(struct vc_data *vc, uint c)
+ 
+ static void do_compute_shiftstate(void)
+ {
+-	unsigned int i, j, k, sym, val;
++	unsigned int k, sym, val;
+ 
+ 	shift_state = 0;
+ 	memset(shift_down, 0, sizeof(shift_down));
+ 
+-	for (i = 0; i < ARRAY_SIZE(key_down); i++) {
+-
+-		if (!key_down[i])
++	for_each_set_bit(k, key_down, min(NR_KEYS, KEY_CNT)) {
++		sym = U(key_maps[0][k]);
++		if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+ 			continue;
+ 
+-		k = i * BITS_PER_LONG;
+-
+-		for (j = 0; j < BITS_PER_LONG; j++, k++) {
+-
+-			if (!test_bit(k, key_down))
+-				continue;
++		val = KVAL(sym);
++		if (val == KVAL(K_CAPSSHIFT))
++			val = KVAL(K_SHIFT);
+ 
+-			sym = U(key_maps[0][k]);
+-			if (KTYP(sym) != KT_SHIFT && KTYP(sym) != KT_SLOCK)
+-				continue;
+-
+-			val = KVAL(sym);
+-			if (val == KVAL(K_CAPSSHIFT))
+-				val = KVAL(K_SHIFT);
+-
+-			shift_down[val]++;
+-			shift_state |= (1 << val);
+-		}
++		shift_down[val]++;
++		shift_state |= BIT(val);
+ 	}
+ }
+ 
+diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
+index bd523adb9643..e9e29ded3f30 100644
+--- a/drivers/tty/vt/vt.c
++++ b/drivers/tty/vt/vt.c
+@@ -750,6 +750,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
+ 	vc->vc_complement_mask = 0;
+ 	vc->vc_can_do_color = 0;
+ 	vc->vc_panic_force_write = false;
++	vc->vc_cur_blink_ms = DEFAULT_CURSOR_BLINK_MS;
+ 	vc->vc_sw->con_init(vc, init);
+ 	if (!vc->vc_complement_mask)
+ 		vc->vc_complement_mask = vc->vc_can_do_color ? 0x7700 : 0x0800;
+diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c
+index 504708f59b93..6c6040c22c7a 100644
+--- a/drivers/usb/common/usb-otg-fsm.c
++++ b/drivers/usb/common/usb-otg-fsm.c
+@@ -21,6 +21,7 @@
+  * 675 Mass Ave, Cambridge, MA 02139, USA.
+  */
+ 
++#include <linux/module.h>
+ #include <linux/kernel.h>
+ #include <linux/types.h>
+ #include <linux/mutex.h>
+@@ -452,3 +453,4 @@ int otg_statemachine(struct otg_fsm *fsm)
+ 	return state_changed;
+ }
+ EXPORT_SYMBOL_GPL(otg_statemachine);
++MODULE_LICENSE("GPL");
+diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
+index 980fc5774151..2d107d0f61b0 100644
+--- a/drivers/usb/core/hcd.c
++++ b/drivers/usb/core/hcd.c
+@@ -2597,26 +2597,23 @@ EXPORT_SYMBOL_GPL(usb_create_hcd);
+  * Don't deallocate the bandwidth_mutex until the last shared usb_hcd is
+  * deallocated.
+  *
+- * Make sure to only deallocate the bandwidth_mutex when the primary HCD is
+- * freed.  When hcd_release() is called for either hcd in a peer set
+- * invalidate the peer's ->shared_hcd and ->primary_hcd pointers to
+- * block new peering attempts
++ * Make sure to deallocate the bandwidth_mutex only when the last HCD is
++ * freed.  When hcd_release() is called for either hcd in a peer set,
++ * invalidate the peer's ->shared_hcd and ->primary_hcd pointers.
+  */
+ static void hcd_release(struct kref *kref)
+ {
+ 	struct usb_hcd *hcd = container_of (kref, struct usb_hcd, kref);
+ 
+ 	mutex_lock(&usb_port_peer_mutex);
+-	if (usb_hcd_is_primary_hcd(hcd)) {
+-		kfree(hcd->address0_mutex);
+-		kfree(hcd->bandwidth_mutex);
+-	}
+ 	if (hcd->shared_hcd) {
+ 		struct usb_hcd *peer = hcd->shared_hcd;
+ 
+ 		peer->shared_hcd = NULL;
+-		if (peer->primary_hcd == hcd)
+-			peer->primary_hcd = NULL;
++		peer->primary_hcd = NULL;
++	} else {
++		kfree(hcd->address0_mutex);
++		kfree(hcd->bandwidth_mutex);
+ 	}
+ 	mutex_unlock(&usb_port_peer_mutex);
+ 	kfree(hcd);
+diff --git a/drivers/usb/dwc2/core.h b/drivers/usb/dwc2/core.h
+index 3c58d633ce80..dec0b21fc626 100644
+--- a/drivers/usb/dwc2/core.h
++++ b/drivers/usb/dwc2/core.h
+@@ -64,6 +64,17 @@
+ 	DWC2_TRACE_SCHEDULER_VB(pr_fmt("%s: SCH: " fmt),		\
+ 				dev_name(hsotg->dev), ##__VA_ARGS__)
+ 
++#ifdef CONFIG_MIPS
++/*
++ * There are some MIPS machines that can run in either big-endian
++ * or little-endian mode and that use the dwc2 register without
++ * a byteswap in both ways.
++ * Unlike other architectures, MIPS apparently does not require a
++ * barrier before the __raw_writel() to synchronize with DMA but does
++ * require the barrier after the __raw_writel() to serialize a set of
++ * writes. This set of operations was added specifically for MIPS and
++ * should only be used there.
++ */
+ static inline u32 dwc2_readl(const void __iomem *addr)
+ {
+ 	u32 value = __raw_readl(addr);
+@@ -90,6 +101,22 @@ static inline void dwc2_writel(u32 value, void __iomem *addr)
+ 	pr_info("INFO:: wrote %08x to %p\n", value, addr);
+ #endif
+ }
++#else
++/* Normal architectures just use readl/write */
++static inline u32 dwc2_readl(const void __iomem *addr)
++{
++	return readl(addr);
++}
++
++static inline void dwc2_writel(u32 value, void __iomem *addr)
++{
++	writel(value, addr);
++
++#ifdef DWC2_LOG_WRITES
++	pr_info("info:: wrote %08x to %p\n", value, addr);
++#endif
++}
++#endif
+ 
+ /* Maximum number of Endpoints/HostChannels */
+ #define MAX_EPS_CHANNELS	16
+diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
+index 7b6d74f0c72f..476c0e3a7150 100644
+--- a/drivers/virtio/virtio_balloon.c
++++ b/drivers/virtio/virtio_balloon.c
+@@ -75,7 +75,7 @@ struct virtio_balloon {
+ 
+ 	/* The array of pfns we tell the Host about. */
+ 	unsigned int num_pfns;
+-	u32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
++	__virtio32 pfns[VIRTIO_BALLOON_ARRAY_PFNS_MAX];
+ 
+ 	/* Memory statistics */
+ 	struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
+@@ -127,14 +127,16 @@ static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
+ 
+ }
+ 
+-static void set_page_pfns(u32 pfns[], struct page *page)
++static void set_page_pfns(struct virtio_balloon *vb,
++			  __virtio32 pfns[], struct page *page)
+ {
+ 	unsigned int i;
+ 
+ 	/* Set balloon pfns pointing at this page.
+ 	 * Note that the first pfn points at start of the page. */
+ 	for (i = 0; i < VIRTIO_BALLOON_PAGES_PER_PAGE; i++)
+-		pfns[i] = page_to_balloon_pfn(page) + i;
++		pfns[i] = cpu_to_virtio32(vb->vdev,
++					  page_to_balloon_pfn(page) + i);
+ }
+ 
+ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
+@@ -158,7 +160,7 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
+ 			msleep(200);
+ 			break;
+ 		}
+-		set_page_pfns(vb->pfns + vb->num_pfns, page);
++		set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
+ 		vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE;
+ 		if (!virtio_has_feature(vb->vdev,
+ 					VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
+@@ -177,10 +179,12 @@ static unsigned fill_balloon(struct virtio_balloon *vb, size_t num)
+ static void release_pages_balloon(struct virtio_balloon *vb)
+ {
+ 	unsigned int i;
++	struct page *page;
+ 
+ 	/* Find pfns pointing at start of each page, get pages and free them. */
+ 	for (i = 0; i < vb->num_pfns; i += VIRTIO_BALLOON_PAGES_PER_PAGE) {
+-		struct page *page = balloon_pfn_to_page(vb->pfns[i]);
++		page = balloon_pfn_to_page(virtio32_to_cpu(vb->vdev,
++							   vb->pfns[i]));
+ 		if (!virtio_has_feature(vb->vdev,
+ 					VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
+ 			adjust_managed_page_count(page, 1);
+@@ -203,7 +207,7 @@ static unsigned leak_balloon(struct virtio_balloon *vb, size_t num)
+ 		page = balloon_page_dequeue(vb_dev_info);
+ 		if (!page)
+ 			break;
+-		set_page_pfns(vb->pfns + vb->num_pfns, page);
++		set_page_pfns(vb, vb->pfns + vb->num_pfns, page);
+ 		vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
+ 	}
+ 
+@@ -471,13 +475,13 @@ static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
+ 	__count_vm_event(BALLOON_MIGRATE);
+ 	spin_unlock_irqrestore(&vb_dev_info->pages_lock, flags);
+ 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+-	set_page_pfns(vb->pfns, newpage);
++	set_page_pfns(vb, vb->pfns, newpage);
+ 	tell_host(vb, vb->inflate_vq);
+ 
+ 	/* balloon's page migration 2nd step -- deflate "page" */
+ 	balloon_page_delete(page);
+ 	vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE;
+-	set_page_pfns(vb->pfns, page);
++	set_page_pfns(vb, vb->pfns, page);
+ 	tell_host(vb, vb->deflate_vq);
+ 
+ 	mutex_unlock(&vb->balloon_lock);
+diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
+index d46839f51e73..e4db19e88ab1 100644
+--- a/drivers/xen/balloon.c
++++ b/drivers/xen/balloon.c
+@@ -151,8 +151,6 @@ static DECLARE_WAIT_QUEUE_HEAD(balloon_wq);
+ static void balloon_process(struct work_struct *work);
+ static DECLARE_DELAYED_WORK(balloon_worker, balloon_process);
+ 
+-static void release_memory_resource(struct resource *resource);
+-
+ /* When ballooning out (allocating memory to return to Xen) we don't really
+    want the kernel to try too hard since that can trigger the oom killer. */
+ #define GFP_BALLOON \
+@@ -248,6 +246,19 @@ static enum bp_state update_schedule(enum bp_state state)
+ }
+ 
+ #ifdef CONFIG_XEN_BALLOON_MEMORY_HOTPLUG
++static void release_memory_resource(struct resource *resource)
++{
++	if (!resource)
++		return;
++
++	/*
++	 * No need to reset region to identity mapped since we now
++	 * know that no I/O can be in this region
++	 */
++	release_resource(resource);
++	kfree(resource);
++}
++
+ static struct resource *additional_memory_resource(phys_addr_t size)
+ {
+ 	struct resource *res;
+@@ -286,19 +297,6 @@ static struct resource *additional_memory_resource(phys_addr_t size)
+ 	return res;
+ }
+ 
+-static void release_memory_resource(struct resource *resource)
+-{
+-	if (!resource)
+-		return;
+-
+-	/*
+-	 * No need to reset region to identity mapped since we now
+-	 * know that no I/O can be in this region
+-	 */
+-	release_resource(resource);
+-	kfree(resource);
+-}
+-
+ static enum bp_state reserve_additional_memory(void)
+ {
+ 	long credit;
+diff --git a/drivers/xen/xen-acpi-processor.c b/drivers/xen/xen-acpi-processor.c
+index 076970a54f89..4ce10bcca18b 100644
+--- a/drivers/xen/xen-acpi-processor.c
++++ b/drivers/xen/xen-acpi-processor.c
+@@ -423,36 +423,7 @@ upload:
+ 
+ 	return 0;
+ }
+-static int __init check_prereq(void)
+-{
+-	struct cpuinfo_x86 *c = &cpu_data(0);
+-
+-	if (!xen_initial_domain())
+-		return -ENODEV;
+-
+-	if (!acpi_gbl_FADT.smi_command)
+-		return -ENODEV;
+-
+-	if (c->x86_vendor == X86_VENDOR_INTEL) {
+-		if (!cpu_has(c, X86_FEATURE_EST))
+-			return -ENODEV;
+ 
+-		return 0;
+-	}
+-	if (c->x86_vendor == X86_VENDOR_AMD) {
+-		/* Copied from powernow-k8.h, can't include ../cpufreq/powernow
+-		 * as we get compile warnings for the static functions.
+-		 */
+-#define CPUID_FREQ_VOLT_CAPABILITIES    0x80000007
+-#define USE_HW_PSTATE                   0x00000080
+-		u32 eax, ebx, ecx, edx;
+-		cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
+-		if ((edx & USE_HW_PSTATE) != USE_HW_PSTATE)
+-			return -ENODEV;
+-		return 0;
+-	}
+-	return -ENODEV;
+-}
+ /* acpi_perf_data is a pointer to percpu data. */
+ static struct acpi_processor_performance __percpu *acpi_perf_data;
+ 
+@@ -509,10 +480,10 @@ struct notifier_block xen_acpi_processor_resume_nb = {
+ static int __init xen_acpi_processor_init(void)
+ {
+ 	unsigned int i;
+-	int rc = check_prereq();
++	int rc;
+ 
+-	if (rc)
+-		return rc;
++	if (!xen_initial_domain())
++		return -ENODEV;
+ 
+ 	nr_acpi_bits = get_max_acpi_id() + 1;
+ 	acpi_ids_done = kcalloc(BITS_TO_LONGS(nr_acpi_bits), sizeof(unsigned long), GFP_KERNEL);
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
+index ec7928a27aaa..234707cc419c 100644
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -1552,6 +1552,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans,
+ 		       trans->transid, root->fs_info->generation);
+ 
+ 	if (!should_cow_block(trans, root, buf)) {
++		trans->dirty = true;
+ 		*cow_ret = buf;
+ 		return 0;
+ 	}
+@@ -2773,8 +2774,10 @@ again:
+ 			 * then we don't want to set the path blocking,
+ 			 * so we test it here
+ 			 */
+-			if (!should_cow_block(trans, root, b))
++			if (!should_cow_block(trans, root, b)) {
++				trans->dirty = true;
+ 				goto cow_done;
++			}
+ 
+ 			/*
+ 			 * must have write locks on this node and the
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 84e060eb0de8..78f1b57d0b46 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -7929,7 +7929,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root,
+ 		set_extent_dirty(&trans->transaction->dirty_pages, buf->start,
+ 			 buf->start + buf->len - 1, GFP_NOFS);
+ 	}
+-	trans->blocks_used++;
++	trans->dirty = true;
+ 	/* this returns a buffer locked for blocking */
+ 	return buf;
+ }
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index 00b8f37cc306..d7c138f42bdf 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -239,7 +239,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans,
+ 	trans->aborted = errno;
+ 	/* Nothing used. The other threads that have joined this
+ 	 * transaction may be able to continue. */
+-	if (!trans->blocks_used && list_empty(&trans->new_bgs)) {
++	if (!trans->dirty && list_empty(&trans->new_bgs)) {
+ 		const char *errstr;
+ 
+ 		errstr = btrfs_decode_error(errno);
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index 72be51f7ca2f..c0b501a5a353 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -110,7 +110,6 @@ struct btrfs_trans_handle {
+ 	u64 chunk_bytes_reserved;
+ 	unsigned long use_count;
+ 	unsigned long blocks_reserved;
+-	unsigned long blocks_used;
+ 	unsigned long delayed_ref_updates;
+ 	struct btrfs_transaction *transaction;
+ 	struct btrfs_block_rsv *block_rsv;
+@@ -121,6 +120,7 @@ struct btrfs_trans_handle {
+ 	bool can_flush_pending_bgs;
+ 	bool reloc_reserved;
+ 	bool sync;
++	bool dirty;
+ 	unsigned int type;
+ 	/*
+ 	 * this root is only needed to validate that the root passed to
+diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c
+index 5a53ac6b1e02..02b071bf3732 100644
+--- a/fs/cifs/cifs_unicode.c
++++ b/fs/cifs/cifs_unicode.c
+@@ -101,6 +101,12 @@ convert_sfm_char(const __u16 src_char, char *target)
+ 	case SFM_SLASH:
+ 		*target = '\\';
+ 		break;
++	case SFM_SPACE:
++		*target = ' ';
++		break;
++	case SFM_PERIOD:
++		*target = '.';
++		break;
+ 	default:
+ 		return false;
+ 	}
+@@ -404,7 +410,7 @@ static __le16 convert_to_sfu_char(char src_char)
+ 	return dest_char;
+ }
+ 
+-static __le16 convert_to_sfm_char(char src_char)
++static __le16 convert_to_sfm_char(char src_char, bool end_of_string)
+ {
+ 	__le16 dest_char;
+ 
+@@ -427,6 +433,18 @@ static __le16 convert_to_sfm_char(char src_char)
+ 	case '|':
+ 		dest_char = cpu_to_le16(SFM_PIPE);
+ 		break;
++	case '.':
++		if (end_of_string)
++			dest_char = cpu_to_le16(SFM_PERIOD);
++		else
++			dest_char = 0;
++		break;
++	case ' ':
++		if (end_of_string)
++			dest_char = cpu_to_le16(SFM_SPACE);
++		else
++			dest_char = 0;
++		break;
+ 	default:
+ 		dest_char = 0;
+ 	}
+@@ -469,9 +487,16 @@ cifsConvertToUTF16(__le16 *target, const char *source, int srclen,
+ 		/* see if we must remap this char */
+ 		if (map_chars == SFU_MAP_UNI_RSVD)
+ 			dst_char = convert_to_sfu_char(src_char);
+-		else if (map_chars == SFM_MAP_UNI_RSVD)
+-			dst_char = convert_to_sfm_char(src_char);
+-		else
++		else if (map_chars == SFM_MAP_UNI_RSVD) {
++			bool end_of_string;
++
++			if (i == srclen - 1)
++				end_of_string = true;
++			else
++				end_of_string = false;
++
++			dst_char = convert_to_sfm_char(src_char, end_of_string);
++		} else
+ 			dst_char = 0;
+ 		/*
+ 		 * FIXME: We can not handle remapping backslash (UNI_SLASH)
+diff --git a/fs/cifs/cifs_unicode.h b/fs/cifs/cifs_unicode.h
+index bdc52cb9a676..479bc0a941f3 100644
+--- a/fs/cifs/cifs_unicode.h
++++ b/fs/cifs/cifs_unicode.h
+@@ -64,6 +64,8 @@
+ #define SFM_LESSTHAN    ((__u16) 0xF023)
+ #define SFM_PIPE        ((__u16) 0xF027)
+ #define SFM_SLASH       ((__u16) 0xF026)
++#define SFM_PERIOD	((__u16) 0xF028)
++#define SFM_SPACE	((__u16) 0xF029)
+ 
+ /*
+  * Mapping mechanism to use when one of the seven reserved characters is
+diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
+index 6f62ac821a84..34cbc582e8d7 100644
+--- a/fs/cifs/connect.c
++++ b/fs/cifs/connect.c
+@@ -428,7 +428,9 @@ cifs_echo_request(struct work_struct *work)
+ 	 * server->ops->need_neg() == true. Also, no need to ping if
+ 	 * we got a response recently.
+ 	 */
+-	if (!server->ops->need_neg || server->ops->need_neg(server) ||
++
++	if (server->tcpStatus == CifsNeedReconnect ||
++	    server->tcpStatus == CifsExiting || server->tcpStatus == CifsNew ||
+ 	    (server->ops->can_echo && !server->ops->can_echo(server)) ||
+ 	    time_before(jiffies, server->lstrp + echo_interval - HZ))
+ 		goto requeue_echo;
+diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
+index 848249fa120f..3079b38f0afb 100644
+--- a/fs/cifs/ntlmssp.h
++++ b/fs/cifs/ntlmssp.h
+@@ -133,6 +133,6 @@ typedef struct _AUTHENTICATE_MESSAGE {
+ 
+ int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len, struct cifs_ses *ses);
+ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, struct cifs_ses *ses);
+-int build_ntlmssp_auth_blob(unsigned char *pbuffer, u16 *buflen,
++int build_ntlmssp_auth_blob(unsigned char **pbuffer, u16 *buflen,
+ 			struct cifs_ses *ses,
+ 			const struct nls_table *nls_cp);
+diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
+index af0ec2d5ad0e..e88ffe1da045 100644
+--- a/fs/cifs/sess.c
++++ b/fs/cifs/sess.c
+@@ -364,19 +364,43 @@ void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
+ 	sec_blob->DomainName.MaximumLength = 0;
+ }
+ 
+-/* We do not malloc the blob, it is passed in pbuffer, because its
+-   maximum possible size is fixed and small, making this approach cleaner.
+-   This function returns the length of the data in the blob */
+-int build_ntlmssp_auth_blob(unsigned char *pbuffer,
++static int size_of_ntlmssp_blob(struct cifs_ses *ses)
++{
++	int sz = sizeof(AUTHENTICATE_MESSAGE) + ses->auth_key.len
++		- CIFS_SESS_KEY_SIZE + CIFS_CPHTXT_SIZE + 2;
++
++	if (ses->domainName)
++		sz += 2 * strnlen(ses->domainName, CIFS_MAX_DOMAINNAME_LEN);
++	else
++		sz += 2;
++
++	if (ses->user_name)
++		sz += 2 * strnlen(ses->user_name, CIFS_MAX_USERNAME_LEN);
++	else
++		sz += 2;
++
++	return sz;
++}
++
++int build_ntlmssp_auth_blob(unsigned char **pbuffer,
+ 					u16 *buflen,
+ 				   struct cifs_ses *ses,
+ 				   const struct nls_table *nls_cp)
+ {
+ 	int rc;
+-	AUTHENTICATE_MESSAGE *sec_blob = (AUTHENTICATE_MESSAGE *)pbuffer;
++	AUTHENTICATE_MESSAGE *sec_blob;
+ 	__u32 flags;
+ 	unsigned char *tmp;
+ 
++	rc = setup_ntlmv2_rsp(ses, nls_cp);
++	if (rc) {
++		cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
++		*buflen = 0;
++		goto setup_ntlmv2_ret;
++	}
++	*pbuffer = kmalloc(size_of_ntlmssp_blob(ses), GFP_KERNEL);
++	sec_blob = (AUTHENTICATE_MESSAGE *)*pbuffer;
++
+ 	memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
+ 	sec_blob->MessageType = NtLmAuthenticate;
+ 
+@@ -391,7 +415,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 			flags |= NTLMSSP_NEGOTIATE_KEY_XCH;
+ 	}
+ 
+-	tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
++	tmp = *pbuffer + sizeof(AUTHENTICATE_MESSAGE);
+ 	sec_blob->NegotiateFlags = cpu_to_le32(flags);
+ 
+ 	sec_blob->LmChallengeResponse.BufferOffset =
+@@ -399,13 +423,9 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 	sec_blob->LmChallengeResponse.Length = 0;
+ 	sec_blob->LmChallengeResponse.MaximumLength = 0;
+ 
+-	sec_blob->NtChallengeResponse.BufferOffset = cpu_to_le32(tmp - pbuffer);
++	sec_blob->NtChallengeResponse.BufferOffset =
++				cpu_to_le32(tmp - *pbuffer);
+ 	if (ses->user_name != NULL) {
+-		rc = setup_ntlmv2_rsp(ses, nls_cp);
+-		if (rc) {
+-			cifs_dbg(VFS, "Error %d during NTLMSSP authentication\n", rc);
+-			goto setup_ntlmv2_ret;
+-		}
+ 		memcpy(tmp, ses->auth_key.response + CIFS_SESS_KEY_SIZE,
+ 				ses->auth_key.len - CIFS_SESS_KEY_SIZE);
+ 		tmp += ses->auth_key.len - CIFS_SESS_KEY_SIZE;
+@@ -423,7 +443,7 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 	}
+ 
+ 	if (ses->domainName == NULL) {
+-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->DomainName.Length = 0;
+ 		sec_blob->DomainName.MaximumLength = 0;
+ 		tmp += 2;
+@@ -432,14 +452,14 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 		len = cifs_strtoUTF16((__le16 *)tmp, ses->domainName,
+ 				      CIFS_MAX_USERNAME_LEN, nls_cp);
+ 		len *= 2; /* unicode is 2 bytes each */
+-		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->DomainName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->DomainName.Length = cpu_to_le16(len);
+ 		sec_blob->DomainName.MaximumLength = cpu_to_le16(len);
+ 		tmp += len;
+ 	}
+ 
+ 	if (ses->user_name == NULL) {
+-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->UserName.Length = 0;
+ 		sec_blob->UserName.MaximumLength = 0;
+ 		tmp += 2;
+@@ -448,13 +468,13 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 		len = cifs_strtoUTF16((__le16 *)tmp, ses->user_name,
+ 				      CIFS_MAX_USERNAME_LEN, nls_cp);
+ 		len *= 2; /* unicode is 2 bytes each */
+-		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->UserName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->UserName.Length = cpu_to_le16(len);
+ 		sec_blob->UserName.MaximumLength = cpu_to_le16(len);
+ 		tmp += len;
+ 	}
+ 
+-	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - pbuffer);
++	sec_blob->WorkstationName.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 	sec_blob->WorkstationName.Length = 0;
+ 	sec_blob->WorkstationName.MaximumLength = 0;
+ 	tmp += 2;
+@@ -463,19 +483,19 @@ int build_ntlmssp_auth_blob(unsigned char *pbuffer,
+ 		(ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
+ 			&& !calc_seckey(ses)) {
+ 		memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
+-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
+ 		sec_blob->SessionKey.MaximumLength =
+ 				cpu_to_le16(CIFS_CPHTXT_SIZE);
+ 		tmp += CIFS_CPHTXT_SIZE;
+ 	} else {
+-		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
++		sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - *pbuffer);
+ 		sec_blob->SessionKey.Length = 0;
+ 		sec_blob->SessionKey.MaximumLength = 0;
+ 	}
+ 
++	*buflen = tmp - *pbuffer;
+ setup_ntlmv2_ret:
+-	*buflen = tmp - pbuffer;
+ 	return rc;
+ }
+ 
+@@ -1266,7 +1286,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
+ 	struct cifs_ses *ses = sess_data->ses;
+ 	__u16 bytes_remaining;
+ 	char *bcc_ptr;
+-	char *ntlmsspblob = NULL;
++	unsigned char *ntlmsspblob = NULL;
+ 	u16 blob_len;
+ 
+ 	cifs_dbg(FYI, "rawntlmssp session setup authenticate phase\n");
+@@ -1279,19 +1299,7 @@ sess_auth_rawntlmssp_authenticate(struct sess_data *sess_data)
+ 	/* Build security blob before we assemble the request */
+ 	pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base;
+ 	smb_buf = (struct smb_hdr *)pSMB;
+-	/*
+-	 * 5 is an empirical value, large enough to hold
+-	 * authenticate message plus max 10 of av paris,
+-	 * domain, user, workstation names, flags, etc.
+-	 */
+-	ntlmsspblob = kzalloc(5*sizeof(struct _AUTHENTICATE_MESSAGE),
+-				GFP_KERNEL);
+-	if (!ntlmsspblob) {
+-		rc = -ENOMEM;
+-		goto out;
+-	}
+-
+-	rc = build_ntlmssp_auth_blob(ntlmsspblob,
++	rc = build_ntlmssp_auth_blob(&ntlmsspblob,
+ 					&blob_len, ses, sess_data->nls_cp);
+ 	if (rc)
+ 		goto out_free_ntlmsspblob;
+diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
+index 8f38e33d365b..29e06db5f187 100644
+--- a/fs/cifs/smb2pdu.c
++++ b/fs/cifs/smb2pdu.c
+@@ -588,7 +588,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
+ 	u16 blob_length = 0;
+ 	struct key *spnego_key = NULL;
+ 	char *security_blob = NULL;
+-	char *ntlmssp_blob = NULL;
++	unsigned char *ntlmssp_blob = NULL;
+ 	bool use_spnego = false; /* else use raw ntlmssp */
+ 
+ 	cifs_dbg(FYI, "Session Setup\n");
+@@ -713,13 +713,7 @@ ssetup_ntlmssp_authenticate:
+ 		iov[1].iov_len = blob_length;
+ 	} else if (phase == NtLmAuthenticate) {
+ 		req->hdr.SessionId = ses->Suid;
+-		ntlmssp_blob = kzalloc(sizeof(struct _NEGOTIATE_MESSAGE) + 500,
+-				       GFP_KERNEL);
+-		if (ntlmssp_blob == NULL) {
+-			rc = -ENOMEM;
+-			goto ssetup_exit;
+-		}
+-		rc = build_ntlmssp_auth_blob(ntlmssp_blob, &blob_length, ses,
++		rc = build_ntlmssp_auth_blob(&ntlmssp_blob, &blob_length, ses,
+ 					     nls_cp);
+ 		if (rc) {
+ 			cifs_dbg(FYI, "build_ntlmssp_auth_blob failed %d\n",
+@@ -1818,6 +1812,33 @@ 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);
++	}
++
++	/* 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/namei.c b/fs/namei.c
+index 30145f8f21ed..aaa3b693ec0b 100644
+--- a/fs/namei.c
++++ b/fs/namei.c
+@@ -3173,6 +3173,10 @@ retry_lookup:
+ 		got_write = false;
+ 	}
+ 
++	error = follow_managed(&path, nd);
++	if (unlikely(error < 0))
++		return error;
++
+ 	if (unlikely(d_is_negative(path.dentry))) {
+ 		path_to_nameidata(&path, nd);
+ 		return -ENOENT;
+@@ -3188,10 +3192,6 @@ retry_lookup:
+ 		return -EEXIST;
+ 	}
+ 
+-	error = follow_managed(&path, nd);
+-	if (unlikely(error < 0))
+-		return error;
+-
+ 	seq = 0;	/* out of RCU mode, so the value doesn't matter */
+ 	inode = d_backing_inode(path.dentry);
+ finish_lookup:
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 4fb1691b4355..783004af5707 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -2409,8 +2409,10 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
+ 			mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
+ 		}
+ 		if (type->fs_flags & FS_USERNS_VISIBLE) {
+-			if (!fs_fully_visible(type, &mnt_flags))
++			if (!fs_fully_visible(type, &mnt_flags)) {
++				put_filesystem(type);
+ 				return -EPERM;
++			}
+ 		}
+ 	}
+ 
+@@ -3245,6 +3247,10 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
+ 		if (mnt->mnt.mnt_sb->s_iflags & SB_I_NOEXEC)
+ 			mnt_flags &= ~(MNT_LOCK_NOSUID | MNT_LOCK_NOEXEC);
+ 
++		/* Don't miss readonly hidden in the superblock flags */
++		if (mnt->mnt.mnt_sb->s_flags & MS_RDONLY)
++			mnt_flags |= MNT_LOCK_READONLY;
++
+ 		/* Verify the mount flags are equal to or more permissive
+ 		 * than the proposed new mount.
+ 		 */
+@@ -3271,7 +3277,7 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
+ 		list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
+ 			struct inode *inode = child->mnt_mountpoint->d_inode;
+ 			/* Only worry about locked mounts */
+-			if (!(mnt_flags & MNT_LOCKED))
++			if (!(child->mnt.mnt_flags & MNT_LOCKED))
+ 				continue;
+ 			/* Is the directory permanetly empty? */
+ 			if (!is_empty_dir_inode(inode))
+diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
+index 33eb81738d03..a7dd1fee8f13 100644
+--- a/fs/nfs/dir.c
++++ b/fs/nfs/dir.c
+@@ -1527,9 +1527,9 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
+ 		err = PTR_ERR(inode);
+ 		trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
+ 		put_nfs_open_context(ctx);
++		d_drop(dentry);
+ 		switch (err) {
+ 		case -ENOENT:
+-			d_drop(dentry);
+ 			d_add(dentry, NULL);
+ 			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
+ 			break;
+diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
+index 327b8c34d360..de2523f5e7c9 100644
+--- a/fs/nfs/nfs4proc.c
++++ b/fs/nfs/nfs4proc.c
+@@ -2860,12 +2860,11 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
+ 			call_close |= is_wronly;
+ 		else if (is_wronly)
+ 			calldata->arg.fmode |= FMODE_WRITE;
++		if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE))
++			call_close |= is_rdwr;
+ 	} else if (is_rdwr)
+ 		calldata->arg.fmode |= FMODE_READ|FMODE_WRITE;
+ 
+-	if (calldata->arg.fmode == 0)
+-		call_close |= is_rdwr;
+-
+ 	if (!nfs4_valid_open_stateid(state))
+ 		call_close = 0;
+ 	spin_unlock(&state->owner->so_lock);
+diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
+index 776dccbc306d..dcb70001ae2c 100644
+--- a/fs/nfs/pnfs_nfs.c
++++ b/fs/nfs/pnfs_nfs.c
+@@ -247,7 +247,11 @@ void pnfs_fetch_commit_bucket_list(struct list_head *pages,
+ }
+ 
+ /* Helper function for pnfs_generic_commit_pagelist to catch an empty
+- * page list. This can happen when two commits race. */
++ * page list. This can happen when two commits race.
++ *
++ * This must be called instead of nfs_init_commit - call one or the other, but
++ * not both!
++ */
+ static bool
+ pnfs_generic_commit_cancel_empty_pagelist(struct list_head *pages,
+ 					  struct nfs_commit_data *data,
+@@ -256,7 +260,11 @@ pnfs_generic_commit_cancel_empty_pagelist(struct list_head *pages,
+ 	if (list_empty(pages)) {
+ 		if (atomic_dec_and_test(&cinfo->mds->rpcs_out))
+ 			wake_up_atomic_t(&cinfo->mds->rpcs_out);
+-		nfs_commitdata_release(data);
++		/* don't call nfs_commitdata_release - it tries to put
++		 * the open_context which is not acquired until nfs_init_commit
++		 * which has not been called on @data */
++		WARN_ON_ONCE(data->context);
++		nfs_commit_free(data);
+ 		return true;
+ 	}
+ 
+diff --git a/fs/nfs/read.c b/fs/nfs/read.c
+index 6776d7a7839e..572e5b3b06f1 100644
+--- a/fs/nfs/read.c
++++ b/fs/nfs/read.c
+@@ -367,13 +367,13 @@ readpage_async_filler(void *data, struct page *page)
+ 		nfs_list_remove_request(new);
+ 		nfs_readpage_release(new);
+ 		error = desc->pgio->pg_error;
+-		goto out_unlock;
++		goto out;
+ 	}
+ 	return 0;
+ out_error:
+ 	error = PTR_ERR(new);
+-out_unlock:
+ 	unlock_page(page);
++out:
+ 	return error;
+ }
+ 
+diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
+index 1580ea6fd64d..d08cd88155c7 100644
+--- a/fs/nfsd/nfs2acl.c
++++ b/fs/nfsd/nfs2acl.c
+@@ -104,22 +104,21 @@ static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp,
+ 		goto out;
+ 
+ 	inode = d_inode(fh->fh_dentry);
+-	if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
+-		error = -EOPNOTSUPP;
+-		goto out_errno;
+-	}
+ 
+ 	error = fh_want_write(fh);
+ 	if (error)
+ 		goto out_errno;
+ 
+-	error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
++	fh_lock(fh);
++
++	error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access);
+ 	if (error)
+-		goto out_drop_write;
+-	error = inode->i_op->set_acl(inode, argp->acl_default,
+-				     ACL_TYPE_DEFAULT);
++		goto out_drop_lock;
++	error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default);
+ 	if (error)
+-		goto out_drop_write;
++		goto out_drop_lock;
++
++	fh_unlock(fh);
+ 
+ 	fh_drop_write(fh);
+ 
+@@ -131,7 +130,8 @@ out:
+ 	posix_acl_release(argp->acl_access);
+ 	posix_acl_release(argp->acl_default);
+ 	return nfserr;
+-out_drop_write:
++out_drop_lock:
++	fh_unlock(fh);
+ 	fh_drop_write(fh);
+ out_errno:
+ 	nfserr = nfserrno(error);
+diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
+index 01df4cd7c753..0c890347cde3 100644
+--- a/fs/nfsd/nfs3acl.c
++++ b/fs/nfsd/nfs3acl.c
+@@ -95,22 +95,20 @@ static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp,
+ 		goto out;
+ 
+ 	inode = d_inode(fh->fh_dentry);
+-	if (!IS_POSIXACL(inode) || !inode->i_op->set_acl) {
+-		error = -EOPNOTSUPP;
+-		goto out_errno;
+-	}
+ 
+ 	error = fh_want_write(fh);
+ 	if (error)
+ 		goto out_errno;
+ 
+-	error = inode->i_op->set_acl(inode, argp->acl_access, ACL_TYPE_ACCESS);
++	fh_lock(fh);
++
++	error = set_posix_acl(inode, ACL_TYPE_ACCESS, argp->acl_access);
+ 	if (error)
+-		goto out_drop_write;
+-	error = inode->i_op->set_acl(inode, argp->acl_default,
+-				     ACL_TYPE_DEFAULT);
++		goto out_drop_lock;
++	error = set_posix_acl(inode, ACL_TYPE_DEFAULT, argp->acl_default);
+ 
+-out_drop_write:
++out_drop_lock:
++	fh_unlock(fh);
+ 	fh_drop_write(fh);
+ out_errno:
+ 	nfserr = nfserrno(error);
+diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c
+index 6adabd6049b7..71292a0d6f09 100644
+--- a/fs/nfsd/nfs4acl.c
++++ b/fs/nfsd/nfs4acl.c
+@@ -770,9 +770,6 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ 	dentry = fhp->fh_dentry;
+ 	inode = d_inode(dentry);
+ 
+-	if (!inode->i_op->set_acl || !IS_POSIXACL(inode))
+-		return nfserr_attrnotsupp;
+-
+ 	if (S_ISDIR(inode->i_mode))
+ 		flags = NFS4_ACL_DIR;
+ 
+@@ -782,16 +779,19 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqstp, struct svc_fh *fhp,
+ 	if (host_error < 0)
+ 		goto out_nfserr;
+ 
+-	host_error = inode->i_op->set_acl(inode, pacl, ACL_TYPE_ACCESS);
++	fh_lock(fhp);
++
++	host_error = set_posix_acl(inode, ACL_TYPE_ACCESS, pacl);
+ 	if (host_error < 0)
+-		goto out_release;
++		goto out_drop_lock;
+ 
+ 	if (S_ISDIR(inode->i_mode)) {
+-		host_error = inode->i_op->set_acl(inode, dpacl,
+-						  ACL_TYPE_DEFAULT);
++		host_error = set_posix_acl(inode, ACL_TYPE_DEFAULT, dpacl);
+ 	}
+ 
+-out_release:
++out_drop_lock:
++	fh_unlock(fhp);
++
+ 	posix_acl_release(pacl);
+ 	posix_acl_release(dpacl);
+ out_nfserr:
+diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
+index 7389cb1d7409..04c68d900324 100644
+--- a/fs/nfsd/nfs4callback.c
++++ b/fs/nfsd/nfs4callback.c
+@@ -710,22 +710,6 @@ static struct rpc_cred *get_backchannel_cred(struct nfs4_client *clp, struct rpc
+ 	}
+ }
+ 
+-static struct rpc_clnt *create_backchannel_client(struct rpc_create_args *args)
+-{
+-	struct rpc_xprt *xprt;
+-
+-	if (args->protocol != XPRT_TRANSPORT_BC_TCP)
+-		return rpc_create(args);
+-
+-	xprt = args->bc_xprt->xpt_bc_xprt;
+-	if (xprt) {
+-		xprt_get(xprt);
+-		return rpc_create_xprt(args, xprt);
+-	}
+-
+-	return rpc_create(args);
+-}
+-
+ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *conn, struct nfsd4_session *ses)
+ {
+ 	int maxtime = max_cb_time(clp->net);
+@@ -768,7 +752,7 @@ static int setup_callback_client(struct nfs4_client *clp, struct nfs4_cb_conn *c
+ 		args.authflavor = ses->se_cb_sec.flavor;
+ 	}
+ 	/* Create RPC client */
+-	client = create_backchannel_client(&args);
++	client = rpc_create(&args);
+ 	if (IS_ERR(client)) {
+ 		dprintk("NFSD: couldn't create callback client: %ld\n",
+ 			PTR_ERR(client));
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index 0462eeddfff9..9e04e49df681 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -3487,6 +3487,10 @@ init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
+ 	struct nfs4_openowner *oo = open->op_openowner;
+ 	struct nfs4_ol_stateid *retstp = NULL;
+ 
++	/* We are moving these outside of the spinlocks to avoid the warnings */
++	mutex_init(&stp->st_mutex);
++	mutex_lock(&stp->st_mutex);
++
+ 	spin_lock(&oo->oo_owner.so_client->cl_lock);
+ 	spin_lock(&fp->fi_lock);
+ 
+@@ -3502,13 +3506,17 @@ init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
+ 	stp->st_access_bmap = 0;
+ 	stp->st_deny_bmap = 0;
+ 	stp->st_openstp = NULL;
+-	init_rwsem(&stp->st_rwsem);
+ 	list_add(&stp->st_perstateowner, &oo->oo_owner.so_stateids);
+ 	list_add(&stp->st_perfile, &fp->fi_stateids);
+ 
+ out_unlock:
+ 	spin_unlock(&fp->fi_lock);
+ 	spin_unlock(&oo->oo_owner.so_client->cl_lock);
++	if (retstp) {
++		mutex_lock(&retstp->st_mutex);
++		/* Not that we need to, just for neatness */
++		mutex_unlock(&stp->st_mutex);
++	}
+ 	return retstp;
+ }
+ 
+@@ -4335,32 +4343,34 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
+ 	 */
+ 	if (stp) {
+ 		/* Stateid was found, this is an OPEN upgrade */
+-		down_read(&stp->st_rwsem);
++		mutex_lock(&stp->st_mutex);
+ 		status = nfs4_upgrade_open(rqstp, fp, current_fh, stp, open);
+ 		if (status) {
+-			up_read(&stp->st_rwsem);
++			mutex_unlock(&stp->st_mutex);
+ 			goto out;
+ 		}
+ 	} else {
+ 		stp = open->op_stp;
+ 		open->op_stp = NULL;
++		/*
++		 * init_open_stateid() either returns a locked stateid
++		 * it found, or initializes and locks the new one we passed in
++		 */
+ 		swapstp = init_open_stateid(stp, fp, open);
+ 		if (swapstp) {
+ 			nfs4_put_stid(&stp->st_stid);
+ 			stp = swapstp;
+-			down_read(&stp->st_rwsem);
+ 			status = nfs4_upgrade_open(rqstp, fp, current_fh,
+ 						stp, open);
+ 			if (status) {
+-				up_read(&stp->st_rwsem);
++				mutex_unlock(&stp->st_mutex);
+ 				goto out;
+ 			}
+ 			goto upgrade_out;
+ 		}
+-		down_read(&stp->st_rwsem);
+ 		status = nfs4_get_vfs_file(rqstp, fp, current_fh, stp, open);
+ 		if (status) {
+-			up_read(&stp->st_rwsem);
++			mutex_unlock(&stp->st_mutex);
+ 			release_open_stateid(stp);
+ 			goto out;
+ 		}
+@@ -4372,7 +4382,7 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
+ 	}
+ upgrade_out:
+ 	nfs4_inc_and_copy_stateid(&open->op_stateid, &stp->st_stid);
+-	up_read(&stp->st_rwsem);
++	mutex_unlock(&stp->st_mutex);
+ 
+ 	if (nfsd4_has_session(&resp->cstate)) {
+ 		if (open->op_deleg_want & NFS4_SHARE_WANT_NO_DELEG) {
+@@ -4983,12 +4993,12 @@ static __be32 nfs4_seqid_op_checks(struct nfsd4_compound_state *cstate, stateid_
+ 		 * revoked delegations are kept only for free_stateid.
+ 		 */
+ 		return nfserr_bad_stateid;
+-	down_write(&stp->st_rwsem);
++	mutex_lock(&stp->st_mutex);
+ 	status = check_stateid_generation(stateid, &stp->st_stid.sc_stateid, nfsd4_has_session(cstate));
+ 	if (status == nfs_ok)
+ 		status = nfs4_check_fh(current_fh, &stp->st_stid);
+ 	if (status != nfs_ok)
+-		up_write(&stp->st_rwsem);
++		mutex_unlock(&stp->st_mutex);
+ 	return status;
+ }
+ 
+@@ -5036,7 +5046,7 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs
+ 		return status;
+ 	oo = openowner(stp->st_stateowner);
+ 	if (!(oo->oo_flags & NFS4_OO_CONFIRMED)) {
+-		up_write(&stp->st_rwsem);
++		mutex_unlock(&stp->st_mutex);
+ 		nfs4_put_stid(&stp->st_stid);
+ 		return nfserr_bad_stateid;
+ 	}
+@@ -5068,12 +5078,12 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 	oo = openowner(stp->st_stateowner);
+ 	status = nfserr_bad_stateid;
+ 	if (oo->oo_flags & NFS4_OO_CONFIRMED) {
+-		up_write(&stp->st_rwsem);
++		mutex_unlock(&stp->st_mutex);
+ 		goto put_stateid;
+ 	}
+ 	oo->oo_flags |= NFS4_OO_CONFIRMED;
+ 	nfs4_inc_and_copy_stateid(&oc->oc_resp_stateid, &stp->st_stid);
+-	up_write(&stp->st_rwsem);
++	mutex_unlock(&stp->st_mutex);
+ 	dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n",
+ 		__func__, oc->oc_seqid, STATEID_VAL(&stp->st_stid.sc_stateid));
+ 
+@@ -5149,7 +5159,7 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp,
+ 	nfs4_inc_and_copy_stateid(&od->od_stateid, &stp->st_stid);
+ 	status = nfs_ok;
+ put_stateid:
+-	up_write(&stp->st_rwsem);
++	mutex_unlock(&stp->st_mutex);
+ 	nfs4_put_stid(&stp->st_stid);
+ out:
+ 	nfsd4_bump_seqid(cstate, status);
+@@ -5202,7 +5212,7 @@ nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 	if (status)
+ 		goto out; 
+ 	nfs4_inc_and_copy_stateid(&close->cl_stateid, &stp->st_stid);
+-	up_write(&stp->st_rwsem);
++	mutex_unlock(&stp->st_mutex);
+ 
+ 	nfsd4_close_open_stateid(stp);
+ 
+@@ -5428,7 +5438,7 @@ init_lock_stateid(struct nfs4_ol_stateid *stp, struct nfs4_lockowner *lo,
+ 	stp->st_access_bmap = 0;
+ 	stp->st_deny_bmap = open_stp->st_deny_bmap;
+ 	stp->st_openstp = open_stp;
+-	init_rwsem(&stp->st_rwsem);
++	mutex_init(&stp->st_mutex);
+ 	list_add(&stp->st_locks, &open_stp->st_locks);
+ 	list_add(&stp->st_perstateowner, &lo->lo_owner.so_stateids);
+ 	spin_lock(&fp->fi_lock);
+@@ -5597,7 +5607,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 					&open_stp, nn);
+ 		if (status)
+ 			goto out;
+-		up_write(&open_stp->st_rwsem);
++		mutex_unlock(&open_stp->st_mutex);
+ 		open_sop = openowner(open_stp->st_stateowner);
+ 		status = nfserr_bad_stateid;
+ 		if (!same_clid(&open_sop->oo_owner.so_client->cl_clientid,
+@@ -5606,7 +5616,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ 		status = lookup_or_create_lock_state(cstate, open_stp, lock,
+ 							&lock_stp, &new);
+ 		if (status == nfs_ok)
+-			down_write(&lock_stp->st_rwsem);
++			mutex_lock(&lock_stp->st_mutex);
+ 	} else {
+ 		status = nfs4_preprocess_seqid_op(cstate,
+ 				       lock->lk_old_lock_seqid,
+@@ -5710,7 +5720,7 @@ out:
+ 		    seqid_mutating_err(ntohl(status)))
+ 			lock_sop->lo_owner.so_seqid++;
+ 
+-		up_write(&lock_stp->st_rwsem);
++		mutex_unlock(&lock_stp->st_mutex);
+ 
+ 		/*
+ 		 * If this is a new, never-before-used stateid, and we are
+@@ -5880,7 +5890,7 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+ fput:
+ 	fput(filp);
+ put_stateid:
+-	up_write(&stp->st_rwsem);
++	mutex_unlock(&stp->st_mutex);
+ 	nfs4_put_stid(&stp->st_stid);
+ out:
+ 	nfsd4_bump_seqid(cstate, status);
+diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
+index c050c53036a6..c89d7b55fb9a 100644
+--- a/fs/nfsd/state.h
++++ b/fs/nfsd/state.h
+@@ -535,7 +535,7 @@ struct nfs4_ol_stateid {
+ 	unsigned char			st_access_bmap;
+ 	unsigned char			st_deny_bmap;
+ 	struct nfs4_ol_stateid		*st_openstp;
+-	struct rw_semaphore		st_rwsem;
++	struct mutex			st_mutex;
+ };
+ 
+ static inline struct nfs4_ol_stateid *openlockstateid(struct nfs4_stid *s)
+diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
+index b3fc0a35bf62..fb35aa21b34b 100644
+--- a/fs/overlayfs/dir.c
++++ b/fs/overlayfs/dir.c
+@@ -511,6 +511,7 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
+ 	struct dentry *upper;
+ 	struct dentry *opaquedir = NULL;
+ 	int err;
++	int flags = 0;
+ 
+ 	if (WARN_ON(!workdir))
+ 		return -EROFS;
+@@ -540,46 +541,39 @@ static int ovl_remove_and_whiteout(struct dentry *dentry, bool is_dir)
+ 	if (err)
+ 		goto out_dput;
+ 
+-	whiteout = ovl_whiteout(workdir, dentry);
+-	err = PTR_ERR(whiteout);
+-	if (IS_ERR(whiteout))
++	upper = lookup_one_len(dentry->d_name.name, upperdir,
++			       dentry->d_name.len);
++	err = PTR_ERR(upper);
++	if (IS_ERR(upper))
+ 		goto out_unlock;
+ 
+-	upper = ovl_dentry_upper(dentry);
+-	if (!upper) {
+-		upper = lookup_one_len(dentry->d_name.name, upperdir,
+-				       dentry->d_name.len);
+-		err = PTR_ERR(upper);
+-		if (IS_ERR(upper))
+-			goto kill_whiteout;
+-
+-		err = ovl_do_rename(wdir, whiteout, udir, upper, 0);
+-		dput(upper);
+-		if (err)
+-			goto kill_whiteout;
+-	} else {
+-		int flags = 0;
++	err = -ESTALE;
++	if ((opaquedir && upper != opaquedir) ||
++	    (!opaquedir && ovl_dentry_upper(dentry) &&
++	     upper != ovl_dentry_upper(dentry))) {
++		goto out_dput_upper;
++	}
+ 
+-		if (opaquedir)
+-			upper = opaquedir;
+-		err = -ESTALE;
+-		if (upper->d_parent != upperdir)
+-			goto kill_whiteout;
++	whiteout = ovl_whiteout(workdir, dentry);
++	err = PTR_ERR(whiteout);
++	if (IS_ERR(whiteout))
++		goto out_dput_upper;
+ 
+-		if (is_dir)
+-			flags |= RENAME_EXCHANGE;
++	if (d_is_dir(upper))
++		flags = RENAME_EXCHANGE;
+ 
+-		err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
+-		if (err)
+-			goto kill_whiteout;
++	err = ovl_do_rename(wdir, whiteout, udir, upper, flags);
++	if (err)
++		goto kill_whiteout;
++	if (flags)
++		ovl_cleanup(wdir, upper);
+ 
+-		if (is_dir)
+-			ovl_cleanup(wdir, upper);
+-	}
+ 	ovl_dentry_version_inc(dentry->d_parent);
+ out_d_drop:
+ 	d_drop(dentry);
+ 	dput(whiteout);
++out_dput_upper:
++	dput(upper);
+ out_unlock:
+ 	unlock_rename(workdir, upperdir);
+ out_dput:
+diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
+index a4ff5d0d7db9..d46fa609e803 100644
+--- a/fs/overlayfs/inode.c
++++ b/fs/overlayfs/inode.c
+@@ -59,16 +59,40 @@ int ovl_setattr(struct dentry *dentry, struct iattr *attr)
+ 	if (err)
+ 		goto out;
+ 
++	if (attr->ia_valid & ATTR_SIZE) {
++		struct inode *realinode = d_inode(ovl_dentry_real(dentry));
++
++		err = -ETXTBSY;
++		if (atomic_read(&realinode->i_writecount) < 0)
++			goto out_drop_write;
++	}
++
+ 	err = ovl_copy_up(dentry);
+ 	if (!err) {
++		struct inode *winode = NULL;
++
+ 		upperdentry = ovl_dentry_upper(dentry);
+ 
++		if (attr->ia_valid & ATTR_SIZE) {
++			winode = d_inode(upperdentry);
++			err = get_write_access(winode);
++			if (err)
++				goto out_drop_write;
++		}
++
++		if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
++			attr->ia_valid &= ~ATTR_MODE;
++
+ 		inode_lock(upperdentry->d_inode);
+ 		err = notify_change(upperdentry, attr, NULL);
+ 		if (!err)
+ 			ovl_copyattr(upperdentry->d_inode, dentry->d_inode);
+ 		inode_unlock(upperdentry->d_inode);
++
++		if (winode)
++			put_write_access(winode);
+ 	}
++out_drop_write:
+ 	ovl_drop_write(dentry);
+ out:
+ 	return err;
+@@ -121,16 +145,18 @@ int ovl_permission(struct inode *inode, int mask)
+ 
+ 		err = vfs_getattr(&realpath, &stat);
+ 		if (err)
+-			return err;
++			goto out_dput;
+ 
++		err = -ESTALE;
+ 		if ((stat.mode ^ inode->i_mode) & S_IFMT)
+-			return -ESTALE;
++			goto out_dput;
+ 
+ 		inode->i_mode = stat.mode;
+ 		inode->i_uid = stat.uid;
+ 		inode->i_gid = stat.gid;
+ 
+-		return generic_permission(inode, mask);
++		err = generic_permission(inode, mask);
++		goto out_dput;
+ 	}
+ 
+ 	/* Careful in RCU walk mode */
+@@ -400,12 +426,11 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode,
+ 	if (!inode)
+ 		return NULL;
+ 
+-	mode &= S_IFMT;
+-
+ 	inode->i_ino = get_next_ino();
+ 	inode->i_mode = mode;
+ 	inode->i_flags |= S_NOATIME | S_NOCMTIME;
+ 
++	mode &= S_IFMT;
+ 	switch (mode) {
+ 	case S_IFDIR:
+ 		inode->i_private = oe;
+diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
+index 6a7090f4a441..294ccc0c1fc7 100644
+--- a/fs/overlayfs/overlayfs.h
++++ b/fs/overlayfs/overlayfs.h
+@@ -185,6 +185,7 @@ static inline void ovl_copyattr(struct inode *from, struct inode *to)
+ {
+ 	to->i_uid = from->i_uid;
+ 	to->i_gid = from->i_gid;
++	to->i_mode = from->i_mode;
+ }
+ 
+ /* dir.c */
+diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
+index 791235e03d17..7952a50f0a72 100644
+--- a/fs/overlayfs/super.c
++++ b/fs/overlayfs/super.c
+@@ -1064,16 +1064,21 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
+ 		/*
+ 		 * Upper should support d_type, else whiteouts are visible.
+ 		 * Given workdir and upper are on same fs, we can do
+-		 * iterate_dir() on workdir.
++		 * iterate_dir() on workdir. This check requires successful
++		 * creation of workdir in previous step.
+ 		 */
+-		err = ovl_check_d_type_supported(&workpath);
+-		if (err < 0)
+-			goto out_put_workdir;
++		if (ufs->workdir) {
++			err = ovl_check_d_type_supported(&workpath);
++			if (err < 0)
++				goto out_put_workdir;
+ 
+-		if (!err) {
+-			pr_err("overlayfs: upper fs needs to support d_type.\n");
+-			err = -EINVAL;
+-			goto out_put_workdir;
++			/*
++			 * We allowed this configuration and don't want to
++			 * break users over kernel upgrade. So warn instead
++			 * of erroring out.
++			 */
++			if (!err)
++				pr_warn("overlayfs: upper fs needs to support d_type.\n");
+ 		}
+ 	}
+ 
+diff --git a/fs/posix_acl.c b/fs/posix_acl.c
+index 711dd5170376..e11ea5fb1bad 100644
+--- a/fs/posix_acl.c
++++ b/fs/posix_acl.c
+@@ -786,39 +786,43 @@ posix_acl_xattr_get(const struct xattr_handler *handler,
+ 	return error;
+ }
+ 
+-static int
+-posix_acl_xattr_set(const struct xattr_handler *handler,
+-		    struct dentry *dentry, const char *name,
+-		    const void *value, size_t size, int flags)
++int
++set_posix_acl(struct inode *inode, int type, struct posix_acl *acl)
+ {
+-	struct inode *inode = d_backing_inode(dentry);
+-	struct posix_acl *acl = NULL;
+-	int ret;
+-
+ 	if (!IS_POSIXACL(inode))
+ 		return -EOPNOTSUPP;
+ 	if (!inode->i_op->set_acl)
+ 		return -EOPNOTSUPP;
+ 
+-	if (handler->flags == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
+-		return value ? -EACCES : 0;
++	if (type == ACL_TYPE_DEFAULT && !S_ISDIR(inode->i_mode))
++		return acl ? -EACCES : 0;
+ 	if (!inode_owner_or_capable(inode))
+ 		return -EPERM;
+ 
++	if (acl) {
++		int ret = posix_acl_valid(acl);
++		if (ret)
++			return ret;
++	}
++	return inode->i_op->set_acl(inode, acl, type);
++}
++EXPORT_SYMBOL(set_posix_acl);
++
++static int
++posix_acl_xattr_set(const struct xattr_handler *handler,
++		    struct dentry *dentry, const char *name,
++		    const void *value, size_t size, int flags)
++{
++	struct inode *inode = d_backing_inode(dentry);
++	struct posix_acl *acl = NULL;
++	int ret;
++
+ 	if (value) {
+ 		acl = posix_acl_from_xattr(&init_user_ns, value, size);
+ 		if (IS_ERR(acl))
+ 			return PTR_ERR(acl);
+-
+-		if (acl) {
+-			ret = posix_acl_valid(acl);
+-			if (ret)
+-				goto out;
+-		}
+ 	}
+-
+-	ret = inode->i_op->set_acl(inode, acl, handler->flags);
+-out:
++	ret = set_posix_acl(inode, handler->flags, acl);
+ 	posix_acl_release(acl);
+ 	return ret;
+ }
+diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
+index 446753d8ac34..5b5ec8d0f324 100644
+--- a/fs/ubifs/file.c
++++ b/fs/ubifs/file.c
+@@ -52,6 +52,7 @@
+ #include "ubifs.h"
+ #include <linux/mount.h>
+ #include <linux/slab.h>
++#include <linux/migrate.h>
+ 
+ static int read_block(struct inode *inode, void *addr, unsigned int block,
+ 		      struct ubifs_data_node *dn)
+@@ -1452,6 +1453,26 @@ static int ubifs_set_page_dirty(struct page *page)
+ 	return ret;
+ }
+ 
++#ifdef CONFIG_MIGRATION
++static int ubifs_migrate_page(struct address_space *mapping,
++		struct page *newpage, struct page *page, enum migrate_mode mode)
++{
++	int rc;
++
++	rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
++	if (rc != MIGRATEPAGE_SUCCESS)
++		return rc;
++
++	if (PagePrivate(page)) {
++		ClearPagePrivate(page);
++		SetPagePrivate(newpage);
++	}
++
++	migrate_page_copy(newpage, page);
++	return MIGRATEPAGE_SUCCESS;
++}
++#endif
++
+ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
+ {
+ 	/*
+@@ -1591,6 +1612,9 @@ const struct address_space_operations ubifs_file_address_operations = {
+ 	.write_end      = ubifs_write_end,
+ 	.invalidatepage = ubifs_invalidatepage,
+ 	.set_page_dirty = ubifs_set_page_dirty,
++#ifdef CONFIG_MIGRATION
++	.migratepage	= ubifs_migrate_page,
++#endif
+ 	.releasepage    = ubifs_releasepage,
+ };
+ 
+diff --git a/include/asm-generic/qspinlock.h b/include/asm-generic/qspinlock.h
+index 6bd05700d8c9..05f05f17a7c2 100644
+--- a/include/asm-generic/qspinlock.h
++++ b/include/asm-generic/qspinlock.h
+@@ -22,37 +22,33 @@
+ #include <asm-generic/qspinlock_types.h>
+ 
+ /**
++ * queued_spin_unlock_wait - wait until the _current_ lock holder releases the lock
++ * @lock : Pointer to queued spinlock structure
++ *
++ * There is a very slight possibility of live-lock if the lockers keep coming
++ * and the waiter is just unfortunate enough to not see any unlock state.
++ */
++#ifndef queued_spin_unlock_wait
++extern void queued_spin_unlock_wait(struct qspinlock *lock);
++#endif
++
++/**
+  * queued_spin_is_locked - is the spinlock locked?
+  * @lock: Pointer to queued spinlock structure
+  * Return: 1 if it is locked, 0 otherwise
+  */
++#ifndef queued_spin_is_locked
+ static __always_inline int queued_spin_is_locked(struct qspinlock *lock)
+ {
+ 	/*
+-	 * queued_spin_lock_slowpath() can ACQUIRE the lock before
+-	 * issuing the unordered store that sets _Q_LOCKED_VAL.
+-	 *
+-	 * See both smp_cond_acquire() sites for more detail.
+-	 *
+-	 * This however means that in code like:
+-	 *
+-	 *   spin_lock(A)		spin_lock(B)
+-	 *   spin_unlock_wait(B)	spin_is_locked(A)
+-	 *   do_something()		do_something()
+-	 *
+-	 * Both CPUs can end up running do_something() because the store
+-	 * setting _Q_LOCKED_VAL will pass through the loads in
+-	 * spin_unlock_wait() and/or spin_is_locked().
++	 * See queued_spin_unlock_wait().
+ 	 *
+-	 * Avoid this by issuing a full memory barrier between the spin_lock()
+-	 * and the loads in spin_unlock_wait() and spin_is_locked().
+-	 *
+-	 * Note that regular mutual exclusion doesn't care about this
+-	 * delayed store.
++	 * Any !0 state indicates it is locked, even if _Q_LOCKED_VAL
++	 * isn't immediately observable.
+ 	 */
+-	smp_mb();
+-	return atomic_read(&lock->val) & _Q_LOCKED_MASK;
++	return atomic_read(&lock->val);
+ }
++#endif
+ 
+ /**
+  * queued_spin_value_unlocked - is the spinlock structure unlocked?
+@@ -122,21 +118,6 @@ static __always_inline void queued_spin_unlock(struct qspinlock *lock)
+ }
+ #endif
+ 
+-/**
+- * queued_spin_unlock_wait - wait until current lock holder releases the lock
+- * @lock : Pointer to queued spinlock structure
+- *
+- * There is a very slight possibility of live-lock if the lockers keep coming
+- * and the waiter is just unfortunate enough to not see any unlock state.
+- */
+-static inline void queued_spin_unlock_wait(struct qspinlock *lock)
+-{
+-	/* See queued_spin_is_locked() */
+-	smp_mb();
+-	while (atomic_read(&lock->val) & _Q_LOCKED_MASK)
+-		cpu_relax();
+-}
+-
+ #ifndef virt_spin_lock
+ static __always_inline bool virt_spin_lock(struct qspinlock *lock)
+ {
+diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h
+index 055a08ddac02..a74c49d7c0fc 100644
+--- a/include/drm/ttm/ttm_bo_api.h
++++ b/include/drm/ttm/ttm_bo_api.h
+@@ -316,6 +316,20 @@ ttm_bo_reference(struct ttm_buffer_object *bo)
+  */
+ extern int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy,
+ 		       bool interruptible, bool no_wait);
++
++/**
++ * ttm_bo_mem_compat - Check if proposed placement is compatible with a bo
++ *
++ * @placement:  Return immediately if buffer is busy.
++ * @mem:  The struct ttm_mem_reg indicating the region where the bo resides
++ * @new_flags: Describes compatible placement found
++ *
++ * Returns true if the placement is compatible
++ */
++extern bool ttm_bo_mem_compat(struct ttm_placement *placement,
++			      struct ttm_mem_reg *mem,
++			      uint32_t *new_flags);
++
+ /**
+  * ttm_bo_validate
+  *
+diff --git a/include/linux/cpuidle.h b/include/linux/cpuidle.h
+index 786ad32631a6..07b83d32f66c 100644
+--- a/include/linux/cpuidle.h
++++ b/include/linux/cpuidle.h
+@@ -152,6 +152,8 @@ extern void cpuidle_disable_device(struct cpuidle_device *dev);
+ extern int cpuidle_play_dead(void);
+ 
+ extern struct cpuidle_driver *cpuidle_get_cpu_driver(struct cpuidle_device *dev);
++static inline struct cpuidle_device *cpuidle_get_device(void)
++{return __this_cpu_read(cpuidle_devices); }
+ #else
+ static inline void disable_cpuidle(void) { }
+ static inline bool cpuidle_not_available(struct cpuidle_driver *drv,
+@@ -187,6 +189,7 @@ static inline void cpuidle_disable_device(struct cpuidle_device *dev) { }
+ static inline int cpuidle_play_dead(void) {return -ENODEV; }
+ static inline struct cpuidle_driver *cpuidle_get_cpu_driver(
+ 	struct cpuidle_device *dev) {return NULL; }
++static inline struct cpuidle_device *cpuidle_get_device(void) {return NULL; }
+ #endif
+ 
+ #if defined(CONFIG_CPU_IDLE) && defined(CONFIG_SUSPEND)
+diff --git a/include/linux/dcache.h b/include/linux/dcache.h
+index 7e9422cb5989..ad5d582f9b14 100644
+--- a/include/linux/dcache.h
++++ b/include/linux/dcache.h
+@@ -576,5 +576,17 @@ static inline struct inode *vfs_select_inode(struct dentry *dentry,
+ 	return inode;
+ }
+ 
++/**
++ * d_real_inode - Return the real inode
++ * @dentry: The dentry to query
++ *
++ * If dentry is on an union/overlay, then return the underlying, real inode.
++ * Otherwise return d_inode().
++ */
++static inline struct inode *d_real_inode(struct dentry *dentry)
++{
++	return d_backing_inode(d_real(dentry));
++}
++
+ 
+ #endif	/* __LINUX_DCACHE_H */
+diff --git a/include/linux/jump_label.h b/include/linux/jump_label.h
+index 0536524bb9eb..68904469fba1 100644
+--- a/include/linux/jump_label.h
++++ b/include/linux/jump_label.h
+@@ -117,13 +117,18 @@ struct module;
+ 
+ #include <linux/atomic.h>
+ 
++#ifdef HAVE_JUMP_LABEL
++
+ static inline int static_key_count(struct static_key *key)
+ {
+-	return atomic_read(&key->enabled);
++	/*
++	 * -1 means the first static_key_slow_inc() is in progress.
++	 *  static_key_enabled() must return true, so return 1 here.
++	 */
++	int n = atomic_read(&key->enabled);
++	return n >= 0 ? n : 1;
+ }
+ 
+-#ifdef HAVE_JUMP_LABEL
+-
+ #define JUMP_TYPE_FALSE	0UL
+ #define JUMP_TYPE_TRUE	1UL
+ #define JUMP_TYPE_MASK	1UL
+@@ -162,6 +167,11 @@ extern void jump_label_apply_nops(struct module *mod);
+ 
+ #else  /* !HAVE_JUMP_LABEL */
+ 
++static inline int static_key_count(struct static_key *key)
++{
++	return atomic_read(&key->enabled);
++}
++
+ static __always_inline void jump_label_init(void)
+ {
+ 	static_key_initialized = true;
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 15d0df943466..794b924e9669 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -1062,6 +1062,7 @@ __skb_set_sw_hash(struct sk_buff *skb, __u32 hash, bool is_l4)
+ }
+ 
+ void __skb_get_hash(struct sk_buff *skb);
++u32 __skb_get_hash_symmetric(struct sk_buff *skb);
+ u32 skb_get_poff(const struct sk_buff *skb);
+ u32 __skb_get_poff(const struct sk_buff *skb, void *data,
+ 		   const struct flow_keys *keys, int hlen);
+@@ -2860,6 +2861,25 @@ static inline void skb_postpush_rcsum(struct sk_buff *skb,
+ }
+ 
+ /**
++ *	skb_push_rcsum - push skb and update receive checksum
++ *	@skb: buffer to update
++ *	@len: length of data pulled
++ *
++ *	This function performs an skb_push on the packet and updates
++ *	the CHECKSUM_COMPLETE checksum.  It should be used on
++ *	receive path processing instead of skb_push unless you know
++ *	that the checksum difference is zero (e.g., a valid IP header)
++ *	or you are setting ip_summed to CHECKSUM_NONE.
++ */
++static inline unsigned char *skb_push_rcsum(struct sk_buff *skb,
++					    unsigned int len)
++{
++	skb_push(skb, len);
++	skb_postpush_rcsum(skb, skb->data, len);
++	return skb->data;
++}
++
++/**
+  *	pskb_trim_rcsum - trim received skb and update checksum
+  *	@skb: buffer to trim
+  *	@len: new length
+diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
+index 9a7ddbaf116e..14d70f59f0c2 100644
+--- a/include/linux/sunrpc/clnt.h
++++ b/include/linux/sunrpc/clnt.h
+@@ -137,8 +137,6 @@ struct rpc_create_args {
+ #define RPC_CLNT_CREATE_NO_RETRANS_TIMEOUT	(1UL << 9)
+ 
+ struct rpc_clnt *rpc_create(struct rpc_create_args *args);
+-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+-					struct rpc_xprt *xprt);
+ struct rpc_clnt	*rpc_bind_new_program(struct rpc_clnt *,
+ 				const struct rpc_program *, u32);
+ struct rpc_clnt *rpc_clone_client(struct rpc_clnt *);
+diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h
+index b7dabc4baafd..79ba50856707 100644
+--- a/include/linux/sunrpc/svc_xprt.h
++++ b/include/linux/sunrpc/svc_xprt.h
+@@ -84,6 +84,7 @@ struct svc_xprt {
+ 
+ 	struct net		*xpt_net;
+ 	struct rpc_xprt		*xpt_bc_xprt;	/* NFSv4.1 backchannel */
++	struct rpc_xprt_switch	*xpt_bc_xps;	/* NFSv4.1 backchannel */
+ };
+ 
+ static inline void unregister_xpt_user(struct svc_xprt *xpt, struct svc_xpt_user *u)
+diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
+index fb0d212e0d3a..9f51e1df3023 100644
+--- a/include/linux/sunrpc/xprt.h
++++ b/include/linux/sunrpc/xprt.h
+@@ -296,6 +296,7 @@ struct xprt_create {
+ 	size_t			addrlen;
+ 	const char		*servername;
+ 	struct svc_xprt		*bc_xprt;	/* NFSv4.1 backchannel */
++	struct rpc_xprt_switch	*bc_xps;
+ 	unsigned int		flags;
+ };
+ 
+diff --git a/include/linux/usb/ehci_def.h b/include/linux/usb/ehci_def.h
+index 966889a20ea3..e479033bd782 100644
+--- a/include/linux/usb/ehci_def.h
++++ b/include/linux/usb/ehci_def.h
+@@ -180,11 +180,11 @@ struct ehci_regs {
+  * PORTSCx
+  */
+ 	/* HOSTPC: offset 0x84 */
+-	u32		hostpc[1];	/* HOSTPC extension */
++	u32		hostpc[0];	/* HOSTPC extension */
+ #define HOSTPC_PHCD	(1<<22)		/* Phy clock disable */
+ #define HOSTPC_PSPD	(3<<25)		/* Port speed detection */
+ 
+-	u32		reserved5[16];
++	u32		reserved5[17];
+ 
+ 	/* USBMODE_EX: offset 0xc8 */
+ 	u32		usbmode_ex;	/* USB Device mode extension */
+diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
+index fb2cef4e9747..b8334a637095 100644
+--- a/include/rdma/ib_verbs.h
++++ b/include/rdma/ib_verbs.h
+@@ -217,7 +217,7 @@ enum ib_device_cap_flags {
+ 	IB_DEVICE_CROSS_CHANNEL		= (1 << 27),
+ 	IB_DEVICE_MANAGED_FLOW_STEERING		= (1 << 29),
+ 	IB_DEVICE_SIGNATURE_HANDOVER		= (1 << 30),
+-	IB_DEVICE_ON_DEMAND_PAGING		= (1 << 31),
++	IB_DEVICE_ON_DEMAND_PAGING		= (1ULL << 31),
+ 	IB_DEVICE_SG_GAPS_REG			= (1ULL << 32),
+ 	IB_DEVICE_VIRTUAL_FUNCTION		= ((u64)1 << 33),
+ };
+diff --git a/include/rdma/rdma_vt.h b/include/rdma/rdma_vt.h
+index a8696551abb1..6ee9d97004d5 100644
+--- a/include/rdma/rdma_vt.h
++++ b/include/rdma/rdma_vt.h
+@@ -203,7 +203,9 @@ struct rvt_driver_provided {
+ 
+ 	/*
+ 	 * Allocate a private queue pair data structure for driver specific
+-	 * information which is opaque to rdmavt.
++	 * information which is opaque to rdmavt.  Errors are returned via
++	 * ERR_PTR(err).  The driver is free to return NULL or a valid
++	 * pointer.
+ 	 */
+ 	void * (*qp_priv_alloc)(struct rvt_dev_info *rdi, struct rvt_qp *qp,
+ 				gfp_t gfp);
+diff --git a/kernel/futex.c b/kernel/futex.c
+index c20f06f38ef3..6555d5459e98 100644
+--- a/kernel/futex.c
++++ b/kernel/futex.c
+@@ -469,7 +469,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
+ {
+ 	unsigned long address = (unsigned long)uaddr;
+ 	struct mm_struct *mm = current->mm;
+-	struct page *page;
++	struct page *page, *tail;
+ 	struct address_space *mapping;
+ 	int err, ro = 0;
+ 
+@@ -530,7 +530,15 @@ again:
+ 	 * considered here and page lock forces unnecessarily serialization
+ 	 * From this point on, mapping will be re-verified if necessary and
+ 	 * page lock will be acquired only if it is unavoidable
+-	 */
++	 *
++	 * Mapping checks require the head page for any compound page so the
++	 * head page and mapping is looked up now. For anonymous pages, it
++	 * does not matter if the page splits in the future as the key is
++	 * based on the address. For filesystem-backed pages, the tail is
++	 * required as the index of the page determines the key. For
++	 * base pages, there is no tail page and tail == page.
++	 */
++	tail = page;
+ 	page = compound_head(page);
+ 	mapping = READ_ONCE(page->mapping);
+ 
+@@ -654,7 +662,7 @@ again:
+ 
+ 		key->both.offset |= FUT_OFF_INODE; /* inode-based key */
+ 		key->shared.inode = inode;
+-		key->shared.pgoff = basepage_index(page);
++		key->shared.pgoff = basepage_index(tail);
+ 		rcu_read_unlock();
+ 	}
+ 
+diff --git a/kernel/jump_label.c b/kernel/jump_label.c
+index 05254eeb4b4e..4b353e0be121 100644
+--- a/kernel/jump_label.c
++++ b/kernel/jump_label.c
+@@ -58,13 +58,36 @@ static void jump_label_update(struct static_key *key);
+ 
+ void static_key_slow_inc(struct static_key *key)
+ {
++	int v, v1;
++
+ 	STATIC_KEY_CHECK_USE();
+-	if (atomic_inc_not_zero(&key->enabled))
+-		return;
++
++	/*
++	 * Careful if we get concurrent static_key_slow_inc() calls;
++	 * later calls must wait for the first one to _finish_ the
++	 * jump_label_update() process.  At the same time, however,
++	 * the jump_label_update() call below wants to see
++	 * static_key_enabled(&key) for jumps to be updated properly.
++	 *
++	 * So give a special meaning to negative key->enabled: it sends
++	 * static_key_slow_inc() down the slow path, and it is non-zero
++	 * so it counts as "enabled" in jump_label_update().  Note that
++	 * atomic_inc_unless_negative() checks >= 0, so roll our own.
++	 */
++	for (v = atomic_read(&key->enabled); v > 0; v = v1) {
++		v1 = atomic_cmpxchg(&key->enabled, v, v + 1);
++		if (likely(v1 == v))
++			return;
++	}
+ 
+ 	jump_label_lock();
+-	if (atomic_inc_return(&key->enabled) == 1)
++	if (atomic_read(&key->enabled) == 0) {
++		atomic_set(&key->enabled, -1);
+ 		jump_label_update(key);
++		atomic_set(&key->enabled, 1);
++	} else {
++		atomic_inc(&key->enabled);
++	}
+ 	jump_label_unlock();
+ }
+ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+@@ -72,6 +95,13 @@ EXPORT_SYMBOL_GPL(static_key_slow_inc);
+ static void __static_key_slow_dec(struct static_key *key,
+ 		unsigned long rate_limit, struct delayed_work *work)
+ {
++	/*
++	 * The negative count check is valid even when a negative
++	 * key->enabled is in use by static_key_slow_inc(); a
++	 * __static_key_slow_dec() before the first static_key_slow_inc()
++	 * returns is unbalanced, because all other static_key_slow_inc()
++	 * instances block while the update is in progress.
++	 */
+ 	if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) {
+ 		WARN(atomic_read(&key->enabled) < 0,
+ 		     "jump label: negative count!\n");
+diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c
+index e364b424b019..79d2d765a75f 100644
+--- a/kernel/locking/mutex.c
++++ b/kernel/locking/mutex.c
+@@ -486,9 +486,6 @@ __ww_mutex_lock_check_stamp(struct mutex *lock, struct ww_acquire_ctx *ctx)
+ 	if (!hold_ctx)
+ 		return 0;
+ 
+-	if (unlikely(ctx == hold_ctx))
+-		return -EALREADY;
+-
+ 	if (ctx->stamp - hold_ctx->stamp <= LONG_MAX &&
+ 	    (ctx->stamp != hold_ctx->stamp || ctx > hold_ctx)) {
+ #ifdef CONFIG_DEBUG_MUTEXES
+@@ -514,6 +511,12 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
+ 	unsigned long flags;
+ 	int ret;
+ 
++	if (use_ww_ctx) {
++		struct ww_mutex *ww = container_of(lock, struct ww_mutex, base);
++		if (unlikely(ww_ctx == READ_ONCE(ww->ctx)))
++			return -EALREADY;
++	}
++
+ 	preempt_disable();
+ 	mutex_acquire_nest(&lock->dep_map, subclass, 0, nest_lock, ip);
+ 
+diff --git a/kernel/locking/qspinlock.c b/kernel/locking/qspinlock.c
+index ce2f75e32ae1..5fc8c311b8fe 100644
+--- a/kernel/locking/qspinlock.c
++++ b/kernel/locking/qspinlock.c
+@@ -267,6 +267,66 @@ static __always_inline u32  __pv_wait_head_or_lock(struct qspinlock *lock,
+ #define queued_spin_lock_slowpath	native_queued_spin_lock_slowpath
+ #endif
+ 
++/*
++ * queued_spin_lock_slowpath() can (load-)ACQUIRE the lock before
++ * issuing an _unordered_ store to set _Q_LOCKED_VAL.
++ *
++ * This means that the store can be delayed, but no later than the
++ * store-release from the unlock. This means that simply observing
++ * _Q_LOCKED_VAL is not sufficient to determine if the lock is acquired.
++ *
++ * There are two paths that can issue the unordered store:
++ *
++ *  (1) clear_pending_set_locked():	*,1,0 -> *,0,1
++ *
++ *  (2) set_locked():			t,0,0 -> t,0,1 ; t != 0
++ *      atomic_cmpxchg_relaxed():	t,0,0 -> 0,0,1
++ *
++ * However, in both cases we have other !0 state we've set before to queue
++ * ourseves:
++ *
++ * For (1) we have the atomic_cmpxchg_acquire() that set _Q_PENDING_VAL, our
++ * load is constrained by that ACQUIRE to not pass before that, and thus must
++ * observe the store.
++ *
++ * For (2) we have a more intersting scenario. We enqueue ourselves using
++ * xchg_tail(), which ends up being a RELEASE. This in itself is not
++ * sufficient, however that is followed by an smp_cond_acquire() on the same
++ * word, giving a RELEASE->ACQUIRE ordering. This again constrains our load and
++ * guarantees we must observe that store.
++ *
++ * Therefore both cases have other !0 state that is observable before the
++ * unordered locked byte store comes through. This means we can use that to
++ * wait for the lock store, and then wait for an unlock.
++ */
++#ifndef queued_spin_unlock_wait
++void queued_spin_unlock_wait(struct qspinlock *lock)
++{
++	u32 val;
++
++	for (;;) {
++		val = atomic_read(&lock->val);
++
++		if (!val) /* not locked, we're done */
++			goto done;
++
++		if (val & _Q_LOCKED_MASK) /* locked, go wait for unlock */
++			break;
++
++		/* not locked, but pending, wait until we observe the lock */
++		cpu_relax();
++	}
++
++	/* any unlock is good */
++	while (atomic_read(&lock->val) & _Q_LOCKED_MASK)
++		cpu_relax();
++
++done:
++	smp_rmb(); /* CTRL + RMB -> ACQUIRE */
++}
++EXPORT_SYMBOL(queued_spin_unlock_wait);
++#endif
++
+ #endif /* _GEN_PV_LOCK_SLOWPATH */
+ 
+ /**
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index e7dd0ec169be..eeaf920f46b9 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -2821,6 +2821,23 @@ static inline void update_tg_load_avg(struct cfs_rq *cfs_rq, int force) {}
+ 
+ static inline u64 cfs_rq_clock_task(struct cfs_rq *cfs_rq);
+ 
++/*
++ * Unsigned subtract and clamp on underflow.
++ *
++ * Explicitly do a load-store to ensure the intermediate value never hits
++ * memory. This allows lockless observations without ever seeing the negative
++ * values.
++ */
++#define sub_positive(_ptr, _val) do {				\
++	typeof(_ptr) ptr = (_ptr);				\
++	typeof(*ptr) val = (_val);				\
++	typeof(*ptr) res, var = READ_ONCE(*ptr);		\
++	res = var - val;					\
++	if (res > var)						\
++		res = 0;					\
++	WRITE_ONCE(*ptr, res);					\
++} while (0)
++
+ /* Group cfs_rq's load_avg is used for task_h_load and update_cfs_share */
+ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
+ {
+@@ -2829,15 +2846,15 @@ static inline int update_cfs_rq_load_avg(u64 now, struct cfs_rq *cfs_rq)
+ 
+ 	if (atomic_long_read(&cfs_rq->removed_load_avg)) {
+ 		s64 r = atomic_long_xchg(&cfs_rq->removed_load_avg, 0);
+-		sa->load_avg = max_t(long, sa->load_avg - r, 0);
+-		sa->load_sum = max_t(s64, sa->load_sum - r * LOAD_AVG_MAX, 0);
++		sub_positive(&sa->load_avg, r);
++		sub_positive(&sa->load_sum, r * LOAD_AVG_MAX);
+ 		removed = 1;
+ 	}
+ 
+ 	if (atomic_long_read(&cfs_rq->removed_util_avg)) {
+ 		long r = atomic_long_xchg(&cfs_rq->removed_util_avg, 0);
+-		sa->util_avg = max_t(long, sa->util_avg - r, 0);
+-		sa->util_sum = max_t(s32, sa->util_sum - r * LOAD_AVG_MAX, 0);
++		sub_positive(&sa->util_avg, r);
++		sub_positive(&sa->util_sum, r * LOAD_AVG_MAX);
+ 	}
+ 
+ 	decayed = __update_load_avg(now, cpu_of(rq_of(cfs_rq)), sa,
+@@ -2927,10 +2944,10 @@ static void detach_entity_load_avg(struct cfs_rq *cfs_rq, struct sched_entity *s
+ 			  &se->avg, se->on_rq * scale_load_down(se->load.weight),
+ 			  cfs_rq->curr == se, NULL);
+ 
+-	cfs_rq->avg.load_avg = max_t(long, cfs_rq->avg.load_avg - se->avg.load_avg, 0);
+-	cfs_rq->avg.load_sum = max_t(s64,  cfs_rq->avg.load_sum - se->avg.load_sum, 0);
+-	cfs_rq->avg.util_avg = max_t(long, cfs_rq->avg.util_avg - se->avg.util_avg, 0);
+-	cfs_rq->avg.util_sum = max_t(s32,  cfs_rq->avg.util_sum - se->avg.util_sum, 0);
++	sub_positive(&cfs_rq->avg.load_avg, se->avg.load_avg);
++	sub_positive(&cfs_rq->avg.load_sum, se->avg.load_sum);
++	sub_positive(&cfs_rq->avg.util_avg, se->avg.util_avg);
++	sub_positive(&cfs_rq->avg.util_sum, se->avg.util_sum);
+ }
+ 
+ /* Add the load generated by se into cfs_rq's load average */
+diff --git a/kernel/sched/idle.c b/kernel/sched/idle.c
+index bd12c6c714ec..c5aeedf4e93a 100644
+--- a/kernel/sched/idle.c
++++ b/kernel/sched/idle.c
+@@ -127,7 +127,7 @@ static int call_cpuidle(struct cpuidle_driver *drv, struct cpuidle_device *dev,
+  */
+ static void cpuidle_idle_call(void)
+ {
+-	struct cpuidle_device *dev = __this_cpu_read(cpuidle_devices);
++	struct cpuidle_device *dev = cpuidle_get_device();
+ 	struct cpuidle_driver *drv = cpuidle_get_cpu_driver(dev);
+ 	int next_state, entered_state;
+ 
+diff --git a/kernel/trace/trace_printk.c b/kernel/trace/trace_printk.c
+index f96f0383f6c6..ad1d6164e946 100644
+--- a/kernel/trace/trace_printk.c
++++ b/kernel/trace/trace_printk.c
+@@ -36,6 +36,10 @@ struct trace_bprintk_fmt {
+ static inline struct trace_bprintk_fmt *lookup_format(const char *fmt)
+ {
+ 	struct trace_bprintk_fmt *pos;
++
++	if (!fmt)
++		return ERR_PTR(-EINVAL);
++
+ 	list_for_each_entry(pos, &trace_bprintk_fmt_list, list) {
+ 		if (!strcmp(pos->fmt, fmt))
+ 			return pos;
+@@ -57,7 +61,8 @@ void hold_module_trace_bprintk_format(const char **start, const char **end)
+ 	for (iter = start; iter < end; iter++) {
+ 		struct trace_bprintk_fmt *tb_fmt = lookup_format(*iter);
+ 		if (tb_fmt) {
+-			*iter = tb_fmt->fmt;
++			if (!IS_ERR(tb_fmt))
++				*iter = tb_fmt->fmt;
+ 			continue;
+ 		}
+ 
+diff --git a/mm/migrate.c b/mm/migrate.c
+index f9dfb18a4eba..bdf3410bb4fa 100644
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -431,6 +431,7 @@ int migrate_page_move_mapping(struct address_space *mapping,
+ 
+ 	return MIGRATEPAGE_SUCCESS;
+ }
++EXPORT_SYMBOL(migrate_page_move_mapping);
+ 
+ /*
+  * The expected number of remaining references is the same as that
+@@ -586,6 +587,7 @@ void migrate_page_copy(struct page *newpage, struct page *page)
+ 
+ 	mem_cgroup_migrate(page, newpage);
+ }
++EXPORT_SYMBOL(migrate_page_copy);
+ 
+ /************************************************************
+  *                    Migration functions
+diff --git a/mm/page-writeback.c b/mm/page-writeback.c
+index bc5149d5ec38..e389f0a998f1 100644
+--- a/mm/page-writeback.c
++++ b/mm/page-writeback.c
+@@ -369,8 +369,9 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
+ 	struct dirty_throttle_control *gdtc = mdtc_gdtc(dtc);
+ 	unsigned long bytes = vm_dirty_bytes;
+ 	unsigned long bg_bytes = dirty_background_bytes;
+-	unsigned long ratio = vm_dirty_ratio;
+-	unsigned long bg_ratio = dirty_background_ratio;
++	/* convert ratios to per-PAGE_SIZE for higher precision */
++	unsigned long ratio = (vm_dirty_ratio * PAGE_SIZE) / 100;
++	unsigned long bg_ratio = (dirty_background_ratio * PAGE_SIZE) / 100;
+ 	unsigned long thresh;
+ 	unsigned long bg_thresh;
+ 	struct task_struct *tsk;
+@@ -382,26 +383,28 @@ static void domain_dirty_limits(struct dirty_throttle_control *dtc)
+ 		/*
+ 		 * The byte settings can't be applied directly to memcg
+ 		 * domains.  Convert them to ratios by scaling against
+-		 * globally available memory.
++		 * globally available memory.  As the ratios are in
++		 * per-PAGE_SIZE, they can be obtained by dividing bytes by
++		 * number of pages.
+ 		 */
+ 		if (bytes)
+-			ratio = min(DIV_ROUND_UP(bytes, PAGE_SIZE) * 100 /
+-				    global_avail, 100UL);
++			ratio = min(DIV_ROUND_UP(bytes, global_avail),
++				    PAGE_SIZE);
+ 		if (bg_bytes)
+-			bg_ratio = min(DIV_ROUND_UP(bg_bytes, PAGE_SIZE) * 100 /
+-				       global_avail, 100UL);
++			bg_ratio = min(DIV_ROUND_UP(bg_bytes, global_avail),
++				       PAGE_SIZE);
+ 		bytes = bg_bytes = 0;
+ 	}
+ 
+ 	if (bytes)
+ 		thresh = DIV_ROUND_UP(bytes, PAGE_SIZE);
+ 	else
+-		thresh = (ratio * available_memory) / 100;
++		thresh = (ratio * available_memory) / PAGE_SIZE;
+ 
+ 	if (bg_bytes)
+ 		bg_thresh = DIV_ROUND_UP(bg_bytes, PAGE_SIZE);
+ 	else
+-		bg_thresh = (bg_ratio * available_memory) / 100;
++		bg_thresh = (bg_ratio * available_memory) / PAGE_SIZE;
+ 
+ 	if (bg_thresh >= thresh)
+ 		bg_thresh = thresh / 2;
+diff --git a/mm/percpu.c b/mm/percpu.c
+index 0c59684f1ff2..9903830aaebb 100644
+--- a/mm/percpu.c
++++ b/mm/percpu.c
+@@ -112,7 +112,7 @@ struct pcpu_chunk {
+ 	int			map_used;	/* # of map entries used before the sentry */
+ 	int			map_alloc;	/* # of map entries allocated */
+ 	int			*map;		/* allocation map */
+-	struct work_struct	map_extend_work;/* async ->map[] extension */
++	struct list_head	map_extend_list;/* on pcpu_map_extend_chunks */
+ 
+ 	void			*data;		/* chunk data */
+ 	int			first_free;	/* no free below this */
+@@ -162,10 +162,13 @@ static struct pcpu_chunk *pcpu_reserved_chunk;
+ static int pcpu_reserved_chunk_limit;
+ 
+ static DEFINE_SPINLOCK(pcpu_lock);	/* all internal data structures */
+-static DEFINE_MUTEX(pcpu_alloc_mutex);	/* chunk create/destroy, [de]pop */
++static DEFINE_MUTEX(pcpu_alloc_mutex);	/* chunk create/destroy, [de]pop, map ext */
+ 
+ static struct list_head *pcpu_slot __read_mostly; /* chunk list slots */
+ 
++/* chunks which need their map areas extended, protected by pcpu_lock */
++static LIST_HEAD(pcpu_map_extend_chunks);
++
+ /*
+  * The number of empty populated pages, protected by pcpu_lock.  The
+  * reserved chunk doesn't contribute to the count.
+@@ -395,13 +398,19 @@ static int pcpu_need_to_extend(struct pcpu_chunk *chunk, bool is_atomic)
+ {
+ 	int margin, new_alloc;
+ 
++	lockdep_assert_held(&pcpu_lock);
++
+ 	if (is_atomic) {
+ 		margin = 3;
+ 
+ 		if (chunk->map_alloc <
+-		    chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW &&
+-		    pcpu_async_enabled)
+-			schedule_work(&chunk->map_extend_work);
++		    chunk->map_used + PCPU_ATOMIC_MAP_MARGIN_LOW) {
++			if (list_empty(&chunk->map_extend_list)) {
++				list_add_tail(&chunk->map_extend_list,
++					      &pcpu_map_extend_chunks);
++				pcpu_schedule_balance_work();
++			}
++		}
+ 	} else {
+ 		margin = PCPU_ATOMIC_MAP_MARGIN_HIGH;
+ 	}
+@@ -435,6 +444,8 @@ static int pcpu_extend_area_map(struct pcpu_chunk *chunk, int new_alloc)
+ 	size_t old_size = 0, new_size = new_alloc * sizeof(new[0]);
+ 	unsigned long flags;
+ 
++	lockdep_assert_held(&pcpu_alloc_mutex);
++
+ 	new = pcpu_mem_zalloc(new_size);
+ 	if (!new)
+ 		return -ENOMEM;
+@@ -467,20 +478,6 @@ out_unlock:
+ 	return 0;
+ }
+ 
+-static void pcpu_map_extend_workfn(struct work_struct *work)
+-{
+-	struct pcpu_chunk *chunk = container_of(work, struct pcpu_chunk,
+-						map_extend_work);
+-	int new_alloc;
+-
+-	spin_lock_irq(&pcpu_lock);
+-	new_alloc = pcpu_need_to_extend(chunk, false);
+-	spin_unlock_irq(&pcpu_lock);
+-
+-	if (new_alloc)
+-		pcpu_extend_area_map(chunk, new_alloc);
+-}
+-
+ /**
+  * pcpu_fit_in_area - try to fit the requested allocation in a candidate area
+  * @chunk: chunk the candidate area belongs to
+@@ -740,7 +737,7 @@ static struct pcpu_chunk *pcpu_alloc_chunk(void)
+ 	chunk->map_used = 1;
+ 
+ 	INIT_LIST_HEAD(&chunk->list);
+-	INIT_WORK(&chunk->map_extend_work, pcpu_map_extend_workfn);
++	INIT_LIST_HEAD(&chunk->map_extend_list);
+ 	chunk->free_size = pcpu_unit_size;
+ 	chunk->contig_hint = pcpu_unit_size;
+ 
+@@ -895,6 +892,9 @@ static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved,
+ 		return NULL;
+ 	}
+ 
++	if (!is_atomic)
++		mutex_lock(&pcpu_alloc_mutex);
++
+ 	spin_lock_irqsave(&pcpu_lock, flags);
+ 
+ 	/* serve reserved allocations from the reserved chunk if available */
+@@ -967,12 +967,9 @@ restart:
+ 	if (is_atomic)
+ 		goto fail;
+ 
+-	mutex_lock(&pcpu_alloc_mutex);
+-
+ 	if (list_empty(&pcpu_slot[pcpu_nr_slots - 1])) {
+ 		chunk = pcpu_create_chunk();
+ 		if (!chunk) {
+-			mutex_unlock(&pcpu_alloc_mutex);
+ 			err = "failed to allocate new chunk";
+ 			goto fail;
+ 		}
+@@ -983,7 +980,6 @@ restart:
+ 		spin_lock_irqsave(&pcpu_lock, flags);
+ 	}
+ 
+-	mutex_unlock(&pcpu_alloc_mutex);
+ 	goto restart;
+ 
+ area_found:
+@@ -993,8 +989,6 @@ area_found:
+ 	if (!is_atomic) {
+ 		int page_start, page_end, rs, re;
+ 
+-		mutex_lock(&pcpu_alloc_mutex);
+-
+ 		page_start = PFN_DOWN(off);
+ 		page_end = PFN_UP(off + size);
+ 
+@@ -1005,7 +999,6 @@ area_found:
+ 
+ 			spin_lock_irqsave(&pcpu_lock, flags);
+ 			if (ret) {
+-				mutex_unlock(&pcpu_alloc_mutex);
+ 				pcpu_free_area(chunk, off, &occ_pages);
+ 				err = "failed to populate";
+ 				goto fail_unlock;
+@@ -1045,6 +1038,8 @@ fail:
+ 		/* see the flag handling in pcpu_blance_workfn() */
+ 		pcpu_atomic_alloc_failed = true;
+ 		pcpu_schedule_balance_work();
++	} else {
++		mutex_unlock(&pcpu_alloc_mutex);
+ 	}
+ 	return NULL;
+ }
+@@ -1129,6 +1124,7 @@ static void pcpu_balance_workfn(struct work_struct *work)
+ 		if (chunk == list_first_entry(free_head, struct pcpu_chunk, list))
+ 			continue;
+ 
++		list_del_init(&chunk->map_extend_list);
+ 		list_move(&chunk->list, &to_free);
+ 	}
+ 
+@@ -1146,6 +1142,25 @@ static void pcpu_balance_workfn(struct work_struct *work)
+ 		pcpu_destroy_chunk(chunk);
+ 	}
+ 
++	/* service chunks which requested async area map extension */
++	do {
++		int new_alloc = 0;
++
++		spin_lock_irq(&pcpu_lock);
++
++		chunk = list_first_entry_or_null(&pcpu_map_extend_chunks,
++					struct pcpu_chunk, map_extend_list);
++		if (chunk) {
++			list_del_init(&chunk->map_extend_list);
++			new_alloc = pcpu_need_to_extend(chunk, false);
++		}
++
++		spin_unlock_irq(&pcpu_lock);
++
++		if (new_alloc)
++			pcpu_extend_area_map(chunk, new_alloc);
++	} while (chunk);
++
+ 	/*
+ 	 * Ensure there are certain number of free populated pages for
+ 	 * atomic allocs.  Fill up from the most packed so that atomic
+@@ -1644,7 +1659,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
+ 	 */
+ 	schunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
+ 	INIT_LIST_HEAD(&schunk->list);
+-	INIT_WORK(&schunk->map_extend_work, pcpu_map_extend_workfn);
++	INIT_LIST_HEAD(&schunk->map_extend_list);
+ 	schunk->base_addr = base_addr;
+ 	schunk->map = smap;
+ 	schunk->map_alloc = ARRAY_SIZE(smap);
+@@ -1673,7 +1688,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai,
+ 	if (dyn_size) {
+ 		dchunk = memblock_virt_alloc(pcpu_chunk_struct_size, 0);
+ 		INIT_LIST_HEAD(&dchunk->list);
+-		INIT_WORK(&dchunk->map_extend_work, pcpu_map_extend_workfn);
++		INIT_LIST_HEAD(&dchunk->map_extend_list);
+ 		dchunk->base_addr = base_addr;
+ 		dchunk->map = dmap;
+ 		dchunk->map_alloc = ARRAY_SIZE(dmap);
+diff --git a/mm/shmem.c b/mm/shmem.c
+index 719bd6b88d98..9ca09f52fef5 100644
+--- a/mm/shmem.c
++++ b/mm/shmem.c
+@@ -2236,9 +2236,11 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset,
+ 									NULL);
+ 		if (error) {
+ 			/* Remove the !PageUptodate pages we added */
+-			shmem_undo_range(inode,
+-				(loff_t)start << PAGE_SHIFT,
+-				(loff_t)index << PAGE_SHIFT, true);
++			if (index > start) {
++				shmem_undo_range(inode,
++				    (loff_t)start << PAGE_SHIFT,
++				    ((loff_t)index << PAGE_SHIFT) - 1, true);
++			}
+ 			goto undone;
+ 		}
+ 
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index a669dea146c6..61ad43f61c5e 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -651,6 +651,23 @@ void make_flow_keys_digest(struct flow_keys_digest *digest,
+ }
+ EXPORT_SYMBOL(make_flow_keys_digest);
+ 
++static struct flow_dissector flow_keys_dissector_symmetric __read_mostly;
++
++u32 __skb_get_hash_symmetric(struct sk_buff *skb)
++{
++	struct flow_keys keys;
++
++	__flow_hash_secret_init();
++
++	memset(&keys, 0, sizeof(keys));
++	__skb_flow_dissect(skb, &flow_keys_dissector_symmetric, &keys,
++			   NULL, 0, 0, 0,
++			   FLOW_DISSECTOR_F_STOP_AT_FLOW_LABEL);
++
++	return __flow_hash_from_keys(&keys, hashrnd);
++}
++EXPORT_SYMBOL_GPL(__skb_get_hash_symmetric);
++
+ /**
+  * __skb_get_hash: calculate a flow hash
+  * @skb: sk_buff to calculate flow hash from
+@@ -868,6 +885,29 @@ static const struct flow_dissector_key flow_keys_dissector_keys[] = {
+ 	},
+ };
+ 
++static const struct flow_dissector_key flow_keys_dissector_symmetric_keys[] = {
++	{
++		.key_id = FLOW_DISSECTOR_KEY_CONTROL,
++		.offset = offsetof(struct flow_keys, control),
++	},
++	{
++		.key_id = FLOW_DISSECTOR_KEY_BASIC,
++		.offset = offsetof(struct flow_keys, basic),
++	},
++	{
++		.key_id = FLOW_DISSECTOR_KEY_IPV4_ADDRS,
++		.offset = offsetof(struct flow_keys, addrs.v4addrs),
++	},
++	{
++		.key_id = FLOW_DISSECTOR_KEY_IPV6_ADDRS,
++		.offset = offsetof(struct flow_keys, addrs.v6addrs),
++	},
++	{
++		.key_id = FLOW_DISSECTOR_KEY_PORTS,
++		.offset = offsetof(struct flow_keys, ports),
++	},
++};
++
+ static const struct flow_dissector_key flow_keys_buf_dissector_keys[] = {
+ 	{
+ 		.key_id = FLOW_DISSECTOR_KEY_CONTROL,
+@@ -889,6 +929,9 @@ static int __init init_default_flow_dissectors(void)
+ 	skb_flow_dissector_init(&flow_keys_dissector,
+ 				flow_keys_dissector_keys,
+ 				ARRAY_SIZE(flow_keys_dissector_keys));
++	skb_flow_dissector_init(&flow_keys_dissector_symmetric,
++				flow_keys_dissector_symmetric_keys,
++				ARRAY_SIZE(flow_keys_dissector_symmetric_keys));
+ 	skb_flow_dissector_init(&flow_keys_buf_dissector,
+ 				flow_keys_buf_dissector_keys,
+ 				ARRAY_SIZE(flow_keys_buf_dissector_keys));
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index e561f9f07d6d..59bf4d77154f 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -3016,24 +3016,6 @@ int skb_append_pagefrags(struct sk_buff *skb, struct page *page,
+ EXPORT_SYMBOL_GPL(skb_append_pagefrags);
+ 
+ /**
+- *	skb_push_rcsum - push skb and update receive checksum
+- *	@skb: buffer to update
+- *	@len: length of data pulled
+- *
+- *	This function performs an skb_push on the packet and updates
+- *	the CHECKSUM_COMPLETE checksum.  It should be used on
+- *	receive path processing instead of skb_push unless you know
+- *	that the checksum difference is zero (e.g., a valid IP header)
+- *	or you are setting ip_summed to CHECKSUM_NONE.
+- */
+-static unsigned char *skb_push_rcsum(struct sk_buff *skb, unsigned len)
+-{
+-	skb_push(skb, len);
+-	skb_postpush_rcsum(skb, skb->data, len);
+-	return skb->data;
+-}
+-
+-/**
+  *	skb_pull_rcsum - pull skb and update receive checksum
+  *	@skb: buffer to update
+  *	@len: length of data pulled
+diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
+index ea071fad67a0..c26fac26b23c 100644
+--- a/net/ipv6/ip6_fib.c
++++ b/net/ipv6/ip6_fib.c
+@@ -177,6 +177,7 @@ static void rt6_free_pcpu(struct rt6_info *non_pcpu_rt)
+ 		}
+ 	}
+ 
++	free_percpu(non_pcpu_rt->rt6i_pcpu);
+ 	non_pcpu_rt->rt6i_pcpu = NULL;
+ }
+ 
+diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
+index d32cefcb63b0..34a5712d467f 100644
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -150,19 +150,26 @@ u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata)
+ void mesh_sta_cleanup(struct sta_info *sta)
+ {
+ 	struct ieee80211_sub_if_data *sdata = sta->sdata;
+-	u32 changed;
++	u32 changed = 0;
+ 
+ 	/*
+ 	 * maybe userspace handles peer allocation and peering, but in either
+ 	 * case the beacon is still generated by the kernel and we might need
+ 	 * an update.
+ 	 */
+-	changed = mesh_accept_plinks_update(sdata);
++	if (sdata->u.mesh.user_mpm &&
++	    sta->mesh->plink_state == NL80211_PLINK_ESTAB)
++		changed |= mesh_plink_dec_estab_count(sdata);
++	changed |= mesh_accept_plinks_update(sdata);
+ 	if (!sdata->u.mesh.user_mpm) {
+ 		changed |= mesh_plink_deactivate(sta);
+ 		del_timer_sync(&sta->mesh->plink_timer);
+ 	}
+ 
++	/* make sure no readers can access nexthop sta from here on */
++	mesh_path_flush_by_nexthop(sta);
++	synchronize_net();
++
+ 	if (changed)
+ 		ieee80211_mbss_info_change_notify(sdata, changed);
+ }
+diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
+index 62193f4bc37b..ba7ce53ec615 100644
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -275,7 +275,7 @@ struct ieee80211_fast_tx {
+ 	u8 sa_offs, da_offs, pn_offs;
+ 	u8 band;
+ 	u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV +
+-	       sizeof(rfc1042_header)];
++	       sizeof(rfc1042_header)] __aligned(2);
+ 
+ 	struct rcu_head rcu_head;
+ };
+diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
+index 18d0becbc46d..8012f67ca5ae 100644
+--- a/net/packet/af_packet.c
++++ b/net/packet/af_packet.c
+@@ -1340,7 +1340,7 @@ static unsigned int fanout_demux_hash(struct packet_fanout *f,
+ 				      struct sk_buff *skb,
+ 				      unsigned int num)
+ {
+-	return reciprocal_scale(skb_get_hash(skb), num);
++	return reciprocal_scale(__skb_get_hash_symmetric(skb), num);
+ }
+ 
+ static unsigned int fanout_demux_lb(struct packet_fanout *f,
+diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c
+index 8f3948dd38b8..934336e12a65 100644
+--- a/net/sched/act_mirred.c
++++ b/net/sched/act_mirred.c
+@@ -180,7 +180,7 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a,
+ 
+ 	if (!(at & AT_EGRESS)) {
+ 		if (m->tcfm_ok_push)
+-			skb_push(skb2, skb->mac_len);
++			skb_push_rcsum(skb2, skb->mac_len);
+ 	}
+ 
+ 	/* mirror is always swallowed */
+diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
+index 7e0c9bf22df8..837dd910a252 100644
+--- a/net/sunrpc/clnt.c
++++ b/net/sunrpc/clnt.c
+@@ -446,16 +446,27 @@ out_no_rpciod:
+ 	return ERR_PTR(err);
+ }
+ 
+-struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
++static struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+ 					struct rpc_xprt *xprt)
+ {
+ 	struct rpc_clnt *clnt = NULL;
+ 	struct rpc_xprt_switch *xps;
+ 
+-	xps = xprt_switch_alloc(xprt, GFP_KERNEL);
+-	if (xps == NULL)
+-		return ERR_PTR(-ENOMEM);
+-
++	if (args->bc_xprt && args->bc_xprt->xpt_bc_xps) {
++		WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP);
++		xps = args->bc_xprt->xpt_bc_xps;
++		xprt_switch_get(xps);
++	} else {
++		xps = xprt_switch_alloc(xprt, GFP_KERNEL);
++		if (xps == NULL) {
++			xprt_put(xprt);
++			return ERR_PTR(-ENOMEM);
++		}
++		if (xprt->bc_xprt) {
++			xprt_switch_get(xps);
++			xprt->bc_xprt->xpt_bc_xps = xps;
++		}
++	}
+ 	clnt = rpc_new_client(args, xps, xprt, NULL);
+ 	if (IS_ERR(clnt))
+ 		return clnt;
+@@ -483,7 +494,6 @@ struct rpc_clnt *rpc_create_xprt(struct rpc_create_args *args,
+ 
+ 	return clnt;
+ }
+-EXPORT_SYMBOL_GPL(rpc_create_xprt);
+ 
+ /**
+  * rpc_create - create an RPC client and transport with one call
+@@ -509,6 +519,15 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
+ 	};
+ 	char servername[48];
+ 
++	if (args->bc_xprt) {
++		WARN_ON(args->protocol != XPRT_TRANSPORT_BC_TCP);
++		xprt = args->bc_xprt->xpt_bc_xprt;
++		if (xprt) {
++			xprt_get(xprt);
++			return rpc_create_xprt(args, xprt);
++		}
++	}
++
+ 	if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS)
+ 		xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS;
+ 	if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT)
+diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c
+index 7422f28818b2..7231cb413a2c 100644
+--- a/net/sunrpc/svc_xprt.c
++++ b/net/sunrpc/svc_xprt.c
+@@ -136,6 +136,8 @@ static void svc_xprt_free(struct kref *kref)
+ 	/* See comment on corresponding get in xs_setup_bc_tcp(): */
+ 	if (xprt->xpt_bc_xprt)
+ 		xprt_put(xprt->xpt_bc_xprt);
++	if (xprt->xpt_bc_xps)
++		xprt_switch_put(xprt->xpt_bc_xps);
+ 	xprt->xpt_ops->xpo_free(xprt);
+ 	module_put(owner);
+ }
+diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c
+index 65e759569e48..e9e5dd0dc8f4 100644
+--- a/net/sunrpc/xprtsock.c
++++ b/net/sunrpc/xprtsock.c
+@@ -3050,6 +3050,7 @@ static struct rpc_xprt *xs_setup_bc_tcp(struct xprt_create *args)
+ 		return xprt;
+ 
+ 	args->bc_xprt->xpt_bc_xprt = NULL;
++	args->bc_xprt->xpt_bc_xps = NULL;
+ 	xprt_put(xprt);
+ 	ret = ERR_PTR(-EINVAL);
+ out_err:
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index 8269da73e9e5..7748199b3568 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -315,7 +315,7 @@ static struct sock *unix_find_socket_byinode(struct inode *i)
+ 		    &unix_socket_table[i->i_ino & (UNIX_HASH_SIZE - 1)]) {
+ 		struct dentry *dentry = unix_sk(s)->path.dentry;
+ 
+-		if (dentry && d_backing_inode(dentry) == i) {
++		if (dentry && d_real_inode(dentry) == i) {
+ 			sock_hold(s);
+ 			goto found;
+ 		}
+@@ -911,7 +911,7 @@ static struct sock *unix_find_other(struct net *net,
+ 		err = kern_path(sunname->sun_path, LOOKUP_FOLLOW, &path);
+ 		if (err)
+ 			goto fail;
+-		inode = d_backing_inode(path.dentry);
++		inode = d_real_inode(path.dentry);
+ 		err = inode_permission(inode, MAY_WRITE);
+ 		if (err)
+ 			goto put_fail;
+@@ -1048,7 +1048,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+ 			goto out_up;
+ 		}
+ 		addr->hash = UNIX_HASH_SIZE;
+-		hash = d_backing_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
++		hash = d_real_inode(dentry)->i_ino & (UNIX_HASH_SIZE - 1);
+ 		spin_lock(&unix_table_lock);
+ 		u->path = u_path;
+ 		list = &unix_socket_table[hash];
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 9f1c4aa851ef..c878045d146a 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -360,8 +360,6 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv,
+ 	WARN_ON(ops->remain_on_channel && !ops->cancel_remain_on_channel);
+ 	WARN_ON(ops->tdls_channel_switch && !ops->tdls_cancel_channel_switch);
+ 	WARN_ON(ops->add_tx_ts && !ops->del_tx_ts);
+-	WARN_ON(ops->set_tx_power && !ops->get_tx_power);
+-	WARN_ON(ops->set_antenna && !ops->get_antenna);
+ 
+ 	alloc_size = sizeof(*rdev) + sizeof_priv;
+ 
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 9f440a9de63b..47b917841623 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -509,7 +509,7 @@ static int __ieee80211_data_to_8023(struct sk_buff *skb, struct ethhdr *ehdr,
+ 		 * replace EtherType */
+ 		hdrlen += ETH_ALEN + 2;
+ 	else
+-		tmp.h_proto = htons(skb->len);
++		tmp.h_proto = htons(skb->len - hdrlen);
+ 
+ 	pskb_pull(skb, hdrlen);
+ 
+diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
+index a9155077feef..fec75786f75b 100644
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -384,7 +384,7 @@ static void do_of_entry_multi(void *symval, struct module *mod)
+ 	len = sprintf(alias, "of:N%sT%s", (*name)[0] ? *name : "*",
+ 		      (*type)[0] ? *type : "*");
+ 
+-	if (compatible[0])
++	if ((*compatible)[0])
+ 		sprintf(&alias[len], "%sC%s", (*type)[0] ? "*" : "",
+ 			*compatible);
+ 
+diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
+index dec607c17b64..5ee820111027 100644
+--- a/security/apparmor/lsm.c
++++ b/security/apparmor/lsm.c
+@@ -523,34 +523,34 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
+ {
+ 	struct common_audit_data sa;
+ 	struct apparmor_audit_data aad = {0,};
+-	char *command, *args = value;
++	char *command, *largs = NULL, *args = value;
+ 	size_t arg_size;
+ 	int error;
+ 
+ 	if (size == 0)
+ 		return -EINVAL;
+-	/* args points to a PAGE_SIZE buffer, AppArmor requires that
+-	 * the buffer must be null terminated or have size <= PAGE_SIZE -1
+-	 * so that AppArmor can null terminate them
+-	 */
+-	if (args[size - 1] != '\0') {
+-		if (size == PAGE_SIZE)
+-			return -EINVAL;
+-		args[size] = '\0';
+-	}
+-
+ 	/* task can only write its own attributes */
+ 	if (current != task)
+ 		return -EACCES;
+ 
+-	args = value;
++	/* AppArmor requires that the buffer must be null terminated atm */
++	if (args[size - 1] != '\0') {
++		/* null terminate */
++		largs = args = kmalloc(size + 1, GFP_KERNEL);
++		if (!args)
++			return -ENOMEM;
++		memcpy(args, value, size);
++		args[size] = '\0';
++	}
++
++	error = -EINVAL;
+ 	args = strim(args);
+ 	command = strsep(&args, " ");
+ 	if (!args)
+-		return -EINVAL;
++		goto out;
+ 	args = skip_spaces(args);
+ 	if (!*args)
+-		return -EINVAL;
++		goto out;
+ 
+ 	arg_size = size - (args - (char *) value);
+ 	if (strcmp(name, "current") == 0) {
+@@ -576,10 +576,12 @@ static int apparmor_setprocattr(struct task_struct *task, char *name,
+ 			goto fail;
+ 	} else
+ 		/* only support the "current" and "exec" process attributes */
+-		return -EINVAL;
++		goto fail;
+ 
+ 	if (!error)
+ 		error = size;
++out:
++	kfree(largs);
+ 	return error;
+ 
+ fail:
+@@ -588,9 +590,9 @@ fail:
+ 	aad.profile = aa_current_profile();
+ 	aad.op = OP_SETPROCATTR;
+ 	aad.info = name;
+-	aad.error = -EINVAL;
++	aad.error = error = -EINVAL;
+ 	aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL);
+-	return -EINVAL;
++	goto out;
+ }
+ 
+ static int apparmor_task_setrlimit(struct task_struct *task,
+diff --git a/security/keys/key.c b/security/keys/key.c
+index b28755131687..af7f6821d26b 100644
+--- a/security/keys/key.c
++++ b/security/keys/key.c
+@@ -584,7 +584,7 @@ int key_reject_and_link(struct key *key,
+ 
+ 	mutex_unlock(&key_construction_mutex);
+ 
+-	if (keyring)
++	if (keyring && link_ret == 0)
+ 		__key_link_end(keyring, &key->index_key, edit);
+ 
+ 	/* wake up anyone waiting for a key to be constructed */
+diff --git a/sound/core/control.c b/sound/core/control.c
+index a85d45595d02..b4fe9b002512 100644
+--- a/sound/core/control.c
++++ b/sound/core/control.c
+@@ -160,6 +160,8 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
+ 	
+ 	if (snd_BUG_ON(!card || !id))
+ 		return;
++	if (card->shutdown)
++		return;
+ 	read_lock(&card->ctl_files_rwlock);
+ #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
+ 	card->mixer_oss_change_count++;
+diff --git a/sound/core/pcm.c b/sound/core/pcm.c
+index 308c9ecf73db..8e980aa678d0 100644
+--- a/sound/core/pcm.c
++++ b/sound/core/pcm.c
+@@ -849,6 +849,14 @@ int snd_pcm_new_internal(struct snd_card *card, const char *id, int device,
+ }
+ EXPORT_SYMBOL(snd_pcm_new_internal);
+ 
++static void free_chmap(struct snd_pcm_str *pstr)
++{
++	if (pstr->chmap_kctl) {
++		snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl);
++		pstr->chmap_kctl = NULL;
++	}
++}
++
+ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
+ {
+ 	struct snd_pcm_substream *substream, *substream_next;
+@@ -871,6 +879,7 @@ static void snd_pcm_free_stream(struct snd_pcm_str * pstr)
+ 		kfree(setup);
+ 	}
+ #endif
++	free_chmap(pstr);
+ 	if (pstr->substream_count)
+ 		put_device(&pstr->dev);
+ }
+@@ -1135,10 +1144,7 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
+ 	for (cidx = 0; cidx < 2; cidx++) {
+ 		if (!pcm->internal)
+ 			snd_unregister_device(&pcm->streams[cidx].dev);
+-		if (pcm->streams[cidx].chmap_kctl) {
+-			snd_ctl_remove(pcm->card, pcm->streams[cidx].chmap_kctl);
+-			pcm->streams[cidx].chmap_kctl = NULL;
+-		}
++		free_chmap(&pcm->streams[cidx]);
+ 	}
+ 	mutex_unlock(&pcm->open_mutex);
+ 	mutex_unlock(&register_mutex);
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index 6469bedda2f3..23b73f6ac040 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1954,6 +1954,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ 
+ 		qhead = tu->qhead++;
+ 		tu->qhead %= tu->queue_size;
++		tu->qused--;
+ 		spin_unlock_irq(&tu->qlock);
+ 
+ 		if (tu->tread) {
+@@ -1967,7 +1968,6 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ 		}
+ 
+ 		spin_lock_irq(&tu->qlock);
+-		tu->qused--;
+ 		if (err < 0)
+ 			goto _error;
+ 		result += unit;
+diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
+index c0f8f613f1f1..172dacd925f5 100644
+--- a/sound/drivers/dummy.c
++++ b/sound/drivers/dummy.c
+@@ -420,6 +420,7 @@ static int dummy_hrtimer_stop(struct snd_pcm_substream *substream)
+ 
+ static inline void dummy_hrtimer_sync(struct dummy_hrtimer_pcm *dpcm)
+ {
++	hrtimer_cancel(&dpcm->timer);
+ 	tasklet_kill(&dpcm->tasklet);
+ }
+ 
+diff --git a/sound/hda/hdac_regmap.c b/sound/hda/hdac_regmap.c
+index 87041ddd29cb..47a358fab132 100644
+--- a/sound/hda/hdac_regmap.c
++++ b/sound/hda/hdac_regmap.c
+@@ -444,7 +444,7 @@ int snd_hdac_regmap_write_raw(struct hdac_device *codec, unsigned int reg,
+ 	err = reg_raw_write(codec, reg, val);
+ 	if (err == -EAGAIN) {
+ 		err = snd_hdac_power_up_pm(codec);
+-		if (!err)
++		if (err >= 0)
+ 			err = reg_raw_write(codec, reg, val);
+ 		snd_hdac_power_down_pm(codec);
+ 	}
+@@ -470,7 +470,7 @@ static int __snd_hdac_regmap_read_raw(struct hdac_device *codec,
+ 	err = reg_raw_read(codec, reg, val, uncached);
+ 	if (err == -EAGAIN) {
+ 		err = snd_hdac_power_up_pm(codec);
+-		if (!err)
++		if (err >= 0)
+ 			err = reg_raw_read(codec, reg, val, uncached);
+ 		snd_hdac_power_down_pm(codec);
+ 	}
+diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c
+index 4667c3232b7f..74177189063c 100644
+--- a/sound/pci/au88x0/au88x0_core.c
++++ b/sound/pci/au88x0/au88x0_core.c
+@@ -1444,9 +1444,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma)
+ 	int page, p, pp, delta, i;
+ 
+ 	page =
+-	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2)) &
+-	     WT_SUBBUF_MASK)
+-	    >> WT_SUBBUF_SHIFT;
++	    (hwread(vortex->mmio, VORTEX_WTDMA_STAT + (wtdma << 2))
++	     >> WT_SUBBUF_SHIFT) & WT_SUBBUF_MASK;
+ 	if (dma->nr_periods >= 4)
+ 		delta = (page - dma->period_real) & 3;
+ 	else {
+diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c
+index 1cb85aeb0cea..286f5e3686a3 100644
+--- a/sound/pci/echoaudio/echoaudio.c
++++ b/sound/pci/echoaudio/echoaudio.c
+@@ -2200,11 +2200,11 @@ static int snd_echo_resume(struct device *dev)
+ 	u32 pipe_alloc_mask;
+ 	int err;
+ 
+-	commpage_bak = kmalloc(sizeof(struct echoaudio), GFP_KERNEL);
++	commpage_bak = kmalloc(sizeof(*commpage), GFP_KERNEL);
+ 	if (commpage_bak == NULL)
+ 		return -ENOMEM;
+ 	commpage = chip->comm_page;
+-	memcpy(commpage_bak, commpage, sizeof(struct comm_page));
++	memcpy(commpage_bak, commpage, sizeof(*commpage));
+ 
+ 	err = init_hw(chip, chip->pci->device, chip->pci->subsystem_device);
+ 	if (err < 0) {
+diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
+index dfaf1a93fb8a..d77cc76aadab 100644
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -3977,6 +3977,8 @@ static hda_nid_t set_path_power(struct hda_codec *codec, hda_nid_t nid,
+ 
+ 	for (n = 0; n < spec->paths.used; n++) {
+ 		path = snd_array_elem(&spec->paths, n);
++		if (!path->depth)
++			continue;
+ 		if (path->path[0] == nid ||
+ 		    path->path[path->depth - 1] == nid) {
+ 			bool pin_old = path->pin_enabled;
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 94089fc71884..6f8ea13323c1 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -367,9 +367,10 @@ enum {
+ #define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+ #define IS_KBL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa171)
+ #define IS_KBL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d71)
++#define IS_KBL_H(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa2f0)
+ #define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+ #define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci)) || \
+-			IS_KBL(pci) || IS_KBL_LP(pci)
++			IS_KBL(pci) || IS_KBL_LP(pci) || IS_KBL_H(pci)
+ 
+ static char *driver_short_names[] = {
+ 	[AZX_DRIVER_ICH] = "HDA Intel",
+@@ -1217,8 +1218,10 @@ static int azx_free(struct azx *chip)
+ 	if (use_vga_switcheroo(hda)) {
+ 		if (chip->disabled && hda->probe_continued)
+ 			snd_hda_unlock_devices(&chip->bus);
+-		if (hda->vga_switcheroo_registered)
++		if (hda->vga_switcheroo_registered) {
+ 			vga_switcheroo_unregister_client(chip->pci);
++			vga_switcheroo_fini_domain_pm_ops(chip->card->dev);
++		}
+ 	}
+ 
+ 	if (bus->chip_init) {
+@@ -2190,6 +2193,9 @@ static const struct pci_device_id azx_ids[] = {
+ 	/* Kabylake-LP */
+ 	{ PCI_DEVICE(0x8086, 0x9d71),
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
++	/* Kabylake-H */
++	{ PCI_DEVICE(0x8086, 0xa2f0),
++	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_SKYLAKE },
+ 	/* Broxton-P(Apollolake) */
+ 	{ PCI_DEVICE(0x8086, 0x5a98),
+ 	  .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_INTEL_BROXTON },
+@@ -2263,6 +2269,8 @@ static const struct pci_device_id azx_ids[] = {
+ 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+ 	{ PCI_DEVICE(0x1002, 0x157a),
+ 	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
++	{ PCI_DEVICE(0x1002, 0x15b3),
++	  .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI_NS },
+ 	{ PCI_DEVICE(0x1002, 0x793b),
+ 	  .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI },
+ 	{ PCI_DEVICE(0x1002, 0x7919),
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 0fe18ede3e85..abcb5a6a1cd9 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -5650,6 +5650,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x17aa, 0x503c, "Thinkpad L450", ALC292_FIXUP_TPT440_DOCK),
+ 	SND_PCI_QUIRK(0x17aa, 0x504a, "ThinkPad X260", ALC292_FIXUP_TPT440_DOCK),
+ 	SND_PCI_QUIRK(0x17aa, 0x504b, "Thinkpad", ALC293_FIXUP_LENOVO_SPK_NOISE),
++	SND_PCI_QUIRK(0x17aa, 0x5050, "Thinkpad T560p", ALC292_FIXUP_TPT460),
++	SND_PCI_QUIRK(0x17aa, 0x5051, "Thinkpad L460", ALC292_FIXUP_TPT460),
++	SND_PCI_QUIRK(0x17aa, 0x5053, "Thinkpad T460", ALC292_FIXUP_TPT460),
+ 	SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
+ 	SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
+ 	SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
+@@ -5735,7 +5738,6 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ 	{}
+ };
+ #define ALC225_STANDARD_PINS \
+-	{0x12, 0xb7a60130}, \
+ 	{0x21, 0x04211020}
+ 
+ #define ALC256_STANDARD_PINS \
+@@ -5760,10 +5762,24 @@ static const struct hda_model_fixup alc269_fixup_models[] = {
+ static const struct snd_hda_pin_quirk alc269_pin_fixup_tbl[] = {
+ 	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC225_STANDARD_PINS,
++		{0x12, 0xb7a60130},
+ 		{0x14, 0x901701a0}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
+ 		ALC225_STANDARD_PINS,
++		{0x12, 0xb7a60130},
+ 		{0x14, 0x901701b0}),
++	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++		ALC225_STANDARD_PINS,
++		{0x12, 0xb7a60150},
++		{0x14, 0x901701a0}),
++	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++		ALC225_STANDARD_PINS,
++		{0x12, 0xb7a60150},
++		{0x14, 0x901701b0}),
++	SND_HDA_PIN_QUIRK(0x10ec0225, 0x1028, "Dell", ALC225_FIXUP_DELL1_MIC_NO_PRESENCE,
++		ALC225_STANDARD_PINS,
++		{0x12, 0xb7a60130},
++		{0x1b, 0x90170110}),
+ 	SND_HDA_PIN_QUIRK(0x10ec0255, 0x1028, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE,
+ 		{0x14, 0x90170110},
+ 		{0x21, 0x02211020}),
+@@ -5832,6 +5848,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, 0x90a60170},
++		{0x14, 0x90170120},
++		{0x21, 0x02211030}),
++	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},
+diff --git a/sound/usb/card.c b/sound/usb/card.c
+index 3fc63583a537..2d493501b7f6 100644
+--- a/sound/usb/card.c
++++ b/sound/usb/card.c
+@@ -552,7 +552,6 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 				goto __error;
+ 			}
+ 			chip = usb_chip[i];
+-			dev_set_drvdata(&dev->dev, chip);
+ 			atomic_inc(&chip->active); /* avoid autopm */
+ 			break;
+ 		}
+@@ -578,6 +577,7 @@ static int usb_audio_probe(struct usb_interface *intf,
+ 			goto __error;
+ 		}
+ 	}
++	dev_set_drvdata(&dev->dev, chip);
+ 
+ 	/*
+ 	 * For devices with more than one control interface, we assume the
+diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
+index 4fd482fb9260..7cb12249baa5 100644
+--- a/virt/kvm/kvm_main.c
++++ b/virt/kvm/kvm_main.c
+@@ -2868,7 +2868,7 @@ static long kvm_vm_ioctl(struct file *filp,
+ 		if (copy_from_user(&routing, argp, sizeof(routing)))
+ 			goto out;
+ 		r = -EINVAL;
+-		if (routing.nr >= KVM_MAX_IRQ_ROUTES)
++		if (routing.nr > KVM_MAX_IRQ_ROUTES)
+ 			goto out;
+ 		if (routing.flags)
+ 			goto out;


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

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

commit:     c8839f5a116f5e0d27d587a09b40e1cc668c9885
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 27 23:51:56 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Jul 27 23:51:56 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c8839f5a

Add BFQ patches for 4.6.X: http://algogroup.unimore.it/people/paolo/disk_sched/patches/4.6.0-v8/

 0000_README                                        |   16 +
 ...oups-kconfig-build-bits-for-BFQ-v7r11-4.6.patch |  103 +
 ...ntroduce-the-BFQ-v7r11-I-O-sched-for-4.6.patch1 | 7097 ++++++++++++++++++++
 ...arly-Queue-Merge-EQM-to-BFQ-v7r11-for-4.6.patch | 1101 +++
 ...rn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2 | 6361 ++++++++++++++++++
 5 files changed, 14678 insertions(+)

diff --git a/0000_README b/0000_README
index 67da565..9e42d11 100644
--- a/0000_README
+++ b/0000_README
@@ -91,6 +91,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.6.patch
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 1 for 4.6: Build, cgroups and kconfig bits
+
+Patch:  5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.6.patch1
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 2 for 4.6: BFQ Scheduler
+
+Patch:  5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.6.patch
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 3 for 4.6: Early Queue Merge (EQM)
+
+Patch:  5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2
+From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
+Desc:   BFQ v7r11 patch 4 for 4.7: Early Queue Merge (EQM)
+
 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/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.6.patch b/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.6.patch
new file mode 100644
index 0000000..ee3934f
--- /dev/null
+++ b/5001_block-cgroups-kconfig-build-bits-for-BFQ-v7r11-4.6.patch
@@ -0,0 +1,103 @@
+From 4cf5d043709bfe73b4553272706cb5beb8072301 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.6.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 669e419..119be87 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
+ 
+ struct request;
+ typedef void (rq_end_io_fn)(struct request *, int);
+-- 
+1.9.1
+

diff --git a/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.6.patch1 b/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.6.patch1
new file mode 100644
index 0000000..c232a83
--- /dev/null
+++ b/5002_block-introduce-the-BFQ-v7r11-I-O-sched-for-4.6.patch1
@@ -0,0 +1,7097 @@
+From 75c0230fa4f82fb77e41cf60c06e22b5e07f7f97 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 for 4.6.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    | 1182 ++++++++++++++++
+ block/bfq-ioc.c       |   36 +
+ block/bfq-iosched.c   | 3754 +++++++++++++++++++++++++++++++++++++++++++++++++
+ block/bfq-sched.c     | 1200 ++++++++++++++++
+ block/bfq.h           |  801 +++++++++++
+ 6 files changed, 6975 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..8610cd6
+--- /dev/null
++++ b/block/bfq-cgroup.c
+@@ -0,0 +1,1182 @@
++/*
++ * 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);
++	return;
++}
++
++/**
++ * 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);
++
++	return;
++}
++
++/**
++ * 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..f9787a6
+--- /dev/null
++++ b/block/bfq-iosched.c
+@@ -0,0 +1,3754 @@
++/*
++ * 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 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;
++		else {
++			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",
++		(long long unsigned)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),
++			(long long unsigned)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) {
++		printk(KERN_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),
++		     (long long unsigned)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)
++{
++	if (bfq_pool)
++		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, dur %d/%u\n",
++			      bfqq->pid,
++			      bfqq->entity.weight,
++			      bfqq->queued[0],
++			      bfqq->queued[1],
++			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..a64fec1
+--- /dev/null
++++ b/block/bfq-sched.c
+@@ -0,0 +1,1200 @@
++/*
++ * 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) {
++				printk(KERN_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..485d0c9
+--- /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 */
+-- 
+1.9.1
+

diff --git a/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.6.patch b/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.6.patch
new file mode 100644
index 0000000..3a1c06d
--- /dev/null
+++ b/5003_block-bfq-add-Early-Queue-Merge-EQM-to-BFQ-v7r11-for-4.6.patch
@@ -0,0 +1,1101 @@
+From c41c6d65f72971e565e7980db2c34224ca06fffd 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 for
+ 4.6.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  |   4 +
+ block/bfq-iosched.c | 687 ++++++++++++++++++++++++++++++++++++++++++++++++++--
+ block/bfq.h         |  66 +++++
+ 3 files changed, 743 insertions(+), 14 deletions(-)
+
+diff --git a/block/bfq-cgroup.c b/block/bfq-cgroup.c
+index 8610cd6..5ee99ec 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -437,6 +437,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)
+@@ -530,6 +531,8 @@ 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.
+@@ -577,6 +580,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 f9787a6..d1f648d 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -296,6 +296,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",
++		(long long unsigned)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.
+  */
+@@ -528,6 +594,57 @@ static unsigned int bfq_wr_duration(struct bfq_data *bfqd)
+ 	return dur;
+ }
+ 
++static unsigned 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)
+ {
+@@ -764,8 +881,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);
+@@ -793,11 +916,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));
+ 
+@@ -816,6 +940,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,
+@@ -840,7 +967,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)) {
+@@ -905,6 +1032,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:
+@@ -1047,6 +1175,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);
++		}
+ 	}
+ }
+ 
+@@ -1129,11 +1266,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",
++		(long unsigned)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.
+@@ -1150,7 +1622,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,
+@@ -1349,6 +1840,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
+@@ -1357,8 +1857,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);
++	}
+ }
+ 
+ /**
+@@ -2242,10 +2747,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;
+@@ -2474,6 +2981,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) {
+@@ -2484,6 +3010,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);
+ }
+ 
+@@ -2492,6 +3020,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)
+@@ -2505,6 +3052,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;
+ 	}
+@@ -2809,6 +3363,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 ||
+@@ -2856,6 +3414,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)",
+@@ -2920,12 +3479,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);
+ 
+@@ -3094,6 +3688,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,
+@@ -3105,6 +3725,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));
+ 
+@@ -3117,15 +3738,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
+-				bfq_clear_bfqq_in_large_burst(bfqq);
++			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;
+ 		}
+ 	}
+ 
+@@ -3137,6 +3773,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;
+@@ -3290,6 +3946,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;
+ }
+@@ -3370,6 +4027,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 485d0c9..f73c942 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);
+-- 
+1.9.1
+

diff --git a/5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2 b/5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2
new file mode 100644
index 0000000..bbccb23
--- /dev/null
+++ b/5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2
@@ -0,0 +1,6361 @@
+From 62745bf5f16f14ce2bd56377eeb84615b4a19cd2 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] blkck, bfq: turn BFQ-v7r11 for 4.7.0 into BFQ-v8 for
+ 4.7.0
+
+---
+ block/Kconfig.iosched |    2 +-
+ block/bfq-cgroup.c    |  448 +++++----
+ block/bfq-iosched.c   | 2582 +++++++++++++++++++++++++++++--------------------
+ block/bfq-sched.c     |  432 +++++++--
+ block/bfq.h           |  697 +++++++------
+ 5 files changed, 2433 insertions(+), 1728 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 5ee99ec..bc01663 100644
+--- a/block/bfq-cgroup.c
++++ b/block/bfq-cgroup.c
+@@ -162,7 +162,6 @@ static struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg)
+ 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);
+ }
+ 
+@@ -224,14 +223,6 @@ 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)
+ {
+@@ -248,17 +239,11 @@ static void bfqg_stats_update_completion(struct bfq_group *bfqg,
+ /* @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);
+@@ -268,21 +253,19 @@ 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);
++	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);
+@@ -308,10 +291,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,
+@@ -332,15 +313,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);
+@@ -351,15 +328,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) ||
+@@ -374,20 +347,36 @@ static int bfqg_stats_init(struct bfqg_stats *stats, gfp_t gfp)
+ }
+ 
+ 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 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)
+@@ -398,8 +387,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;
+ 	}
+@@ -407,27 +395,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;
+@@ -445,45 +426,28 @@ 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;
+-
+-	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;
+-}
++	struct bfq_entity *entity;
+ 
+-static void bfq_pd_reset_stats(struct blkg_policy_data *pd)
+-{
+-	struct bfq_group *bfqg = pd_to_bfqg(pd);
++	BUG_ON(!parent);
++	BUG_ON(!bfqg);
++	BUG_ON(bfqg == parent);
+ 
+-	bfqg_stats_reset(&bfqg->stats);
+-	bfqg_stats_reset(&bfqg->dead_stats);
++	entity = &bfqg->entity;
++	entity->parent = parent->my_entity;
++	entity->sched_data = &parent->sched_data;
+ }
+ 
+ static struct bfq_group *bfq_find_alloc_group(struct bfq_data *bfqd,
+@@ -531,13 +495,18 @@ 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);
++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
+@@ -548,26 +517,40 @@ static void bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
+  * 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;
++	struct bfq_entity *entity = &bfqq->entity;
+ 
+-	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 &&
++	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 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);
+ 
+-	if (busy) {
+-		BUG_ON(atomic_read(&bfqq->ref) < 2);
++	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));
+ 
+ 	/*
+@@ -579,14 +562,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);
+ }
+ 
+ /**
+@@ -621,7 +607,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);
+ 		}
+ 	}
+@@ -629,7 +616,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;
+@@ -638,25 +625,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();
+ }
+ 
+ /**
+@@ -682,8 +667,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);
+-	return;
++	bfq_bfqq_move(bfqd, bfqq, bfqd->root_group);
+ }
+ 
+ /**
+@@ -711,16 +695,15 @@ static void bfq_reparent_active_entities(struct bfq_data *bfqd,
+ 	if (bfqg->sched_data.in_service_entity)
+ 		bfq_reparent_leaf_entity(bfqd,
+ 			bfqg->sched_data.in_service_entity);
+-
+-	return;
+ }
+ 
+ /**
+- * 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)
+ {
+@@ -779,6 +762,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);
+ }
+ 
+@@ -788,46 +777,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;
+@@ -837,6 +815,7 @@ static int bfqio_cgroup_weight_write(struct cgroup_subsys_state *css,
+ 	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;
+ 		/*
+@@ -871,13 +850,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)
+@@ -897,16 +881,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);
+ }
+ 
+@@ -926,6 +911,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)
+ {
+@@ -950,7 +970,8 @@ static int bfqg_print_avg_queue_size(struct seq_file *sf, void *v)
+ 	return 0;
+ }
+ 
+-static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
++static struct bfq_group *
++bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
+ {
+ 	int ret;
+ 
+@@ -958,41 +979,18 @@ static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int n
+ 	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;
++	return blkg_to_bfqg(bfqd->queue->root_blkg);
+ }
+ 
+-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),
+@@ -1000,18 +998,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",
+@@ -1042,18 +1039,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",
+@@ -1099,32 +1095,35 @@ 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 rw) { }
++static inline void bfqg_stats_update_io_remove(struct bfq_group *bfqg, int rw) { }
++static inline void bfqg_stats_update_io_merged(struct bfq_group *bfqg, int rw) { }
++static inline void bfqg_stats_update_completion(struct bfq_group *bfqg,
++			uint64_t start_time, uint64_t io_start_time, int rw) { }
++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)
+@@ -1146,29 +1145,22 @@ 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)
+-{
+-	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 *bfqq_group(struct bfq_queue *bfqq)
++{
++	return bfqq->bfqd->root_group;
++}
++
+ static struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
+ {
+ 	struct bfq_group *bfqg;
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c
+index d1f648d..d1f3666 100644
+--- a/block/bfq-iosched.c
++++ b/block/bfq-iosched.c
+@@ -7,25 +7,26 @@
+  * 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) 2016 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 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
+@@ -87,7 +88,6 @@ 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,8 +97,7 @@ 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;
+ 
+@@ -109,8 +108,9 @@ struct kmem_cache *bfq_pool;
+ #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
+@@ -141,16 +141,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
+@@ -410,11 +418,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);
+ }
+ 
+ /*
+@@ -534,9 +538,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;
+ }
+ 
+ /**
+@@ -591,12 +605,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 bfq_bfqq_cooperations(struct bfq_queue *bfqq)
+-{
+-	return bfqq->bic ? bfqq->bic->cooperations : 0;
++	return dur;
+ }
+ 
+ static void
+@@ -606,31 +631,11 @@ 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;
+-	}
+-	/*
+-	 * 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)
+@@ -640,7 +645,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;
+ }
+@@ -655,6 +660,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) */
+@@ -663,6 +669,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;
+@@ -672,15 +682,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
+@@ -692,67 +706,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.
++ *
++ * 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 activated, the queue is inserted into the
++ * . 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
+@@ -773,13 +799,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:
+@@ -792,52 +818,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;
+ 	}
+ 
+ 	/*
+@@ -846,8 +864,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;
+ 	}
+ 
+ 	/*
+@@ -856,25 +875,492 @@ 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).
++		 */
++		entity->budget = min_t(unsigned long,
++				       bfq_bfqq_budget_left(bfqq),
++				       bfqq->max_budget);
++
++		BUG_ON(entity->budget < 0);
++		return true;
++	}
++
++	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 */
++		bfqq->wr_coeff = bfqd->bfq_wr_coeff;
++		if (interactive) /* update wr duration */
++			bfqq->wr_cur_max_time = bfq_wr_duration(bfqd);
++		else
++			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 duration */
++			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 (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;
++			bfq_log_bfqq(bfqd, bfqq,
++				     "switching to soft_rt wr, or "
++				     " just moving forward duration");
++		}
++	}
++}
++
++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 = time_is_after_jiffies(
++			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,
++				 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 == 1 &&
++	    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);
+@@ -887,160 +1373,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 +
+@@ -1049,16 +1385,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;
+@@ -1106,6 +1469,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);
+@@ -1119,8 +1485,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.
+ 		 */
+@@ -1134,9 +1517,7 @@ 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
+ }
+ 
+ static int bfq_merge(struct request_queue *q, struct request **req,
+@@ -1221,21 +1602,25 @@ 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
+ }
+ 
+ /* 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 */
++	/*
++	 * 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: wr_busy %d",
++		     bfqq->bfqd->wr_busy_queues);
+ }
+ 
+ static void bfq_end_wr_async_queues(struct bfq_data *bfqd,
+@@ -1278,7 +1663,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,
+@@ -1400,7 +1785,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;
+ }
+ 
+@@ -1431,9 +1816,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
+@@ -1442,6 +1841,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,
+@@ -1451,16 +1862,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;
+ 
+@@ -1482,7 +1909,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);
+ 
+@@ -1498,46 +1933,11 @@ static void bfq_bfqq_save_state(struct bfq_queue *bfqq)
+ 	 */
+ 	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)
+@@ -1562,6 +1962,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;
++		if (bfq_bfqq_busy(new_bfqq))
++		    bfqd->wr_busy_queues++;
++		new_bfqq->entity.prio_changed = 1;
++		bfq_log_bfqq(bfqd, new_bfqq,
++			     "wr starting 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().
+@@ -1588,18 +2022,6 @@ 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)
+ {
+@@ -1637,30 +2059,86 @@ 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);
+ }
+ 
++/*
++ * 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 (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 -
++				bfqq->budget_timeout;
++		}
++
++		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;
+ }
+@@ -1676,31 +2154,6 @@ 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;
+@@ -1723,64 +2176,36 @@ static void bfq_arm_slice_timer(struct bfq_data *bfqd)
+ 	 *
+ 	 * 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;
++	 * 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
++	 * 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 (BFQQ_SEEKY(bfqq) && bfqq->wr_coeff == 1 &&
++	    bfq_symmetric_scenario(bfqd))
++		sl = min(sl, msecs_to_jiffies(BFQ_MIN_TT));
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "set budget_timeout %u",
+-		jiffies_to_msecs(bfqd->bfq_timeout[bfq_bfqq_sync(bfqq)] *
+-		timeout_coeff));
++	bfqd->last_idling_start = ktime_get();
++	mod_timer(&bfqd->idle_slice_timer, jiffies + sl);
++	bfqg_stats_set_start_idle_time(bfqq_group(bfqq));
++	bfq_log(bfqd, "arm idle: %u/%u ms",
++		jiffies_to_msecs(sl), jiffies_to_msecs(bfqd->bfq_slice_idle));
+ }
+ 
+ /*
+- * 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 +2219,9 @@ static void bfq_dispatch_insert(struct request_queue *q, struct request *rq)
+ 	 * 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
+ }
+ 
+ /*
+@@ -1822,18 +2241,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 (time_is_after_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);
+@@ -1850,12 +2263,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);
+@@ -1882,10 +2298,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));
+@@ -1894,7 +2319,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
+@@ -1936,14 +2361,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;
+@@ -1960,17 +2381,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;
+ 
+@@ -1981,65 +2434,105 @@ 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)
++static unsigned long bfq_calc_max_budget(struct bfq_data *bfqd)
+ {
+-	unsigned long max_budget;
+-
+ 	/*
+ 	 * The max_budget calculated when autotuning is equal to the
+-	 * amount of sectors transfered in timeout_sync at the
++	 * amount of sectors transfered in timeout at the
+ 	 * estimated peak rate.
+ 	 */
+-	max_budget = (unsigned long)(peak_rate * 1000 *
+-				     timeout >> BFQ_RATE_SHIFT);
+-
+-	return max_budget;
++	return bfqd->peak_rate * 1000 * jiffies_to_msecs(bfqd->bfq_timeout) >>
++		BFQ_RATE_SHIFT;
+ }
+ 
+ /*
+- * 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.
++ * Update the read peak rate (quantity used for auto-tuning) as a
++ * function of the rate at which bfqq has been served, and check
++ * whether the process associated with bfqq is "slow". Return true if
++ * the process is slow. The 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. More details in the body of the function.
++ *
++ * An important observation is in order: 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, the device may be 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,
++ * as written above, this sum is the quantity used in this function to
++ * evaluate the peak rate.
+  */
+ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+-				 bool compensate, enum bfqq_expiration reason)
++				 bool compensate, enum bfqq_expiration reason,
++				 unsigned long *delta_ms)
+ {
+-	u64 bw, usecs, expected, timeout;
+-	ktime_t delta;
++	u64 bw, bwdiv10, delta_usecs, delta_ms_tmp;
++	ktime_t delta_ktime;
+ 	int update = 0;
++	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;
++		delta_ktime = bfqd->last_idling_start;
+ 	else
+-		delta = ktime_get();
+-	delta = ktime_sub(delta, bfqd->last_budget_start);
+-	usecs = ktime_to_us(delta);
++		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 (usecs < 100 || usecs >= LONG_MAX)
+-		return false;
++	if (delta_usecs < 1000 || delta_usecs >= LONG_MAX) {
++		if (blk_queue_nonrot(bfqd->queue))
++			*delta_ms = BFQ_MIN_TT; /* give same worst-case
++						   guarantees as
++						   idling for seeky
++						*/
++		else /* Charge at least one seek */
++			*delta_ms = jiffies_to_msecs(bfq_slice_idle);
++		return slow;
++	}
++
++	delta_ms_tmp = delta_usecs;
++	do_div(delta_ms_tmp, 1000);
++	*delta_ms = delta_ms_tmp;
+ 
+ 	/*
+ 	 * Calculate the bandwidth for the last slice.  We use a 64 bit
+@@ -2048,32 +2541,51 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 	 * 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]);
++	do_div(bw, (unsigned long)delta_usecs);
+ 
++	bfq_log(bfqd, "measured bw = %llu sects/sec",
++		(1000000*bw)>>BFQ_RATE_SHIFT);
+ 	/*
+ 	 * Use only long (> 20ms) intervals to filter out spikes for
+ 	 * the peak rate estimation.
+ 	 */
+-	if (usecs > 20000) {
++	if (delta_usecs > 20000) {
++		bool fully_sequential = bfqq->seek_history == 0;
++		/*
++		 * Soft real-time queues are not good candidates for
++		 * evaluating bw, as they are likely to be slow even
++		 * if sequential.
++		 */
++		bool non_soft_rt = bfqq->wr_coeff == 1 ||
++			bfqq->wr_cur_max_time != bfqd->bfq_wr_rt_max_time;
++		bool consumed_large_budget =
++			reason == BFQ_BFQQ_BUDGET_EXHAUSTED &&
++			bfqq->entity.budget >= bfqd->bfq_max_budget * 2 / 3;
++		bool served_for_long_time =
++			reason == BFQ_BFQQ_BUDGET_TIMEOUT ||
++			consumed_large_budget;
++
++		BUG_ON(bfqq->seek_history == 0 &&
++		       hweight32(bfqq->seek_history) != 0);
++
+ 		if (bw > bfqd->peak_rate ||
+-		   (!BFQQ_SEEKY(bfqq) &&
+-		    reason == BFQ_BFQQ_BUDGET_TIMEOUT)) {
+-			bfq_log(bfqd, "measured bw =%llu", bw);
++		    (bfq_bfqq_sync(bfqq) && fully_sequential && non_soft_rt &&
++		     served_for_long_time)) {
+ 			/*
+ 			 * To smooth oscillations use a low-pass filter with
+-			 * alpha=7/8, i.e.,
+-			 * new_rate = (7/8) * old_rate + (1/8) * bw
++			 * alpha=9/10, i.e.,
++			 * new_rate = (9/10) * old_rate + (1/10) * bw
+ 			 */
+-			do_div(bw, 8);
+-			if (bw == 0)
+-				return 0;
+-			bfqd->peak_rate *= 7;
+-			do_div(bfqd->peak_rate, 8);
+-			bfqd->peak_rate += bw;
++			bwdiv10 = bw;
++			do_div(bwdiv10, 10);
++			if (bwdiv10 == 0)
++				return false; /* bw too low to be used */
++			bfqd->peak_rate *= 9;
++			do_div(bfqd->peak_rate, 10);
++			bfqd->peak_rate += bwdiv10;
+ 			update = 1;
+-			bfq_log(bfqd, "new peak_rate=%llu", bfqd->peak_rate);
++			bfq_log(bfqd, "new peak_rate = %llu sects/sec",
++				(1000000*bfqd->peak_rate)>>BFQ_RATE_SHIFT);
+ 		}
+ 
+ 		update |= bfqd->peak_rate_samples == BFQ_PEAK_RATE_SAMPLES - 1;
+@@ -2086,9 +2598,8 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 			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",
++					bfq_calc_max_budget(bfqd);
++				bfq_log(bfqd, "new max_budget = %d",
+ 					bfqd->bfq_max_budget);
+ 			}
+ 			if (bfqd->device_speed == BFQ_BFQD_FAST &&
+@@ -2102,38 +2613,35 @@ static bool bfq_update_peak_rate(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 				bfqd->RT_prod = R_fast[dev_type] *
+ 						T_fast[dev_type];
+ 			}
++			bfq_log(bfqd, "dev_speed_class = %d (%d sects/sec), "
++				"thresh %d setcs/sec",
++				bfqd->device_speed,
++				bfqd->device_speed == BFQ_BFQD_FAST ?
++				(1000000*R_fast[dev_type])>>BFQ_RATE_SHIFT :
++				(1000000*R_slow[dev_type])>>BFQ_RATE_SHIFT,
++				(1000000*device_speed_thresh[dev_type])>>
++				BFQ_RATE_SHIFT);
+ 		}
++		/*
++		 * Caveat: processes doing IO 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 bw has been lower than half
++		 * of the estimated peak rate.
++		 */
++		slow = bw < bfqd->peak_rate / 2;
+ 	}
+ 
+-	/*
+-	 * 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;
++	bfq_log_bfqq(bfqd, bfqq,
++		     "update_peak_rate: bw %llu sect/s, peak rate %llu, "
++		     "slow %d",
++		     (1000000*bw)>>BFQ_RATE_SHIFT,
++		     (1000000*bfqd->peak_rate)>>BFQ_RATE_SHIFT,
++		     bw < bfqd->peak_rate / 2);
+ 
+-	/*
+-	 * 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;
++	return slow;
+ }
+ 
+ /*
+@@ -2191,6 +2699,15 @@ 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,
+@@ -2198,13 +2715,21 @@ static unsigned long bfq_bfqq_softrt_next_start(struct bfq_data *bfqd,
+ }
+ 
+ /*
+- * 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 future time instant according to jiffies
++ * macros.
++ */
++static unsigned long bfq_greatest_from_now(void)
++{
++	return jiffies + MAX_JIFFY_OFFSET;
++}
++
++/*
++ * 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;
+ }
+ 
+ /**
+@@ -2214,28 +2739,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,
+@@ -2243,40 +2764,51 @@ 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
++	 * Update device 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);
++	slow = bfq_update_peak_rate(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;
+-
+-	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++;
+-	}
++	/*
++	 * 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 (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)
+@@ -2285,19 +2817,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:
+@@ -2314,7 +2850,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.
+@@ -2324,8 +2860,9 @@ 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
+@@ -2333,6 +2870,14 @@ static void bfq_bfqq_expire(struct bfq_data *bfqd,
+ 	 */
+ 	__bfq_bfqq_recalc_budget(bfqd, bfqq, reason);
+ 	__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);
+ }
+ 
+ /*
+@@ -2342,20 +2887,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,
+@@ -2397,10 +2939,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.
+@@ -2422,7 +2966,7 @@ static bool bfq_bfqq_may_idle(struct bfq_queue *bfqq)
+ 	 */
+ 	idling_boosts_thr = !bfqd->hw_tag ||
+ 		(!blk_queue_nonrot(bfqd->queue) && bfq_bfqq_IO_bound(bfqq) &&
+-		 bfq_bfqq_idle_window(bfqq)) ;
++		 bfq_bfqq_idle_window(bfqq));
+ 
+ 	/*
+ 	 * The value of the next variable,
+@@ -2463,74 +3007,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.
+-	 *
+-	 * 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.
++	 * guarantees.
+ 	 *
+-	 * 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
+@@ -2552,26 +3049,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
+@@ -2579,7 +3103,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
+@@ -2601,17 +3125,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
+@@ -2621,6 +3144,14 @@ 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 "
++		     "wr_busy %d boosts %d IO-bound %d guar %d",
++		     bfq_bfqq_sync(bfqq), idling_boosts_thr,
++		     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);
+@@ -2632,7 +3163,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.
+@@ -2698,9 +3229,7 @@ static struct bfq_queue *bfq_select_queue(struct bfq_data *bfqd)
+ 				 */
+ 				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;
+ 		}
+@@ -2745,14 +3274,11 @@ 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;
+@@ -2814,10 +3340,25 @@ static int bfq_dispatch_request(struct bfq_data *bfqd,
+ 		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,
+@@ -2833,9 +3374,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;
+@@ -2881,8 +3420,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);
+ 	}
+ 
+@@ -2895,9 +3434,9 @@ 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;
+ 
+@@ -2908,21 +3447,7 @@ static int bfq_dispatch_requests(struct request_queue *q, int force)
+ 	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));
+@@ -2933,6 +3458,7 @@ 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->entity.budget < bfqq->entity.service);
+ 	return 1;
+ }
+ 
+@@ -2949,11 +3475,11 @@ static void bfq_put_queue(struct bfq_queue *bfqq)
+ 	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(bfqd, bfqq, "put_queue: %p %d", bfqq, bfqq->ref);
++	bfqq->ref--;
++	if (bfqq->ref)
+ 		return;
+ 
+ 	BUG_ON(rb_first(&bfqq->sort_list));
+@@ -3007,8 +3533,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);
+ 
+@@ -3019,26 +3544,7 @@ 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;
++	bic->ttime.last_end_request = bfq_smallest_from_now();
+ }
+ 
+ static void bfq_exit_icq(struct io_cq *icq)
+@@ -3046,21 +3552,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);
+ 	}
+ }
+ 
+@@ -3068,7 +3574,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;
+@@ -3100,7 +3607,7 @@ static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *b
+ 		break;
+ 	}
+ 
+-	if (bfqq->new_ioprio < 0 || bfqq->new_ioprio >= IOPRIO_BE_NR) {
++	if (bfqq->new_ioprio >= IOPRIO_BE_NR) {
+ 		printk(KERN_CRIT "bfq_set_next_ioprio_data: new_ioprio %d\n",
+ 				 bfqq->new_ioprio);
+ 		BUG();
+@@ -3108,45 +3615,39 @@ static void bfq_set_next_ioprio_data(struct bfq_queue *bfqq, struct bfq_io_cq *b
+ 
+ 	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;
+-	unsigned long uninitialized_var(flags);
++	struct bfq_data *bfqd = bic_to_bfqd(bic);
++	struct bfq_queue *bfqq;
+ 	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,
+@@ -3155,8 +3656,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)
+@@ -3166,6 +3668,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);
+@@ -3175,72 +3678,17 @@ 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 = 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);
++	bfqq->soft_rt_next_start = bfq_greatest_from_now();
+ 
+-	rcu_read_unlock();
+-
+-	return bfqq;
++	/* first request is almost certainly seeky */
++	bfqq->seek_history = 1;
+ }
+ 
+ static struct bfq_queue **bfq_async_queue_prio(struct bfq_data *bfqd,
+@@ -3263,44 +3711,56 @@ 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();
+ 
+-		rcu_read_lock();
+-		blkcg = bio_blkcg(bio);
+-		rcu_read_unlock();
+-		bfqg = bfq_find_alloc_group(bfqd, blkcg);
++	bfqg = bfq_find_alloc_group(bfqd,bio_blkcg(bio));
++
++	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;
+ }
+ 
+@@ -3316,37 +3776,21 @@ static void bfq_update_io_thinktime(struct bfq_data *bfqd,
+ 				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;
++static void
++bfq_update_io_seektime(struct bfq_data *bfqd, struct bfq_queue *bfqq,
++		       struct request *rq)
++{
++	sector_t sdist = 0;
++	if (bfqq->last_request_pos) {
++		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);
++	}
+ 
+-	bfq_log_bfqq(bfqd, bfqq, "dist=%llu mean=%llu", (u64)sdist,
+-			(u64)bfqq->seek_mean);
++	bfqq->seek_history <<= 1;
++	bfqq->seek_history |= (sdist > BFQQ_SEEK_THR);
+ }
+ 
+ /*
+@@ -3364,7 +3808,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);
+@@ -3404,22 +3849,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),
+-		     (long long unsigned)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);
+ 
+@@ -3433,14 +3869,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;
+@@ -3453,9 +3890,7 @@ static void bfq_rq_enqueued(struct bfq_data *bfqd, struct bfq_queue *bfqq,
+ 		 */
+ 		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
+@@ -3499,27 +3934,19 @@ 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)];
+ 	list_add_tail(&rq->queuelist, &bfqq->fifo);
+ 
+@@ -3528,8 +3955,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,43 +3987,41 @@ static void bfq_completed_request(struct request_queue *q, struct request *rq)
+ 	bfq_log_bfqq(bfqd, bfqq, "completed one req with %u sects left (%d)",
+ 		     blk_rq_sectors(rq), sync);
+ 
++	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
+ 
+ 	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;
+-	}
++	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 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))
+@@ -3608,10 +4033,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))
+@@ -3682,14 +4104,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)
+@@ -3727,11 +4149,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;
+@@ -3741,23 +4160,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 {
+-			    bfq_clear_bfqq_in_large_burst(bfqq);
+-			    if (bic->was_in_burst_list)
+-			       hlist_add_head(&bfqq->burst_list_node,
+-				              &bfqd->burst_list);
++			} 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)
+@@ -3766,9 +4209,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;
+@@ -3783,7 +4225,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
+@@ -3793,6 +4234,9 @@ new_queue:
+ 		}
+ 	}
+ 
++	if (unlikely(bfq_bfqq_just_created(bfqq)))
++		bfq_handle_burst(bfqd, bfqq);
++
+ 	spin_unlock_irqrestore(q->queue_lock, flags);
+ 
+ 	return 0;
+@@ -3872,6 +4316,7 @@ static void bfq_shutdown_timer_wq(struct bfq_data *bfqd)
+ 	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)
+ {
+@@ -3880,9 +4325,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;
+ 	}
+@@ -3904,6 +4349,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)
+ {
+@@ -3923,8 +4369,6 @@ static void bfq_exit_queue(struct elevator_queue *e)
+ 
+ 	bfq_shutdown_timer_wq(bfqd);
+ 
+-	synchronize_rcu();
+-
+ 	BUG_ON(timer_pending(&bfqd->idle_slice_timer));
+ 
+ #ifdef CONFIG_BFQ_GROUP_IOSCHED
+@@ -3973,11 +4417,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
+@@ -3996,9 +4443,6 @@ 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);
+ 	bfqd->idle_slice_timer.function = bfq_idle_slice_timer;
+@@ -4023,20 +4467,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);
+@@ -4048,16 +4491,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;
+@@ -4161,10 +4603,8 @@ 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_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);
+@@ -4199,10 +4639,6 @@ 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,
+@@ -4224,10 +4660,8 @@ static ssize_t bfq_weights_store(struct elevator_queue *e,
+ 
+ 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);
++		return bfq_calc_max_budget(bfqd);
+ 	else
+ 		return bfq_default_max_budget;
+ }
+@@ -4252,6 +4686,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)
+ {
+@@ -4264,13 +4702,31 @@ 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);
+ 
+ 	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 < msecs_to_jiffies(8))
++		bfqd->bfq_slice_idle = msecs_to_jiffies(8);
++
++	bfqd->strict_guarantees = __data;
++
++	return ret;
++}
++
+ static ssize_t bfq_low_latency_store(struct elevator_queue *e,
+ 				     const char *page, size_t count)
+ {
+@@ -4297,9 +4753,8 @@ static struct elv_fs_entry bfq_attrs[] = {
+ 	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(strict_guarantees),
+ 	BFQ_ATTR(low_latency),
+ 	BFQ_ATTR(wr_coeff),
+ 	BFQ_ATTR(wr_max_time),
+@@ -4342,9 +4797,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;
++	char msg[50] = "BFQ I/O-scheduler: v8";
+ 
+ 	/*
+ 	 * Can be 0 on HZ < 1000 setups.
+@@ -4352,9 +4826,6 @@ static int __init bfq_init(void)
+ 	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)
+@@ -4370,23 +4841,34 @@ static int __init bfq_init(void)
+ 	 * 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);
++	T_slow[0] = msecs_to_jiffies(3500);
++	T_slow[1] = msecs_to_jiffies(1500);
++	T_fast[0] = msecs_to_jiffies(8000);
++	T_fast[1] = msecs_to_jiffies(3000);
+ 
+ 	/*
+-	 * 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 a64fec1..e54b149 100644
+--- a/block/bfq-sched.c
++++ b/block/bfq-sched.c
+@@ -7,9 +7,11 @@
+  * 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) 2016 Paolo Valente <paolo.valente@unimore.it>
+  */
+ 
++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 +24,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 +48,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 +66,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 +167,35 @@ 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
+ 	}
+ }
+ 
+@@ -386,8 +417,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 +428,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 +451,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 +528,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 +577,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);
+ 	}
+ }
+@@ -628,12 +653,14 @@ __bfq_entity_update_weight_prio(struct bfq_service_tree *old_st,
+ 		if (entity->new_weight != entity->orig_weight) {
+ 			if (entity->new_weight < BFQ_MIN_WEIGHT ||
+ 			    entity->new_weight > BFQ_MAX_WEIGHT) {
+-				printk(KERN_CRIT "update_weight_prio: "
+-						 "new_weight %d\n",
++				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;
++		       	entity->orig_weight = entity->new_weight;
+ 			if (bfqq)
+ 				bfqq->ioprio =
+ 				  bfq_weight_to_ioprio(entity->orig_weight);
+@@ -708,7 +735,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);
+@@ -717,31 +744,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
++ *
++ * 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.
+  *
+- * 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.
++ * 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;
++
++	if (tot_serv_to_charge < entity->service)
++		tot_serv_to_charge = 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);
+ 
+-	bfq_log_bfqq(bfqq->bfqd, bfqq, "charge_full_budget");
++	/* Increase budget to avoid inconsistencies */
++	if (tot_serv_to_charge > entity->budget)
++		entity->budget = tot_serv_to_charge;
+ 
+-	bfq_bfqq_served(bfqq, entity->budget - entity->service);
++	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
+@@ -749,11 +814,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);
+ 		/*
+@@ -771,45 +841,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;
+ 
+-		BUG_ON(entity->on_st);
+-		entity->on_st = 1;
++		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;
++		}
+ 	}
+ 
+ 	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))
+@@ -890,23 +1048,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;
+ 	}
+@@ -916,9 +1075,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;
+ 	}
+@@ -997,10 +1170,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;
+@@ -1009,6 +1183,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
+@@ -1045,10 +1237,28 @@ static struct bfq_entity *bfq_lookup_next_entity(struct bfq_sched_data *sd,
+ 	BUG_ON(sd->in_service_entity);
+ 
+ 	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;
+@@ -1057,6 +1267,24 @@ 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);
+@@ -1070,6 +1298,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.
+  */
+@@ -1086,7 +1321,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;
+ 	}
+@@ -1113,9 +1377,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);
+ }
+ 
+@@ -1123,12 +1385,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
+@@ -1139,6 +1400,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");
+ 
+@@ -1147,27 +1409,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);
+ }
+ 
+ /*
+@@ -1185,16 +1440,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 f73c942..9e76b27 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-v8 for 4.6.0: data structures and common functions prototypes.
+  *
+  * Based on ideas and code from CFQ:
+  * Copyright (C) 2003 Jens Axboe <axboe@kernel.dk>
+@@ -28,7 +28,7 @@
+ 
+ #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
+ 
+@@ -36,12 +36,6 @@ 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 +43,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 +74,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;
++	short 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 +123,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;
++	/* 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 short weight; 	/* weight of the queue */
++	unsigned short new_weight; /* next weight if a change is in progress */
++
++	/* original weight, used to implement weight boosting */
+ 	unsigned short 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 +176,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 +186,163 @@ 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;
++
++	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;
++	unsigned long last_end_request; /* completion time of last request */
++
++	unsigned long ttime_total; /* total process thinktime */
++	unsigned long ttime_samples; /* number of thinktime samples */
++	unsigned long 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;
+ };
+ 
+ enum bfq_device_speed {
+@@ -354,224 +351,216 @@ 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;
+ 
++	/*
++	 * Timer set when idling (waiting) for the next request from
++	 * the queue in service.
++	 */
+ 	struct timer_list 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;
+ 
++	/* beginning of the last budget */
+ 	ktime_t last_budget_start;
++	/* beginning of the last idle slice */
+ 	ktime_t last_idling_start;
++	/* number of samples used to calculate @peak_rate */
+ 	int peak_rate_samples;
++	/* peak transfer rate observed for a budget */
+ 	u64 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;
+ 
++	/*
++	 * Timeout for async/sync requests; when it fires, requests
++	 * are served in fifo order.
++	 */
+ 	unsigned int 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;
++	/* maximum idling time */
+ 	unsigned int 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 +570,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 +592,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 +652,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 +666,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 +685,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.
+  *
+@@ -712,7 +719,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 +752,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 +773,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 +811,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 +836,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 */
+-- 
+1.9.1
+


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

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

commit:     c12def91a2d1b232600418a34f79774f6cb40a2c
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 10 12:57:38 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Aug 10 12:57:38 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=c12def91

Linux patch 4.6.6

 0000_README            |    4 +
 1005_linux-4.6.6.patch | 3625 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 3629 insertions(+)

diff --git a/0000_README b/0000_README
index 9e42d11..1bb262e 100644
--- a/0000_README
+++ b/0000_README
@@ -63,6 +63,10 @@ Patch:  1004_linux-4.6.5.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.5
 
+Patch:  1005_linux-4.6.6.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.6
+
 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/1005_linux-4.6.6.patch b/1005_linux-4.6.6.patch
new file mode 100644
index 0000000..4fe50ff
--- /dev/null
+++ b/1005_linux-4.6.6.patch
@@ -0,0 +1,3625 @@
+diff --git a/Makefile b/Makefile
+index 7d693a825fc7..bee1a1692fed 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 5
++SUBLEVEL = 6
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+diff --git a/arch/arc/Makefile b/arch/arc/Makefile
+index def69e347b2d..f5add9784b2d 100644
+--- a/arch/arc/Makefile
++++ b/arch/arc/Makefile
+@@ -66,8 +66,6 @@ endif
+ 
+ endif
+ 
+-cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -fasynchronous-unwind-tables
+-
+ # By default gcc 4.8 generates dwarf4 which kernel unwinder can't grok
+ ifeq ($(atleast_gcc48),y)
+ cflags-$(CONFIG_ARC_DW2_UNWIND)		+= -gdwarf-2
+diff --git a/arch/arc/kernel/stacktrace.c b/arch/arc/kernel/stacktrace.c
+index e0efff15a5ae..b9192a653b7e 100644
+--- a/arch/arc/kernel/stacktrace.c
++++ b/arch/arc/kernel/stacktrace.c
+@@ -142,7 +142,7 @@ arc_unwind_core(struct task_struct *tsk, struct pt_regs *regs,
+ 	 * prelogue is setup (callee regs saved and then fp set and not other
+ 	 * way around
+ 	 */
+-	pr_warn("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
++	pr_warn_once("CONFIG_ARC_DW2_UNWIND needs to be enabled\n");
+ 	return 0;
+ 
+ #endif
+diff --git a/arch/mips/include/asm/mips-cm.h b/arch/mips/include/asm/mips-cm.h
+index d4635391c36a..ec0510cc5c3c 100644
+--- a/arch/mips/include/asm/mips-cm.h
++++ b/arch/mips/include/asm/mips-cm.h
+@@ -461,7 +461,10 @@ static inline unsigned int mips_cm_max_vp_width(void)
+ 	if (mips_cm_revision() >= CM_REV_CM3)
+ 		return read_gcr_sys_config2() & CM_GCR_SYS_CONFIG2_MAXVPW_MSK;
+ 
+-	return smp_num_siblings;
++	if (config_enabled(CONFIG_SMP))
++		return smp_num_siblings;
++
++	return 1;
+ }
+ 
+ /**
+diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
+index fdcc04020636..538ae944855e 100644
+--- a/arch/x86/include/asm/pvclock.h
++++ b/arch/x86/include/asm/pvclock.h
+@@ -85,6 +85,8 @@ unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src,
+ 	u8 ret_flags;
+ 
+ 	version = src->version;
++	/* Make the latest version visible */
++	smp_rmb();
+ 
+ 	offset = pvclock_get_nsec_offset(src);
+ 	ret = src->system_time + offset;
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
+index bca14c899137..57b71373bae3 100644
+--- a/arch/x86/kernel/early-quirks.c
++++ b/arch/x86/kernel/early-quirks.c
+@@ -11,7 +11,11 @@
+ 
+ #include <linux/pci.h>
+ #include <linux/acpi.h>
++#include <linux/delay.h>
++#include <linux/dmi.h>
+ #include <linux/pci_ids.h>
++#include <linux/bcma/bcma.h>
++#include <linux/bcma/bcma_regs.h>
+ #include <drm/i915_drm.h>
+ #include <asm/pci-direct.h>
+ #include <asm/dma.h>
+@@ -21,6 +25,9 @@
+ #include <asm/iommu.h>
+ #include <asm/gart.h>
+ #include <asm/irq_remapping.h>
++#include <asm/early_ioremap.h>
++
++#define dev_err(msg)  pr_err("pci 0000:%02x:%02x.%d: %s", bus, slot, func, msg)
+ 
+ static void __init fix_hypertransport_config(int num, int slot, int func)
+ {
+@@ -76,6 +83,13 @@ static void __init nvidia_bugs(int num, int slot, int func)
+ #ifdef CONFIG_ACPI
+ #ifdef CONFIG_X86_IO_APIC
+ 	/*
++	 * Only applies to Nvidia root ports (bus 0) and not to
++	 * Nvidia graphics cards with PCI ports on secondary buses.
++	 */
++	if (num)
++		return;
++
++	/*
+ 	 * All timer overrides on Nvidia are
+ 	 * wrong unless HPET is enabled.
+ 	 * Unfortunately that's not true on many Asus boards.
+@@ -590,6 +604,61 @@ static void __init force_disable_hpet(int num, int slot, int func)
+ #endif
+ }
+ 
++#define BCM4331_MMIO_SIZE	16384
++#define BCM4331_PM_CAP		0x40
++#define bcma_aread32(reg)	ioread32(mmio + 1 * BCMA_CORE_SIZE + reg)
++#define bcma_awrite32(reg, val)	iowrite32(val, mmio + 1 * BCMA_CORE_SIZE + reg)
++
++static void __init apple_airport_reset(int bus, int slot, int func)
++{
++	void __iomem *mmio;
++	u16 pmcsr;
++	u64 addr;
++	int i;
++
++	if (!dmi_match(DMI_SYS_VENDOR, "Apple Inc."))
++		return;
++
++	/* Card may have been put into PCI_D3hot by grub quirk */
++	pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
++
++	if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
++		pmcsr &= ~PCI_PM_CTRL_STATE_MASK;
++		write_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL, pmcsr);
++		mdelay(10);
++
++		pmcsr = read_pci_config_16(bus, slot, func, BCM4331_PM_CAP + PCI_PM_CTRL);
++		if ((pmcsr & PCI_PM_CTRL_STATE_MASK) != PCI_D0) {
++			dev_err("Cannot power up Apple AirPort card\n");
++			return;
++		}
++	}
++
++	addr  =      read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_0);
++	addr |= (u64)read_pci_config(bus, slot, func, PCI_BASE_ADDRESS_1) << 32;
++	addr &= PCI_BASE_ADDRESS_MEM_MASK;
++
++	mmio = early_ioremap(addr, BCM4331_MMIO_SIZE);
++	if (!mmio) {
++		dev_err("Cannot iomap Apple AirPort card\n");
++		return;
++	}
++
++	pr_info("Resetting Apple AirPort card (left enabled by EFI)\n");
++
++	for (i = 0; bcma_aread32(BCMA_RESET_ST) && i < 30; i++)
++		udelay(10);
++
++	bcma_awrite32(BCMA_RESET_CTL, BCMA_RESET_CTL_RESET);
++	bcma_aread32(BCMA_RESET_CTL);
++	udelay(1);
++
++	bcma_awrite32(BCMA_RESET_CTL, 0);
++	bcma_aread32(BCMA_RESET_CTL);
++	udelay(10);
++
++	early_iounmap(mmio, BCM4331_MMIO_SIZE);
++}
+ 
+ #define QFLAG_APPLY_ONCE 	0x1
+ #define QFLAG_APPLIED		0x2
+@@ -603,12 +672,6 @@ struct chipset {
+ 	void (*f)(int num, int slot, int func);
+ };
+ 
+-/*
+- * Only works for devices on the root bus. If you add any devices
+- * not on bus 0 readd another loop level in early_quirks(). But
+- * be careful because at least the Nvidia quirk here relies on
+- * only matching on bus 0.
+- */
+ static struct chipset early_qrk[] __initdata = {
+ 	{ PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID,
+ 	  PCI_CLASS_BRIDGE_PCI, PCI_ANY_ID, QFLAG_APPLY_ONCE, nvidia_bugs },
+@@ -638,9 +701,13 @@ static struct chipset early_qrk[] __initdata = {
+ 	 */
+ 	{ PCI_VENDOR_ID_INTEL, 0x0f00,
+ 		PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet},
++	{ PCI_VENDOR_ID_BROADCOM, 0x4331,
++	  PCI_CLASS_NETWORK_OTHER, PCI_ANY_ID, 0, apple_airport_reset},
+ 	{}
+ };
+ 
++static void __init early_pci_scan_bus(int bus);
++
+ /**
+  * check_dev_quirk - apply early quirks to a given PCI device
+  * @num: bus number
+@@ -649,7 +716,7 @@ static struct chipset early_qrk[] __initdata = {
+  *
+  * Check the vendor & device ID against the early quirks table.
+  *
+- * If the device is single function, let early_quirks() know so we don't
++ * If the device is single function, let early_pci_scan_bus() know so we don't
+  * poke at this device again.
+  */
+ static int __init check_dev_quirk(int num, int slot, int func)
+@@ -658,6 +725,7 @@ static int __init check_dev_quirk(int num, int slot, int func)
+ 	u16 vendor;
+ 	u16 device;
+ 	u8 type;
++	u8 sec;
+ 	int i;
+ 
+ 	class = read_pci_config_16(num, slot, func, PCI_CLASS_DEVICE);
+@@ -685,25 +753,36 @@ static int __init check_dev_quirk(int num, int slot, int func)
+ 
+ 	type = read_pci_config_byte(num, slot, func,
+ 				    PCI_HEADER_TYPE);
++
++	if ((type & 0x7f) == PCI_HEADER_TYPE_BRIDGE) {
++		sec = read_pci_config_byte(num, slot, func, PCI_SECONDARY_BUS);
++		if (sec > num)
++			early_pci_scan_bus(sec);
++	}
++
+ 	if (!(type & 0x80))
+ 		return -1;
+ 
+ 	return 0;
+ }
+ 
+-void __init early_quirks(void)
++static void __init early_pci_scan_bus(int bus)
+ {
+ 	int slot, func;
+ 
+-	if (!early_pci_allowed())
+-		return;
+-
+ 	/* Poor man's PCI discovery */
+-	/* Only scan the root bus */
+ 	for (slot = 0; slot < 32; slot++)
+ 		for (func = 0; func < 8; func++) {
+ 			/* Only probe function 0 on single fn devices */
+-			if (check_dev_quirk(0, slot, func))
++			if (check_dev_quirk(bus, slot, func))
+ 				break;
+ 		}
+ }
++
++void __init early_quirks(void)
++{
++	if (!early_pci_allowed())
++		return;
++
++	early_pci_scan_bus(0);
++}
+diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
+index 99bfc025111d..7f82fe0a6807 100644
+--- a/arch/x86/kernel/pvclock.c
++++ b/arch/x86/kernel/pvclock.c
+@@ -66,6 +66,8 @@ u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src)
+ 
+ 	do {
+ 		version = __pvclock_read_cycles(src, &ret, &flags);
++		/* Make sure that the version double-check is last. */
++		smp_rmb();
+ 	} while ((src->version & 1) || version != src->version);
+ 
+ 	return flags & valid_flags;
+@@ -80,6 +82,8 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
+ 
+ 	do {
+ 		version = __pvclock_read_cycles(src, &ret, &flags);
++		/* Make sure that the version double-check is last. */
++		smp_rmb();
+ 	} while ((src->version & 1) || version != src->version);
+ 
+ 	if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) {
+diff --git a/block/ioprio.c b/block/ioprio.c
+index cc7800e9eb44..01b8116298a1 100644
+--- a/block/ioprio.c
++++ b/block/ioprio.c
+@@ -150,8 +150,10 @@ static int get_task_ioprio(struct task_struct *p)
+ 	if (ret)
+ 		goto out;
+ 	ret = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_NONE, IOPRIO_NORM);
++	task_lock(p);
+ 	if (p->io_context)
+ 		ret = p->io_context->ioprio;
++	task_unlock(p);
+ out:
+ 	return ret;
+ }
+diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
+index 55e257c268dd..c40deed8c440 100644
+--- a/drivers/ata/libata-core.c
++++ b/drivers/ata/libata-core.c
+@@ -4141,6 +4141,12 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
+ 	 */
+ 	{ "ST380013AS",		"3.20",		ATA_HORKAGE_MAX_SEC_1024 },
+ 
++	/*
++	 * Device times out with higher max sects.
++	 * https://bugzilla.kernel.org/show_bug.cgi?id=121671
++	 */
++	{ "LITEON CX1-JB256-HP", NULL,		ATA_HORKAGE_MAX_SEC_1024 },
++
+ 	/* Devices we expect to fail diagnostics */
+ 
+ 	/* Devices where NCQ should be avoided */
+diff --git a/drivers/bcma/bcma_private.h b/drivers/bcma/bcma_private.h
+index eda09090cb52..f642c4264c27 100644
+--- a/drivers/bcma/bcma_private.h
++++ b/drivers/bcma/bcma_private.h
+@@ -8,8 +8,6 @@
+ #include <linux/bcma/bcma.h>
+ #include <linux/delay.h>
+ 
+-#define BCMA_CORE_SIZE		0x1000
+-
+ #define bcma_err(bus, fmt, ...) \
+ 	pr_err("bus%d: " fmt, (bus)->num, ##__VA_ARGS__)
+ #define bcma_warn(bus, fmt, ...) \
+diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
+index 6405b6557792..d6ea31d30bf9 100644
+--- a/drivers/block/xen-blkfront.c
++++ b/drivers/block/xen-blkfront.c
+@@ -207,6 +207,9 @@ struct blkfront_info
+ 	struct blk_mq_tag_set tag_set;
+ 	struct blkfront_ring_info *rinfo;
+ 	unsigned int nr_rings;
++	/* Save uncomplete reqs and bios for migration. */
++	struct list_head requests;
++	struct bio_list bio_list;
+ };
+ 
+ static unsigned int nr_minors;
+@@ -874,8 +877,12 @@ static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
+ 			  const struct blk_mq_queue_data *qd)
+ {
+ 	unsigned long flags;
+-	struct blkfront_ring_info *rinfo = (struct blkfront_ring_info *)hctx->driver_data;
++	int qid = hctx->queue_num;
++	struct blkfront_info *info = hctx->queue->queuedata;
++	struct blkfront_ring_info *rinfo = NULL;
+ 
++	BUG_ON(info->nr_rings <= qid);
++	rinfo = &info->rinfo[qid];
+ 	blk_mq_start_request(qd->rq);
+ 	spin_lock_irqsave(&rinfo->ring_lock, flags);
+ 	if (RING_FULL(&rinfo->ring))
+@@ -901,20 +908,9 @@ out_busy:
+ 	return BLK_MQ_RQ_QUEUE_BUSY;
+ }
+ 
+-static int blk_mq_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
+-			    unsigned int index)
+-{
+-	struct blkfront_info *info = (struct blkfront_info *)data;
+-
+-	BUG_ON(info->nr_rings <= index);
+-	hctx->driver_data = &info->rinfo[index];
+-	return 0;
+-}
+-
+ static struct blk_mq_ops blkfront_mq_ops = {
+ 	.queue_rq = blkif_queue_rq,
+ 	.map_queue = blk_mq_map_queue,
+-	.init_hctx = blk_mq_init_hctx,
+ };
+ 
+ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
+@@ -950,6 +946,7 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
+ 		return PTR_ERR(rq);
+ 	}
+ 
++	rq->queuedata = info;
+ 	queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);
+ 
+ 	if (info->feature_discard) {
+@@ -2007,69 +2004,22 @@ static int blkif_recover(struct blkfront_info *info)
+ {
+ 	unsigned int i, r_index;
+ 	struct request *req, *n;
+-	struct blk_shadow *copy;
+ 	int rc;
+ 	struct bio *bio, *cloned_bio;
+-	struct bio_list bio_list, merge_bio;
+ 	unsigned int segs, offset;
+ 	int pending, size;
+ 	struct split_bio *split_bio;
+-	struct list_head requests;
+ 
+ 	blkfront_gather_backend_features(info);
+ 	segs = info->max_indirect_segments ? : BLKIF_MAX_SEGMENTS_PER_REQUEST;
+ 	blk_queue_max_segments(info->rq, segs);
+-	bio_list_init(&bio_list);
+-	INIT_LIST_HEAD(&requests);
+ 
+ 	for (r_index = 0; r_index < info->nr_rings; r_index++) {
+-		struct blkfront_ring_info *rinfo;
+-
+-		rinfo = &info->rinfo[r_index];
+-		/* Stage 1: Make a safe copy of the shadow state. */
+-		copy = kmemdup(rinfo->shadow, sizeof(rinfo->shadow),
+-			       GFP_NOIO | __GFP_REPEAT | __GFP_HIGH);
+-		if (!copy)
+-			return -ENOMEM;
+-
+-		/* Stage 2: Set up free list. */
+-		memset(&rinfo->shadow, 0, sizeof(rinfo->shadow));
+-		for (i = 0; i < BLK_RING_SIZE(info); i++)
+-			rinfo->shadow[i].req.u.rw.id = i+1;
+-		rinfo->shadow_free = rinfo->ring.req_prod_pvt;
+-		rinfo->shadow[BLK_RING_SIZE(info)-1].req.u.rw.id = 0x0fffffff;
++		struct blkfront_ring_info *rinfo = &info->rinfo[r_index];
+ 
+ 		rc = blkfront_setup_indirect(rinfo);
+-		if (rc) {
+-			kfree(copy);
++		if (rc)
+ 			return rc;
+-		}
+-
+-		for (i = 0; i < BLK_RING_SIZE(info); i++) {
+-			/* Not in use? */
+-			if (!copy[i].request)
+-				continue;
+-
+-			/*
+-			 * Get the bios in the request so we can re-queue them.
+-			 */
+-			if (copy[i].request->cmd_flags &
+-			    (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
+-				/*
+-				 * Flush operations don't contain bios, so
+-				 * we need to requeue the whole request
+-				 */
+-				list_add(&copy[i].request->queuelist, &requests);
+-				continue;
+-			}
+-			merge_bio.head = copy[i].request->bio;
+-			merge_bio.tail = copy[i].request->biotail;
+-			bio_list_merge(&bio_list, &merge_bio);
+-			copy[i].request->bio = NULL;
+-			blk_end_request_all(copy[i].request, 0);
+-		}
+-
+-		kfree(copy);
+ 	}
+ 	xenbus_switch_state(info->xbdev, XenbusStateConnected);
+ 
+@@ -2084,7 +2034,7 @@ static int blkif_recover(struct blkfront_info *info)
+ 		kick_pending_request_queues(rinfo);
+ 	}
+ 
+-	list_for_each_entry_safe(req, n, &requests, queuelist) {
++	list_for_each_entry_safe(req, n, &info->requests, queuelist) {
+ 		/* Requeue pending requests (flush or discard) */
+ 		list_del_init(&req->queuelist);
+ 		BUG_ON(req->nr_phys_segments > segs);
+@@ -2092,7 +2042,7 @@ static int blkif_recover(struct blkfront_info *info)
+ 	}
+ 	blk_mq_kick_requeue_list(info->rq);
+ 
+-	while ((bio = bio_list_pop(&bio_list)) != NULL) {
++	while ((bio = bio_list_pop(&info->bio_list)) != NULL) {
+ 		/* Traverse the list of pending bios and re-queue them */
+ 		if (bio_segments(bio) > segs) {
+ 			/*
+@@ -2138,9 +2088,42 @@ static int blkfront_resume(struct xenbus_device *dev)
+ {
+ 	struct blkfront_info *info = dev_get_drvdata(&dev->dev);
+ 	int err = 0;
++	unsigned int i, j;
+ 
+ 	dev_dbg(&dev->dev, "blkfront_resume: %s\n", dev->nodename);
+ 
++	bio_list_init(&info->bio_list);
++	INIT_LIST_HEAD(&info->requests);
++	for (i = 0; i < info->nr_rings; i++) {
++		struct blkfront_ring_info *rinfo = &info->rinfo[i];
++		struct bio_list merge_bio;
++		struct blk_shadow *shadow = rinfo->shadow;
++
++		for (j = 0; j < BLK_RING_SIZE(info); j++) {
++			/* Not in use? */
++			if (!shadow[j].request)
++				continue;
++
++			/*
++			 * Get the bios in the request so we can re-queue them.
++			 */
++			if (shadow[j].request->cmd_flags &
++					(REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
++				/*
++				 * Flush operations don't contain bios, so
++				 * we need to requeue the whole request
++				 */
++				list_add(&shadow[j].request->queuelist, &info->requests);
++				continue;
++			}
++			merge_bio.head = shadow[j].request->bio;
++			merge_bio.tail = shadow[j].request->biotail;
++			bio_list_merge(&info->bio_list, &merge_bio);
++			shadow[j].request->bio = NULL;
++			blk_mq_end_request(shadow[j].request, 0);
++		}
++	}
++
+ 	blkif_free(info, info->connected == BLKIF_STATE_CONNECTED);
+ 
+ 	err = negotiate_mq(info);
+@@ -2148,6 +2131,8 @@ static int blkfront_resume(struct xenbus_device *dev)
+ 		return err;
+ 
+ 	err = talk_to_blkback(dev, info);
++	if (!err)
++		blk_mq_update_nr_hw_queues(&info->tag_set, info->nr_rings);
+ 
+ 	/*
+ 	 * We have to wait for the backend to switch to
+@@ -2484,10 +2469,23 @@ static void blkback_changed(struct xenbus_device *dev,
+ 		break;
+ 
+ 	case XenbusStateConnected:
+-		if (dev->state != XenbusStateInitialised) {
++		/*
++		 * talk_to_blkback sets state to XenbusStateInitialised
++		 * and blkfront_connect sets it to XenbusStateConnected
++		 * (if connection went OK).
++		 *
++		 * If the backend (or toolstack) decides to poke at backend
++		 * state (and re-trigger the watch by setting the state repeatedly
++		 * to XenbusStateConnected (4)) we need to deal with this.
++		 * This is allowed as this is used to communicate to the guest
++		 * that the size of disk has changed!
++		 */
++		if ((dev->state != XenbusStateInitialised) &&
++		    (dev->state != XenbusStateConnected)) {
+ 			if (talk_to_blkback(dev, info))
+ 				break;
+ 		}
++
+ 		blkfront_connect(info);
+ 		break;
+ 
+diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c
+index 10f846cc8db1..25d5906640c3 100644
+--- a/drivers/clk/at91/clk-programmable.c
++++ b/drivers/clk/at91/clk-programmable.c
+@@ -99,7 +99,7 @@ static int clk_programmable_set_parent(struct clk_hw *hw, u8 index)
+ 	struct clk_programmable *prog = to_clk_programmable(hw);
+ 	const struct clk_programmable_layout *layout = prog->layout;
+ 	unsigned int mask = layout->css_mask;
+-	unsigned int pckr = 0;
++	unsigned int pckr = index;
+ 
+ 	if (layout->have_slck_mck)
+ 		mask |= AT91_PMC_CSSMCK_MCK;
+diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
+index e0dc7e83403a..102399f3c550 100644
+--- a/drivers/clk/rockchip/clk-mmc-phase.c
++++ b/drivers/clk/rockchip/clk-mmc-phase.c
+@@ -153,6 +153,7 @@ struct clk *rockchip_clk_register_mmc(const char *name,
+ 		return ERR_PTR(-ENOMEM);
+ 
+ 	init.name = name;
++	init.flags = 0;
+ 	init.num_parents = num_parents;
+ 	init.parent_names = parent_names;
+ 	init.ops = &rockchip_mmc_clk_ops;
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
+index c4acfc5273b3..e380457792ae 100644
+--- a/drivers/cpufreq/cpufreq.c
++++ b/drivers/cpufreq/cpufreq.c
+@@ -2169,6 +2169,10 @@ int cpufreq_update_policy(unsigned int cpu)
+ 	 * -> ask driver for current freq and notify governors about a change
+ 	 */
+ 	if (cpufreq_driver->get && !cpufreq_driver->setpolicy) {
++		if (cpufreq_suspended) {
++			ret = -EAGAIN;
++			goto unlock;
++		}
+ 		new_policy.cur = cpufreq_update_current_freq(policy);
+ 		if (WARN_ON(!new_policy.cur)) {
+ 			ret = -EIO;
+diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c
+index 8e304b1befc5..75bd6621dc5d 100644
+--- a/drivers/dma/at_xdmac.c
++++ b/drivers/dma/at_xdmac.c
+@@ -242,7 +242,7 @@ struct at_xdmac_lld {
+ 	u32		mbr_dus;	/* Destination Microblock Stride Register */
+ };
+ 
+-
++/* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */
+ struct at_xdmac_desc {
+ 	struct at_xdmac_lld		lld;
+ 	enum dma_transfer_direction	direction;
+@@ -253,7 +253,7 @@ struct at_xdmac_desc {
+ 	unsigned int			xfer_size;
+ 	struct list_head		descs_list;
+ 	struct list_head		xfer_node;
+-};
++} __aligned(sizeof(u64));
+ 
+ static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb)
+ {
+@@ -1400,6 +1400,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+ 	u32			cur_nda, check_nda, cur_ubc, mask, value;
+ 	u8			dwidth = 0;
+ 	unsigned long		flags;
++	bool			initd;
+ 
+ 	ret = dma_cookie_status(chan, cookie, txstate);
+ 	if (ret == DMA_COMPLETE)
+@@ -1424,7 +1425,16 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+ 	residue = desc->xfer_size;
+ 	/*
+ 	 * Flush FIFO: only relevant when the transfer is source peripheral
+-	 * synchronized.
++	 * synchronized. Flush is needed before reading CUBC because data in
++	 * the FIFO are not reported by CUBC. Reporting a residue of the
++	 * transfer length while we have data in FIFO can cause issue.
++	 * Usecase: atmel USART has a timeout which means I have received
++	 * characters but there is no more character received for a while. On
++	 * timeout, it requests the residue. If the data are in the DMA FIFO,
++	 * we will return a residue of the transfer length. It means no data
++	 * received. If an application is waiting for these data, it will hang
++	 * since we won't have another USART timeout without receiving new
++	 * data.
+ 	 */
+ 	mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC;
+ 	value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM;
+@@ -1435,34 +1445,43 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+ 	}
+ 
+ 	/*
+-	 * When processing the residue, we need to read two registers but we
+-	 * can't do it in an atomic way. AT_XDMAC_CNDA is used to find where
+-	 * we stand in the descriptor list and AT_XDMAC_CUBC is used
+-	 * to know how many data are remaining for the current descriptor.
+-	 * Since the dma channel is not paused to not loose data, between the
+-	 * AT_XDMAC_CNDA and AT_XDMAC_CUBC read, we may have change of
+-	 * descriptor.
+-	 * For that reason, after reading AT_XDMAC_CUBC, we check if we are
+-	 * still using the same descriptor by reading a second time
+-	 * AT_XDMAC_CNDA. If AT_XDMAC_CNDA has changed, it means we have to
+-	 * read again AT_XDMAC_CUBC.
++	 * The easiest way to compute the residue should be to pause the DMA
++	 * but doing this can lead to miss some data as some devices don't
++	 * have FIFO.
++	 * We need to read several registers because:
++	 * - DMA is running therefore a descriptor change is possible while
++	 * reading these registers
++	 * - When the block transfer is done, the value of the CUBC register
++	 * is set to its initial value until the fetch of the next descriptor.
++	 * This value will corrupt the residue calculation so we have to skip
++	 * it.
++	 *
++	 * INITD --------                    ------------
++	 *              |____________________|
++	 *       _______________________  _______________
++	 * NDA       @desc2             \/   @desc3
++	 *       _______________________/\_______________
++	 *       __________  ___________  _______________
++	 * CUBC       0    \/ MAX desc1 \/  MAX desc2
++	 *       __________/\___________/\_______________
++	 *
++	 * Since descriptors are aligned on 64 bits, we can assume that
++	 * the update of NDA and CUBC is atomic.
+ 	 * Memory barriers are used to ensure the read order of the registers.
+-	 * A max number of retries is set because unlikely it can never ends if
+-	 * we are transferring a lot of data with small buffers.
++	 * A max number of retries is set because unlikely it could never ends.
+ 	 */
+-	cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
+-	rmb();
+-	cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
+ 	for (retry = 0; retry < AT_XDMAC_RESIDUE_MAX_RETRIES; retry++) {
+-		rmb();
+ 		check_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
+-
+-		if (likely(cur_nda == check_nda))
+-			break;
+-
+-		cur_nda = check_nda;
++		rmb();
++		initd = !!(at_xdmac_chan_read(atchan, AT_XDMAC_CC) & AT_XDMAC_CC_INITD);
+ 		rmb();
+ 		cur_ubc = at_xdmac_chan_read(atchan, AT_XDMAC_CUBC);
++		rmb();
++		cur_nda = at_xdmac_chan_read(atchan, AT_XDMAC_CNDA) & 0xfffffffc;
++		rmb();
++
++		if ((check_nda == cur_nda) && initd)
++			break;
+ 	}
+ 
+ 	if (unlikely(retry >= AT_XDMAC_RESIDUE_MAX_RETRIES)) {
+@@ -1471,6 +1490,19 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
+ 	}
+ 
+ 	/*
++	 * Flush FIFO: only relevant when the transfer is source peripheral
++	 * synchronized. Another flush is needed here because CUBC is updated
++	 * when the controller sends the data write command. It can lead to
++	 * report data that are not written in the memory or the device. The
++	 * FIFO flush ensures that data are really written.
++	 */
++	if ((desc->lld.mbr_cfg & mask) == value) {
++		at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask);
++		while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS))
++			cpu_relax();
++	}
++
++	/*
+ 	 * Remove size of all microblocks already transferred and the current
+ 	 * one. Then add the remaining size to transfer of the current
+ 	 * microblock.
+diff --git a/drivers/hwtracing/intel_th/core.c b/drivers/hwtracing/intel_th/core.c
+index 4272f2ce5f6e..dca16540e7fd 100644
+--- a/drivers/hwtracing/intel_th/core.c
++++ b/drivers/hwtracing/intel_th/core.c
+@@ -440,6 +440,38 @@ static struct intel_th_subdevice {
+ 	},
+ };
+ 
++#ifdef CONFIG_MODULES
++static void __intel_th_request_hub_module(struct work_struct *work)
++{
++	struct intel_th *th = container_of(work, struct intel_th,
++					   request_module_work);
++
++	request_module("intel_th_%s", th->hub->name);
++}
++
++static int intel_th_request_hub_module(struct intel_th *th)
++{
++	INIT_WORK(&th->request_module_work, __intel_th_request_hub_module);
++	schedule_work(&th->request_module_work);
++
++	return 0;
++}
++
++static void intel_th_request_hub_module_flush(struct intel_th *th)
++{
++	flush_work(&th->request_module_work);
++}
++#else
++static inline int intel_th_request_hub_module(struct intel_th *th)
++{
++	return -EINVAL;
++}
++
++static inline void intel_th_request_hub_module_flush(struct intel_th *th)
++{
++}
++#endif /* CONFIG_MODULES */
++
+ static int intel_th_populate(struct intel_th *th, struct resource *devres,
+ 			     unsigned int ndevres, int irq)
+ {
+@@ -510,7 +542,7 @@ static int intel_th_populate(struct intel_th *th, struct resource *devres,
+ 		/* need switch driver to be loaded to enumerate the rest */
+ 		if (subdev->type == INTEL_TH_SWITCH && !req) {
+ 			th->hub = thdev;
+-			err = request_module("intel_th_%s", subdev->name);
++			err = intel_th_request_hub_module(th);
+ 			if (!err)
+ 				req++;
+ 		}
+@@ -627,6 +659,7 @@ void intel_th_free(struct intel_th *th)
+ {
+ 	int i;
+ 
++	intel_th_request_hub_module_flush(th);
+ 	for (i = 0; i < TH_SUBDEVICE_MAX; i++)
+ 		if (th->thdev[i] != th->hub)
+ 			intel_th_device_remove(th->thdev[i]);
+diff --git a/drivers/hwtracing/intel_th/intel_th.h b/drivers/hwtracing/intel_th/intel_th.h
+index eedd09332db6..72cd3c6018e1 100644
+--- a/drivers/hwtracing/intel_th/intel_th.h
++++ b/drivers/hwtracing/intel_th/intel_th.h
+@@ -199,6 +199,9 @@ struct intel_th {
+ 
+ 	int			id;
+ 	int			major;
++#ifdef CONFIG_MODULES
++	struct work_struct	request_module_work;
++#endif /* CONFIG_MODULES */
+ #ifdef CONFIG_INTEL_TH_DEBUG
+ 	struct dentry		*dbg;
+ #endif
+diff --git a/drivers/hwtracing/intel_th/pci.c b/drivers/hwtracing/intel_th/pci.c
+index bca7a2ac00d6..72c9189fac8a 100644
+--- a/drivers/hwtracing/intel_th/pci.c
++++ b/drivers/hwtracing/intel_th/pci.c
+@@ -75,6 +75,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
+ 		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0a80),
+ 		.driver_data = (kernel_ulong_t)0,
+ 	},
++	{
++		/* Kaby Lake PCH-H */
++		PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0xa2a6),
++		.driver_data = (kernel_ulong_t)0,
++	},
+ 	{ 0 },
+ };
+ 
+diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c
+index 23eaabb19f96..a5eb09c5539f 100644
+--- a/drivers/i2c/busses/i2c-qup.c
++++ b/drivers/i2c/busses/i2c-qup.c
+@@ -1268,6 +1268,8 @@ static int qup_i2c_xfer_v2(struct i2c_adapter *adap,
+ 		}
+ 	}
+ 
++	idx = 0;
++
+ 	do {
+ 		if (msgs[idx].len == 0) {
+ 			ret = -EINVAL;
+diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-reg.c
+index 5fbd5bd0878f..49fc2c7e560a 100644
+--- a/drivers/i2c/muxes/i2c-mux-reg.c
++++ b/drivers/i2c/muxes/i2c-mux-reg.c
+@@ -150,7 +150,7 @@ static int i2c_mux_reg_probe_dt(struct regmux *mux,
+ 		mux->data.idle_in_use = true;
+ 
+ 	/* map address from "reg" if exists */
+-	if (of_address_to_resource(np, 0, &res)) {
++	if (of_address_to_resource(np, 0, &res) == 0) {
+ 		mux->data.reg_size = resource_size(&res);
+ 		mux->data.reg = devm_ioremap_resource(&pdev->dev, &res);
+ 		if (IS_ERR(mux->data.reg))
+diff --git a/drivers/input/joystick/xpad.c b/drivers/input/joystick/xpad.c
+index ca62a6e11846..4a6104beb60d 100644
+--- a/drivers/input/joystick/xpad.c
++++ b/drivers/input/joystick/xpad.c
+@@ -1421,22 +1421,15 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
+ 	int ep_irq_in_idx;
+ 	int i, error;
+ 
++	if (intf->cur_altsetting->desc.bNumEndpoints != 2)
++		return -ENODEV;
++
+ 	for (i = 0; xpad_device[i].idVendor; i++) {
+ 		if ((le16_to_cpu(udev->descriptor.idVendor) == xpad_device[i].idVendor) &&
+ 		    (le16_to_cpu(udev->descriptor.idProduct) == xpad_device[i].idProduct))
+ 			break;
+ 	}
+ 
+-	if (xpad_device[i].xtype == XTYPE_XBOXONE &&
+-	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
+-		/*
+-		 * The Xbox One controller lists three interfaces all with the
+-		 * same interface class, subclass and protocol. Differentiate by
+-		 * interface number.
+-		 */
+-		return -ENODEV;
+-	}
+-
+ 	xpad = kzalloc(sizeof(struct usb_xpad), GFP_KERNEL);
+ 	if (!xpad)
+ 		return -ENOMEM;
+@@ -1468,6 +1461,8 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
+ 		if (intf->cur_altsetting->desc.bInterfaceClass == USB_CLASS_VENDOR_SPEC) {
+ 			if (intf->cur_altsetting->desc.bInterfaceProtocol == 129)
+ 				xpad->xtype = XTYPE_XBOX360W;
++			else if (intf->cur_altsetting->desc.bInterfaceProtocol == 208)
++				xpad->xtype = XTYPE_XBOXONE;
+ 			else
+ 				xpad->xtype = XTYPE_XBOX360;
+ 		} else {
+@@ -1482,6 +1477,17 @@ static int xpad_probe(struct usb_interface *intf, const struct usb_device_id *id
+ 			xpad->mapping |= MAP_STICKS_TO_NULL;
+ 	}
+ 
++	if (xpad->xtype == XTYPE_XBOXONE &&
++	    intf->cur_altsetting->desc.bInterfaceNumber != 0) {
++		/*
++		 * The Xbox One controller lists three interfaces all with the
++		 * same interface class, subclass and protocol. Differentiate by
++		 * interface number.
++		 */
++		error = -ENODEV;
++		goto err_free_in_urb;
++	}
++
+ 	error = xpad_init_output(intf, xpad);
+ 	if (error)
+ 		goto err_free_in_urb;
+diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c
+index 78f93cf68840..be5b399da5d3 100644
+--- a/drivers/input/mouse/elantech.c
++++ b/drivers/input/mouse/elantech.c
+@@ -1568,13 +1568,7 @@ static int elantech_set_properties(struct elantech_data *etd)
+ 		case 5:
+ 			etd->hw_version = 3;
+ 			break;
+-		case 6:
+-		case 7:
+-		case 8:
+-		case 9:
+-		case 10:
+-		case 13:
+-		case 14:
++		case 6 ... 14:
+ 			etd->hw_version = 4;
+ 			break;
+ 		default:
+diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
+index a3f0f5a47490..0f586780ceb4 100644
+--- a/drivers/input/mouse/vmmouse.c
++++ b/drivers/input/mouse/vmmouse.c
+@@ -355,18 +355,11 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
+ 		return -ENXIO;
+ 	}
+ 
+-	if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) {
+-		psmouse_dbg(psmouse, "VMMouse port in use.\n");
+-		return -EBUSY;
+-	}
+-
+ 	/* Check if the device is present */
+ 	response = ~VMMOUSE_PROTO_MAGIC;
+ 	VMMOUSE_CMD(GETVERSION, 0, version, response, dummy1, dummy2);
+-	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU) {
+-		release_region(VMMOUSE_PROTO_PORT, 4);
++	if (response != VMMOUSE_PROTO_MAGIC || version == 0xffffffffU)
+ 		return -ENXIO;
+-	}
+ 
+ 	if (set_properties) {
+ 		psmouse->vendor = VMMOUSE_VENDOR;
+@@ -374,8 +367,6 @@ int vmmouse_detect(struct psmouse *psmouse, bool set_properties)
+ 		psmouse->model = version;
+ 	}
+ 
+-	release_region(VMMOUSE_PROTO_PORT, 4);
+-
+ 	return 0;
+ }
+ 
+@@ -394,7 +385,6 @@ static void vmmouse_disconnect(struct psmouse *psmouse)
+ 	psmouse_reset(psmouse);
+ 	input_unregister_device(priv->abs_dev);
+ 	kfree(priv);
+-	release_region(VMMOUSE_PROTO_PORT, 4);
+ }
+ 
+ /**
+@@ -438,15 +428,10 @@ int vmmouse_init(struct psmouse *psmouse)
+ 	struct input_dev *rel_dev = psmouse->dev, *abs_dev;
+ 	int error;
+ 
+-	if (!request_region(VMMOUSE_PROTO_PORT, 4, "vmmouse")) {
+-		psmouse_dbg(psmouse, "VMMouse port in use.\n");
+-		return -EBUSY;
+-	}
+-
+ 	psmouse_reset(psmouse);
+ 	error = vmmouse_enable(psmouse);
+ 	if (error)
+-		goto release_region;
++		return error;
+ 
+ 	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ 	abs_dev = input_allocate_device();
+@@ -502,8 +487,5 @@ init_fail:
+ 	kfree(priv);
+ 	psmouse->private = NULL;
+ 
+-release_region:
+-	release_region(VMMOUSE_PROTO_PORT, 4);
+-
+ 	return error;
+ }
+diff --git a/drivers/input/rmi4/rmi_f12.c b/drivers/input/rmi4/rmi_f12.c
+index 8dd3fb5e1f94..88e91559c84e 100644
+--- a/drivers/input/rmi4/rmi_f12.c
++++ b/drivers/input/rmi4/rmi_f12.c
+@@ -66,7 +66,7 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
+ 	struct rmi_device *rmi_dev = fn->rmi_dev;
+ 	int ret;
+ 	int offset;
+-	u8 buf[14];
++	u8 buf[15];
+ 	int pitch_x = 0;
+ 	int pitch_y = 0;
+ 	int clip_x_low = 0;
+@@ -86,9 +86,10 @@ static int rmi_f12_read_sensor_tuning(struct f12_data *f12)
+ 
+ 	offset = rmi_register_desc_calc_reg_offset(&f12->control_reg_desc, 8);
+ 
+-	if (item->reg_size > 14) {
+-		dev_err(&fn->dev, "F12 control8 should be 14 bytes, not: %ld\n",
+-			item->reg_size);
++	if (item->reg_size > sizeof(buf)) {
++		dev_err(&fn->dev,
++			"F12 control8 should be no bigger than %zd bytes, not: %ld\n",
++			sizeof(buf), item->reg_size);
+ 		return -ENODEV;
+ 	}
+ 
+diff --git a/drivers/input/touchscreen/tsc2004.c b/drivers/input/touchscreen/tsc2004.c
+index 7295c198aa08..6fe55d598fac 100644
+--- a/drivers/input/touchscreen/tsc2004.c
++++ b/drivers/input/touchscreen/tsc2004.c
+@@ -22,6 +22,11 @@
+ #include <linux/regmap.h>
+ #include "tsc200x-core.h"
+ 
++static const struct input_id tsc2004_input_id = {
++	.bustype = BUS_I2C,
++	.product = 2004,
++};
++
+ static int tsc2004_cmd(struct device *dev, u8 cmd)
+ {
+ 	u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
+@@ -42,7 +47,7 @@ static int tsc2004_probe(struct i2c_client *i2c,
+ 			 const struct i2c_device_id *id)
+ 
+ {
+-	return tsc200x_probe(&i2c->dev, i2c->irq, BUS_I2C,
++	return tsc200x_probe(&i2c->dev, i2c->irq, &tsc2004_input_id,
+ 			     devm_regmap_init_i2c(i2c, &tsc200x_regmap_config),
+ 			     tsc2004_cmd);
+ }
+diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c
+index b9f593dfd2ef..f2c5f0e47f77 100644
+--- a/drivers/input/touchscreen/tsc2005.c
++++ b/drivers/input/touchscreen/tsc2005.c
+@@ -24,6 +24,11 @@
+ #include <linux/regmap.h>
+ #include "tsc200x-core.h"
+ 
++static const struct input_id tsc2005_input_id = {
++	.bustype = BUS_SPI,
++	.product = 2005,
++};
++
+ static int tsc2005_cmd(struct device *dev, u8 cmd)
+ {
+ 	u8 tx = TSC200X_CMD | TSC200X_CMD_12BIT | cmd;
+@@ -62,7 +67,7 @@ static int tsc2005_probe(struct spi_device *spi)
+ 	if (error)
+ 		return error;
+ 
+-	return tsc200x_probe(&spi->dev, spi->irq, BUS_SPI,
++	return tsc200x_probe(&spi->dev, spi->irq, &tsc2005_input_id,
+ 			     devm_regmap_init_spi(spi, &tsc200x_regmap_config),
+ 			     tsc2005_cmd);
+ }
+diff --git a/drivers/input/touchscreen/tsc200x-core.c b/drivers/input/touchscreen/tsc200x-core.c
+index 15240c1ee850..dfa7f1c4f545 100644
+--- a/drivers/input/touchscreen/tsc200x-core.c
++++ b/drivers/input/touchscreen/tsc200x-core.c
+@@ -450,7 +450,7 @@ static void tsc200x_close(struct input_dev *input)
+ 	mutex_unlock(&ts->mutex);
+ }
+ 
+-int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
++int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
+ 		  struct regmap *regmap,
+ 		  int (*tsc200x_cmd)(struct device *dev, u8 cmd))
+ {
+@@ -547,9 +547,18 @@ int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
+ 	snprintf(ts->phys, sizeof(ts->phys),
+ 		 "%s/input-ts", dev_name(dev));
+ 
+-	input_dev->name = "TSC200X touchscreen";
++	if (tsc_id->product == 2004) {
++		input_dev->name = "TSC200X touchscreen";
++	} else {
++		input_dev->name = devm_kasprintf(dev, GFP_KERNEL,
++						 "TSC%04d touchscreen",
++						 tsc_id->product);
++		if (!input_dev->name)
++			return -ENOMEM;
++	}
++
+ 	input_dev->phys = ts->phys;
+-	input_dev->id.bustype = bustype;
++	input_dev->id = *tsc_id;
+ 	input_dev->dev.parent = dev;
+ 	input_dev->evbit[0] = BIT(EV_ABS) | BIT(EV_KEY);
+ 	input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+diff --git a/drivers/input/touchscreen/tsc200x-core.h b/drivers/input/touchscreen/tsc200x-core.h
+index 7a482d102614..49a63a3c6840 100644
+--- a/drivers/input/touchscreen/tsc200x-core.h
++++ b/drivers/input/touchscreen/tsc200x-core.h
+@@ -70,7 +70,7 @@
+ extern const struct regmap_config tsc200x_regmap_config;
+ extern const struct dev_pm_ops tsc200x_pm_ops;
+ 
+-int tsc200x_probe(struct device *dev, int irq, __u16 bustype,
++int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
+ 		  struct regmap *regmap,
+ 		  int (*tsc200x_cmd)(struct device *dev, u8 cmd));
+ int tsc200x_remove(struct device *dev);
+diff --git a/drivers/input/touchscreen/wacom_w8001.c b/drivers/input/touchscreen/wacom_w8001.c
+index bab3c6acf6a2..b6fc4bde79de 100644
+--- a/drivers/input/touchscreen/wacom_w8001.c
++++ b/drivers/input/touchscreen/wacom_w8001.c
+@@ -27,7 +27,7 @@ MODULE_AUTHOR("Jaya Kumar <jayakumar.lkml@gmail.com>");
+ MODULE_DESCRIPTION(DRIVER_DESC);
+ MODULE_LICENSE("GPL");
+ 
+-#define W8001_MAX_LENGTH	11
++#define W8001_MAX_LENGTH	13
+ #define W8001_LEAD_MASK		0x80
+ #define W8001_LEAD_BYTE		0x80
+ #define W8001_TAB_MASK		0x40
+@@ -155,6 +155,7 @@ static void parse_multi_touch(struct w8001 *w8001)
+ 		bool touch = data[0] & (1 << i);
+ 
+ 		input_mt_slot(dev, i);
++		input_mt_report_slot_state(dev, MT_TOOL_FINGER, touch);
+ 		if (touch) {
+ 			x = (data[6 * i + 1] << 7) | data[6 * i + 2];
+ 			y = (data[6 * i + 3] << 7) | data[6 * i + 4];
+@@ -339,6 +340,15 @@ static irqreturn_t w8001_interrupt(struct serio *serio,
+ 		w8001->idx = 0;
+ 		parse_multi_touch(w8001);
+ 		break;
++
++	default:
++		/*
++		 * ThinkPad X60 Tablet PC (pen only device) sometimes
++		 * sends invalid data packets that are larger than
++		 * W8001_PKTLEN_TPCPEN. Let's start over again.
++		 */
++		if (!w8001->touch_dev && w8001->idx > W8001_PKTLEN_TPCPEN - 1)
++			w8001->idx = 0;
+ 	}
+ 
+ 	return IRQ_HANDLED;
+@@ -513,6 +523,8 @@ static int w8001_setup_touch(struct w8001 *w8001, char *basename,
+ 					0, touch.x, 0, 0);
+ 		input_set_abs_params(dev, ABS_MT_POSITION_Y,
+ 					0, touch.y, 0, 0);
++		input_set_abs_params(dev, ABS_MT_TOOL_TYPE,
++					0, MT_TOOL_MAX, 0, 0);
+ 
+ 		strlcat(basename, " 2FG", basename_sz);
+ 		if (w8001->max_pen_x && w8001->max_pen_y)
+diff --git a/drivers/irqchip/irq-mips-gic.c b/drivers/irqchip/irq-mips-gic.c
+index 40fb1209d512..83f93404c446 100644
+--- a/drivers/irqchip/irq-mips-gic.c
++++ b/drivers/irqchip/irq-mips-gic.c
+@@ -706,7 +706,7 @@ static int gic_shared_irq_domain_map(struct irq_domain *d, unsigned int virq,
+ 
+ 	spin_lock_irqsave(&gic_lock, flags);
+ 	gic_map_to_pin(intr, gic_cpu_pin);
+-	gic_map_to_vpe(intr, vpe);
++	gic_map_to_vpe(intr, mips_cm_vp_id(vpe));
+ 	for (i = 0; i < min(gic_vpes, NR_CPUS); i++)
+ 		clear_bit(intr, pcpu_masks[i].pcpu_mask);
+ 	set_bit(intr, pcpu_masks[vpe].pcpu_mask);
+@@ -947,7 +947,7 @@ int gic_ipi_domain_match(struct irq_domain *d, struct device_node *node,
+ 	switch (bus_token) {
+ 	case DOMAIN_BUS_IPI:
+ 		is_ipi = d->bus_token == bus_token;
+-		return to_of_node(d->fwnode) == node && is_ipi;
++		return (!node || to_of_node(d->fwnode) == node) && is_ipi;
+ 		break;
+ 	default:
+ 		return 0;
+diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
+index 41a1bfc5eaa7..3646aaf7188c 100644
+--- a/drivers/media/i2c/adv7604.c
++++ b/drivers/media/i2c/adv7604.c
+@@ -779,11 +779,31 @@ static const struct v4l2_dv_timings_cap adv76xx_timings_cap_digital = {
+ 			V4L2_DV_BT_CAP_CUSTOM)
+ };
+ 
+-static inline const struct v4l2_dv_timings_cap *
+-adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd)
++/*
++ * Return the DV timings capabilities for the requested sink pad. As a special
++ * case, pad value -1 returns the capabilities for the currently selected input.
++ */
++static const struct v4l2_dv_timings_cap *
++adv76xx_get_dv_timings_cap(struct v4l2_subdev *sd, int pad)
+ {
+-	return is_digital_input(sd) ? &adv76xx_timings_cap_digital :
+-				      &adv7604_timings_cap_analog;
++	if (pad == -1) {
++		struct adv76xx_state *state = to_state(sd);
++
++		pad = state->selected_input;
++	}
++
++	switch (pad) {
++	case ADV76XX_PAD_HDMI_PORT_A:
++	case ADV7604_PAD_HDMI_PORT_B:
++	case ADV7604_PAD_HDMI_PORT_C:
++	case ADV7604_PAD_HDMI_PORT_D:
++		return &adv76xx_timings_cap_digital;
++
++	case ADV7604_PAD_VGA_RGB:
++	case ADV7604_PAD_VGA_COMP:
++	default:
++		return &adv7604_timings_cap_analog;
++	}
+ }
+ 
+ 
+@@ -1329,7 +1349,7 @@ static int stdi2dv_timings(struct v4l2_subdev *sd,
+ 		const struct v4l2_bt_timings *bt = &v4l2_dv_timings_presets[i].bt;
+ 
+ 		if (!v4l2_valid_dv_timings(&v4l2_dv_timings_presets[i],
+-					   adv76xx_get_dv_timings_cap(sd),
++					   adv76xx_get_dv_timings_cap(sd, -1),
+ 					   adv76xx_check_dv_timings, NULL))
+ 			continue;
+ 		if (vtotal(bt) != stdi->lcf + 1)
+@@ -1430,18 +1450,22 @@ static int adv76xx_enum_dv_timings(struct v4l2_subdev *sd,
+ 		return -EINVAL;
+ 
+ 	return v4l2_enum_dv_timings_cap(timings,
+-		adv76xx_get_dv_timings_cap(sd), adv76xx_check_dv_timings, NULL);
++		adv76xx_get_dv_timings_cap(sd, timings->pad),
++		adv76xx_check_dv_timings, NULL);
+ }
+ 
+ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
+ 			struct v4l2_dv_timings_cap *cap)
+ {
+ 	struct adv76xx_state *state = to_state(sd);
++	unsigned int pad = cap->pad;
+ 
+ 	if (cap->pad >= state->source_pad)
+ 		return -EINVAL;
+ 
+-	*cap = *adv76xx_get_dv_timings_cap(sd);
++	*cap = *adv76xx_get_dv_timings_cap(sd, pad);
++	cap->pad = pad;
++
+ 	return 0;
+ }
+ 
+@@ -1450,9 +1474,9 @@ static int adv76xx_dv_timings_cap(struct v4l2_subdev *sd,
+ static void adv76xx_fill_optional_dv_timings_fields(struct v4l2_subdev *sd,
+ 		struct v4l2_dv_timings *timings)
+ {
+-	v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd),
+-			is_digital_input(sd) ? 250000 : 1000000,
+-			adv76xx_check_dv_timings, NULL);
++	v4l2_find_dv_timings_cap(timings, adv76xx_get_dv_timings_cap(sd, -1),
++				 is_digital_input(sd) ? 250000 : 1000000,
++				 adv76xx_check_dv_timings, NULL);
+ }
+ 
+ static unsigned int adv7604_read_hdmi_pixelclock(struct v4l2_subdev *sd)
+@@ -1620,7 +1644,7 @@ static int adv76xx_s_dv_timings(struct v4l2_subdev *sd,
+ 
+ 	bt = &timings->bt;
+ 
+-	if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd),
++	if (!v4l2_valid_dv_timings(timings, adv76xx_get_dv_timings_cap(sd, -1),
+ 				   adv76xx_check_dv_timings, NULL))
+ 		return -ERANGE;
+ 
+diff --git a/drivers/media/usb/airspy/airspy.c b/drivers/media/usb/airspy/airspy.c
+index 87c12930416f..92d9d4214c3a 100644
+--- a/drivers/media/usb/airspy/airspy.c
++++ b/drivers/media/usb/airspy/airspy.c
+@@ -1072,7 +1072,7 @@ static int airspy_probe(struct usb_interface *intf,
+ 	if (ret) {
+ 		dev_err(s->dev, "Failed to register as video device (%d)\n",
+ 				ret);
+-		goto err_unregister_v4l2_dev;
++		goto err_free_controls;
+ 	}
+ 	dev_info(s->dev, "Registered as %s\n",
+ 			video_device_node_name(&s->vdev));
+@@ -1081,7 +1081,6 @@ static int airspy_probe(struct usb_interface *intf,
+ 
+ err_free_controls:
+ 	v4l2_ctrl_handler_free(&s->hdl);
+-err_unregister_v4l2_dev:
+ 	v4l2_device_unregister(&s->v4l2_dev);
+ err_free_mem:
+ 	kfree(s);
+diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
+index b0a27413cb13..185bd359ee6e 100644
+--- a/drivers/mmc/card/block.c
++++ b/drivers/mmc/card/block.c
+@@ -352,8 +352,10 @@ static struct mmc_blk_ioc_data *mmc_blk_ioctl_copy_from_user(
+ 		goto idata_err;
+ 	}
+ 
+-	if (!idata->buf_bytes)
++	if (!idata->buf_bytes) {
++		idata->buf = NULL;
+ 		return idata;
++	}
+ 
+ 	idata->buf = kmalloc(idata->buf_bytes, GFP_KERNEL);
+ 	if (!idata->buf) {
+@@ -1760,8 +1762,8 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
+ 
+ 	packed_cmd_hdr = packed->cmd_hdr;
+ 	memset(packed_cmd_hdr, 0, sizeof(packed->cmd_hdr));
+-	packed_cmd_hdr[0] = (packed->nr_entries << 16) |
+-		(PACKED_CMD_WR << 8) | PACKED_CMD_VER;
++	packed_cmd_hdr[0] = cpu_to_le32((packed->nr_entries << 16) |
++		(PACKED_CMD_WR << 8) | PACKED_CMD_VER);
+ 	hdr_blocks = mmc_large_sector(card) ? 8 : 1;
+ 
+ 	/*
+@@ -1775,14 +1777,14 @@ static void mmc_blk_packed_hdr_wrq_prep(struct mmc_queue_req *mqrq,
+ 			((brq->data.blocks * brq->data.blksz) >=
+ 			 card->ext_csd.data_tag_unit_size);
+ 		/* Argument of CMD23 */
+-		packed_cmd_hdr[(i * 2)] =
++		packed_cmd_hdr[(i * 2)] = cpu_to_le32(
+ 			(do_rel_wr ? MMC_CMD23_ARG_REL_WR : 0) |
+ 			(do_data_tag ? MMC_CMD23_ARG_TAG_REQ : 0) |
+-			blk_rq_sectors(prq);
++			blk_rq_sectors(prq));
+ 		/* Argument of CMD18 or CMD25 */
+-		packed_cmd_hdr[((i * 2)) + 1] =
++		packed_cmd_hdr[((i * 2)) + 1] = cpu_to_le32(
+ 			mmc_card_blockaddr(card) ?
+-			blk_rq_pos(prq) : blk_rq_pos(prq) << 9;
++			blk_rq_pos(prq) : blk_rq_pos(prq) << 9);
+ 		packed->blocks += blk_rq_sectors(prq);
+ 		i++;
+ 	}
+diff --git a/drivers/net/can/at91_can.c b/drivers/net/can/at91_can.c
+index 8b3275d7792a..8f5e93cb7975 100644
+--- a/drivers/net/can/at91_can.c
++++ b/drivers/net/can/at91_can.c
+@@ -712,9 +712,10 @@ static int at91_poll_rx(struct net_device *dev, int quota)
+ 
+ 	/* upper group completed, look again in lower */
+ 	if (priv->rx_next > get_mb_rx_low_last(priv) &&
+-	    quota > 0 && mb > get_mb_rx_last(priv)) {
++	    mb > get_mb_rx_last(priv)) {
+ 		priv->rx_next = get_mb_rx_first(priv);
+-		goto again;
++		if (quota > 0)
++			goto again;
+ 	}
+ 
+ 	return received;
+diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c
+index f91b094288da..e3dccd3200d5 100644
+--- a/drivers/net/can/c_can/c_can.c
++++ b/drivers/net/can/c_can/c_can.c
+@@ -332,9 +332,23 @@ static void c_can_setup_tx_object(struct net_device *dev, int iface,
+ 
+ 	priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl);
+ 
+-	for (i = 0; i < frame->can_dlc; i += 2) {
+-		priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2,
+-				frame->data[i] | (frame->data[i + 1] << 8));
++	if (priv->type == BOSCH_D_CAN) {
++		u32 data = 0, dreg = C_CAN_IFACE(DATA1_REG, iface);
++
++		for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
++			data = (u32)frame->data[i];
++			data |= (u32)frame->data[i + 1] << 8;
++			data |= (u32)frame->data[i + 2] << 16;
++			data |= (u32)frame->data[i + 3] << 24;
++			priv->write_reg32(priv, dreg, data);
++		}
++	} else {
++		for (i = 0; i < frame->can_dlc; i += 2) {
++			priv->write_reg(priv,
++					C_CAN_IFACE(DATA1_REG, iface) + i / 2,
++					frame->data[i] |
++					(frame->data[i + 1] << 8));
++		}
+ 	}
+ }
+ 
+@@ -402,10 +416,20 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl)
+ 	} else {
+ 		int i, dreg = C_CAN_IFACE(DATA1_REG, iface);
+ 
+-		for (i = 0; i < frame->can_dlc; i += 2, dreg ++) {
+-			data = priv->read_reg(priv, dreg);
+-			frame->data[i] = data;
+-			frame->data[i + 1] = data >> 8;
++		if (priv->type == BOSCH_D_CAN) {
++			for (i = 0; i < frame->can_dlc; i += 4, dreg += 2) {
++				data = priv->read_reg32(priv, dreg);
++				frame->data[i] = data;
++				frame->data[i + 1] = data >> 8;
++				frame->data[i + 2] = data >> 16;
++				frame->data[i + 3] = data >> 24;
++			}
++		} else {
++			for (i = 0; i < frame->can_dlc; i += 2, dreg++) {
++				data = priv->read_reg(priv, dreg);
++				frame->data[i] = data;
++				frame->data[i + 1] = data >> 8;
++			}
+ 		}
+ 	}
+ 
+diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c
+index 910c12e2638e..ad535a854e5c 100644
+--- a/drivers/net/can/dev.c
++++ b/drivers/net/can/dev.c
+@@ -798,6 +798,9 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[])
+ 	 * - control mode with CAN_CTRLMODE_FD set
+ 	 */
+ 
++	if (!data)
++		return 0;
++
+ 	if (data[IFLA_CAN_CTRLMODE]) {
+ 		struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
+ 
+@@ -1008,6 +1011,11 @@ static int can_newlink(struct net *src_net, struct net_device *dev,
+ 	return -EOPNOTSUPP;
+ }
+ 
++static void can_dellink(struct net_device *dev, struct list_head *head)
++{
++	return;
++}
++
+ static struct rtnl_link_ops can_link_ops __read_mostly = {
+ 	.kind		= "can",
+ 	.maxtype	= IFLA_CAN_MAX,
+@@ -1016,6 +1024,7 @@ static struct rtnl_link_ops can_link_ops __read_mostly = {
+ 	.validate	= can_validate,
+ 	.newlink	= can_newlink,
+ 	.changelink	= can_changelink,
++	.dellink	= can_dellink,
+ 	.get_size	= can_get_size,
+ 	.fill_info	= can_fill_info,
+ 	.get_xstats_size = can_get_xstats_size,
+diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c
+index a6d26d351dfc..bfddcab82c29 100644
+--- a/drivers/net/ethernet/marvell/mvneta.c
++++ b/drivers/net/ethernet/marvell/mvneta.c
+@@ -244,7 +244,7 @@
+ /* Various constants */
+ 
+ /* Coalescing */
+-#define MVNETA_TXDONE_COAL_PKTS		1
++#define MVNETA_TXDONE_COAL_PKTS		0	/* interrupt per packet */
+ #define MVNETA_RX_COAL_PKTS		32
+ #define MVNETA_RX_COAL_USEC		100
+ 
+diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c
+index 9cfa544072b5..cfde7bc551a1 100644
+--- a/drivers/pinctrl/freescale/pinctrl-imx.c
++++ b/drivers/pinctrl/freescale/pinctrl-imx.c
+@@ -209,9 +209,9 @@ static int imx_pmx_set(struct pinctrl_dev *pctldev, unsigned selector,
+ 		pin_reg = &info->pin_regs[pin_id];
+ 
+ 		if (pin_reg->mux_reg == -1) {
+-			dev_err(ipctl->dev, "Pin(%s) does not support mux function\n",
++			dev_dbg(ipctl->dev, "Pin(%s) does not support mux function\n",
+ 				info->pins[pin_id].name);
+-			return -EINVAL;
++			continue;
+ 		}
+ 
+ 		if (info->flags & SHARE_MUX_CONF_REG) {
+diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c
+index cf9bafa10acf..bfdf720db270 100644
+--- a/drivers/pinctrl/pinctrl-single.c
++++ b/drivers/pinctrl/pinctrl-single.c
+@@ -1580,6 +1580,9 @@ static inline void pcs_irq_set(struct pcs_soc_data *pcs_soc,
+ 		else
+ 			mask &= ~soc_mask;
+ 		pcs->write(mask, pcswi->reg);
++
++		/* flush posted write */
++		mask = pcs->read(pcswi->reg);
+ 		raw_spin_unlock(&pcs->lock);
+ 	}
+ 
+diff --git a/drivers/platform/chrome/cros_ec_dev.c b/drivers/platform/chrome/cros_ec_dev.c
+index d45cd254ed1c..2b331d5b9e79 100644
+--- a/drivers/platform/chrome/cros_ec_dev.c
++++ b/drivers/platform/chrome/cros_ec_dev.c
+@@ -147,13 +147,19 @@ static long ec_device_ioctl_xcmd(struct cros_ec_dev *ec, void __user *arg)
+ 		goto exit;
+ 	}
+ 
++	if (u_cmd.outsize != s_cmd->outsize ||
++	    u_cmd.insize != s_cmd->insize) {
++		ret = -EINVAL;
++		goto exit;
++	}
++
+ 	s_cmd->command += ec->cmd_offset;
+ 	ret = cros_ec_cmd_xfer(ec->ec_dev, s_cmd);
+ 	/* Only copy data to userland if data was received. */
+ 	if (ret < 0)
+ 		goto exit;
+ 
+-	if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + u_cmd.insize))
++	if (copy_to_user(arg, s_cmd, sizeof(*s_cmd) + s_cmd->insize))
+ 		ret = -EFAULT;
+ exit:
+ 	kfree(s_cmd);
+diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
+index 456987c88baa..b13cd074c52a 100644
+--- a/drivers/power/power_supply_core.c
++++ b/drivers/power/power_supply_core.c
+@@ -565,11 +565,12 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd,
+ 
+ 	WARN_ON(tzd == NULL);
+ 	psy = tzd->devdata;
+-	ret = psy->desc->get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
++	ret = power_supply_get_property(psy, POWER_SUPPLY_PROP_TEMP, &val);
++	if (ret)
++		return ret;
+ 
+ 	/* Convert tenths of degree Celsius to milli degree Celsius. */
+-	if (!ret)
+-		*temp = val.intval * 100;
++	*temp = val.intval * 100;
+ 
+ 	return ret;
+ }
+@@ -612,10 +613,12 @@ static int ps_get_max_charge_cntl_limit(struct thermal_cooling_device *tcd,
+ 	int ret;
+ 
+ 	psy = tcd->devdata;
+-	ret = psy->desc->get_property(psy,
+-		POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val);
+-	if (!ret)
+-		*state = val.intval;
++	ret = power_supply_get_property(psy,
++			POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT_MAX, &val);
++	if (ret)
++		return ret;
++
++	*state = val.intval;
+ 
+ 	return ret;
+ }
+@@ -628,10 +631,12 @@ static int ps_get_cur_chrage_cntl_limit(struct thermal_cooling_device *tcd,
+ 	int ret;
+ 
+ 	psy = tcd->devdata;
+-	ret = psy->desc->get_property(psy,
+-		POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
+-	if (!ret)
+-		*state = val.intval;
++	ret = power_supply_get_property(psy,
++			POWER_SUPPLY_PROP_CHARGE_CONTROL_LIMIT, &val);
++	if (ret)
++		return ret;
++
++	*state = val.intval;
+ 
+ 	return ret;
+ }
+diff --git a/drivers/pps/clients/pps_parport.c b/drivers/pps/clients/pps_parport.c
+index 38a8bbe74810..83797d89c30f 100644
+--- a/drivers/pps/clients/pps_parport.c
++++ b/drivers/pps/clients/pps_parport.c
+@@ -195,7 +195,7 @@ static void parport_detach(struct parport *port)
+ 	struct pps_client_pp *device;
+ 
+ 	/* FIXME: oooh, this is ugly! */
+-	if (strcmp(pardev->name, KBUILD_MODNAME))
++	if (!pardev || strcmp(pardev->name, KBUILD_MODNAME))
+ 		/* not our port */
+ 		return;
+ 
+diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
+index 80b1979e8d95..df036b872b05 100644
+--- a/drivers/s390/net/qeth_l2_main.c
++++ b/drivers/s390/net/qeth_l2_main.c
+@@ -1051,6 +1051,7 @@ static void qeth_l2_remove_device(struct ccwgroup_device *cgdev)
+ 		qeth_l2_set_offline(cgdev);
+ 
+ 	if (card->dev) {
++		netif_napi_del(&card->napi);
+ 		unregister_netdev(card->dev);
+ 		card->dev = NULL;
+ 	}
+diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
+index ac544330daeb..709b52339ff9 100644
+--- a/drivers/s390/net/qeth_l3_main.c
++++ b/drivers/s390/net/qeth_l3_main.c
+@@ -3226,6 +3226,7 @@ static void qeth_l3_remove_device(struct ccwgroup_device *cgdev)
+ 		qeth_l3_set_offline(cgdev);
+ 
+ 	if (card->dev) {
++		netif_napi_del(&card->napi);
+ 		unregister_netdev(card->dev);
+ 		card->dev = NULL;
+ 	}
+diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
+index d6a691e27d33..d6803a9e5ab8 100644
+--- a/drivers/scsi/ipr.c
++++ b/drivers/scsi/ipr.c
+@@ -10093,6 +10093,7 @@ static int ipr_probe_ioa(struct pci_dev *pdev,
+ 		ioa_cfg->intr_flag = IPR_USE_MSI;
+ 	else {
+ 		ioa_cfg->intr_flag = IPR_USE_LSI;
++		ioa_cfg->clear_isr = 1;
+ 		ioa_cfg->nvectors = 1;
+ 		dev_info(&pdev->dev, "Cannot enable MSI.\n");
+ 	}
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 5649c200d37c..a92a62dea793 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -2548,7 +2548,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
+ 	if (!vha->flags.online)
+ 		return;
+ 
+-	if (rsp->msix->cpuid != smp_processor_id()) {
++	if (rsp->msix && rsp->msix->cpuid != smp_processor_id()) {
+ 		/* if kernel does not notify qla of IRQ's CPU change,
+ 		 * then set it here.
+ 		 */
+diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
+index ff41c310c900..eaccd651ccda 100644
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -429,7 +429,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
+ 	 * here, and we don't know what device it is
+ 	 * trying to work with, leave it as-is.
+ 	 */
+-	vmax = 8;	/* max length of vendor */
++	vmax = sizeof(devinfo->vendor);
+ 	vskip = vendor;
+ 	while (vmax > 0 && *vskip == ' ') {
+ 		vmax--;
+@@ -439,7 +439,7 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
+ 	while (vmax > 0 && vskip[vmax - 1] == ' ')
+ 		--vmax;
+ 
+-	mmax = 16;	/* max length of model */
++	mmax = sizeof(devinfo->model);
+ 	mskip = model;
+ 	while (mmax > 0 && *mskip == ' ') {
+ 		mmax--;
+@@ -455,10 +455,12 @@ static struct scsi_dev_info_list *scsi_dev_info_list_find(const char *vendor,
+ 			 * Behave like the older version of get_device_flags.
+ 			 */
+ 			if (memcmp(devinfo->vendor, vskip, vmax) ||
+-					devinfo->vendor[vmax])
++					(vmax < sizeof(devinfo->vendor) &&
++						devinfo->vendor[vmax]))
+ 				continue;
+ 			if (memcmp(devinfo->model, mskip, mmax) ||
+-					devinfo->model[mmax])
++					(mmax < sizeof(devinfo->model) &&
++						devinfo->model[mmax]))
+ 				continue;
+ 			return devinfo;
+ 		} else {
+diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
+index 6c6c0013ec7a..8048c2fedf5b 100644
+--- a/drivers/spi/spi-rockchip.c
++++ b/drivers/spi/spi-rockchip.c
+@@ -578,7 +578,7 @@ static int rockchip_spi_transfer_one(
+ 		struct spi_device *spi,
+ 		struct spi_transfer *xfer)
+ {
+-	int ret = 1;
++	int ret = 0;
+ 	struct rockchip_spi *rs = spi_master_get_devdata(master);
+ 
+ 	WARN_ON(readl_relaxed(rs->regs + ROCKCHIP_SPI_SSIENR) &&
+@@ -627,6 +627,8 @@ static int rockchip_spi_transfer_one(
+ 			spi_enable_chip(rs, 1);
+ 			ret = rockchip_spi_prepare_dma(rs);
+ 		}
++		/* successful DMA prepare means the transfer is in progress */
++		ret = ret ? ret : 1;
+ 	} else {
+ 		spi_enable_chip(rs, 1);
+ 		ret = rockchip_spi_pio_transfer(rs);
+diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c
+index 1ddd9e2309b6..cf007f3b83ec 100644
+--- a/drivers/spi/spi-sun4i.c
++++ b/drivers/spi/spi-sun4i.c
+@@ -173,13 +173,17 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
+ {
+ 	struct sun4i_spi *sspi = spi_master_get_devdata(master);
+ 	unsigned int mclk_rate, div, timeout;
++	unsigned int start, end, tx_time;
+ 	unsigned int tx_len = 0;
+ 	int ret = 0;
+ 	u32 reg;
+ 
+ 	/* We don't support transfer larger than the FIFO */
+ 	if (tfr->len > SUN4I_FIFO_DEPTH)
+-		return -EINVAL;
++		return -EMSGSIZE;
++
++	if (tfr->tx_buf && tfr->len >= SUN4I_FIFO_DEPTH)
++		return -EMSGSIZE;
+ 
+ 	reinit_completion(&sspi->done);
+ 	sspi->tx_buf = tfr->tx_buf;
+@@ -269,8 +273,12 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
+ 	sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len));
+ 	sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len));
+ 
+-	/* Fill the TX FIFO */
+-	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH);
++	/*
++	 * Fill the TX FIFO
++	 * Filling the FIFO fully causes timeout for some reason
++	 * at least on spi2 on A10s
++	 */
++	sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1);
+ 
+ 	/* Enable the interrupts */
+ 	sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, SUN4I_INT_CTL_TC);
+@@ -279,9 +287,16 @@ static int sun4i_spi_transfer_one(struct spi_master *master,
+ 	reg = sun4i_spi_read(sspi, SUN4I_CTL_REG);
+ 	sun4i_spi_write(sspi, SUN4I_CTL_REG, reg | SUN4I_CTL_XCH);
+ 
++	tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
++	start = jiffies;
+ 	timeout = wait_for_completion_timeout(&sspi->done,
+-					      msecs_to_jiffies(1000));
++					      msecs_to_jiffies(tx_time));
++	end = jiffies;
+ 	if (!timeout) {
++		dev_warn(&master->dev,
++			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
++			 dev_name(&spi->dev), tfr->len, tfr->speed_hz,
++			 jiffies_to_msecs(end - start), tx_time);
+ 		ret = -ETIMEDOUT;
+ 		goto out;
+ 	}
+diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c
+index 42e2c4bd690a..7fce79a60608 100644
+--- a/drivers/spi/spi-sun6i.c
++++ b/drivers/spi/spi-sun6i.c
+@@ -160,6 +160,7 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
+ {
+ 	struct sun6i_spi *sspi = spi_master_get_devdata(master);
+ 	unsigned int mclk_rate, div, timeout;
++	unsigned int start, end, tx_time;
+ 	unsigned int tx_len = 0;
+ 	int ret = 0;
+ 	u32 reg;
+@@ -269,9 +270,16 @@ static int sun6i_spi_transfer_one(struct spi_master *master,
+ 	reg = sun6i_spi_read(sspi, SUN6I_TFR_CTL_REG);
+ 	sun6i_spi_write(sspi, SUN6I_TFR_CTL_REG, reg | SUN6I_TFR_CTL_XCH);
+ 
++	tx_time = max(tfr->len * 8 * 2 / (tfr->speed_hz / 1000), 100U);
++	start = jiffies;
+ 	timeout = wait_for_completion_timeout(&sspi->done,
+-					      msecs_to_jiffies(1000));
++					      msecs_to_jiffies(tx_time));
++	end = jiffies;
+ 	if (!timeout) {
++		dev_warn(&master->dev,
++			 "%s: timeout transferring %u bytes@%iHz for %i(%i)ms",
++			 dev_name(&spi->dev), tfr->len, tfr->speed_hz,
++			 jiffies_to_msecs(end - start), tx_time);
+ 		ret = -ETIMEDOUT;
+ 		goto out;
+ 	}
+diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
+index e198996c5b83..9e45c5728d9b 100644
+--- a/drivers/tty/pty.c
++++ b/drivers/tty/pty.c
+@@ -667,8 +667,11 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
+ 		fsi = tty->driver_data;
+ 	else
+ 		fsi = tty->link->driver_data;
+-	devpts_kill_index(fsi, tty->index);
+-	devpts_put_ref(fsi);
++
++	if (fsi) {
++		devpts_kill_index(fsi, tty->index);
++		devpts_put_ref(fsi);
++	}
+ }
+ 
+ static const struct tty_operations ptm_unix98_ops = {
+diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
+index d029bbe9eb36..641fed609911 100644
+--- a/drivers/usb/host/ohci-q.c
++++ b/drivers/usb/host/ohci-q.c
+@@ -183,7 +183,6 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
+ {
+ 	int	branch;
+ 
+-	ed->state = ED_OPER;
+ 	ed->ed_prev = NULL;
+ 	ed->ed_next = NULL;
+ 	ed->hwNextED = 0;
+@@ -259,6 +258,8 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed)
+ 	/* the HC may not see the schedule updates yet, but if it does
+ 	 * then they'll be properly ordered.
+ 	 */
++
++	ed->state = ED_OPER;
+ 	return 0;
+ }
+ 
+diff --git a/drivers/xen/xen-pciback/conf_space.c b/drivers/xen/xen-pciback/conf_space.c
+index 8e67336f8ddd..6a25533da237 100644
+--- a/drivers/xen/xen-pciback/conf_space.c
++++ b/drivers/xen/xen-pciback/conf_space.c
+@@ -183,8 +183,7 @@ int xen_pcibk_config_read(struct pci_dev *dev, int offset, int size,
+ 		field_start = OFFSET(cfg_entry);
+ 		field_end = OFFSET(cfg_entry) + field->size;
+ 
+-		if ((req_start >= field_start && req_start < field_end)
+-		    || (req_end > field_start && req_end <= field_end)) {
++		 if (req_end > field_start && field_end > req_start) {
+ 			err = conf_space_read(dev, cfg_entry, field_start,
+ 					      &tmp_val);
+ 			if (err)
+@@ -230,8 +229,7 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)
+ 		field_start = OFFSET(cfg_entry);
+ 		field_end = OFFSET(cfg_entry) + field->size;
+ 
+-		if ((req_start >= field_start && req_start < field_end)
+-		    || (req_end > field_start && req_end <= field_end)) {
++		 if (req_end > field_start && field_end > req_start) {
+ 			tmp_val = 0;
+ 
+ 			err = xen_pcibk_config_read(dev, field_start,
+diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c
+index cacf30d14747..7487971f9f78 100644
+--- a/drivers/xen/xenbus/xenbus_dev_frontend.c
++++ b/drivers/xen/xenbus/xenbus_dev_frontend.c
+@@ -316,11 +316,18 @@ static int xenbus_write_transaction(unsigned msg_type,
+ 			rc = -ENOMEM;
+ 			goto out;
+ 		}
++	} else {
++		list_for_each_entry(trans, &u->transactions, list)
++			if (trans->handle.id == u->u.msg.tx_id)
++				break;
++		if (&trans->list == &u->transactions)
++			return -ESRCH;
+ 	}
+ 
+ 	reply = xenbus_dev_request_and_reply(&u->u.msg);
+ 	if (IS_ERR(reply)) {
+-		kfree(trans);
++		if (msg_type == XS_TRANSACTION_START)
++			kfree(trans);
+ 		rc = PTR_ERR(reply);
+ 		goto out;
+ 	}
+@@ -333,12 +340,7 @@ static int xenbus_write_transaction(unsigned msg_type,
+ 			list_add(&trans->list, &u->transactions);
+ 		}
+ 	} else if (u->u.msg.type == XS_TRANSACTION_END) {
+-		list_for_each_entry(trans, &u->transactions, list)
+-			if (trans->handle.id == u->u.msg.tx_id)
+-				break;
+-		BUG_ON(&trans->list == &u->transactions);
+ 		list_del(&trans->list);
+-
+ 		kfree(trans);
+ 	}
+ 
+diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
+index 374b12af8812..0bd3d47ad24d 100644
+--- a/drivers/xen/xenbus/xenbus_xs.c
++++ b/drivers/xen/xenbus/xenbus_xs.c
+@@ -249,9 +249,6 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
+ 
+ 	mutex_unlock(&xs_state.request_mutex);
+ 
+-	if (IS_ERR(ret))
+-		return ret;
+-
+ 	if ((msg->type == XS_TRANSACTION_END) ||
+ 	    ((req_msg.type == XS_TRANSACTION_START) &&
+ 	     (msg->type == XS_ERROR)))
+diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
+index b84c291ba1eb..d7b78d531e63 100644
+--- a/fs/9p/vfs_file.c
++++ b/fs/9p/vfs_file.c
+@@ -74,7 +74,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
+ 					v9fs_proto_dotu(v9ses));
+ 	fid = file->private_data;
+ 	if (!fid) {
+-		fid = v9fs_fid_clone(file->f_path.dentry);
++		fid = v9fs_fid_clone(file_dentry(file));
+ 		if (IS_ERR(fid))
+ 			return PTR_ERR(fid);
+ 
+@@ -100,7 +100,7 @@ int v9fs_file_open(struct inode *inode, struct file *file)
+ 		 * because we want write after unlink usecase
+ 		 * to work.
+ 		 */
+-		fid = v9fs_writeback_fid(file->f_path.dentry);
++		fid = v9fs_writeback_fid(file_dentry(file));
+ 		if (IS_ERR(fid)) {
+ 			err = PTR_ERR(fid);
+ 			mutex_unlock(&v9inode->v_mutex);
+@@ -516,7 +516,7 @@ v9fs_mmap_file_mmap(struct file *filp, struct vm_area_struct *vma)
+ 		 * because we want write after unlink usecase
+ 		 * to work.
+ 		 */
+-		fid = v9fs_writeback_fid(filp->f_path.dentry);
++		fid = v9fs_writeback_fid(file_dentry(filp));
+ 		if (IS_ERR(fid)) {
+ 			retval = PTR_ERR(fid);
+ 			mutex_unlock(&v9inode->v_mutex);
+diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
+index f02404052b7b..27794b137b24 100644
+--- a/fs/ecryptfs/file.c
++++ b/fs/ecryptfs/file.c
+@@ -169,6 +169,19 @@ out:
+ 	return rc;
+ }
+ 
++static int ecryptfs_mmap(struct file *file, struct vm_area_struct *vma)
++{
++	struct file *lower_file = ecryptfs_file_to_lower(file);
++	/*
++	 * Don't allow mmap on top of file systems that don't support it
++	 * natively.  If FILESYSTEM_MAX_STACK_DEPTH > 2 or ecryptfs
++	 * allows recursive mounting, this will need to be extended.
++	 */
++	if (!lower_file->f_op->mmap)
++		return -ENODEV;
++	return generic_file_mmap(file, vma);
++}
++
+ /**
+  * ecryptfs_open
+  * @inode: inode speciying file to open
+@@ -403,7 +416,7 @@ const struct file_operations ecryptfs_main_fops = {
+ #ifdef CONFIG_COMPAT
+ 	.compat_ioctl = ecryptfs_compat_ioctl,
+ #endif
+-	.mmap = generic_file_mmap,
++	.mmap = ecryptfs_mmap,
+ 	.open = ecryptfs_open,
+ 	.flush = ecryptfs_flush,
+ 	.release = ecryptfs_release,
+diff --git a/fs/ecryptfs/kthread.c b/fs/ecryptfs/kthread.c
+index e818f5ac7a26..866bb18efefe 100644
+--- a/fs/ecryptfs/kthread.c
++++ b/fs/ecryptfs/kthread.c
+@@ -25,7 +25,6 @@
+ #include <linux/slab.h>
+ #include <linux/wait.h>
+ #include <linux/mount.h>
+-#include <linux/file.h>
+ #include "ecryptfs_kernel.h"
+ 
+ struct ecryptfs_open_req {
+@@ -148,7 +147,7 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ 	flags |= IS_RDONLY(d_inode(lower_dentry)) ? O_RDONLY : O_RDWR;
+ 	(*lower_file) = dentry_open(&req.path, flags, cred);
+ 	if (!IS_ERR(*lower_file))
+-		goto have_file;
++		goto out;
+ 	if ((flags & O_ACCMODE) == O_RDONLY) {
+ 		rc = PTR_ERR((*lower_file));
+ 		goto out;
+@@ -166,16 +165,8 @@ int ecryptfs_privileged_open(struct file **lower_file,
+ 	mutex_unlock(&ecryptfs_kthread_ctl.mux);
+ 	wake_up(&ecryptfs_kthread_ctl.wait);
+ 	wait_for_completion(&req.done);
+-	if (IS_ERR(*lower_file)) {
++	if (IS_ERR(*lower_file))
+ 		rc = PTR_ERR(*lower_file);
+-		goto out;
+-	}
+-have_file:
+-	if ((*lower_file)->f_op->mmap == NULL) {
+-		fput(*lower_file);
+-		*lower_file = NULL;
+-		rc = -EMEDIUMTYPE;
+-	}
+ out:
+ 	return rc;
+ }
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index 95bf4679ac54..de692b91c166 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -469,6 +469,10 @@ static int __ext4_ext_check(const char *function, unsigned int line,
+ 		error_msg = "invalid extent entries";
+ 		goto corrupted;
+ 	}
++	if (unlikely(depth > 32)) {
++		error_msg = "too large eh_depth";
++		goto corrupted;
++	}
+ 	/* Verify checksum on non-root extent tree nodes */
+ 	if (ext_depth(inode) != depth &&
+ 	    !ext4_extent_block_csum_verify(inode, eh)) {
+diff --git a/fs/inode.c b/fs/inode.c
+index 69b8b526c194..721fa18ead59 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -1739,8 +1739,8 @@ static int __remove_privs(struct dentry *dentry, int kill)
+  */
+ int file_remove_privs(struct file *file)
+ {
+-	struct dentry *dentry = file->f_path.dentry;
+-	struct inode *inode = d_inode(dentry);
++	struct dentry *dentry = file_dentry(file);
++	struct inode *inode = file_inode(file);
+ 	int kill;
+ 	int error = 0;
+ 
+@@ -1748,7 +1748,7 @@ int file_remove_privs(struct file *file)
+ 	if (IS_NOSEC(inode))
+ 		return 0;
+ 
+-	kill = file_needs_remove_privs(file);
++	kill = dentry_needs_remove_privs(dentry);
+ 	if (kill < 0)
+ 		return kill;
+ 	if (kill)
+diff --git a/fs/ioctl.c b/fs/ioctl.c
+index 116a333e9c77..0f56deb24ce6 100644
+--- a/fs/ioctl.c
++++ b/fs/ioctl.c
+@@ -590,6 +590,7 @@ static long ioctl_file_dedupe_range(struct file *file, void __user *arg)
+ 		goto out;
+ 	}
+ 
++	same->dest_count = count;
+ 	ret = vfs_dedupe_file_range(file, same);
+ 	if (ret)
+ 		goto out;
+diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
+index 154a107cd376..fc4084ef4736 100644
+--- a/fs/lockd/svc.c
++++ b/fs/lockd/svc.c
+@@ -335,12 +335,17 @@ static struct notifier_block lockd_inet6addr_notifier = {
+ };
+ #endif
+ 
+-static void lockd_svc_exit_thread(void)
++static void lockd_unregister_notifiers(void)
+ {
+ 	unregister_inetaddr_notifier(&lockd_inetaddr_notifier);
+ #if IS_ENABLED(CONFIG_IPV6)
+ 	unregister_inet6addr_notifier(&lockd_inet6addr_notifier);
+ #endif
++}
++
++static void lockd_svc_exit_thread(void)
++{
++	lockd_unregister_notifiers();
+ 	svc_exit_thread(nlmsvc_rqst);
+ }
+ 
+@@ -462,7 +467,7 @@ int lockd_up(struct net *net)
+ 	 * Note: svc_serv structures have an initial use count of 1,
+ 	 * so we exit through here on both success and failure.
+ 	 */
+-err_net:
++err_put:
+ 	svc_destroy(serv);
+ err_create:
+ 	mutex_unlock(&nlmsvc_mutex);
+@@ -470,7 +475,9 @@ err_create:
+ 
+ err_start:
+ 	lockd_down_net(serv, net);
+-	goto err_net;
++err_net:
++	lockd_unregister_notifiers();
++	goto err_put;
+ }
+ EXPORT_SYMBOL_GPL(lockd_up);
+ 
+diff --git a/fs/locks.c b/fs/locks.c
+index 7c5f91be9b65..ee1b15f6fc13 100644
+--- a/fs/locks.c
++++ b/fs/locks.c
+@@ -1628,7 +1628,7 @@ generic_add_lease(struct file *filp, long arg, struct file_lock **flp, void **pr
+ {
+ 	struct file_lock *fl, *my_fl = NULL, *lease;
+ 	struct dentry *dentry = filp->f_path.dentry;
+-	struct inode *inode = dentry->d_inode;
++	struct inode *inode = file_inode(filp);
+ 	struct file_lock_context *ctx;
+ 	bool is_deleg = (*flp)->fl_flags & FL_DELEG;
+ 	int error;
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 783004af5707..419f746d851d 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1562,6 +1562,7 @@ void __detach_mounts(struct dentry *dentry)
+ 		goto out_unlock;
+ 
+ 	lock_mount_hash();
++	event++;
+ 	while (!hlist_empty(&mp->m_list)) {
+ 		mnt = hlist_entry(mp->m_list.first, struct mount, mnt_mp_list);
+ 		if (mnt->mnt.mnt_flags & MNT_UMOUNT) {
+diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
+index 69bd801afb53..37e49cb2ac4c 100644
+--- a/fs/nilfs2/the_nilfs.c
++++ b/fs/nilfs2/the_nilfs.c
+@@ -443,7 +443,7 @@ static int nilfs_valid_sb(struct nilfs_super_block *sbp)
+ 	if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
+ 		return 0;
+ 	bytes = le16_to_cpu(sbp->s_bytes);
+-	if (bytes > BLOCK_SIZE)
++	if (bytes < sumoff + 4 || bytes > BLOCK_SIZE)
+ 		return 0;
+ 	crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
+ 		       sumoff);
+diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
+index 339125bb4d2c..2a9f10c8af1b 100644
+--- a/include/asm-generic/vmlinux.lds.h
++++ b/include/asm-generic/vmlinux.lds.h
+@@ -540,15 +540,19 @@
+ 
+ #define INIT_TEXT							\
+ 	*(.init.text)							\
++	*(.text.startup)						\
+ 	MEM_DISCARD(init.text)
+ 
+ #define EXIT_DATA							\
+ 	*(.exit.data)							\
++	*(.fini_array)							\
++	*(.dtors)							\
+ 	MEM_DISCARD(exit.data)						\
+ 	MEM_DISCARD(exit.rodata)
+ 
+ #define EXIT_TEXT							\
+ 	*(.exit.text)							\
++	*(.text.exit)							\
+ 	MEM_DISCARD(exit.text)
+ 
+ #define EXIT_CALL							\
+diff --git a/include/linux/bcma/bcma.h b/include/linux/bcma/bcma.h
+index 0367c63f5960..5c37b58445c6 100644
+--- a/include/linux/bcma/bcma.h
++++ b/include/linux/bcma/bcma.h
+@@ -158,6 +158,7 @@ struct bcma_host_ops {
+ #define BCMA_CORE_DEFAULT		0xFFF
+ 
+ #define BCMA_MAX_NR_CORES		16
++#define BCMA_CORE_SIZE			0x1000
+ 
+ /* Chip IDs of PCIe devices */
+ #define BCMA_CHIP_ID_BCM4313	0x4313
+diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
+index 1191d79aa495..4d061681dbf1 100644
+--- a/include/linux/memcontrol.h
++++ b/include/linux/memcontrol.h
+@@ -97,6 +97,11 @@ enum mem_cgroup_events_target {
+ #define MEM_CGROUP_ID_SHIFT	16
+ #define MEM_CGROUP_ID_MAX	USHRT_MAX
+ 
++struct mem_cgroup_id {
++	int id;
++	atomic_t ref;
++};
++
+ struct mem_cgroup_stat_cpu {
+ 	long count[MEMCG_NR_STAT];
+ 	unsigned long events[MEMCG_NR_EVENTS];
+@@ -172,6 +177,9 @@ enum memcg_kmem_state {
+ struct mem_cgroup {
+ 	struct cgroup_subsys_state css;
+ 
++	/* Private memcg ID. Used to ID objects that outlive the cgroup */
++	struct mem_cgroup_id id;
++
+ 	/* Accounted resources */
+ 	struct page_counter memory;
+ 	struct page_counter swap;
+@@ -330,22 +338,9 @@ static inline unsigned short mem_cgroup_id(struct mem_cgroup *memcg)
+ 	if (mem_cgroup_disabled())
+ 		return 0;
+ 
+-	return memcg->css.id;
+-}
+-
+-/**
+- * mem_cgroup_from_id - look up a memcg from an id
+- * @id: the id to look up
+- *
+- * Caller must hold rcu_read_lock() and use css_tryget() as necessary.
+- */
+-static inline struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
+-{
+-	struct cgroup_subsys_state *css;
+-
+-	css = css_from_id(id, &memory_cgrp_subsys);
+-	return mem_cgroup_from_css(css);
++	return memcg->id.id;
+ }
++struct mem_cgroup *mem_cgroup_from_id(unsigned short id);
+ 
+ /**
+  * parent_mem_cgroup - find the accounting parent of a memcg
+diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
+index 51a97ac8bfbf..495a09bfeb94 100644
+--- a/include/linux/radix-tree.h
++++ b/include/linux/radix-tree.h
+@@ -399,6 +399,7 @@ static inline __must_check
+ void **radix_tree_iter_retry(struct radix_tree_iter *iter)
+ {
+ 	iter->next_index = iter->index;
++	iter->tags = 0;
+ 	return NULL;
+ }
+ 
+diff --git a/include/linux/rmap.h b/include/linux/rmap.h
+index 49eb4f8ebac9..2b0fad83683f 100644
+--- a/include/linux/rmap.h
++++ b/include/linux/rmap.h
+@@ -158,7 +158,7 @@ struct anon_vma *page_get_anon_vma(struct page *page);
+ /*
+  * rmap interfaces called when adding or removing pte of page
+  */
+-void page_move_anon_rmap(struct page *, struct vm_area_struct *, unsigned long);
++void page_move_anon_rmap(struct page *, struct vm_area_struct *);
+ void page_add_anon_rmap(struct page *, struct vm_area_struct *,
+ 		unsigned long, bool);
+ void do_page_add_anon_rmap(struct page *, struct vm_area_struct *,
+diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
+index 813ffb2e22c9..1c589b62c244 100644
+--- a/include/uapi/linux/Kbuild
++++ b/include/uapi/linux/Kbuild
+@@ -244,6 +244,7 @@ endif
+ header-y += hw_breakpoint.h
+ header-y += l2tp.h
+ header-y += libc-compat.h
++header-y += lirc.h
+ header-y += limits.h
+ header-y += llc.h
+ header-y += loop.h
+diff --git a/init/Kconfig b/init/Kconfig
+index 0dfd09d54c65..d895c7a183c6 100644
+--- a/init/Kconfig
++++ b/init/Kconfig
+@@ -1423,6 +1423,7 @@ config KALLSYMS_ALL
+ 
+ config KALLSYMS_ABSOLUTE_PERCPU
+ 	bool
++	depends on KALLSYMS
+ 	default X86_64 && SMP
+ 
+ config KALLSYMS_BASE_RELATIVE
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index 86cb5c6e8932..75c0ff00aca6 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -837,6 +837,8 @@ static void put_css_set_locked(struct css_set *cset)
+ 
+ static void put_css_set(struct css_set *cset)
+ {
++	unsigned long flags;
++
+ 	/*
+ 	 * Ensure that the refcount doesn't hit zero while any readers
+ 	 * can see it. Similar to atomic_dec_and_lock(), but for an
+@@ -845,9 +847,9 @@ static void put_css_set(struct css_set *cset)
+ 	if (atomic_add_unless(&cset->refcount, -1, 1))
+ 		return;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irqsave(&css_set_lock, flags);
+ 	put_css_set_locked(cset);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irqrestore(&css_set_lock, flags);
+ }
+ 
+ /*
+@@ -1070,11 +1072,11 @@ static struct css_set *find_css_set(struct css_set *old_cset,
+ 
+ 	/* First see if we already have a cgroup group that matches
+ 	 * the desired set */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	cset = find_existing_css_set(old_cset, cgrp, template);
+ 	if (cset)
+ 		get_css_set(cset);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	if (cset)
+ 		return cset;
+@@ -1102,7 +1104,7 @@ static struct css_set *find_css_set(struct css_set *old_cset,
+ 	 * find_existing_css_set() */
+ 	memcpy(cset->subsys, template, sizeof(cset->subsys));
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	/* Add reference counts and links from the new css_set. */
+ 	list_for_each_entry(link, &old_cset->cgrp_links, cgrp_link) {
+ 		struct cgroup *c = link->cgrp;
+@@ -1128,7 +1130,7 @@ static struct css_set *find_css_set(struct css_set *old_cset,
+ 		css_get(css);
+ 	}
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	return cset;
+ }
+@@ -1192,7 +1194,7 @@ static void cgroup_destroy_root(struct cgroup_root *root)
+ 	 * Release all the links from cset_links to this hierarchy's
+ 	 * root cgroup
+ 	 */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	list_for_each_entry_safe(link, tmp_link, &cgrp->cset_links, cset_link) {
+ 		list_del(&link->cset_link);
+@@ -1200,7 +1202,7 @@ static void cgroup_destroy_root(struct cgroup_root *root)
+ 		kfree(link);
+ 	}
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	if (!list_empty(&root->root_list)) {
+ 		list_del(&root->root_list);
+@@ -1600,11 +1602,11 @@ static int rebind_subsystems(struct cgroup_root *dst_root, u16 ss_mask)
+ 		ss->root = dst_root;
+ 		css->cgroup = dcgrp;
+ 
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		hash_for_each(css_set_table, i, cset, hlist)
+ 			list_move_tail(&cset->e_cset_node[ss->id],
+ 				       &dcgrp->e_csets[ss->id]);
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 
+ 		/* default hierarchy doesn't enable controllers by default */
+ 		dst_root->subsys_mask |= 1 << ssid;
+@@ -1640,10 +1642,10 @@ static int cgroup_show_path(struct seq_file *sf, struct kernfs_node *kf_node,
+ 	if (!buf)
+ 		return -ENOMEM;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	ns_cgroup = current_cgns_cgroup_from_root(kf_cgroot);
+ 	len = kernfs_path_from_node(kf_node, ns_cgroup->kn, buf, PATH_MAX);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	if (len >= PATH_MAX)
+ 		len = -ERANGE;
+@@ -1897,7 +1899,7 @@ static void cgroup_enable_task_cg_lists(void)
+ {
+ 	struct task_struct *p, *g;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	if (use_task_css_set_links)
+ 		goto out_unlock;
+@@ -1922,8 +1924,12 @@ static void cgroup_enable_task_cg_lists(void)
+ 		 * entry won't be deleted though the process has exited.
+ 		 * Do it while holding siglock so that we don't end up
+ 		 * racing against cgroup_exit().
++		 *
++		 * Interrupts were already disabled while acquiring
++		 * the css_set_lock, so we do not need to disable it
++		 * again when acquiring the sighand->siglock here.
+ 		 */
+-		spin_lock_irq(&p->sighand->siglock);
++		spin_lock(&p->sighand->siglock);
+ 		if (!(p->flags & PF_EXITING)) {
+ 			struct css_set *cset = task_css_set(p);
+ 
+@@ -1932,11 +1938,11 @@ static void cgroup_enable_task_cg_lists(void)
+ 			list_add_tail(&p->cg_list, &cset->tasks);
+ 			get_css_set(cset);
+ 		}
+-		spin_unlock_irq(&p->sighand->siglock);
++		spin_unlock(&p->sighand->siglock);
+ 	} while_each_thread(g, p);
+ 	read_unlock(&tasklist_lock);
+ out_unlock:
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ }
+ 
+ static void init_cgroup_housekeeping(struct cgroup *cgrp)
+@@ -2043,13 +2049,13 @@ static int cgroup_setup_root(struct cgroup_root *root, u16 ss_mask)
+ 	 * Link the root cgroup in this hierarchy into all the css_set
+ 	 * objects.
+ 	 */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	hash_for_each(css_set_table, i, cset, hlist) {
+ 		link_css_set(&tmp_links, cset, root_cgrp);
+ 		if (css_set_populated(cset))
+ 			cgroup_update_populated(root_cgrp, true);
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	BUG_ON(!list_empty(&root_cgrp->self.children));
+ 	BUG_ON(atomic_read(&root->nr_cgrps) != 1);
+@@ -2256,11 +2262,11 @@ out_mount:
+ 		struct cgroup *cgrp;
+ 
+ 		mutex_lock(&cgroup_mutex);
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 
+ 		cgrp = cset_cgroup_from_root(ns->root_cset, root);
+ 
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 		mutex_unlock(&cgroup_mutex);
+ 
+ 		nsdentry = kernfs_node_dentry(cgrp->kn, dentry->d_sb);
+@@ -2337,11 +2343,11 @@ char *cgroup_path_ns(struct cgroup *cgrp, char *buf, size_t buflen,
+ 	char *ret;
+ 
+ 	mutex_lock(&cgroup_mutex);
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	ret = cgroup_path_ns_locked(cgrp, buf, buflen, ns);
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	mutex_unlock(&cgroup_mutex);
+ 
+ 	return ret;
+@@ -2369,7 +2375,7 @@ char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
+ 	char *path = NULL;
+ 
+ 	mutex_lock(&cgroup_mutex);
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	root = idr_get_next(&cgroup_hierarchy_idr, &hierarchy_id);
+ 
+@@ -2382,7 +2388,7 @@ char *task_cgroup_path(struct task_struct *task, char *buf, size_t buflen)
+ 			path = buf;
+ 	}
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	mutex_unlock(&cgroup_mutex);
+ 	return path;
+ }
+@@ -2557,7 +2563,7 @@ static int cgroup_taskset_migrate(struct cgroup_taskset *tset,
+ 	 * the new cgroup.  There are no failure cases after here, so this
+ 	 * is the commit point.
+ 	 */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(cset, &tset->src_csets, mg_node) {
+ 		list_for_each_entry_safe(task, tmp_task, &cset->mg_tasks, cg_list) {
+ 			struct css_set *from_cset = task_css_set(task);
+@@ -2568,7 +2574,7 @@ static int cgroup_taskset_migrate(struct cgroup_taskset *tset,
+ 			put_css_set_locked(from_cset);
+ 		}
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	/*
+ 	 * Migration is committed, all target tasks are now on dst_csets.
+@@ -2597,13 +2603,13 @@ out_cancel_attach:
+ 		}
+ 	} while_each_subsys_mask();
+ out_release_tset:
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_splice_init(&tset->dst_csets, &tset->src_csets);
+ 	list_for_each_entry_safe(cset, tmp_cset, &tset->src_csets, mg_node) {
+ 		list_splice_tail_init(&cset->mg_tasks, &cset->tasks);
+ 		list_del_init(&cset->mg_node);
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	return ret;
+ }
+ 
+@@ -2634,7 +2640,7 @@ static void cgroup_migrate_finish(struct list_head *preloaded_csets)
+ 
+ 	lockdep_assert_held(&cgroup_mutex);
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry_safe(cset, tmp_cset, preloaded_csets, mg_preload_node) {
+ 		cset->mg_src_cgrp = NULL;
+ 		cset->mg_dst_cgrp = NULL;
+@@ -2642,7 +2648,7 @@ static void cgroup_migrate_finish(struct list_head *preloaded_csets)
+ 		list_del_init(&cset->mg_preload_node);
+ 		put_css_set_locked(cset);
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ }
+ 
+ /**
+@@ -2783,7 +2789,7 @@ static int cgroup_migrate(struct task_struct *leader, bool threadgroup,
+ 	 * already PF_EXITING could be freed from underneath us unless we
+ 	 * take an rcu_read_lock.
+ 	 */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	rcu_read_lock();
+ 	task = leader;
+ 	do {
+@@ -2792,7 +2798,7 @@ static int cgroup_migrate(struct task_struct *leader, bool threadgroup,
+ 			break;
+ 	} while_each_thread(leader, task);
+ 	rcu_read_unlock();
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	return cgroup_taskset_migrate(&tset, root);
+ }
+@@ -2816,7 +2822,7 @@ static int cgroup_attach_task(struct cgroup *dst_cgrp,
+ 		return -EBUSY;
+ 
+ 	/* look up all src csets */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	rcu_read_lock();
+ 	task = leader;
+ 	do {
+@@ -2826,7 +2832,7 @@ static int cgroup_attach_task(struct cgroup *dst_cgrp,
+ 			break;
+ 	} while_each_thread(leader, task);
+ 	rcu_read_unlock();
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	/* prepare dst csets and commit */
+ 	ret = cgroup_migrate_prepare_dst(&preloaded_csets);
+@@ -2859,9 +2865,9 @@ static int cgroup_procs_write_permission(struct task_struct *task,
+ 		struct cgroup *cgrp;
+ 		struct inode *inode;
+ 
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		cgrp = task_cgroup_from_root(task, &cgrp_dfl_root);
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 
+ 		while (!cgroup_is_descendant(dst_cgrp, cgrp))
+ 			cgrp = cgroup_parent(cgrp);
+@@ -2962,9 +2968,9 @@ int cgroup_attach_task_all(struct task_struct *from, struct task_struct *tsk)
+ 		if (root == &cgrp_dfl_root)
+ 			continue;
+ 
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		from_cgrp = task_cgroup_from_root(from, root);
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 
+ 		retval = cgroup_attach_task(from_cgrp, tsk, false);
+ 		if (retval)
+@@ -3080,7 +3086,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
+ 	percpu_down_write(&cgroup_threadgroup_rwsem);
+ 
+ 	/* look up all csses currently attached to @cgrp's subtree */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	cgroup_for_each_live_descendant_pre(dsct, d_css, cgrp) {
+ 		struct cgrp_cset_link *link;
+ 
+@@ -3088,14 +3094,14 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
+ 			cgroup_migrate_add_src(link->cset, dsct,
+ 					       &preloaded_csets);
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	/* NULL dst indicates self on default hierarchy */
+ 	ret = cgroup_migrate_prepare_dst(&preloaded_csets);
+ 	if (ret)
+ 		goto out_finish;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(src_cset, &preloaded_csets, mg_preload_node) {
+ 		struct task_struct *task, *ntask;
+ 
+@@ -3107,7 +3113,7 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp)
+ 		list_for_each_entry_safe(task, ntask, &src_cset->tasks, cg_list)
+ 			cgroup_taskset_add(task, &tset);
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	ret = cgroup_taskset_migrate(&tset, cgrp->root);
+ out_finish:
+@@ -3908,10 +3914,10 @@ static int cgroup_task_count(const struct cgroup *cgrp)
+ 	int count = 0;
+ 	struct cgrp_cset_link *link;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(link, &cgrp->cset_links, cset_link)
+ 		count += atomic_read(&link->cset->refcount);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	return count;
+ }
+ 
+@@ -4249,7 +4255,7 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
+ 
+ 	memset(it, 0, sizeof(*it));
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	it->ss = css->ss;
+ 
+@@ -4262,7 +4268,7 @@ void css_task_iter_start(struct cgroup_subsys_state *css,
+ 
+ 	css_task_iter_advance_css_set(it);
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ }
+ 
+ /**
+@@ -4280,7 +4286,7 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
+ 		it->cur_task = NULL;
+ 	}
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	if (it->task_pos) {
+ 		it->cur_task = list_entry(it->task_pos, struct task_struct,
+@@ -4289,7 +4295,7 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
+ 		css_task_iter_advance(it);
+ 	}
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	return it->cur_task;
+ }
+@@ -4303,10 +4309,10 @@ struct task_struct *css_task_iter_next(struct css_task_iter *it)
+ void css_task_iter_end(struct css_task_iter *it)
+ {
+ 	if (it->cur_cset) {
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		list_del(&it->iters_node);
+ 		put_css_set_locked(it->cur_cset);
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 	}
+ 
+ 	if (it->cur_task)
+@@ -4338,10 +4344,10 @@ int cgroup_transfer_tasks(struct cgroup *to, struct cgroup *from)
+ 	mutex_lock(&cgroup_mutex);
+ 
+ 	/* all tasks in @from are being moved, all csets are source */
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(link, &from->cset_links, cset_link)
+ 		cgroup_migrate_add_src(link->cset, to, &preloaded_csets);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	ret = cgroup_migrate_prepare_dst(&preloaded_csets);
+ 	if (ret)
+@@ -5063,6 +5069,7 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
+ 	memset(css, 0, sizeof(*css));
+ 	css->cgroup = cgrp;
+ 	css->ss = ss;
++	css->id = -1;
+ 	INIT_LIST_HEAD(&css->sibling);
+ 	INIT_LIST_HEAD(&css->children);
+ 	css->serial_nr = css_serial_nr_next++;
+@@ -5150,7 +5157,7 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
+ 
+ 	err = cgroup_idr_alloc(&ss->css_idr, NULL, 2, 0, GFP_KERNEL);
+ 	if (err < 0)
+-		goto err_free_percpu_ref;
++		goto err_free_css;
+ 	css->id = err;
+ 
+ 	/* @css is ready to be brought online now, make it visible */
+@@ -5174,9 +5181,6 @@ static struct cgroup_subsys_state *css_create(struct cgroup *cgrp,
+ 
+ err_list_del:
+ 	list_del_rcu(&css->sibling);
+-	cgroup_idr_remove(&ss->css_idr, css->id);
+-err_free_percpu_ref:
+-	percpu_ref_exit(&css->refcnt);
+ err_free_css:
+ 	call_rcu(&css->rcu_head, css_free_rcu_fn);
+ 	return ERR_PTR(err);
+@@ -5451,10 +5455,10 @@ static int cgroup_destroy_locked(struct cgroup *cgrp)
+ 	 */
+ 	cgrp->self.flags &= ~CSS_ONLINE;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(link, &cgrp->cset_links, cset_link)
+ 		link->cset->dead = true;
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 
+ 	/* initiate massacre of all css's */
+ 	for_each_css(css, ssid, cgrp)
+@@ -5725,7 +5729,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
+ 		goto out;
+ 
+ 	mutex_lock(&cgroup_mutex);
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	for_each_root(root) {
+ 		struct cgroup_subsys *ss;
+@@ -5778,7 +5782,7 @@ int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
+ 
+ 	retval = 0;
+ out_unlock:
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	mutex_unlock(&cgroup_mutex);
+ 	kfree(buf);
+ out:
+@@ -5923,13 +5927,13 @@ void cgroup_post_fork(struct task_struct *child)
+ 	if (use_task_css_set_links) {
+ 		struct css_set *cset;
+ 
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		cset = task_css_set(current);
+ 		if (list_empty(&child->cg_list)) {
+ 			get_css_set(cset);
+ 			css_set_move_task(child, NULL, cset, false);
+ 		}
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 	}
+ 
+ 	/*
+@@ -5974,9 +5978,9 @@ void cgroup_exit(struct task_struct *tsk)
+ 	cset = task_css_set(tsk);
+ 
+ 	if (!list_empty(&tsk->cg_list)) {
+-		spin_lock_bh(&css_set_lock);
++		spin_lock_irq(&css_set_lock);
+ 		css_set_move_task(tsk, cset, NULL, false);
+-		spin_unlock_bh(&css_set_lock);
++		spin_unlock_irq(&css_set_lock);
+ 	} else {
+ 		get_css_set(cset);
+ 	}
+@@ -6044,9 +6048,9 @@ static void cgroup_release_agent(struct work_struct *work)
+ 	if (!pathbuf || !agentbuf)
+ 		goto out;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	path = cgroup_path_ns_locked(cgrp, pathbuf, PATH_MAX, &init_cgroup_ns);
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	if (!path)
+ 		goto out;
+ 
+@@ -6306,12 +6310,12 @@ struct cgroup_namespace *copy_cgroup_ns(unsigned long flags,
+ 		return ERR_PTR(-EPERM);
+ 
+ 	mutex_lock(&cgroup_mutex);
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 
+ 	cset = task_css_set(current);
+ 	get_css_set(cset);
+ 
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	mutex_unlock(&cgroup_mutex);
+ 
+ 	new_ns = alloc_cgroup_ns();
+@@ -6435,7 +6439,7 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v)
+ 	if (!name_buf)
+ 		return -ENOMEM;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	rcu_read_lock();
+ 	cset = rcu_dereference(current->cgroups);
+ 	list_for_each_entry(link, &cset->cgrp_links, cgrp_link) {
+@@ -6446,7 +6450,7 @@ static int current_css_set_cg_links_read(struct seq_file *seq, void *v)
+ 			   c->root->hierarchy_id, name_buf);
+ 	}
+ 	rcu_read_unlock();
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	kfree(name_buf);
+ 	return 0;
+ }
+@@ -6457,7 +6461,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v)
+ 	struct cgroup_subsys_state *css = seq_css(seq);
+ 	struct cgrp_cset_link *link;
+ 
+-	spin_lock_bh(&css_set_lock);
++	spin_lock_irq(&css_set_lock);
+ 	list_for_each_entry(link, &css->cgroup->cset_links, cset_link) {
+ 		struct css_set *cset = link->cset;
+ 		struct task_struct *task;
+@@ -6480,7 +6484,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v)
+ 	overflow:
+ 		seq_puts(seq, "  ...\n");
+ 	}
+-	spin_unlock_bh(&css_set_lock);
++	spin_unlock_irq(&css_set_lock);
+ 	return 0;
+ }
+ 
+diff --git a/kernel/cpu.c b/kernel/cpu.c
+index 3e3f6e49eabb..e7cea29bb9e2 100644
+--- a/kernel/cpu.c
++++ b/kernel/cpu.c
+@@ -1218,6 +1218,8 @@ static struct cpuhp_step cpuhp_bp_states[] = {
+ 		.teardown		= takedown_cpu,
+ 		.cant_stop		= true,
+ 	},
++#else
++	[CPUHP_BRINGUP_CPU] = { },
+ #endif
+ };
+ 
+diff --git a/kernel/sched/core.c b/kernel/sched/core.c
+index 11546a6ed5df..65716cef21f4 100644
+--- a/kernel/sched/core.c
++++ b/kernel/sched/core.c
+@@ -4993,14 +4993,16 @@ void show_state_filter(unsigned long state_filter)
+ 		/*
+ 		 * reset the NMI-timeout, listing all files on a slow
+ 		 * console might take a lot of time:
++		 * Also, reset softlockup watchdogs on all CPUs, because
++		 * another CPU might be blocked waiting for us to process
++		 * an IPI.
+ 		 */
+ 		touch_nmi_watchdog();
++		touch_all_softlockup_watchdogs();
+ 		if (!state_filter || (p->state & state_filter))
+ 			sched_show_task(p);
+ 	}
+ 
+-	touch_all_softlockup_watchdogs();
+-
+ #ifdef CONFIG_SCHED_DEBUG
+ 	sysrq_sched_debug_show();
+ #endif
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
+index eeaf920f46b9..0858959cf747 100644
+--- a/kernel/sched/fair.c
++++ b/kernel/sched/fair.c
+@@ -687,8 +687,6 @@ void init_entity_runnable_average(struct sched_entity *se)
+ 	/* when this task enqueue'ed, it will contribute to its cfs_rq's load_avg */
+ }
+ 
+-static inline unsigned long cfs_rq_runnable_load_avg(struct cfs_rq *cfs_rq);
+-static inline unsigned long cfs_rq_load_avg(struct cfs_rq *cfs_rq);
+ #else
+ void init_entity_runnable_average(struct sched_entity *se)
+ {
+@@ -3194,7 +3192,7 @@ static inline void check_schedstat_required(void)
+ 			trace_sched_stat_iowait_enabled()  ||
+ 			trace_sched_stat_blocked_enabled() ||
+ 			trace_sched_stat_runtime_enabled())  {
+-		pr_warn_once("Scheduler tracepoints stat_sleep, stat_iowait, "
++		printk_deferred_once("Scheduler tracepoints stat_sleep, stat_iowait, "
+ 			     "stat_blocked and stat_runtime require the "
+ 			     "kernel parameter schedstats=enabled or "
+ 			     "kernel.sched_schedstats=1\n");
+@@ -4822,19 +4820,24 @@ static long effective_load(struct task_group *tg, int cpu, long wl, long wg)
+ 		return wl;
+ 
+ 	for_each_sched_entity(se) {
+-		long w, W;
++		struct cfs_rq *cfs_rq = se->my_q;
++		long W, w = cfs_rq_load_avg(cfs_rq);
+ 
+-		tg = se->my_q->tg;
++		tg = cfs_rq->tg;
+ 
+ 		/*
+ 		 * W = @wg + \Sum rw_j
+ 		 */
+-		W = wg + calc_tg_weight(tg, se->my_q);
++		W = wg + atomic_long_read(&tg->load_avg);
++
++		/* Ensure \Sum rw_j >= rw_i */
++		W -= cfs_rq->tg_load_avg_contrib;
++		W += w;
+ 
+ 		/*
+ 		 * w = rw_i + @wl
+ 		 */
+-		w = cfs_rq_load_avg(se->my_q) + wl;
++		w += wl;
+ 
+ 		/*
+ 		 * wl = S * s'_i; see (2)
+diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
+index 1cafba860b08..39008d78927a 100644
+--- a/kernel/time/posix-cpu-timers.c
++++ b/kernel/time/posix-cpu-timers.c
+@@ -777,6 +777,7 @@ static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp)
+ 			timer->it.cpu.expires = 0;
+ 			sample_to_timespec(timer->it_clock, timer->it.cpu.expires,
+ 					   &itp->it_value);
++			return;
+ 		} else {
+ 			cpu_timer_sample_group(timer->it_clock, p, &now);
+ 			unlock_task_sighand(p, &flags);
+diff --git a/mm/compaction.c b/mm/compaction.c
+index f8e925eb479b..c59a3c480f83 100644
+--- a/mm/compaction.c
++++ b/mm/compaction.c
+@@ -436,25 +436,23 @@ static unsigned long isolate_freepages_block(struct compact_control *cc,
+ 
+ 		/* Found a free page, break it into order-0 pages */
+ 		isolated = split_free_page(page);
++		if (!isolated)
++			break;
++
+ 		total_isolated += isolated;
++		cc->nr_freepages += isolated;
+ 		for (i = 0; i < isolated; i++) {
+ 			list_add(&page->lru, freelist);
+ 			page++;
+ 		}
+-
+-		/* If a page was split, advance to the end of it */
+-		if (isolated) {
+-			cc->nr_freepages += isolated;
+-			if (!strict &&
+-				cc->nr_migratepages <= cc->nr_freepages) {
+-				blockpfn += isolated;
+-				break;
+-			}
+-
+-			blockpfn += isolated - 1;
+-			cursor += isolated - 1;
+-			continue;
++		if (!strict && cc->nr_migratepages <= cc->nr_freepages) {
++			blockpfn += isolated;
++			break;
+ 		}
++		/* Advance to the end of split page */
++		blockpfn += isolated - 1;
++		cursor += isolated - 1;
++		continue;
+ 
+ isolate_fail:
+ 		if (strict)
+@@ -464,6 +462,9 @@ isolate_fail:
+ 
+ 	}
+ 
++	if (locked)
++		spin_unlock_irqrestore(&cc->zone->lock, flags);
++
+ 	/*
+ 	 * There is a tiny chance that we have read bogus compound_order(),
+ 	 * so be careful to not go outside of the pageblock.
+@@ -485,9 +486,6 @@ isolate_fail:
+ 	if (strict && blockpfn < end_pfn)
+ 		total_isolated = 0;
+ 
+-	if (locked)
+-		spin_unlock_irqrestore(&cc->zone->lock, flags);
+-
+ 	/* Update the pageblock-skip if the whole pageblock was scanned */
+ 	if (blockpfn == end_pfn)
+ 		update_pageblock_skip(cc, valid_page, total_isolated, false);
+@@ -938,7 +936,6 @@ static void isolate_freepages(struct compact_control *cc)
+ 				block_end_pfn = block_start_pfn,
+ 				block_start_pfn -= pageblock_nr_pages,
+ 				isolate_start_pfn = block_start_pfn) {
+-
+ 		/*
+ 		 * This can iterate a massively long zone without finding any
+ 		 * suitable migration targets, so periodically check if we need
+@@ -962,32 +959,30 @@ static void isolate_freepages(struct compact_control *cc)
+ 			continue;
+ 
+ 		/* Found a block suitable for isolating free pages from. */
+-		isolate_freepages_block(cc, &isolate_start_pfn,
+-					block_end_pfn, freelist, false);
++		isolate_freepages_block(cc, &isolate_start_pfn, block_end_pfn,
++					freelist, false);
+ 
+ 		/*
+-		 * If we isolated enough freepages, or aborted due to async
+-		 * compaction being contended, terminate the loop.
+-		 * Remember where the free scanner should restart next time,
+-		 * which is where isolate_freepages_block() left off.
+-		 * But if it scanned the whole pageblock, isolate_start_pfn
+-		 * now points at block_end_pfn, which is the start of the next
+-		 * pageblock.
+-		 * In that case we will however want to restart at the start
+-		 * of the previous pageblock.
++		 * If we isolated enough freepages, or aborted due to lock
++		 * contention, terminate.
+ 		 */
+ 		if ((cc->nr_freepages >= cc->nr_migratepages)
+ 							|| cc->contended) {
+-			if (isolate_start_pfn >= block_end_pfn)
++			if (isolate_start_pfn >= block_end_pfn) {
++				/*
++				 * Restart at previous pageblock if more
++				 * freepages can be isolated next time.
++				 */
+ 				isolate_start_pfn =
+ 					block_start_pfn - pageblock_nr_pages;
++			}
+ 			break;
+-		} else {
++		} else if (isolate_start_pfn < block_end_pfn) {
+ 			/*
+-			 * isolate_freepages_block() should not terminate
+-			 * prematurely unless contended, or isolated enough
++			 * If isolation failed early, do not continue
++			 * needlessly.
+ 			 */
+-			VM_BUG_ON(isolate_start_pfn < block_end_pfn);
++			break;
+ 		}
+ 	}
+ 
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 19d0d08b396f..6b5058f9a1e3 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -3328,7 +3328,7 @@ retry_avoidcopy:
+ 	/* If no-one else is actually using this page, avoid the copy
+ 	 * and just make the page writable */
+ 	if (page_mapcount(old_page) == 1 && PageAnon(old_page)) {
+-		page_move_anon_rmap(old_page, vma, address);
++		page_move_anon_rmap(old_page, vma);
+ 		set_huge_ptep_writable(vma, address, ptep);
+ 		return 0;
+ 	}
+diff --git a/mm/internal.h b/mm/internal.h
+index b79abb6721cf..bb309ad2b5e3 100644
+--- a/mm/internal.h
++++ b/mm/internal.h
+@@ -24,7 +24,8 @@
+  */
+ #define GFP_RECLAIM_MASK (__GFP_RECLAIM|__GFP_HIGH|__GFP_IO|__GFP_FS|\
+ 			__GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
+-			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC)
++			__GFP_NORETRY|__GFP_MEMALLOC|__GFP_NOMEMALLOC|\
++			__GFP_ATOMIC)
+ 
+ /* The GFP flags allowed during early boot */
+ #define GFP_BOOT_MASK (__GFP_BITS_MASK & ~(__GFP_RECLAIM|__GFP_IO|__GFP_FS))
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index a2e79b83920f..bf860dbdd26e 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4038,6 +4038,60 @@ static struct cftype mem_cgroup_legacy_files[] = {
+ 	{ },	/* terminate */
+ };
+ 
++/*
++ * Private memory cgroup IDR
++ *
++ * Swap-out records and page cache shadow entries need to store memcg
++ * references in constrained space, so we maintain an ID space that is
++ * limited to 16 bit (MEM_CGROUP_ID_MAX), limiting the total number of
++ * memory-controlled cgroups to 64k.
++ *
++ * However, there usually are many references to the oflline CSS after
++ * the cgroup has been destroyed, such as page cache or reclaimable
++ * slab objects, that don't need to hang on to the ID. We want to keep
++ * those dead CSS from occupying IDs, or we might quickly exhaust the
++ * relatively small ID space and prevent the creation of new cgroups
++ * even when there are much fewer than 64k cgroups - possibly none.
++ *
++ * Maintain a private 16-bit ID space for memcg, and allow the ID to
++ * be freed and recycled when it's no longer needed, which is usually
++ * when the CSS is offlined.
++ *
++ * The only exception to that are records of swapped out tmpfs/shmem
++ * pages that need to be attributed to live ancestors on swapin. But
++ * those references are manageable from userspace.
++ */
++
++static DEFINE_IDR(mem_cgroup_idr);
++
++static void mem_cgroup_id_get(struct mem_cgroup *memcg)
++{
++	atomic_inc(&memcg->id.ref);
++}
++
++static void mem_cgroup_id_put(struct mem_cgroup *memcg)
++{
++	if (atomic_dec_and_test(&memcg->id.ref)) {
++		idr_remove(&mem_cgroup_idr, memcg->id.id);
++		memcg->id.id = 0;
++
++		/* Memcg ID pins CSS */
++		css_put(&memcg->css);
++	}
++}
++
++/**
++ * mem_cgroup_from_id - look up a memcg from a memcg id
++ * @id: the memcg id to look up
++ *
++ * Caller must hold rcu_read_lock().
++ */
++struct mem_cgroup *mem_cgroup_from_id(unsigned short id)
++{
++	WARN_ON_ONCE(!rcu_read_lock_held());
++	return idr_find(&mem_cgroup_idr, id);
++}
++
+ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *memcg, int node)
+ {
+ 	struct mem_cgroup_per_node *pn;
+@@ -4097,6 +4151,12 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
+ 	if (!memcg)
+ 		return NULL;
+ 
++	memcg->id.id = idr_alloc(&mem_cgroup_idr, NULL,
++				 1, MEM_CGROUP_ID_MAX,
++				 GFP_KERNEL);
++	if (memcg->id.id < 0)
++		goto fail;
++
+ 	memcg->stat = alloc_percpu(struct mem_cgroup_stat_cpu);
+ 	if (!memcg->stat)
+ 		goto fail;
+@@ -4123,8 +4183,11 @@ static struct mem_cgroup *mem_cgroup_alloc(void)
+ #ifdef CONFIG_CGROUP_WRITEBACK
+ 	INIT_LIST_HEAD(&memcg->cgwb_list);
+ #endif
++	idr_replace(&mem_cgroup_idr, memcg, memcg->id.id);
+ 	return memcg;
+ fail:
++	if (memcg->id.id > 0)
++		idr_remove(&mem_cgroup_idr, memcg->id.id);
+ 	mem_cgroup_free(memcg);
+ 	return NULL;
+ }
+@@ -4184,15 +4247,14 @@ mem_cgroup_css_alloc(struct cgroup_subsys_state *parent_css)
+ 	return &memcg->css;
+ fail:
+ 	mem_cgroup_free(memcg);
+-	return NULL;
++	return ERR_PTR(-ENOMEM);
+ }
+ 
+-static int
+-mem_cgroup_css_online(struct cgroup_subsys_state *css)
++static int mem_cgroup_css_online(struct cgroup_subsys_state *css)
+ {
+-	if (css->id > MEM_CGROUP_ID_MAX)
+-		return -ENOSPC;
+-
++	/* Online state pins memcg ID, memcg ID pins CSS */
++	mem_cgroup_id_get(mem_cgroup_from_css(css));
++	css_get(css);
+ 	return 0;
+ }
+ 
+@@ -4215,6 +4277,8 @@ static void mem_cgroup_css_offline(struct cgroup_subsys_state *css)
+ 
+ 	memcg_offline_kmem(memcg);
+ 	wb_memcg_offline(memcg);
++
++	mem_cgroup_id_put(memcg);
+ }
+ 
+ static void mem_cgroup_css_released(struct cgroup_subsys_state *css)
+@@ -5524,6 +5588,7 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage)
+ 	struct mem_cgroup *memcg;
+ 	unsigned int nr_pages;
+ 	bool compound;
++	unsigned long flags;
+ 
+ 	VM_BUG_ON_PAGE(!PageLocked(oldpage), oldpage);
+ 	VM_BUG_ON_PAGE(!PageLocked(newpage), newpage);
+@@ -5554,10 +5619,10 @@ void mem_cgroup_migrate(struct page *oldpage, struct page *newpage)
+ 
+ 	commit_charge(newpage, memcg, false);
+ 
+-	local_irq_disable();
++	local_irq_save(flags);
+ 	mem_cgroup_charge_statistics(memcg, newpage, compound, nr_pages);
+ 	memcg_check_events(memcg, newpage);
+-	local_irq_enable();
++	local_irq_restore(flags);
+ }
+ 
+ DEFINE_STATIC_KEY_FALSE(memcg_sockets_enabled_key);
+@@ -5735,6 +5800,7 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
+ 	if (!memcg)
+ 		return;
+ 
++	mem_cgroup_id_get(memcg);
+ 	oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
+ 	VM_BUG_ON_PAGE(oldid, page);
+ 	mem_cgroup_swap_statistics(memcg, true);
+@@ -5753,6 +5819,9 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
+ 	VM_BUG_ON(!irqs_disabled());
+ 	mem_cgroup_charge_statistics(memcg, page, false, -1);
+ 	memcg_check_events(memcg, page);
++
++	if (!mem_cgroup_is_root(memcg))
++		css_put(&memcg->css);
+ }
+ 
+ /*
+@@ -5783,11 +5852,11 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
+ 	    !page_counter_try_charge(&memcg->swap, 1, &counter))
+ 		return -ENOMEM;
+ 
++	mem_cgroup_id_get(memcg);
+ 	oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
+ 	VM_BUG_ON_PAGE(oldid, page);
+ 	mem_cgroup_swap_statistics(memcg, true);
+ 
+-	css_get(&memcg->css);
+ 	return 0;
+ }
+ 
+@@ -5816,7 +5885,7 @@ void mem_cgroup_uncharge_swap(swp_entry_t entry)
+ 				page_counter_uncharge(&memcg->memsw, 1);
+ 		}
+ 		mem_cgroup_swap_statistics(memcg, false);
+-		css_put(&memcg->css);
++		mem_cgroup_id_put(memcg);
+ 	}
+ 	rcu_read_unlock();
+ }
+diff --git a/mm/memory.c b/mm/memory.c
+index 07493e34ab7e..338cc5406fe0 100644
+--- a/mm/memory.c
++++ b/mm/memory.c
+@@ -2397,8 +2397,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
+ 				 * Protected against the rmap code by
+ 				 * the page lock.
+ 				 */
+-				page_move_anon_rmap(compound_head(old_page),
+-						    vma, address);
++				page_move_anon_rmap(old_page, vma);
+ 			}
+ 			unlock_page(old_page);
+ 			return wp_page_reuse(mm, vma, address, page_table, ptl,
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c
+index 898fe3f909f9..ff50f5974d74 100644
+--- a/mm/page_alloc.c
++++ b/mm/page_alloc.c
+@@ -286,7 +286,9 @@ static inline void reset_deferred_meminit(pg_data_t *pgdat)
+ /* Returns true if the struct page for the pfn is uninitialised */
+ static inline bool __meminit early_page_uninitialised(unsigned long pfn)
+ {
+-	if (pfn >= NODE_DATA(early_pfn_to_nid(pfn))->first_deferred_pfn)
++	int nid = early_pfn_to_nid(pfn);
++
++	if (node_online(nid) && pfn >= NODE_DATA(nid)->first_deferred_pfn)
+ 		return true;
+ 
+ 	return false;
+@@ -1110,7 +1112,7 @@ int __meminit early_pfn_to_nid(unsigned long pfn)
+ 	spin_lock(&early_pfn_lock);
+ 	nid = __early_pfn_to_nid(pfn, &early_pfnnid_cache);
+ 	if (nid < 0)
+-		nid = 0;
++		nid = first_online_node;
+ 	spin_unlock(&early_pfn_lock);
+ 
+ 	return nid;
+diff --git a/mm/rmap.c b/mm/rmap.c
+index 3ebf9c4c2f4d..08fc03a31aaa 100644
+--- a/mm/rmap.c
++++ b/mm/rmap.c
+@@ -1084,23 +1084,20 @@ EXPORT_SYMBOL_GPL(page_mkclean);
+  * page_move_anon_rmap - move a page to our anon_vma
+  * @page:	the page to move to our anon_vma
+  * @vma:	the vma the page belongs to
+- * @address:	the user virtual address mapped
+  *
+  * When a page belongs exclusively to one process after a COW event,
+  * that page can be moved into the anon_vma that belongs to just that
+  * process, so the rmap code will not search the parent or sibling
+  * processes.
+  */
+-void page_move_anon_rmap(struct page *page,
+-	struct vm_area_struct *vma, unsigned long address)
++void page_move_anon_rmap(struct page *page, struct vm_area_struct *vma)
+ {
+ 	struct anon_vma *anon_vma = vma->anon_vma;
+ 
++	page = compound_head(page);
++
+ 	VM_BUG_ON_PAGE(!PageLocked(page), page);
+ 	VM_BUG_ON_VMA(!anon_vma, vma);
+-	if (IS_ENABLED(CONFIG_DEBUG_VM) && PageTransHuge(page))
+-		address &= HPAGE_PMD_MASK;
+-	VM_BUG_ON_PAGE(page->index != linear_page_index(vma, address), page);
+ 
+ 	anon_vma = (void *) anon_vma + PAGE_MAPPING_ANON;
+ 	/*
+diff --git a/mm/slab_common.c b/mm/slab_common.c
+index 3239bfd758e6..3ac9e661dc86 100644
+--- a/mm/slab_common.c
++++ b/mm/slab_common.c
+@@ -526,8 +526,8 @@ void memcg_create_kmem_cache(struct mem_cgroup *memcg,
+ 		goto out_unlock;
+ 
+ 	cgroup_name(css->cgroup, memcg_name_buf, sizeof(memcg_name_buf));
+-	cache_name = kasprintf(GFP_KERNEL, "%s(%d:%s)", root_cache->name,
+-			       css->id, memcg_name_buf);
++	cache_name = kasprintf(GFP_KERNEL, "%s(%llu:%s)", root_cache->name,
++			       css->serial_nr, memcg_name_buf);
+ 	if (!cache_name)
+ 		goto out_unlock;
+ 
+diff --git a/mm/swap.c b/mm/swap.c
+index 03aacbcb013f..374aa6e0c576 100644
+--- a/mm/swap.c
++++ b/mm/swap.c
+@@ -239,7 +239,7 @@ void rotate_reclaimable_page(struct page *page)
+ 		get_page(page);
+ 		local_irq_save(flags);
+ 		pvec = this_cpu_ptr(&lru_rotate_pvecs);
+-		if (!pagevec_add(pvec, page))
++		if (!pagevec_add(pvec, page) || PageCompound(page))
+ 			pagevec_move_tail(pvec);
+ 		local_irq_restore(flags);
+ 	}
+@@ -295,7 +295,7 @@ void activate_page(struct page *page)
+ 		struct pagevec *pvec = &get_cpu_var(activate_page_pvecs);
+ 
+ 		get_page(page);
+-		if (!pagevec_add(pvec, page))
++		if (!pagevec_add(pvec, page) || PageCompound(page))
+ 			pagevec_lru_move_fn(pvec, __activate_page, NULL);
+ 		put_cpu_var(activate_page_pvecs);
+ 	}
+@@ -390,9 +390,8 @@ static void __lru_cache_add(struct page *page)
+ 	struct pagevec *pvec = &get_cpu_var(lru_add_pvec);
+ 
+ 	get_page(page);
+-	if (!pagevec_space(pvec))
++	if (!pagevec_add(pvec, page) || PageCompound(page))
+ 		__pagevec_lru_add(pvec);
+-	pagevec_add(pvec, page);
+ 	put_cpu_var(lru_add_pvec);
+ }
+ 
+@@ -627,7 +626,7 @@ void deactivate_file_page(struct page *page)
+ 	if (likely(get_page_unless_zero(page))) {
+ 		struct pagevec *pvec = &get_cpu_var(lru_deactivate_file_pvecs);
+ 
+-		if (!pagevec_add(pvec, page))
++		if (!pagevec_add(pvec, page) || PageCompound(page))
+ 			pagevec_lru_move_fn(pvec, lru_deactivate_file_fn, NULL);
+ 		put_cpu_var(lru_deactivate_file_pvecs);
+ 	}
+@@ -647,7 +646,7 @@ void deactivate_page(struct page *page)
+ 		struct pagevec *pvec = &get_cpu_var(lru_deactivate_pvecs);
+ 
+ 		get_page(page);
+-		if (!pagevec_add(pvec, page))
++		if (!pagevec_add(pvec, page) || PageCompound(page))
+ 			pagevec_lru_move_fn(pvec, lru_deactivate_fn, NULL);
+ 		put_cpu_var(lru_deactivate_pvecs);
+ 	}
+diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c
+index 243574c8cf33..8a832fa80dde 100644
+--- a/net/ceph/osdmap.c
++++ b/net/ceph/osdmap.c
+@@ -1201,6 +1201,115 @@ struct ceph_osdmap *ceph_osdmap_decode(void **p, void *end)
+ }
+ 
+ /*
++ * Encoding order is (new_up_client, new_state, new_weight).  Need to
++ * apply in the (new_weight, new_state, new_up_client) order, because
++ * an incremental map may look like e.g.
++ *
++ *     new_up_client: { osd=6, addr=... } # set osd_state and addr
++ *     new_state: { osd=6, xorstate=EXISTS } # clear osd_state
++ */
++static int decode_new_up_state_weight(void **p, void *end,
++				      struct ceph_osdmap *map)
++{
++	void *new_up_client;
++	void *new_state;
++	void *new_weight_end;
++	u32 len;
++
++	new_up_client = *p;
++	ceph_decode_32_safe(p, end, len, e_inval);
++	len *= sizeof(u32) + sizeof(struct ceph_entity_addr);
++	ceph_decode_need(p, end, len, e_inval);
++	*p += len;
++
++	new_state = *p;
++	ceph_decode_32_safe(p, end, len, e_inval);
++	len *= sizeof(u32) + sizeof(u8);
++	ceph_decode_need(p, end, len, e_inval);
++	*p += len;
++
++	/* new_weight */
++	ceph_decode_32_safe(p, end, len, e_inval);
++	while (len--) {
++		s32 osd;
++		u32 w;
++
++		ceph_decode_need(p, end, 2*sizeof(u32), e_inval);
++		osd = ceph_decode_32(p);
++		w = ceph_decode_32(p);
++		BUG_ON(osd >= map->max_osd);
++		pr_info("osd%d weight 0x%x %s\n", osd, w,
++		     w == CEPH_OSD_IN ? "(in)" :
++		     (w == CEPH_OSD_OUT ? "(out)" : ""));
++		map->osd_weight[osd] = w;
++
++		/*
++		 * If we are marking in, set the EXISTS, and clear the
++		 * AUTOOUT and NEW bits.
++		 */
++		if (w) {
++			map->osd_state[osd] |= CEPH_OSD_EXISTS;
++			map->osd_state[osd] &= ~(CEPH_OSD_AUTOOUT |
++						 CEPH_OSD_NEW);
++		}
++	}
++	new_weight_end = *p;
++
++	/* new_state (up/down) */
++	*p = new_state;
++	len = ceph_decode_32(p);
++	while (len--) {
++		s32 osd;
++		u8 xorstate;
++		int ret;
++
++		osd = ceph_decode_32(p);
++		xorstate = ceph_decode_8(p);
++		if (xorstate == 0)
++			xorstate = CEPH_OSD_UP;
++		BUG_ON(osd >= map->max_osd);
++		if ((map->osd_state[osd] & CEPH_OSD_UP) &&
++		    (xorstate & CEPH_OSD_UP))
++			pr_info("osd%d down\n", osd);
++		if ((map->osd_state[osd] & CEPH_OSD_EXISTS) &&
++		    (xorstate & CEPH_OSD_EXISTS)) {
++			pr_info("osd%d does not exist\n", osd);
++			map->osd_weight[osd] = CEPH_OSD_IN;
++			ret = set_primary_affinity(map, osd,
++						   CEPH_OSD_DEFAULT_PRIMARY_AFFINITY);
++			if (ret)
++				return ret;
++			memset(map->osd_addr + osd, 0, sizeof(*map->osd_addr));
++			map->osd_state[osd] = 0;
++		} else {
++			map->osd_state[osd] ^= xorstate;
++		}
++	}
++
++	/* new_up_client */
++	*p = new_up_client;
++	len = ceph_decode_32(p);
++	while (len--) {
++		s32 osd;
++		struct ceph_entity_addr addr;
++
++		osd = ceph_decode_32(p);
++		ceph_decode_copy(p, &addr, sizeof(addr));
++		ceph_decode_addr(&addr);
++		BUG_ON(osd >= map->max_osd);
++		pr_info("osd%d up\n", osd);
++		map->osd_state[osd] |= CEPH_OSD_EXISTS | CEPH_OSD_UP;
++		map->osd_addr[osd] = addr;
++	}
++
++	*p = new_weight_end;
++	return 0;
++
++e_inval:
++	return -EINVAL;
++}
++
++/*
+  * decode and apply an incremental map update.
+  */
+ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+@@ -1299,49 +1408,10 @@ struct ceph_osdmap *osdmap_apply_incremental(void **p, void *end,
+ 			__remove_pg_pool(&map->pg_pools, pi);
+ 	}
+ 
+-	/* new_up */
+-	ceph_decode_32_safe(p, end, len, e_inval);
+-	while (len--) {
+-		u32 osd;
+-		struct ceph_entity_addr addr;
+-		ceph_decode_32_safe(p, end, osd, e_inval);
+-		ceph_decode_copy_safe(p, end, &addr, sizeof(addr), e_inval);
+-		ceph_decode_addr(&addr);
+-		pr_info("osd%d up\n", osd);
+-		BUG_ON(osd >= map->max_osd);
+-		map->osd_state[osd] |= CEPH_OSD_UP | CEPH_OSD_EXISTS;
+-		map->osd_addr[osd] = addr;
+-	}
+-
+-	/* new_state */
+-	ceph_decode_32_safe(p, end, len, e_inval);
+-	while (len--) {
+-		u32 osd;
+-		u8 xorstate;
+-		ceph_decode_32_safe(p, end, osd, e_inval);
+-		xorstate = **(u8 **)p;
+-		(*p)++;  /* clean flag */
+-		if (xorstate == 0)
+-			xorstate = CEPH_OSD_UP;
+-		if (xorstate & CEPH_OSD_UP)
+-			pr_info("osd%d down\n", osd);
+-		if (osd < map->max_osd)
+-			map->osd_state[osd] ^= xorstate;
+-	}
+-
+-	/* new_weight */
+-	ceph_decode_32_safe(p, end, len, e_inval);
+-	while (len--) {
+-		u32 osd, off;
+-		ceph_decode_need(p, end, sizeof(u32)*2, e_inval);
+-		osd = ceph_decode_32(p);
+-		off = ceph_decode_32(p);
+-		pr_info("osd%d weight 0x%x %s\n", osd, off,
+-		     off == CEPH_OSD_IN ? "(in)" :
+-		     (off == CEPH_OSD_OUT ? "(out)" : ""));
+-		if (osd < map->max_osd)
+-			map->osd_weight[osd] = off;
+-	}
++	/* new_up_client, new_state, new_weight */
++	err = decode_new_up_state_weight(p, end, map);
++	if (err)
++		goto bad;
+ 
+ 	/* new_pg_temp */
+ 	err = decode_new_pg_temp(p, end, map);
+diff --git a/net/rds/tcp.c b/net/rds/tcp.c
+index 86187dad1440..f8d94f4042ef 100644
+--- a/net/rds/tcp.c
++++ b/net/rds/tcp.c
+@@ -544,7 +544,7 @@ static int rds_tcp_init(void)
+ 
+ 	ret = rds_tcp_recv_init();
+ 	if (ret)
+-		goto out_slab;
++		goto out_pernet;
+ 
+ 	ret = rds_trans_register(&rds_tcp_transport);
+ 	if (ret)
+@@ -556,8 +556,9 @@ static int rds_tcp_init(void)
+ 
+ out_recv:
+ 	rds_tcp_recv_exit();
+-out_slab:
++out_pernet:
+ 	unregister_pernet_subsys(&rds_tcp_net_ops);
++out_slab:
+ 	kmem_cache_destroy(rds_tcp_conn_slab);
+ out:
+ 	return ret;
+diff --git a/net/wireless/util.c b/net/wireless/util.c
+index 47b917841623..29b145ed3338 100644
+--- a/net/wireless/util.c
++++ b/net/wireless/util.c
+@@ -721,6 +721,8 @@ __ieee80211_amsdu_copy(struct sk_buff *skb, unsigned int hlen,
+ 	 * alignment since sizeof(struct ethhdr) is 14.
+ 	 */
+ 	frame = dev_alloc_skb(hlen + sizeof(struct ethhdr) + 2 + cur_len);
++	if (!frame)
++		return NULL;
+ 
+ 	skb_reserve(frame, hlen + sizeof(struct ethhdr) + 2);
+ 	skb_copy_bits(skb, offset, skb_put(frame, cur_len), cur_len);
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index 23b73f6ac040..98378539fc59 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -1225,6 +1225,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri,
+ 		tu->tstamp = *tstamp;
+ 	if ((tu->filter & (1 << event)) == 0 || !tu->tread)
+ 		return;
++	memset(&r1, 0, sizeof(r1));
+ 	r1.event = event;
+ 	r1.tstamp = *tstamp;
+ 	r1.val = resolution;
+@@ -1267,6 +1268,7 @@ static void snd_timer_user_tinterrupt(struct snd_timer_instance *timeri,
+ 	}
+ 	if ((tu->filter & (1 << SNDRV_TIMER_EVENT_RESOLUTION)) &&
+ 	    tu->last_resolution != resolution) {
++		memset(&r1, 0, sizeof(r1));
+ 		r1.event = SNDRV_TIMER_EVENT_RESOLUTION;
+ 		r1.tstamp = tstamp;
+ 		r1.val = resolution;
+@@ -1739,6 +1741,7 @@ static int snd_timer_user_params(struct file *file,
+ 	if (tu->timeri->flags & SNDRV_TIMER_IFLG_EARLY_EVENT) {
+ 		if (tu->tread) {
+ 			struct snd_timer_tread tread;
++			memset(&tread, 0, sizeof(tread));
+ 			tread.event = SNDRV_TIMER_EVENT_EARLY;
+ 			tread.tstamp.tv_sec = 0;
+ 			tread.tstamp.tv_nsec = 0;


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

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

commit:     adac5d24f7d9814142c94318ccb82b69e9d91a3c
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 12 11:24:28 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Fri Aug 12 11:24:28 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=adac5d24

Rename one of the BFQ patches. See bug #591078.

 0000_README                                                             | 2 +-
 ... => 5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch1 | 0
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/0000_README b/0000_README
index 1bb262e..a0547ab 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.6.patch
 From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
 Desc:   BFQ v7r11 patch 3 for 4.6: Early Queue Merge (EQM)
 
-Patch:  5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2
+Patch:  5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch1
 From:   http://algo.ing.unimo.it/people/paolo/disk_sched/
 Desc:   BFQ v7r11 patch 4 for 4.7: Early Queue Merge (EQM)
 

diff --git a/5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2 b/5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch1
similarity index 100%
rename from 5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch2
rename to 5004_blkck-bfq-turn-BFQ-v7r11-for-4.7.0-into-BFQ-v8-for-4.patch1


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

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

commit:     df00160fd19ac3ffbd1887ee9bdc64384f4f8421
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Tue Aug 16 23:53:09 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Tue Aug 16 23:53:09 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=df00160f

Linux patch 4.6.7

 0000_README            |    4 +
 1006_linux-4.6.7.patch | 2184 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2188 insertions(+)

diff --git a/0000_README b/0000_README
index a0547ab..90202fe 100644
--- a/0000_README
+++ b/0000_README
@@ -67,6 +67,10 @@ Patch:  1005_linux-4.6.6.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.6.6
 
+Patch:  1006_linux-4.6.7.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.6.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.6.7.patch b/1006_linux-4.6.7.patch
new file mode 100644
index 0000000..0bd4bce
--- /dev/null
+++ b/1006_linux-4.6.7.patch
@@ -0,0 +1,2184 @@
+diff --git a/Documentation/cpu-freq/pcc-cpufreq.txt b/Documentation/cpu-freq/pcc-cpufreq.txt
+index 0a94224ad296..9e3c3b33514c 100644
+--- a/Documentation/cpu-freq/pcc-cpufreq.txt
++++ b/Documentation/cpu-freq/pcc-cpufreq.txt
+@@ -159,8 +159,8 @@ to be strictly associated with a P-state.
+ 
+ 2.2 cpuinfo_transition_latency:
+ -------------------------------
+-The cpuinfo_transition_latency field is CPUFREQ_ETERNAL. The PCC specification
+-does not include a field to expose this value currently.
++The cpuinfo_transition_latency field is 0. The PCC specification does
++not include a field to expose this value currently.
+ 
+ 2.3 cpuinfo_cur_freq:
+ ---------------------
+diff --git a/Documentation/x86/pat.txt b/Documentation/x86/pat.txt
+index 54944c71b819..2a4ee6302122 100644
+--- a/Documentation/x86/pat.txt
++++ b/Documentation/x86/pat.txt
+@@ -196,3 +196,35 @@ Another, more verbose way of getting PAT related debug messages is with
+ "debugpat" boot parameter. With this parameter, various debug messages are
+ printed to dmesg log.
+ 
++PAT Initialization
++------------------
++
++The following table describes how PAT is initialized under various
++configurations. The PAT MSR must be updated by Linux in order to support WC
++and WT attributes. Otherwise, the PAT MSR has the value programmed in it
++by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests.
++
++ MTRR PAT   Call Sequence               PAT State  PAT MSR
++ =========================================================
++ E    E     MTRR -> PAT init            Enabled    OS
++ E    D     MTRR -> PAT init            Disabled    -
++ D    E     MTRR -> PAT disable         Disabled   BIOS
++ D    D     MTRR -> PAT disable         Disabled    -
++ -    np/E  PAT  -> PAT disable         Disabled   BIOS
++ -    np/D  PAT  -> PAT disable         Disabled    -
++ E    !P/E  MTRR -> PAT init            Disabled   BIOS
++ D    !P/E  MTRR -> PAT disable         Disabled   BIOS
++ !M   !P/E  MTRR stub -> PAT disable    Disabled   BIOS
++
++ Legend
++ ------------------------------------------------
++ E         Feature enabled in CPU
++ D	   Feature disabled/unsupported in CPU
++ np	   "nopat" boot option specified
++ !P	   CONFIG_X86_PAT option unset
++ !M	   CONFIG_MTRR option unset
++ Enabled   PAT state set to enabled
++ Disabled  PAT state set to disabled
++ OS        PAT initializes PAT MSR with OS setting
++ BIOS      PAT keeps PAT MSR with BIOS setting
++
+diff --git a/Makefile b/Makefile
+index bee1a1692fed..5fe9a7a9cd65 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 6
+-SUBLEVEL = 6
++SUBLEVEL = 7
+ EXTRAVERSION =
+ NAME = Charred Weasel
+ 
+diff --git a/arch/arm/kernel/sys_oabi-compat.c b/arch/arm/kernel/sys_oabi-compat.c
+index 087acb569b63..5f221acd21ae 100644
+--- a/arch/arm/kernel/sys_oabi-compat.c
++++ b/arch/arm/kernel/sys_oabi-compat.c
+@@ -279,8 +279,12 @@ asmlinkage long sys_oabi_epoll_wait(int epfd,
+ 	mm_segment_t fs;
+ 	long ret, err, i;
+ 
+-	if (maxevents <= 0 || maxevents > (INT_MAX/sizeof(struct epoll_event)))
++	if (maxevents <= 0 ||
++			maxevents > (INT_MAX/sizeof(*kbuf)) ||
++			maxevents > (INT_MAX/sizeof(*events)))
+ 		return -EINVAL;
++	if (!access_ok(VERIFY_WRITE, events, sizeof(*events) * maxevents))
++		return -EFAULT;
+ 	kbuf = kmalloc(sizeof(*kbuf) * maxevents, GFP_KERNEL);
+ 	if (!kbuf)
+ 		return -ENOMEM;
+@@ -317,6 +321,8 @@ asmlinkage long sys_oabi_semtimedop(int semid,
+ 
+ 	if (nsops < 1 || nsops > SEMOPM)
+ 		return -EINVAL;
++	if (!access_ok(VERIFY_READ, tsops, sizeof(*tsops) * nsops))
++		return -EFAULT;
+ 	sops = kmalloc(sizeof(*sops) * nsops, GFP_KERNEL);
+ 	if (!sops)
+ 		return -ENOMEM;
+diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
+index 71f99d5f7a06..6021318bfbb0 100644
+--- a/arch/mips/kernel/scall64-n32.S
++++ b/arch/mips/kernel/scall64-n32.S
+@@ -344,7 +344,7 @@ EXPORT(sysn32_call_table)
+ 	PTR	sys_ni_syscall			/* available, was setaltroot */
+ 	PTR	sys_add_key
+ 	PTR	sys_request_key
+-	PTR	sys_keyctl			/* 6245 */
++	PTR	compat_sys_keyctl		/* 6245 */
+ 	PTR	sys_set_thread_area
+ 	PTR	sys_inotify_init
+ 	PTR	sys_inotify_add_watch
+diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S
+index 91b43eea2d5a..71fe3259a5e3 100644
+--- a/arch/mips/kernel/scall64-o32.S
++++ b/arch/mips/kernel/scall64-o32.S
+@@ -500,7 +500,7 @@ EXPORT(sys32_call_table)
+ 	PTR	sys_ni_syscall			/* available, was setaltroot */
+ 	PTR	sys_add_key			/* 4280 */
+ 	PTR	sys_request_key
+-	PTR	sys_keyctl
++	PTR	compat_sys_keyctl
+ 	PTR	sys_set_thread_area
+ 	PTR	sys_inotify_init
+ 	PTR	sys_inotify_add_watch		/* 4285 */
+diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
+index 7cd32c038286..4e1b060b8481 100644
+--- a/arch/powerpc/Kconfig
++++ b/arch/powerpc/Kconfig
+@@ -126,7 +126,7 @@ config PPC
+ 	select IRQ_FORCED_THREADING
+ 	select HAVE_RCU_TABLE_FREE if SMP
+ 	select HAVE_SYSCALL_TRACEPOINTS
+-	select HAVE_BPF_JIT
++	select HAVE_BPF_JIT if CPU_BIG_ENDIAN
+ 	select HAVE_ARCH_JUMP_LABEL
+ 	select ARCH_HAVE_NMI_SAFE_CMPXCHG
+ 	select ARCH_HAS_GCOV_PROFILE_ALL
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index 31e4c7e1a4b4..c42627645b54 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -648,7 +648,6 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
+ 		if (pe->type & EEH_PE_VF) {
+ 			eeh_pe_dev_traverse(pe, eeh_rmv_device, NULL);
+ 		} else {
+-			eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 			pci_lock_rescan_remove();
+ 			pcibios_remove_pci_devices(bus);
+ 			pci_unlock_rescan_remove();
+@@ -698,10 +697,12 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus,
+ 		 */
+ 		edev = list_first_entry(&pe->edevs, struct eeh_dev, list);
+ 		eeh_pe_traverse(pe, eeh_pe_detach_dev, NULL);
+-		if (pe->type & EEH_PE_VF)
++		if (pe->type & EEH_PE_VF) {
+ 			eeh_add_virt_device(edev, NULL);
+-		else
++		} else {
++			eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 			pcibios_add_pci_devices(bus);
++		}
+ 	} else if (frozen_bus && rmv_data->removed) {
+ 		pr_info("EEH: Sleep 5s ahead of partial hotplug\n");
+ 		ssleep(5);
+diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl
+index 4cddd17153fb..f848572169ea 100644
+--- a/arch/x86/entry/syscalls/syscall_32.tbl
++++ b/arch/x86/entry/syscalls/syscall_32.tbl
+@@ -294,7 +294,7 @@
+ # 285 sys_setaltroot
+ 286	i386	add_key			sys_add_key
+ 287	i386	request_key		sys_request_key
+-288	i386	keyctl			sys_keyctl
++288	i386	keyctl			sys_keyctl			compat_sys_keyctl
+ 289	i386	ioprio_set		sys_ioprio_set
+ 290	i386	ioprio_get		sys_ioprio_get
+ 291	i386	inotify_init		sys_inotify_init
+diff --git a/arch/x86/include/asm/microcode.h b/arch/x86/include/asm/microcode.h
+index 9d3a96c4da78..01c2d14ec05f 100644
+--- a/arch/x86/include/asm/microcode.h
++++ b/arch/x86/include/asm/microcode.h
+@@ -133,13 +133,11 @@ static inline unsigned int x86_cpuid_family(void)
+ #ifdef CONFIG_MICROCODE
+ extern void __init load_ucode_bsp(void);
+ extern void load_ucode_ap(void);
+-extern int __init save_microcode_in_initrd(void);
+ void reload_early_microcode(void);
+ extern bool get_builtin_firmware(struct cpio_data *cd, const char *name);
+ #else
+ static inline void __init load_ucode_bsp(void)			{ }
+ static inline void load_ucode_ap(void)				{ }
+-static inline int __init save_microcode_in_initrd(void)		{ return 0; }
+ static inline void reload_early_microcode(void)			{ }
+ static inline bool
+ get_builtin_firmware(struct cpio_data *cd, const char *name)	{ return false; }
+diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
+index b94f6f64e23d..dbff1456d215 100644
+--- a/arch/x86/include/asm/mtrr.h
++++ b/arch/x86/include/asm/mtrr.h
+@@ -24,6 +24,7 @@
+ #define _ASM_X86_MTRR_H
+ 
+ #include <uapi/asm/mtrr.h>
++#include <asm/pat.h>
+ 
+ 
+ /*
+@@ -83,9 +84,12 @@ static inline int mtrr_trim_uncached_memory(unsigned long end_pfn)
+ static inline void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
+ {
+ }
++static inline void mtrr_bp_init(void)
++{
++	pat_disable("MTRRs disabled, skipping PAT initialization too.");
++}
+ 
+ #define mtrr_ap_init() do {} while (0)
+-#define mtrr_bp_init() do {} while (0)
+ #define set_mtrr_aps_delayed_init() do {} while (0)
+ #define mtrr_aps_init() do {} while (0)
+ #define mtrr_bp_restore() do {} while (0)
+diff --git a/arch/x86/include/asm/pat.h b/arch/x86/include/asm/pat.h
+index ca6c228d5e62..0b1ff4c1c14e 100644
+--- a/arch/x86/include/asm/pat.h
++++ b/arch/x86/include/asm/pat.h
+@@ -5,8 +5,8 @@
+ #include <asm/pgtable_types.h>
+ 
+ bool pat_enabled(void);
++void pat_disable(const char *reason);
+ extern void pat_init(void);
+-void pat_init_cache_modes(u64);
+ 
+ extern int reserve_memtype(u64 start, u64 end,
+ 		enum page_cache_mode req_pcm, enum page_cache_mode *ret_pcm);
+diff --git a/arch/x86/kernel/cpu/microcode/core.c b/arch/x86/kernel/cpu/microcode/core.c
+index ac360bfbbdb6..12823b6ebd6d 100644
+--- a/arch/x86/kernel/cpu/microcode/core.c
++++ b/arch/x86/kernel/cpu/microcode/core.c
+@@ -175,7 +175,7 @@ void load_ucode_ap(void)
+ 	}
+ }
+ 
+-int __init save_microcode_in_initrd(void)
++static int __init save_microcode_in_initrd(void)
+ {
+ 	struct cpuinfo_x86 *c = &boot_cpu_data;
+ 
+@@ -691,4 +691,5 @@ int __init microcode_init(void)
+ 	return error;
+ 
+ }
++fs_initcall(save_microcode_in_initrd);
+ late_initcall(microcode_init);
+diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
+index 19f57360dfd2..8d7a29ed9377 100644
+--- a/arch/x86/kernel/cpu/mtrr/generic.c
++++ b/arch/x86/kernel/cpu/mtrr/generic.c
+@@ -444,11 +444,24 @@ static void __init print_mtrr_state(void)
+ 		pr_debug("TOM2: %016llx aka %lldM\n", mtrr_tom2, mtrr_tom2>>20);
+ }
+ 
++/* PAT setup for BP. We need to go through sync steps here */
++void __init mtrr_bp_pat_init(void)
++{
++	unsigned long flags;
++
++	local_irq_save(flags);
++	prepare_set();
++
++	pat_init();
++
++	post_set();
++	local_irq_restore(flags);
++}
++
+ /* Grab all of the MTRR state for this CPU into *state */
+ bool __init get_mtrr_state(void)
+ {
+ 	struct mtrr_var_range *vrs;
+-	unsigned long flags;
+ 	unsigned lo, dummy;
+ 	unsigned int i;
+ 
+@@ -481,15 +494,6 @@ bool __init get_mtrr_state(void)
+ 
+ 	mtrr_state_set = 1;
+ 
+-	/* PAT setup for BP. We need to go through sync steps here */
+-	local_irq_save(flags);
+-	prepare_set();
+-
+-	pat_init();
+-
+-	post_set();
+-	local_irq_restore(flags);
+-
+ 	return !!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED);
+ }
+ 
+diff --git a/arch/x86/kernel/cpu/mtrr/main.c b/arch/x86/kernel/cpu/mtrr/main.c
+index 10f8d4796240..7d393ecdeee6 100644
+--- a/arch/x86/kernel/cpu/mtrr/main.c
++++ b/arch/x86/kernel/cpu/mtrr/main.c
+@@ -752,6 +752,9 @@ void __init mtrr_bp_init(void)
+ 			/* BIOS may override */
+ 			__mtrr_enabled = get_mtrr_state();
+ 
++			if (mtrr_enabled())
++				mtrr_bp_pat_init();
++
+ 			if (mtrr_cleanup(phys_addr)) {
+ 				changed_by_mtrr_cleanup = 1;
+ 				mtrr_if->set_all();
+@@ -759,8 +762,16 @@ void __init mtrr_bp_init(void)
+ 		}
+ 	}
+ 
+-	if (!mtrr_enabled())
++	if (!mtrr_enabled()) {
+ 		pr_info("MTRR: Disabled\n");
++
++		/*
++		 * PAT initialization relies on MTRR's rendezvous handler.
++		 * Skip PAT init until the handler can initialize both
++		 * features independently.
++		 */
++		pat_disable("MTRRs disabled, skipping PAT initialization too.");
++	}
+ }
+ 
+ void mtrr_ap_init(void)
+diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.h b/arch/x86/kernel/cpu/mtrr/mtrr.h
+index 951884dcc433..6c7ced07d16d 100644
+--- a/arch/x86/kernel/cpu/mtrr/mtrr.h
++++ b/arch/x86/kernel/cpu/mtrr/mtrr.h
+@@ -52,6 +52,7 @@ void set_mtrr_prepare_save(struct set_mtrr_context *ctxt);
+ void fill_mtrr_var_range(unsigned int index,
+ 		u32 base_lo, u32 base_hi, u32 mask_lo, u32 mask_hi);
+ bool get_mtrr_state(void);
++void mtrr_bp_pat_init(void);
+ 
+ extern void set_mtrr_ops(const struct mtrr_ops *ops);
+ 
+diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
+index 9d56f271d519..6df291c2987c 100644
+--- a/arch/x86/mm/init.c
++++ b/arch/x86/mm/init.c
+@@ -696,13 +696,6 @@ void free_initmem(void)
+ void __init free_initrd_mem(unsigned long start, unsigned long end)
+ {
+ 	/*
+-	 * Remember, initrd memory may contain microcode or other useful things.
+-	 * Before we lose initrd mem, we need to find a place to hold them
+-	 * now that normal virtual memory is enabled.
+-	 */
+-	save_microcode_in_initrd();
+-
+-	/*
+ 	 * end could be not aligned, and We can not align that,
+ 	 * decompresser could be confused by aligned initrd_end
+ 	 * We already reserve the end partial page before in
+diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
+index faec01e7a17d..fb0604f11eec 100644
+--- a/arch/x86/mm/pat.c
++++ b/arch/x86/mm/pat.c
+@@ -40,11 +40,22 @@
+ static bool boot_cpu_done;
+ 
+ static int __read_mostly __pat_enabled = IS_ENABLED(CONFIG_X86_PAT);
++static void init_cache_modes(void);
+ 
+-static inline void pat_disable(const char *reason)
++void pat_disable(const char *reason)
+ {
++	if (!__pat_enabled)
++		return;
++
++	if (boot_cpu_done) {
++		WARN_ONCE(1, "x86/PAT: PAT cannot be disabled after initialization\n");
++		return;
++	}
++
+ 	__pat_enabled = 0;
+ 	pr_info("x86/PAT: %s\n", reason);
++
++	init_cache_modes();
+ }
+ 
+ static int __init nopat(char *str)
+@@ -181,7 +192,7 @@ static enum page_cache_mode pat_get_cache_mode(unsigned pat_val, char *msg)
+  * configuration.
+  * Using lower indices is preferred, so we start with highest index.
+  */
+-void pat_init_cache_modes(u64 pat)
++static void __init_cache_modes(u64 pat)
+ {
+ 	enum page_cache_mode cache;
+ 	char pat_msg[33];
+@@ -202,14 +213,11 @@ static void pat_bsp_init(u64 pat)
+ {
+ 	u64 tmp_pat;
+ 
+-	if (!cpu_has_pat) {
++	if (!boot_cpu_has(X86_FEATURE_PAT)) {
+ 		pat_disable("PAT not supported by CPU.");
+ 		return;
+ 	}
+ 
+-	if (!pat_enabled())
+-		goto done;
+-
+ 	rdmsrl(MSR_IA32_CR_PAT, tmp_pat);
+ 	if (!tmp_pat) {
+ 		pat_disable("PAT MSR is 0, disabled.");
+@@ -218,16 +226,12 @@ static void pat_bsp_init(u64 pat)
+ 
+ 	wrmsrl(MSR_IA32_CR_PAT, pat);
+ 
+-done:
+-	pat_init_cache_modes(pat);
++	__init_cache_modes(pat);
+ }
+ 
+ static void pat_ap_init(u64 pat)
+ {
+-	if (!pat_enabled())
+-		return;
+-
+-	if (!cpu_has_pat) {
++	if (!boot_cpu_has(X86_FEATURE_PAT)) {
+ 		/*
+ 		 * If this happens we are on a secondary CPU, but switched to
+ 		 * PAT on the boot CPU. We have no way to undo PAT.
+@@ -238,18 +242,32 @@ static void pat_ap_init(u64 pat)
+ 	wrmsrl(MSR_IA32_CR_PAT, pat);
+ }
+ 
+-void pat_init(void)
++static void init_cache_modes(void)
+ {
+-	u64 pat;
+-	struct cpuinfo_x86 *c = &boot_cpu_data;
++	u64 pat = 0;
++	static int init_cm_done;
+ 
+-	if (!pat_enabled()) {
++	if (init_cm_done)
++		return;
++
++	if (boot_cpu_has(X86_FEATURE_PAT)) {
++		/*
++		 * CPU supports PAT. Set PAT table to be consistent with
++		 * PAT MSR. This case supports "nopat" boot option, and
++		 * virtual machine environments which support PAT without
++		 * MTRRs. In specific, Xen has unique setup to PAT MSR.
++		 *
++		 * If PAT MSR returns 0, it is considered invalid and emulates
++		 * as No PAT.
++		 */
++		rdmsrl(MSR_IA32_CR_PAT, pat);
++	}
++
++	if (!pat) {
+ 		/*
+ 		 * No PAT. Emulate the PAT table that corresponds to the two
+-		 * cache bits, PWT (Write Through) and PCD (Cache Disable). This
+-		 * setup is the same as the BIOS default setup when the system
+-		 * has PAT but the "nopat" boot option has been specified. This
+-		 * emulated PAT table is used when MSR_IA32_CR_PAT returns 0.
++		 * cache bits, PWT (Write Through) and PCD (Cache Disable).
++		 * This setup is also the same as the BIOS default setup.
+ 		 *
+ 		 * PTE encoding:
+ 		 *
+@@ -266,10 +284,36 @@ void pat_init(void)
+ 		 */
+ 		pat = PAT(0, WB) | PAT(1, WT) | PAT(2, UC_MINUS) | PAT(3, UC) |
+ 		      PAT(4, WB) | PAT(5, WT) | PAT(6, UC_MINUS) | PAT(7, UC);
++	}
++
++	__init_cache_modes(pat);
++
++	init_cm_done = 1;
++}
++
++/**
++ * pat_init - Initialize PAT MSR and PAT table
++ *
++ * This function initializes PAT MSR and PAT table with an OS-defined value
++ * to enable additional cache attributes, WC and WT.
++ *
++ * This function must be called on all CPUs using the specific sequence of
++ * operations defined in Intel SDM. mtrr_rendezvous_handler() provides this
++ * procedure for PAT.
++ */
++void pat_init(void)
++{
++	u64 pat;
++	struct cpuinfo_x86 *c = &boot_cpu_data;
++
++	if (!pat_enabled()) {
++		init_cache_modes();
++		return;
++	}
+ 
+-	} else if ((c->x86_vendor == X86_VENDOR_INTEL) &&
+-		   (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
+-		    ((c->x86 == 0xf) && (c->x86_model <= 0x6)))) {
++	if ((c->x86_vendor == X86_VENDOR_INTEL) &&
++	    (((c->x86 == 0x6) && (c->x86_model <= 0xd)) ||
++	     ((c->x86 == 0xf) && (c->x86_model <= 0x6)))) {
+ 		/*
+ 		 * PAT support with the lower four entries. Intel Pentium 2,
+ 		 * 3, M, and 4 are affected by PAT errata, which makes the
+@@ -734,25 +778,6 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
+ 	if (file->f_flags & O_DSYNC)
+ 		pcm = _PAGE_CACHE_MODE_UC_MINUS;
+ 
+-#ifdef CONFIG_X86_32
+-	/*
+-	 * On the PPro and successors, the MTRRs are used to set
+-	 * memory types for physical addresses outside main memory,
+-	 * so blindly setting UC or PWT on those pages is wrong.
+-	 * For Pentiums and earlier, the surround logic should disable
+-	 * caching for the high addresses through the KEN pin, but
+-	 * we maintain the tradition of paranoia in this code.
+-	 */
+-	if (!pat_enabled() &&
+-	    !(boot_cpu_has(X86_FEATURE_MTRR) ||
+-	      boot_cpu_has(X86_FEATURE_K6_MTRR) ||
+-	      boot_cpu_has(X86_FEATURE_CYRIX_ARR) ||
+-	      boot_cpu_has(X86_FEATURE_CENTAUR_MCR)) &&
+-	    (pfn << PAGE_SHIFT) >= __pa(high_memory)) {
+-		pcm = _PAGE_CACHE_MODE_UC;
+-	}
+-#endif
+-
+ 	*vma_prot = __pgprot((pgprot_val(*vma_prot) & ~_PAGE_CACHE_MASK) |
+ 			     cachemode2protval(pcm));
+ 	return 1;
+diff --git a/arch/x86/power/hibernate_asm_64.S b/arch/x86/power/hibernate_asm_64.S
+index 4400a43b9e28..f2a990285a5c 100644
+--- a/arch/x86/power/hibernate_asm_64.S
++++ b/arch/x86/power/hibernate_asm_64.S
+@@ -24,7 +24,6 @@
+ #include <asm/frame.h>
+ 
+ ENTRY(swsusp_arch_suspend)
+-	FRAME_BEGIN
+ 	movq	$saved_context, %rax
+ 	movq	%rsp, pt_regs_sp(%rax)
+ 	movq	%rbp, pt_regs_bp(%rax)
+@@ -51,6 +50,7 @@ ENTRY(swsusp_arch_suspend)
+ 	movq	%cr3, %rax
+ 	movq	%rax, restore_cr3(%rip)
+ 
++	FRAME_BEGIN
+ 	call swsusp_save
+ 	FRAME_END
+ 	ret
+@@ -111,7 +111,6 @@ ENTRY(core_restore_code)
+ 	 */
+ 
+ ENTRY(restore_registers)
+-	FRAME_BEGIN
+ 	/* go back to the original page tables */
+ 	movq    %rbx, %cr3
+ 
+@@ -152,6 +151,5 @@ ENTRY(restore_registers)
+ 	/* tell the hibernation core that we've just restored the memory */
+ 	movq	%rax, in_suspend(%rip)
+ 
+-	FRAME_END
+ 	ret
+ ENDPROC(restore_registers)
+diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
+index 880862c7d9dd..d8cca75e3b3e 100644
+--- a/arch/x86/xen/enlighten.c
++++ b/arch/x86/xen/enlighten.c
+@@ -75,7 +75,6 @@
+ #include <asm/mach_traps.h>
+ #include <asm/mwait.h>
+ #include <asm/pci_x86.h>
+-#include <asm/pat.h>
+ #include <asm/cpu.h>
+ 
+ #ifdef CONFIG_ACPI
+@@ -1511,7 +1510,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
+ {
+ 	struct physdev_set_iopl set_iopl;
+ 	unsigned long initrd_start = 0;
+-	u64 pat;
+ 	int rc;
+ 
+ 	if (!xen_start_info)
+@@ -1618,13 +1616,6 @@ asmlinkage __visible void __init xen_start_kernel(void)
+ 				   xen_start_info->nr_pages);
+ 	xen_reserve_special_pages();
+ 
+-	/*
+-	 * Modify the cache mode translation tables to match Xen's PAT
+-	 * configuration.
+-	 */
+-	rdmsrl(MSR_IA32_CR_PAT, pat);
+-	pat_init_cache_modes(pat);
+-
+ 	/* keep using Xen gdt for now; no urgent need to change it */
+ 
+ #ifdef CONFIG_X86_32
+diff --git a/block/genhd.c b/block/genhd.c
+index 9f42526b4d62..3eebd256b765 100644
+--- a/block/genhd.c
++++ b/block/genhd.c
+@@ -856,6 +856,7 @@ static void disk_seqf_stop(struct seq_file *seqf, void *v)
+ 	if (iter) {
+ 		class_dev_iter_exit(iter);
+ 		kfree(iter);
++		seqf->private = NULL;
+ 	}
+ }
+ 
+diff --git a/crypto/gcm.c b/crypto/gcm.c
+index bec329b3de8d..d9ea5f9c0574 100644
+--- a/crypto/gcm.c
++++ b/crypto/gcm.c
+@@ -639,7 +639,9 @@ static int crypto_gcm_create_common(struct crypto_template *tmpl,
+ 
+ 	ghash_alg = crypto_find_alg(ghash_name, &crypto_ahash_type,
+ 				    CRYPTO_ALG_TYPE_HASH,
+-				    CRYPTO_ALG_TYPE_AHASH_MASK);
++				    CRYPTO_ALG_TYPE_AHASH_MASK |
++				    crypto_requires_sync(algt->type,
++							 algt->mask));
+ 	if (IS_ERR(ghash_alg))
+ 		return PTR_ERR(ghash_alg);
+ 
+diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
+index ea5815c5e128..bc769c448d4a 100644
+--- a/crypto/scatterwalk.c
++++ b/crypto/scatterwalk.c
+@@ -72,7 +72,8 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
+ 
+ void scatterwalk_done(struct scatter_walk *walk, int out, int more)
+ {
+-	if (!(scatterwalk_pagelen(walk) & (PAGE_SIZE - 1)) || !more)
++	if (!more || walk->offset >= walk->sg->offset + walk->sg->length ||
++	    !(walk->offset & (PAGE_SIZE - 1)))
+ 		scatterwalk_pagedone(walk, out, more);
+ }
+ EXPORT_SYMBOL_GPL(scatterwalk_done);
+diff --git a/drivers/char/random.c b/drivers/char/random.c
+index b583e5336630..e511f34be177 100644
+--- a/drivers/char/random.c
++++ b/drivers/char/random.c
+@@ -722,15 +722,18 @@ retry:
+ 	}
+ }
+ 
+-static void credit_entropy_bits_safe(struct entropy_store *r, int nbits)
++static int credit_entropy_bits_safe(struct entropy_store *r, int nbits)
+ {
+ 	const int nbits_max = (int)(~0U >> (ENTROPY_SHIFT + 1));
+ 
++	if (nbits < 0)
++		return -EINVAL;
++
+ 	/* Cap the value to avoid overflows */
+ 	nbits = min(nbits,  nbits_max);
+-	nbits = max(nbits, -nbits_max);
+ 
+ 	credit_entropy_bits(r, nbits);
++	return 0;
+ }
+ 
+ /*********************************************************************
+@@ -1542,8 +1545,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ 			return -EPERM;
+ 		if (get_user(ent_count, p))
+ 			return -EFAULT;
+-		credit_entropy_bits_safe(&input_pool, ent_count);
+-		return 0;
++		return credit_entropy_bits_safe(&input_pool, ent_count);
+ 	case RNDADDENTROPY:
+ 		if (!capable(CAP_SYS_ADMIN))
+ 			return -EPERM;
+@@ -1557,8 +1559,7 @@ static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
+ 				    size);
+ 		if (retval < 0)
+ 			return retval;
+-		credit_entropy_bits_safe(&input_pool, ent_count);
+-		return 0;
++		return credit_entropy_bits_safe(&input_pool, ent_count);
+ 	case RNDZAPENTCNT:
+ 	case RNDCLEARPOOL:
+ 		/*
+diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c
+index 808a320e9d5d..2a0d58959acf 100644
+--- a/drivers/cpufreq/pcc-cpufreq.c
++++ b/drivers/cpufreq/pcc-cpufreq.c
+@@ -555,8 +555,6 @@ static int pcc_cpufreq_cpu_init(struct cpufreq_policy *policy)
+ 	policy->min = policy->cpuinfo.min_freq =
+ 		ioread32(&pcch_hdr->minimum_frequency) * 1000;
+ 
+-	policy->cpuinfo.transition_latency = CPUFREQ_ETERNAL;
+-
+ 	pr_debug("init: policy->max is %d, policy->min is %d\n",
+ 		policy->max, policy->min);
+ out:
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
+index 585a3b7915bd..f1b0eafecd0d 100644
+--- a/drivers/i2c/busses/i2c-i801.c
++++ b/drivers/i2c/busses/i2c-i801.c
+@@ -244,6 +244,13 @@ struct i801_priv {
+ 	struct platform_device *mux_pdev;
+ #endif
+ 	struct platform_device *tco_pdev;
++
++	/*
++	 * If set to true the host controller registers are reserved for
++	 * ACPI AML use. Protected by acpi_lock.
++	 */
++	bool acpi_reserved;
++	struct mutex acpi_lock;
+ };
+ 
+ #define FEATURE_SMBUS_PEC	(1 << 0)
+@@ -714,9 +721,15 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
+ {
+ 	int hwpec;
+ 	int block = 0;
+-	int ret, xact = 0;
++	int ret = 0, xact = 0;
+ 	struct i801_priv *priv = i2c_get_adapdata(adap);
+ 
++	mutex_lock(&priv->acpi_lock);
++	if (priv->acpi_reserved) {
++		mutex_unlock(&priv->acpi_lock);
++		return -EBUSY;
++	}
++
+ 	hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
+ 		&& size != I2C_SMBUS_QUICK
+ 		&& size != I2C_SMBUS_I2C_BLOCK_DATA;
+@@ -773,7 +786,8 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
+ 	default:
+ 		dev_err(&priv->pci_dev->dev, "Unsupported transaction %d\n",
+ 			size);
+-		return -EOPNOTSUPP;
++		ret = -EOPNOTSUPP;
++		goto out;
+ 	}
+ 
+ 	if (hwpec)	/* enable/disable hardware PEC */
+@@ -796,11 +810,11 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
+ 		       ~(SMBAUXCTL_CRC | SMBAUXCTL_E32B), SMBAUXCTL(priv));
+ 
+ 	if (block)
+-		return ret;
++		goto out;
+ 	if (ret)
+-		return ret;
++		goto out;
+ 	if ((read_write == I2C_SMBUS_WRITE) || (xact == I801_QUICK))
+-		return 0;
++		goto out;
+ 
+ 	switch (xact & 0x7f) {
+ 	case I801_BYTE:	/* Result put in SMBHSTDAT0 */
+@@ -812,7 +826,10 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
+ 			     (inb_p(SMBHSTDAT1(priv)) << 8);
+ 		break;
+ 	}
+-	return 0;
++
++out:
++	mutex_unlock(&priv->acpi_lock);
++	return ret;
+ }
+ 
+ 
+@@ -1249,6 +1266,72 @@ static void i801_add_tco(struct i801_priv *priv)
+ 	priv->tco_pdev = pdev;
+ }
+ 
++#ifdef CONFIG_ACPI
++static acpi_status
++i801_acpi_io_handler(u32 function, acpi_physical_address address, u32 bits,
++		     u64 *value, void *handler_context, void *region_context)
++{
++	struct i801_priv *priv = handler_context;
++	struct pci_dev *pdev = priv->pci_dev;
++	acpi_status status;
++
++	/*
++	 * Once BIOS AML code touches the OpRegion we warn and inhibit any
++	 * further access from the driver itself. This device is now owned
++	 * by the system firmware.
++	 */
++	mutex_lock(&priv->acpi_lock);
++
++	if (!priv->acpi_reserved) {
++		priv->acpi_reserved = true;
++
++		dev_warn(&pdev->dev, "BIOS is accessing SMBus registers\n");
++		dev_warn(&pdev->dev, "Driver SMBus register access inhibited\n");
++	}
++
++	if ((function & ACPI_IO_MASK) == ACPI_READ)
++		status = acpi_os_read_port(address, (u32 *)value, bits);
++	else
++		status = acpi_os_write_port(address, (u32)*value, bits);
++
++	mutex_unlock(&priv->acpi_lock);
++
++	return status;
++}
++
++static int i801_acpi_probe(struct i801_priv *priv)
++{
++	struct acpi_device *adev;
++	acpi_status status;
++
++	adev = ACPI_COMPANION(&priv->pci_dev->dev);
++	if (adev) {
++		status = acpi_install_address_space_handler(adev->handle,
++				ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler,
++				NULL, priv);
++		if (ACPI_SUCCESS(status))
++			return 0;
++	}
++
++	return acpi_check_resource_conflict(&priv->pci_dev->resource[SMBBAR]);
++}
++
++static void i801_acpi_remove(struct i801_priv *priv)
++{
++	struct acpi_device *adev;
++
++	adev = ACPI_COMPANION(&priv->pci_dev->dev);
++	if (!adev)
++		return;
++
++	acpi_remove_address_space_handler(adev->handle,
++		ACPI_ADR_SPACE_SYSTEM_IO, i801_acpi_io_handler);
++}
++#else
++static inline int i801_acpi_probe(struct i801_priv *priv) { return 0; }
++static inline void i801_acpi_remove(struct i801_priv *priv) { }
++#endif
++
+ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ {
+ 	unsigned char temp;
+@@ -1266,6 +1349,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ 	priv->adapter.dev.parent = &dev->dev;
+ 	ACPI_COMPANION_SET(&priv->adapter.dev, ACPI_COMPANION(&dev->dev));
+ 	priv->adapter.retries = 3;
++	mutex_init(&priv->acpi_lock);
+ 
+ 	priv->pci_dev = dev;
+ 	switch (dev->device) {
+@@ -1328,10 +1412,8 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ 		return -ENODEV;
+ 	}
+ 
+-	err = acpi_check_resource_conflict(&dev->resource[SMBBAR]);
+-	if (err) {
++	if (i801_acpi_probe(priv))
+ 		return -ENODEV;
+-	}
+ 
+ 	err = pcim_iomap_regions(dev, 1 << SMBBAR,
+ 				 dev_driver_string(&dev->dev));
+@@ -1340,6 +1422,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ 			"Failed to request SMBus region 0x%lx-0x%Lx\n",
+ 			priv->smba,
+ 			(unsigned long long)pci_resource_end(dev, SMBBAR));
++		i801_acpi_remove(priv);
+ 		return err;
+ 	}
+ 
+@@ -1404,6 +1487,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
+ 	err = i2c_add_adapter(&priv->adapter);
+ 	if (err) {
+ 		dev_err(&dev->dev, "Failed to add SMBus adapter\n");
++		i801_acpi_remove(priv);
+ 		return err;
+ 	}
+ 
+@@ -1422,6 +1506,7 @@ static void i801_remove(struct pci_dev *dev)
+ 
+ 	i801_del_mux(priv);
+ 	i2c_del_adapter(&priv->adapter);
++	i801_acpi_remove(priv);
+ 	pci_write_config_byte(dev, SMBHSTCFG, priv->original_hstcfg);
+ 
+ 	platform_device_unregister(priv->tco_pdev);
+diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c
+index db760e84119f..b8df0f5e8c25 100644
+--- a/drivers/net/bonding/bond_netlink.c
++++ b/drivers/net/bonding/bond_netlink.c
+@@ -446,7 +446,11 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
+ 	if (err < 0)
+ 		return err;
+ 
+-	return register_netdevice(bond_dev);
++	err = register_netdevice(bond_dev);
++
++	netif_carrier_off(bond_dev);
++
++	return err;
+ }
+ 
+ static size_t bond_get_size(const struct net_device *bond_dev)
+diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c
+index 38db2e4d7d54..832401b41b98 100644
+--- a/drivers/net/ethernet/broadcom/bgmac.c
++++ b/drivers/net/ethernet/broadcom/bgmac.c
+@@ -231,7 +231,7 @@ err_dma:
+ 	dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb),
+ 			 DMA_TO_DEVICE);
+ 
+-	while (i > 0) {
++	while (i-- > 0) {
+ 		int index = (ring->end + i) % BGMAC_TX_RING_SLOTS;
+ 		struct bgmac_slot_info *slot = &ring->slots[index];
+ 		u32 ctl1 = le32_to_cpu(ring->cpu_base[index].ctl1);
+diff --git a/drivers/net/ethernet/qlogic/qed/qed_spq.c b/drivers/net/ethernet/qlogic/qed/qed_spq.c
+index 89469d5aae25..40e6f6c11f20 100644
+--- a/drivers/net/ethernet/qlogic/qed/qed_spq.c
++++ b/drivers/net/ethernet/qlogic/qed/qed_spq.c
+@@ -791,13 +791,12 @@ int qed_spq_completion(struct qed_hwfn *p_hwfn,
+ 			 * in a bitmap and increasing the chain consumer only
+ 			 * for the first successive completed entries.
+ 			 */
+-			bitmap_set(p_spq->p_comp_bitmap, pos, SPQ_RING_SIZE);
++			__set_bit(pos, p_spq->p_comp_bitmap);
+ 
+ 			while (test_bit(p_spq->comp_bitmap_idx,
+ 					p_spq->p_comp_bitmap)) {
+-				bitmap_clear(p_spq->p_comp_bitmap,
+-					     p_spq->comp_bitmap_idx,
+-					     SPQ_RING_SIZE);
++				__clear_bit(p_spq->comp_bitmap_idx,
++					    p_spq->p_comp_bitmap);
+ 				p_spq->comp_bitmap_idx++;
+ 				qed_chain_return_produced(&p_spq->chain);
+ 			}
+diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
+index 8f3c55d03d5d..f58858b7972c 100644
+--- a/drivers/net/macsec.c
++++ b/drivers/net/macsec.c
+@@ -914,7 +914,6 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb,
+ 	}
+ 
+ 	macsec_skb_cb(skb)->req = req;
+-	macsec_skb_cb(skb)->rx_sa = rx_sa;
+ 	skb->dev = dev;
+ 	aead_request_set_callback(req, 0, macsec_decrypt_done, skb);
+ 
+@@ -1141,6 +1140,8 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)
+ 		}
+ 	}
+ 
++	macsec_skb_cb(skb)->rx_sa = rx_sa;
++
+ 	/* Disabled && !changed text => skip validation */
+ 	if (hdr->tci_an & MACSEC_TCI_C ||
+ 	    secy->validate_frames != MACSEC_VALIDATE_DISABLED)
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
+index f572b31a2b20..9ab88e1ed394 100644
+--- a/drivers/net/ppp/ppp_generic.c
++++ b/drivers/net/ppp/ppp_generic.c
+@@ -2404,8 +2404,6 @@ ppp_unregister_channel(struct ppp_channel *chan)
+ 	spin_lock_bh(&pn->all_channels_lock);
+ 	list_del(&pch->list);
+ 	spin_unlock_bh(&pn->all_channels_lock);
+-	put_net(pch->chan_net);
+-	pch->chan_net = NULL;
+ 
+ 	pch->file.dead = 1;
+ 	wake_up_interruptible(&pch->file.rwait);
+@@ -2999,6 +2997,9 @@ ppp_disconnect_channel(struct channel *pch)
+  */
+ static void ppp_destroy_channel(struct channel *pch)
+ {
++	put_net(pch->chan_net);
++	pch->chan_net = NULL;
++
+ 	atomic_dec(&channel_count);
+ 
+ 	if (!pch->file.dead) {
+diff --git a/drivers/nvdimm/pfn.h b/drivers/nvdimm/pfn.h
+index 8e343a3ca873..9d2704c83fa7 100644
+--- a/drivers/nvdimm/pfn.h
++++ b/drivers/nvdimm/pfn.h
+@@ -33,7 +33,9 @@ struct nd_pfn_sb {
+ 	/* minor-version-1 additions for section alignment */
+ 	__le32 start_pad;
+ 	__le32 end_trunc;
+-	u8 padding[4004];
++	/* minor-version-2 record the base alignment of the mapping */
++	__le32 align;
++	u8 padding[4000];
+ 	__le64 checksum;
+ };
+ 
+diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c
+index e071e214feba..84f2372dd0bb 100644
+--- a/drivers/nvdimm/pfn_devs.c
++++ b/drivers/nvdimm/pfn_devs.c
+@@ -329,6 +329,8 @@ struct device *nd_pfn_create(struct nd_region *nd_region)
+ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ {
+ 	u64 checksum, offset;
++	unsigned long align;
++	enum nd_pfn_mode mode;
+ 	struct nd_namespace_io *nsio;
+ 	struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
+ 	struct nd_namespace_common *ndns = nd_pfn->ndns;
+@@ -360,6 +362,9 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ 		pfn_sb->end_trunc = 0;
+ 	}
+ 
++	if (__le16_to_cpu(pfn_sb->version_minor) < 2)
++		pfn_sb->align = 0;
++
+ 	switch (le32_to_cpu(pfn_sb->mode)) {
+ 	case PFN_MODE_RAM:
+ 	case PFN_MODE_PMEM:
+@@ -368,20 +373,50 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ 		return -ENXIO;
+ 	}
+ 
++	align = le32_to_cpu(pfn_sb->align);
++	offset = le64_to_cpu(pfn_sb->dataoff);
++	if (align == 0)
++		align = 1UL << ilog2(offset);
++	mode = le32_to_cpu(pfn_sb->mode);
++
+ 	if (!nd_pfn->uuid) {
+-		/* from probe we allocate */
++		/*
++		 * When probing a namepace via nd_pfn_probe() the uuid
++		 * is NULL (see: nd_pfn_devinit()) we init settings from
++		 * pfn_sb
++		 */
+ 		nd_pfn->uuid = kmemdup(pfn_sb->uuid, 16, GFP_KERNEL);
+ 		if (!nd_pfn->uuid)
+ 			return -ENOMEM;
++		nd_pfn->align = align;
++		nd_pfn->mode = mode;
+ 	} else {
+-		/* from init we validate */
++		/*
++		 * When probing a pfn / dax instance we validate the
++		 * live settings against the pfn_sb
++		 */
+ 		if (memcmp(nd_pfn->uuid, pfn_sb->uuid, 16) != 0)
+ 			return -ENODEV;
++
++		/*
++		 * If the uuid validates, but other settings mismatch
++		 * return EINVAL because userspace has managed to change
++		 * the configuration without specifying new
++		 * identification.
++		 */
++		if (nd_pfn->align != align || nd_pfn->mode != mode) {
++			dev_err(&nd_pfn->dev,
++					"init failed, settings mismatch\n");
++			dev_dbg(&nd_pfn->dev, "align: %lx:%lx mode: %d:%d\n",
++					nd_pfn->align, align, nd_pfn->mode,
++					mode);
++			return -EINVAL;
++		}
+ 	}
+ 
+-	if (nd_pfn->align > nvdimm_namespace_capacity(ndns)) {
++	if (align > nvdimm_namespace_capacity(ndns)) {
+ 		dev_err(&nd_pfn->dev, "alignment: %lx exceeds capacity %llx\n",
+-				nd_pfn->align, nvdimm_namespace_capacity(ndns));
++				align, nvdimm_namespace_capacity(ndns));
+ 		return -EINVAL;
+ 	}
+ 
+@@ -391,7 +426,6 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ 	 * namespace has changed since the pfn superblock was
+ 	 * established.
+ 	 */
+-	offset = le64_to_cpu(pfn_sb->dataoff);
+ 	nsio = to_nd_namespace_io(&ndns->dev);
+ 	if (offset >= resource_size(&nsio->res)) {
+ 		dev_err(&nd_pfn->dev, "pfn array size exceeds capacity of %s\n",
+@@ -399,10 +433,11 @@ int nd_pfn_validate(struct nd_pfn *nd_pfn)
+ 		return -EBUSY;
+ 	}
+ 
+-	nd_pfn->align = 1UL << ilog2(offset);
+-	if (!is_power_of_2(offset) || offset < PAGE_SIZE) {
+-		dev_err(&nd_pfn->dev, "bad offset: %#llx dax disabled\n",
+-				offset);
++	if ((align && !IS_ALIGNED(offset, align))
++			|| !IS_ALIGNED(offset, PAGE_SIZE)) {
++		dev_err(&nd_pfn->dev,
++				"bad offset: %#llx dax disabled align: %#lx\n",
++				offset, align);
+ 		return -ENXIO;
+ 	}
+ 
+diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c
+index 92f536596b24..368efac7a950 100644
+--- a/drivers/nvdimm/pmem.c
++++ b/drivers/nvdimm/pmem.c
+@@ -426,9 +426,10 @@ static int nd_pfn_init(struct nd_pfn *nd_pfn)
+ 	memcpy(pfn_sb->uuid, nd_pfn->uuid, 16);
+ 	memcpy(pfn_sb->parent_uuid, nd_dev_to_uuid(&ndns->dev), 16);
+ 	pfn_sb->version_major = cpu_to_le16(1);
+-	pfn_sb->version_minor = cpu_to_le16(1);
++	pfn_sb->version_minor = cpu_to_le16(2);
+ 	pfn_sb->start_pad = cpu_to_le32(start_pad);
+ 	pfn_sb->end_trunc = cpu_to_le32(end_trunc);
++	pfn_sb->align = cpu_to_le32(nd_pfn->align);
+ 	checksum = nd_sb_checksum((struct nd_gen_sb *) pfn_sb);
+ 	pfn_sb->checksum = cpu_to_le64(checksum);
+ 
+@@ -501,7 +502,6 @@ static int __nvdimm_namespace_attach_pfn(struct nd_pfn *nd_pfn)
+ 	pmem = dev_get_drvdata(dev);
+ 	pmem->data_offset = le64_to_cpu(pfn_sb->dataoff);
+ 	pmem->pfn_pad = start_pad + end_trunc;
+-	nd_pfn->mode = le32_to_cpu(nd_pfn->pfn_sb->mode);
+ 	if (nd_pfn->mode == PFN_MODE_RAM) {
+ 		if (pmem->data_offset < SZ_8K)
+ 			return -EINVAL;
+diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c
+index 6c7fe4778793..7e156a0b65dd 100644
+--- a/drivers/regulator/qcom_smd-regulator.c
++++ b/drivers/regulator/qcom_smd-regulator.c
+@@ -140,7 +140,6 @@ static const struct regulator_ops rpm_smps_ldo_ops = {
+ 	.enable = rpm_reg_enable,
+ 	.disable = rpm_reg_disable,
+ 	.is_enabled = rpm_reg_is_enabled,
+-	.list_voltage = regulator_list_voltage_linear_range,
+ 
+ 	.get_voltage = rpm_reg_get_voltage,
+ 	.set_voltage = rpm_reg_set_voltage,
+diff --git a/drivers/staging/rdma/hfi1/ud.c b/drivers/staging/rdma/hfi1/ud.c
+index ae8a70f703eb..23e60feb81bb 100644
+--- a/drivers/staging/rdma/hfi1/ud.c
++++ b/drivers/staging/rdma/hfi1/ud.c
+@@ -678,8 +678,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 	u32 tlen = packet->tlen;
+ 	struct rvt_qp *qp = packet->qp;
+ 	bool has_grh = rcv_flags & HFI1_HAS_GRH;
+-	bool sc4_bit = has_sc4_bit(packet);
+-	u8 sc;
++	u8 sc5 = hdr2sc((struct hfi1_message_header *)hdr, packet->rhf);
+ 	u32 bth1;
+ 	int is_mcast;
+ 	struct ib_grh *grh = NULL;
+@@ -697,10 +696,8 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 		 */
+ 		struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ 		u32 lqpn =  be32_to_cpu(ohdr->bth[1]) & RVT_QPN_MASK;
+-		u8 sl, sc5;
++		u8 sl;
+ 
+-		sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
+-		sc5 |= sc4_bit;
+ 		sl = ibp->sc_to_sl[sc5];
+ 
+ 		process_becn(ppd, sl, 0, lqpn, 0, IB_CC_SVCTYPE_UD);
+@@ -717,10 +714,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 
+ 	if (!is_mcast && (opcode != IB_OPCODE_CNP) && bth1 & HFI1_FECN_SMASK) {
+ 		u16 slid = be16_to_cpu(hdr->lrh[3]);
+-		u8 sc5;
+-
+-		sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
+-		sc5 |= sc4_bit;
+ 
+ 		return_cnp(ibp, qp, src_qp, pkey, dlid, slid, sc5, grh);
+ 	}
+@@ -745,10 +738,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 		if (qp->ibqp.qp_num > 1) {
+ 			struct hfi1_pportdata *ppd = ppd_from_ibp(ibp);
+ 			u16 slid;
+-			u8 sc5;
+-
+-			sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
+-			sc5 |= sc4_bit;
+ 
+ 			slid = be16_to_cpu(hdr->lrh[3]);
+ 			if (unlikely(rcv_pkey_check(ppd, pkey, sc5, slid))) {
+@@ -790,10 +779,6 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 		/* Received on QP0, and so by definition, this is an SMP */
+ 		struct opa_smp *smp = (struct opa_smp *)data;
+ 		u16 slid = be16_to_cpu(hdr->lrh[3]);
+-		u8 sc5;
+-
+-		sc5 = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
+-		sc5 |= sc4_bit;
+ 
+ 		if (opa_smp_check(ibp, pkey, sc5, qp, slid, smp))
+ 			goto drop;
+@@ -890,9 +875,7 @@ void hfi1_ud_rcv(struct hfi1_packet *packet)
+ 	}
+ 
+ 	wc.slid = be16_to_cpu(hdr->lrh[3]);
+-	sc = (be16_to_cpu(hdr->lrh[0]) >> 12) & 0xf;
+-	sc |= sc4_bit;
+-	wc.sl = ibp->sc_to_sl[sc];
++	wc.sl = ibp->sc_to_sl[sc5];
+ 
+ 	/*
+ 	 * Save the LMC lower bits if the destination LID is a unicast LID.
+diff --git a/drivers/staging/rdma/hfi1/verbs_txreq.c b/drivers/staging/rdma/hfi1/verbs_txreq.c
+index bc95c4112c61..d8fb056526f8 100644
+--- a/drivers/staging/rdma/hfi1/verbs_txreq.c
++++ b/drivers/staging/rdma/hfi1/verbs_txreq.c
+@@ -92,11 +92,10 @@ void hfi1_put_txreq(struct verbs_txreq *tx)
+ 
+ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
+ 				struct rvt_qp *qp)
++	__must_hold(&qp->s_lock)
+ {
+ 	struct verbs_txreq *tx = ERR_PTR(-EBUSY);
+-	unsigned long flags;
+ 
+-	spin_lock_irqsave(&qp->s_lock, flags);
+ 	write_seqlock(&dev->iowait_lock);
+ 	if (ib_rvt_state_ops[qp->state] & RVT_PROCESS_RECV_OK) {
+ 		struct hfi1_qp_priv *priv;
+@@ -116,7 +115,6 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
+ 	}
+ out:
+ 	write_sequnlock(&dev->iowait_lock);
+-	spin_unlock_irqrestore(&qp->s_lock, flags);
+ 	return tx;
+ }
+ 
+diff --git a/drivers/staging/rdma/hfi1/verbs_txreq.h b/drivers/staging/rdma/hfi1/verbs_txreq.h
+index 1cf69b2fe4a5..a1d6e0807f97 100644
+--- a/drivers/staging/rdma/hfi1/verbs_txreq.h
++++ b/drivers/staging/rdma/hfi1/verbs_txreq.h
+@@ -73,6 +73,7 @@ struct verbs_txreq *__get_txreq(struct hfi1_ibdev *dev,
+ 
+ static inline struct verbs_txreq *get_txreq(struct hfi1_ibdev *dev,
+ 					    struct rvt_qp *qp)
++	__must_hold(&qp->slock)
+ {
+ 	struct verbs_txreq *tx;
+ 	struct hfi1_qp_priv *priv = qp->priv;
+diff --git a/drivers/tty/serial/mvebu-uart.c b/drivers/tty/serial/mvebu-uart.c
+index 0ff27818bb87..25b9f178c8d3 100644
+--- a/drivers/tty/serial/mvebu-uart.c
++++ b/drivers/tty/serial/mvebu-uart.c
+@@ -299,6 +299,8 @@ static int mvebu_uart_startup(struct uart_port *port)
+ static void mvebu_uart_shutdown(struct uart_port *port)
+ {
+ 	writel(0, port->membase + UART_CTRL);
++
++	free_irq(port->irq, port);
+ }
+ 
+ static void mvebu_uart_set_termios(struct uart_port *port,
+diff --git a/fs/dcache.c b/fs/dcache.c
+index 44008e3fafc4..5612631b7b46 100644
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -578,7 +578,6 @@ static struct dentry *dentry_kill(struct dentry *dentry)
+ 
+ failed:
+ 	spin_unlock(&dentry->d_lock);
+-	cpu_relax();
+ 	return dentry; /* try again with same dentry */
+ }
+ 
+@@ -752,6 +751,8 @@ void dput(struct dentry *dentry)
+ 		return;
+ 
+ repeat:
++	might_sleep();
++
+ 	rcu_read_lock();
+ 	if (likely(fast_dput(dentry))) {
+ 		rcu_read_unlock();
+@@ -783,8 +784,10 @@ repeat:
+ 
+ kill_it:
+ 	dentry = dentry_kill(dentry);
+-	if (dentry)
++	if (dentry) {
++		cond_resched();
+ 		goto repeat;
++	}
+ }
+ EXPORT_SYMBOL(dput);
+ 
+diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
+index fe1f50fe764f..f97110461c19 100644
+--- a/fs/ext4/balloc.c
++++ b/fs/ext4/balloc.c
+@@ -208,6 +208,9 @@ static int ext4_init_block_bitmap(struct super_block *sb,
+ 	memset(bh->b_data, 0, sb->s_blocksize);
+ 
+ 	bit_max = ext4_num_base_meta_clusters(sb, block_group);
++	if ((bit_max >> 3) >= bh->b_size)
++		return -EFSCORRUPTED;
++
+ 	for (bit = 0; bit < bit_max; bit++)
+ 		ext4_set_bit(bit, bh->b_data);
+ 
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
+index de692b91c166..8211698600c2 100644
+--- a/fs/ext4/extents.c
++++ b/fs/ext4/extents.c
+@@ -376,9 +376,13 @@ static int ext4_valid_extent(struct inode *inode, struct ext4_extent *ext)
+ 	ext4_fsblk_t block = ext4_ext_pblock(ext);
+ 	int len = ext4_ext_get_actual_len(ext);
+ 	ext4_lblk_t lblock = le32_to_cpu(ext->ee_block);
+-	ext4_lblk_t last = lblock + len - 1;
+ 
+-	if (len == 0 || lblock > last)
++	/*
++	 * We allow neither:
++	 *  - zero length
++	 *  - overflow/wrap-around
++	 */
++	if (lblock + len <= lblock)
+ 		return 0;
+ 	return ext4_data_block_valid(EXT4_SB(inode->i_sb), block, len);
+ }
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 250c2df04a92..58197a7c3c2c 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -205,9 +205,9 @@ void ext4_evict_inode(struct inode *inode)
+ 		 * Note that directories do not have this problem because they
+ 		 * don't use page cache.
+ 		 */
+-		if (ext4_should_journal_data(inode) &&
+-		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode)) &&
+-		    inode->i_ino != EXT4_JOURNAL_INO) {
++		if (inode->i_ino != EXT4_JOURNAL_INO &&
++		    ext4_should_journal_data(inode) &&
++		    (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) {
+ 			journal_t *journal = EXT4_SB(inode->i_sb)->s_journal;
+ 			tid_t commit_tid = EXT4_I(inode)->i_datasync_tid;
+ 
+@@ -2741,13 +2741,36 @@ retry:
+ 				done = true;
+ 			}
+ 		}
+-		ext4_journal_stop(handle);
++		/*
++		 * Caution: If the handle is synchronous,
++		 * ext4_journal_stop() can wait for transaction commit
++		 * to finish which may depend on writeback of pages to
++		 * complete or on page lock to be released.  In that
++		 * case, we have to wait until after after we have
++		 * submitted all the IO, released page locks we hold,
++		 * and dropped io_end reference (for extent conversion
++		 * to be able to complete) before stopping the handle.
++		 */
++		if (!ext4_handle_valid(handle) || handle->h_sync == 0) {
++			ext4_journal_stop(handle);
++			handle = NULL;
++		}
+ 		/* Submit prepared bio */
+ 		ext4_io_submit(&mpd.io_submit);
+ 		/* Unlock pages we didn't use */
+ 		mpage_release_unused_pages(&mpd, give_up_on_write);
+-		/* Drop our io_end reference we got from init */
+-		ext4_put_io_end(mpd.io_submit.io_end);
++		/*
++		 * Drop our io_end reference we got from init. We have
++		 * to be careful and use deferred io_end finishing if
++		 * we are still holding the transaction as we can
++		 * release the last reference to io_end which may end
++		 * up doing unwritten extent conversion.
++		 */
++		if (handle) {
++			ext4_put_io_end_defer(mpd.io_submit.io_end);
++			ext4_journal_stop(handle);
++		} else
++			ext4_put_io_end(mpd.io_submit.io_end);
+ 
+ 		if (ret == -ENOSPC && sbi->s_journal) {
+ 			/*
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
+index 9d26fa2188f6..5f7ae0898ef7 100644
+--- a/fs/ext4/mballoc.c
++++ b/fs/ext4/mballoc.c
+@@ -2939,7 +2939,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
+ 		ext4_error(sb, "Allocating blocks %llu-%llu which overlap "
+ 			   "fs metadata", block, block+len);
+ 		/* File system mounted not to panic on error
+-		 * Fix the bitmap and repeat the block allocation
++		 * Fix the bitmap and return EFSCORRUPTED
+ 		 * We leak some of the blocks here.
+ 		 */
+ 		ext4_lock_group(sb, ac->ac_b_ex.fe_group);
+@@ -2948,7 +2948,7 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
+ 		ext4_unlock_group(sb, ac->ac_b_ex.fe_group);
+ 		err = ext4_handle_dirty_metadata(handle, NULL, bitmap_bh);
+ 		if (!err)
+-			err = -EAGAIN;
++			err = -EFSCORRUPTED;
+ 		goto out_err;
+ 	}
+ 
+@@ -4513,18 +4513,7 @@ repeat:
+ 	}
+ 	if (likely(ac->ac_status == AC_STATUS_FOUND)) {
+ 		*errp = ext4_mb_mark_diskspace_used(ac, handle, reserv_clstrs);
+-		if (*errp == -EAGAIN) {
+-			/*
+-			 * drop the reference that we took
+-			 * in ext4_mb_use_best_found
+-			 */
+-			ext4_mb_release_context(ac);
+-			ac->ac_b_ex.fe_group = 0;
+-			ac->ac_b_ex.fe_start = 0;
+-			ac->ac_b_ex.fe_len = 0;
+-			ac->ac_status = AC_STATUS_CONTINUE;
+-			goto repeat;
+-		} else if (*errp) {
++		if (*errp) {
+ 			ext4_discard_allocated_blocks(ac);
+ 			goto errout;
+ 		} else {
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c
+index 304c712dbe12..7fca76b6cd61 100644
+--- a/fs/ext4/super.c
++++ b/fs/ext4/super.c
+@@ -2277,6 +2277,16 @@ static void ext4_orphan_cleanup(struct super_block *sb,
+ 	while (es->s_last_orphan) {
+ 		struct inode *inode;
+ 
++		/*
++		 * We may have encountered an error during cleanup; if
++		 * so, skip the rest.
++		 */
++		if (EXT4_SB(sb)->s_mount_state & EXT4_ERROR_FS) {
++			jbd_debug(1, "Skipping orphan recovery on fs with errors.\n");
++			es->s_last_orphan = 0;
++			break;
++		}
++
+ 		inode = ext4_orphan_get(sb, le32_to_cpu(es->s_last_orphan));
+ 		if (IS_ERR(inode)) {
+ 			es->s_last_orphan = 0;
+@@ -3415,6 +3425,13 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
+ 		goto failed_mount;
+ 	}
+ 
++	if (le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks) > (blocksize / 4)) {
++		ext4_msg(sb, KERN_ERR,
++			 "Number of reserved GDT blocks insanely large: %d",
++			 le16_to_cpu(sbi->s_es->s_reserved_gdt_blocks));
++		goto failed_mount;
++	}
++
+ 	if (sbi->s_mount_opt & EXT4_MOUNT_DAX) {
+ 		if (blocksize != PAGE_SIZE) {
+ 			ext4_msg(sb, KERN_ERR,
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c
+index dcad5e210525..3c7675fa664f 100644
+--- a/fs/fuse/file.c
++++ b/fs/fuse/file.c
+@@ -417,6 +417,15 @@ static int fuse_flush(struct file *file, fl_owner_t id)
+ 	fuse_sync_writes(inode);
+ 	inode_unlock(inode);
+ 
++	if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
++	    test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
++		err = -ENOSPC;
++	if (test_bit(AS_EIO, &file->f_mapping->flags) &&
++	    test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
++		err = -EIO;
++	if (err)
++		return err;
++
+ 	req = fuse_get_req_nofail_nopages(fc, file);
+ 	memset(&inarg, 0, sizeof(inarg));
+ 	inarg.fh = ff->fh;
+@@ -462,6 +471,21 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
+ 		goto out;
+ 
+ 	fuse_sync_writes(inode);
++
++	/*
++	 * Due to implementation of fuse writeback
++	 * filemap_write_and_wait_range() does not catch errors.
++	 * We have to do this directly after fuse_sync_writes()
++	 */
++	if (test_bit(AS_ENOSPC, &file->f_mapping->flags) &&
++	    test_and_clear_bit(AS_ENOSPC, &file->f_mapping->flags))
++		err = -ENOSPC;
++	if (test_bit(AS_EIO, &file->f_mapping->flags) &&
++	    test_and_clear_bit(AS_EIO, &file->f_mapping->flags))
++		err = -EIO;
++	if (err)
++		goto out;
++
+ 	err = sync_inode_metadata(inode, 1);
+ 	if (err)
+ 		goto out;
+diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
+index 1ce67668a8e1..d302a5fff9ba 100644
+--- a/fs/fuse/inode.c
++++ b/fs/fuse/inode.c
+@@ -926,7 +926,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
+ 	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
+ 		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
+ 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
+-		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
++		FUSE_FLOCK_LOCKS | FUSE_HAS_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
+ 		FUSE_DO_READDIRPLUS | FUSE_READDIRPLUS_AUTO | FUSE_ASYNC_DIO |
+ 		FUSE_WRITEBACK_CACHE | FUSE_NO_OPEN_SUPPORT;
+ 	req->in.h.opcode = FUSE_INIT;
+diff --git a/fs/inode.c b/fs/inode.c
+index 721fa18ead59..fd832eba4596 100644
+--- a/fs/inode.c
++++ b/fs/inode.c
+@@ -344,7 +344,7 @@ EXPORT_SYMBOL(inc_nlink);
+ void address_space_init_once(struct address_space *mapping)
+ {
+ 	memset(mapping, 0, sizeof(*mapping));
+-	INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC);
++	INIT_RADIX_TREE(&mapping->page_tree, GFP_ATOMIC | __GFP_ACCOUNT);
+ 	spin_lock_init(&mapping->tree_lock);
+ 	init_rwsem(&mapping->i_mmap_rwsem);
+ 	INIT_LIST_HEAD(&mapping->private_list);
+diff --git a/fs/udf/super.c b/fs/udf/super.c
+index 36661acaf33b..5e2c8c814e1b 100644
+--- a/fs/udf/super.c
++++ b/fs/udf/super.c
+@@ -78,6 +78,15 @@
+ #define VSD_FIRST_SECTOR_OFFSET		32768
+ #define VSD_MAX_SECTOR_OFFSET		0x800000
+ 
++/*
++ * Maximum number of Terminating Descriptor / Logical Volume Integrity
++ * Descriptor redirections. The chosen numbers are arbitrary - just that we
++ * hopefully don't limit any real use of rewritten inode on write-once media
++ * but avoid looping for too long on corrupted media.
++ */
++#define UDF_MAX_TD_NESTING 64
++#define UDF_MAX_LVID_NESTING 1000
++
+ enum { UDF_MAX_LINKS = 0xffff };
+ 
+ /* These are the "meat" - everything else is stuffing */
+@@ -1541,42 +1550,52 @@ out_bh:
+ }
+ 
+ /*
+- * udf_load_logicalvolint
+- *
++ * Find the prevailing Logical Volume Integrity Descriptor.
+  */
+ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_ad loc)
+ {
+-	struct buffer_head *bh = NULL;
++	struct buffer_head *bh, *final_bh;
+ 	uint16_t ident;
+ 	struct udf_sb_info *sbi = UDF_SB(sb);
+ 	struct logicalVolIntegrityDesc *lvid;
++	int indirections = 0;
++
++	while (++indirections <= UDF_MAX_LVID_NESTING) {
++		final_bh = NULL;
++		while (loc.extLength > 0 &&
++			(bh = udf_read_tagged(sb, loc.extLocation,
++					loc.extLocation, &ident))) {
++			if (ident != TAG_IDENT_LVID) {
++				brelse(bh);
++				break;
++			}
++
++			brelse(final_bh);
++			final_bh = bh;
+ 
+-	while (loc.extLength > 0 &&
+-	       (bh = udf_read_tagged(sb, loc.extLocation,
+-				     loc.extLocation, &ident)) &&
+-	       ident == TAG_IDENT_LVID) {
+-		sbi->s_lvid_bh = bh;
+-		lvid = (struct logicalVolIntegrityDesc *)bh->b_data;
++			loc.extLength -= sb->s_blocksize;
++			loc.extLocation++;
++		}
+ 
+-		if (lvid->nextIntegrityExt.extLength)
+-			udf_load_logicalvolint(sb,
+-				leea_to_cpu(lvid->nextIntegrityExt));
++		if (!final_bh)
++			return;
+ 
+-		if (sbi->s_lvid_bh != bh)
+-			brelse(bh);
+-		loc.extLength -= sb->s_blocksize;
+-		loc.extLocation++;
++		brelse(sbi->s_lvid_bh);
++		sbi->s_lvid_bh = final_bh;
++
++		lvid = (struct logicalVolIntegrityDesc *)final_bh->b_data;
++		if (lvid->nextIntegrityExt.extLength == 0)
++			return;
++
++		loc = leea_to_cpu(lvid->nextIntegrityExt);
+ 	}
+-	if (sbi->s_lvid_bh != bh)
+-		brelse(bh);
++
++	udf_warn(sb, "Too many LVID indirections (max %u), ignoring.\n",
++		UDF_MAX_LVID_NESTING);
++	brelse(sbi->s_lvid_bh);
++	sbi->s_lvid_bh = NULL;
+ }
+ 
+-/*
+- * Maximum number of Terminating Descriptor redirections. The chosen number is
+- * arbitrary - just that we hopefully don't limit any real use of rewritten
+- * inode on write-once media but avoid looping for too long on corrupted media.
+- */
+-#define UDF_MAX_TD_NESTING 64
+ 
+ /*
+  * Process a main/reserve volume descriptor sequence.
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 78181a88903b..54355a7e46de 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -4156,6 +4156,13 @@ static inline void netif_keep_dst(struct net_device *dev)
+ 	dev->priv_flags &= ~(IFF_XMIT_DST_RELEASE | IFF_XMIT_DST_RELEASE_PERM);
+ }
+ 
++/* return true if dev can't cope with mtu frames that need vlan tag insertion */
++static inline bool netif_reduces_vlan_mtu(struct net_device *dev)
++{
++	/* TODO: reserve and use an additional IFF bit, if we get more users */
++	return dev->priv_flags & IFF_MACSEC;
++}
++
+ extern struct pernet_operations __net_initdata loopback_net_ops;
+ 
+ /* Logging, debugging and troubleshooting/diagnostic helpers. */
+diff --git a/ipc/msg.c b/ipc/msg.c
+index 1471db9a7e61..c6521c205cb4 100644
+--- a/ipc/msg.c
++++ b/ipc/msg.c
+@@ -680,7 +680,7 @@ long do_msgsnd(int msqid, long mtype, void __user *mtext,
+ 		rcu_read_lock();
+ 		ipc_lock_object(&msq->q_perm);
+ 
+-		ipc_rcu_putref(msq, ipc_rcu_free);
++		ipc_rcu_putref(msq, msg_rcu_free);
+ 		/* raced with RMID? */
+ 		if (!ipc_valid_object(&msq->q_perm)) {
+ 			err = -EIDRM;
+diff --git a/ipc/sem.c b/ipc/sem.c
+index b3757ea0694b..5d2f875e8e2e 100644
+--- a/ipc/sem.c
++++ b/ipc/sem.c
+@@ -449,7 +449,7 @@ static inline struct sem_array *sem_obtain_object_check(struct ipc_namespace *ns
+ static inline void sem_lock_and_putref(struct sem_array *sma)
+ {
+ 	sem_lock(sma, NULL, -1);
+-	ipc_rcu_putref(sma, ipc_rcu_free);
++	ipc_rcu_putref(sma, sem_rcu_free);
+ }
+ 
+ static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
+@@ -1392,7 +1392,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
+ 			rcu_read_unlock();
+ 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
+ 			if (sem_io == NULL) {
+-				ipc_rcu_putref(sma, ipc_rcu_free);
++				ipc_rcu_putref(sma, sem_rcu_free);
+ 				return -ENOMEM;
+ 			}
+ 
+@@ -1426,20 +1426,20 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
+ 		if (nsems > SEMMSL_FAST) {
+ 			sem_io = ipc_alloc(sizeof(ushort)*nsems);
+ 			if (sem_io == NULL) {
+-				ipc_rcu_putref(sma, ipc_rcu_free);
++				ipc_rcu_putref(sma, sem_rcu_free);
+ 				return -ENOMEM;
+ 			}
+ 		}
+ 
+ 		if (copy_from_user(sem_io, p, nsems*sizeof(ushort))) {
+-			ipc_rcu_putref(sma, ipc_rcu_free);
++			ipc_rcu_putref(sma, sem_rcu_free);
+ 			err = -EFAULT;
+ 			goto out_free;
+ 		}
+ 
+ 		for (i = 0; i < nsems; i++) {
+ 			if (sem_io[i] > SEMVMX) {
+-				ipc_rcu_putref(sma, ipc_rcu_free);
++				ipc_rcu_putref(sma, sem_rcu_free);
+ 				err = -ERANGE;
+ 				goto out_free;
+ 			}
+@@ -1731,7 +1731,7 @@ static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
+ 	/* step 2: allocate new undo structure */
+ 	new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL);
+ 	if (!new) {
+-		ipc_rcu_putref(sma, ipc_rcu_free);
++		ipc_rcu_putref(sma, sem_rcu_free);
+ 		return ERR_PTR(-ENOMEM);
+ 	}
+ 
+diff --git a/lib/radix-tree.c b/lib/radix-tree.c
+index 1624c4117961..9b9be3ffa1f6 100644
+--- a/lib/radix-tree.c
++++ b/lib/radix-tree.c
+@@ -228,10 +228,11 @@ radix_tree_node_alloc(struct radix_tree_root *root)
+ 
+ 		/*
+ 		 * Even if the caller has preloaded, try to allocate from the
+-		 * cache first for the new node to get accounted.
++		 * cache first for the new node to get accounted to the memory
++		 * cgroup.
+ 		 */
+ 		ret = kmem_cache_alloc(radix_tree_node_cachep,
+-				       gfp_mask | __GFP_ACCOUNT | __GFP_NOWARN);
++				       gfp_mask | __GFP_NOWARN);
+ 		if (ret)
+ 			goto out;
+ 
+@@ -254,8 +255,7 @@ radix_tree_node_alloc(struct radix_tree_root *root)
+ 		kmemleak_update_trace(ret);
+ 		goto out;
+ 	}
+-	ret = kmem_cache_alloc(radix_tree_node_cachep,
+-			       gfp_mask | __GFP_ACCOUNT);
++	ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask);
+ out:
+ 	BUG_ON(radix_tree_is_indirect_ptr(ret));
+ 	return ret;
+@@ -302,6 +302,12 @@ static int __radix_tree_preload(gfp_t gfp_mask)
+ 	struct radix_tree_node *node;
+ 	int ret = -ENOMEM;
+ 
++	/*
++	 * Nodes preloaded by one cgroup can be be used by another cgroup, so
++	 * they should never be accounted to any particular memory cgroup.
++	 */
++	gfp_mask &= ~__GFP_ACCOUNT;
++
+ 	preempt_disable();
+ 	rtp = this_cpu_ptr(&radix_tree_preloads);
+ 	while (rtp->nr < RADIX_TREE_PRELOAD_SIZE) {
+diff --git a/mm/memcontrol.c b/mm/memcontrol.c
+index bf860dbdd26e..eb2d761a83a2 100644
+--- a/mm/memcontrol.c
++++ b/mm/memcontrol.c
+@@ -4064,14 +4064,32 @@ static struct cftype mem_cgroup_legacy_files[] = {
+ 
+ static DEFINE_IDR(mem_cgroup_idr);
+ 
+-static void mem_cgroup_id_get(struct mem_cgroup *memcg)
++static void mem_cgroup_id_get_many(struct mem_cgroup *memcg, unsigned int n)
+ {
+-	atomic_inc(&memcg->id.ref);
++	atomic_add(n, &memcg->id.ref);
+ }
+ 
+-static void mem_cgroup_id_put(struct mem_cgroup *memcg)
++static struct mem_cgroup *mem_cgroup_id_get_online(struct mem_cgroup *memcg)
+ {
+-	if (atomic_dec_and_test(&memcg->id.ref)) {
++	while (!atomic_inc_not_zero(&memcg->id.ref)) {
++		/*
++		 * The root cgroup cannot be destroyed, so it's refcount must
++		 * always be >= 1.
++		 */
++		if (WARN_ON_ONCE(memcg == root_mem_cgroup)) {
++			VM_BUG_ON(1);
++			break;
++		}
++		memcg = parent_mem_cgroup(memcg);
++		if (!memcg)
++			memcg = root_mem_cgroup;
++	}
++	return memcg;
++}
++
++static void mem_cgroup_id_put_many(struct mem_cgroup *memcg, unsigned int n)
++{
++	if (atomic_sub_and_test(n, &memcg->id.ref)) {
+ 		idr_remove(&mem_cgroup_idr, memcg->id.id);
+ 		memcg->id.id = 0;
+ 
+@@ -4080,6 +4098,16 @@ static void mem_cgroup_id_put(struct mem_cgroup *memcg)
+ 	}
+ }
+ 
++static inline void mem_cgroup_id_get(struct mem_cgroup *memcg)
++{
++	mem_cgroup_id_get_many(memcg, 1);
++}
++
++static inline void mem_cgroup_id_put(struct mem_cgroup *memcg)
++{
++	mem_cgroup_id_put_many(memcg, 1);
++}
++
+ /**
+  * mem_cgroup_from_id - look up a memcg from a memcg id
+  * @id: the memcg id to look up
+@@ -4716,6 +4744,8 @@ static void __mem_cgroup_clear_mc(void)
+ 		if (!mem_cgroup_is_root(mc.from))
+ 			page_counter_uncharge(&mc.from->memsw, mc.moved_swap);
+ 
++		mem_cgroup_id_put_many(mc.from, mc.moved_swap);
++
+ 		/*
+ 		 * we charged both to->memory and to->memsw, so we
+ 		 * should uncharge to->memory.
+@@ -4723,9 +4753,9 @@ static void __mem_cgroup_clear_mc(void)
+ 		if (!mem_cgroup_is_root(mc.to))
+ 			page_counter_uncharge(&mc.to->memory, mc.moved_swap);
+ 
+-		css_put_many(&mc.from->css, mc.moved_swap);
++		mem_cgroup_id_get_many(mc.to, mc.moved_swap);
++		css_put_many(&mc.to->css, mc.moved_swap);
+ 
+-		/* we've already done css_get(mc.to) */
+ 		mc.moved_swap = 0;
+ 	}
+ 	memcg_oom_recover(from);
+@@ -5785,7 +5815,7 @@ subsys_initcall(mem_cgroup_init);
+  */
+ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
+ {
+-	struct mem_cgroup *memcg;
++	struct mem_cgroup *memcg, *swap_memcg;
+ 	unsigned short oldid;
+ 
+ 	VM_BUG_ON_PAGE(PageLRU(page), page);
+@@ -5800,16 +5830,27 @@ void mem_cgroup_swapout(struct page *page, swp_entry_t entry)
+ 	if (!memcg)
+ 		return;
+ 
+-	mem_cgroup_id_get(memcg);
+-	oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
++	/*
++	 * In case the memcg owning these pages has been offlined and doesn't
++	 * have an ID allocated to it anymore, charge the closest online
++	 * ancestor for the swap instead and transfer the memory+swap charge.
++	 */
++	swap_memcg = mem_cgroup_id_get_online(memcg);
++	oldid = swap_cgroup_record(entry, mem_cgroup_id(swap_memcg));
+ 	VM_BUG_ON_PAGE(oldid, page);
+-	mem_cgroup_swap_statistics(memcg, true);
++	mem_cgroup_swap_statistics(swap_memcg, true);
+ 
+ 	page->mem_cgroup = NULL;
+ 
+ 	if (!mem_cgroup_is_root(memcg))
+ 		page_counter_uncharge(&memcg->memory, 1);
+ 
++	if (memcg != swap_memcg) {
++		if (!mem_cgroup_is_root(swap_memcg))
++			page_counter_charge(&swap_memcg->memsw, 1);
++		page_counter_uncharge(&memcg->memsw, 1);
++	}
++
+ 	/*
+ 	 * Interrupts should be disabled here because the caller holds the
+ 	 * mapping->tree_lock lock which is taken with interrupts-off. It is
+@@ -5848,11 +5889,14 @@ int mem_cgroup_try_charge_swap(struct page *page, swp_entry_t entry)
+ 	if (!memcg)
+ 		return 0;
+ 
++	memcg = mem_cgroup_id_get_online(memcg);
++
+ 	if (!mem_cgroup_is_root(memcg) &&
+-	    !page_counter_try_charge(&memcg->swap, 1, &counter))
++	    !page_counter_try_charge(&memcg->swap, 1, &counter)) {
++		mem_cgroup_id_put(memcg);
+ 		return -ENOMEM;
++	}
+ 
+-	mem_cgroup_id_get(memcg);
+ 	oldid = swap_cgroup_record(entry, mem_cgroup_id(memcg));
+ 	VM_BUG_ON_PAGE(oldid, page);
+ 	mem_cgroup_swap_statistics(memcg, true);
+diff --git a/mm/mempool.c b/mm/mempool.c
+index 9b7a14a791cc..fd3a393b9eea 100644
+--- a/mm/mempool.c
++++ b/mm/mempool.c
+@@ -310,7 +310,7 @@ EXPORT_SYMBOL(mempool_resize);
+  * returns NULL. Note that due to preallocation, this function
+  * *never* fails when called from process contexts. (it might
+  * fail if called from an IRQ context.)
+- * Note: neither __GFP_NOMEMALLOC nor __GFP_ZERO are supported.
++ * Note: using __GFP_ZERO is not supported.
+  */
+ void *mempool_alloc(mempool_t *pool, gfp_t gfp_mask)
+ {
+@@ -319,27 +319,16 @@ void *mempool_alloc(mempool_t *pool, gfp_t gfp_mask)
+ 	wait_queue_t wait;
+ 	gfp_t gfp_temp;
+ 
+-	/* If oom killed, memory reserves are essential to prevent livelock */
+-	VM_WARN_ON_ONCE(gfp_mask & __GFP_NOMEMALLOC);
+-	/* No element size to zero on allocation */
+ 	VM_WARN_ON_ONCE(gfp_mask & __GFP_ZERO);
+-
+ 	might_sleep_if(gfp_mask & __GFP_DIRECT_RECLAIM);
+ 
++	gfp_mask |= __GFP_NOMEMALLOC;	/* don't allocate emergency reserves */
+ 	gfp_mask |= __GFP_NORETRY;	/* don't loop in __alloc_pages */
+ 	gfp_mask |= __GFP_NOWARN;	/* failures are OK */
+ 
+ 	gfp_temp = gfp_mask & ~(__GFP_DIRECT_RECLAIM|__GFP_IO);
+ 
+ repeat_alloc:
+-	if (likely(pool->curr_nr)) {
+-		/*
+-		 * Don't allocate from emergency reserves if there are
+-		 * elements available.  This check is racy, but it will
+-		 * be rechecked each loop.
+-		 */
+-		gfp_temp |= __GFP_NOMEMALLOC;
+-	}
+ 
+ 	element = pool->alloc(gfp_temp, pool->pool_data);
+ 	if (likely(element != NULL))
+@@ -363,12 +352,11 @@ repeat_alloc:
+ 	 * We use gfp mask w/o direct reclaim or IO for the first round.  If
+ 	 * alloc failed with that and @pool was empty, retry immediately.
+ 	 */
+-	if ((gfp_temp & ~__GFP_NOMEMALLOC) != gfp_mask) {
++	if (gfp_temp != gfp_mask) {
+ 		spin_unlock_irqrestore(&pool->lock, flags);
+ 		gfp_temp = gfp_mask;
+ 		goto repeat_alloc;
+ 	}
+-	gfp_temp = gfp_mask;
+ 
+ 	/* We must not sleep if !__GFP_DIRECT_RECLAIM */
+ 	if (!(gfp_mask & __GFP_DIRECT_RECLAIM)) {
+diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
+index e7e62570bdb8..3a573a2dcee2 100644
+--- a/net/8021q/vlan_dev.c
++++ b/net/8021q/vlan_dev.c
+@@ -146,10 +146,12 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb,
+ 
+ static int vlan_dev_change_mtu(struct net_device *dev, int new_mtu)
+ {
+-	/* TODO: gotta make sure the underlying layer can handle it,
+-	 * maybe an IFF_VLAN_CAPABLE flag for devices?
+-	 */
+-	if (vlan_dev_priv(dev)->real_dev->mtu < new_mtu)
++	struct net_device *real_dev = vlan_dev_priv(dev)->real_dev;
++	unsigned int max_mtu = real_dev->mtu;
++
++	if (netif_reduces_vlan_mtu(real_dev))
++		max_mtu -= VLAN_HLEN;
++	if (max_mtu < new_mtu)
+ 		return -ERANGE;
+ 
+ 	dev->mtu = new_mtu;
+diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
+index c92b52f37d38..1270207f3d7c 100644
+--- a/net/8021q/vlan_netlink.c
++++ b/net/8021q/vlan_netlink.c
+@@ -118,6 +118,7 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
+ {
+ 	struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
+ 	struct net_device *real_dev;
++	unsigned int max_mtu;
+ 	__be16 proto;
+ 	int err;
+ 
+@@ -144,9 +145,11 @@ static int vlan_newlink(struct net *src_net, struct net_device *dev,
+ 	if (err < 0)
+ 		return err;
+ 
++	max_mtu = netif_reduces_vlan_mtu(real_dev) ? real_dev->mtu - VLAN_HLEN :
++						     real_dev->mtu;
+ 	if (!tb[IFLA_MTU])
+-		dev->mtu = real_dev->mtu;
+-	else if (dev->mtu > real_dev->mtu)
++		dev->mtu = max_mtu;
++	else if (dev->mtu > max_mtu)
+ 		return -EINVAL;
+ 
+ 	err = vlan_changelink(dev, tb, data);
+diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
+index 160797722228..b32f5a4750bf 100644
+--- a/net/bridge/br_input.c
++++ b/net/bridge/br_input.c
+@@ -213,6 +213,16 @@ drop:
+ }
+ EXPORT_SYMBOL_GPL(br_handle_frame_finish);
+ 
++static void __br_handle_local_finish(struct sk_buff *skb)
++{
++	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
++	u16 vid = 0;
++
++	/* check if vlan is allowed, to avoid spoofing */
++	if (p->flags & BR_LEARNING && br_should_learn(p, skb, &vid))
++		br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid, false);
++}
++
+ /* note: already called with rcu_read_lock */
+ static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
+ {
+@@ -279,6 +289,14 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
+ 		case 0x01:	/* IEEE MAC (Pause) */
+ 			goto drop;
+ 
++		case 0x0E:	/* 802.1AB LLDP */
++			fwd_mask |= p->br->group_fwd_mask;
++			if (fwd_mask & (1u << dest[5]))
++				goto forward;
++			*pskb = skb;
++			__br_handle_local_finish(skb);
++			return RX_HANDLER_PASS;
++
+ 		default:
+ 			/* Allow selective forwarding for most other protocols */
+ 			fwd_mask |= p->br->group_fwd_mask;
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index c124c3c12f7c..e2e78843301c 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -87,7 +87,7 @@ int sysctl_tcp_adv_win_scale __read_mostly = 1;
+ EXPORT_SYMBOL(sysctl_tcp_adv_win_scale);
+ 
+ /* rfc5961 challenge ack rate limiting */
+-int sysctl_tcp_challenge_ack_limit = 100;
++int sysctl_tcp_challenge_ack_limit = 1000;
+ 
+ int sysctl_tcp_stdurg __read_mostly;
+ int sysctl_tcp_rfc1337 __read_mostly;
+@@ -3423,6 +3423,23 @@ static int tcp_ack_update_window(struct sock *sk, const struct sk_buff *skb, u32
+ 	return flag;
+ }
+ 
++static bool __tcp_oow_rate_limited(struct net *net, int mib_idx,
++				   u32 *last_oow_ack_time)
++{
++	if (*last_oow_ack_time) {
++		s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
++
++		if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
++			NET_INC_STATS_BH(net, mib_idx);
++			return true;	/* rate-limited: don't send yet! */
++		}
++	}
++
++	*last_oow_ack_time = tcp_time_stamp;
++
++	return false;	/* not rate-limited: go ahead, send dupack now! */
++}
++
+ /* Return true if we're currently rate-limiting out-of-window ACKs and
+  * thus shouldn't send a dupack right now. We rate-limit dupacks in
+  * response to out-of-window SYNs or ACKs to mitigate ACK loops or DoS
+@@ -3436,21 +3453,9 @@ bool tcp_oow_rate_limited(struct net *net, const struct sk_buff *skb,
+ 	/* Data packets without SYNs are not likely part of an ACK loop. */
+ 	if ((TCP_SKB_CB(skb)->seq != TCP_SKB_CB(skb)->end_seq) &&
+ 	    !tcp_hdr(skb)->syn)
+-		goto not_rate_limited;
+-
+-	if (*last_oow_ack_time) {
+-		s32 elapsed = (s32)(tcp_time_stamp - *last_oow_ack_time);
+-
+-		if (0 <= elapsed && elapsed < sysctl_tcp_invalid_ratelimit) {
+-			NET_INC_STATS_BH(net, mib_idx);
+-			return true;	/* rate-limited: don't send yet! */
+-		}
+-	}
+-
+-	*last_oow_ack_time = tcp_time_stamp;
++		return false;
+ 
+-not_rate_limited:
+-	return false;	/* not rate-limited: go ahead, send dupack now! */
++	return __tcp_oow_rate_limited(net, mib_idx, last_oow_ack_time);
+ }
+ 
+ /* RFC 5961 7 [ACK Throttling] */
+@@ -3460,21 +3465,26 @@ static void tcp_send_challenge_ack(struct sock *sk, const struct sk_buff *skb)
+ 	static u32 challenge_timestamp;
+ 	static unsigned int challenge_count;
+ 	struct tcp_sock *tp = tcp_sk(sk);
+-	u32 now;
++	u32 count, now;
+ 
+ 	/* First check our per-socket dupack rate limit. */
+-	if (tcp_oow_rate_limited(sock_net(sk), skb,
+-				 LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
+-				 &tp->last_oow_ack_time))
++	if (__tcp_oow_rate_limited(sock_net(sk),
++				   LINUX_MIB_TCPACKSKIPPEDCHALLENGE,
++				   &tp->last_oow_ack_time))
+ 		return;
+ 
+-	/* Then check the check host-wide RFC 5961 rate limit. */
++	/* Then check host-wide RFC 5961 rate limit. */
+ 	now = jiffies / HZ;
+ 	if (now != challenge_timestamp) {
++		u32 half = (sysctl_tcp_challenge_ack_limit + 1) >> 1;
++
+ 		challenge_timestamp = now;
+-		challenge_count = 0;
++		WRITE_ONCE(challenge_count, half +
++			   prandom_u32_max(sysctl_tcp_challenge_ack_limit));
+ 	}
+-	if (++challenge_count <= sysctl_tcp_challenge_ack_limit) {
++	count = READ_ONCE(challenge_count);
++	if (count > 0) {
++		WRITE_ONCE(challenge_count, count - 1);
+ 		NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK);
+ 		tcp_send_ack(sk);
+ 	}
+diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
+index 79a03b87a771..7b8e903b2a97 100644
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -236,7 +236,8 @@ void tcp_select_initial_window(int __space, __u32 mss,
+ 		/* Set window scaling on max possible window
+ 		 * See RFC1323 for an explanation of the limit to 14
+ 		 */
+-		space = max_t(u32, sysctl_tcp_rmem[2], sysctl_rmem_max);
++		space = max_t(u32, space, sysctl_tcp_rmem[2]);
++		space = max_t(u32, space, sysctl_rmem_max);
+ 		space = min_t(u32, space, *window_clamp);
+ 		while (space > 65535 && (*rcv_wscale) < 14) {
+ 			space >>= 1;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index 8ec4b3089e20..e3fc0cdf82a9 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -3563,6 +3563,10 @@ restart:
+ 		if (state != INET6_IFADDR_STATE_DEAD) {
+ 			__ipv6_ifa_notify(RTM_DELADDR, ifa);
+ 			inet6addr_notifier_call_chain(NETDEV_DOWN, ifa);
++		} else {
++			if (idev->cnf.forwarding)
++				addrconf_leave_anycast(ifa);
++			addrconf_leave_solict(ifa->idev, &ifa->addr);
+ 		}
+ 
+ 		write_lock_bh(&idev->lock);
+diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
+index 923abd6b3064..8d2f7c9b491d 100644
+--- a/net/irda/af_irda.c
++++ b/net/irda/af_irda.c
+@@ -1024,8 +1024,11 @@ static int irda_connect(struct socket *sock, struct sockaddr *uaddr,
+ 	}
+ 
+ 	/* Check if we have opened a local TSAP */
+-	if (!self->tsap)
+-		irda_open_tsap(self, LSAP_ANY, addr->sir_name);
++	if (!self->tsap) {
++		err = irda_open_tsap(self, LSAP_ANY, addr->sir_name);
++		if (err)
++			goto out;
++	}
+ 
+ 	/* Move to connecting socket, start sending Connect Requests */
+ 	sock->state = SS_CONNECTING;
+diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
+index ad4fa49ad1db..9068369f8a1b 100644
+--- a/security/apparmor/apparmorfs.c
++++ b/security/apparmor/apparmorfs.c
+@@ -331,6 +331,7 @@ static int aa_fs_seq_hash_show(struct seq_file *seq, void *v)
+ 			seq_printf(seq, "%.2x", profile->hash[i]);
+ 		seq_puts(seq, "\n");
+ 	}
++	aa_put_profile(profile);
+ 
+ 	return 0;
+ }


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

end of thread, other threads:[~2016-08-16 23:53 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-07-01  0:31 [gentoo-commits] proj/linux-patches:4.6 commit in: / Mike Pagano
  -- strict thread matches above, loose matches on Subject: below --
2016-08-16 23:53 Mike Pagano
2016-08-12 11:24 Mike Pagano
2016-08-10 12:57 Mike Pagano
2016-07-27 23:52 Mike Pagano
2016-07-27 19:23 Mike Pagano
2016-07-11 19:57 Mike Pagano
2016-07-02 15:27 Mike Pagano
2016-06-24 20:41 Mike Pagano
2016-06-08 10:09 Mike Pagano
2016-06-02 19:39 Mike Pagano
2016-04-25 12:19 Mike Pagano

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