public inbox for gentoo-commits@lists.gentoo.org
 help / color / mirror / Atom feed
From: "Mike Pagano" <mpagano@gentoo.org>
To: gentoo-commits@lists.gentoo.org
Subject: [gentoo-commits] proj/linux-patches:4.1 commit in: /
Date: Sat,  5 Mar 2016 23:38:37 +0000 (UTC)	[thread overview]
Message-ID: <1457221107.4a919eff2d079c34d6f84bf9073c32ef11af9864.mpagano@gentoo> (raw)

commit:     4a919eff2d079c34d6f84bf9073c32ef11af9864
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Sat Mar  5 23:38:27 2016 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Sat Mar  5 23:38:27 2016 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=4a919eff

Linux patch 4.1.19

 0000_README             |    4 +
 1018_linux-4.1.19.patch | 7602 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 7606 insertions(+)

diff --git a/0000_README b/0000_README
index ed66531..ad1d372 100644
--- a/0000_README
+++ b/0000_README
@@ -115,6 +115,10 @@ Patch:  1017_linux-4.1.18.patch
 From:   http://www.kernel.org
 Desc:   Linux 4.1.18
 
+Patch:  1018_linux-4.1.19.patch
+From:   http://www.kernel.org
+Desc:   Linux 4.1.19
+
 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/1018_linux-4.1.19.patch b/1018_linux-4.1.19.patch
new file mode 100644
index 0000000..449c63a
--- /dev/null
+++ b/1018_linux-4.1.19.patch
@@ -0,0 +1,7602 @@
+diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
+index 071fb18dc57c..07fad3d2fc56 100644
+--- a/Documentation/networking/ip-sysctl.txt
++++ b/Documentation/networking/ip-sysctl.txt
+@@ -1321,6 +1321,14 @@ accept_ra_from_local - BOOLEAN
+ 	   disabled if accept_ra_from_local is disabled
+                on a specific interface.
+ 
++accept_ra_min_hop_limit - INTEGER
++	Minimum hop limit Information in Router Advertisement.
++
++	Hop limit Information in Router Advertisement less than this
++	variable shall be ignored.
++
++	Default: 1
++
+ accept_ra_pinfo - BOOLEAN
+ 	Learn Prefix Information in Router Advertisement.
+ 
+diff --git a/Makefile b/Makefile
+index 001375cfd815..06107f683bbe 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,6 +1,6 @@
+ VERSION = 4
+ PATCHLEVEL = 1
+-SUBLEVEL = 18
++SUBLEVEL = 19
+ EXTRAVERSION =
+ NAME = Series 4800
+ 
+diff --git a/arch/arm/common/icst.c b/arch/arm/common/icst.c
+index 2dc6da70ae59..d7ed252708c5 100644
+--- a/arch/arm/common/icst.c
++++ b/arch/arm/common/icst.c
+@@ -16,7 +16,7 @@
+  */
+ #include <linux/module.h>
+ #include <linux/kernel.h>
+-
++#include <asm/div64.h>
+ #include <asm/hardware/icst.h>
+ 
+ /*
+@@ -29,7 +29,11 @@ EXPORT_SYMBOL(icst525_s2div);
+ 
+ unsigned long icst_hz(const struct icst_params *p, struct icst_vco vco)
+ {
+-	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * p->s2div[vco.s]);
++	u64 dividend = p->ref * 2 * (u64)(vco.v + 8);
++	u32 divisor = (vco.r + 2) * p->s2div[vco.s];
++
++	do_div(dividend, divisor);
++	return (unsigned long)dividend;
+ }
+ 
+ EXPORT_SYMBOL(icst_hz);
+@@ -58,6 +62,7 @@ icst_hz_to_vco(const struct icst_params *p, unsigned long freq)
+ 
+ 		if (f > p->vco_min && f <= p->vco_max)
+ 			break;
++		i++;
+ 	} while (i < 8);
+ 
+ 	if (i >= 8)
+diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h
+index 6499d93ae68d..47bc45a67e9b 100644
+--- a/arch/mips/include/asm/syscall.h
++++ b/arch/mips/include/asm/syscall.h
+@@ -101,10 +101,8 @@ static inline void syscall_get_arguments(struct task_struct *task,
+ 	/* O32 ABI syscall() - Either 64-bit with O32 or 32-bit */
+ 	if ((config_enabled(CONFIG_32BIT) ||
+ 	    test_tsk_thread_flag(task, TIF_32BIT_REGS)) &&
+-	    (regs->regs[2] == __NR_syscall)) {
++	    (regs->regs[2] == __NR_syscall))
+ 		i++;
+-		n++;
+-	}
+ 
+ 	while (n--)
+ 		ret |= mips_get_syscall_arg(args++, task, regs, i++);
+diff --git a/arch/powerpc/include/asm/eeh.h b/arch/powerpc/include/asm/eeh.h
+index a52db28ecc1e..4457cb605356 100644
+--- a/arch/powerpc/include/asm/eeh.h
++++ b/arch/powerpc/include/asm/eeh.h
+@@ -79,6 +79,7 @@ struct pci_dn;
+ #define EEH_PE_KEEP		(1 << 8)	/* Keep PE on hotplug	*/
+ #define EEH_PE_CFG_RESTRICTED	(1 << 9)	/* Block config on error */
+ #define EEH_PE_REMOVED		(1 << 10)	/* Removed permanently	*/
++#define EEH_PE_PRI_BUS		(1 << 11)	/* Cached primary bus   */
+ 
+ struct eeh_pe {
+ 	int type;			/* PE type: PHB/Bus/Device	*/
+@@ -336,19 +337,13 @@ static inline int eeh_check_failure(const volatile void __iomem *token)
+ 
+ #define eeh_dev_check_failure(x) (0)
+ 
+-static inline void eeh_addr_cache_build(void) { }
+-
+-static inline void eeh_add_device_early(struct pci_dn *pdn) { }
+-
+-static inline void eeh_add_device_tree_early(struct pci_dn *pdn) { }
+-
+-static inline void eeh_add_device_late(struct pci_dev *dev) { }
+-
+-static inline void eeh_add_device_tree_late(struct pci_bus *bus) { }
+-
+-static inline void eeh_add_sysfs_files(struct pci_bus *bus) { }
+-
+-static inline void eeh_remove_device(struct pci_dev *dev) { }
++#define eeh_addr_cache_build()
++#define eeh_add_device_early(pdn)
++#define eeh_add_device_tree_early(pdn)
++#define eeh_add_device_late(pdev)
++#define eeh_add_device_tree_late(pbus)
++#define eeh_add_sysfs_files(pbus)
++#define eeh_remove_device(pdev)
+ 
+ #define EEH_POSSIBLE_ERROR(val, type) (0)
+ #define EEH_IO_ERROR_VALUE(size) (-1UL)
+diff --git a/arch/powerpc/kernel/eeh_driver.c b/arch/powerpc/kernel/eeh_driver.c
+index 24768ff3cb73..90cc67904dc6 100644
+--- a/arch/powerpc/kernel/eeh_driver.c
++++ b/arch/powerpc/kernel/eeh_driver.c
+@@ -561,6 +561,7 @@ static int eeh_reset_device(struct eeh_pe *pe, struct pci_bus *bus)
+ 	 */
+ 	eeh_pe_state_mark(pe, EEH_PE_KEEP);
+ 	if (bus) {
++		eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 		pci_lock_rescan_remove();
+ 		pcibios_remove_pci_devices(bus);
+ 		pci_unlock_rescan_remove();
+@@ -792,6 +793,7 @@ perm_error:
+ 	 * the their PCI config any more.
+ 	 */
+ 	if (frozen_bus) {
++		eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 		eeh_pe_dev_mode_mark(pe, EEH_DEV_REMOVED);
+ 
+ 		pci_lock_rescan_remove();
+@@ -875,6 +877,7 @@ static void eeh_handle_special_event(void)
+ 					continue;
+ 
+ 				/* Notify all devices to be down */
++				eeh_pe_state_clear(pe, EEH_PE_PRI_BUS);
+ 				bus = eeh_pe_bus_get(phb_pe);
+ 				eeh_pe_dev_traverse(pe,
+ 					eeh_report_failure, NULL);
+diff --git a/arch/powerpc/kernel/eeh_pe.c b/arch/powerpc/kernel/eeh_pe.c
+index 22f6d954ef89..c3e0420b8a42 100644
+--- a/arch/powerpc/kernel/eeh_pe.c
++++ b/arch/powerpc/kernel/eeh_pe.c
+@@ -906,7 +906,7 @@ struct pci_bus *eeh_pe_bus_get(struct eeh_pe *pe)
+ 		bus = pe->phb->bus;
+ 	} else if (pe->type & EEH_PE_BUS ||
+ 		   pe->type & EEH_PE_DEVICE) {
+-		if (pe->bus) {
++		if (pe->state & EEH_PE_PRI_BUS) {
+ 			bus = pe->bus;
+ 			goto out;
+ 		}
+diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c
+index ce738ab3d5a9..abb396876b9a 100644
+--- a/arch/powerpc/platforms/powernv/eeh-powernv.c
++++ b/arch/powerpc/platforms/powernv/eeh-powernv.c
+@@ -455,9 +455,12 @@ static void *pnv_eeh_probe(struct pci_dn *pdn, void *data)
+ 	 * PCI devices of the PE are expected to be removed prior
+ 	 * to PE reset.
+ 	 */
+-	if (!edev->pe->bus)
++	if (!(edev->pe->state & EEH_PE_PRI_BUS)) {
+ 		edev->pe->bus = pci_find_bus(hose->global_number,
+ 					     pdn->busno);
++		if (edev->pe->bus)
++			edev->pe->state |= EEH_PE_PRI_BUS;
++	}
+ 
+ 	/*
+ 	 * Enable EEH explicitly so that we will do EEH check
+diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
+index 181c53bac3a7..62855ac37ab7 100644
+--- a/arch/x86/mm/fault.c
++++ b/arch/x86/mm/fault.c
+@@ -285,6 +285,9 @@ static noinline int vmalloc_fault(unsigned long address)
+ 	if (!pmd_k)
+ 		return -1;
+ 
++	if (pmd_huge(*pmd_k))
++		return 0;
++
+ 	pte_k = pte_offset_kernel(pmd_k, address);
+ 	if (!pte_present(*pte_k))
+ 		return -1;
+@@ -356,8 +359,6 @@ void vmalloc_sync_all(void)
+  * 64-bit:
+  *
+  *   Handle a fault on the vmalloc area
+- *
+- * This assumes no large pages in there.
+  */
+ static noinline int vmalloc_fault(unsigned long address)
+ {
+@@ -399,17 +400,23 @@ static noinline int vmalloc_fault(unsigned long address)
+ 	if (pud_none(*pud_ref))
+ 		return -1;
+ 
+-	if (pud_none(*pud) || pud_page_vaddr(*pud) != pud_page_vaddr(*pud_ref))
++	if (pud_none(*pud) || pud_pfn(*pud) != pud_pfn(*pud_ref))
+ 		BUG();
+ 
++	if (pud_huge(*pud))
++		return 0;
++
+ 	pmd = pmd_offset(pud, address);
+ 	pmd_ref = pmd_offset(pud_ref, address);
+ 	if (pmd_none(*pmd_ref))
+ 		return -1;
+ 
+-	if (pmd_none(*pmd) || pmd_page(*pmd) != pmd_page(*pmd_ref))
++	if (pmd_none(*pmd) || pmd_pfn(*pmd) != pmd_pfn(*pmd_ref))
+ 		BUG();
+ 
++	if (pmd_huge(*pmd))
++		return 0;
++
+ 	pte_ref = pte_offset_kernel(pmd_ref, address);
+ 	if (!pte_present(*pte_ref))
+ 		return -1;
+diff --git a/block/bio.c b/block/bio.c
+index 4441522ca339..cbce3e2208f4 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1122,9 +1122,12 @@ int bio_uncopy_user(struct bio *bio)
+ 	if (!bio_flagged(bio, BIO_NULL_MAPPED)) {
+ 		/*
+ 		 * if we're in a workqueue, the request is orphaned, so
+-		 * don't copy into a random user address space, just free.
++		 * don't copy into a random user address space, just free
++		 * and return -EINTR so user space doesn't expect any data.
+ 		 */
+-		if (current->mm && bio_data_dir(bio) == READ)
++		if (!current->mm)
++			ret = -EINTR;
++		else if (bio_data_dir(bio) == READ)
+ 			ret = bio_copy_to_iter(bio, bmd->iter);
+ 		if (bmd->is_our_pages)
+ 			bio_free_pages(bio);
+diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c
+index 5bc42f9b23f0..c0f03562a145 100644
+--- a/crypto/algif_skcipher.c
++++ b/crypto/algif_skcipher.c
+@@ -31,6 +31,11 @@ struct skcipher_sg_list {
+ 	struct scatterlist sg[0];
+ };
+ 
++struct skcipher_tfm {
++	struct crypto_ablkcipher *skcipher;
++	bool has_key;
++};
++
+ struct skcipher_ctx {
+ 	struct list_head tsgl;
+ 	struct af_alg_sgl rsgl;
+@@ -750,19 +755,139 @@ static struct proto_ops algif_skcipher_ops = {
+ 	.poll		=	skcipher_poll,
+ };
+ 
++static int skcipher_check_key(struct socket *sock)
++{
++	int err = 0;
++	struct sock *psk;
++	struct alg_sock *pask;
++	struct skcipher_tfm *tfm;
++	struct sock *sk = sock->sk;
++	struct alg_sock *ask = alg_sk(sk);
++
++	lock_sock(sk);
++	if (ask->refcnt)
++		goto unlock_child;
++
++	psk = ask->parent;
++	pask = alg_sk(ask->parent);
++	tfm = pask->private;
++
++	err = -ENOKEY;
++	lock_sock_nested(psk, SINGLE_DEPTH_NESTING);
++	if (!tfm->has_key)
++		goto unlock;
++
++	if (!pask->refcnt++)
++		sock_hold(psk);
++
++	ask->refcnt = 1;
++	sock_put(psk);
++
++	err = 0;
++
++unlock:
++	release_sock(psk);
++unlock_child:
++	release_sock(sk);
++
++	return err;
++}
++
++static int skcipher_sendmsg_nokey(struct socket *sock, struct msghdr *msg,
++				  size_t size)
++{
++	int err;
++
++	err = skcipher_check_key(sock);
++	if (err)
++		return err;
++
++	return skcipher_sendmsg(sock, msg, size);
++}
++
++static ssize_t skcipher_sendpage_nokey(struct socket *sock, struct page *page,
++				       int offset, size_t size, int flags)
++{
++	int err;
++
++	err = skcipher_check_key(sock);
++	if (err)
++		return err;
++
++	return skcipher_sendpage(sock, page, offset, size, flags);
++}
++
++static int skcipher_recvmsg_nokey(struct socket *sock, struct msghdr *msg,
++				  size_t ignored, int flags)
++{
++	int err;
++
++	err = skcipher_check_key(sock);
++	if (err)
++		return err;
++
++	return skcipher_recvmsg(sock, msg, ignored, flags);
++}
++
++static struct proto_ops algif_skcipher_ops_nokey = {
++	.family		=	PF_ALG,
++
++	.connect	=	sock_no_connect,
++	.socketpair	=	sock_no_socketpair,
++	.getname	=	sock_no_getname,
++	.ioctl		=	sock_no_ioctl,
++	.listen		=	sock_no_listen,
++	.shutdown	=	sock_no_shutdown,
++	.getsockopt	=	sock_no_getsockopt,
++	.mmap		=	sock_no_mmap,
++	.bind		=	sock_no_bind,
++	.accept		=	sock_no_accept,
++	.setsockopt	=	sock_no_setsockopt,
++
++	.release	=	af_alg_release,
++	.sendmsg	=	skcipher_sendmsg_nokey,
++	.sendpage	=	skcipher_sendpage_nokey,
++	.recvmsg	=	skcipher_recvmsg_nokey,
++	.poll		=	skcipher_poll,
++};
++
+ static void *skcipher_bind(const char *name, u32 type, u32 mask)
+ {
+-	return crypto_alloc_ablkcipher(name, type, mask);
++	struct skcipher_tfm *tfm;
++	struct crypto_ablkcipher *skcipher;
++
++	tfm = kzalloc(sizeof(*tfm), GFP_KERNEL);
++	if (!tfm)
++		return ERR_PTR(-ENOMEM);
++
++	skcipher = crypto_alloc_ablkcipher(name, type, mask);
++	if (IS_ERR(skcipher)) {
++		kfree(tfm);
++		return ERR_CAST(skcipher);
++	}
++
++	tfm->skcipher = skcipher;
++
++	return tfm;
+ }
+ 
+ static void skcipher_release(void *private)
+ {
+-	crypto_free_ablkcipher(private);
++	struct skcipher_tfm *tfm = private;
++
++	crypto_free_ablkcipher(tfm->skcipher);
++	kfree(tfm);
+ }
+ 
+ static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen)
+ {
+-	return crypto_ablkcipher_setkey(private, key, keylen);
++	struct skcipher_tfm *tfm = private;
++	int err;
++
++	err = crypto_ablkcipher_setkey(tfm->skcipher, key, keylen);
++	tfm->has_key = !err;
++
++	return err;
+ }
+ 
+ static void skcipher_wait(struct sock *sk)
+@@ -790,24 +915,26 @@ static void skcipher_sock_destruct(struct sock *sk)
+ 	af_alg_release_parent(sk);
+ }
+ 
+-static int skcipher_accept_parent(void *private, struct sock *sk)
++static int skcipher_accept_parent_nokey(void *private, struct sock *sk)
+ {
+ 	struct skcipher_ctx *ctx;
+ 	struct alg_sock *ask = alg_sk(sk);
+-	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private);
++	struct skcipher_tfm *tfm = private;
++	struct crypto_ablkcipher *skcipher = tfm->skcipher;
++	unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(skcipher);
+ 
+ 	ctx = sock_kmalloc(sk, len, GFP_KERNEL);
+ 	if (!ctx)
+ 		return -ENOMEM;
+ 
+-	ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private),
++	ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(skcipher),
+ 			       GFP_KERNEL);
+ 	if (!ctx->iv) {
+ 		sock_kfree_s(sk, ctx, len);
+ 		return -ENOMEM;
+ 	}
+ 
+-	memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private));
++	memset(ctx->iv, 0, crypto_ablkcipher_ivsize(skcipher));
+ 
+ 	INIT_LIST_HEAD(&ctx->tsgl);
+ 	ctx->len = len;
+@@ -820,7 +947,7 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
+ 
+ 	ask->private = ctx;
+ 
+-	ablkcipher_request_set_tfm(&ctx->req, private);
++	ablkcipher_request_set_tfm(&ctx->req, skcipher);
+ 	ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG,
+ 					af_alg_complete, &ctx->completion);
+ 
+@@ -829,12 +956,24 @@ static int skcipher_accept_parent(void *private, struct sock *sk)
+ 	return 0;
+ }
+ 
++static int skcipher_accept_parent(void *private, struct sock *sk)
++{
++	struct skcipher_tfm *tfm = private;
++
++	if (!tfm->has_key)
++		return -ENOKEY;
++
++	return skcipher_accept_parent_nokey(private, sk);
++}
++
+ static const struct af_alg_type algif_type_skcipher = {
+ 	.bind		=	skcipher_bind,
+ 	.release	=	skcipher_release,
+ 	.setkey		=	skcipher_setkey,
+ 	.accept		=	skcipher_accept_parent,
++	.accept_nokey	=	skcipher_accept_parent_nokey,
+ 	.ops		=	&algif_skcipher_ops,
++	.ops_nokey	=	&algif_skcipher_ops_nokey,
+ 	.name		=	"skcipher",
+ 	.owner		=	THIS_MODULE
+ };
+diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c
+index edf2e3ea1740..6a050e12fcdf 100644
+--- a/crypto/crypto_user.c
++++ b/crypto/crypto_user.c
+@@ -499,6 +499,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+ 		if (link->dump == NULL)
+ 			return -EINVAL;
+ 
++		down_read(&crypto_alg_sem);
+ 		list_for_each_entry(alg, &crypto_alg_list, cra_list)
+ 			dump_alloc += CRYPTO_REPORT_MAXSIZE;
+ 
+@@ -508,8 +509,11 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
+ 				.done = link->done,
+ 				.min_dump_alloc = dump_alloc,
+ 			};
+-			return netlink_dump_start(crypto_nlsk, skb, nlh, &c);
++			err = netlink_dump_start(crypto_nlsk, skb, nlh, &c);
+ 		}
++		up_read(&crypto_alg_sem);
++
++		return err;
+ 	}
+ 
+ 	err = nlmsg_parse(nlh, crypto_msg_min[type], attrs, CRYPTOCFGA_MAX,
+diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
+index e6ea912aee31..666fd8a1500a 100644
+--- a/drivers/ata/ahci.c
++++ b/drivers/ata/ahci.c
+@@ -262,6 +262,26 @@ static const struct pci_device_id ahci_pci_tbl[] = {
+ 	{ PCI_VDEVICE(INTEL, 0x3b2b), board_ahci }, /* PCH RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x3b2c), board_ahci }, /* PCH RAID */
+ 	{ PCI_VDEVICE(INTEL, 0x3b2f), board_ahci }, /* PCH AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b0), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b1), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b2), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b3), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b4), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b5), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b6), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19b7), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19bE), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19bF), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c0), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c1), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c2), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c3), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c4), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c5), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c6), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19c7), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19cE), board_ahci }, /* DNV AHCI */
++	{ PCI_VDEVICE(INTEL, 0x19cF), board_ahci }, /* DNV AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1c02), board_ahci }, /* CPT AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1c03), board_ahci }, /* CPT AHCI */
+ 	{ PCI_VDEVICE(INTEL, 0x1c04), board_ahci }, /* CPT RAID */
+diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
+index 287c4ba0219f..49840264dd57 100644
+--- a/drivers/ata/libahci.c
++++ b/drivers/ata/libahci.c
+@@ -495,8 +495,8 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
+ 		}
+ 	}
+ 
+-	/* fabricate port_map from cap.nr_ports */
+-	if (!port_map) {
++	/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */
++	if (!port_map && vers < 0x10300) {
+ 		port_map = (1 << ahci_nr_ports(cap)) - 1;
+ 		dev_warn(dev, "forcing PORTS_IMPL to 0x%x\n", port_map);
+ 
+diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
+index cdf6215a9a22..7dbba387d12a 100644
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struct ata_port *ap,
+ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
+ {
+ 	struct ata_port *ap = qc->ap;
+-	unsigned long flags;
+ 
+ 	if (ap->ops->error_handler) {
+ 		if (in_wq) {
+-			spin_lock_irqsave(ap->lock, flags);
+-
+ 			/* EH might have kicked in while host lock is
+ 			 * released.
+ 			 */
+@@ -1014,8 +1011,6 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
+ 				} else
+ 					ata_port_freeze(ap);
+ 			}
+-
+-			spin_unlock_irqrestore(ap->lock, flags);
+ 		} else {
+ 			if (likely(!(qc->err_mask & AC_ERR_HSM)))
+ 				ata_qc_complete(qc);
+@@ -1024,10 +1019,8 @@ static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
+ 		}
+ 	} else {
+ 		if (in_wq) {
+-			spin_lock_irqsave(ap->lock, flags);
+ 			ata_sff_irq_on(ap);
+ 			ata_qc_complete(qc);
+-			spin_unlock_irqrestore(ap->lock, flags);
+ 		} else
+ 			ata_qc_complete(qc);
+ 	}
+@@ -1048,9 +1041,10 @@ int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+ {
+ 	struct ata_link *link = qc->dev->link;
+ 	struct ata_eh_info *ehi = &link->eh_info;
+-	unsigned long flags = 0;
+ 	int poll_next;
+ 
++	lockdep_assert_held(ap->lock);
++
+ 	WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
+ 
+ 	/* Make sure ata_sff_qc_issue() does not throw things
+@@ -1112,14 +1106,6 @@ fsm_start:
+ 			}
+ 		}
+ 
+-		/* Send the CDB (atapi) or the first data block (ata pio out).
+-		 * During the state transition, interrupt handler shouldn't
+-		 * be invoked before the data transfer is complete and
+-		 * hsm_task_state is changed. Hence, the following locking.
+-		 */
+-		if (in_wq)
+-			spin_lock_irqsave(ap->lock, flags);
+-
+ 		if (qc->tf.protocol == ATA_PROT_PIO) {
+ 			/* PIO data out protocol.
+ 			 * send first data block.
+@@ -1135,9 +1121,6 @@ fsm_start:
+ 			/* send CDB */
+ 			atapi_send_cdb(ap, qc);
+ 
+-		if (in_wq)
+-			spin_unlock_irqrestore(ap->lock, flags);
+-
+ 		/* if polling, ata_sff_pio_task() handles the rest.
+ 		 * otherwise, interrupt handler takes over from here.
+ 		 */
+@@ -1361,12 +1344,14 @@ static void ata_sff_pio_task(struct work_struct *work)
+ 	u8 status;
+ 	int poll_next;
+ 
++	spin_lock_irq(ap->lock);
++
+ 	BUG_ON(ap->sff_pio_task_link == NULL);
+ 	/* qc can be NULL if timeout occurred */
+ 	qc = ata_qc_from_tag(ap, link->active_tag);
+ 	if (!qc) {
+ 		ap->sff_pio_task_link = NULL;
+-		return;
++		goto out_unlock;
+ 	}
+ 
+ fsm_start:
+@@ -1381,11 +1366,14 @@ fsm_start:
+ 	 */
+ 	status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
+ 	if (status & ATA_BUSY) {
++		spin_unlock_irq(ap->lock);
+ 		ata_msleep(ap, 2);
++		spin_lock_irq(ap->lock);
++
+ 		status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
+ 		if (status & ATA_BUSY) {
+ 			ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
+-			return;
++			goto out_unlock;
+ 		}
+ 	}
+ 
+@@ -1402,6 +1390,8 @@ fsm_start:
+ 	 */
+ 	if (poll_next)
+ 		goto fsm_start;
++out_unlock:
++	spin_unlock_irq(ap->lock);
+ }
+ 
+ /**
+diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c
+index 0f9a9dc06a83..fb16d812c8f5 100644
+--- a/drivers/crypto/atmel-aes.c
++++ b/drivers/crypto/atmel-aes.c
+@@ -260,7 +260,11 @@ static struct atmel_aes_dev *atmel_aes_find_dev(struct atmel_aes_ctx *ctx)
+ 
+ static int atmel_aes_hw_init(struct atmel_aes_dev *dd)
+ {
+-	clk_prepare_enable(dd->iclk);
++	int err;
++
++	err = clk_prepare_enable(dd->iclk);
++	if (err)
++		return err;
+ 
+ 	if (!(dd->flags & AES_FLAGS_INIT)) {
+ 		atmel_aes_write(dd, AES_CR, AES_CR_SWRST);
+@@ -1320,7 +1324,6 @@ static int atmel_aes_probe(struct platform_device *pdev)
+ 	struct crypto_platform_data *pdata;
+ 	struct device *dev = &pdev->dev;
+ 	struct resource *aes_res;
+-	unsigned long aes_phys_size;
+ 	int err;
+ 
+ 	pdata = pdev->dev.platform_data;
+@@ -1337,7 +1340,7 @@ static int atmel_aes_probe(struct platform_device *pdev)
+ 		goto aes_dd_err;
+ 	}
+ 
+-	aes_dd = kzalloc(sizeof(struct atmel_aes_dev), GFP_KERNEL);
++	aes_dd = devm_kzalloc(&pdev->dev, sizeof(*aes_dd), GFP_KERNEL);
+ 	if (aes_dd == NULL) {
+ 		dev_err(dev, "unable to alloc data struct.\n");
+ 		err = -ENOMEM;
+@@ -1368,36 +1371,35 @@ static int atmel_aes_probe(struct platform_device *pdev)
+ 		goto res_err;
+ 	}
+ 	aes_dd->phys_base = aes_res->start;
+-	aes_phys_size = resource_size(aes_res);
+ 
+ 	/* Get the IRQ */
+ 	aes_dd->irq = platform_get_irq(pdev,  0);
+ 	if (aes_dd->irq < 0) {
+ 		dev_err(dev, "no IRQ resource info\n");
+ 		err = aes_dd->irq;
+-		goto aes_irq_err;
++		goto res_err;
+ 	}
+ 
+-	err = request_irq(aes_dd->irq, atmel_aes_irq, IRQF_SHARED, "atmel-aes",
+-						aes_dd);
++	err = devm_request_irq(&pdev->dev, aes_dd->irq, atmel_aes_irq,
++			       IRQF_SHARED, "atmel-aes", aes_dd);
+ 	if (err) {
+ 		dev_err(dev, "unable to request aes irq.\n");
+-		goto aes_irq_err;
++		goto res_err;
+ 	}
+ 
+ 	/* Initializing the clock */
+-	aes_dd->iclk = clk_get(&pdev->dev, "aes_clk");
++	aes_dd->iclk = devm_clk_get(&pdev->dev, "aes_clk");
+ 	if (IS_ERR(aes_dd->iclk)) {
+ 		dev_err(dev, "clock initialization failed.\n");
+ 		err = PTR_ERR(aes_dd->iclk);
+-		goto clk_err;
++		goto res_err;
+ 	}
+ 
+-	aes_dd->io_base = ioremap(aes_dd->phys_base, aes_phys_size);
++	aes_dd->io_base = devm_ioremap_resource(&pdev->dev, aes_res);
+ 	if (!aes_dd->io_base) {
+ 		dev_err(dev, "can't ioremap\n");
+ 		err = -ENOMEM;
+-		goto aes_io_err;
++		goto res_err;
+ 	}
+ 
+ 	atmel_aes_hw_version_init(aes_dd);
+@@ -1434,17 +1436,9 @@ err_algs:
+ err_aes_dma:
+ 	atmel_aes_buff_cleanup(aes_dd);
+ err_aes_buff:
+-	iounmap(aes_dd->io_base);
+-aes_io_err:
+-	clk_put(aes_dd->iclk);
+-clk_err:
+-	free_irq(aes_dd->irq, aes_dd);
+-aes_irq_err:
+ res_err:
+ 	tasklet_kill(&aes_dd->done_task);
+ 	tasklet_kill(&aes_dd->queue_task);
+-	kfree(aes_dd);
+-	aes_dd = NULL;
+ aes_dd_err:
+ 	dev_err(dev, "initialization failed.\n");
+ 
+@@ -1469,16 +1463,6 @@ static int atmel_aes_remove(struct platform_device *pdev)
+ 
+ 	atmel_aes_dma_cleanup(aes_dd);
+ 
+-	iounmap(aes_dd->io_base);
+-
+-	clk_put(aes_dd->iclk);
+-
+-	if (aes_dd->irq > 0)
+-		free_irq(aes_dd->irq, aes_dd);
+-
+-	kfree(aes_dd);
+-	aes_dd = NULL;
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c
+index 5b35433c5399..a71c97c03c39 100644
+--- a/drivers/crypto/atmel-sha.c
++++ b/drivers/crypto/atmel-sha.c
+@@ -783,7 +783,7 @@ static void atmel_sha_finish_req(struct ahash_request *req, int err)
+ 	dd->flags &= ~(SHA_FLAGS_BUSY | SHA_FLAGS_FINAL | SHA_FLAGS_CPU |
+ 			SHA_FLAGS_DMA_READY | SHA_FLAGS_OUTPUT_READY);
+ 
+-	clk_disable_unprepare(dd->iclk);
++	clk_disable(dd->iclk);
+ 
+ 	if (req->base.complete)
+ 		req->base.complete(&req->base, err);
+@@ -794,7 +794,11 @@ static void atmel_sha_finish_req(struct ahash_request *req, int err)
+ 
+ static int atmel_sha_hw_init(struct atmel_sha_dev *dd)
+ {
+-	clk_prepare_enable(dd->iclk);
++	int err;
++
++	err = clk_enable(dd->iclk);
++	if (err)
++		return err;
+ 
+ 	if (!(SHA_FLAGS_INIT & dd->flags)) {
+ 		atmel_sha_write(dd, SHA_CR, SHA_CR_SWRST);
+@@ -819,7 +823,7 @@ static void atmel_sha_hw_version_init(struct atmel_sha_dev *dd)
+ 	dev_info(dd->dev,
+ 			"version: 0x%x\n", dd->hw_version);
+ 
+-	clk_disable_unprepare(dd->iclk);
++	clk_disable(dd->iclk);
+ }
+ 
+ static int atmel_sha_handle_queue(struct atmel_sha_dev *dd,
+@@ -1345,11 +1349,9 @@ static int atmel_sha_probe(struct platform_device *pdev)
+ 	struct crypto_platform_data	*pdata;
+ 	struct device *dev = &pdev->dev;
+ 	struct resource *sha_res;
+-	unsigned long sha_phys_size;
+ 	int err;
+ 
+-	sha_dd = devm_kzalloc(&pdev->dev, sizeof(struct atmel_sha_dev),
+-				GFP_KERNEL);
++	sha_dd = devm_kzalloc(&pdev->dev, sizeof(*sha_dd), GFP_KERNEL);
+ 	if (sha_dd == NULL) {
+ 		dev_err(dev, "unable to alloc data struct.\n");
+ 		err = -ENOMEM;
+@@ -1378,7 +1380,6 @@ static int atmel_sha_probe(struct platform_device *pdev)
+ 		goto res_err;
+ 	}
+ 	sha_dd->phys_base = sha_res->start;
+-	sha_phys_size = resource_size(sha_res);
+ 
+ 	/* Get the IRQ */
+ 	sha_dd->irq = platform_get_irq(pdev,  0);
+@@ -1388,28 +1389,32 @@ static int atmel_sha_probe(struct platform_device *pdev)
+ 		goto res_err;
+ 	}
+ 
+-	err = request_irq(sha_dd->irq, atmel_sha_irq, IRQF_SHARED, "atmel-sha",
+-						sha_dd);
++	err = devm_request_irq(&pdev->dev, sha_dd->irq, atmel_sha_irq,
++			       IRQF_SHARED, "atmel-sha", sha_dd);
+ 	if (err) {
+ 		dev_err(dev, "unable to request sha irq.\n");
+ 		goto res_err;
+ 	}
+ 
+ 	/* Initializing the clock */
+-	sha_dd->iclk = clk_get(&pdev->dev, "sha_clk");
++	sha_dd->iclk = devm_clk_get(&pdev->dev, "sha_clk");
+ 	if (IS_ERR(sha_dd->iclk)) {
+ 		dev_err(dev, "clock initialization failed.\n");
+ 		err = PTR_ERR(sha_dd->iclk);
+-		goto clk_err;
++		goto res_err;
+ 	}
+ 
+-	sha_dd->io_base = ioremap(sha_dd->phys_base, sha_phys_size);
++	sha_dd->io_base = devm_ioremap_resource(&pdev->dev, sha_res);
+ 	if (!sha_dd->io_base) {
+ 		dev_err(dev, "can't ioremap\n");
+ 		err = -ENOMEM;
+-		goto sha_io_err;
++		goto res_err;
+ 	}
+ 
++	err = clk_prepare(sha_dd->iclk);
++	if (err)
++		goto res_err;
++
+ 	atmel_sha_hw_version_init(sha_dd);
+ 
+ 	atmel_sha_get_cap(sha_dd);
+@@ -1421,12 +1426,12 @@ static int atmel_sha_probe(struct platform_device *pdev)
+ 			if (IS_ERR(pdata)) {
+ 				dev_err(&pdev->dev, "platform data not available\n");
+ 				err = PTR_ERR(pdata);
+-				goto err_pdata;
++				goto iclk_unprepare;
+ 			}
+ 		}
+ 		if (!pdata->dma_slave) {
+ 			err = -ENXIO;
+-			goto err_pdata;
++			goto iclk_unprepare;
+ 		}
+ 		err = atmel_sha_dma_init(sha_dd, pdata);
+ 		if (err)
+@@ -1457,12 +1462,8 @@ err_algs:
+ 	if (sha_dd->caps.has_dma)
+ 		atmel_sha_dma_cleanup(sha_dd);
+ err_sha_dma:
+-err_pdata:
+-	iounmap(sha_dd->io_base);
+-sha_io_err:
+-	clk_put(sha_dd->iclk);
+-clk_err:
+-	free_irq(sha_dd->irq, sha_dd);
++iclk_unprepare:
++	clk_unprepare(sha_dd->iclk);
+ res_err:
+ 	tasklet_kill(&sha_dd->done_task);
+ sha_dd_err:
+@@ -1489,6 +1490,8 @@ static int atmel_sha_remove(struct platform_device *pdev)
+ 	if (sha_dd->caps.has_dma)
+ 		atmel_sha_dma_cleanup(sha_dd);
+ 
++	clk_unprepare(sha_dd->iclk);
++
+ 	iounmap(sha_dd->io_base);
+ 
+ 	clk_put(sha_dd->iclk);
+diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c
+index ca2999709eb4..2c7a628d0375 100644
+--- a/drivers/crypto/atmel-tdes.c
++++ b/drivers/crypto/atmel-tdes.c
+@@ -218,7 +218,11 @@ static struct atmel_tdes_dev *atmel_tdes_find_dev(struct atmel_tdes_ctx *ctx)
+ 
+ static int atmel_tdes_hw_init(struct atmel_tdes_dev *dd)
+ {
+-	clk_prepare_enable(dd->iclk);
++	int err;
++
++	err = clk_prepare_enable(dd->iclk);
++	if (err)
++		return err;
+ 
+ 	if (!(dd->flags & TDES_FLAGS_INIT)) {
+ 		atmel_tdes_write(dd, TDES_CR, TDES_CR_SWRST);
+@@ -1355,7 +1359,6 @@ static int atmel_tdes_probe(struct platform_device *pdev)
+ 	struct crypto_platform_data	*pdata;
+ 	struct device *dev = &pdev->dev;
+ 	struct resource *tdes_res;
+-	unsigned long tdes_phys_size;
+ 	int err;
+ 
+ 	tdes_dd = devm_kmalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL);
+@@ -1389,7 +1392,6 @@ static int atmel_tdes_probe(struct platform_device *pdev)
+ 		goto res_err;
+ 	}
+ 	tdes_dd->phys_base = tdes_res->start;
+-	tdes_phys_size = resource_size(tdes_res);
+ 
+ 	/* Get the IRQ */
+ 	tdes_dd->irq = platform_get_irq(pdev,  0);
+@@ -1399,26 +1401,26 @@ static int atmel_tdes_probe(struct platform_device *pdev)
+ 		goto res_err;
+ 	}
+ 
+-	err = request_irq(tdes_dd->irq, atmel_tdes_irq, IRQF_SHARED,
+-			"atmel-tdes", tdes_dd);
++	err = devm_request_irq(&pdev->dev, tdes_dd->irq, atmel_tdes_irq,
++			       IRQF_SHARED, "atmel-tdes", tdes_dd);
+ 	if (err) {
+ 		dev_err(dev, "unable to request tdes irq.\n");
+-		goto tdes_irq_err;
++		goto res_err;
+ 	}
+ 
+ 	/* Initializing the clock */
+-	tdes_dd->iclk = clk_get(&pdev->dev, "tdes_clk");
++	tdes_dd->iclk = devm_clk_get(&pdev->dev, "tdes_clk");
+ 	if (IS_ERR(tdes_dd->iclk)) {
+ 		dev_err(dev, "clock initialization failed.\n");
+ 		err = PTR_ERR(tdes_dd->iclk);
+-		goto clk_err;
++		goto res_err;
+ 	}
+ 
+-	tdes_dd->io_base = ioremap(tdes_dd->phys_base, tdes_phys_size);
++	tdes_dd->io_base = devm_ioremap_resource(&pdev->dev, tdes_res);
+ 	if (!tdes_dd->io_base) {
+ 		dev_err(dev, "can't ioremap\n");
+ 		err = -ENOMEM;
+-		goto tdes_io_err;
++		goto res_err;
+ 	}
+ 
+ 	atmel_tdes_hw_version_init(tdes_dd);
+@@ -1474,12 +1476,6 @@ err_tdes_dma:
+ err_pdata:
+ 	atmel_tdes_buff_cleanup(tdes_dd);
+ err_tdes_buff:
+-	iounmap(tdes_dd->io_base);
+-tdes_io_err:
+-	clk_put(tdes_dd->iclk);
+-clk_err:
+-	free_irq(tdes_dd->irq, tdes_dd);
+-tdes_irq_err:
+ res_err:
+ 	tasklet_kill(&tdes_dd->done_task);
+ 	tasklet_kill(&tdes_dd->queue_task);
+@@ -1510,13 +1506,6 @@ static int atmel_tdes_remove(struct platform_device *pdev)
+ 
+ 	atmel_tdes_buff_cleanup(tdes_dd);
+ 
+-	iounmap(tdes_dd->io_base);
+-
+-	clk_put(tdes_dd->iclk);
+-
+-	if (tdes_dd->irq >= 0)
+-		free_irq(tdes_dd->irq, tdes_dd);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/dma/dw/core.c b/drivers/dma/dw/core.c
+index 303d937d63c7..ebffc744cb1b 100644
+--- a/drivers/dma/dw/core.c
++++ b/drivers/dma/dw/core.c
+@@ -156,7 +156,6 @@ static void dwc_initialize(struct dw_dma_chan *dwc)
+ 
+ 	/* Enable interrupts */
+ 	channel_set_bit(dw, MASK.XFER, dwc->mask);
+-	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
+ 	channel_set_bit(dw, MASK.ERROR, dwc->mask);
+ 
+ 	dwc->initialized = true;
+@@ -588,6 +587,9 @@ static void dwc_handle_cyclic(struct dw_dma *dw, struct dw_dma_chan *dwc,
+ 
+ 		spin_unlock_irqrestore(&dwc->lock, flags);
+ 	}
++
++	/* Re-enable interrupts */
++	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
+ }
+ 
+ /* ------------------------------------------------------------------------- */
+@@ -618,11 +620,8 @@ static void dw_dma_tasklet(unsigned long data)
+ 			dwc_scan_descriptors(dw, dwc);
+ 	}
+ 
+-	/*
+-	 * Re-enable interrupts.
+-	 */
++	/* Re-enable interrupts */
+ 	channel_set_bit(dw, MASK.XFER, dw->all_chan_mask);
+-	channel_set_bit(dw, MASK.BLOCK, dw->all_chan_mask);
+ 	channel_set_bit(dw, MASK.ERROR, dw->all_chan_mask);
+ }
+ 
+@@ -1256,6 +1255,7 @@ static void dwc_free_chan_resources(struct dma_chan *chan)
+ int dw_dma_cyclic_start(struct dma_chan *chan)
+ {
+ 	struct dw_dma_chan	*dwc = to_dw_dma_chan(chan);
++	struct dw_dma		*dw = to_dw_dma(chan->device);
+ 	unsigned long		flags;
+ 
+ 	if (!test_bit(DW_DMA_IS_CYCLIC, &dwc->flags)) {
+@@ -1264,7 +1264,12 @@ int dw_dma_cyclic_start(struct dma_chan *chan)
+ 	}
+ 
+ 	spin_lock_irqsave(&dwc->lock, flags);
++
++	/* Enable interrupts to perform cyclic transfer */
++	channel_set_bit(dw, MASK.BLOCK, dwc->mask);
++
+ 	dwc_dostart(dwc, dwc->cdesc->desc[0]);
++
+ 	spin_unlock_irqrestore(&dwc->lock, flags);
+ 
+ 	return 0;
+diff --git a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+index d2cd8d5b27a1..82f8e20cca74 100644
+--- a/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
++++ b/drivers/gpu/drm/i915/intel_dsi_panel_vbt.c
+@@ -207,7 +207,12 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+ 	gpio = *data++;
+ 
+ 	/* pull up/down */
+-	action = *data++;
++	action = *data++ & 1;
++
++	if (gpio >= ARRAY_SIZE(gtable)) {
++		DRM_DEBUG_KMS("unknown gpio %u\n", gpio);
++		goto out;
++	}
+ 
+ 	function = gtable[gpio].function_reg;
+ 	pad = gtable[gpio].pad_reg;
+@@ -226,6 +231,7 @@ static const u8 *mipi_exec_gpio(struct intel_dsi *intel_dsi, const u8 *data)
+ 	vlv_gpio_nc_write(dev_priv, pad, val);
+ 	mutex_unlock(&dev_priv->dpio_lock);
+ 
++out:
+ 	return data;
+ }
+ 
+diff --git a/drivers/gpu/drm/qxl/qxl_ioctl.c b/drivers/gpu/drm/qxl/qxl_ioctl.c
+index 7354a4cda59d..3aefaa058f0c 100644
+--- a/drivers/gpu/drm/qxl/qxl_ioctl.c
++++ b/drivers/gpu/drm/qxl/qxl_ioctl.c
+@@ -168,7 +168,8 @@ static int qxl_process_single_command(struct qxl_device *qdev,
+ 		       cmd->command_size))
+ 		return -EFAULT;
+ 
+-	reloc_info = kmalloc(sizeof(struct qxl_reloc_info) * cmd->relocs_num, GFP_KERNEL);
++	reloc_info = kmalloc_array(cmd->relocs_num,
++				   sizeof(struct qxl_reloc_info), GFP_KERNEL);
+ 	if (!reloc_info)
+ 		return -ENOMEM;
+ 
+diff --git a/drivers/gpu/drm/radeon/radeon_sa.c b/drivers/gpu/drm/radeon/radeon_sa.c
+index c507896aca45..197b157b73d0 100644
+--- a/drivers/gpu/drm/radeon/radeon_sa.c
++++ b/drivers/gpu/drm/radeon/radeon_sa.c
+@@ -349,8 +349,13 @@ int radeon_sa_bo_new(struct radeon_device *rdev,
+ 			/* see if we can skip over some allocations */
+ 		} while (radeon_sa_bo_next_hole(sa_manager, fences, tries));
+ 
++		for (i = 0; i < RADEON_NUM_RINGS; ++i)
++			radeon_fence_ref(fences[i]);
++
+ 		spin_unlock(&sa_manager->wq.lock);
+ 		r = radeon_fence_wait_any(rdev, fences, false);
++		for (i = 0; i < RADEON_NUM_RINGS; ++i)
++			radeon_fence_unref(&fences[i]);
+ 		spin_lock(&sa_manager->wq.lock);
+ 		/* if we have nothing to wait for block */
+ 		if (r == -ENOENT) {
+diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c
+index edafd3c2b170..f5c0590bbf73 100644
+--- a/drivers/gpu/drm/radeon/radeon_ttm.c
++++ b/drivers/gpu/drm/radeon/radeon_ttm.c
+@@ -758,7 +758,7 @@ static int radeon_ttm_tt_populate(struct ttm_tt *ttm)
+ 						       0, PAGE_SIZE,
+ 						       PCI_DMA_BIDIRECTIONAL);
+ 		if (pci_dma_mapping_error(rdev->pdev, gtt->ttm.dma_address[i])) {
+-			while (--i) {
++			while (i--) {
+ 				pci_unmap_page(rdev->pdev, gtt->ttm.dma_address[i],
+ 					       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
+ 				gtt->ttm.dma_address[i] = 0;
+diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
+index c32a934f7693..353e2ab090ee 100644
+--- a/drivers/infiniband/ulp/isert/ib_isert.c
++++ b/drivers/infiniband/ulp/isert/ib_isert.c
+@@ -1349,7 +1349,7 @@ sequence_cmd:
+ 	if (!rc && dump_payload == false && unsol_data)
+ 		iscsit_set_unsoliticed_dataout(cmd);
+ 	else if (dump_payload && imm_data)
+-		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++		target_put_sess_cmd(&cmd->se_cmd);
+ 
+ 	return 0;
+ }
+@@ -1774,7 +1774,7 @@ isert_put_cmd(struct isert_cmd *isert_cmd, bool comp_err)
+ 			    cmd->se_cmd.t_state == TRANSPORT_WRITE_PENDING) {
+ 				struct se_cmd *se_cmd = &cmd->se_cmd;
+ 
+-				target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++				target_put_sess_cmd(se_cmd);
+ 			}
+ 		}
+ 
+@@ -1947,7 +1947,7 @@ isert_completion_rdma_read(struct iser_tx_desc *tx_desc,
+ 	spin_unlock_bh(&cmd->istate_lock);
+ 
+ 	if (ret) {
+-		target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++		target_put_sess_cmd(se_cmd);
+ 		transport_send_check_condition_and_sense(se_cmd,
+ 							 se_cmd->pi_err, 0);
+ 	} else {
+diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
+index 9b84b4c0a000..6fbc7bc824d2 100644
+--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
++++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
+@@ -1334,7 +1334,7 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
+ 
+ 		BUG_ON(ch->sess == NULL);
+ 
+-		target_put_sess_cmd(ch->sess, &ioctx->cmd);
++		target_put_sess_cmd(&ioctx->cmd);
+ 		goto out;
+ 	}
+ 
+@@ -1365,11 +1365,11 @@ static int srpt_abort_cmd(struct srpt_send_ioctx *ioctx)
+ 		 * not been received in time.
+ 		 */
+ 		srpt_unmap_sg_to_ib_sge(ioctx->ch, ioctx);
+-		target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
++		target_put_sess_cmd(&ioctx->cmd);
+ 		break;
+ 	case SRPT_STATE_MGMT_RSP_SENT:
+ 		srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
+-		target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
++		target_put_sess_cmd(&ioctx->cmd);
+ 		break;
+ 	default:
+ 		WARN(1, "Unexpected command state (%d)", state);
+@@ -1679,7 +1679,7 @@ static int srpt_check_stop_free(struct se_cmd *cmd)
+ 	struct srpt_send_ioctx *ioctx = container_of(cmd,
+ 				struct srpt_send_ioctx, cmd);
+ 
+-	return target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
++	return target_put_sess_cmd(&ioctx->cmd);
+ }
+ 
+ /**
+@@ -3074,7 +3074,7 @@ static void srpt_queue_response(struct se_cmd *cmd)
+ 		       ioctx->tag);
+ 		srpt_unmap_sg_to_ib_sge(ch, ioctx);
+ 		srpt_set_cmd_state(ioctx, SRPT_STATE_DONE);
+-		target_put_sess_cmd(ioctx->ch->sess, &ioctx->cmd);
++		target_put_sess_cmd(&ioctx->cmd);
+ 	}
+ }
+ 
+diff --git a/drivers/input/mouse/vmmouse.c b/drivers/input/mouse/vmmouse.c
+index e272f06258ce..a3f0f5a47490 100644
+--- a/drivers/input/mouse/vmmouse.c
++++ b/drivers/input/mouse/vmmouse.c
+@@ -458,8 +458,6 @@ int vmmouse_init(struct psmouse *psmouse)
+ 	priv->abs_dev = abs_dev;
+ 	psmouse->private = priv;
+ 
+-	input_set_capability(rel_dev, EV_REL, REL_WHEEL);
+-
+ 	/* Set up and register absolute device */
+ 	snprintf(priv->phys, sizeof(priv->phys), "%s/input1",
+ 		 psmouse->ps2dev.serio->phys);
+@@ -475,10 +473,6 @@ int vmmouse_init(struct psmouse *psmouse)
+ 	abs_dev->id.version = psmouse->model;
+ 	abs_dev->dev.parent = &psmouse->ps2dev.serio->dev;
+ 
+-	error = input_register_device(priv->abs_dev);
+-	if (error)
+-		goto init_fail;
+-
+ 	/* Set absolute device capabilities */
+ 	input_set_capability(abs_dev, EV_KEY, BTN_LEFT);
+ 	input_set_capability(abs_dev, EV_KEY, BTN_RIGHT);
+@@ -488,6 +482,13 @@ int vmmouse_init(struct psmouse *psmouse)
+ 	input_set_abs_params(abs_dev, ABS_X, 0, VMMOUSE_MAX_X, 0, 0);
+ 	input_set_abs_params(abs_dev, ABS_Y, 0, VMMOUSE_MAX_Y, 0, 0);
+ 
++	error = input_register_device(priv->abs_dev);
++	if (error)
++		goto init_fail;
++
++	/* Add wheel capability to the relative device */
++	input_set_capability(rel_dev, EV_REL, REL_WHEEL);
++
+ 	psmouse->protocol_handler = vmmouse_process_byte;
+ 	psmouse->disconnect = vmmouse_disconnect;
+ 	psmouse->reconnect = vmmouse_reconnect;
+diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
+index 9847613085e1..5a2ec39e1fd9 100644
+--- a/drivers/iommu/dmar.c
++++ b/drivers/iommu/dmar.c
+@@ -1342,7 +1342,7 @@ void dmar_disable_qi(struct intel_iommu *iommu)
+ 
+ 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
+ 
+-	sts =  dmar_readq(iommu->reg + DMAR_GSTS_REG);
++	sts =  readl(iommu->reg + DMAR_GSTS_REG);
+ 	if (!(sts & DMA_GSTS_QIES))
+ 		goto end;
+ 
+diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
+index 5709ae9c3e77..04b39be8f1f3 100644
+--- a/drivers/iommu/intel_irq_remapping.c
++++ b/drivers/iommu/intel_irq_remapping.c
+@@ -544,7 +544,7 @@ static void iommu_disable_irq_remapping(struct intel_iommu *iommu)
+ 
+ 	raw_spin_lock_irqsave(&iommu->register_lock, flags);
+ 
+-	sts = dmar_readq(iommu->reg + DMAR_GSTS_REG);
++	sts = readl(iommu->reg + DMAR_GSTS_REG);
+ 	if (!(sts & DMA_GSTS_IRES))
+ 		goto end;
+ 
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
+index 72ba774df7a7..bd744e31c434 100644
+--- a/drivers/net/bonding/bond_main.c
++++ b/drivers/net/bonding/bond_main.c
+@@ -214,6 +214,8 @@ static void bond_uninit(struct net_device *bond_dev);
+ static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev,
+ 						struct rtnl_link_stats64 *stats);
+ static void bond_slave_arr_handler(struct work_struct *work);
++static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act,
++				  int mod);
+ 
+ /*---------------------------- General routines -----------------------------*/
+ 
+@@ -2397,7 +2399,7 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
+ 		 struct slave *slave)
+ {
+ 	struct arphdr *arp = (struct arphdr *)skb->data;
+-	struct slave *curr_active_slave;
++	struct slave *curr_active_slave, *curr_arp_slave;
+ 	unsigned char *arp_ptr;
+ 	__be32 sip, tip;
+ 	int alen, is_arp = skb->protocol == __cpu_to_be16(ETH_P_ARP);
+@@ -2444,26 +2446,41 @@ int bond_arp_rcv(const struct sk_buff *skb, struct bonding *bond,
+ 		     &sip, &tip);
+ 
+ 	curr_active_slave = rcu_dereference(bond->curr_active_slave);
++	curr_arp_slave = rcu_dereference(bond->current_arp_slave);
+ 
+-	/* Backup slaves won't see the ARP reply, but do come through
+-	 * here for each ARP probe (so we swap the sip/tip to validate
+-	 * the probe).  In a "redundant switch, common router" type of
+-	 * configuration, the ARP probe will (hopefully) travel from
+-	 * the active, through one switch, the router, then the other
+-	 * switch before reaching the backup.
++	/* We 'trust' the received ARP enough to validate it if:
++	 *
++	 * (a) the slave receiving the ARP is active (which includes the
++	 * current ARP slave, if any), or
++	 *
++	 * (b) the receiving slave isn't active, but there is a currently
++	 * active slave and it received valid arp reply(s) after it became
++	 * the currently active slave, or
++	 *
++	 * (c) there is an ARP slave that sent an ARP during the prior ARP
++	 * interval, and we receive an ARP reply on any slave.  We accept
++	 * these because switch FDB update delays may deliver the ARP
++	 * reply to a slave other than the sender of the ARP request.
+ 	 *
+-	 * We 'trust' the arp requests if there is an active slave and
+-	 * it received valid arp reply(s) after it became active. This
+-	 * is done to avoid endless looping when we can't reach the
++	 * Note: for (b), backup slaves are receiving the broadcast ARP
++	 * request, not a reply.  This request passes from the sending
++	 * slave through the L2 switch(es) to the receiving slave.  Since
++	 * this is checking the request, sip/tip are swapped for
++	 * validation.
++	 *
++	 * This is done to avoid endless looping when we can't reach the
+ 	 * arp_ip_target and fool ourselves with our own arp requests.
+ 	 */
+-
+ 	if (bond_is_active_slave(slave))
+ 		bond_validate_arp(bond, slave, sip, tip);
+ 	else if (curr_active_slave &&
+ 		 time_after(slave_last_rx(bond, curr_active_slave),
+ 			    curr_active_slave->last_link_up))
+ 		bond_validate_arp(bond, slave, tip, sip);
++	else if (curr_arp_slave && (arp->ar_op == htons(ARPOP_REPLY)) &&
++		 bond_time_in_interval(bond,
++				       dev_trans_start(curr_arp_slave->dev), 1))
++		bond_validate_arp(bond, slave, sip, tip);
+ 
+ out_unlock:
+ 	if (arp != (struct arphdr *)skb->data)
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index 0d8af5bb5907..d5415205779f 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -7833,6 +7833,14 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
+ 	return ret;
+ }
+ 
++static bool tg3_tso_bug_gso_check(struct tg3_napi *tnapi, struct sk_buff *skb)
++{
++	/* Check if we will never have enough descriptors,
++	 * as gso_segs can be more than current ring size
++	 */
++	return skb_shinfo(skb)->gso_segs < tnapi->tx_pending / 3;
++}
++
+ static netdev_tx_t tg3_start_xmit(struct sk_buff *, struct net_device *);
+ 
+ /* Use GSO to workaround all TSO packets that meet HW bug conditions
+@@ -7936,14 +7944,19 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		 * vlan encapsulated.
+ 		 */
+ 		if (skb->protocol == htons(ETH_P_8021Q) ||
+-		    skb->protocol == htons(ETH_P_8021AD))
+-			return tg3_tso_bug(tp, tnapi, txq, skb);
++		    skb->protocol == htons(ETH_P_8021AD)) {
++			if (tg3_tso_bug_gso_check(tnapi, skb))
++				return tg3_tso_bug(tp, tnapi, txq, skb);
++			goto drop;
++		}
+ 
+ 		if (!skb_is_gso_v6(skb)) {
+ 			if (unlikely((ETH_HLEN + hdr_len) > 80) &&
+-			    tg3_flag(tp, TSO_BUG))
+-				return tg3_tso_bug(tp, tnapi, txq, skb);
+-
++			    tg3_flag(tp, TSO_BUG)) {
++				if (tg3_tso_bug_gso_check(tnapi, skb))
++					return tg3_tso_bug(tp, tnapi, txq, skb);
++				goto drop;
++			}
+ 			ip_csum = iph->check;
+ 			ip_tot_len = iph->tot_len;
+ 			iph->check = 0;
+@@ -8075,7 +8088,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	if (would_hit_hwbug) {
+ 		tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
+ 
+-		if (mss) {
++		if (mss && tg3_tso_bug_gso_check(tnapi, skb)) {
+ 			/* If it's a TSO packet, do GSO instead of
+ 			 * allocating and copying to a large linear SKB
+ 			 */
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+index 8a083d73efdb..dae2ebb53af7 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c
+@@ -236,6 +236,24 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = {
+ 	.enable		= mlx4_en_phc_enable,
+ };
+ 
++#define MLX4_EN_WRAP_AROUND_SEC	10ULL
++
++/* This function calculates the max shift that enables the user range
++ * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register.
++ */
++static u32 freq_to_shift(u16 freq)
++{
++	u32 freq_khz = freq * 1000;
++	u64 max_val_cycles = freq_khz * 1000 * MLX4_EN_WRAP_AROUND_SEC;
++	u64 max_val_cycles_rounded = is_power_of_2(max_val_cycles + 1) ?
++		max_val_cycles : roundup_pow_of_two(max_val_cycles) - 1;
++	/* calculate max possible multiplier in order to fit in 64bit */
++	u64 max_mul = div_u64(0xffffffffffffffffULL, max_val_cycles_rounded);
++
++	/* This comes from the reverse of clocksource_khz2mult */
++	return ilog2(div_u64(max_mul * freq_khz, 1000000));
++}
++
+ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
+ {
+ 	struct mlx4_dev *dev = mdev->dev;
+@@ -247,12 +265,7 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev)
+ 	memset(&mdev->cycles, 0, sizeof(mdev->cycles));
+ 	mdev->cycles.read = mlx4_en_read_clock;
+ 	mdev->cycles.mask = CLOCKSOURCE_MASK(48);
+-	/* Using shift to make calculation more accurate. Since current HW
+-	 * clock frequency is 427 MHz, and cycles are given using a 48 bits
+-	 * register, the biggest shift when calculating using u64, is 14
+-	 * (max_cycles * multiplier < 2^64)
+-	 */
+-	mdev->cycles.shift = 14;
++	mdev->cycles.shift = freq_to_shift(dev->caps.hca_core_clock);
+ 	mdev->cycles.mult =
+ 		clocksource_khz2mult(1000 * dev->caps.hca_core_clock, mdev->cycles.shift);
+ 	mdev->nominal_c_mult = mdev->cycles.mult;
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+index a5a0b8420d26..e9189597000d 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c
+@@ -2330,8 +2330,6 @@ out:
+ 	/* set offloads */
+ 	priv->dev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+ 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL;
+-	priv->dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
+-	priv->dev->features    |= NETIF_F_GSO_UDP_TUNNEL;
+ }
+ 
+ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+@@ -2342,8 +2340,6 @@ static void mlx4_en_del_vxlan_offloads(struct work_struct *work)
+ 	/* unset offloads */
+ 	priv->dev->hw_enc_features &= ~(NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
+ 				      NETIF_F_TSO | NETIF_F_GSO_UDP_TUNNEL);
+-	priv->dev->hw_features &= ~NETIF_F_GSO_UDP_TUNNEL;
+-	priv->dev->features    &= ~NETIF_F_GSO_UDP_TUNNEL;
+ 
+ 	ret = mlx4_SET_PORT_VXLAN(priv->mdev->dev, priv->port,
+ 				  VXLAN_STEER_BY_OUTER_MAC, 0);
+@@ -2940,6 +2936,11 @@ int mlx4_en_init_netdev(struct mlx4_en_dev *mdev, int port,
+ 		priv->rss_hash_fn = ETH_RSS_HASH_TOP;
+ 	}
+ 
++	if (mdev->dev->caps.tunnel_offload_mode == MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
++		dev->hw_features |= NETIF_F_GSO_UDP_TUNNEL;
++		dev->features    |= NETIF_F_GSO_UDP_TUNNEL;
++	}
++
+ 	mdev->pndev[port] = dev;
+ 	mdev->upper[port] = NULL;
+ 
+diff --git a/drivers/net/ethernet/mellanox/mlx4/en_port.c b/drivers/net/ethernet/mellanox/mlx4/en_port.c
+index 0a56f010c846..760a8b387912 100644
+--- a/drivers/net/ethernet/mellanox/mlx4/en_port.c
++++ b/drivers/net/ethernet/mellanox/mlx4/en_port.c
+@@ -223,11 +223,11 @@ int mlx4_en_DUMP_ETH_STATS(struct mlx4_en_dev *mdev, u8 port, u8 reset)
+ 	stats->collisions = 0;
+ 	stats->rx_dropped = be32_to_cpu(mlx4_en_stats->RDROP);
+ 	stats->rx_length_errors = be32_to_cpu(mlx4_en_stats->RdropLength);
+-	stats->rx_over_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
++	stats->rx_over_errors = 0;
+ 	stats->rx_crc_errors = be32_to_cpu(mlx4_en_stats->RCRC);
+ 	stats->rx_frame_errors = 0;
+ 	stats->rx_fifo_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
+-	stats->rx_missed_errors = be32_to_cpu(mlx4_en_stats->RdropOvflw);
++	stats->rx_missed_errors = 0;
+ 	stats->tx_aborted_errors = 0;
+ 	stats->tx_carrier_errors = 0;
+ 	stats->tx_fifo_errors = 0;
+diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c
+index 73b6fc21ea00..4fedf7fa72c4 100644
+--- a/drivers/net/ethernet/rocker/rocker.c
++++ b/drivers/net/ethernet/rocker/rocker.c
+@@ -3384,12 +3384,14 @@ static void rocker_port_fdb_learn_work(struct work_struct *work)
+ 	info.addr = lw->addr;
+ 	info.vid = lw->vid;
+ 
++	rtnl_lock();
+ 	if (learned && removing)
+ 		call_netdev_switch_notifiers(NETDEV_SWITCH_FDB_DEL,
+ 					     lw->dev, &info.info);
+ 	else if (learned && !removing)
+ 		call_netdev_switch_notifiers(NETDEV_SWITCH_FDB_ADD,
+ 					     lw->dev, &info.info);
++	rtnl_unlock();
+ 
+ 	kfree(work);
+ }
+diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
+index 00cb41e71312..c56cf0b86f2c 100644
+--- a/drivers/net/phy/dp83640.c
++++ b/drivers/net/phy/dp83640.c
+@@ -833,6 +833,11 @@ static void decode_rxts(struct dp83640_private *dp83640,
+ 	struct skb_shared_hwtstamps *shhwtstamps = NULL;
+ 	struct sk_buff *skb;
+ 	unsigned long flags;
++	u8 overflow;
++
++	overflow = (phy_rxts->ns_hi >> 14) & 0x3;
++	if (overflow)
++		pr_debug("rx timestamp queue overflow, count %d\n", overflow);
+ 
+ 	spin_lock_irqsave(&dp83640->rx_lock, flags);
+ 
+@@ -875,6 +880,7 @@ static void decode_txts(struct dp83640_private *dp83640,
+ 	struct skb_shared_hwtstamps shhwtstamps;
+ 	struct sk_buff *skb;
+ 	u64 ns;
++	u8 overflow;
+ 
+ 	/* We must already have the skb that triggered this. */
+ 
+@@ -884,6 +890,17 @@ static void decode_txts(struct dp83640_private *dp83640,
+ 		pr_debug("have timestamp but tx_queue empty\n");
+ 		return;
+ 	}
++
++	overflow = (phy_txts->ns_hi >> 14) & 0x3;
++	if (overflow) {
++		pr_debug("tx timestamp queue overflow, count %d\n", overflow);
++		while (skb) {
++			skb_complete_tx_timestamp(skb, NULL);
++			skb = skb_dequeue(&dp83640->tx_queue);
++		}
++		return;
++	}
++
+ 	ns = phy2txts(phy_txts);
+ 	memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+ 	shhwtstamps.hwtstamp = ns_to_ktime(ns);
+diff --git a/drivers/net/ppp/pppoe.c b/drivers/net/ppp/pppoe.c
+index 9c8fabed4444..d1c4bc1c4df0 100644
+--- a/drivers/net/ppp/pppoe.c
++++ b/drivers/net/ppp/pppoe.c
+@@ -395,6 +395,8 @@ static int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
+ 
+ 		if (!__pppoe_xmit(sk_pppox(relay_po), skb))
+ 			goto abort_put;
++
++		sock_put(sk_pppox(relay_po));
+ 	} else {
+ 		if (sock_queue_rcv_skb(sk, skb))
+ 			goto abort_kfree;
+diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c
+index 0bacabfa486e..b35199cc8f34 100644
+--- a/drivers/net/ppp/pptp.c
++++ b/drivers/net/ppp/pptp.c
+@@ -131,24 +131,27 @@ static int lookup_chan_dst(u16 call_id, __be32 d_addr)
+ 	return i < MAX_CALLID;
+ }
+ 
+-static int add_chan(struct pppox_sock *sock)
++static int add_chan(struct pppox_sock *sock,
++		    struct pptp_addr *sa)
+ {
+ 	static int call_id;
+ 
+ 	spin_lock(&chan_lock);
+-	if (!sock->proto.pptp.src_addr.call_id)	{
++	if (!sa->call_id)	{
+ 		call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, call_id + 1);
+ 		if (call_id == MAX_CALLID) {
+ 			call_id = find_next_zero_bit(callid_bitmap, MAX_CALLID, 1);
+ 			if (call_id == MAX_CALLID)
+ 				goto out_err;
+ 		}
+-		sock->proto.pptp.src_addr.call_id = call_id;
+-	} else if (test_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap))
++		sa->call_id = call_id;
++	} else if (test_bit(sa->call_id, callid_bitmap)) {
+ 		goto out_err;
++	}
+ 
+-	set_bit(sock->proto.pptp.src_addr.call_id, callid_bitmap);
+-	rcu_assign_pointer(callid_sock[sock->proto.pptp.src_addr.call_id], sock);
++	sock->proto.pptp.src_addr = *sa;
++	set_bit(sa->call_id, callid_bitmap);
++	rcu_assign_pointer(callid_sock[sa->call_id], sock);
+ 	spin_unlock(&chan_lock);
+ 
+ 	return 0;
+@@ -417,7 +420,6 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
+ 	struct sock *sk = sock->sk;
+ 	struct sockaddr_pppox *sp = (struct sockaddr_pppox *) uservaddr;
+ 	struct pppox_sock *po = pppox_sk(sk);
+-	struct pptp_opt *opt = &po->proto.pptp;
+ 	int error = 0;
+ 
+ 	if (sockaddr_len < sizeof(struct sockaddr_pppox))
+@@ -425,10 +427,22 @@ static int pptp_bind(struct socket *sock, struct sockaddr *uservaddr,
+ 
+ 	lock_sock(sk);
+ 
+-	opt->src_addr = sp->sa_addr.pptp;
+-	if (add_chan(po))
++	if (sk->sk_state & PPPOX_DEAD) {
++		error = -EALREADY;
++		goto out;
++	}
++
++	if (sk->sk_state & PPPOX_BOUND) {
+ 		error = -EBUSY;
++		goto out;
++	}
++
++	if (add_chan(po, &sp->sa_addr.pptp))
++		error = -EBUSY;
++	else
++		sk->sk_state |= PPPOX_BOUND;
+ 
++out:
+ 	release_sock(sk);
+ 	return error;
+ }
+@@ -499,7 +513,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr,
+ 	}
+ 
+ 	opt->dst_addr = sp->sa_addr.pptp;
+-	sk->sk_state = PPPOX_CONNECTED;
++	sk->sk_state |= PPPOX_CONNECTED;
+ 
+  end:
+ 	release_sock(sk);
+diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c
+index 71190dc1eacf..cffb25280a3b 100644
+--- a/drivers/net/usb/qmi_wwan.c
++++ b/drivers/net/usb/qmi_wwan.c
+@@ -542,6 +542,7 @@ static const struct usb_device_id products[] = {
+ 
+ 	/* 3. Combined interface devices matching on interface number */
+ 	{QMI_FIXED_INTF(0x0408, 0xea42, 4)},	/* Yota / Megafon M100-1 */
++	{QMI_FIXED_INTF(0x05c6, 0x6001, 3)},	/* 4G LTE usb-modem U901 */
+ 	{QMI_FIXED_INTF(0x05c6, 0x7000, 0)},
+ 	{QMI_FIXED_INTF(0x05c6, 0x7001, 1)},
+ 	{QMI_FIXED_INTF(0x05c6, 0x7002, 1)},
+diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
+index 0bf82a20a0fb..48d21e0edd56 100644
+--- a/drivers/pci/pcie/aer/aerdrv.c
++++ b/drivers/pci/pcie/aer/aerdrv.c
+@@ -262,7 +262,6 @@ static struct aer_rpc *aer_alloc_rpc(struct pcie_device *dev)
+ 	rpc->rpd = dev;
+ 	INIT_WORK(&rpc->dpc_handler, aer_isr);
+ 	mutex_init(&rpc->rpc_mutex);
+-	init_waitqueue_head(&rpc->wait_release);
+ 
+ 	/* Use PCIe bus function to store rpc into PCIe device */
+ 	set_service_data(dev, rpc);
+@@ -285,8 +284,7 @@ static void aer_remove(struct pcie_device *dev)
+ 		if (rpc->isr)
+ 			free_irq(dev->irq, dev);
+ 
+-		wait_event(rpc->wait_release, rpc->prod_idx == rpc->cons_idx);
+-
++		flush_work(&rpc->dpc_handler);
+ 		aer_disable_rootport(rpc);
+ 		kfree(rpc);
+ 		set_service_data(dev, NULL);
+diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h
+index 84420b7c9456..945c939a86c5 100644
+--- a/drivers/pci/pcie/aer/aerdrv.h
++++ b/drivers/pci/pcie/aer/aerdrv.h
+@@ -72,7 +72,6 @@ struct aer_rpc {
+ 					 * recovery on the same
+ 					 * root port hierarchy
+ 					 */
+-	wait_queue_head_t wait_release;
+ };
+ 
+ struct aer_broadcast_data {
+diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
+index 5653ea94547f..b60a325234c5 100644
+--- a/drivers/pci/pcie/aer/aerdrv_core.c
++++ b/drivers/pci/pcie/aer/aerdrv_core.c
+@@ -784,8 +784,6 @@ void aer_isr(struct work_struct *work)
+ 	while (get_e_source(rpc, &e_src))
+ 		aer_isr_one_error(p_device, &e_src);
+ 	mutex_unlock(&rpc->rpc_mutex);
+-
+-	wake_up(&rpc->wait_release);
+ }
+ 
+ /**
+diff --git a/drivers/phy/phy-core.c b/drivers/phy/phy-core.c
+index 63bc12d7a73e..153e0a27c7ee 100644
+--- a/drivers/phy/phy-core.c
++++ b/drivers/phy/phy-core.c
+@@ -275,20 +275,21 @@ EXPORT_SYMBOL_GPL(phy_exit);
+ 
+ int phy_power_on(struct phy *phy)
+ {
+-	int ret;
++	int ret = 0;
+ 
+ 	if (!phy)
+-		return 0;
++		goto out;
+ 
+ 	if (phy->pwr) {
+ 		ret = regulator_enable(phy->pwr);
+ 		if (ret)
+-			return ret;
++			goto out;
+ 	}
+ 
+ 	ret = phy_pm_runtime_get_sync(phy);
+ 	if (ret < 0 && ret != -ENOTSUPP)
+-		return ret;
++		goto err_pm_sync;
++
+ 	ret = 0; /* Override possible ret == -ENOTSUPP */
+ 
+ 	mutex_lock(&phy->mutex);
+@@ -296,19 +297,20 @@ int phy_power_on(struct phy *phy)
+ 		ret = phy->ops->power_on(phy);
+ 		if (ret < 0) {
+ 			dev_err(&phy->dev, "phy poweron failed --> %d\n", ret);
+-			goto out;
++			goto err_pwr_on;
+ 		}
+ 	}
+ 	++phy->power_count;
+ 	mutex_unlock(&phy->mutex);
+ 	return 0;
+ 
+-out:
++err_pwr_on:
+ 	mutex_unlock(&phy->mutex);
+ 	phy_pm_runtime_put_sync(phy);
++err_pm_sync:
+ 	if (phy->pwr)
+ 		regulator_disable(phy->pwr);
+-
++out:
+ 	return ret;
+ }
+ EXPORT_SYMBOL_GPL(phy_power_on);
+diff --git a/drivers/phy/phy-twl4030-usb.c b/drivers/phy/phy-twl4030-usb.c
+index 6285f46f3ddb..fb9e30ed8018 100644
+--- a/drivers/phy/phy-twl4030-usb.c
++++ b/drivers/phy/phy-twl4030-usb.c
+@@ -719,6 +719,7 @@ static int twl4030_usb_probe(struct platform_device *pdev)
+ 	pm_runtime_use_autosuspend(&pdev->dev);
+ 	pm_runtime_set_autosuspend_delay(&pdev->dev, 2000);
+ 	pm_runtime_enable(&pdev->dev);
++	pm_runtime_get_sync(&pdev->dev);
+ 
+ 	/* Our job is to use irqs and status from the power module
+ 	 * to keep the transceiver disabled when nothing's connected.
+@@ -754,6 +755,7 @@ static int twl4030_usb_remove(struct platform_device *pdev)
+ 	struct twl4030_usb *twl = platform_get_drvdata(pdev);
+ 	int val;
+ 
++	usb_remove_phy(&twl->phy);
+ 	pm_runtime_get_sync(twl->dev);
+ 	cancel_delayed_work(&twl->id_workaround_work);
+ 	device_remove_file(twl->dev, &dev_attr_vbus);
+@@ -761,6 +763,13 @@ static int twl4030_usb_remove(struct platform_device *pdev)
+ 	/* set transceiver mode to power on defaults */
+ 	twl4030_usb_set_mode(twl, -1);
+ 
++	/* idle ulpi before powering off */
++	if (cable_present(twl->linkstat))
++		pm_runtime_put_noidle(twl->dev);
++	pm_runtime_mark_last_busy(twl->dev);
++	pm_runtime_put_sync_suspend(twl->dev);
++	pm_runtime_disable(twl->dev);
++
+ 	/* autogate 60MHz ULPI clock,
+ 	 * clear dpll clock request for i2c access,
+ 	 * disable 32KHz
+@@ -775,11 +784,6 @@ static int twl4030_usb_remove(struct platform_device *pdev)
+ 	/* disable complete OTG block */
+ 	twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB);
+ 
+-	if (cable_present(twl->linkstat))
+-		pm_runtime_put_noidle(twl->dev);
+-	pm_runtime_mark_last_busy(twl->dev);
+-	pm_runtime_put(twl->dev);
+-
+ 	return 0;
+ }
+ 
+diff --git a/drivers/platform/x86/intel_scu_ipcutil.c b/drivers/platform/x86/intel_scu_ipcutil.c
+index 02bc5a6343c3..aa454241489c 100644
+--- a/drivers/platform/x86/intel_scu_ipcutil.c
++++ b/drivers/platform/x86/intel_scu_ipcutil.c
+@@ -49,7 +49,7 @@ struct scu_ipc_data {
+ 
+ static int scu_reg_access(u32 cmd, struct scu_ipc_data  *data)
+ {
+-	int count = data->count;
++	unsigned int count = data->count;
+ 
+ 	if (count == 0 || count == 3 || count > 4)
+ 		return -EINVAL;
+diff --git a/drivers/s390/block/dasd_alias.c b/drivers/s390/block/dasd_alias.c
+index a2597e683e79..6a64e86e8ccd 100644
+--- a/drivers/s390/block/dasd_alias.c
++++ b/drivers/s390/block/dasd_alias.c
+@@ -264,8 +264,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
+ 		spin_unlock_irqrestore(&lcu->lock, flags);
+ 		cancel_work_sync(&lcu->suc_data.worker);
+ 		spin_lock_irqsave(&lcu->lock, flags);
+-		if (device == lcu->suc_data.device)
++		if (device == lcu->suc_data.device) {
++			dasd_put_device(device);
+ 			lcu->suc_data.device = NULL;
++		}
+ 	}
+ 	was_pending = 0;
+ 	if (device == lcu->ruac_data.device) {
+@@ -273,8 +275,10 @@ void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
+ 		was_pending = 1;
+ 		cancel_delayed_work_sync(&lcu->ruac_data.dwork);
+ 		spin_lock_irqsave(&lcu->lock, flags);
+-		if (device == lcu->ruac_data.device)
++		if (device == lcu->ruac_data.device) {
++			dasd_put_device(device);
+ 			lcu->ruac_data.device = NULL;
++		}
+ 	}
+ 	private->lcu = NULL;
+ 	spin_unlock_irqrestore(&lcu->lock, flags);
+@@ -549,8 +553,10 @@ static void lcu_update_work(struct work_struct *work)
+ 	if ((rc && (rc != -EOPNOTSUPP)) || (lcu->flags & NEED_UAC_UPDATE)) {
+ 		DBF_DEV_EVENT(DBF_WARNING, device, "could not update"
+ 			    " alias data in lcu (rc = %d), retry later", rc);
+-		schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
++		if (!schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ))
++			dasd_put_device(device);
+ 	} else {
++		dasd_put_device(device);
+ 		lcu->ruac_data.device = NULL;
+ 		lcu->flags &= ~UPDATE_PENDING;
+ 	}
+@@ -593,8 +599,10 @@ static int _schedule_lcu_update(struct alias_lcu *lcu,
+ 	 */
+ 	if (!usedev)
+ 		return -EINVAL;
++	dasd_get_device(usedev);
+ 	lcu->ruac_data.device = usedev;
+-	schedule_delayed_work(&lcu->ruac_data.dwork, 0);
++	if (!schedule_delayed_work(&lcu->ruac_data.dwork, 0))
++		dasd_put_device(usedev);
+ 	return 0;
+ }
+ 
+@@ -722,7 +730,7 @@ static int reset_summary_unit_check(struct alias_lcu *lcu,
+ 	ASCEBC((char *) &cqr->magic, 4);
+ 	ccw = cqr->cpaddr;
+ 	ccw->cmd_code = DASD_ECKD_CCW_RSCK;
+-	ccw->flags = 0 ;
++	ccw->flags = CCW_FLAG_SLI;
+ 	ccw->count = 16;
+ 	ccw->cda = (__u32)(addr_t) cqr->data;
+ 	((char *)cqr->data)[0] = reason;
+@@ -926,6 +934,7 @@ static void summary_unit_check_handling_work(struct work_struct *work)
+ 	/* 3. read new alias configuration */
+ 	_schedule_lcu_update(lcu, device);
+ 	lcu->suc_data.device = NULL;
++	dasd_put_device(device);
+ 	spin_unlock_irqrestore(&lcu->lock, flags);
+ }
+ 
+@@ -985,6 +994,8 @@ void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
+ 	}
+ 	lcu->suc_data.reason = reason;
+ 	lcu->suc_data.device = device;
++	dasd_get_device(device);
+ 	spin_unlock(&lcu->lock);
+-	schedule_work(&lcu->suc_data.worker);
++	if (!schedule_work(&lcu->suc_data.worker))
++		dasd_put_device(device);
+ };
+diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
+index b46ace3d4bf0..dd0c133aa312 100644
+--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
++++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
+@@ -568,7 +568,7 @@ static int mode_select_handle_sense(struct scsi_device *sdev,
+ 			/*
+ 			 * Command Lock contention
+ 			 */
+-			err = SCSI_DH_RETRY;
++			err = SCSI_DH_IMM_RETRY;
+ 		break;
+ 	default:
+ 		break;
+@@ -618,6 +618,8 @@ retry:
+ 		err = mode_select_handle_sense(sdev, h->sense);
+ 		if (err == SCSI_DH_RETRY && retry_cnt--)
+ 			goto retry;
++		if (err == SCSI_DH_IMM_RETRY)
++			goto retry;
+ 	}
+ 	if (err == SCSI_DH_OK) {
+ 		h->state = RDAC_STATE_ACTIVE;
+diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
+index e9ae6b924c70..8b011aef12bd 100644
+--- a/drivers/scsi/qla2xxx/qla_dbg.c
++++ b/drivers/scsi/qla2xxx/qla_dbg.c
+@@ -67,10 +67,10 @@
+  * |                              |                    | 0xd031-0xd0ff	|
+  * |                              |                    | 0xd101-0xd1fe	|
+  * |                              |                    | 0xd214-0xd2fe	|
+- * | Target Mode		  |	  0xe079       |		|
+- * | Target Mode Management	  |	  0xf080       | 0xf002		|
++ * | Target Mode		  |	  0xe080       |		|
++ * | Target Mode Management	  |	  0xf096       | 0xf002		|
+  * |                              |                    | 0xf046-0xf049  |
+- * | Target Mode Task Management  |	  0x1000b      |		|
++ * | Target Mode Task Management  |	  0x1000d      |		|
+  * ----------------------------------------------------------------------
+  */
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index e86201d3b8c6..90d926ca1200 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -274,6 +274,7 @@
+ #define RESPONSE_ENTRY_CNT_FX00		256     /* Number of response entries.*/
+ 
+ struct req_que;
++struct qla_tgt_sess;
+ 
+ /*
+  * (sd.h is not exported, hence local inclusion)
+@@ -2026,6 +2027,7 @@ typedef struct fc_port {
+ 	uint16_t port_id;
+ 
+ 	unsigned long retry_delay_timestamp;
++	struct qla_tgt_sess *tgt_session;
+ } fc_port_t;
+ 
+ #include "qla_mr.h"
+@@ -3579,6 +3581,16 @@ typedef struct scsi_qla_host {
+ 	uint16_t	fcoe_fcf_idx;
+ 	uint8_t		fcoe_vn_port_mac[6];
+ 
++	/* list of commands waiting on workqueue */
++	struct list_head	qla_cmd_list;
++	struct list_head	qla_sess_op_cmd_list;
++	spinlock_t		cmd_list_lock;
++
++	/* Counter to detect races between ELS and RSCN events */
++	atomic_t		generation_tick;
++	/* Time when global fcport update has been scheduled */
++	int			total_fcport_update_gen;
++
+ 	uint32_t	vp_abort_cnt;
+ 
+ 	struct fc_vport	*fc_vport;	/* holds fc_vport * for each vport */
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index 998498e2341b..60f9651f2643 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -115,6 +115,8 @@ qla2x00_async_iocb_timeout(void *data)
+ 			QLA_LOGIO_LOGIN_RETRIED : 0;
+ 		qla2x00_post_async_login_done_work(fcport->vha, fcport,
+ 			lio->u.logio.data);
++	} else if (sp->type == SRB_LOGOUT_CMD) {
++		qlt_logo_completion_handler(fcport, QLA_FUNCTION_TIMEOUT);
+ 	}
+ }
+ 
+@@ -497,7 +499,10 @@ void
+ qla2x00_async_logout_done(struct scsi_qla_host *vha, fc_port_t *fcport,
+     uint16_t *data)
+ {
+-	qla2x00_mark_device_lost(vha, fcport, 1, 0);
++	/* Don't re-login in target mode */
++	if (!fcport->tgt_session)
++		qla2x00_mark_device_lost(vha, fcport, 1, 0);
++	qlt_logo_completion_handler(fcport, data[0]);
+ 	return;
+ }
+ 
+@@ -2189,7 +2194,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
+ 	/* Clear outstanding commands array. */
+ 	for (que = 0; que < ha->max_req_queues; que++) {
+ 		req = ha->req_q_map[que];
+-		if (!req)
++		if (!req || !test_bit(que, ha->req_qid_map))
+ 			continue;
+ 		req->out_ptr = (void *)(req->ring + req->length);
+ 		*req->out_ptr = 0;
+@@ -2206,7 +2211,7 @@ qla2x00_init_rings(scsi_qla_host_t *vha)
+ 
+ 	for (que = 0; que < ha->max_rsp_queues; que++) {
+ 		rsp = ha->rsp_q_map[que];
+-		if (!rsp)
++		if (!rsp || !test_bit(que, ha->rsp_qid_map))
+ 			continue;
+ 		rsp->in_ptr = (void *)(rsp->ring + rsp->length);
+ 		*rsp->in_ptr = 0;
+@@ -2922,24 +2927,14 @@ qla2x00_rport_del(void *data)
+ {
+ 	fc_port_t *fcport = data;
+ 	struct fc_rport *rport;
+-	scsi_qla_host_t *vha = fcport->vha;
+ 	unsigned long flags;
+-	unsigned long vha_flags;
+ 
+ 	spin_lock_irqsave(fcport->vha->host->host_lock, flags);
+ 	rport = fcport->drport ? fcport->drport: fcport->rport;
+ 	fcport->drport = NULL;
+ 	spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
+-	if (rport) {
++	if (rport)
+ 		fc_remote_port_delete(rport);
+-		/*
+-		 * Release the target mode FC NEXUS in qla_target.c code
+-		 * if target mod is enabled.
+-		 */
+-		spin_lock_irqsave(&vha->hw->hardware_lock, vha_flags);
+-		qlt_fc_port_deleted(vha, fcport);
+-		spin_unlock_irqrestore(&vha->hw->hardware_lock, vha_flags);
+-	}
+ }
+ 
+ /**
+@@ -3379,6 +3374,7 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
+ 	LIST_HEAD(new_fcports);
+ 	struct qla_hw_data *ha = vha->hw;
+ 	struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
++	int		discovery_gen;
+ 
+ 	/* If FL port exists, then SNS is present */
+ 	if (IS_FWI2_CAPABLE(ha))
+@@ -3449,6 +3445,14 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
+ 			fcport->scan_state = QLA_FCPORT_SCAN;
+ 		}
+ 
++		/* Mark the time right before querying FW for connected ports.
++		 * This process is long, asynchronous and by the time it's done,
++		 * collected information might not be accurate anymore. E.g.
++		 * disconnected port might have re-connected and a brand new
++		 * session has been created. In this case session's generation
++		 * will be newer than discovery_gen. */
++		qlt_do_generation_tick(vha, &discovery_gen);
++
+ 		rval = qla2x00_find_all_fabric_devs(vha, &new_fcports);
+ 		if (rval != QLA_SUCCESS)
+ 			break;
+@@ -3500,7 +3504,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *vha)
+ 					    atomic_read(&fcport->state),
+ 					    fcport->flags, fcport->fc4_type,
+ 					    fcport->scan_state);
+-					qlt_fc_port_deleted(vha, fcport);
++					qlt_fc_port_deleted(vha, fcport,
++					    discovery_gen);
+ 				}
+ 			}
+ 		}
+@@ -4277,6 +4282,14 @@ qla2x00_update_fcports(scsi_qla_host_t *base_vha)
+ 			    atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
+ 				spin_unlock_irqrestore(&ha->vport_slock, flags);
+ 				qla2x00_rport_del(fcport);
++
++				/*
++				 * Release the target mode FC NEXUS in
++				 * qla_target.c, if target mod is enabled.
++				 */
++				qlt_fc_port_deleted(vha, fcport,
++				    base_vha->total_fcport_update_gen);
++
+ 				spin_lock_irqsave(&ha->vport_slock, flags);
+ 			}
+ 		}
+@@ -4944,7 +4957,7 @@ qla25xx_init_queues(struct qla_hw_data *ha)
+ 
+ 	for (i = 1; i < ha->max_rsp_queues; i++) {
+ 		rsp = ha->rsp_q_map[i];
+-		if (rsp) {
++		if (rsp && test_bit(i, ha->rsp_qid_map)) {
+ 			rsp->options &= ~BIT_0;
+ 			ret = qla25xx_init_rsp_que(base_vha, rsp);
+ 			if (ret != QLA_SUCCESS)
+@@ -4959,8 +4972,8 @@ qla25xx_init_queues(struct qla_hw_data *ha)
+ 	}
+ 	for (i = 1; i < ha->max_req_queues; i++) {
+ 		req = ha->req_q_map[i];
+-		if (req) {
+-		/* Clear outstanding commands array. */
++		if (req && test_bit(i, ha->req_qid_map)) {
++			/* Clear outstanding commands array. */
+ 			req->options &= ~BIT_0;
+ 			ret = qla25xx_init_req_que(base_vha, req);
+ 			if (ret != QLA_SUCCESS)
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index a1ab25fca874..dc96f31a8831 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -1943,6 +1943,9 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
+ 	logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
+ 	logio->control_flags =
+ 	    cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
++	if (!sp->fcport->tgt_session ||
++	    !sp->fcport->tgt_session->keep_nport_handle)
++		logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
+ 	logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
+ 	logio->port_id[0] = sp->fcport->d_id.b.al_pa;
+ 	logio->port_id[1] = sp->fcport->d_id.b.area;
+diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c
+index 6dc14cd782b2..1f3991ba7580 100644
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -2992,9 +2992,9 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
+ 		    "MSI-X: Failed to enable support "
+ 		    "-- %d/%d\n Retry with %d vectors.\n",
+ 		    ha->msix_count, ret, ret);
++		ha->msix_count = ret;
++		ha->max_rsp_queues = ha->msix_count - 1;
+ 	}
+-	ha->msix_count = ret;
+-	ha->max_rsp_queues = ha->msix_count - 1;
+ 	ha->msix_entries = kzalloc(sizeof(struct qla_msix_entry) *
+ 				ha->msix_count, GFP_KERNEL);
+ 	if (!ha->msix_entries) {
+diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c
+index cc94192511cf..63abed122adf 100644
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -601,7 +601,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha)
+ 	/* Delete request queues */
+ 	for (cnt = 1; cnt < ha->max_req_queues; cnt++) {
+ 		req = ha->req_q_map[cnt];
+-		if (req) {
++		if (req && test_bit(cnt, ha->req_qid_map)) {
+ 			ret = qla25xx_delete_req_que(vha, req);
+ 			if (ret != QLA_SUCCESS) {
+ 				ql_log(ql_log_warn, vha, 0x00ea,
+@@ -615,7 +615,7 @@ qla25xx_delete_queues(struct scsi_qla_host *vha)
+ 	/* Delete response queues */
+ 	for (cnt = 1; cnt < ha->max_rsp_queues; cnt++) {
+ 		rsp = ha->rsp_q_map[cnt];
+-		if (rsp) {
++		if (rsp && test_bit(cnt, ha->rsp_qid_map)) {
+ 			ret = qla25xx_delete_rsp_que(vha, rsp);
+ 			if (ret != QLA_SUCCESS) {
+ 				ql_log(ql_log_warn, vha, 0x00eb,
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 7462dd70b150..d00725574577 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -398,6 +398,9 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
+ 	int cnt;
+ 
+ 	for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
++		if (!test_bit(cnt, ha->req_qid_map))
++			continue;
++
+ 		req = ha->req_q_map[cnt];
+ 		qla2x00_free_req_que(ha, req);
+ 	}
+@@ -405,6 +408,9 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
+ 	ha->req_q_map = NULL;
+ 
+ 	for (cnt = 0; cnt < ha->max_rsp_queues; cnt++) {
++		if (!test_bit(cnt, ha->rsp_qid_map))
++			continue;
++
+ 		rsp = ha->rsp_q_map[cnt];
+ 		qla2x00_free_rsp_que(ha, rsp);
+ 	}
+@@ -3229,11 +3235,14 @@ qla2x00_schedule_rport_del(struct scsi_qla_host *vha, fc_port_t *fcport,
+ 		spin_lock_irqsave(vha->host->host_lock, flags);
+ 		fcport->drport = rport;
+ 		spin_unlock_irqrestore(vha->host->host_lock, flags);
++		qlt_do_generation_tick(vha, &base_vha->total_fcport_update_gen);
+ 		set_bit(FCPORT_UPDATE_NEEDED, &base_vha->dpc_flags);
+ 		qla2xxx_wake_dpc(base_vha);
+ 	} else {
++		int now;
+ 		fc_remote_port_delete(rport);
+-		qlt_fc_port_deleted(vha, fcport);
++		qlt_do_generation_tick(vha, &now);
++		qlt_fc_port_deleted(vha, fcport, now);
+ 	}
+ }
+ 
+@@ -3763,8 +3772,11 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
+ 	INIT_LIST_HEAD(&vha->vp_fcports);
+ 	INIT_LIST_HEAD(&vha->work_list);
+ 	INIT_LIST_HEAD(&vha->list);
++	INIT_LIST_HEAD(&vha->qla_cmd_list);
++	INIT_LIST_HEAD(&vha->qla_sess_op_cmd_list);
+ 
+ 	spin_lock_init(&vha->work_lock);
++	spin_lock_init(&vha->cmd_list_lock);
+ 
+ 	sprintf(vha->host_str, "%s_%ld", QLA2XXX_DRIVER_NAME, vha->host_no);
+ 	ql_dbg(ql_dbg_init, vha, 0x0041,
+diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c
+index 496a733d0ca3..df6193b48177 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -114,6 +114,10 @@ static void qlt_alloc_qfull_cmd(struct scsi_qla_host *vha,
+ 	struct atio_from_isp *atio, uint16_t status, int qfull);
+ static void qlt_disable_vha(struct scsi_qla_host *vha);
+ static void qlt_clear_tgt_db(struct qla_tgt *tgt);
++static void qlt_send_notify_ack(struct scsi_qla_host *vha,
++	struct imm_ntfy_from_isp *ntfy,
++	uint32_t add_flags, uint16_t resp_code, int resp_code_valid,
++	uint16_t srr_flags, uint16_t srr_reject_code, uint8_t srr_explan);
+ /*
+  * Global Variables
+  */
+@@ -123,6 +127,16 @@ static struct workqueue_struct *qla_tgt_wq;
+ static DEFINE_MUTEX(qla_tgt_mutex);
+ static LIST_HEAD(qla_tgt_glist);
+ 
++/* This API intentionally takes dest as a parameter, rather than returning
++ * int value to avoid caller forgetting to issue wmb() after the store */
++void qlt_do_generation_tick(struct scsi_qla_host *vha, int *dest)
++{
++	scsi_qla_host_t *base_vha = pci_get_drvdata(vha->hw->pdev);
++	*dest = atomic_inc_return(&base_vha->generation_tick);
++	/* memory barrier */
++	wmb();
++}
++
+ /* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list) */
+ static struct qla_tgt_sess *qlt_find_sess_by_port_name(
+ 	struct qla_tgt *tgt,
+@@ -382,14 +396,73 @@ static void qlt_free_session_done(struct work_struct *work)
+ 	struct qla_tgt *tgt = sess->tgt;
+ 	struct scsi_qla_host *vha = sess->vha;
+ 	struct qla_hw_data *ha = vha->hw;
++	unsigned long flags;
++	bool logout_started = false;
++	fc_port_t fcport;
++
++	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf084,
++		"%s: se_sess %p / sess %p from port %8phC loop_id %#04x"
++		" s_id %02x:%02x:%02x logout %d keep %d plogi %d\n",
++		__func__, sess->se_sess, sess, sess->port_name, sess->loop_id,
++		sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
++		sess->logout_on_delete, sess->keep_nport_handle,
++		sess->plogi_ack_needed);
+ 
+ 	BUG_ON(!tgt);
++
++	if (sess->logout_on_delete) {
++		int rc;
++
++		memset(&fcport, 0, sizeof(fcport));
++		fcport.loop_id = sess->loop_id;
++		fcport.d_id = sess->s_id;
++		memcpy(fcport.port_name, sess->port_name, WWN_SIZE);
++		fcport.vha = vha;
++		fcport.tgt_session = sess;
++
++		rc = qla2x00_post_async_logout_work(vha, &fcport, NULL);
++		if (rc != QLA_SUCCESS)
++			ql_log(ql_log_warn, vha, 0xf085,
++			       "Schedule logo failed sess %p rc %d\n",
++			       sess, rc);
++		else
++			logout_started = true;
++	}
++
+ 	/*
+ 	 * Release the target session for FC Nexus from fabric module code.
+ 	 */
+ 	if (sess->se_sess != NULL)
+ 		ha->tgt.tgt_ops->free_session(sess);
+ 
++	if (logout_started) {
++		bool traced = false;
++
++		while (!ACCESS_ONCE(sess->logout_completed)) {
++			if (!traced) {
++				ql_dbg(ql_dbg_tgt_mgt, vha, 0xf086,
++					"%s: waiting for sess %p logout\n",
++					__func__, sess);
++				traced = true;
++			}
++			msleep(100);
++		}
++
++		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf087,
++			"%s: sess %p logout completed\n",
++			__func__, sess);
++	}
++
++	spin_lock_irqsave(&ha->hardware_lock, flags);
++
++	if (sess->plogi_ack_needed)
++		qlt_send_notify_ack(vha, &sess->tm_iocb,
++				    0, 0, 0, 0, 0, 0);
++
++	list_del(&sess->sess_list_entry);
++
++	spin_unlock_irqrestore(&ha->hardware_lock, flags);
++
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf001,
+ 	    "Unregistration of sess %p finished\n", sess);
+ 
+@@ -410,9 +483,9 @@ void qlt_unreg_sess(struct qla_tgt_sess *sess)
+ 
+ 	vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
+ 
+-	list_del(&sess->sess_list_entry);
+-	if (sess->deleted)
+-		list_del(&sess->del_list_entry);
++	if (!list_empty(&sess->del_list_entry))
++		list_del_init(&sess->del_list_entry);
++	sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
+ 
+ 	INIT_WORK(&sess->free_work, qlt_free_session_done);
+ 	schedule_work(&sess->free_work);
+@@ -490,27 +563,38 @@ static void qlt_schedule_sess_for_deletion(struct qla_tgt_sess *sess,
+ 	struct qla_tgt *tgt = sess->tgt;
+ 	uint32_t dev_loss_tmo = tgt->ha->port_down_retry_count + 5;
+ 
+-	if (sess->deleted)
+-		return;
++	if (sess->deleted) {
++		/* Upgrade to unconditional deletion in case it was temporary */
++		if (immediate && sess->deleted == QLA_SESS_DELETION_PENDING)
++			list_del(&sess->del_list_entry);
++		else
++			return;
++	}
+ 
+ 	ql_dbg(ql_dbg_tgt, sess->vha, 0xe001,
+ 	    "Scheduling sess %p for deletion\n", sess);
+-	list_add_tail(&sess->del_list_entry, &tgt->del_sess_list);
+-	sess->deleted = 1;
+ 
+-	if (immediate)
++	if (immediate) {
+ 		dev_loss_tmo = 0;
++		sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
++		list_add(&sess->del_list_entry, &tgt->del_sess_list);
++	} else {
++		sess->deleted = QLA_SESS_DELETION_PENDING;
++		list_add_tail(&sess->del_list_entry, &tgt->del_sess_list);
++	}
+ 
+ 	sess->expires = jiffies + dev_loss_tmo * HZ;
+ 
+ 	ql_dbg(ql_dbg_tgt, sess->vha, 0xe048,
+-	    "qla_target(%d): session for port %8phC (loop ID %d) scheduled for "
+-	    "deletion in %u secs (expires: %lu) immed: %d\n",
+-	    sess->vha->vp_idx, sess->port_name, sess->loop_id, dev_loss_tmo,
+-	    sess->expires, immediate);
++	    "qla_target(%d): session for port %8phC (loop ID %d s_id %02x:%02x:%02x)"
++	    " scheduled for deletion in %u secs (expires: %lu) immed: %d, logout: %d, gen: %#x\n",
++	    sess->vha->vp_idx, sess->port_name, sess->loop_id,
++	    sess->s_id.b.domain, sess->s_id.b.area, sess->s_id.b.al_pa,
++	    dev_loss_tmo, sess->expires, immediate, sess->logout_on_delete,
++	    sess->generation);
+ 
+ 	if (immediate)
+-		schedule_delayed_work(&tgt->sess_del_work, 0);
++		mod_delayed_work(system_wq, &tgt->sess_del_work, 0);
+ 	else
+ 		schedule_delayed_work(&tgt->sess_del_work,
+ 		    sess->expires - jiffies);
+@@ -579,9 +663,9 @@ out_free_id_list:
+ /* ha->hardware_lock supposed to be held on entry */
+ static void qlt_undelete_sess(struct qla_tgt_sess *sess)
+ {
+-	BUG_ON(!sess->deleted);
++	BUG_ON(sess->deleted != QLA_SESS_DELETION_PENDING);
+ 
+-	list_del(&sess->del_list_entry);
++	list_del_init(&sess->del_list_entry);
+ 	sess->deleted = 0;
+ }
+ 
+@@ -600,7 +684,9 @@ static void qlt_del_sess_work_fn(struct delayed_work *work)
+ 		    del_list_entry);
+ 		elapsed = jiffies;
+ 		if (time_after_eq(elapsed, sess->expires)) {
+-			qlt_undelete_sess(sess);
++			/* No turning back */
++			list_del_init(&sess->del_list_entry);
++			sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
+ 
+ 			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf004,
+ 			    "Timeout: sess %p about to be deleted\n",
+@@ -644,6 +730,13 @@ static struct qla_tgt_sess *qlt_create_sess(
+ 			    fcport->d_id.b.al_pa, fcport->d_id.b.area,
+ 			    fcport->loop_id);
+ 
++			/* Cannot undelete at this point */
++			if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++				spin_unlock_irqrestore(&ha->hardware_lock,
++				    flags);
++				return NULL;
++			}
++
+ 			if (sess->deleted)
+ 				qlt_undelete_sess(sess);
+ 
+@@ -653,6 +746,9 @@ static struct qla_tgt_sess *qlt_create_sess(
+ 
+ 			if (sess->local && !local)
+ 				sess->local = 0;
++
++			qlt_do_generation_tick(vha, &sess->generation);
++
+ 			spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ 
+ 			return sess;
+@@ -674,6 +770,14 @@ static struct qla_tgt_sess *qlt_create_sess(
+ 	sess->s_id = fcport->d_id;
+ 	sess->loop_id = fcport->loop_id;
+ 	sess->local = local;
++	INIT_LIST_HEAD(&sess->del_list_entry);
++
++	/* Under normal circumstances we want to logout from firmware when
++	 * session eventually ends and release corresponding nport handle.
++	 * In the exception cases (e.g. when new PLOGI is waiting) corresponding
++	 * code will adjust these flags as necessary. */
++	sess->logout_on_delete = 1;
++	sess->keep_nport_handle = 0;
+ 
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf006,
+ 	    "Adding sess %p to tgt %p via ->check_initiator_node_acl()\n",
+@@ -706,6 +810,7 @@ static struct qla_tgt_sess *qlt_create_sess(
+ 	spin_lock_irqsave(&ha->hardware_lock, flags);
+ 	list_add_tail(&sess->sess_list_entry, &vha->vha_tgt.qla_tgt->sess_list);
+ 	vha->vha_tgt.qla_tgt->sess_count++;
++	qlt_do_generation_tick(vha, &sess->generation);
+ 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ 
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf04b,
+@@ -719,7 +824,7 @@ static struct qla_tgt_sess *qlt_create_sess(
+ }
+ 
+ /*
+- * Called from drivers/scsi/qla2xxx/qla_init.c:qla2x00_reg_remote_port()
++ * Called from qla2x00_reg_remote_port()
+  */
+ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
+ {
+@@ -751,6 +856,10 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
+ 		mutex_unlock(&vha->vha_tgt.tgt_mutex);
+ 
+ 		spin_lock_irqsave(&ha->hardware_lock, flags);
++	} else if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++		/* Point of no return */
++		spin_unlock_irqrestore(&ha->hardware_lock, flags);
++		return;
+ 	} else {
+ 		kref_get(&sess->se_sess->sess_kref);
+ 
+@@ -781,7 +890,12 @@ void qlt_fc_port_added(struct scsi_qla_host *vha, fc_port_t *fcport)
+ 	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+ }
+ 
+-void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
++/*
++ * max_gen - specifies maximum session generation
++ * at which this deletion requestion is still valid
++ */
++void
++qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport, int max_gen)
+ {
+ 	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
+ 	struct qla_tgt_sess *sess;
+@@ -800,6 +914,15 @@ void qlt_fc_port_deleted(struct scsi_qla_host *vha, fc_port_t *fcport)
+ 		return;
+ 	}
+ 
++	if (max_gen - sess->generation < 0) {
++		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf092,
++		    "Ignoring stale deletion request for se_sess %p / sess %p"
++		    " for port %8phC, req_gen %d, sess_gen %d\n",
++		    sess->se_sess, sess, sess->port_name, max_gen,
++		    sess->generation);
++		return;
++	}
++
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf008, "qla_tgt_fc_port_deleted %p", sess);
+ 
+ 	sess->local = 1;
+@@ -1170,6 +1293,70 @@ static void qlt_24xx_retry_term_exchange(struct scsi_qla_host *vha,
+ 	    FCP_TMF_CMPL, true);
+ }
+ 
++static int abort_cmd_for_tag(struct scsi_qla_host *vha, uint32_t tag)
++{
++	struct qla_tgt_sess_op *op;
++	struct qla_tgt_cmd *cmd;
++
++	spin_lock(&vha->cmd_list_lock);
++
++	list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
++		if (tag == op->atio.u.isp24.exchange_addr) {
++			op->aborted = true;
++			spin_unlock(&vha->cmd_list_lock);
++			return 1;
++		}
++	}
++
++	list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
++		if (tag == cmd->atio.u.isp24.exchange_addr) {
++			cmd->state = QLA_TGT_STATE_ABORTED;
++			spin_unlock(&vha->cmd_list_lock);
++			return 1;
++		}
++	}
++
++	spin_unlock(&vha->cmd_list_lock);
++	return 0;
++}
++
++/* drop cmds for the given lun
++ * XXX only looks for cmds on the port through which lun reset was recieved
++ * XXX does not go through the list of other port (which may have cmds
++ *     for the same lun)
++ */
++static void abort_cmds_for_lun(struct scsi_qla_host *vha,
++				uint32_t lun, uint8_t *s_id)
++{
++	struct qla_tgt_sess_op *op;
++	struct qla_tgt_cmd *cmd;
++	uint32_t key;
++
++	key = sid_to_key(s_id);
++	spin_lock(&vha->cmd_list_lock);
++	list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
++		uint32_t op_key;
++		uint32_t op_lun;
++
++		op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
++		op_lun = scsilun_to_int(
++			(struct scsi_lun *)&op->atio.u.isp24.fcp_cmnd.lun);
++		if (op_key == key && op_lun == lun)
++			op->aborted = true;
++	}
++	list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
++		uint32_t cmd_key;
++		uint32_t cmd_lun;
++
++		cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
++		cmd_lun = scsilun_to_int(
++			(struct scsi_lun *)&cmd->atio.u.isp24.fcp_cmnd.lun);
++		if (cmd_key == key && cmd_lun == lun)
++			cmd->state = QLA_TGT_STATE_ABORTED;
++	}
++	spin_unlock(&vha->cmd_list_lock);
++}
++
+ /* ha->hardware_lock supposed to be held on entry */
+ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
+ 	struct abts_recv_from_24xx *abts, struct qla_tgt_sess *sess)
+@@ -1194,8 +1381,19 @@ static int __qlt_24xx_handle_abts(struct scsi_qla_host *vha,
+ 	}
+ 	spin_unlock(&se_sess->sess_cmd_lock);
+ 
+-	if (!found_lun)
+-		return -ENOENT;
++	/* cmd not in LIO lists, look in qla list */
++	if (!found_lun) {
++		if (abort_cmd_for_tag(vha, abts->exchange_addr_to_abort)) {
++			/* send TASK_ABORT response immediately */
++			qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_CMPL, false);
++			return 0;
++		} else {
++			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf081,
++			    "unable to find cmd in driver or LIO for tag 0x%x\n",
++			    abts->exchange_addr_to_abort);
++			return -ENOENT;
++		}
++	}
+ 
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf00f,
+ 	    "qla_target(%d): task abort (tag=%d)\n",
+@@ -1279,6 +1477,11 @@ static void qlt_24xx_handle_abts(struct scsi_qla_host *vha,
+ 		return;
+ 	}
+ 
++	if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++		qlt_24xx_send_abts_resp(vha, abts, FCP_TMF_REJECTED, false);
++		return;
++	}
++
+ 	rc = __qlt_24xx_handle_abts(vha, abts, sess);
+ 	if (rc != 0) {
+ 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf054,
+@@ -1721,21 +1924,6 @@ static int qlt_pre_xmit_response(struct qla_tgt_cmd *cmd,
+ 	struct qla_hw_data *ha = vha->hw;
+ 	struct se_cmd *se_cmd = &cmd->se_cmd;
+ 
+-	if (unlikely(cmd->aborted)) {
+-		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
+-		    "qla_target(%d): terminating exchange "
+-		    "for aborted cmd=%p (se_cmd=%p, tag=%d)", vha->vp_idx, cmd,
+-		    se_cmd, cmd->tag);
+-
+-		cmd->state = QLA_TGT_STATE_ABORTED;
+-		cmd->cmd_flags |= BIT_6;
+-
+-		qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
+-
+-		/* !! At this point cmd could be already freed !! */
+-		return QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED;
+-	}
+-
+ 	prm->cmd = cmd;
+ 	prm->tgt = tgt;
+ 	prm->rq_result = scsi_status;
+@@ -2298,6 +2486,19 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
+ 	unsigned long flags = 0;
+ 	int res;
+ 
++	spin_lock_irqsave(&ha->hardware_lock, flags);
++	if (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++		cmd->state = QLA_TGT_STATE_PROCESSED;
++		if (cmd->sess->logout_completed)
++			/* no need to terminate. FW already freed exchange. */
++			qlt_abort_cmd_on_host_reset(cmd->vha, cmd);
++		else
++			qlt_send_term_exchange(vha, cmd, &cmd->atio, 1);
++		spin_unlock_irqrestore(&ha->hardware_lock, flags);
++		return 0;
++	}
++	spin_unlock_irqrestore(&ha->hardware_lock, flags);
++
+ 	memset(&prm, 0, sizeof(prm));
+ 	qlt_check_srr_debug(cmd, &xmit_type);
+ 
+@@ -2310,9 +2511,6 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
+ 	res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
+ 	    &full_req_cnt);
+ 	if (unlikely(res != 0)) {
+-		if (res == QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED)
+-			return 0;
+-
+ 		return res;
+ 	}
+ 
+@@ -2459,7 +2657,8 @@ int qlt_rdy_to_xfer(struct qla_tgt_cmd *cmd)
+ 
+ 	spin_lock_irqsave(&ha->hardware_lock, flags);
+ 
+-	if (qla2x00_reset_active(vha) || cmd->reset_count != ha->chip_reset) {
++	if (qla2x00_reset_active(vha) || (cmd->reset_count != ha->chip_reset) ||
++	    (cmd->sess && cmd->sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)) {
+ 		/*
+ 		 * Either a chip reset is active or this request was from
+ 		 * previous life, just abort the processing.
+@@ -2652,6 +2851,89 @@ out:
+ 
+ /* If hardware_lock held on entry, might drop it, then reaquire */
+ /* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
++static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha,
++	struct imm_ntfy_from_isp *ntfy)
++{
++	struct nack_to_isp *nack;
++	struct qla_hw_data *ha = vha->hw;
++	request_t *pkt;
++	int ret = 0;
++
++	ql_dbg(ql_dbg_tgt_tmr, vha, 0xe01c,
++	    "Sending TERM ELS CTIO (ha=%p)\n", ha);
++
++	pkt = (request_t *)qla2x00_alloc_iocbs_ready(vha, NULL);
++	if (pkt == NULL) {
++		ql_dbg(ql_dbg_tgt, vha, 0xe080,
++		    "qla_target(%d): %s failed: unable to allocate "
++		    "request packet\n", vha->vp_idx, __func__);
++		return -ENOMEM;
++	}
++
++	pkt->entry_type = NOTIFY_ACK_TYPE;
++	pkt->entry_count = 1;
++	pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK;
++
++	nack = (struct nack_to_isp *)pkt;
++	nack->ox_id = ntfy->ox_id;
++
++	nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle;
++	if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) {
++		nack->u.isp24.flags = ntfy->u.isp24.flags &
++			__constant_cpu_to_le32(NOTIFY24XX_FLAGS_PUREX_IOCB);
++	}
++
++	/* terminate */
++	nack->u.isp24.flags |=
++		__constant_cpu_to_le16(NOTIFY_ACK_FLAGS_TERMINATE);
++
++	nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id;
++	nack->u.isp24.status = ntfy->u.isp24.status;
++	nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode;
++	nack->u.isp24.fw_handle = ntfy->u.isp24.fw_handle;
++	nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address;
++	nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs;
++	nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui;
++	nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
++
++	qla2x00_start_iocbs(vha, vha->req);
++	return ret;
++}
++
++static void qlt_send_term_imm_notif(struct scsi_qla_host *vha,
++	struct imm_ntfy_from_isp *imm, int ha_locked)
++{
++	unsigned long flags = 0;
++	int rc;
++
++	if (qlt_issue_marker(vha, ha_locked) < 0)
++		return;
++
++	if (ha_locked) {
++		rc = __qlt_send_term_imm_notif(vha, imm);
++
++#if 0	/* Todo  */
++		if (rc == -ENOMEM)
++			qlt_alloc_qfull_cmd(vha, imm, 0, 0);
++#endif
++		goto done;
++	}
++
++	spin_lock_irqsave(&vha->hw->hardware_lock, flags);
++	rc = __qlt_send_term_imm_notif(vha, imm);
++
++#if 0	/* Todo */
++	if (rc == -ENOMEM)
++		qlt_alloc_qfull_cmd(vha, imm, 0, 0);
++#endif
++
++done:
++	if (!ha_locked)
++		spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
++}
++
++/* If hardware_lock held on entry, might drop it, then reaquire */
++/* This function sends the appropriate CTIO to ISP 2xxx or 24xx */
+ static int __qlt_send_term_exchange(struct scsi_qla_host *vha,
+ 	struct qla_tgt_cmd *cmd,
+ 	struct atio_from_isp *atio)
+@@ -2794,6 +3076,24 @@ static void qlt_chk_exch_leak_thresh_hold(struct scsi_qla_host *vha)
+ 
+ }
+ 
++void qlt_abort_cmd(struct qla_tgt_cmd *cmd)
++{
++	struct qla_tgt *tgt = cmd->tgt;
++	struct scsi_qla_host *vha = tgt->vha;
++	struct se_cmd *se_cmd = &cmd->se_cmd;
++
++	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf014,
++	    "qla_target(%d): terminating exchange for aborted cmd=%p "
++	    "(se_cmd=%p, tag=%llu)", vha->vp_idx, cmd, &cmd->se_cmd,
++	    cmd->tag);
++
++	cmd->state = QLA_TGT_STATE_ABORTED;
++	cmd->cmd_flags |= BIT_6;
++
++	qlt_send_term_exchange(vha, cmd, &cmd->atio, 0);
++}
++EXPORT_SYMBOL(qlt_abort_cmd);
++
+ void qlt_free_cmd(struct qla_tgt_cmd *cmd)
+ {
+ 	struct qla_tgt_sess *sess = cmd->sess;
+@@ -3265,6 +3565,13 @@ static void __qlt_do_work(struct qla_tgt_cmd *cmd)
+ 	if (tgt->tgt_stop)
+ 		goto out_term;
+ 
++	if (cmd->state == QLA_TGT_STATE_ABORTED) {
++		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf082,
++		    "cmd with tag %u is aborted\n",
++		    cmd->atio.u.isp24.exchange_addr);
++		goto out_term;
++	}
++
+ 	cdb = &atio->u.isp24.fcp_cmnd.cdb[0];
+ 	cmd->tag = atio->u.isp24.exchange_addr;
+ 	cmd->unpacked_lun = scsilun_to_int(
+@@ -3318,6 +3625,12 @@ out_term:
+ static void qlt_do_work(struct work_struct *work)
+ {
+ 	struct qla_tgt_cmd *cmd = container_of(work, struct qla_tgt_cmd, work);
++	scsi_qla_host_t *vha = cmd->vha;
++	unsigned long flags;
++
++	spin_lock_irqsave(&vha->cmd_list_lock, flags);
++	list_del(&cmd->cmd_list);
++	spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
+ 
+ 	__qlt_do_work(cmd);
+ }
+@@ -3369,14 +3682,25 @@ static void qlt_create_sess_from_atio(struct work_struct *work)
+ 	unsigned long flags;
+ 	uint8_t *s_id = op->atio.u.isp24.fcp_hdr.s_id;
+ 
++	spin_lock_irqsave(&vha->cmd_list_lock, flags);
++	list_del(&op->cmd_list);
++	spin_unlock_irqrestore(&vha->cmd_list_lock, flags);
++
++	if (op->aborted) {
++		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf083,
++		    "sess_op with tag %u is aborted\n",
++		    op->atio.u.isp24.exchange_addr);
++		goto out_term;
++	}
++
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf022,
+-		"qla_target(%d): Unable to find wwn login"
+-		" (s_id %x:%x:%x), trying to create it manually\n",
+-		vha->vp_idx, s_id[0], s_id[1], s_id[2]);
++	    "qla_target(%d): Unable to find wwn login"
++	    " (s_id %x:%x:%x), trying to create it manually\n",
++	    vha->vp_idx, s_id[0], s_id[1], s_id[2]);
+ 
+ 	if (op->atio.u.raw.entry_count > 1) {
+ 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf023,
+-		        "Dropping multy entry atio %p\n", &op->atio);
++		    "Dropping multy entry atio %p\n", &op->atio);
+ 		goto out_term;
+ 	}
+ 
+@@ -3441,10 +3765,25 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
+ 
+ 		memcpy(&op->atio, atio, sizeof(*atio));
+ 		op->vha = vha;
++
++		spin_lock(&vha->cmd_list_lock);
++		list_add_tail(&op->cmd_list, &vha->qla_sess_op_cmd_list);
++		spin_unlock(&vha->cmd_list_lock);
++
+ 		INIT_WORK(&op->work, qlt_create_sess_from_atio);
+ 		queue_work(qla_tgt_wq, &op->work);
+ 		return 0;
+ 	}
++
++	/* Another WWN used to have our s_id. Our PLOGI scheduled its
++	 * session deletion, but it's still in sess_del_work wq */
++	if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++		ql_dbg(ql_dbg_io, vha, 0x3061,
++		    "New command while old session %p is being deleted\n",
++		    sess);
++		return -EFAULT;
++	}
++
+ 	/*
+ 	 * Do kref_get() before returning + dropping qla_hw_data->hardware_lock.
+ 	 */
+@@ -3460,6 +3799,11 @@ static int qlt_handle_cmd_for_atio(struct scsi_qla_host *vha,
+ 
+ 	cmd->cmd_in_wq = 1;
+ 	cmd->cmd_flags |= BIT_0;
++
++	spin_lock(&vha->cmd_list_lock);
++	list_add_tail(&cmd->cmd_list, &vha->qla_cmd_list);
++	spin_unlock(&vha->cmd_list_lock);
++
+ 	INIT_WORK(&cmd->work, qlt_do_work);
+ 	queue_work(qla_tgt_wq, &cmd->work);
+ 	return 0;
+@@ -3473,6 +3817,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
+ 	struct scsi_qla_host *vha = sess->vha;
+ 	struct qla_hw_data *ha = vha->hw;
+ 	struct qla_tgt_mgmt_cmd *mcmd;
++	struct atio_from_isp *a = (struct atio_from_isp *)iocb;
+ 	int res;
+ 	uint8_t tmr_func;
+ 
+@@ -3513,6 +3858,7 @@ static int qlt_issue_task_mgmt(struct qla_tgt_sess *sess, uint32_t lun,
+ 		ql_dbg(ql_dbg_tgt_tmr, vha, 0x10002,
+ 		    "qla_target(%d): LUN_RESET received\n", sess->vha->vp_idx);
+ 		tmr_func = TMR_LUN_RESET;
++		abort_cmds_for_lun(vha, lun, a->u.isp24.fcp_hdr.s_id);
+ 		break;
+ 
+ 	case QLA_TGT_CLEAR_TS:
+@@ -3601,6 +3947,9 @@ static int qlt_handle_task_mgmt(struct scsi_qla_host *vha, void *iocb)
+ 		    sizeof(struct atio_from_isp));
+ 	}
+ 
++	if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS)
++		return -EFAULT;
++
+ 	return qlt_issue_task_mgmt(sess, unpacked_lun, fn, iocb, 0);
+ }
+ 
+@@ -3666,22 +4015,280 @@ static int qlt_abort_task(struct scsi_qla_host *vha,
+ 	return __qlt_abort_task(vha, iocb, sess);
+ }
+ 
++void qlt_logo_completion_handler(fc_port_t *fcport, int rc)
++{
++	if (fcport->tgt_session) {
++		if (rc != MBS_COMMAND_COMPLETE) {
++			ql_dbg(ql_dbg_tgt_mgt, fcport->vha, 0xf093,
++				"%s: se_sess %p / sess %p from"
++				" port %8phC loop_id %#04x s_id %02x:%02x:%02x"
++				" LOGO failed: %#x\n",
++				__func__,
++				fcport->tgt_session->se_sess,
++				fcport->tgt_session,
++				fcport->port_name, fcport->loop_id,
++				fcport->d_id.b.domain, fcport->d_id.b.area,
++				fcport->d_id.b.al_pa, rc);
++		}
++
++		fcport->tgt_session->logout_completed = 1;
++	}
++}
++
++static void qlt_swap_imm_ntfy_iocb(struct imm_ntfy_from_isp *a,
++    struct imm_ntfy_from_isp *b)
++{
++	struct imm_ntfy_from_isp tmp;
++	memcpy(&tmp, a, sizeof(struct imm_ntfy_from_isp));
++	memcpy(a, b, sizeof(struct imm_ntfy_from_isp));
++	memcpy(b, &tmp, sizeof(struct imm_ntfy_from_isp));
++}
++
++/*
++* ha->hardware_lock supposed to be held on entry (to protect tgt->sess_list)
++*
++* Schedules sessions with matching port_id/loop_id but different wwn for
++* deletion. Returns existing session with matching wwn if present.
++* Null otherwise.
++*/
++static struct qla_tgt_sess *
++qlt_find_sess_invalidate_other(struct qla_tgt *tgt, uint64_t wwn,
++    port_id_t port_id, uint16_t loop_id)
++{
++	struct qla_tgt_sess *sess = NULL, *other_sess;
++	uint64_t other_wwn;
++
++	list_for_each_entry(other_sess, &tgt->sess_list, sess_list_entry) {
++
++		other_wwn = wwn_to_u64(other_sess->port_name);
++
++		if (wwn == other_wwn) {
++			WARN_ON(sess);
++			sess = other_sess;
++			continue;
++		}
++
++		/* find other sess with nport_id collision */
++		if (port_id.b24 == other_sess->s_id.b24) {
++			if (loop_id != other_sess->loop_id) {
++				ql_dbg(ql_dbg_tgt_tmr, tgt->vha, 0x1000c,
++				    "Invalidating sess %p loop_id %d wwn %llx.\n",
++				    other_sess, other_sess->loop_id, other_wwn);
++
++				/*
++				 * logout_on_delete is set by default, but another
++				 * session that has the same s_id/loop_id combo
++				 * might have cleared it when requested this session
++				 * deletion, so don't touch it
++				 */
++				qlt_schedule_sess_for_deletion(other_sess, true);
++			} else {
++				/*
++				 * Another wwn used to have our s_id/loop_id
++				 * combo - kill the session, but don't log out
++				 */
++				sess->logout_on_delete = 0;
++				qlt_schedule_sess_for_deletion(other_sess,
++				    true);
++			}
++			continue;
++		}
++
++		/* find other sess with nport handle collision */
++		if (loop_id == other_sess->loop_id) {
++			ql_dbg(ql_dbg_tgt_tmr, tgt->vha, 0x1000d,
++			       "Invalidating sess %p loop_id %d wwn %llx.\n",
++			       other_sess, other_sess->loop_id, other_wwn);
++
++			/* Same loop_id but different s_id
++			 * Ok to kill and logout */
++			qlt_schedule_sess_for_deletion(other_sess, true);
++		}
++	}
++
++	return sess;
++}
++
++/* Abort any commands for this s_id waiting on qla_tgt_wq workqueue */
++static int abort_cmds_for_s_id(struct scsi_qla_host *vha, port_id_t *s_id)
++{
++	struct qla_tgt_sess_op *op;
++	struct qla_tgt_cmd *cmd;
++	uint32_t key;
++	int count = 0;
++
++	key = (((u32)s_id->b.domain << 16) |
++	       ((u32)s_id->b.area   <<  8) |
++	       ((u32)s_id->b.al_pa));
++
++	spin_lock(&vha->cmd_list_lock);
++	list_for_each_entry(op, &vha->qla_sess_op_cmd_list, cmd_list) {
++		uint32_t op_key = sid_to_key(op->atio.u.isp24.fcp_hdr.s_id);
++		if (op_key == key) {
++			op->aborted = true;
++			count++;
++		}
++	}
++	list_for_each_entry(cmd, &vha->qla_cmd_list, cmd_list) {
++		uint32_t cmd_key = sid_to_key(cmd->atio.u.isp24.fcp_hdr.s_id);
++		if (cmd_key == key) {
++			cmd->state = QLA_TGT_STATE_ABORTED;
++			count++;
++		}
++	}
++	spin_unlock(&vha->cmd_list_lock);
++
++	return count;
++}
++
+ /*
+  * ha->hardware_lock supposed to be held on entry. Might drop it, then reaquire
+  */
+ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
+ 	struct imm_ntfy_from_isp *iocb)
+ {
++	struct qla_tgt *tgt = vha->vha_tgt.qla_tgt;
++	struct qla_hw_data *ha = vha->hw;
++	struct qla_tgt_sess *sess = NULL;
++	uint64_t wwn;
++	port_id_t port_id;
++	uint16_t loop_id;
++	uint16_t wd3_lo;
+ 	int res = 0;
+ 
++	wwn = wwn_to_u64(iocb->u.isp24.port_name);
++
++	port_id.b.domain = iocb->u.isp24.port_id[2];
++	port_id.b.area   = iocb->u.isp24.port_id[1];
++	port_id.b.al_pa  = iocb->u.isp24.port_id[0];
++	port_id.b.rsvd_1 = 0;
++
++	loop_id = le16_to_cpu(iocb->u.isp24.nport_handle);
++
+ 	ql_dbg(ql_dbg_tgt_mgt, vha, 0xf026,
+ 	    "qla_target(%d): Port ID: 0x%3phC ELS opcode: 0x%02x\n",
+ 	    vha->vp_idx, iocb->u.isp24.port_id, iocb->u.isp24.status_subcode);
+ 
++	/* res = 1 means ack at the end of thread
++	 * res = 0 means ack async/later.
++	 */
+ 	switch (iocb->u.isp24.status_subcode) {
+ 	case ELS_PLOGI:
+-	case ELS_FLOGI:
++
++		/* Mark all stale commands in qla_tgt_wq for deletion */
++		abort_cmds_for_s_id(vha, &port_id);
++
++		if (wwn)
++			sess = qlt_find_sess_invalidate_other(tgt, wwn,
++			    port_id, loop_id);
++
++		if (!sess || IS_SW_RESV_ADDR(sess->s_id)) {
++			res = 1;
++			break;
++		}
++
++		if (sess->plogi_ack_needed) {
++			/*
++			 * Initiator sent another PLOGI before last PLOGI could
++			 * finish. Swap plogi iocbs and terminate old one
++			 * without acking, new one will get acked when session
++			 * deletion completes.
++			 */
++			ql_log(ql_log_warn, sess->vha, 0xf094,
++			    "sess %p received double plogi.\n", sess);
++
++			qlt_swap_imm_ntfy_iocb(iocb, &sess->tm_iocb);
++
++			qlt_send_term_imm_notif(vha, iocb, 1);
++
++			res = 0;
++			break;
++		}
++
++		res = 0;
++
++		/*
++		 * Save immediate Notif IOCB for Ack when sess is done
++		 * and being deleted.
++		 */
++		memcpy(&sess->tm_iocb, iocb, sizeof(sess->tm_iocb));
++		sess->plogi_ack_needed  = 1;
++
++		 /*
++		  * Under normal circumstances we want to release nport handle
++		  * during LOGO process to avoid nport handle leaks inside FW.
++		  * The exception is when LOGO is done while another PLOGI with
++		  * the same nport handle is waiting as might be the case here.
++		  * Note: there is always a possibily of a race where session
++		  * deletion has already started for other reasons (e.g. ACL
++		  * removal) and now PLOGI arrives:
++		  * 1. if PLOGI arrived in FW after nport handle has been freed,
++		  *    FW must have assigned this PLOGI a new/same handle and we
++		  *    can proceed ACK'ing it as usual when session deletion
++		  *    completes.
++		  * 2. if PLOGI arrived in FW before LOGO with LCF_FREE_NPORT
++		  *    bit reached it, the handle has now been released. We'll
++		  *    get an error when we ACK this PLOGI. Nothing will be sent
++		  *    back to initiator. Initiator should eventually retry
++		  *    PLOGI and situation will correct itself.
++		  */
++		sess->keep_nport_handle = ((sess->loop_id == loop_id) &&
++					   (sess->s_id.b24 == port_id.b24));
++		qlt_schedule_sess_for_deletion(sess, true);
++		break;
++
+ 	case ELS_PRLI:
++		wd3_lo = le16_to_cpu(iocb->u.isp24.u.prli.wd3_lo);
++
++		if (wwn)
++			sess = qlt_find_sess_invalidate_other(tgt, wwn, port_id,
++			    loop_id);
++
++		if (sess != NULL) {
++			if (sess->deleted) {
++				/*
++				 * Impatient initiator sent PRLI before last
++				 * PLOGI could finish. Will force him to re-try,
++				 * while last one finishes.
++				 */
++				ql_log(ql_log_warn, sess->vha, 0xf095,
++				    "sess %p PRLI received, before plogi ack.\n",
++				    sess);
++				qlt_send_term_imm_notif(vha, iocb, 1);
++				res = 0;
++				break;
++			}
++
++			/*
++			 * This shouldn't happen under normal circumstances,
++			 * since we have deleted the old session during PLOGI
++			 */
++			ql_dbg(ql_dbg_tgt_mgt, vha, 0xf096,
++			    "PRLI (loop_id %#04x) for existing sess %p (loop_id %#04x)\n",
++			    sess->loop_id, sess, iocb->u.isp24.nport_handle);
++
++			sess->local = 0;
++			sess->loop_id = loop_id;
++			sess->s_id = port_id;
++
++			if (wd3_lo & BIT_7)
++				sess->conf_compl_supported = 1;
++
++		}
++		res = 1; /* send notify ack */
++
++		/* Make session global (not used in fabric mode) */
++		if (ha->current_topology != ISP_CFG_F) {
++			set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags);
++			set_bit(LOCAL_LOOP_UPDATE, &vha->dpc_flags);
++			qla2xxx_wake_dpc(vha);
++		} else {
++			/* todo: else - create sess here. */
++			res = 1; /* send notify ack */
++		}
++
++		break;
++
+ 	case ELS_LOGO:
+ 	case ELS_PRLO:
+ 		res = qlt_reset(vha, iocb, QLA_TGT_NEXUS_LOSS_SESS);
+@@ -3699,6 +4306,7 @@ static int qlt_24xx_handle_els(struct scsi_qla_host *vha,
+ 		break;
+ 	}
+ 
++	case ELS_FLOGI:	/* should never happen */
+ 	default:
+ 		ql_dbg(ql_dbg_tgt_mgt, vha, 0xf061,
+ 		    "qla_target(%d): Unsupported ELS command %x "
+@@ -5016,6 +5624,11 @@ static void qlt_abort_work(struct qla_tgt *tgt,
+ 		if (!sess)
+ 			goto out_term;
+ 	} else {
++		if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++			sess = NULL;
++			goto out_term;
++		}
++
+ 		kref_get(&sess->se_sess->sess_kref);
+ 	}
+ 
+@@ -5070,6 +5683,11 @@ static void qlt_tmr_work(struct qla_tgt *tgt,
+ 		if (!sess)
+ 			goto out_term;
+ 	} else {
++		if (sess->deleted == QLA_SESS_DELETION_IN_PROGRESS) {
++			sess = NULL;
++			goto out_term;
++		}
++
+ 		kref_get(&sess->se_sess->sess_kref);
+ 	}
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h
+index 332086776dfe..d30c60a1d522 100644
+--- a/drivers/scsi/qla2xxx/qla_target.h
++++ b/drivers/scsi/qla2xxx/qla_target.h
+@@ -167,7 +167,24 @@ struct imm_ntfy_from_isp {
+ 			uint32_t srr_rel_offs;
+ 			uint16_t srr_ui;
+ 			uint16_t srr_ox_id;
+-			uint8_t  reserved_4[19];
++			union {
++				struct {
++					uint8_t node_name[8];
++				} plogi; /* PLOGI/ADISC/PDISC */
++				struct {
++					/* PRLI word 3 bit 0-15 */
++					uint16_t wd3_lo;
++					uint8_t resv0[6];
++				} prli;
++				struct {
++					uint8_t port_id[3];
++					uint8_t resv1;
++					uint16_t nport_handle;
++					uint16_t resv2;
++				} req_els;
++			} u;
++			uint8_t port_name[8];
++			uint8_t resv3[3];
+ 			uint8_t  vp_index;
+ 			uint32_t reserved_5;
+ 			uint8_t  port_id[3];
+@@ -234,6 +251,7 @@ struct nack_to_isp {
+ 	uint8_t  reserved[2];
+ 	uint16_t ox_id;
+ } __packed;
++#define NOTIFY_ACK_FLAGS_TERMINATE	BIT_3
+ #define NOTIFY_ACK_SRR_FLAGS_ACCEPT	0
+ #define NOTIFY_ACK_SRR_FLAGS_REJECT	1
+ 
+@@ -790,13 +808,6 @@ int qla2x00_wait_for_hba_online(struct scsi_qla_host *);
+ #define	FC_TM_REJECT                4
+ #define FC_TM_FAILED                5
+ 
+-/*
+- * Error code of qlt_pre_xmit_response() meaning that cmd's exchange was
+- * terminated, so no more actions is needed and success should be returned
+- * to target.
+- */
+-#define QLA_TGT_PRE_XMIT_RESP_CMD_ABORTED	0x1717
+-
+ #if (BITS_PER_LONG > 32) || defined(CONFIG_HIGHMEM64G)
+ #define pci_dma_lo32(a) (a & 0xffffffff)
+ #define pci_dma_hi32(a) ((((a) >> 16)>>16) & 0xffffffff)
+@@ -874,6 +885,15 @@ struct qla_tgt_sess_op {
+ 	struct scsi_qla_host *vha;
+ 	struct atio_from_isp atio;
+ 	struct work_struct work;
++	struct list_head cmd_list;
++	bool aborted;
++};
++
++enum qla_sess_deletion {
++	QLA_SESS_DELETION_NONE		= 0,
++	QLA_SESS_DELETION_PENDING	= 1, /* hopefully we can get rid of
++					      * this one */
++	QLA_SESS_DELETION_IN_PROGRESS	= 2,
+ };
+ 
+ /*
+@@ -884,8 +904,15 @@ struct qla_tgt_sess {
+ 	port_id_t s_id;
+ 
+ 	unsigned int conf_compl_supported:1;
+-	unsigned int deleted:1;
++	unsigned int deleted:2;
+ 	unsigned int local:1;
++	unsigned int logout_on_delete:1;
++	unsigned int plogi_ack_needed:1;
++	unsigned int keep_nport_handle:1;
++
++	unsigned char logout_completed;
++
++	int generation;
+ 
+ 	struct se_session *se_sess;
+ 	struct scsi_qla_host *vha;
+@@ -897,6 +924,10 @@ struct qla_tgt_sess {
+ 
+ 	uint8_t port_name[WWN_SIZE];
+ 	struct work_struct free_work;
++
++	union {
++		struct imm_ntfy_from_isp tm_iocb;
++	};
+ };
+ 
+ struct qla_tgt_cmd {
+@@ -912,7 +943,6 @@ struct qla_tgt_cmd {
+ 	unsigned int conf_compl_supported:1;
+ 	unsigned int sg_mapped:1;
+ 	unsigned int free_sg:1;
+-	unsigned int aborted:1; /* Needed in case of SRR */
+ 	unsigned int write_data_transferred:1;
+ 	unsigned int ctx_dsd_alloced:1;
+ 	unsigned int q_full:1;
+@@ -1027,6 +1057,10 @@ struct qla_tgt_srr_ctio {
+ 	struct qla_tgt_cmd *cmd;
+ };
+ 
++/* Check for Switch reserved address */
++#define IS_SW_RESV_ADDR(_s_id) \
++	((_s_id.b.domain == 0xff) && (_s_id.b.area == 0xfc))
++
+ #define QLA_TGT_XMIT_DATA		1
+ #define QLA_TGT_XMIT_STATUS		2
+ #define QLA_TGT_XMIT_ALL		(QLA_TGT_XMIT_STATUS|QLA_TGT_XMIT_DATA)
+@@ -1044,7 +1078,7 @@ extern int qlt_lport_register(void *, u64, u64, u64,
+ extern void qlt_lport_deregister(struct scsi_qla_host *);
+ extern void qlt_unreg_sess(struct qla_tgt_sess *);
+ extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);
+-extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *);
++extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int);
+ extern int __init qlt_init(void);
+ extern void qlt_exit(void);
+ extern void qlt_update_vp_map(struct scsi_qla_host *, int);
+@@ -1074,12 +1108,23 @@ static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha)
+ 		ha->host->active_mode |= MODE_INITIATOR;
+ }
+ 
++static inline uint32_t sid_to_key(const uint8_t *s_id)
++{
++	uint32_t key;
++
++	key = (((unsigned long)s_id[0] << 16) |
++	       ((unsigned long)s_id[1] << 8) |
++	       (unsigned long)s_id[2]);
++	return key;
++}
++
+ /*
+  * Exported symbols from qla_target.c LLD logic used by qla2xxx code..
+  */
+ extern void qlt_response_pkt_all_vps(struct scsi_qla_host *, response_t *);
+ extern int qlt_rdy_to_xfer(struct qla_tgt_cmd *);
+ extern int qlt_xmit_response(struct qla_tgt_cmd *, int, uint8_t);
++extern void qlt_abort_cmd(struct qla_tgt_cmd *);
+ extern void qlt_xmit_tm_rsp(struct qla_tgt_mgmt_cmd *);
+ extern void qlt_free_mcmd(struct qla_tgt_mgmt_cmd *);
+ extern void qlt_free_cmd(struct qla_tgt_cmd *cmd);
+@@ -1110,5 +1155,7 @@ extern void qlt_stop_phase2(struct qla_tgt *);
+ extern irqreturn_t qla83xx_msix_atio_q(int, void *);
+ extern void qlt_83xx_iospace_config(struct qla_hw_data *);
+ extern int qlt_free_qfull_cmds(struct scsi_qla_host *);
++extern void qlt_logo_completion_handler(fc_port_t *, int);
++extern void qlt_do_generation_tick(struct scsi_qla_host *, int *);
+ 
+ #endif /* __QLA_TARGET_H */
+diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c
+index 962cb89fe0ae..af806fdb0dbc 100644
+--- a/drivers/scsi/qla2xxx/qla_tmpl.c
++++ b/drivers/scsi/qla2xxx/qla_tmpl.c
+@@ -395,6 +395,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
+ 	if (ent->t263.queue_type == T263_QUEUE_TYPE_REQ) {
+ 		for (i = 0; i < vha->hw->max_req_queues; i++) {
+ 			struct req_que *req = vha->hw->req_q_map[i];
++
++			if (!test_bit(i, vha->hw->req_qid_map))
++				continue;
++
+ 			if (req || !buf) {
+ 				length = req ?
+ 				    req->length : REQUEST_ENTRY_CNT_24XX;
+@@ -408,6 +412,10 @@ qla27xx_fwdt_entry_t263(struct scsi_qla_host *vha,
+ 	} else if (ent->t263.queue_type == T263_QUEUE_TYPE_RSP) {
+ 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
+ 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
++
++			if (!test_bit(i, vha->hw->rsp_qid_map))
++				continue;
++
+ 			if (rsp || !buf) {
+ 				length = rsp ?
+ 				    rsp->length : RESPONSE_ENTRY_CNT_MQ;
+@@ -634,6 +642,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
+ 	if (ent->t274.queue_type == T274_QUEUE_TYPE_REQ_SHAD) {
+ 		for (i = 0; i < vha->hw->max_req_queues; i++) {
+ 			struct req_que *req = vha->hw->req_q_map[i];
++
++			if (!test_bit(i, vha->hw->req_qid_map))
++				continue;
++
+ 			if (req || !buf) {
+ 				qla27xx_insert16(i, buf, len);
+ 				qla27xx_insert16(1, buf, len);
+@@ -645,6 +657,10 @@ qla27xx_fwdt_entry_t274(struct scsi_qla_host *vha,
+ 	} else if (ent->t274.queue_type == T274_QUEUE_TYPE_RSP_SHAD) {
+ 		for (i = 0; i < vha->hw->max_rsp_queues; i++) {
+ 			struct rsp_que *rsp = vha->hw->rsp_q_map[i];
++
++			if (!test_bit(i, vha->hw->rsp_qid_map))
++				continue;
++
+ 			if (rsp || !buf) {
+ 				qla27xx_insert16(i, buf, len);
+ 				qla27xx_insert16(1, buf, len);
+diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.c b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+index 5c9e680aa375..fdad875ca777 100644
+--- a/drivers/scsi/qla2xxx/tcm_qla2xxx.c
++++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.c
+@@ -429,7 +429,7 @@ static int tcm_qla2xxx_check_stop_free(struct se_cmd *se_cmd)
+ 		cmd->cmd_flags |= BIT_14;
+ 	}
+ 
+-	return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++	return target_put_sess_cmd(se_cmd);
+ }
+ 
+ /* tcm_qla2xxx_release_cmd - Callback from TCM Core to release underlying
+@@ -669,7 +669,6 @@ static int tcm_qla2xxx_queue_data_in(struct se_cmd *se_cmd)
+ 	cmd->cmd_flags |= BIT_4;
+ 	cmd->bufflen = se_cmd->data_length;
+ 	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
+-	cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
+ 
+ 	cmd->sg_cnt = se_cmd->t_data_nents;
+ 	cmd->sg = se_cmd->t_data_sg;
+@@ -699,7 +698,6 @@ static int tcm_qla2xxx_queue_status(struct se_cmd *se_cmd)
+ 	cmd->sg_cnt = 0;
+ 	cmd->offset = 0;
+ 	cmd->dma_data_direction = target_reverse_dma_direction(se_cmd);
+-	cmd->aborted = (se_cmd->transport_state & CMD_T_ABORTED);
+ 	if (cmd->cmd_flags &  BIT_5) {
+ 		pr_crit("Bit_5 already set for cmd = %p.\n", cmd);
+ 		dump_stack();
+@@ -764,14 +762,7 @@ static void tcm_qla2xxx_aborted_task(struct se_cmd *se_cmd)
+ {
+ 	struct qla_tgt_cmd *cmd = container_of(se_cmd,
+ 				struct qla_tgt_cmd, se_cmd);
+-	struct scsi_qla_host *vha = cmd->vha;
+-	struct qla_hw_data *ha = vha->hw;
+-
+-	if (!cmd->sg_mapped)
+-		return;
+-
+-	pci_unmap_sg(ha->pdev, cmd->sg, cmd->sg_cnt, cmd->dma_data_direction);
+-	cmd->sg_mapped = 0;
++	qlt_abort_cmd(cmd);
+ }
+ 
+ static void tcm_qla2xxx_clear_sess_lookup(struct tcm_qla2xxx_lport *,
+@@ -1323,9 +1314,7 @@ static struct qla_tgt_sess *tcm_qla2xxx_find_sess_by_s_id(
+ 		return NULL;
+ 	}
+ 
+-	key = (((unsigned long)s_id[0] << 16) |
+-	       ((unsigned long)s_id[1] << 8) |
+-	       (unsigned long)s_id[2]);
++	key = sid_to_key(s_id);
+ 	pr_debug("find_sess_by_s_id: 0x%06x\n", key);
+ 
+ 	se_nacl = btree_lookup32(&lport->lport_fcport_map, key);
+@@ -1360,9 +1349,7 @@ static void tcm_qla2xxx_set_sess_by_s_id(
+ 	void *slot;
+ 	int rc;
+ 
+-	key = (((unsigned long)s_id[0] << 16) |
+-	       ((unsigned long)s_id[1] << 8) |
+-	       (unsigned long)s_id[2]);
++	key = sid_to_key(s_id);
+ 	pr_debug("set_sess_by_s_id: %06x\n", key);
+ 
+ 	slot = btree_lookup32(&lport->lport_fcport_map, key);
+@@ -1718,6 +1705,10 @@ static void tcm_qla2xxx_update_sess(struct qla_tgt_sess *sess, port_id_t s_id,
+ 	}
+ 
+ 	sess->conf_compl_supported = conf_compl_supported;
++
++	/* Reset logout parameters to default */
++	sess->logout_on_delete = 1;
++	sess->keep_nport_handle = 0;
+ }
+ 
+ /*
+diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
+index 64ed88a67e6e..ac418e73536d 100644
+--- a/drivers/scsi/scsi_devinfo.c
++++ b/drivers/scsi/scsi_devinfo.c
+@@ -205,6 +205,7 @@ static struct {
+ 	{"Intel", "Multi-Flex", NULL, BLIST_NO_RSOC},
+ 	{"iRiver", "iFP Mass Driver", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
+ 	{"LASOUND", "CDX7405", "3.10", BLIST_MAX5LUN | BLIST_SINGLELUN},
++	{"Marvell", "Console", NULL, BLIST_SKIP_VPD_PAGES},
+ 	{"MATSHITA", "PD-1", NULL, BLIST_FORCELUN | BLIST_SINGLELUN},
+ 	{"MATSHITA", "DMC-LC5", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
+ 	{"MATSHITA", "DMC-LC40", NULL, BLIST_NOT_LOCKABLE | BLIST_INQUIRY_36},
+diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
+index 330bbe831066..2e58279fab60 100644
+--- a/drivers/target/iscsi/iscsi_target.c
++++ b/drivers/target/iscsi/iscsi_target.c
+@@ -712,7 +712,7 @@ static int iscsit_add_reject_from_cmd(
+ 	 */
+ 	if (cmd->se_cmd.se_tfo != NULL) {
+ 		pr_debug("iscsi reject: calling target_put_sess_cmd >>>>>>\n");
+-		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++		target_put_sess_cmd(&cmd->se_cmd);
+ 	}
+ 	return -1;
+ }
+@@ -998,7 +998,7 @@ int iscsit_setup_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ 		hdr->cmdsn, be32_to_cpu(hdr->data_length), payload_length,
+ 		conn->cid);
+ 
+-	target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
++	target_get_sess_cmd(&cmd->se_cmd, true);
+ 
+ 	cmd->sense_reason = transport_lookup_cmd_lun(&cmd->se_cmd,
+ 						     scsilun_to_int(&hdr->lun));
+@@ -1064,7 +1064,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ 		if (cmdsn_ret == CMDSN_ERROR_CANNOT_RECOVER)
+ 			return -1;
+ 		else if (cmdsn_ret == CMDSN_LOWER_THAN_EXP) {
+-			target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++			target_put_sess_cmd(&cmd->se_cmd);
+ 			return 0;
+ 		}
+ 	}
+@@ -1080,7 +1080,7 @@ int iscsit_process_scsi_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ 		if (!cmd->sense_reason)
+ 			return 0;
+ 
+-		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++		target_put_sess_cmd(&cmd->se_cmd);
+ 		return 0;
+ 	}
+ 
+@@ -1111,7 +1111,6 @@ static int
+ iscsit_get_immediate_data(struct iscsi_cmd *cmd, struct iscsi_scsi_req *hdr,
+ 			  bool dump_payload)
+ {
+-	struct iscsi_conn *conn = cmd->conn;
+ 	int cmdsn_ret = 0, immed_ret = IMMEDIATE_DATA_NORMAL_OPERATION;
+ 	/*
+ 	 * Special case for Unsupported SAM WRITE Opcodes and ImmediateData=Yes.
+@@ -1138,7 +1137,7 @@ after_immediate_data:
+ 
+ 			rc = iscsit_dump_data_payload(cmd->conn,
+ 						      cmd->first_burst_len, 1);
+-			target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++			target_put_sess_cmd(&cmd->se_cmd);
+ 			return rc;
+ 		} else if (cmd->unsolicited_data)
+ 			iscsit_set_unsoliticed_dataout(cmd);
+@@ -1807,7 +1806,7 @@ iscsit_handle_task_mgt_cmd(struct iscsi_conn *conn, struct iscsi_cmd *cmd,
+ 				      conn->sess->se_sess, 0, DMA_NONE,
+ 				      TCM_SIMPLE_TAG, cmd->sense_buffer + 2);
+ 
+-		target_get_sess_cmd(conn->sess->se_sess, &cmd->se_cmd, true);
++		target_get_sess_cmd(&cmd->se_cmd, true);
+ 		sess_ref = true;
+ 
+ 		switch (function) {
+@@ -1949,7 +1948,7 @@ attach:
+ 	 */
+ 	if (sess_ref) {
+ 		pr_debug("Handle TMR, using sess_ref=true check\n");
+-		target_put_sess_cmd(conn->sess->se_sess, &cmd->se_cmd);
++		target_put_sess_cmd(&cmd->se_cmd);
+ 	}
+ 
+ 	iscsit_add_cmd_to_response_queue(cmd, conn, cmd->i_state);
+diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c
+index 5a8add721741..83bb55b94434 100644
+--- a/drivers/target/iscsi/iscsi_target_configfs.c
++++ b/drivers/target/iscsi/iscsi_target_configfs.c
+@@ -1981,7 +1981,7 @@ static void lio_set_default_node_attributes(struct se_node_acl *se_acl)
+ 
+ static int lio_check_stop_free(struct se_cmd *se_cmd)
+ {
+-	return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++	return target_put_sess_cmd(se_cmd);
+ }
+ 
+ static void lio_release_cmd(struct se_cmd *se_cmd)
+diff --git a/drivers/target/iscsi/iscsi_target_util.c b/drivers/target/iscsi/iscsi_target_util.c
+index b18edda3e8af..231e2e0e5894 100644
+--- a/drivers/target/iscsi/iscsi_target_util.c
++++ b/drivers/target/iscsi/iscsi_target_util.c
+@@ -746,7 +746,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
+ 		rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
+ 		if (!rc && shutdown && se_cmd && se_cmd->se_sess) {
+ 			__iscsit_free_cmd(cmd, true, shutdown);
+-			target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++			target_put_sess_cmd(se_cmd);
+ 		}
+ 		break;
+ 	case ISCSI_OP_REJECT:
+@@ -762,7 +762,7 @@ void iscsit_free_cmd(struct iscsi_cmd *cmd, bool shutdown)
+ 			rc = transport_generic_free_cmd(&cmd->se_cmd, shutdown);
+ 			if (!rc && shutdown && se_cmd->se_sess) {
+ 				__iscsit_free_cmd(cmd, true, shutdown);
+-				target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++				target_put_sess_cmd(se_cmd);
+ 			}
+ 			break;
+ 		}
+diff --git a/drivers/target/target_core_tmr.c b/drivers/target/target_core_tmr.c
+index 315ec3458eeb..adb8016955c4 100644
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -71,7 +71,7 @@ void core_tmr_release_req(struct se_tmr_req *tmr)
+ 
+ 	if (dev) {
+ 		spin_lock_irqsave(&dev->se_tmr_lock, flags);
+-		list_del(&tmr->tmr_list);
++		list_del_init(&tmr->tmr_list);
+ 		spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
+ 	}
+ 
+@@ -153,7 +153,7 @@ void core_tmr_abort_task(
+ 		cancel_work_sync(&se_cmd->work);
+ 		transport_wait_for_tasks(se_cmd);
+ 
+-		target_put_sess_cmd(se_sess, se_cmd);
++		target_put_sess_cmd(se_cmd);
+ 		transport_cmd_finish_abort(se_cmd, true);
+ 
+ 		printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
+@@ -175,9 +175,11 @@ static void core_tmr_drain_tmr_list(
+ 	struct list_head *preempt_and_abort_list)
+ {
+ 	LIST_HEAD(drain_tmr_list);
++	struct se_session *sess;
+ 	struct se_tmr_req *tmr_p, *tmr_pp;
+ 	struct se_cmd *cmd;
+ 	unsigned long flags;
++	bool rc;
+ 	/*
+ 	 * Release all pending and outgoing TMRs aside from the received
+ 	 * LUN_RESET tmr..
+@@ -203,17 +205,31 @@ static void core_tmr_drain_tmr_list(
+ 		if (target_check_cdb_and_preempt(preempt_and_abort_list, cmd))
+ 			continue;
+ 
++		sess = cmd->se_sess;
++		if (WARN_ON_ONCE(!sess))
++			continue;
++
++		spin_lock(&sess->sess_cmd_lock);
+ 		spin_lock(&cmd->t_state_lock);
+ 		if (!(cmd->transport_state & CMD_T_ACTIVE)) {
+ 			spin_unlock(&cmd->t_state_lock);
++			spin_unlock(&sess->sess_cmd_lock);
+ 			continue;
+ 		}
+ 		if (cmd->t_state == TRANSPORT_ISTATE_PROCESSING) {
+ 			spin_unlock(&cmd->t_state_lock);
++			spin_unlock(&sess->sess_cmd_lock);
+ 			continue;
+ 		}
++		cmd->transport_state |= CMD_T_ABORTED;
+ 		spin_unlock(&cmd->t_state_lock);
+ 
++		rc = kref_get_unless_zero(&cmd->cmd_kref);
++		spin_unlock(&sess->sess_cmd_lock);
++		if (!rc) {
++			printk("LUN_RESET TMR: non-zero kref_get_unless_zero\n");
++			continue;
++		}
+ 		list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
+ 	}
+ 	spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
+@@ -227,7 +243,11 @@ static void core_tmr_drain_tmr_list(
+ 			(preempt_and_abort_list) ? "Preempt" : "", tmr_p,
+ 			tmr_p->function, tmr_p->response, cmd->t_state);
+ 
++		cancel_work_sync(&cmd->work);
++		transport_wait_for_tasks(cmd);
++
+ 		transport_cmd_finish_abort(cmd, 1);
++		target_put_sess_cmd(cmd);
+ 	}
+ }
+ 
+diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
+index 675f2d9d1f14..3881504b40d8 100644
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -1419,7 +1419,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
+ 	 * for fabrics using TARGET_SCF_ACK_KREF that expect a second
+ 	 * kref_put() to happen during fabric packet acknowledgement.
+ 	 */
+-	ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
++	ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
+ 	if (ret)
+ 		return ret;
+ 	/*
+@@ -1433,7 +1433,7 @@ int target_submit_cmd_map_sgls(struct se_cmd *se_cmd, struct se_session *se_sess
+ 	rc = transport_lookup_cmd_lun(se_cmd, unpacked_lun);
+ 	if (rc) {
+ 		transport_send_check_condition_and_sense(se_cmd, rc, 0);
+-		target_put_sess_cmd(se_sess, se_cmd);
++		target_put_sess_cmd(se_cmd);
+ 		return 0;
+ 	}
+ 
+@@ -1584,7 +1584,7 @@ int target_submit_tmr(struct se_cmd *se_cmd, struct se_session *se_sess,
+ 		se_cmd->se_tmr_req->ref_task_tag = tag;
+ 
+ 	/* See target_submit_cmd for commentary */
+-	ret = target_get_sess_cmd(se_sess, se_cmd, (flags & TARGET_SCF_ACK_KREF));
++	ret = target_get_sess_cmd(se_cmd, flags & TARGET_SCF_ACK_KREF);
+ 	if (ret) {
+ 		core_tmr_release_req(se_cmd->se_tmr_req);
+ 		return ret;
+@@ -2227,7 +2227,7 @@ static int transport_release_cmd(struct se_cmd *cmd)
+ 	 * If this cmd has been setup with target_get_sess_cmd(), drop
+ 	 * the kref and call ->release_cmd() in kref callback.
+ 	 */
+-	return target_put_sess_cmd(cmd->se_sess, cmd);
++	return target_put_sess_cmd(cmd);
+ }
+ 
+ /**
+@@ -2471,13 +2471,12 @@ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+ EXPORT_SYMBOL(transport_generic_free_cmd);
+ 
+ /* target_get_sess_cmd - Add command to active ->sess_cmd_list
+- * @se_sess:	session to reference
+  * @se_cmd:	command descriptor to add
+  * @ack_kref:	Signal that fabric will perform an ack target_put_sess_cmd()
+  */
+-int target_get_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd,
+-			       bool ack_kref)
++int target_get_sess_cmd(struct se_cmd *se_cmd, bool ack_kref)
+ {
++	struct se_session *se_sess = se_cmd->se_sess;
+ 	unsigned long flags;
+ 	int ret = 0;
+ 
+@@ -2499,7 +2498,7 @@ out:
+ 	spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ 
+ 	if (ret && ack_kref)
+-		target_put_sess_cmd(se_sess, se_cmd);
++		target_put_sess_cmd(se_cmd);
+ 
+ 	return ret;
+ }
+@@ -2528,11 +2527,12 @@ static void target_release_cmd_kref(struct kref *kref)
+ }
+ 
+ /* target_put_sess_cmd - Check for active I/O shutdown via kref_put
+- * @se_sess:	session to reference
+  * @se_cmd:	command descriptor to drop
+  */
+-int target_put_sess_cmd(struct se_session *se_sess, struct se_cmd *se_cmd)
++int target_put_sess_cmd(struct se_cmd *se_cmd)
+ {
++	struct se_session *se_sess = se_cmd->se_sess;
++
+ 	if (!se_sess) {
+ 		se_cmd->se_tfo->release_cmd(se_cmd);
+ 		return 1;
+@@ -3025,8 +3025,17 @@ static void target_tmr_work(struct work_struct *work)
+ 	struct se_cmd *cmd = container_of(work, struct se_cmd, work);
+ 	struct se_device *dev = cmd->se_dev;
+ 	struct se_tmr_req *tmr = cmd->se_tmr_req;
++	unsigned long flags;
+ 	int ret;
+ 
++	spin_lock_irqsave(&cmd->t_state_lock, flags);
++	if (cmd->transport_state & CMD_T_ABORTED) {
++		tmr->response = TMR_FUNCTION_REJECTED;
++		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++		goto check_stop;
++	}
++	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++
+ 	switch (tmr->function) {
+ 	case TMR_ABORT_TASK:
+ 		core_tmr_abort_task(dev, tmr, cmd->se_sess);
+@@ -3054,9 +3063,17 @@ static void target_tmr_work(struct work_struct *work)
+ 		break;
+ 	}
+ 
++	spin_lock_irqsave(&cmd->t_state_lock, flags);
++	if (cmd->transport_state & CMD_T_ABORTED) {
++		spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++		goto check_stop;
++	}
+ 	cmd->t_state = TRANSPORT_ISTATE_PROCESSING;
++	spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++
+ 	cmd->se_tfo->queue_tm_rsp(cmd);
+ 
++check_stop:
+ 	transport_cmd_check_stop_to_fabric(cmd);
+ }
+ 
+diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
+index 4d5e8409769c..254c183a5efe 100644
+--- a/drivers/tty/pty.c
++++ b/drivers/tty/pty.c
+@@ -672,7 +672,14 @@ static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
+ /* this is called once with whichever end is closed last */
+ static void pty_unix98_shutdown(struct tty_struct *tty)
+ {
+-	devpts_kill_index(tty->driver_data, tty->index);
++	struct inode *ptmx_inode;
++
++	if (tty->driver->subtype == PTY_TYPE_MASTER)
++		ptmx_inode = tty->driver_data;
++	else
++		ptmx_inode = tty->link->driver_data;
++	devpts_kill_index(ptmx_inode, tty->index);
++	devpts_del_ref(ptmx_inode);
+ }
+ 
+ static const struct tty_operations ptm_unix98_ops = {
+@@ -764,6 +771,18 @@ static int ptmx_open(struct inode *inode, struct file *filp)
+ 	set_bit(TTY_PTY_LOCK, &tty->flags); /* LOCK THE SLAVE */
+ 	tty->driver_data = inode;
+ 
++	/*
++	 * In the case where all references to ptmx inode are dropped and we
++	 * still have /dev/tty opened pointing to the master/slave pair (ptmx
++	 * is closed/released before /dev/tty), we must make sure that the inode
++	 * is still valid when we call the final pty_unix98_shutdown, thus we
++	 * hold an additional reference to the ptmx inode. For the same /dev/tty
++	 * last close case, we also need to make sure the super_block isn't
++	 * destroyed (devpts instance unmounted), before /dev/tty is closed and
++	 * on its release devpts_kill_index is called.
++	 */
++	devpts_add_ref(inode);
++
+ 	tty_add_file(tty, filp);
+ 
+ 	slave_inode = devpts_pty_new(inode,
+diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
+index 2fd163b75665..b82b2a0f82a3 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -2002,6 +2002,7 @@ pci_wch_ch38x_setup(struct serial_private *priv,
+ #define PCIE_VENDOR_ID_WCH		0x1c00
+ #define PCIE_DEVICE_ID_WCH_CH382_2S1P	0x3250
+ #define PCIE_DEVICE_ID_WCH_CH384_4S	0x3470
++#define PCIE_DEVICE_ID_WCH_CH382_2S	0x3253
+ 
+ #define PCI_DEVICE_ID_EXAR_XR17V4358	0x4358
+ #define PCI_DEVICE_ID_EXAR_XR17V8358	0x8358
+@@ -2729,6 +2730,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
+ 		.subdevice	= PCI_ANY_ID,
+ 		.setup		= pci_wch_ch353_setup,
+ 	},
++	/* WCH CH382 2S card (16850 clone) */
++	{
++		.vendor         = PCIE_VENDOR_ID_WCH,
++		.device         = PCIE_DEVICE_ID_WCH_CH382_2S,
++		.subvendor      = PCI_ANY_ID,
++		.subdevice      = PCI_ANY_ID,
++		.setup          = pci_wch_ch38x_setup,
++	},
+ 	/* WCH CH382 2S1P card (16850 clone) */
+ 	{
+ 		.vendor         = PCIE_VENDOR_ID_WCH,
+@@ -3049,6 +3058,7 @@ enum pci_board_num_t {
+ 	pbn_fintek_4,
+ 	pbn_fintek_8,
+ 	pbn_fintek_12,
++	pbn_wch382_2,
+ 	pbn_wch384_4,
+ 	pbn_pericom_PI7C9X7951,
+ 	pbn_pericom_PI7C9X7952,
+@@ -3879,6 +3889,13 @@ static struct pciserial_board pci_boards[] = {
+ 		.base_baud	= 115200,
+ 		.first_offset	= 0x40,
+ 	},
++	[pbn_wch382_2] = {
++		.flags		= FL_BASE0,
++		.num_ports	= 2,
++		.base_baud	= 115200,
++		.uart_offset	= 8,
++		.first_offset	= 0xC0,
++	},
+ 	[pbn_wch384_4] = {
+ 		.flags		= FL_BASE0,
+ 		.num_ports	= 4,
+@@ -5691,6 +5708,10 @@ static struct pci_device_id serial_pci_tbl[] = {
+ 		PCI_ANY_ID, PCI_ANY_ID,
+ 		0, 0, pbn_b0_bt_2_115200 },
+ 
++	{	PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH382_2S,
++		PCI_ANY_ID, PCI_ANY_ID,
++		0, 0, pbn_wch382_2 },
++
+ 	{	PCIE_VENDOR_ID_WCH, PCIE_DEVICE_ID_WCH_CH384_4S,
+ 		PCI_ANY_ID, PCI_ANY_ID,
+ 		0, 0, pbn_wch384_4 },
+diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
+index 7f49172ccd86..0a88693cd8ca 100644
+--- a/drivers/tty/serial/omap-serial.c
++++ b/drivers/tty/serial/omap-serial.c
+@@ -1368,7 +1368,7 @@ static inline void serial_omap_add_console_port(struct uart_omap_port *up)
+ 
+ /* Enable or disable the rs485 support */
+ static int
+-serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
++serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485)
+ {
+ 	struct uart_omap_port *up = to_uart_omap_port(port);
+ 	unsigned int mode;
+@@ -1381,8 +1381,12 @@ serial_omap_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
+ 	up->ier = 0;
+ 	serial_out(up, UART_IER, 0);
+ 
++	/* Clamp the delays to [0, 100ms] */
++	rs485->delay_rts_before_send = min(rs485->delay_rts_before_send, 100U);
++	rs485->delay_rts_after_send  = min(rs485->delay_rts_after_send, 100U);
++
+ 	/* store new config */
+-	port->rs485 = *rs485conf;
++	port->rs485 = *rs485;
+ 
+ 	/*
+ 	 * Just as a precaution, only allow rs485
+diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
+index ea32b386797f..636435b41293 100644
+--- a/drivers/vhost/scsi.c
++++ b/drivers/vhost/scsi.c
+@@ -607,7 +607,7 @@ static void vhost_scsi_free_cmd(struct vhost_scsi_cmd *cmd)
+ 
+ static int vhost_scsi_check_stop_free(struct se_cmd *se_cmd)
+ {
+-	return target_put_sess_cmd(se_cmd->se_sess, se_cmd);
++	return target_put_sess_cmd(se_cmd);
+ }
+ 
+ static void
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index 723470850b94..30bc9fa763bd 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -1369,7 +1369,8 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
+ 			read_extent_buffer(eb, dest + bytes_left,
+ 					   name_off, name_len);
+ 		if (eb != eb_in) {
+-			btrfs_tree_read_unlock_blocking(eb);
++			if (!path->skip_locking)
++				btrfs_tree_read_unlock_blocking(eb);
+ 			free_extent_buffer(eb);
+ 		}
+ 		ret = btrfs_find_item(fs_root, path, parent, 0,
+@@ -1389,9 +1390,10 @@ char *btrfs_ref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path,
+ 		eb = path->nodes[0];
+ 		/* make sure we can use eb after releasing the path */
+ 		if (eb != eb_in) {
+-			atomic_inc(&eb->refs);
+-			btrfs_tree_read_lock(eb);
+-			btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
++			if (!path->skip_locking)
++				btrfs_set_lock_blocking_rw(eb, BTRFS_READ_LOCK);
++			path->nodes[0] = NULL;
++			path->locks[0] = 0;
+ 		}
+ 		btrfs_release_path(path);
+ 		iref = btrfs_item_ptr(eb, slot, struct btrfs_inode_ref);
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index a2ae42720a6a..bc2d048a9eb9 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -1690,7 +1690,7 @@ int btrfs_should_delete_dir_index(struct list_head *del_list,
+  *
+  */
+ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+-				    struct list_head *ins_list)
++				    struct list_head *ins_list, bool *emitted)
+ {
+ 	struct btrfs_dir_item *di;
+ 	struct btrfs_delayed_item *curr, *next;
+@@ -1734,6 +1734,7 @@ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+ 
+ 		if (over)
+ 			return 1;
++		*emitted = true;
+ 	}
+ 	return 0;
+ }
+diff --git a/fs/btrfs/delayed-inode.h b/fs/btrfs/delayed-inode.h
+index f70119f25421..0167853c84ae 100644
+--- a/fs/btrfs/delayed-inode.h
++++ b/fs/btrfs/delayed-inode.h
+@@ -144,7 +144,7 @@ void btrfs_put_delayed_items(struct list_head *ins_list,
+ int btrfs_should_delete_dir_index(struct list_head *del_list,
+ 				  u64 index);
+ int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
+-				    struct list_head *ins_list);
++				    struct list_head *ins_list, bool *emitted);
+ 
+ /* for init */
+ int __init btrfs_delayed_inode_init(void);
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index df4e0462976e..b114a0539d3d 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -5666,6 +5666,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
+ 	char *name_ptr;
+ 	int name_len;
+ 	int is_curr = 0;	/* ctx->pos points to the current index? */
++	bool emitted;
+ 
+ 	/* FIXME, use a real flag for deciding about the key type */
+ 	if (root->fs_info->tree_root == root)
+@@ -5694,6 +5695,7 @@ static int btrfs_real_readdir(struct file *file, struct dir_context *ctx)
+ 	if (ret < 0)
+ 		goto err;
+ 
++	emitted = false;
+ 	while (1) {
+ 		leaf = path->nodes[0];
+ 		slot = path->slots[0];
+@@ -5773,6 +5775,7 @@ skip:
+ 
+ 			if (over)
+ 				goto nopos;
++			emitted = true;
+ 			di_len = btrfs_dir_name_len(leaf, di) +
+ 				 btrfs_dir_data_len(leaf, di) + sizeof(*di);
+ 			di_cur += di_len;
+@@ -5785,11 +5788,20 @@ next:
+ 	if (key_type == BTRFS_DIR_INDEX_KEY) {
+ 		if (is_curr)
+ 			ctx->pos++;
+-		ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list);
++		ret = btrfs_readdir_delayed_dir_index(ctx, &ins_list, &emitted);
+ 		if (ret)
+ 			goto nopos;
+ 	}
+ 
++	/*
++	 * If we haven't emitted any dir entry, we must not touch ctx->pos as
++	 * it was was set to the termination value in previous call. We assume
++	 * that "." and ".." were emitted if we reach this point and set the
++	 * termination value as well for an empty directory.
++	 */
++	if (ctx->pos > 2 && !emitted)
++		goto nopos;
++
+ 	/* Reached end of directory/root. Bump pos past the last item. */
+ 	ctx->pos++;
+ 
+diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
+index afa09fce8151..e682b36a210f 100644
+--- a/fs/cifs/cifsencrypt.c
++++ b/fs/cifs/cifsencrypt.c
+@@ -714,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
+ 
+ 	ses->auth_key.response = kmalloc(baselen + tilen, GFP_KERNEL);
+ 	if (!ses->auth_key.response) {
+-		rc = ENOMEM;
++		rc = -ENOMEM;
+ 		ses->auth_key.len = 0;
+ 		goto setup_ntlmv2_rsp_ret;
+ 	}
+diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c
+index add566303c68..91360444adf5 100644
+--- a/fs/devpts/inode.c
++++ b/fs/devpts/inode.c
+@@ -569,6 +569,26 @@ void devpts_kill_index(struct inode *ptmx_inode, int idx)
+ 	mutex_unlock(&allocated_ptys_lock);
+ }
+ 
++/*
++ * pty code needs to hold extra references in case of last /dev/tty close
++ */
++
++void devpts_add_ref(struct inode *ptmx_inode)
++{
++	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
++
++	atomic_inc(&sb->s_active);
++	ihold(ptmx_inode);
++}
++
++void devpts_del_ref(struct inode *ptmx_inode)
++{
++	struct super_block *sb = pts_sb_from_inode(ptmx_inode);
++
++	iput(ptmx_inode);
++	deactivate_super(sb);
++}
++
+ /**
+  * devpts_pty_new -- create a new inode in /dev/pts/
+  * @ptmx_inode: inode of the master
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
+index 966c614822cc..2b3a53a51582 100644
+--- a/fs/ext4/inode.c
++++ b/fs/ext4/inode.c
+@@ -3133,29 +3133,29 @@ static ssize_t ext4_ext_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
+ 	 * case, we allocate an io_end structure to hook to the iocb.
+ 	 */
+ 	iocb->private = NULL;
+-	ext4_inode_aio_set(inode, NULL);
+-	if (!is_sync_kiocb(iocb)) {
+-		io_end = ext4_init_io_end(inode, GFP_NOFS);
+-		if (!io_end) {
+-			ret = -ENOMEM;
+-			goto retake_lock;
+-		}
+-		/*
+-		 * Grab reference for DIO. Will be dropped in ext4_end_io_dio()
+-		 */
+-		iocb->private = ext4_get_io_end(io_end);
+-		/*
+-		 * we save the io structure for current async direct
+-		 * IO, so that later ext4_map_blocks() could flag the
+-		 * io structure whether there is a unwritten extents
+-		 * needs to be converted when IO is completed.
+-		 */
+-		ext4_inode_aio_set(inode, io_end);
+-	}
+-
+ 	if (overwrite) {
+ 		get_block_func = ext4_get_block_write_nolock;
+ 	} else {
++		ext4_inode_aio_set(inode, NULL);
++		if (!is_sync_kiocb(iocb)) {
++			io_end = ext4_init_io_end(inode, GFP_NOFS);
++			if (!io_end) {
++				ret = -ENOMEM;
++				goto retake_lock;
++			}
++			/*
++			 * Grab reference for DIO. Will be dropped in
++			 * ext4_end_io_dio()
++			 */
++			iocb->private = ext4_get_io_end(io_end);
++			/*
++			 * we save the io structure for current async direct
++			 * IO, so that later ext4_map_blocks() could flag the
++			 * io structure whether there is a unwritten extents
++			 * needs to be converted when IO is completed.
++			 */
++			ext4_inode_aio_set(inode, io_end);
++		}
+ 		get_block_func = ext4_get_block_write;
+ 		dio_flags = DIO_LOCKING;
+ 	}
+diff --git a/fs/ext4/move_extent.c b/fs/ext4/move_extent.c
+index 370420bfae8d..7da8ac1047f8 100644
+--- a/fs/ext4/move_extent.c
++++ b/fs/ext4/move_extent.c
+@@ -268,11 +268,12 @@ move_extent_per_page(struct file *o_filp, struct inode *donor_inode,
+ 	ext4_lblk_t orig_blk_offset, donor_blk_offset;
+ 	unsigned long blocksize = orig_inode->i_sb->s_blocksize;
+ 	unsigned int tmp_data_size, data_size, replaced_size;
+-	int err2, jblocks, retries = 0;
++	int i, err2, jblocks, retries = 0;
+ 	int replaced_count = 0;
+ 	int from = data_offset_in_page << orig_inode->i_blkbits;
+ 	int blocks_per_page = PAGE_CACHE_SIZE >> orig_inode->i_blkbits;
+ 	struct super_block *sb = orig_inode->i_sb;
++	struct buffer_head *bh = NULL;
+ 
+ 	/*
+ 	 * It needs twice the amount of ordinary journal buffers because
+@@ -383,8 +384,16 @@ data_copy:
+ 	}
+ 	/* Perform all necessary steps similar write_begin()/write_end()
+ 	 * but keeping in mind that i_size will not change */
+-	*err = __block_write_begin(pagep[0], from, replaced_size,
+-				   ext4_get_block);
++	if (!page_has_buffers(pagep[0]))
++		create_empty_buffers(pagep[0], 1 << orig_inode->i_blkbits, 0);
++	bh = page_buffers(pagep[0]);
++	for (i = 0; i < data_offset_in_page; i++)
++		bh = bh->b_this_page;
++	for (i = 0; i < block_len_in_page; i++) {
++		*err = ext4_get_block(orig_inode, orig_blk_offset + i, bh, 0);
++		if (*err < 0)
++			break;
++	}
+ 	if (!*err)
+ 		*err = block_commit_write(pagep[0], from, from + replaced_size);
+ 
+diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
+index cf0c472047e3..0e783b9f7007 100644
+--- a/fs/ext4/resize.c
++++ b/fs/ext4/resize.c
+@@ -198,7 +198,7 @@ static struct ext4_new_flex_group_data *alloc_flex_gd(unsigned long flexbg_size)
+ 	if (flex_gd == NULL)
+ 		goto out3;
+ 
+-	if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_flex_group_data))
++	if (flexbg_size >= UINT_MAX / sizeof(struct ext4_new_group_data))
+ 		goto out2;
+ 	flex_gd->count = flexbg_size;
+ 
+diff --git a/include/asm-generic/cputime_nsecs.h b/include/asm-generic/cputime_nsecs.h
+index 0419485891f2..0f1c6f315cdc 100644
+--- a/include/asm-generic/cputime_nsecs.h
++++ b/include/asm-generic/cputime_nsecs.h
+@@ -75,7 +75,7 @@ typedef u64 __nocast cputime64_t;
+  */
+ static inline cputime_t timespec_to_cputime(const struct timespec *val)
+ {
+-	u64 ret = val->tv_sec * NSEC_PER_SEC + val->tv_nsec;
++	u64 ret = (u64)val->tv_sec * NSEC_PER_SEC + val->tv_nsec;
+ 	return (__force cputime_t) ret;
+ }
+ static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
+@@ -91,7 +91,8 @@ static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
+  */
+ static inline cputime_t timeval_to_cputime(const struct timeval *val)
+ {
+-	u64 ret = val->tv_sec * NSEC_PER_SEC + val->tv_usec * NSEC_PER_USEC;
++	u64 ret = (u64)val->tv_sec * NSEC_PER_SEC +
++			val->tv_usec * NSEC_PER_USEC;
+ 	return (__force cputime_t) ret;
+ }
+ static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
+diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h
+new file mode 100644
+index 000000000000..8d9c7e7a6432
+--- /dev/null
++++ b/include/linux/cgroup-defs.h
+@@ -0,0 +1,470 @@
++/*
++ * linux/cgroup-defs.h - basic definitions for cgroup
++ *
++ * This file provides basic type and interface.  Include this file directly
++ * only if necessary to avoid cyclic dependencies.
++ */
++#ifndef _LINUX_CGROUP_DEFS_H
++#define _LINUX_CGROUP_DEFS_H
++
++#include <linux/limits.h>
++#include <linux/list.h>
++#include <linux/idr.h>
++#include <linux/wait.h>
++#include <linux/mutex.h>
++#include <linux/rcupdate.h>
++#include <linux/percpu-refcount.h>
++#include <linux/workqueue.h>
++
++#ifdef CONFIG_CGROUPS
++
++struct cgroup;
++struct cgroup_root;
++struct cgroup_subsys;
++struct cgroup_taskset;
++struct kernfs_node;
++struct kernfs_ops;
++struct kernfs_open_file;
++
++#define MAX_CGROUP_TYPE_NAMELEN 32
++#define MAX_CGROUP_ROOT_NAMELEN 64
++#define MAX_CFTYPE_NAME		64
++
++/* define the enumeration of all cgroup subsystems */
++#define SUBSYS(_x) _x ## _cgrp_id,
++enum cgroup_subsys_id {
++#include <linux/cgroup_subsys.h>
++	CGROUP_SUBSYS_COUNT,
++};
++#undef SUBSYS
++
++/* bits in struct cgroup_subsys_state flags field */
++enum {
++	CSS_NO_REF	= (1 << 0), /* no reference counting for this css */
++	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
++	CSS_RELEASED	= (1 << 2), /* refcnt reached zero, released */
++};
++
++/* bits in struct cgroup flags field */
++enum {
++	/* Control Group requires release notifications to userspace */
++	CGRP_NOTIFY_ON_RELEASE,
++	/*
++	 * Clone the parent's configuration when creating a new child
++	 * cpuset cgroup.  For historical reasons, this option can be
++	 * specified at mount time and thus is implemented here.
++	 */
++	CGRP_CPUSET_CLONE_CHILDREN,
++};
++
++/* cgroup_root->flags */
++enum {
++	CGRP_ROOT_SANE_BEHAVIOR	= (1 << 0), /* __DEVEL__sane_behavior specified */
++	CGRP_ROOT_NOPREFIX	= (1 << 1), /* mounted subsystems have no named prefix */
++	CGRP_ROOT_XATTR		= (1 << 2), /* supports extended attributes */
++};
++
++/* cftype->flags */
++enum {
++	CFTYPE_ONLY_ON_ROOT	= (1 << 0),	/* only create on root cgrp */
++	CFTYPE_NOT_ON_ROOT	= (1 << 1),	/* don't create on root cgrp */
++	CFTYPE_NO_PREFIX	= (1 << 3),	/* (DON'T USE FOR NEW FILES) no subsys prefix */
++
++	/* internal flags, do not use outside cgroup core proper */
++	__CFTYPE_ONLY_ON_DFL	= (1 << 16),	/* only on default hierarchy */
++	__CFTYPE_NOT_ON_DFL	= (1 << 17),	/* not on default hierarchy */
++};
++
++/*
++ * Per-subsystem/per-cgroup state maintained by the system.  This is the
++ * fundamental structural building block that controllers deal with.
++ *
++ * Fields marked with "PI:" are public and immutable and may be accessed
++ * directly without synchronization.
++ */
++struct cgroup_subsys_state {
++	/* PI: the cgroup that this css is attached to */
++	struct cgroup *cgroup;
++
++	/* PI: the cgroup subsystem that this css is attached to */
++	struct cgroup_subsys *ss;
++
++	/* reference count - access via css_[try]get() and css_put() */
++	struct percpu_ref refcnt;
++
++	/* PI: the parent css */
++	struct cgroup_subsys_state *parent;
++
++	/* siblings list anchored at the parent's ->children */
++	struct list_head sibling;
++	struct list_head children;
++
++	/*
++	 * PI: Subsys-unique ID.  0 is unused and root is always 1.  The
++	 * matching css can be looked up using css_from_id().
++	 */
++	int id;
++
++	unsigned int flags;
++
++	/*
++	 * Monotonically increasing unique serial number which defines a
++	 * uniform order among all csses.  It's guaranteed that all
++	 * ->children lists are in the ascending order of ->serial_nr and
++	 * used to allow interrupting and resuming iterations.
++	 */
++	u64 serial_nr;
++
++	/*
++	 * Incremented by online self and children.  Used to guarantee that
++	 * parents are not offlined before their children.
++	 */
++	atomic_t online_cnt;
++
++	/* percpu_ref killing and RCU release */
++	struct rcu_head rcu_head;
++	struct work_struct destroy_work;
++};
++
++/*
++ * A css_set is a structure holding pointers to a set of
++ * cgroup_subsys_state objects. This saves space in the task struct
++ * object and speeds up fork()/exit(), since a single inc/dec and a
++ * list_add()/del() can bump the reference count on the entire cgroup
++ * set for a task.
++ */
++struct css_set {
++	/* Reference count */
++	atomic_t refcount;
++
++	/*
++	 * List running through all cgroup groups in the same hash
++	 * slot. Protected by css_set_lock
++	 */
++	struct hlist_node hlist;
++
++	/*
++	 * Lists running through all tasks using this cgroup group.
++	 * mg_tasks lists tasks which belong to this cset but are in the
++	 * process of being migrated out or in.  Protected by
++	 * css_set_rwsem, but, during migration, once tasks are moved to
++	 * mg_tasks, it can be read safely while holding cgroup_mutex.
++	 */
++	struct list_head tasks;
++	struct list_head mg_tasks;
++
++	/*
++	 * List of cgrp_cset_links pointing at cgroups referenced from this
++	 * css_set.  Protected by css_set_lock.
++	 */
++	struct list_head cgrp_links;
++
++	/* the default cgroup associated with this css_set */
++	struct cgroup *dfl_cgrp;
++
++	/*
++	 * Set of subsystem states, one for each subsystem. This array is
++	 * immutable after creation apart from the init_css_set during
++	 * subsystem registration (at boot time).
++	 */
++	struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
++
++	/*
++	 * List of csets participating in the on-going migration either as
++	 * source or destination.  Protected by cgroup_mutex.
++	 */
++	struct list_head mg_preload_node;
++	struct list_head mg_node;
++
++	/*
++	 * If this cset is acting as the source of migration the following
++	 * two fields are set.  mg_src_cgrp is the source cgroup of the
++	 * on-going migration and mg_dst_cset is the destination cset the
++	 * target tasks on this cset should be migrated to.  Protected by
++	 * cgroup_mutex.
++	 */
++	struct cgroup *mg_src_cgrp;
++	struct css_set *mg_dst_cset;
++
++	/*
++	 * On the default hierarhcy, ->subsys[ssid] may point to a css
++	 * attached to an ancestor instead of the cgroup this css_set is
++	 * associated with.  The following node is anchored at
++	 * ->subsys[ssid]->cgroup->e_csets[ssid] and provides a way to
++	 * iterate through all css's attached to a given cgroup.
++	 */
++	struct list_head e_cset_node[CGROUP_SUBSYS_COUNT];
++
++	/* For RCU-protected deletion */
++	struct rcu_head rcu_head;
++};
++
++struct cgroup {
++	/* self css with NULL ->ss, points back to this cgroup */
++	struct cgroup_subsys_state self;
++
++	unsigned long flags;		/* "unsigned long" so bitops work */
++
++	/*
++	 * idr allocated in-hierarchy ID.
++	 *
++	 * ID 0 is not used, the ID of the root cgroup is always 1, and a
++	 * new cgroup will be assigned with a smallest available ID.
++	 *
++	 * Allocating/Removing ID must be protected by cgroup_mutex.
++	 */
++	int id;
++
++	/*
++	 * If this cgroup contains any tasks, it contributes one to
++	 * populated_cnt.  All children with non-zero popuplated_cnt of
++	 * their own contribute one.  The count is zero iff there's no task
++	 * in this cgroup or its subtree.
++	 */
++	int populated_cnt;
++
++	struct kernfs_node *kn;		/* cgroup kernfs entry */
++	struct kernfs_node *populated_kn; /* kn for "cgroup.subtree_populated" */
++
++	/*
++	 * The bitmask of subsystems enabled on the child cgroups.
++	 * ->subtree_control is the one configured through
++	 * "cgroup.subtree_control" while ->child_subsys_mask is the
++	 * effective one which may have more subsystems enabled.
++	 * Controller knobs are made available iff it's enabled in
++	 * ->subtree_control.
++	 */
++	unsigned int subtree_control;
++	unsigned int child_subsys_mask;
++
++	/* Private pointers for each registered subsystem */
++	struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
++
++	struct cgroup_root *root;
++
++	/*
++	 * List of cgrp_cset_links pointing at css_sets with tasks in this
++	 * cgroup.  Protected by css_set_lock.
++	 */
++	struct list_head cset_links;
++
++	/*
++	 * On the default hierarchy, a css_set for a cgroup with some
++	 * susbsys disabled will point to css's which are associated with
++	 * the closest ancestor which has the subsys enabled.  The
++	 * following lists all css_sets which point to this cgroup's css
++	 * for the given subsystem.
++	 */
++	struct list_head e_csets[CGROUP_SUBSYS_COUNT];
++
++	/*
++	 * list of pidlists, up to two for each namespace (one for procs, one
++	 * for tasks); created on demand.
++	 */
++	struct list_head pidlists;
++	struct mutex pidlist_mutex;
++
++	/* used to wait for offlining of csses */
++	wait_queue_head_t offline_waitq;
++
++	/* used to schedule release agent */
++	struct work_struct release_agent_work;
++};
++
++/*
++ * A cgroup_root represents the root of a cgroup hierarchy, and may be
++ * associated with a kernfs_root to form an active hierarchy.  This is
++ * internal to cgroup core.  Don't access directly from controllers.
++ */
++struct cgroup_root {
++	struct kernfs_root *kf_root;
++
++	/* The bitmask of subsystems attached to this hierarchy */
++	unsigned int subsys_mask;
++
++	/* Unique id for this hierarchy. */
++	int hierarchy_id;
++
++	/* The root cgroup.  Root is destroyed on its release. */
++	struct cgroup cgrp;
++
++	/* Number of cgroups in the hierarchy, used only for /proc/cgroups */
++	atomic_t nr_cgrps;
++
++	/* A list running through the active hierarchies */
++	struct list_head root_list;
++
++	/* Hierarchy-specific flags */
++	unsigned int flags;
++
++	/* IDs for cgroups in this hierarchy */
++	struct idr cgroup_idr;
++
++	/* The path to use for release notifications. */
++	char release_agent_path[PATH_MAX];
++
++	/* The name for this hierarchy - may be empty */
++	char name[MAX_CGROUP_ROOT_NAMELEN];
++};
++
++/*
++ * struct cftype: handler definitions for cgroup control files
++ *
++ * When reading/writing to a file:
++ *	- the cgroup to use is file->f_path.dentry->d_parent->d_fsdata
++ *	- the 'cftype' of the file is file->f_path.dentry->d_fsdata
++ */
++struct cftype {
++	/*
++	 * By convention, the name should begin with the name of the
++	 * subsystem, followed by a period.  Zero length string indicates
++	 * end of cftype array.
++	 */
++	char name[MAX_CFTYPE_NAME];
++	int private;
++	/*
++	 * If not 0, file mode is set to this value, otherwise it will
++	 * be figured out automatically
++	 */
++	umode_t mode;
++
++	/*
++	 * The maximum length of string, excluding trailing nul, that can
++	 * be passed to write.  If < PAGE_SIZE-1, PAGE_SIZE-1 is assumed.
++	 */
++	size_t max_write_len;
++
++	/* CFTYPE_* flags */
++	unsigned int flags;
++
++	/*
++	 * Fields used for internal bookkeeping.  Initialized automatically
++	 * during registration.
++	 */
++	struct cgroup_subsys *ss;	/* NULL for cgroup core files */
++	struct list_head node;		/* anchored at ss->cfts */
++	struct kernfs_ops *kf_ops;
++
++	/*
++	 * read_u64() is a shortcut for the common case of returning a
++	 * single integer. Use it in place of read()
++	 */
++	u64 (*read_u64)(struct cgroup_subsys_state *css, struct cftype *cft);
++	/*
++	 * read_s64() is a signed version of read_u64()
++	 */
++	s64 (*read_s64)(struct cgroup_subsys_state *css, struct cftype *cft);
++
++	/* generic seq_file read interface */
++	int (*seq_show)(struct seq_file *sf, void *v);
++
++	/* optional ops, implement all or none */
++	void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
++	void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
++	void (*seq_stop)(struct seq_file *sf, void *v);
++
++	/*
++	 * write_u64() is a shortcut for the common case of accepting
++	 * a single integer (as parsed by simple_strtoull) from
++	 * userspace. Use in place of write(); return 0 or error.
++	 */
++	int (*write_u64)(struct cgroup_subsys_state *css, struct cftype *cft,
++			 u64 val);
++	/*
++	 * write_s64() is a signed version of write_u64()
++	 */
++	int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft,
++			 s64 val);
++
++	/*
++	 * write() is the generic write callback which maps directly to
++	 * kernfs write operation and overrides all other operations.
++	 * Maximum write size is determined by ->max_write_len.  Use
++	 * of_css/cft() to access the associated css and cft.
++	 */
++	ssize_t (*write)(struct kernfs_open_file *of,
++			 char *buf, size_t nbytes, loff_t off);
++
++#ifdef CONFIG_DEBUG_LOCK_ALLOC
++	struct lock_class_key	lockdep_key;
++#endif
++};
++
++/*
++ * Control Group subsystem type.
++ * See Documentation/cgroups/cgroups.txt for details
++ */
++struct cgroup_subsys {
++	struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css);
++	int (*css_online)(struct cgroup_subsys_state *css);
++	void (*css_offline)(struct cgroup_subsys_state *css);
++	void (*css_released)(struct cgroup_subsys_state *css);
++	void (*css_free)(struct cgroup_subsys_state *css);
++	void (*css_reset)(struct cgroup_subsys_state *css);
++	void (*css_e_css_changed)(struct cgroup_subsys_state *css);
++
++	int (*can_attach)(struct cgroup_subsys_state *css,
++			  struct cgroup_taskset *tset);
++	void (*cancel_attach)(struct cgroup_subsys_state *css,
++			      struct cgroup_taskset *tset);
++	void (*attach)(struct cgroup_subsys_state *css,
++		       struct cgroup_taskset *tset);
++	void (*fork)(struct task_struct *task);
++	void (*exit)(struct cgroup_subsys_state *css,
++		     struct cgroup_subsys_state *old_css,
++		     struct task_struct *task);
++	void (*bind)(struct cgroup_subsys_state *root_css);
++
++	int disabled;
++	int early_init;
++
++	/*
++	 * If %false, this subsystem is properly hierarchical -
++	 * configuration, resource accounting and restriction on a parent
++	 * cgroup cover those of its children.  If %true, hierarchy support
++	 * is broken in some ways - some subsystems ignore hierarchy
++	 * completely while others are only implemented half-way.
++	 *
++	 * It's now disallowed to create nested cgroups if the subsystem is
++	 * broken and cgroup core will emit a warning message on such
++	 * cases.  Eventually, all subsystems will be made properly
++	 * hierarchical and this will go away.
++	 */
++	bool broken_hierarchy;
++	bool warned_broken_hierarchy;
++
++	/* the following two fields are initialized automtically during boot */
++	int id;
++	const char *name;
++
++	/* link to parent, protected by cgroup_lock() */
++	struct cgroup_root *root;
++
++	/* idr for css->id */
++	struct idr css_idr;
++
++	/*
++	 * List of cftypes.  Each entry is the first entry of an array
++	 * terminated by zero length name.
++	 */
++	struct list_head cfts;
++
++	/*
++	 * Base cftypes which are automatically registered.  The two can
++	 * point to the same array.
++	 */
++	struct cftype *dfl_cftypes;	/* for the default hierarchy */
++	struct cftype *legacy_cftypes;	/* for the legacy hierarchies */
++
++	/*
++	 * A subsystem may depend on other subsystems.  When such subsystem
++	 * is enabled on a cgroup, the depended-upon subsystems are enabled
++	 * together if available.  Subsystems enabled due to dependency are
++	 * not visible to userland until explicitly enabled.  The following
++	 * specifies the mask of subsystems that this one depends on.
++	 */
++	unsigned int depends_on;
++};
++
++#endif	/* CONFIG_CGROUPS */
++#endif	/* _LINUX_CGROUP_DEFS_H */
+diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
+index b9cb94c3102a..96a2ecd5aa69 100644
+--- a/include/linux/cgroup.h
++++ b/include/linux/cgroup.h
+@@ -11,23 +11,16 @@
+ #include <linux/sched.h>
+ #include <linux/cpumask.h>
+ #include <linux/nodemask.h>
+-#include <linux/rcupdate.h>
+ #include <linux/rculist.h>
+ #include <linux/cgroupstats.h>
+ #include <linux/rwsem.h>
+-#include <linux/idr.h>
+-#include <linux/workqueue.h>
+ #include <linux/fs.h>
+-#include <linux/percpu-refcount.h>
+ #include <linux/seq_file.h>
+ #include <linux/kernfs.h>
+-#include <linux/wait.h>
+ 
+-#ifdef CONFIG_CGROUPS
++#include <linux/cgroup-defs.h>
+ 
+-struct cgroup_root;
+-struct cgroup_subsys;
+-struct cgroup;
++#ifdef CONFIG_CGROUPS
+ 
+ extern int cgroup_init_early(void);
+ extern int cgroup_init(void);
+@@ -40,66 +33,6 @@ extern int cgroupstats_build(struct cgroupstats *stats,
+ extern int proc_cgroup_show(struct seq_file *m, struct pid_namespace *ns,
+ 			    struct pid *pid, struct task_struct *tsk);
+ 
+-/* define the enumeration of all cgroup subsystems */
+-#define SUBSYS(_x) _x ## _cgrp_id,
+-enum cgroup_subsys_id {
+-#include <linux/cgroup_subsys.h>
+-	CGROUP_SUBSYS_COUNT,
+-};
+-#undef SUBSYS
+-
+-/*
+- * Per-subsystem/per-cgroup state maintained by the system.  This is the
+- * fundamental structural building block that controllers deal with.
+- *
+- * Fields marked with "PI:" are public and immutable and may be accessed
+- * directly without synchronization.
+- */
+-struct cgroup_subsys_state {
+-	/* PI: the cgroup that this css is attached to */
+-	struct cgroup *cgroup;
+-
+-	/* PI: the cgroup subsystem that this css is attached to */
+-	struct cgroup_subsys *ss;
+-
+-	/* reference count - access via css_[try]get() and css_put() */
+-	struct percpu_ref refcnt;
+-
+-	/* PI: the parent css */
+-	struct cgroup_subsys_state *parent;
+-
+-	/* siblings list anchored at the parent's ->children */
+-	struct list_head sibling;
+-	struct list_head children;
+-
+-	/*
+-	 * PI: Subsys-unique ID.  0 is unused and root is always 1.  The
+-	 * matching css can be looked up using css_from_id().
+-	 */
+-	int id;
+-
+-	unsigned int flags;
+-
+-	/*
+-	 * Monotonically increasing unique serial number which defines a
+-	 * uniform order among all csses.  It's guaranteed that all
+-	 * ->children lists are in the ascending order of ->serial_nr and
+-	 * used to allow interrupting and resuming iterations.
+-	 */
+-	u64 serial_nr;
+-
+-	/* percpu_ref killing and RCU release */
+-	struct rcu_head rcu_head;
+-	struct work_struct destroy_work;
+-};
+-
+-/* bits in struct cgroup_subsys_state flags field */
+-enum {
+-	CSS_NO_REF	= (1 << 0), /* no reference counting for this css */
+-	CSS_ONLINE	= (1 << 1), /* between ->css_online() and ->css_offline() */
+-	CSS_RELEASED	= (1 << 2), /* refcnt reached zero, released */
+-};
+-
+ /**
+  * css_get - obtain a reference on the specified css
+  * @css: target css
+@@ -185,307 +118,6 @@ static inline void css_put_many(struct cgroup_subsys_state *css, unsigned int n)
+ 		percpu_ref_put_many(&css->refcnt, n);
+ }
+ 
+-/* bits in struct cgroup flags field */
+-enum {
+-	/* Control Group requires release notifications to userspace */
+-	CGRP_NOTIFY_ON_RELEASE,
+-	/*
+-	 * Clone the parent's configuration when creating a new child
+-	 * cpuset cgroup.  For historical reasons, this option can be
+-	 * specified at mount time and thus is implemented here.
+-	 */
+-	CGRP_CPUSET_CLONE_CHILDREN,
+-};
+-
+-struct cgroup {
+-	/* self css with NULL ->ss, points back to this cgroup */
+-	struct cgroup_subsys_state self;
+-
+-	unsigned long flags;		/* "unsigned long" so bitops work */
+-
+-	/*
+-	 * idr allocated in-hierarchy ID.
+-	 *
+-	 * ID 0 is not used, the ID of the root cgroup is always 1, and a
+-	 * new cgroup will be assigned with a smallest available ID.
+-	 *
+-	 * Allocating/Removing ID must be protected by cgroup_mutex.
+-	 */
+-	int id;
+-
+-	/*
+-	 * If this cgroup contains any tasks, it contributes one to
+-	 * populated_cnt.  All children with non-zero popuplated_cnt of
+-	 * their own contribute one.  The count is zero iff there's no task
+-	 * in this cgroup or its subtree.
+-	 */
+-	int populated_cnt;
+-
+-	struct kernfs_node *kn;		/* cgroup kernfs entry */
+-	struct kernfs_node *populated_kn; /* kn for "cgroup.subtree_populated" */
+-
+-	/*
+-	 * The bitmask of subsystems enabled on the child cgroups.
+-	 * ->subtree_control is the one configured through
+-	 * "cgroup.subtree_control" while ->child_subsys_mask is the
+-	 * effective one which may have more subsystems enabled.
+-	 * Controller knobs are made available iff it's enabled in
+-	 * ->subtree_control.
+-	 */
+-	unsigned int subtree_control;
+-	unsigned int child_subsys_mask;
+-
+-	/* Private pointers for each registered subsystem */
+-	struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT];
+-
+-	struct cgroup_root *root;
+-
+-	/*
+-	 * List of cgrp_cset_links pointing at css_sets with tasks in this
+-	 * cgroup.  Protected by css_set_lock.
+-	 */
+-	struct list_head cset_links;
+-
+-	/*
+-	 * On the default hierarchy, a css_set for a cgroup with some
+-	 * susbsys disabled will point to css's which are associated with
+-	 * the closest ancestor which has the subsys enabled.  The
+-	 * following lists all css_sets which point to this cgroup's css
+-	 * for the given subsystem.
+-	 */
+-	struct list_head e_csets[CGROUP_SUBSYS_COUNT];
+-
+-	/*
+-	 * list of pidlists, up to two for each namespace (one for procs, one
+-	 * for tasks); created on demand.
+-	 */
+-	struct list_head pidlists;
+-	struct mutex pidlist_mutex;
+-
+-	/* used to wait for offlining of csses */
+-	wait_queue_head_t offline_waitq;
+-
+-	/* used to schedule release agent */
+-	struct work_struct release_agent_work;
+-};
+-
+-#define MAX_CGROUP_ROOT_NAMELEN 64
+-
+-/* cgroup_root->flags */
+-enum {
+-	CGRP_ROOT_SANE_BEHAVIOR	= (1 << 0), /* __DEVEL__sane_behavior specified */
+-	CGRP_ROOT_NOPREFIX	= (1 << 1), /* mounted subsystems have no named prefix */
+-	CGRP_ROOT_XATTR		= (1 << 2), /* supports extended attributes */
+-};
+-
+-/*
+- * A cgroup_root represents the root of a cgroup hierarchy, and may be
+- * associated with a kernfs_root to form an active hierarchy.  This is
+- * internal to cgroup core.  Don't access directly from controllers.
+- */
+-struct cgroup_root {
+-	struct kernfs_root *kf_root;
+-
+-	/* The bitmask of subsystems attached to this hierarchy */
+-	unsigned int subsys_mask;
+-
+-	/* Unique id for this hierarchy. */
+-	int hierarchy_id;
+-
+-	/* The root cgroup.  Root is destroyed on its release. */
+-	struct cgroup cgrp;
+-
+-	/* Number of cgroups in the hierarchy, used only for /proc/cgroups */
+-	atomic_t nr_cgrps;
+-
+-	/* A list running through the active hierarchies */
+-	struct list_head root_list;
+-
+-	/* Hierarchy-specific flags */
+-	unsigned int flags;
+-
+-	/* IDs for cgroups in this hierarchy */
+-	struct idr cgroup_idr;
+-
+-	/* The path to use for release notifications. */
+-	char release_agent_path[PATH_MAX];
+-
+-	/* The name for this hierarchy - may be empty */
+-	char name[MAX_CGROUP_ROOT_NAMELEN];
+-};
+-
+-/*
+- * A css_set is a structure holding pointers to a set of
+- * cgroup_subsys_state objects. This saves space in the task struct
+- * object and speeds up fork()/exit(), since a single inc/dec and a
+- * list_add()/del() can bump the reference count on the entire cgroup
+- * set for a task.
+- */
+-
+-struct css_set {
+-
+-	/* Reference count */
+-	atomic_t refcount;
+-
+-	/*
+-	 * List running through all cgroup groups in the same hash
+-	 * slot. Protected by css_set_lock
+-	 */
+-	struct hlist_node hlist;
+-
+-	/*
+-	 * Lists running through all tasks using this cgroup group.
+-	 * mg_tasks lists tasks which belong to this cset but are in the
+-	 * process of being migrated out or in.  Protected by
+-	 * css_set_rwsem, but, during migration, once tasks are moved to
+-	 * mg_tasks, it can be read safely while holding cgroup_mutex.
+-	 */
+-	struct list_head tasks;
+-	struct list_head mg_tasks;
+-
+-	/*
+-	 * List of cgrp_cset_links pointing at cgroups referenced from this
+-	 * css_set.  Protected by css_set_lock.
+-	 */
+-	struct list_head cgrp_links;
+-
+-	/* the default cgroup associated with this css_set */
+-	struct cgroup *dfl_cgrp;
+-
+-	/*
+-	 * Set of subsystem states, one for each subsystem. This array is
+-	 * immutable after creation apart from the init_css_set during
+-	 * subsystem registration (at boot time).
+-	 */
+-	struct cgroup_subsys_state *subsys[CGROUP_SUBSYS_COUNT];
+-
+-	/*
+-	 * List of csets participating in the on-going migration either as
+-	 * source or destination.  Protected by cgroup_mutex.
+-	 */
+-	struct list_head mg_preload_node;
+-	struct list_head mg_node;
+-
+-	/*
+-	 * If this cset is acting as the source of migration the following
+-	 * two fields are set.  mg_src_cgrp is the source cgroup of the
+-	 * on-going migration and mg_dst_cset is the destination cset the
+-	 * target tasks on this cset should be migrated to.  Protected by
+-	 * cgroup_mutex.
+-	 */
+-	struct cgroup *mg_src_cgrp;
+-	struct css_set *mg_dst_cset;
+-
+-	/*
+-	 * On the default hierarhcy, ->subsys[ssid] may point to a css
+-	 * attached to an ancestor instead of the cgroup this css_set is
+-	 * associated with.  The following node is anchored at
+-	 * ->subsys[ssid]->cgroup->e_csets[ssid] and provides a way to
+-	 * iterate through all css's attached to a given cgroup.
+-	 */
+-	struct list_head e_cset_node[CGROUP_SUBSYS_COUNT];
+-
+-	/* For RCU-protected deletion */
+-	struct rcu_head rcu_head;
+-};
+-
+-/*
+- * struct cftype: handler definitions for cgroup control files
+- *
+- * When reading/writing to a file:
+- *	- the cgroup to use is file->f_path.dentry->d_parent->d_fsdata
+- *	- the 'cftype' of the file is file->f_path.dentry->d_fsdata
+- */
+-
+-/* cftype->flags */
+-enum {
+-	CFTYPE_ONLY_ON_ROOT	= (1 << 0),	/* only create on root cgrp */
+-	CFTYPE_NOT_ON_ROOT	= (1 << 1),	/* don't create on root cgrp */
+-	CFTYPE_NO_PREFIX	= (1 << 3),	/* (DON'T USE FOR NEW FILES) no subsys prefix */
+-
+-	/* internal flags, do not use outside cgroup core proper */
+-	__CFTYPE_ONLY_ON_DFL	= (1 << 16),	/* only on default hierarchy */
+-	__CFTYPE_NOT_ON_DFL	= (1 << 17),	/* not on default hierarchy */
+-};
+-
+-#define MAX_CFTYPE_NAME		64
+-
+-struct cftype {
+-	/*
+-	 * By convention, the name should begin with the name of the
+-	 * subsystem, followed by a period.  Zero length string indicates
+-	 * end of cftype array.
+-	 */
+-	char name[MAX_CFTYPE_NAME];
+-	int private;
+-	/*
+-	 * If not 0, file mode is set to this value, otherwise it will
+-	 * be figured out automatically
+-	 */
+-	umode_t mode;
+-
+-	/*
+-	 * The maximum length of string, excluding trailing nul, that can
+-	 * be passed to write.  If < PAGE_SIZE-1, PAGE_SIZE-1 is assumed.
+-	 */
+-	size_t max_write_len;
+-
+-	/* CFTYPE_* flags */
+-	unsigned int flags;
+-
+-	/*
+-	 * Fields used for internal bookkeeping.  Initialized automatically
+-	 * during registration.
+-	 */
+-	struct cgroup_subsys *ss;	/* NULL for cgroup core files */
+-	struct list_head node;		/* anchored at ss->cfts */
+-	struct kernfs_ops *kf_ops;
+-
+-	/*
+-	 * read_u64() is a shortcut for the common case of returning a
+-	 * single integer. Use it in place of read()
+-	 */
+-	u64 (*read_u64)(struct cgroup_subsys_state *css, struct cftype *cft);
+-	/*
+-	 * read_s64() is a signed version of read_u64()
+-	 */
+-	s64 (*read_s64)(struct cgroup_subsys_state *css, struct cftype *cft);
+-
+-	/* generic seq_file read interface */
+-	int (*seq_show)(struct seq_file *sf, void *v);
+-
+-	/* optional ops, implement all or none */
+-	void *(*seq_start)(struct seq_file *sf, loff_t *ppos);
+-	void *(*seq_next)(struct seq_file *sf, void *v, loff_t *ppos);
+-	void (*seq_stop)(struct seq_file *sf, void *v);
+-
+-	/*
+-	 * write_u64() is a shortcut for the common case of accepting
+-	 * a single integer (as parsed by simple_strtoull) from
+-	 * userspace. Use in place of write(); return 0 or error.
+-	 */
+-	int (*write_u64)(struct cgroup_subsys_state *css, struct cftype *cft,
+-			 u64 val);
+-	/*
+-	 * write_s64() is a signed version of write_u64()
+-	 */
+-	int (*write_s64)(struct cgroup_subsys_state *css, struct cftype *cft,
+-			 s64 val);
+-
+-	/*
+-	 * write() is the generic write callback which maps directly to
+-	 * kernfs write operation and overrides all other operations.
+-	 * Maximum write size is determined by ->max_write_len.  Use
+-	 * of_css/cft() to access the associated css and cft.
+-	 */
+-	ssize_t (*write)(struct kernfs_open_file *of,
+-			 char *buf, size_t nbytes, loff_t off);
+-
+-#ifdef CONFIG_DEBUG_LOCK_ALLOC
+-	struct lock_class_key	lockdep_key;
+-#endif
+-};
+-
+ extern struct cgroup_root cgrp_dfl_root;
+ extern struct css_set init_css_set;
+ 
+@@ -612,11 +244,6 @@ int cgroup_rm_cftypes(struct cftype *cfts);
+ 
+ bool cgroup_is_descendant(struct cgroup *cgrp, struct cgroup *ancestor);
+ 
+-/*
+- * Control Group taskset, used to pass around set of tasks to cgroup_subsys
+- * methods.
+- */
+-struct cgroup_taskset;
+ struct task_struct *cgroup_taskset_first(struct cgroup_taskset *tset);
+ struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset);
+ 
+@@ -629,84 +256,6 @@ struct task_struct *cgroup_taskset_next(struct cgroup_taskset *tset);
+ 	for ((task) = cgroup_taskset_first((tset)); (task);		\
+ 	     (task) = cgroup_taskset_next((tset)))
+ 
+-/*
+- * Control Group subsystem type.
+- * See Documentation/cgroups/cgroups.txt for details
+- */
+-
+-struct cgroup_subsys {
+-	struct cgroup_subsys_state *(*css_alloc)(struct cgroup_subsys_state *parent_css);
+-	int (*css_online)(struct cgroup_subsys_state *css);
+-	void (*css_offline)(struct cgroup_subsys_state *css);
+-	void (*css_released)(struct cgroup_subsys_state *css);
+-	void (*css_free)(struct cgroup_subsys_state *css);
+-	void (*css_reset)(struct cgroup_subsys_state *css);
+-	void (*css_e_css_changed)(struct cgroup_subsys_state *css);
+-
+-	int (*can_attach)(struct cgroup_subsys_state *css,
+-			  struct cgroup_taskset *tset);
+-	void (*cancel_attach)(struct cgroup_subsys_state *css,
+-			      struct cgroup_taskset *tset);
+-	void (*attach)(struct cgroup_subsys_state *css,
+-		       struct cgroup_taskset *tset);
+-	void (*fork)(struct task_struct *task);
+-	void (*exit)(struct cgroup_subsys_state *css,
+-		     struct cgroup_subsys_state *old_css,
+-		     struct task_struct *task);
+-	void (*bind)(struct cgroup_subsys_state *root_css);
+-
+-	int disabled;
+-	int early_init;
+-
+-	/*
+-	 * If %false, this subsystem is properly hierarchical -
+-	 * configuration, resource accounting and restriction on a parent
+-	 * cgroup cover those of its children.  If %true, hierarchy support
+-	 * is broken in some ways - some subsystems ignore hierarchy
+-	 * completely while others are only implemented half-way.
+-	 *
+-	 * It's now disallowed to create nested cgroups if the subsystem is
+-	 * broken and cgroup core will emit a warning message on such
+-	 * cases.  Eventually, all subsystems will be made properly
+-	 * hierarchical and this will go away.
+-	 */
+-	bool broken_hierarchy;
+-	bool warned_broken_hierarchy;
+-
+-	/* the following two fields are initialized automtically during boot */
+-	int id;
+-#define MAX_CGROUP_TYPE_NAMELEN 32
+-	const char *name;
+-
+-	/* link to parent, protected by cgroup_lock() */
+-	struct cgroup_root *root;
+-
+-	/* idr for css->id */
+-	struct idr css_idr;
+-
+-	/*
+-	 * List of cftypes.  Each entry is the first entry of an array
+-	 * terminated by zero length name.
+-	 */
+-	struct list_head cfts;
+-
+-	/*
+-	 * Base cftypes which are automatically registered.  The two can
+-	 * point to the same array.
+-	 */
+-	struct cftype *dfl_cftypes;	/* for the default hierarchy */
+-	struct cftype *legacy_cftypes;	/* for the legacy hierarchies */
+-
+-	/*
+-	 * A subsystem may depend on other subsystems.  When such subsystem
+-	 * is enabled on a cgroup, the depended-upon subsystems are enabled
+-	 * together if available.  Subsystems enabled due to dependency are
+-	 * not visible to userland until explicitly enabled.  The following
+-	 * specifies the mask of subsystems that this one depends on.
+-	 */
+-	unsigned int depends_on;
+-};
+-
+ #define SUBSYS(_x) extern struct cgroup_subsys _x ## _cgrp_subsys;
+ #include <linux/cgroup_subsys.h>
+ #undef SUBSYS
+diff --git a/include/linux/compiler.h b/include/linux/compiler.h
+index 867722591be2..99728072e536 100644
+--- a/include/linux/compiler.h
++++ b/include/linux/compiler.h
+@@ -142,7 +142,7 @@ void ftrace_likely_update(struct ftrace_branch_data *f, int val, int expect);
+  */
+ #define if(cond, ...) __trace_if( (cond , ## __VA_ARGS__) )
+ #define __trace_if(cond) \
+-	if (__builtin_constant_p((cond)) ? !!(cond) :			\
++	if (__builtin_constant_p(!!(cond)) ? !!(cond) :			\
+ 	({								\
+ 		int ______r;						\
+ 		static struct ftrace_branch_data			\
+diff --git a/include/linux/devpts_fs.h b/include/linux/devpts_fs.h
+index 251a2090a554..e0ee0b3000b2 100644
+--- a/include/linux/devpts_fs.h
++++ b/include/linux/devpts_fs.h
+@@ -19,6 +19,8 @@
+ 
+ int devpts_new_index(struct inode *ptmx_inode);
+ void devpts_kill_index(struct inode *ptmx_inode, int idx);
++void devpts_add_ref(struct inode *ptmx_inode);
++void devpts_del_ref(struct inode *ptmx_inode);
+ /* mknod in devpts */
+ struct inode *devpts_pty_new(struct inode *ptmx_inode, dev_t device, int index,
+ 		void *priv);
+@@ -32,6 +34,8 @@ void devpts_pty_kill(struct inode *inode);
+ /* Dummy stubs in the no-pty case */
+ static inline int devpts_new_index(struct inode *ptmx_inode) { return -EINVAL; }
+ static inline void devpts_kill_index(struct inode *ptmx_inode, int idx) { }
++static inline void devpts_add_ref(struct inode *ptmx_inode) { }
++static inline void devpts_del_ref(struct inode *ptmx_inode) { }
+ static inline struct inode *devpts_pty_new(struct inode *ptmx_inode,
+ 		dev_t device, int index, void *priv)
+ {
+diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
+index e4b464983322..01c25923675b 100644
+--- a/include/linux/ipv6.h
++++ b/include/linux/ipv6.h
+@@ -29,6 +29,7 @@ struct ipv6_devconf {
+ 	__s32		max_desync_factor;
+ 	__s32		max_addresses;
+ 	__s32		accept_ra_defrtr;
++	__s32		accept_ra_min_hop_limit;
+ 	__s32		accept_ra_pinfo;
+ #ifdef CONFIG_IPV6_ROUTER_PREF
+ 	__s32		accept_ra_rtr_pref;
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
+index 1f17abe23725..6633b0cd3fb9 100644
+--- a/include/linux/skbuff.h
++++ b/include/linux/skbuff.h
+@@ -203,6 +203,7 @@ struct sk_buff;
+ #else
+ #define MAX_SKB_FRAGS (65536/PAGE_SIZE + 1)
+ #endif
++extern int sysctl_max_skb_frags;
+ 
+ typedef struct skb_frag_struct skb_frag_t;
+ 
+diff --git a/include/linux/tracepoint.h b/include/linux/tracepoint.h
+index a5f7f3ecafa3..a6e1bca88cc6 100644
+--- a/include/linux/tracepoint.h
++++ b/include/linux/tracepoint.h
+@@ -14,8 +14,10 @@
+  * See the file COPYING for more details.
+  */
+ 
++#include <linux/smp.h>
+ #include <linux/errno.h>
+ #include <linux/types.h>
++#include <linux/cpumask.h>
+ #include <linux/rcupdate.h>
+ #include <linux/static_key.h>
+ 
+@@ -129,6 +131,9 @@ extern void syscall_unregfunc(void);
+ 		void *it_func;						\
+ 		void *__data;						\
+ 									\
++		if (!cpu_online(raw_smp_processor_id()))		\
++			return;						\
++									\
+ 		if (!(cond))						\
+ 			return;						\
+ 		prercu;							\
+diff --git a/include/net/af_unix.h b/include/net/af_unix.h
+index e830c3dff61a..7bb69c9c3c43 100644
+--- a/include/net/af_unix.h
++++ b/include/net/af_unix.h
+@@ -6,8 +6,8 @@
+ #include <linux/mutex.h>
+ #include <net/sock.h>
+ 
+-void unix_inflight(struct file *fp);
+-void unix_notinflight(struct file *fp);
++void unix_inflight(struct user_struct *user, struct file *fp);
++void unix_notinflight(struct user_struct *user, struct file *fp);
+ void unix_gc(void);
+ void wait_for_unix_gc(void);
+ struct sock *unix_get_socket(struct file *filp);
+diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
+index 5e192068e6cb..388dea4da083 100644
+--- a/include/net/ip6_route.h
++++ b/include/net/ip6_route.h
+@@ -64,8 +64,16 @@ static inline bool rt6_need_strict(const struct in6_addr *daddr)
+ 
+ void ip6_route_input(struct sk_buff *skb);
+ 
+-struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
+-				   struct flowi6 *fl6);
++struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
++					 struct flowi6 *fl6, int flags);
++
++static inline struct dst_entry *ip6_route_output(struct net *net,
++						 const struct sock *sk,
++						 struct flowi6 *fl6)
++{
++	return ip6_route_output_flags(net, sk, fl6, 0);
++}
++
+ struct dst_entry *ip6_route_lookup(struct net *net, struct flowi6 *fl6,
+ 				   int flags);
+ 
+diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
+index 54271ed0ed45..13f1a97f6b2b 100644
+--- a/include/net/ip_fib.h
++++ b/include/net/ip_fib.h
+@@ -59,6 +59,7 @@ struct fib_nh_exception {
+ 	struct rtable __rcu		*fnhe_rth_input;
+ 	struct rtable __rcu		*fnhe_rth_output;
+ 	unsigned long			fnhe_stamp;
++	struct rcu_head			rcu;
+ };
+ 
+ struct fnhe_hash_bucket {
+diff --git a/include/net/scm.h b/include/net/scm.h
+index 262532d111f5..59fa93c01d2a 100644
+--- a/include/net/scm.h
++++ b/include/net/scm.h
+@@ -21,6 +21,7 @@ struct scm_creds {
+ struct scm_fp_list {
+ 	short			count;
+ 	short			max;
++	struct user_struct	*user;
+ 	struct file		*fp[SCM_MAX_FD];
+ };
+ 
+diff --git a/include/target/target_core_fabric.h b/include/target/target_core_fabric.h
+index 0f4dc3768587..24c8d9d0d946 100644
+--- a/include/target/target_core_fabric.h
++++ b/include/target/target_core_fabric.h
+@@ -155,8 +155,8 @@ bool	transport_wait_for_tasks(struct se_cmd *);
+ int	transport_check_aborted_status(struct se_cmd *, int);
+ int	transport_send_check_condition_and_sense(struct se_cmd *,
+ 		sense_reason_t, int);
+-int	target_get_sess_cmd(struct se_session *, struct se_cmd *, bool);
+-int	target_put_sess_cmd(struct se_session *, struct se_cmd *);
++int	target_get_sess_cmd(struct se_cmd *, bool);
++int	target_put_sess_cmd(struct se_cmd *);
+ void	target_sess_cmd_list_set_waiting(struct se_session *);
+ void	target_wait_for_sess_cmds(struct se_session *);
+ 
+diff --git a/include/uapi/linux/ipv6.h b/include/uapi/linux/ipv6.h
+index 5efa54ae567c..80f3b74446a1 100644
+--- a/include/uapi/linux/ipv6.h
++++ b/include/uapi/linux/ipv6.h
+@@ -171,6 +171,8 @@ enum {
+ 	DEVCONF_USE_OPTIMISTIC,
+ 	DEVCONF_ACCEPT_RA_MTU,
+ 	DEVCONF_STABLE_SECRET,
++	DEVCONF_USE_OIF_ADDRS_ONLY,
++	DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT,
+ 	DEVCONF_MAX
+ };
+ 
+diff --git a/ipc/msgutil.c b/ipc/msgutil.c
+index 2b491590ebab..71f448e5e927 100644
+--- a/ipc/msgutil.c
++++ b/ipc/msgutil.c
+@@ -123,7 +123,7 @@ struct msg_msg *copy_msg(struct msg_msg *src, struct msg_msg *dst)
+ 	size_t len = src->m_ts;
+ 	size_t alen;
+ 
+-	BUG_ON(dst == NULL);
++	WARN_ON(dst == NULL);
+ 	if (src->m_ts > dst->m_ts)
+ 		return ERR_PTR(-EINVAL);
+ 
+diff --git a/ipc/shm.c b/ipc/shm.c
+index 499a8bd22fad..bbe5f62f2b12 100644
+--- a/ipc/shm.c
++++ b/ipc/shm.c
+@@ -155,9 +155,13 @@ static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id)
+ {
+ 	struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id);
+ 
++	/*
++	 * Callers of shm_lock() must validate the status of the returned ipc
++	 * object pointer (as returned by ipc_lock()), and error out as
++	 * appropriate.
++	 */
+ 	if (IS_ERR(ipcp))
+-		return (struct shmid_kernel *)ipcp;
+-
++		return (void *)ipcp;
+ 	return container_of(ipcp, struct shmid_kernel, shm_perm);
+ }
+ 
+@@ -183,19 +187,33 @@ static inline void shm_rmid(struct ipc_namespace *ns, struct shmid_kernel *s)
+ }
+ 
+ 
+-/* This is called by fork, once for every shm attach. */
+-static void shm_open(struct vm_area_struct *vma)
++static int __shm_open(struct vm_area_struct *vma)
+ {
+ 	struct file *file = vma->vm_file;
+ 	struct shm_file_data *sfd = shm_file_data(file);
+ 	struct shmid_kernel *shp;
+ 
+ 	shp = shm_lock(sfd->ns, sfd->id);
+-	BUG_ON(IS_ERR(shp));
++
++	if (IS_ERR(shp))
++		return PTR_ERR(shp);
++
+ 	shp->shm_atim = get_seconds();
+ 	shp->shm_lprid = task_tgid_vnr(current);
+ 	shp->shm_nattch++;
+ 	shm_unlock(shp);
++	return 0;
++}
++
++/* This is called by fork, once for every shm attach. */
++static void shm_open(struct vm_area_struct *vma)
++{
++	int err = __shm_open(vma);
++	/*
++	 * We raced in the idr lookup or with shm_destroy().
++	 * Either way, the ID is busted.
++	 */
++	WARN_ON_ONCE(err);
+ }
+ 
+ /*
+@@ -258,7 +276,14 @@ static void shm_close(struct vm_area_struct *vma)
+ 	down_write(&shm_ids(ns).rwsem);
+ 	/* remove from the list of attaches of the shm segment */
+ 	shp = shm_lock(ns, sfd->id);
+-	BUG_ON(IS_ERR(shp));
++
++	/*
++	 * We raced in the idr lookup or with shm_destroy().
++	 * Either way, the ID is busted.
++	 */
++	if (WARN_ON_ONCE(IS_ERR(shp)))
++		goto done; /* no-op */
++
+ 	shp->shm_lprid = task_tgid_vnr(current);
+ 	shp->shm_dtim = get_seconds();
+ 	shp->shm_nattch--;
+@@ -266,6 +291,7 @@ static void shm_close(struct vm_area_struct *vma)
+ 		shm_destroy(ns, shp);
+ 	else
+ 		shm_unlock(shp);
++done:
+ 	up_write(&shm_ids(ns).rwsem);
+ }
+ 
+@@ -387,17 +413,25 @@ static int shm_mmap(struct file *file, struct vm_area_struct *vma)
+ 	struct shm_file_data *sfd = shm_file_data(file);
+ 	int ret;
+ 
++	/*
++	 * In case of remap_file_pages() emulation, the file can represent
++	 * removed IPC ID: propogate shm_lock() error to caller.
++	 */
++	ret =__shm_open(vma);
++	if (ret)
++		return ret;
++
+ 	ret = sfd->file->f_op->mmap(sfd->file, vma);
+-	if (ret != 0)
++	if (ret) {
++		shm_close(vma);
+ 		return ret;
++	}
+ 	sfd->vm_ops = vma->vm_ops;
+ #ifdef CONFIG_MMU
+-	BUG_ON(!sfd->vm_ops->fault);
++	WARN_ON(!sfd->vm_ops->fault);
+ #endif
+ 	vma->vm_ops = &shm_vm_ops;
+-	shm_open(vma);
+-
+-	return ret;
++	return 0;
+ }
+ 
+ static int shm_release(struct inode *ino, struct file *file)
+@@ -1192,7 +1226,6 @@ out_fput:
+ out_nattch:
+ 	down_write(&shm_ids(ns).rwsem);
+ 	shp = shm_lock(ns, shmid);
+-	BUG_ON(IS_ERR(shp));
+ 	shp->shm_nattch--;
+ 	if (shm_may_destroy(ns, shp))
+ 		shm_destroy(ns, shp);
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
+index 141d562064a7..6582410a71c7 100644
+--- a/kernel/bpf/verifier.c
++++ b/kernel/bpf/verifier.c
+@@ -1944,7 +1944,7 @@ static void adjust_branches(struct bpf_prog *prog, int pos, int delta)
+ 		/* adjust offset of jmps if necessary */
+ 		if (i < pos && i + insn->off + 1 > pos)
+ 			insn->off += delta;
+-		else if (i > pos && i + insn->off + 1 < pos)
++		else if (i > pos + delta && i + insn->off + 1 <= pos + delta)
+ 			insn->off -= delta;
+ 	}
+ }
+diff --git a/kernel/cgroup.c b/kernel/cgroup.c
+index 4d65b66ae60d..359da3abb004 100644
+--- a/kernel/cgroup.c
++++ b/kernel/cgroup.c
+@@ -4481,6 +4481,7 @@ static void init_and_link_css(struct cgroup_subsys_state *css,
+ 	INIT_LIST_HEAD(&css->sibling);
+ 	INIT_LIST_HEAD(&css->children);
+ 	css->serial_nr = css_serial_nr_next++;
++	atomic_set(&css->online_cnt, 0);
+ 
+ 	if (cgroup_parent(cgrp)) {
+ 		css->parent = cgroup_css(cgroup_parent(cgrp), ss);
+@@ -4503,6 +4504,10 @@ static int online_css(struct cgroup_subsys_state *css)
+ 	if (!ret) {
+ 		css->flags |= CSS_ONLINE;
+ 		rcu_assign_pointer(css->cgroup->subsys[ss->id], css);
++
++		atomic_inc(&css->online_cnt);
++		if (css->parent)
++			atomic_inc(&css->parent->online_cnt);
+ 	}
+ 	return ret;
+ }
+@@ -4740,10 +4745,15 @@ static void css_killed_work_fn(struct work_struct *work)
+ 		container_of(work, struct cgroup_subsys_state, destroy_work);
+ 
+ 	mutex_lock(&cgroup_mutex);
+-	offline_css(css);
+-	mutex_unlock(&cgroup_mutex);
+ 
+-	css_put(css);
++	do {
++		offline_css(css);
++		css_put(css);
++		/* @css can't go away while we're holding cgroup_mutex */
++		css = css->parent;
++	} while (css && atomic_dec_and_test(&css->online_cnt));
++
++	mutex_unlock(&cgroup_mutex);
+ }
+ 
+ /* css kill confirmation processing requires process context, bounce */
+@@ -4752,8 +4762,10 @@ static void css_killed_ref_fn(struct percpu_ref *ref)
+ 	struct cgroup_subsys_state *css =
+ 		container_of(ref, struct cgroup_subsys_state, refcnt);
+ 
+-	INIT_WORK(&css->destroy_work, css_killed_work_fn);
+-	queue_work(cgroup_destroy_wq, &css->destroy_work);
++	if (atomic_dec_and_test(&css->online_cnt)) {
++		INIT_WORK(&css->destroy_work, css_killed_work_fn);
++		queue_work(cgroup_destroy_wq, &css->destroy_work);
++	}
+ }
+ 
+ /**
+diff --git a/kernel/workqueue.c b/kernel/workqueue.c
+index 5c01664c26e2..6d631161705c 100644
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -127,6 +127,11 @@ enum {
+  *
+  * PR: wq_pool_mutex protected for writes.  Sched-RCU protected for reads.
+  *
++ * PW: wq_pool_mutex and wq->mutex protected for writes.  Either for reads.
++ *
++ * PWR: wq_pool_mutex and wq->mutex protected for writes.  Either or
++ *      sched-RCU for reads.
++ *
+  * WQ: wq->mutex protected.
+  *
+  * WR: wq->mutex protected for writes.  Sched-RCU protected for reads.
+@@ -247,8 +252,8 @@ struct workqueue_struct {
+ 	int			nr_drainers;	/* WQ: drain in progress */
+ 	int			saved_max_active; /* WQ: saved pwq max_active */
+ 
+-	struct workqueue_attrs	*unbound_attrs;	/* WQ: only for unbound wqs */
+-	struct pool_workqueue	*dfl_pwq;	/* WQ: only for unbound wqs */
++	struct workqueue_attrs	*unbound_attrs;	/* PW: only for unbound wqs */
++	struct pool_workqueue	*dfl_pwq;	/* PW: only for unbound wqs */
+ 
+ #ifdef CONFIG_SYSFS
+ 	struct wq_device	*wq_dev;	/* I: for sysfs interface */
+@@ -268,7 +273,7 @@ struct workqueue_struct {
+ 	/* hot fields used during command issue, aligned to cacheline */
+ 	unsigned int		flags ____cacheline_aligned; /* WQ: WQ_* flags */
+ 	struct pool_workqueue __percpu *cpu_pwqs; /* I: per-cpu pwqs */
+-	struct pool_workqueue __rcu *numa_pwq_tbl[]; /* FR: unbound pwqs indexed by node */
++	struct pool_workqueue __rcu *numa_pwq_tbl[]; /* PWR: unbound pwqs indexed by node */
+ };
+ 
+ static struct kmem_cache *pwq_cache;
+@@ -347,6 +352,12 @@ static void workqueue_sysfs_unregister(struct workqueue_struct *wq);
+ 			   lockdep_is_held(&wq->mutex),			\
+ 			   "sched RCU or wq->mutex should be held")
+ 
++#define assert_rcu_or_wq_mutex_or_pool_mutex(wq)			\
++	rcu_lockdep_assert(rcu_read_lock_sched_held() ||		\
++			   lockdep_is_held(&wq->mutex) ||		\
++			   lockdep_is_held(&wq_pool_mutex),		\
++			   "sched RCU, wq->mutex or wq_pool_mutex should be held")
++
+ #define for_each_cpu_worker_pool(pool, cpu)				\
+ 	for ((pool) = &per_cpu(cpu_worker_pools, cpu)[0];		\
+ 	     (pool) < &per_cpu(cpu_worker_pools, cpu)[NR_STD_WORKER_POOLS]; \
+@@ -551,7 +562,8 @@ static int worker_pool_assign_id(struct worker_pool *pool)
+  * @wq: the target workqueue
+  * @node: the node ID
+  *
+- * This must be called either with pwq_lock held or sched RCU read locked.
++ * This must be called with any of wq_pool_mutex, wq->mutex or sched RCU
++ * read locked.
+  * If the pwq needs to be used beyond the locking in effect, the caller is
+  * responsible for guaranteeing that the pwq stays online.
+  *
+@@ -560,7 +572,17 @@ static int worker_pool_assign_id(struct worker_pool *pool)
+ static struct pool_workqueue *unbound_pwq_by_node(struct workqueue_struct *wq,
+ 						  int node)
+ {
+-	assert_rcu_or_wq_mutex(wq);
++	assert_rcu_or_wq_mutex_or_pool_mutex(wq);
++
++	/*
++	 * XXX: @node can be NUMA_NO_NODE if CPU goes offline while a
++	 * delayed item is pending.  The plan is to keep CPU -> NODE
++	 * mapping valid and stable across CPU on/offlines.  Once that
++	 * happens, this workaround can be removed.
++	 */
++	if (unlikely(node == NUMA_NO_NODE))
++		return wq->dfl_pwq;
++
+ 	return rcu_dereference_raw(wq->numa_pwq_tbl[node]);
+ }
+ 
+@@ -1451,13 +1473,13 @@ static void __queue_delayed_work(int cpu, struct workqueue_struct *wq,
+ 	timer_stats_timer_set_start_info(&dwork->timer);
+ 
+ 	dwork->wq = wq;
+-	/* timer isn't guaranteed to run in this cpu, record earlier */
+-	if (cpu == WORK_CPU_UNBOUND)
+-		cpu = raw_smp_processor_id();
+ 	dwork->cpu = cpu;
+ 	timer->expires = jiffies + delay;
+ 
+-	add_timer_on(timer, cpu);
++	if (unlikely(cpu != WORK_CPU_UNBOUND))
++		add_timer_on(timer, cpu);
++	else
++		add_timer(timer);
+ }
+ 
+ /**
+@@ -3425,17 +3447,6 @@ static struct pool_workqueue *alloc_unbound_pwq(struct workqueue_struct *wq,
+ 	return pwq;
+ }
+ 
+-/* undo alloc_unbound_pwq(), used only in the error path */
+-static void free_unbound_pwq(struct pool_workqueue *pwq)
+-{
+-	lockdep_assert_held(&wq_pool_mutex);
+-
+-	if (pwq) {
+-		put_unbound_pool(pwq->pool);
+-		kmem_cache_free(pwq_cache, pwq);
+-	}
+-}
+-
+ /**
+  * wq_calc_node_mask - calculate a wq_attrs' cpumask for the specified node
+  * @attrs: the wq_attrs of interest
+@@ -3488,6 +3499,7 @@ static struct pool_workqueue *numa_pwq_tbl_install(struct workqueue_struct *wq,
+ {
+ 	struct pool_workqueue *old_pwq;
+ 
++	lockdep_assert_held(&wq_pool_mutex);
+ 	lockdep_assert_held(&wq->mutex);
+ 
+ 	/* link_pwq() can handle duplicate calls */
+@@ -3498,42 +3510,48 @@ static struct pool_workqueue *numa_pwq_tbl_install(struct workqueue_struct *wq,
+ 	return old_pwq;
+ }
+ 
+-/**
+- * apply_workqueue_attrs - apply new workqueue_attrs to an unbound workqueue
+- * @wq: the target workqueue
+- * @attrs: the workqueue_attrs to apply, allocated with alloc_workqueue_attrs()
+- *
+- * Apply @attrs to an unbound workqueue @wq.  Unless disabled, on NUMA
+- * machines, this function maps a separate pwq to each NUMA node with
+- * possibles CPUs in @attrs->cpumask so that work items are affine to the
+- * NUMA node it was issued on.  Older pwqs are released as in-flight work
+- * items finish.  Note that a work item which repeatedly requeues itself
+- * back-to-back will stay on its current pwq.
+- *
+- * Performs GFP_KERNEL allocations.
+- *
+- * Return: 0 on success and -errno on failure.
+- */
+-int apply_workqueue_attrs(struct workqueue_struct *wq,
+-			  const struct workqueue_attrs *attrs)
++/* context to store the prepared attrs & pwqs before applying */
++struct apply_wqattrs_ctx {
++	struct workqueue_struct	*wq;		/* target workqueue */
++	struct workqueue_attrs	*attrs;		/* attrs to apply */
++	struct pool_workqueue	*dfl_pwq;
++	struct pool_workqueue	*pwq_tbl[];
++};
++
++/* free the resources after success or abort */
++static void apply_wqattrs_cleanup(struct apply_wqattrs_ctx *ctx)
+ {
++	if (ctx) {
++		int node;
++
++		for_each_node(node)
++			put_pwq_unlocked(ctx->pwq_tbl[node]);
++		put_pwq_unlocked(ctx->dfl_pwq);
++
++		free_workqueue_attrs(ctx->attrs);
++
++		kfree(ctx);
++	}
++}
++
++/* allocate the attrs and pwqs for later installation */
++static struct apply_wqattrs_ctx *
++apply_wqattrs_prepare(struct workqueue_struct *wq,
++		      const struct workqueue_attrs *attrs)
++{
++	struct apply_wqattrs_ctx *ctx;
+ 	struct workqueue_attrs *new_attrs, *tmp_attrs;
+-	struct pool_workqueue **pwq_tbl, *dfl_pwq;
+-	int node, ret;
++	int node;
+ 
+-	/* only unbound workqueues can change attributes */
+-	if (WARN_ON(!(wq->flags & WQ_UNBOUND)))
+-		return -EINVAL;
++	lockdep_assert_held(&wq_pool_mutex);
+ 
+-	/* creating multiple pwqs breaks ordering guarantee */
+-	if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs)))
+-		return -EINVAL;
++	ctx = kzalloc(sizeof(*ctx) + nr_node_ids * sizeof(ctx->pwq_tbl[0]),
++		      GFP_KERNEL);
+ 
+-	pwq_tbl = kzalloc(nr_node_ids * sizeof(pwq_tbl[0]), GFP_KERNEL);
+ 	new_attrs = alloc_workqueue_attrs(GFP_KERNEL);
+ 	tmp_attrs = alloc_workqueue_attrs(GFP_KERNEL);
+-	if (!pwq_tbl || !new_attrs || !tmp_attrs)
+-		goto enomem;
++	if (!ctx || !new_attrs || !tmp_attrs)
++		goto out_free;
+ 
+ 	/* make a copy of @attrs and sanitize it */
+ 	copy_workqueue_attrs(new_attrs, attrs);
+@@ -3547,75 +3565,111 @@ int apply_workqueue_attrs(struct workqueue_struct *wq,
+ 	copy_workqueue_attrs(tmp_attrs, new_attrs);
+ 
+ 	/*
+-	 * CPUs should stay stable across pwq creations and installations.
+-	 * Pin CPUs, determine the target cpumask for each node and create
+-	 * pwqs accordingly.
+-	 */
+-	get_online_cpus();
+-
+-	mutex_lock(&wq_pool_mutex);
+-
+-	/*
+ 	 * If something goes wrong during CPU up/down, we'll fall back to
+ 	 * the default pwq covering whole @attrs->cpumask.  Always create
+ 	 * it even if we don't use it immediately.
+ 	 */
+-	dfl_pwq = alloc_unbound_pwq(wq, new_attrs);
+-	if (!dfl_pwq)
+-		goto enomem_pwq;
++	ctx->dfl_pwq = alloc_unbound_pwq(wq, new_attrs);
++	if (!ctx->dfl_pwq)
++		goto out_free;
+ 
+ 	for_each_node(node) {
+ 		if (wq_calc_node_cpumask(attrs, node, -1, tmp_attrs->cpumask)) {
+-			pwq_tbl[node] = alloc_unbound_pwq(wq, tmp_attrs);
+-			if (!pwq_tbl[node])
+-				goto enomem_pwq;
++			ctx->pwq_tbl[node] = alloc_unbound_pwq(wq, tmp_attrs);
++			if (!ctx->pwq_tbl[node])
++				goto out_free;
+ 		} else {
+-			dfl_pwq->refcnt++;
+-			pwq_tbl[node] = dfl_pwq;
++			ctx->dfl_pwq->refcnt++;
++			ctx->pwq_tbl[node] = ctx->dfl_pwq;
+ 		}
+ 	}
+ 
+-	mutex_unlock(&wq_pool_mutex);
++	ctx->attrs = new_attrs;
++	ctx->wq = wq;
++	free_workqueue_attrs(tmp_attrs);
++	return ctx;
++
++out_free:
++	free_workqueue_attrs(tmp_attrs);
++	free_workqueue_attrs(new_attrs);
++	apply_wqattrs_cleanup(ctx);
++	return NULL;
++}
++
++/* set attrs and install prepared pwqs, @ctx points to old pwqs on return */
++static void apply_wqattrs_commit(struct apply_wqattrs_ctx *ctx)
++{
++	int node;
+ 
+ 	/* all pwqs have been created successfully, let's install'em */
+-	mutex_lock(&wq->mutex);
++	mutex_lock(&ctx->wq->mutex);
+ 
+-	copy_workqueue_attrs(wq->unbound_attrs, new_attrs);
++	copy_workqueue_attrs(ctx->wq->unbound_attrs, ctx->attrs);
+ 
+ 	/* save the previous pwq and install the new one */
+ 	for_each_node(node)
+-		pwq_tbl[node] = numa_pwq_tbl_install(wq, node, pwq_tbl[node]);
++		ctx->pwq_tbl[node] = numa_pwq_tbl_install(ctx->wq, node,
++							  ctx->pwq_tbl[node]);
+ 
+ 	/* @dfl_pwq might not have been used, ensure it's linked */
+-	link_pwq(dfl_pwq);
+-	swap(wq->dfl_pwq, dfl_pwq);
++	link_pwq(ctx->dfl_pwq);
++	swap(ctx->wq->dfl_pwq, ctx->dfl_pwq);
+ 
+-	mutex_unlock(&wq->mutex);
++	mutex_unlock(&ctx->wq->mutex);
++}
+ 
+-	/* put the old pwqs */
+-	for_each_node(node)
+-		put_pwq_unlocked(pwq_tbl[node]);
+-	put_pwq_unlocked(dfl_pwq);
++/**
++ * apply_workqueue_attrs - apply new workqueue_attrs to an unbound workqueue
++ * @wq: the target workqueue
++ * @attrs: the workqueue_attrs to apply, allocated with alloc_workqueue_attrs()
++ *
++ * Apply @attrs to an unbound workqueue @wq.  Unless disabled, on NUMA
++ * machines, this function maps a separate pwq to each NUMA node with
++ * possibles CPUs in @attrs->cpumask so that work items are affine to the
++ * NUMA node it was issued on.  Older pwqs are released as in-flight work
++ * items finish.  Note that a work item which repeatedly requeues itself
++ * back-to-back will stay on its current pwq.
++ *
++ * Performs GFP_KERNEL allocations.
++ *
++ * Return: 0 on success and -errno on failure.
++ */
++int apply_workqueue_attrs(struct workqueue_struct *wq,
++			  const struct workqueue_attrs *attrs)
++{
++	struct apply_wqattrs_ctx *ctx;
++	int ret = -ENOMEM;
+ 
+-	put_online_cpus();
+-	ret = 0;
+-	/* fall through */
+-out_free:
+-	free_workqueue_attrs(tmp_attrs);
+-	free_workqueue_attrs(new_attrs);
+-	kfree(pwq_tbl);
+-	return ret;
++	/* only unbound workqueues can change attributes */
++	if (WARN_ON(!(wq->flags & WQ_UNBOUND)))
++		return -EINVAL;
++
++	/* creating multiple pwqs breaks ordering guarantee */
++	if (WARN_ON((wq->flags & __WQ_ORDERED) && !list_empty(&wq->pwqs)))
++		return -EINVAL;
++
++	/*
++	 * CPUs should stay stable across pwq creations and installations.
++	 * Pin CPUs, determine the target cpumask for each node and create
++	 * pwqs accordingly.
++	 */
++	get_online_cpus();
++	mutex_lock(&wq_pool_mutex);
++
++	ctx = apply_wqattrs_prepare(wq, attrs);
++
++	/* the ctx has been prepared successfully, let's commit it */
++	if (ctx) {
++		apply_wqattrs_commit(ctx);
++		ret = 0;
++	}
+ 
+-enomem_pwq:
+-	free_unbound_pwq(dfl_pwq);
+-	for_each_node(node)
+-		if (pwq_tbl && pwq_tbl[node] != dfl_pwq)
+-			free_unbound_pwq(pwq_tbl[node]);
+ 	mutex_unlock(&wq_pool_mutex);
+ 	put_online_cpus();
+-enomem:
+-	ret = -ENOMEM;
+-	goto out_free;
++
++	apply_wqattrs_cleanup(ctx);
++
++	return ret;
+ }
+ 
+ /**
+diff --git a/lib/klist.c b/lib/klist.c
+index 89b485a2a58d..2a072bfaeace 100644
+--- a/lib/klist.c
++++ b/lib/klist.c
+@@ -282,9 +282,9 @@ void klist_iter_init_node(struct klist *k, struct klist_iter *i,
+ 			  struct klist_node *n)
+ {
+ 	i->i_klist = k;
+-	i->i_cur = n;
+-	if (n)
+-		kref_get(&n->n_ref);
++	i->i_cur = NULL;
++	if (n && kref_get_unless_zero(&n->n_ref))
++		i->i_cur = n;
+ }
+ EXPORT_SYMBOL_GPL(klist_iter_init_node);
+ 
+diff --git a/mm/mmap.c b/mm/mmap.c
+index b639fa2721d8..d30b8f8f02b1 100644
+--- a/mm/mmap.c
++++ b/mm/mmap.c
+@@ -2654,12 +2654,29 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ 	if (!vma || !(vma->vm_flags & VM_SHARED))
+ 		goto out;
+ 
+-	if (start < vma->vm_start || start + size > vma->vm_end)
++	if (start < vma->vm_start)
+ 		goto out;
+ 
+-	if (pgoff == linear_page_index(vma, start)) {
+-		ret = 0;
+-		goto out;
++	if (start + size > vma->vm_end) {
++		struct vm_area_struct *next;
++
++		for (next = vma->vm_next; next; next = next->vm_next) {
++			/* hole between vmas ? */
++			if (next->vm_start != next->vm_prev->vm_end)
++				goto out;
++
++			if (next->vm_file != vma->vm_file)
++				goto out;
++
++			if (next->vm_flags != vma->vm_flags)
++				goto out;
++
++			if (start + size <= next->vm_end)
++				break;
++		}
++
++		if (!next)
++			goto out;
+ 	}
+ 
+ 	prot |= vma->vm_flags & VM_READ ? PROT_READ : 0;
+@@ -2669,9 +2686,16 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
+ 	flags &= MAP_NONBLOCK;
+ 	flags |= MAP_SHARED | MAP_FIXED | MAP_POPULATE;
+ 	if (vma->vm_flags & VM_LOCKED) {
++		struct vm_area_struct *tmp;
+ 		flags |= MAP_LOCKED;
++
+ 		/* drop PG_Mlocked flag for over-mapped range */
+-		munlock_vma_pages_range(vma, start, start + size);
++		for (tmp = vma; tmp->vm_start >= start + size;
++				tmp = tmp->vm_next) {
++			munlock_vma_pages_range(tmp,
++					max(tmp->vm_start, start),
++					min(tmp->vm_end, start + size));
++		}
+ 	}
+ 
+ 	file = get_file(vma->vm_file);
+diff --git a/net/bridge/br.c b/net/bridge/br.c
+index 02c24cf63c34..c72e01cf09d0 100644
+--- a/net/bridge/br.c
++++ b/net/bridge/br.c
+@@ -121,6 +121,7 @@ static struct notifier_block br_device_notifier = {
+ 	.notifier_call = br_device_event
+ };
+ 
++/* called with RTNL */
+ static int br_netdev_switch_event(struct notifier_block *unused,
+ 				  unsigned long event, void *ptr)
+ {
+@@ -130,7 +131,6 @@ static int br_netdev_switch_event(struct notifier_block *unused,
+ 	struct netdev_switch_notifier_fdb_info *fdb_info;
+ 	int err = NOTIFY_DONE;
+ 
+-	rtnl_lock();
+ 	p = br_port_get_rtnl(dev);
+ 	if (!p)
+ 		goto out;
+@@ -155,7 +155,6 @@ static int br_netdev_switch_event(struct notifier_block *unused,
+ 	}
+ 
+ out:
+-	rtnl_unlock();
+ 	return err;
+ }
+ 
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
+index 2c35c02a931e..3556791fdc6e 100644
+--- a/net/core/flow_dissector.c
++++ b/net/core/flow_dissector.c
+@@ -113,7 +113,6 @@ ip:
+ 	case htons(ETH_P_IPV6): {
+ 		const struct ipv6hdr *iph;
+ 		struct ipv6hdr _iph;
+-		__be32 flow_label;
+ 
+ ipv6:
+ 		iph = __skb_header_pointer(skb, nhoff, sizeof(_iph), data, hlen, &_iph);
+@@ -130,8 +129,9 @@ ipv6:
+ 		flow->src = (__force __be32)ipv6_addr_hash(&iph->saddr);
+ 		flow->dst = (__force __be32)ipv6_addr_hash(&iph->daddr);
+ 
+-		flow_label = ip6_flowlabel(iph);
+-		if (flow_label) {
++		if (skb && ip6_flowlabel(iph)) {
++			__be32 flow_label = ip6_flowlabel(iph);
++
+ 			/* Awesome, IPv6 packet has a flow label so we can
+ 			 * use that to represent the ports without any
+ 			 * further dissection.
+@@ -233,6 +233,13 @@ ipv6:
+ 					return false;
+ 				proto = eth->h_proto;
+ 				nhoff += sizeof(*eth);
++
++				/* Cap headers that we access via pointers at the
++				 * end of the Ethernet header as our maximum alignment
++				 * at that point is only 2 bytes.
++				 */
++				if (NET_IP_ALIGN)
++					hlen = nhoff;
+ 			}
+ 			goto again;
+ 		}
+diff --git a/net/core/scm.c b/net/core/scm.c
+index 8a1741b14302..dce0acb929f1 100644
+--- a/net/core/scm.c
++++ b/net/core/scm.c
+@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ 		*fplp = fpl;
+ 		fpl->count = 0;
+ 		fpl->max = SCM_MAX_FD;
++		fpl->user = NULL;
+ 	}
+ 	fpp = &fpl->fp[fpl->count];
+ 
+@@ -107,6 +108,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
+ 		*fpp++ = file;
+ 		fpl->count++;
+ 	}
++
++	if (!fpl->user)
++		fpl->user = get_uid(current_user());
++
+ 	return num;
+ }
+ 
+@@ -119,6 +124,7 @@ void __scm_destroy(struct scm_cookie *scm)
+ 		scm->fp = NULL;
+ 		for (i=fpl->count-1; i>=0; i--)
+ 			fput(fpl->fp[i]);
++		free_uid(fpl->user);
+ 		kfree(fpl);
+ 	}
+ }
+@@ -336,6 +342,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
+ 		for (i = 0; i < fpl->count; i++)
+ 			get_file(fpl->fp[i]);
+ 		new_fpl->max = new_fpl->count;
++		new_fpl->user = get_uid(fpl->user);
+ 	}
+ 	return new_fpl;
+ }
+diff --git a/net/core/skbuff.c b/net/core/skbuff.c
+index 2e5fcda16570..c9793c6c5005 100644
+--- a/net/core/skbuff.c
++++ b/net/core/skbuff.c
+@@ -79,6 +79,8 @@
+ 
+ struct kmem_cache *skbuff_head_cache __read_mostly;
+ static struct kmem_cache *skbuff_fclone_cache __read_mostly;
++int sysctl_max_skb_frags __read_mostly = MAX_SKB_FRAGS;
++EXPORT_SYMBOL(sysctl_max_skb_frags);
+ 
+ /**
+  *	skb_panic - private function for out-of-line support
+diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
+index 95b6139d710c..a6beb7b6ae55 100644
+--- a/net/core/sysctl_net_core.c
++++ b/net/core/sysctl_net_core.c
+@@ -26,6 +26,7 @@ static int zero = 0;
+ static int one = 1;
+ static int min_sndbuf = SOCK_MIN_SNDBUF;
+ static int min_rcvbuf = SOCK_MIN_RCVBUF;
++static int max_skb_frags = MAX_SKB_FRAGS;
+ 
+ static int net_msg_warn;	/* Unused, but still a sysctl */
+ 
+@@ -392,6 +393,15 @@ static struct ctl_table net_core_table[] = {
+ 		.mode		= 0644,
+ 		.proc_handler	= proc_dointvec
+ 	},
++	{
++		.procname	= "max_skb_frags",
++		.data		= &sysctl_max_skb_frags,
++		.maxlen		= sizeof(int),
++		.mode		= 0644,
++		.proc_handler	= proc_dointvec_minmax,
++		.extra1		= &one,
++		.extra2		= &max_skb_frags,
++	},
+ 	{ }
+ };
+ 
+diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
+index 419d23c53ec7..280d46f947ea 100644
+--- a/net/ipv4/devinet.c
++++ b/net/ipv4/devinet.c
+@@ -1839,7 +1839,7 @@ static int inet_netconf_get_devconf(struct sk_buff *in_skb,
+ 	if (err < 0)
+ 		goto errout;
+ 
+-	err = EINVAL;
++	err = -EINVAL;
+ 	if (!tb[NETCONFA_IFINDEX])
+ 		goto errout;
+ 
+diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c
+index 6ddde89996f4..b6c7bdea4853 100644
+--- a/net/ipv4/ip_sockglue.c
++++ b/net/ipv4/ip_sockglue.c
+@@ -249,6 +249,8 @@ int ip_cmsg_send(struct net *net, struct msghdr *msg, struct ipcm_cookie *ipc,
+ 		switch (cmsg->cmsg_type) {
+ 		case IP_RETOPTS:
+ 			err = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr));
++
++			/* Our caller is responsible for freeing ipc->opt */
+ 			err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
+ 					     err < 40 ? err : 40);
+ 			if (err)
+diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
+index 05ff44b758df..f6ee0d561aab 100644
+--- a/net/ipv4/ping.c
++++ b/net/ipv4/ping.c
+@@ -745,8 +745,10 @@ static int ping_v4_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 
+ 	if (msg->msg_controllen) {
+ 		err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
+-		if (err)
++		if (unlikely(err)) {
++			kfree(ipc.opt);
+ 			return err;
++		}
+ 		if (ipc.opt)
+ 			free = 1;
+ 	}
+diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
+index 561cd4b8fc6e..c77aac75759d 100644
+--- a/net/ipv4/raw.c
++++ b/net/ipv4/raw.c
+@@ -543,8 +543,10 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 
+ 	if (msg->msg_controllen) {
+ 		err = ip_cmsg_send(sock_net(sk), msg, &ipc, false);
+-		if (err)
++		if (unlikely(err)) {
++			kfree(ipc.opt);
+ 			goto out;
++		}
+ 		if (ipc.opt)
+ 			free = 1;
+ 	}
+diff --git a/net/ipv4/route.c b/net/ipv4/route.c
+index f45f2a12f37b..1d3cdb4d4ebc 100644
+--- a/net/ipv4/route.c
++++ b/net/ipv4/route.c
+@@ -125,6 +125,7 @@ static int ip_rt_mtu_expires __read_mostly	= 10 * 60 * HZ;
+ static int ip_rt_min_pmtu __read_mostly		= 512 + 20 + 20;
+ static int ip_rt_min_advmss __read_mostly	= 256;
+ 
++static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
+ /*
+  *	Interface to generic destination cache.
+  */
+@@ -753,7 +754,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
+ 				struct fib_nh *nh = &FIB_RES_NH(res);
+ 
+ 				update_or_create_fnhe(nh, fl4->daddr, new_gw,
+-						      0, 0);
++						0, jiffies + ip_rt_gc_timeout);
+ 			}
+ 			if (kill_route)
+ 				rt->dst.obsolete = DST_OBSOLETE_KILL;
+@@ -1538,6 +1539,36 @@ static void ip_handle_martian_source(struct net_device *dev,
+ #endif
+ }
+ 
++static void ip_del_fnhe(struct fib_nh *nh, __be32 daddr)
++{
++	struct fnhe_hash_bucket *hash;
++	struct fib_nh_exception *fnhe, __rcu **fnhe_p;
++	u32 hval = fnhe_hashfun(daddr);
++
++	spin_lock_bh(&fnhe_lock);
++
++	hash = rcu_dereference_protected(nh->nh_exceptions,
++					 lockdep_is_held(&fnhe_lock));
++	hash += hval;
++
++	fnhe_p = &hash->chain;
++	fnhe = rcu_dereference_protected(*fnhe_p, lockdep_is_held(&fnhe_lock));
++	while (fnhe) {
++		if (fnhe->fnhe_daddr == daddr) {
++			rcu_assign_pointer(*fnhe_p, rcu_dereference_protected(
++				fnhe->fnhe_next, lockdep_is_held(&fnhe_lock)));
++			fnhe_flush_routes(fnhe);
++			kfree_rcu(fnhe, rcu);
++			break;
++		}
++		fnhe_p = &fnhe->fnhe_next;
++		fnhe = rcu_dereference_protected(fnhe->fnhe_next,
++						 lockdep_is_held(&fnhe_lock));
++	}
++
++	spin_unlock_bh(&fnhe_lock);
++}
++
+ /* called in rcu_read_lock() section */
+ static int __mkroute_input(struct sk_buff *skb,
+ 			   const struct fib_result *res,
+@@ -1592,11 +1623,20 @@ static int __mkroute_input(struct sk_buff *skb,
+ 
+ 	fnhe = find_exception(&FIB_RES_NH(*res), daddr);
+ 	if (do_cache) {
+-		if (fnhe)
++		if (fnhe) {
+ 			rth = rcu_dereference(fnhe->fnhe_rth_input);
+-		else
+-			rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
++			if (rth && rth->dst.expires &&
++			    time_after(jiffies, rth->dst.expires)) {
++				ip_del_fnhe(&FIB_RES_NH(*res), daddr);
++				fnhe = NULL;
++			} else {
++				goto rt_cache;
++			}
++		}
++
++		rth = rcu_dereference(FIB_RES_NH(*res).nh_rth_input);
+ 
++rt_cache:
+ 		if (rt_cache_valid(rth)) {
+ 			skb_dst_set_noref(skb, &rth->dst);
+ 			goto out;
+@@ -1945,19 +1985,29 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
+ 		struct fib_nh *nh = &FIB_RES_NH(*res);
+ 
+ 		fnhe = find_exception(nh, fl4->daddr);
+-		if (fnhe)
++		if (fnhe) {
+ 			prth = &fnhe->fnhe_rth_output;
+-		else {
+-			if (unlikely(fl4->flowi4_flags &
+-				     FLOWI_FLAG_KNOWN_NH &&
+-				     !(nh->nh_gw &&
+-				       nh->nh_scope == RT_SCOPE_LINK))) {
+-				do_cache = false;
+-				goto add;
++			rth = rcu_dereference(*prth);
++			if (rth && rth->dst.expires &&
++			    time_after(jiffies, rth->dst.expires)) {
++				ip_del_fnhe(nh, fl4->daddr);
++				fnhe = NULL;
++			} else {
++				goto rt_cache;
+ 			}
+-			prth = raw_cpu_ptr(nh->nh_pcpu_rth_output);
+ 		}
++
++		if (unlikely(fl4->flowi4_flags &
++			     FLOWI_FLAG_KNOWN_NH &&
++			     !(nh->nh_gw &&
++			       nh->nh_scope == RT_SCOPE_LINK))) {
++			do_cache = false;
++			goto add;
++		}
++		prth = raw_cpu_ptr(nh->nh_pcpu_rth_output);
+ 		rth = rcu_dereference(*prth);
++
++rt_cache:
+ 		if (rt_cache_valid(rth)) {
+ 			dst_hold(&rth->dst);
+ 			return rth;
+@@ -2504,7 +2554,6 @@ void ip_rt_multicast_event(struct in_device *in_dev)
+ }
+ 
+ #ifdef CONFIG_SYSCTL
+-static int ip_rt_gc_timeout __read_mostly	= RT_GC_TIMEOUT;
+ static int ip_rt_gc_interval __read_mostly  = 60 * HZ;
+ static int ip_rt_gc_min_interval __read_mostly	= HZ / 2;
+ static int ip_rt_gc_elasticity __read_mostly	= 8;
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index bb2ce74f6004..19d385a0f02d 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -279,6 +279,7 @@
+ 
+ #include <asm/uaccess.h>
+ #include <asm/ioctls.h>
++#include <asm/unaligned.h>
+ #include <net/busy_poll.h>
+ 
+ int sysctl_tcp_fin_timeout __read_mostly = TCP_FIN_TIMEOUT;
+@@ -921,7 +922,7 @@ new_segment:
+ 
+ 		i = skb_shinfo(skb)->nr_frags;
+ 		can_coalesce = skb_can_coalesce(skb, i, page, offset);
+-		if (!can_coalesce && i >= MAX_SKB_FRAGS) {
++		if (!can_coalesce && i >= sysctl_max_skb_frags) {
+ 			tcp_mark_push(tp, skb);
+ 			goto new_segment;
+ 		}
+@@ -1187,7 +1188,7 @@ new_segment:
+ 
+ 			if (!skb_can_coalesce(skb, i, pfrag->page,
+ 					      pfrag->offset)) {
+-				if (i == MAX_SKB_FRAGS || !sg) {
++				if (i == sysctl_max_skb_frags || !sg) {
+ 					tcp_mark_push(tp, skb);
+ 					goto new_segment;
+ 				}
+@@ -2603,6 +2604,7 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
+ 	const struct inet_connection_sock *icsk = inet_csk(sk);
+ 	u32 now = tcp_time_stamp;
+ 	unsigned int start;
++	u64 rate64;
+ 	u32 rate;
+ 
+ 	memset(info, 0, sizeof(*info));
+@@ -2665,15 +2667,17 @@ void tcp_get_info(struct sock *sk, struct tcp_info *info)
+ 	info->tcpi_total_retrans = tp->total_retrans;
+ 
+ 	rate = READ_ONCE(sk->sk_pacing_rate);
+-	info->tcpi_pacing_rate = rate != ~0U ? rate : ~0ULL;
++	rate64 = rate != ~0U ? rate : ~0ULL;
++	put_unaligned(rate64, &info->tcpi_pacing_rate);
+ 
+ 	rate = READ_ONCE(sk->sk_max_pacing_rate);
+-	info->tcpi_max_pacing_rate = rate != ~0U ? rate : ~0ULL;
++	rate64 = rate != ~0U ? rate : ~0ULL;
++	put_unaligned(rate64, &info->tcpi_max_pacing_rate);
+ 
+ 	do {
+ 		start = u64_stats_fetch_begin_irq(&tp->syncp);
+-		info->tcpi_bytes_acked = tp->bytes_acked;
+-		info->tcpi_bytes_received = tp->bytes_received;
++		put_unaligned(tp->bytes_acked, &info->tcpi_bytes_acked);
++		put_unaligned(tp->bytes_received, &info->tcpi_bytes_received);
+ 	} while (u64_stats_fetch_retry_irq(&tp->syncp, start));
+ }
+ EXPORT_SYMBOL_GPL(tcp_get_info);
+diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
+index cd18c3d3251e..13b92d595138 100644
+--- a/net/ipv4/tcp_ipv4.c
++++ b/net/ipv4/tcp_ipv4.c
+@@ -705,7 +705,8 @@ release_sk1:
+    outside socket context is ugly, certainly. What can I do?
+  */
+ 
+-static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
++static void tcp_v4_send_ack(struct net *net,
++			    struct sk_buff *skb, u32 seq, u32 ack,
+ 			    u32 win, u32 tsval, u32 tsecr, int oif,
+ 			    struct tcp_md5sig_key *key,
+ 			    int reply_flags, u8 tos)
+@@ -720,7 +721,6 @@ static void tcp_v4_send_ack(struct sk_buff *skb, u32 seq, u32 ack,
+ 			];
+ 	} rep;
+ 	struct ip_reply_arg arg;
+-	struct net *net = dev_net(skb_dst(skb)->dev);
+ 
+ 	memset(&rep.th, 0, sizeof(struct tcphdr));
+ 	memset(&arg, 0, sizeof(arg));
+@@ -782,7 +782,8 @@ static void tcp_v4_timewait_ack(struct sock *sk, struct sk_buff *skb)
+ 	struct inet_timewait_sock *tw = inet_twsk(sk);
+ 	struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
+ 
+-	tcp_v4_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
++	tcp_v4_send_ack(sock_net(sk), skb,
++			tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
+ 			tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
+ 			tcp_time_stamp + tcptw->tw_ts_offset,
+ 			tcptw->tw_ts_recent,
+@@ -801,8 +802,10 @@ static void tcp_v4_reqsk_send_ack(struct sock *sk, struct sk_buff *skb,
+ 	/* sk->sk_state == TCP_LISTEN -> for regular TCP_SYN_RECV
+ 	 * sk->sk_state == TCP_SYN_RECV -> for Fast Open.
+ 	 */
+-	tcp_v4_send_ack(skb, (sk->sk_state == TCP_LISTEN) ?
+-			tcp_rsk(req)->snt_isn + 1 : tcp_sk(sk)->snd_nxt,
++	u32 seq = (sk->sk_state == TCP_LISTEN) ? tcp_rsk(req)->snt_isn + 1 :
++					     tcp_sk(sk)->snd_nxt;
++
++	tcp_v4_send_ack(sock_net(sk), skb, seq,
+ 			tcp_rsk(req)->rcv_nxt, req->rcv_wnd,
+ 			tcp_time_stamp,
+ 			req->ts_recent,
+diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
+index 1b8c5ba7d5f7..a390174b96de 100644
+--- a/net/ipv4/udp.c
++++ b/net/ipv4/udp.c
+@@ -963,8 +963,10 @@ int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
+ 	if (msg->msg_controllen) {
+ 		err = ip_cmsg_send(sock_net(sk), msg, &ipc,
+ 				   sk->sk_family == AF_INET6);
+-		if (err)
++		if (unlikely(err)) {
++			kfree(ipc.opt);
+ 			return err;
++		}
+ 		if (ipc.opt)
+ 			free = 1;
+ 		connected = 0;
+diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
+index f4795b0d6e6e..f555f4fc1d62 100644
+--- a/net/ipv6/addrconf.c
++++ b/net/ipv6/addrconf.c
+@@ -195,6 +195,7 @@ static struct ipv6_devconf ipv6_devconf __read_mostly = {
+ 	.max_addresses		= IPV6_MAX_ADDRESSES,
+ 	.accept_ra_defrtr	= 1,
+ 	.accept_ra_from_local	= 0,
++	.accept_ra_min_hop_limit= 1,
+ 	.accept_ra_pinfo	= 1,
+ #ifdef CONFIG_IPV6_ROUTER_PREF
+ 	.accept_ra_rtr_pref	= 1,
+@@ -236,6 +237,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
+ 	.max_addresses		= IPV6_MAX_ADDRESSES,
+ 	.accept_ra_defrtr	= 1,
+ 	.accept_ra_from_local	= 0,
++	.accept_ra_min_hop_limit= 1,
+ 	.accept_ra_pinfo	= 1,
+ #ifdef CONFIG_IPV6_ROUTER_PREF
+ 	.accept_ra_rtr_pref	= 1,
+@@ -567,7 +569,7 @@ static int inet6_netconf_get_devconf(struct sk_buff *in_skb,
+ 	if (err < 0)
+ 		goto errout;
+ 
+-	err = EINVAL;
++	err = -EINVAL;
+ 	if (!tb[NETCONFA_IFINDEX])
+ 		goto errout;
+ 
+@@ -3421,6 +3423,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
+ {
+ 	struct inet6_dev *idev = ifp->idev;
+ 	struct net_device *dev = idev->dev;
++	bool notify = false;
+ 
+ 	addrconf_join_solict(dev, &ifp->addr);
+ 
+@@ -3466,7 +3469,7 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
+ 			/* Because optimistic nodes can use this address,
+ 			 * notify listeners. If DAD fails, RTM_DELADDR is sent.
+ 			 */
+-			ipv6_ifa_notify(RTM_NEWADDR, ifp);
++			notify = true;
+ 		}
+ 	}
+ 
+@@ -3474,6 +3477,8 @@ static void addrconf_dad_begin(struct inet6_ifaddr *ifp)
+ out:
+ 	spin_unlock(&ifp->lock);
+ 	read_unlock_bh(&idev->lock);
++	if (notify)
++		ipv6_ifa_notify(RTM_NEWADDR, ifp);
+ }
+ 
+ static void addrconf_dad_start(struct inet6_ifaddr *ifp)
+@@ -4565,6 +4570,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
+ 	array[DEVCONF_MAX_DESYNC_FACTOR] = cnf->max_desync_factor;
+ 	array[DEVCONF_MAX_ADDRESSES] = cnf->max_addresses;
+ 	array[DEVCONF_ACCEPT_RA_DEFRTR] = cnf->accept_ra_defrtr;
++	array[DEVCONF_ACCEPT_RA_MIN_HOP_LIMIT] = cnf->accept_ra_min_hop_limit;
+ 	array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
+ #ifdef CONFIG_IPV6_ROUTER_PREF
+ 	array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
+@@ -5458,6 +5464,13 @@ static struct addrconf_sysctl_table
+ 			.proc_handler	= proc_dointvec,
+ 		},
+ 		{
++			.procname	= "accept_ra_min_hop_limit",
++			.data		= &ipv6_devconf.accept_ra_min_hop_limit,
++			.maxlen		= sizeof(int),
++			.mode		= 0644,
++			.proc_handler	= proc_dointvec,
++		},
++		{
+ 			.procname	= "accept_ra_pinfo",
+ 			.data		= &ipv6_devconf.accept_ra_pinfo,
+ 			.maxlen		= sizeof(int),
+diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
+index 13ca4cf5616f..8e6cb3f14326 100644
+--- a/net/ipv6/datagram.c
++++ b/net/ipv6/datagram.c
+@@ -162,6 +162,9 @@ ipv4_connected:
+ 	fl6.fl6_dport = inet->inet_dport;
+ 	fl6.fl6_sport = inet->inet_sport;
+ 
++	if (!fl6.flowi6_oif)
++		fl6.flowi6_oif = np->sticky_pktinfo.ipi6_ifindex;
++
+ 	if (!fl6.flowi6_oif && (addr_type&IPV6_ADDR_MULTICAST))
+ 		fl6.flowi6_oif = np->mcast_oif;
+ 
+diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
+index d491125011c4..db939e4ac68a 100644
+--- a/net/ipv6/ip6_flowlabel.c
++++ b/net/ipv6/ip6_flowlabel.c
+@@ -540,12 +540,13 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
+ 		}
+ 		spin_lock_bh(&ip6_sk_fl_lock);
+ 		for (sflp = &np->ipv6_fl_list;
+-		     (sfl = rcu_dereference(*sflp)) != NULL;
++		     (sfl = rcu_dereference_protected(*sflp,
++						      lockdep_is_held(&ip6_sk_fl_lock))) != NULL;
+ 		     sflp = &sfl->next) {
+ 			if (sfl->fl->label == freq.flr_label) {
+ 				if (freq.flr_label == (np->flow_label&IPV6_FLOWLABEL_MASK))
+ 					np->flow_label &= ~IPV6_FLOWLABEL_MASK;
+-				*sflp = rcu_dereference(sfl->next);
++				*sflp = sfl->next;
+ 				spin_unlock_bh(&ip6_sk_fl_lock);
+ 				fl_release(sfl->fl);
+ 				kfree_rcu(sfl, rcu);
+diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
+index f50228b0abe5..36b9ac48b8fb 100644
+--- a/net/ipv6/ip6_output.c
++++ b/net/ipv6/ip6_output.c
+@@ -885,6 +885,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
+ 	struct rt6_info *rt;
+ #endif
+ 	int err;
++	int flags = 0;
+ 
+ 	/* The correct way to handle this would be to do
+ 	 * ip6_route_get_saddr, and then ip6_route_output; however,
+@@ -916,10 +917,13 @@ static int ip6_dst_lookup_tail(struct sock *sk,
+ 			dst_release(*dst);
+ 			*dst = NULL;
+ 		}
++
++		if (fl6->flowi6_oif)
++			flags |= RT6_LOOKUP_F_IFACE;
+ 	}
+ 
+ 	if (!*dst)
+-		*dst = ip6_route_output(net, sk, fl6);
++		*dst = ip6_route_output_flags(net, sk, fl6, flags);
+ 
+ 	err = (*dst)->error;
+ 	if (err)
+diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
+index 96f153c0846b..abb0bdda759a 100644
+--- a/net/ipv6/ndisc.c
++++ b/net/ipv6/ndisc.c
+@@ -1225,18 +1225,16 @@ static void ndisc_router_discovery(struct sk_buff *skb)
+ 
+ 	if (rt)
+ 		rt6_set_expires(rt, jiffies + (HZ * lifetime));
+-	if (ra_msg->icmph.icmp6_hop_limit) {
+-		/* Only set hop_limit on the interface if it is higher than
+-		 * the current hop_limit.
+-		 */
+-		if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) {
++	if (in6_dev->cnf.accept_ra_min_hop_limit < 256 &&
++	    ra_msg->icmph.icmp6_hop_limit) {
++		if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
+ 			in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
++			if (rt)
++				dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
++					       ra_msg->icmph.icmp6_hop_limit);
+ 		} else {
+-			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n");
++			ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
+ 		}
+-		if (rt)
+-			dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
+-				       ra_msg->icmph.icmp6_hop_limit);
+ 	}
+ 
+ skip_defrtr:
+diff --git a/net/ipv6/route.c b/net/ipv6/route.c
+index f371fefa7fdc..fe70bd6a7516 100644
+--- a/net/ipv6/route.c
++++ b/net/ipv6/route.c
+@@ -1030,11 +1030,9 @@ static struct rt6_info *ip6_pol_route_output(struct net *net, struct fib6_table
+ 	return ip6_pol_route(net, table, fl6->flowi6_oif, fl6, flags);
+ }
+ 
+-struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
+-				    struct flowi6 *fl6)
++struct dst_entry *ip6_route_output_flags(struct net *net, const struct sock *sk,
++					 struct flowi6 *fl6, int flags)
+ {
+-	int flags = 0;
+-
+ 	fl6->flowi6_iif = LOOPBACK_IFINDEX;
+ 
+ 	if ((sk && sk->sk_bound_dev_if) || rt6_need_strict(&fl6->daddr))
+@@ -1047,7 +1045,7 @@ struct dst_entry *ip6_route_output(struct net *net, const struct sock *sk,
+ 
+ 	return fib6_rule_lookup(net, fl6, flags, ip6_pol_route_output);
+ }
+-EXPORT_SYMBOL(ip6_route_output);
++EXPORT_SYMBOL_GPL(ip6_route_output_flags);
+ 
+ struct dst_entry *ip6_blackhole_route(struct net *net, struct dst_entry *dst_orig)
+ {
+diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
+index 6daa52a18d40..123f6f9f854c 100644
+--- a/net/iucv/af_iucv.c
++++ b/net/iucv/af_iucv.c
+@@ -709,6 +709,9 @@ static int iucv_sock_bind(struct socket *sock, struct sockaddr *addr,
+ 	if (!addr || addr->sa_family != AF_IUCV)
+ 		return -EINVAL;
+ 
++	if (addr_len < sizeof(struct sockaddr_iucv))
++		return -EINVAL;
++
+ 	lock_sock(sk);
+ 	if (sk->sk_state != IUCV_OPEN) {
+ 		err = -EBADFD;
+diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
+index 9e13c2ff8789..fe92a08b3cd5 100644
+--- a/net/l2tp/l2tp_netlink.c
++++ b/net/l2tp/l2tp_netlink.c
+@@ -124,8 +124,13 @@ static int l2tp_tunnel_notify(struct genl_family *family,
+ 	ret = l2tp_nl_tunnel_send(msg, info->snd_portid, info->snd_seq,
+ 				  NLM_F_ACK, tunnel, cmd);
+ 
+-	if (ret >= 0)
+-		return genlmsg_multicast_allns(family, msg, 0,	0, GFP_ATOMIC);
++	if (ret >= 0) {
++		ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
++		/* We don't care if no one is listening */
++		if (ret == -ESRCH)
++			ret = 0;
++		return ret;
++	}
+ 
+ 	nlmsg_free(msg);
+ 
+@@ -147,8 +152,13 @@ static int l2tp_session_notify(struct genl_family *family,
+ 	ret = l2tp_nl_session_send(msg, info->snd_portid, info->snd_seq,
+ 				   NLM_F_ACK, session, cmd);
+ 
+-	if (ret >= 0)
+-		return genlmsg_multicast_allns(family, msg, 0,	0, GFP_ATOMIC);
++	if (ret >= 0) {
++		ret = genlmsg_multicast_allns(family, msg, 0, 0, GFP_ATOMIC);
++		/* We don't care if no one is listening */
++		if (ret == -ESRCH)
++			ret = 0;
++		return ret;
++	}
+ 
+ 	nlmsg_free(msg);
+ 
+diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c
+index e13c3c3ea4ac..9d134ab3351f 100644
+--- a/net/sctp/protocol.c
++++ b/net/sctp/protocol.c
+@@ -60,6 +60,8 @@
+ #include <net/inet_common.h>
+ #include <net/inet_ecn.h>
+ 
++#define MAX_SCTP_PORT_HASH_ENTRIES (64 * 1024)
++
+ /* Global data structures. */
+ struct sctp_globals sctp_globals __read_mostly;
+ 
+@@ -1332,6 +1334,8 @@ static __init int sctp_init(void)
+ 	unsigned long limit;
+ 	int max_share;
+ 	int order;
++	int num_entries;
++	int max_entry_order;
+ 
+ 	sock_skb_cb_check_size(sizeof(struct sctp_ulpevent));
+ 
+@@ -1384,14 +1388,24 @@ static __init int sctp_init(void)
+ 
+ 	/* Size and allocate the association hash table.
+ 	 * The methodology is similar to that of the tcp hash tables.
++	 * Though not identical.  Start by getting a goal size
+ 	 */
+ 	if (totalram_pages >= (128 * 1024))
+ 		goal = totalram_pages >> (22 - PAGE_SHIFT);
+ 	else
+ 		goal = totalram_pages >> (24 - PAGE_SHIFT);
+ 
+-	for (order = 0; (1UL << order) < goal; order++)
+-		;
++	/* Then compute the page order for said goal */
++	order = get_order(goal);
++
++	/* Now compute the required page order for the maximum sized table we
++	 * want to create
++	 */
++	max_entry_order = get_order(MAX_SCTP_PORT_HASH_ENTRIES *
++				    sizeof(struct sctp_bind_hashbucket));
++
++	/* Limit the page order by that maximum hash table size */
++	order = min(order, max_entry_order);
+ 
+ 	do {
+ 		sctp_assoc_hashsize = (1UL << order) * PAGE_SIZE /
+@@ -1425,27 +1439,42 @@ static __init int sctp_init(void)
+ 		INIT_HLIST_HEAD(&sctp_ep_hashtable[i].chain);
+ 	}
+ 
+-	/* Allocate and initialize the SCTP port hash table.  */
++	/* Allocate and initialize the SCTP port hash table.
++	 * Note that order is initalized to start at the max sized
++	 * table we want to support.  If we can't get that many pages
++	 * reduce the order and try again
++	 */
+ 	do {
+-		sctp_port_hashsize = (1UL << order) * PAGE_SIZE /
+-					sizeof(struct sctp_bind_hashbucket);
+-		if ((sctp_port_hashsize > (64 * 1024)) && order > 0)
+-			continue;
+ 		sctp_port_hashtable = (struct sctp_bind_hashbucket *)
+ 			__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, order);
+ 	} while (!sctp_port_hashtable && --order > 0);
++
+ 	if (!sctp_port_hashtable) {
+ 		pr_err("Failed bind hash alloc\n");
+ 		status = -ENOMEM;
+ 		goto err_bhash_alloc;
+ 	}
++
++	/* Now compute the number of entries that will fit in the
++	 * port hash space we allocated
++	 */
++	num_entries = (1UL << order) * PAGE_SIZE /
++		      sizeof(struct sctp_bind_hashbucket);
++
++	/* And finish by rounding it down to the nearest power of two
++	 * this wastes some memory of course, but its needed because
++	 * the hash function operates based on the assumption that
++	 * that the number of entries is a power of two
++	 */
++	sctp_port_hashsize = rounddown_pow_of_two(num_entries);
++
+ 	for (i = 0; i < sctp_port_hashsize; i++) {
+ 		spin_lock_init(&sctp_port_hashtable[i].lock);
+ 		INIT_HLIST_HEAD(&sctp_port_hashtable[i].chain);
+ 	}
+ 
+-	pr_info("Hash tables configured (established %d bind %d)\n",
+-		sctp_assoc_hashsize, sctp_port_hashsize);
++	pr_info("Hash tables configured (established %d bind %d/%d)\n",
++		sctp_assoc_hashsize, sctp_port_hashsize, num_entries);
+ 
+ 	sctp_sysctl_register();
+ 
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 76e6ec62cf92..3c5833058b03 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -5555,6 +5555,7 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
+ 	struct sctp_hmac_algo_param *hmacs;
+ 	__u16 data_len = 0;
+ 	u32 num_idents;
++	int i;
+ 
+ 	if (!ep->auth_enable)
+ 		return -EACCES;
+@@ -5572,8 +5573,12 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
+ 		return -EFAULT;
+ 	if (put_user(num_idents, &p->shmac_num_idents))
+ 		return -EFAULT;
+-	if (copy_to_user(p->shmac_idents, hmacs->hmac_ids, data_len))
+-		return -EFAULT;
++	for (i = 0; i < num_idents; i++) {
++		__u16 hmacid = ntohs(hmacs->hmac_ids[i]);
++
++		if (copy_to_user(&p->shmac_idents[i], &hmacid, sizeof(__u16)))
++			return -EFAULT;
++	}
+ 	return 0;
+ }
+ 
+@@ -6653,6 +6658,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
+ 
+ 			if (cmsgs->srinfo->sinfo_flags &
+ 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
++			      SCTP_SACK_IMMEDIATELY |
+ 			      SCTP_ABORT | SCTP_EOF))
+ 				return -EINVAL;
+ 			break;
+@@ -6676,6 +6682,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
+ 
+ 			if (cmsgs->sinfo->snd_flags &
+ 			    ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
++			      SCTP_SACK_IMMEDIATELY |
+ 			      SCTP_ABORT | SCTP_EOF))
+ 				return -EINVAL;
+ 			break;
+diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
+index 055453d48668..a8dbe8001e46 100644
+--- a/net/switchdev/switchdev.c
++++ b/net/switchdev/switchdev.c
+@@ -15,6 +15,7 @@
+ #include <linux/mutex.h>
+ #include <linux/notifier.h>
+ #include <linux/netdevice.h>
++#include <linux/rtnetlink.h>
+ #include <net/ip_fib.h>
+ #include <net/switchdev.h>
+ 
+@@ -64,7 +65,6 @@ int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
+ }
+ EXPORT_SYMBOL_GPL(netdev_switch_port_stp_update);
+ 
+-static DEFINE_MUTEX(netdev_switch_mutex);
+ static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain);
+ 
+ /**
+@@ -79,9 +79,9 @@ int register_netdev_switch_notifier(struct notifier_block *nb)
+ {
+ 	int err;
+ 
+-	mutex_lock(&netdev_switch_mutex);
++	rtnl_lock();
+ 	err = raw_notifier_chain_register(&netdev_switch_notif_chain, nb);
+-	mutex_unlock(&netdev_switch_mutex);
++	rtnl_unlock();
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(register_netdev_switch_notifier);
+@@ -97,9 +97,9 @@ int unregister_netdev_switch_notifier(struct notifier_block *nb)
+ {
+ 	int err;
+ 
+-	mutex_lock(&netdev_switch_mutex);
++	rtnl_lock();
+ 	err = raw_notifier_chain_unregister(&netdev_switch_notif_chain, nb);
+-	mutex_unlock(&netdev_switch_mutex);
++	rtnl_unlock();
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(unregister_netdev_switch_notifier);
+@@ -113,16 +113,17 @@ EXPORT_SYMBOL_GPL(unregister_netdev_switch_notifier);
+  *	Call all network notifier blocks. This should be called by driver
+  *	when it needs to propagate hardware event.
+  *	Return values are same as for atomic_notifier_call_chain().
++ *	rtnl_lock must be held.
+  */
+ int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev,
+ 				 struct netdev_switch_notifier_info *info)
+ {
+ 	int err;
+ 
++	ASSERT_RTNL();
++
+ 	info->dev = dev;
+-	mutex_lock(&netdev_switch_mutex);
+ 	err = raw_notifier_call_chain(&netdev_switch_notif_chain, val, info);
+-	mutex_unlock(&netdev_switch_mutex);
+ 	return err;
+ }
+ EXPORT_SYMBOL_GPL(call_netdev_switch_notifiers);
+diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
+index 1c147c869c2e..948f316019d7 100644
+--- a/net/tipc/subscr.c
++++ b/net/tipc/subscr.c
+@@ -302,11 +302,10 @@ static void subscr_conn_msg_event(struct net *net, int conid,
+ 	struct tipc_net *tn = net_generic(net, tipc_net_id);
+ 
+ 	spin_lock_bh(&subscriber->lock);
+-	subscr_subscribe(net, (struct tipc_subscr *)buf, subscriber, &sub);
+-	if (sub)
+-		tipc_nametbl_subscribe(sub);
+-	else
++	if (subscr_subscribe(net, (struct tipc_subscr *)buf, subscriber, &sub))
+ 		tipc_conn_terminate(tn->topsrv, subscriber->conid);
++	else
++		tipc_nametbl_subscribe(sub);
+ 	spin_unlock_bh(&subscriber->lock);
+ }
+ 
+diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
+index cb3a01a9ed38..535a642a1688 100644
+--- a/net/unix/af_unix.c
++++ b/net/unix/af_unix.c
+@@ -1464,7 +1464,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ 	UNIXCB(skb).fp = NULL;
+ 
+ 	for (i = scm->fp->count-1; i >= 0; i--)
+-		unix_notinflight(scm->fp->fp[i]);
++		unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+ }
+ 
+ static void unix_destruct_scm(struct sk_buff *skb)
+@@ -1529,7 +1529,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+ 		return -ENOMEM;
+ 
+ 	for (i = scm->fp->count - 1; i >= 0; i--)
+-		unix_inflight(scm->fp->fp[i]);
++		unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ 	return max_level;
+ }
+ 
+@@ -1714,7 +1714,12 @@ restart_locked:
+ 			goto out_unlock;
+ 	}
+ 
+-	if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
++	/* other == sk && unix_peer(other) != sk if
++	 * - unix_peer(sk) == NULL, destination address bound to sk
++	 * - unix_peer(sk) == sk by time of get but disconnected before lock
++	 */
++	if (other != sk &&
++	    unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+ 		if (timeo) {
+ 			timeo = unix_wait_for_peer(other, timeo);
+ 
+@@ -2131,6 +2136,7 @@ again:
+ 
+ 			if (signal_pending(current)) {
+ 				err = sock_intr_errno(timeo);
++				scm_destroy(&scm);
+ 				goto out;
+ 			}
+ 
+diff --git a/net/unix/diag.c b/net/unix/diag.c
+index c512f64d5287..4d9679701a6d 100644
+--- a/net/unix/diag.c
++++ b/net/unix/diag.c
+@@ -220,7 +220,7 @@ done:
+ 	return skb->len;
+ }
+ 
+-static struct sock *unix_lookup_by_ino(int ino)
++static struct sock *unix_lookup_by_ino(unsigned int ino)
+ {
+ 	int i;
+ 	struct sock *sk;
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c
+index 8fcdc2283af5..6a0d48525fcf 100644
+--- a/net/unix/garbage.c
++++ b/net/unix/garbage.c
+@@ -116,7 +116,7 @@ struct sock *unix_get_socket(struct file *filp)
+  * descriptor if it is for an AF_UNIX socket.
+  */
+ 
+-void unix_inflight(struct file *fp)
++void unix_inflight(struct user_struct *user, struct file *fp)
+ {
+ 	struct sock *s = unix_get_socket(fp);
+ 
+@@ -133,11 +133,11 @@ void unix_inflight(struct file *fp)
+ 		}
+ 		unix_tot_inflight++;
+ 	}
+-	fp->f_cred->user->unix_inflight++;
++	user->unix_inflight++;
+ 	spin_unlock(&unix_gc_lock);
+ }
+ 
+-void unix_notinflight(struct file *fp)
++void unix_notinflight(struct user_struct *user, struct file *fp)
+ {
+ 	struct sock *s = unix_get_socket(fp);
+ 
+@@ -152,7 +152,7 @@ void unix_notinflight(struct file *fp)
+ 			list_del_init(&u->link);
+ 		unix_tot_inflight--;
+ 	}
+-	fp->f_cred->user->unix_inflight--;
++	user->unix_inflight--;
+ 	spin_unlock(&unix_gc_lock);
+ }
+ 
+diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
+index 582091498819..d6bc2b3af9ef 100644
+--- a/security/integrity/evm/evm_main.c
++++ b/security/integrity/evm/evm_main.c
+@@ -23,6 +23,7 @@
+ #include <linux/integrity.h>
+ #include <linux/evm.h>
+ #include <crypto/hash.h>
++#include <crypto/algapi.h>
+ #include "evm.h"
+ 
+ int evm_initialized;
+@@ -148,7 +149,7 @@ static enum integrity_status evm_verify_hmac(struct dentry *dentry,
+ 				   xattr_value_len, calc.digest);
+ 		if (rc)
+ 			break;
+-		rc = memcmp(xattr_data->digest, calc.digest,
++		rc = crypto_memneq(xattr_data->digest, calc.digest,
+ 			    sizeof(calc.digest));
+ 		if (rc)
+ 			rc = -EINVAL;
+diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
+index 75888dd38a7f..aa999e747c94 100644
+--- a/sound/core/pcm_native.c
++++ b/sound/core/pcm_native.c
+@@ -74,6 +74,18 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
+ static DEFINE_RWLOCK(snd_pcm_link_rwlock);
+ static DECLARE_RWSEM(snd_pcm_link_rwsem);
+ 
++/* Writer in rwsem may block readers even during its waiting in queue,
++ * and this may lead to a deadlock when the code path takes read sem
++ * twice (e.g. one in snd_pcm_action_nonatomic() and another in
++ * snd_pcm_stream_lock()).  As a (suboptimal) workaround, let writer to
++ * spin until it gets the lock.
++ */
++static inline void down_write_nonblock(struct rw_semaphore *lock)
++{
++	while (!down_write_trylock(lock))
++		cond_resched();
++}
++
+ /**
+  * snd_pcm_stream_lock - Lock the PCM stream
+  * @substream: PCM substream
+@@ -1816,7 +1828,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
+ 		res = -ENOMEM;
+ 		goto _nolock;
+ 	}
+-	down_write(&snd_pcm_link_rwsem);
++	down_write_nonblock(&snd_pcm_link_rwsem);
+ 	write_lock_irq(&snd_pcm_link_rwlock);
+ 	if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
+ 	    substream->runtime->status->state != substream1->runtime->status->state ||
+@@ -1863,7 +1875,7 @@ static int snd_pcm_unlink(struct snd_pcm_substream *substream)
+ 	struct snd_pcm_substream *s;
+ 	int res = 0;
+ 
+-	down_write(&snd_pcm_link_rwsem);
++	down_write_nonblock(&snd_pcm_link_rwsem);
+ 	write_lock_irq(&snd_pcm_link_rwlock);
+ 	if (!snd_pcm_stream_linked(substream)) {
+ 		res = -EALREADY;
+diff --git a/sound/core/seq/seq_memory.c b/sound/core/seq/seq_memory.c
+index 801076687bb1..c850345c43b5 100644
+--- a/sound/core/seq/seq_memory.c
++++ b/sound/core/seq/seq_memory.c
+@@ -383,15 +383,20 @@ int snd_seq_pool_init(struct snd_seq_pool *pool)
+ 
+ 	if (snd_BUG_ON(!pool))
+ 		return -EINVAL;
+-	if (pool->ptr)			/* should be atomic? */
+-		return 0;
+ 
+-	pool->ptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
+-	if (!pool->ptr)
++	cellptr = vmalloc(sizeof(struct snd_seq_event_cell) * pool->size);
++	if (!cellptr)
+ 		return -ENOMEM;
+ 
+ 	/* add new cells to the free cell list */
+ 	spin_lock_irqsave(&pool->lock, flags);
++	if (pool->ptr) {
++		spin_unlock_irqrestore(&pool->lock, flags);
++		vfree(cellptr);
++		return 0;
++	}
++
++	pool->ptr = cellptr;
+ 	pool->free = NULL;
+ 
+ 	for (cell = 0; cell < pool->size; cell++) {
+diff --git a/sound/core/seq/seq_ports.c b/sound/core/seq/seq_ports.c
+index 921fb2bd8fad..fe686ee41c6d 100644
+--- a/sound/core/seq/seq_ports.c
++++ b/sound/core/seq/seq_ports.c
+@@ -535,19 +535,22 @@ static void delete_and_unsubscribe_port(struct snd_seq_client *client,
+ 					bool is_src, bool ack)
+ {
+ 	struct snd_seq_port_subs_info *grp;
++	struct list_head *list;
++	bool empty;
+ 
+ 	grp = is_src ? &port->c_src : &port->c_dest;
++	list = is_src ? &subs->src_list : &subs->dest_list;
+ 	down_write(&grp->list_mutex);
+ 	write_lock_irq(&grp->list_lock);
+-	if (is_src)
+-		list_del(&subs->src_list);
+-	else
+-		list_del(&subs->dest_list);
++	empty = list_empty(list);
++	if (!empty)
++		list_del_init(list);
+ 	grp->exclusive = 0;
+ 	write_unlock_irq(&grp->list_lock);
+ 	up_write(&grp->list_mutex);
+ 
+-	unsubscribe_port(client, port, grp, &subs->info, ack);
++	if (!empty)
++		unsubscribe_port(client, port, grp, &subs->info, ack);
+ }
+ 
+ /* connect two ports */
+diff --git a/sound/core/timer.c b/sound/core/timer.c
+index 00e8c5f4de17..bf48e71f73cd 100644
+--- a/sound/core/timer.c
++++ b/sound/core/timer.c
+@@ -422,7 +422,7 @@ static void snd_timer_notify1(struct snd_timer_instance *ti, int event)
+ 	spin_lock_irqsave(&timer->lock, flags);
+ 	list_for_each_entry(ts, &ti->slave_active_head, active_list)
+ 		if (ts->ccallback)
+-			ts->ccallback(ti, event + 100, &tstamp, resolution);
++			ts->ccallback(ts, event + 100, &tstamp, resolution);
+ 	spin_unlock_irqrestore(&timer->lock, flags);
+ }
+ 
+@@ -518,9 +518,13 @@ static int _snd_timer_stop(struct snd_timer_instance *timeri, int event)
+ 			spin_unlock_irqrestore(&slave_active_lock, flags);
+ 			return -EBUSY;
+ 		}
++		if (timeri->timer)
++			spin_lock(&timeri->timer->lock);
+ 		timeri->flags &= ~SNDRV_TIMER_IFLG_RUNNING;
+ 		list_del_init(&timeri->ack_list);
+ 		list_del_init(&timeri->active_list);
++		if (timeri->timer)
++			spin_unlock(&timeri->timer->lock);
+ 		spin_unlock_irqrestore(&slave_active_lock, flags);
+ 		goto __end;
+ 	}
+@@ -1920,6 +1924,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ {
+ 	struct snd_timer_user *tu;
+ 	long result = 0, unit;
++	int qhead;
+ 	int err = 0;
+ 
+ 	tu = file->private_data;
+@@ -1931,7 +1936,7 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ 
+ 			if ((file->f_flags & O_NONBLOCK) != 0 || result > 0) {
+ 				err = -EAGAIN;
+-				break;
++				goto _error;
+ 			}
+ 
+ 			set_current_state(TASK_INTERRUPTIBLE);
+@@ -1946,42 +1951,37 @@ static ssize_t snd_timer_user_read(struct file *file, char __user *buffer,
+ 
+ 			if (tu->disconnected) {
+ 				err = -ENODEV;
+-				break;
++				goto _error;
+ 			}
+ 			if (signal_pending(current)) {
+ 				err = -ERESTARTSYS;
+-				break;
++				goto _error;
+ 			}
+ 		}
+ 
++		qhead = tu->qhead++;
++		tu->qhead %= tu->queue_size;
+ 		spin_unlock_irq(&tu->qlock);
+-		if (err < 0)
+-			goto _error;
+ 
+ 		if (tu->tread) {
+-			if (copy_to_user(buffer, &tu->tqueue[tu->qhead++],
+-					 sizeof(struct snd_timer_tread))) {
++			if (copy_to_user(buffer, &tu->tqueue[qhead],
++					 sizeof(struct snd_timer_tread)))
+ 				err = -EFAULT;
+-				goto _error;
+-			}
+ 		} else {
+-			if (copy_to_user(buffer, &tu->queue[tu->qhead++],
+-					 sizeof(struct snd_timer_read))) {
++			if (copy_to_user(buffer, &tu->queue[qhead],
++					 sizeof(struct snd_timer_read)))
+ 				err = -EFAULT;
+-				goto _error;
+-			}
+ 		}
+ 
+-		tu->qhead %= tu->queue_size;
+-
+-		result += unit;
+-		buffer += unit;
+-
+ 		spin_lock_irq(&tu->qlock);
+ 		tu->qused--;
++		if (err < 0)
++			goto _error;
++		result += unit;
++		buffer += unit;
+ 	}
+-	spin_unlock_irq(&tu->qlock);
+  _error:
++	spin_unlock_irq(&tu->qlock);
+ 	return result > 0 ? result : err;
+ }
+ 
+diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
+index 96592d5ba7bf..c5d5217a4180 100644
+--- a/sound/drivers/dummy.c
++++ b/sound/drivers/dummy.c
+@@ -87,7 +87,7 @@ MODULE_PARM_DESC(pcm_substreams, "PCM substreams # (1-128) for dummy driver.");
+ module_param(fake_buffer, bool, 0444);
+ MODULE_PARM_DESC(fake_buffer, "Fake buffer allocations.");
+ #ifdef CONFIG_HIGH_RES_TIMERS
+-module_param(hrtimer, bool, 0444);
++module_param(hrtimer, bool, 0644);
+ MODULE_PARM_DESC(hrtimer, "Use hrtimer as the timer source.");
+ #endif
+ 
+@@ -109,6 +109,9 @@ struct dummy_timer_ops {
+ 	snd_pcm_uframes_t (*pointer)(struct snd_pcm_substream *);
+ };
+ 
++#define get_dummy_ops(substream) \
++	(*(const struct dummy_timer_ops **)(substream)->runtime->private_data)
++
+ struct dummy_model {
+ 	const char *name;
+ 	int (*playback_constraints)(struct snd_pcm_runtime *runtime);
+@@ -137,7 +140,6 @@ struct snd_dummy {
+ 	int iobox;
+ 	struct snd_kcontrol *cd_volume_ctl;
+ 	struct snd_kcontrol *cd_switch_ctl;
+-	const struct dummy_timer_ops *timer_ops;
+ };
+ 
+ /*
+@@ -231,6 +233,8 @@ struct dummy_model *dummy_models[] = {
+  */
+ 
+ struct dummy_systimer_pcm {
++	/* ops must be the first item */
++	const struct dummy_timer_ops *timer_ops;
+ 	spinlock_t lock;
+ 	struct timer_list timer;
+ 	unsigned long base_time;
+@@ -366,6 +370,8 @@ static struct dummy_timer_ops dummy_systimer_ops = {
+  */
+ 
+ struct dummy_hrtimer_pcm {
++	/* ops must be the first item */
++	const struct dummy_timer_ops *timer_ops;
+ 	ktime_t base_time;
+ 	ktime_t period_time;
+ 	atomic_t running;
+@@ -492,31 +498,25 @@ static struct dummy_timer_ops dummy_hrtimer_ops = {
+ 
+ static int dummy_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
+ {
+-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+-
+ 	switch (cmd) {
+ 	case SNDRV_PCM_TRIGGER_START:
+ 	case SNDRV_PCM_TRIGGER_RESUME:
+-		return dummy->timer_ops->start(substream);
++		return get_dummy_ops(substream)->start(substream);
+ 	case SNDRV_PCM_TRIGGER_STOP:
+ 	case SNDRV_PCM_TRIGGER_SUSPEND:
+-		return dummy->timer_ops->stop(substream);
++		return get_dummy_ops(substream)->stop(substream);
+ 	}
+ 	return -EINVAL;
+ }
+ 
+ static int dummy_pcm_prepare(struct snd_pcm_substream *substream)
+ {
+-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+-
+-	return dummy->timer_ops->prepare(substream);
++	return get_dummy_ops(substream)->prepare(substream);
+ }
+ 
+ static snd_pcm_uframes_t dummy_pcm_pointer(struct snd_pcm_substream *substream)
+ {
+-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+-
+-	return dummy->timer_ops->pointer(substream);
++	return get_dummy_ops(substream)->pointer(substream);
+ }
+ 
+ static struct snd_pcm_hardware dummy_pcm_hardware = {
+@@ -562,17 +562,19 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
+ 	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+ 	struct dummy_model *model = dummy->model;
+ 	struct snd_pcm_runtime *runtime = substream->runtime;
++	const struct dummy_timer_ops *ops;
+ 	int err;
+ 
+-	dummy->timer_ops = &dummy_systimer_ops;
++	ops = &dummy_systimer_ops;
+ #ifdef CONFIG_HIGH_RES_TIMERS
+ 	if (hrtimer)
+-		dummy->timer_ops = &dummy_hrtimer_ops;
++		ops = &dummy_hrtimer_ops;
+ #endif
+ 
+-	err = dummy->timer_ops->create(substream);
++	err = ops->create(substream);
+ 	if (err < 0)
+ 		return err;
++	get_dummy_ops(substream) = ops;
+ 
+ 	runtime->hw = dummy->pcm_hw;
+ 	if (substream->pcm->device & 1) {
+@@ -594,7 +596,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
+ 			err = model->capture_constraints(substream->runtime);
+ 	}
+ 	if (err < 0) {
+-		dummy->timer_ops->free(substream);
++		get_dummy_ops(substream)->free(substream);
+ 		return err;
+ 	}
+ 	return 0;
+@@ -602,8 +604,7 @@ static int dummy_pcm_open(struct snd_pcm_substream *substream)
+ 
+ static int dummy_pcm_close(struct snd_pcm_substream *substream)
+ {
+-	struct snd_dummy *dummy = snd_pcm_substream_chip(substream);
+-	dummy->timer_ops->free(substream);
++	get_dummy_ops(substream)->free(substream);
+ 	return 0;
+ }
+ 
+diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
+index 5bc7f2e2715c..194627c6c42b 100644
+--- a/sound/pci/hda/hda_generic.c
++++ b/sound/pci/hda/hda_generic.c
+@@ -3998,9 +3998,9 @@ static void pin_power_callback(struct hda_codec *codec,
+ 			       struct hda_jack_callback *jack,
+ 			       bool on)
+ {
+-	if (jack && jack->tbl->nid)
++	if (jack && jack->nid)
+ 		sync_power_state_change(codec,
+-					set_pin_power_jack(codec, jack->tbl->nid, on));
++					set_pin_power_jack(codec, jack->nid, on));
+ }
+ 
+ /* callback only doing power up -- called at first */
+diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
+index 09920ba55ba1..69093ce34231 100644
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -1976,10 +1976,10 @@ static void azx_remove(struct pci_dev *pci)
+ 	struct hda_intel *hda;
+ 
+ 	if (card) {
+-		/* flush the pending probing work */
++		/* cancel the pending probing work */
+ 		chip = card->private_data;
+ 		hda = container_of(chip, struct hda_intel, chip);
+-		flush_work(&hda->probe_work);
++		cancel_work_sync(&hda->probe_work);
+ 
+ 		snd_card_free(card);
+ 	}
+diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
+index d7cfe7b8c32b..52cc36758dd4 100644
+--- a/sound/pci/hda/hda_jack.c
++++ b/sound/pci/hda/hda_jack.c
+@@ -259,7 +259,7 @@ snd_hda_jack_detect_enable_callback(struct hda_codec *codec, hda_nid_t nid,
+ 		if (!callback)
+ 			return ERR_PTR(-ENOMEM);
+ 		callback->func = func;
+-		callback->tbl = jack;
++		callback->nid = jack->nid;
+ 		callback->next = jack->callback;
+ 		jack->callback = callback;
+ 	}
+diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
+index b279e327a23b..a13c11c3ddbb 100644
+--- a/sound/pci/hda/hda_jack.h
++++ b/sound/pci/hda/hda_jack.h
+@@ -21,7 +21,7 @@ struct hda_jack_callback;
+ typedef void (*hda_jack_callback_fn) (struct hda_codec *, struct hda_jack_callback *);
+ 
+ struct hda_jack_callback {
+-	struct hda_jack_tbl *tbl;
++	hda_nid_t nid;
+ 	hda_jack_callback_fn func;
+ 	unsigned int private_data;	/* arbitrary data */
+ 	struct hda_jack_callback *next;
+diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c
+index 4a4e7b282e4f..0374bd5b61c8 100644
+--- a/sound/pci/hda/patch_ca0132.c
++++ b/sound/pci/hda/patch_ca0132.c
+@@ -4401,13 +4401,16 @@ static void ca0132_process_dsp_response(struct hda_codec *codec,
+ static void hp_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
+ {
+ 	struct ca0132_spec *spec = codec->spec;
++	struct hda_jack_tbl *tbl;
+ 
+ 	/* Delay enabling the HP amp, to let the mic-detection
+ 	 * state machine run.
+ 	 */
+ 	cancel_delayed_work_sync(&spec->unsol_hp_work);
+ 	schedule_delayed_work(&spec->unsol_hp_work, msecs_to_jiffies(500));
+-	cb->tbl->block_report = 1;
++	tbl = snd_hda_jack_tbl_get(codec, cb->nid);
++	if (tbl)
++		tbl->block_report = 1;
+ }
+ 
+ static void amic_callback(struct hda_codec *codec, struct hda_jack_callback *cb)
+diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
+index d02eccd51f6e..51d519554744 100644
+--- a/sound/pci/hda/patch_hdmi.c
++++ b/sound/pci/hda/patch_hdmi.c
+@@ -433,7 +433,8 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
+ 	eld = &per_pin->sink_eld;
+ 
+ 	mutex_lock(&per_pin->lock);
+-	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) {
++	if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||
++	    eld->eld_size > ELD_MAX_SIZE) {
+ 		mutex_unlock(&per_pin->lock);
+ 		snd_BUG();
+ 		return -EINVAL;
+@@ -1178,7 +1179,7 @@ static void check_presence_and_report(struct hda_codec *codec, hda_nid_t nid)
+ static void jack_callback(struct hda_codec *codec,
+ 			  struct hda_jack_callback *jack)
+ {
+-	check_presence_and_report(codec, jack->tbl->nid);
++	check_presence_and_report(codec, jack->nid);
+ }
+ 
+ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
+diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
+index 8189f02f8446..df34c78a6ced 100644
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -277,7 +277,7 @@ static void alc_update_knob_master(struct hda_codec *codec,
+ 	uctl = kzalloc(sizeof(*uctl), GFP_KERNEL);
+ 	if (!uctl)
+ 		return;
+-	val = snd_hda_codec_read(codec, jack->tbl->nid, 0,
++	val = snd_hda_codec_read(codec, jack->nid, 0,
+ 				 AC_VERB_GET_VOLUME_KNOB_CONTROL, 0);
+ 	val &= HDA_AMP_VOLMASK;
+ 	uctl->value.integer.value[0] = val;
+@@ -1792,7 +1792,6 @@ enum {
+ 	ALC882_FIXUP_NO_PRIMARY_HP,
+ 	ALC887_FIXUP_ASUS_BASS,
+ 	ALC887_FIXUP_BASS_CHMAP,
+-	ALC882_FIXUP_DISABLE_AAMIX,
+ };
+ 
+ static void alc889_fixup_coef(struct hda_codec *codec,
+@@ -1954,8 +1953,6 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
+ 
+ static void alc_fixup_bass_chmap(struct hda_codec *codec,
+ 				 const struct hda_fixup *fix, int action);
+-static void alc_fixup_disable_aamix(struct hda_codec *codec,
+-				    const struct hda_fixup *fix, int action);
+ 
+ static const struct hda_fixup alc882_fixups[] = {
+ 	[ALC882_FIXUP_ABIT_AW9D_MAX] = {
+@@ -2193,10 +2190,6 @@ static const struct hda_fixup alc882_fixups[] = {
+ 		.type = HDA_FIXUP_FUNC,
+ 		.v.func = alc_fixup_bass_chmap,
+ 	},
+-	[ALC882_FIXUP_DISABLE_AAMIX] = {
+-		.type = HDA_FIXUP_FUNC,
+-		.v.func = alc_fixup_disable_aamix,
+-	},
+ };
+ 
+ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+@@ -2235,6 +2228,7 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x104d, 0x9047, "Sony Vaio TT", ALC889_FIXUP_VAIO_TT),
+ 	SND_PCI_QUIRK(0x104d, 0x905a, "Sony Vaio Z", ALC882_FIXUP_NO_PRIMARY_HP),
+ 	SND_PCI_QUIRK(0x104d, 0x9043, "Sony Vaio VGC-LN51JGB", ALC882_FIXUP_NO_PRIMARY_HP),
++	SND_PCI_QUIRK(0x104d, 0x9044, "Sony VAIO AiO", ALC882_FIXUP_NO_PRIMARY_HP),
+ 
+ 	/* All Apple entries are in codec SSIDs */
+ 	SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC889_FIXUP_MBP_VREF),
+@@ -2264,7 +2258,6 @@ static const struct snd_pci_quirk alc882_fixup_tbl[] = {
+ 	SND_PCI_QUIRK(0x1462, 0x7350, "MSI-7350", ALC889_FIXUP_CD),
+ 	SND_PCI_QUIRK_VENDOR(0x1462, "MSI", ALC882_FIXUP_GPIO3),
+ 	SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte EP45-DS3/Z87X-UD3H", ALC889_FIXUP_FRONT_HP_NO_PRESENCE),
+-	SND_PCI_QUIRK(0x1458, 0xa182, "Gigabyte Z170X-UD3", ALC882_FIXUP_DISABLE_AAMIX),
+ 	SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", ALC882_FIXUP_ABIT_AW9D_MAX),
+ 	SND_PCI_QUIRK_VENDOR(0x1558, "Clevo laptop", ALC882_FIXUP_EAPD),
+ 	SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_FIXUP_EAPD),
+diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
+index 8e7d4c087a7a..840178a26a6b 100644
+--- a/sound/pci/hda/patch_sigmatel.c
++++ b/sound/pci/hda/patch_sigmatel.c
+@@ -493,9 +493,9 @@ static void jack_update_power(struct hda_codec *codec,
+ 	if (!spec->num_pwrs)
+ 		return;
+ 
+-	if (jack && jack->tbl->nid) {
+-		stac_toggle_power_map(codec, jack->tbl->nid,
+-				      snd_hda_jack_detect(codec, jack->tbl->nid),
++	if (jack && jack->nid) {
++		stac_toggle_power_map(codec, jack->nid,
++				      snd_hda_jack_detect(codec, jack->nid),
+ 				      true);
+ 		return;
+ 	}
+diff --git a/sound/soc/codecs/rt5645.c b/sound/soc/codecs/rt5645.c
+index 2ee44abd56a6..6cbd03a5e53d 100644
+--- a/sound/soc/codecs/rt5645.c
++++ b/sound/soc/codecs/rt5645.c
+@@ -487,7 +487,7 @@ static const struct snd_kcontrol_new rt5645_snd_controls[] = {
+ 
+ 	/* IN1/IN2 Control */
+ 	SOC_SINGLE_TLV("IN1 Boost", RT5645_IN1_CTRL1,
+-		RT5645_BST_SFT1, 8, 0, bst_tlv),
++		RT5645_BST_SFT1, 12, 0, bst_tlv),
+ 	SOC_SINGLE_TLV("IN2 Boost", RT5645_IN2_CTRL,
+ 		RT5645_BST_SFT2, 8, 0, bst_tlv),
+ 
+diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
+index 35fe58f4fa86..52fe7eb2dea1 100644
+--- a/sound/soc/soc-pcm.c
++++ b/sound/soc/soc-pcm.c
+@@ -1661,7 +1661,8 @@ int dpcm_be_dai_hw_free(struct snd_soc_pcm_runtime *fe, int stream)
+ 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PREPARE) &&
+ 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_HW_FREE) &&
+ 		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_PAUSED) &&
+-		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP))
++		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_STOP) &&
++		    (be->dpcm[stream].state != SND_SOC_DPCM_STATE_SUSPEND))
+ 			continue;
+ 
+ 		dev_dbg(be->dev, "ASoC: hw_free BE %s\n",
+diff --git a/sound/usb/midi.c b/sound/usb/midi.c
+index bec63e0d2605..f059326a4914 100644
+--- a/sound/usb/midi.c
++++ b/sound/usb/midi.c
+@@ -2451,7 +2451,6 @@ int snd_usbmidi_create(struct snd_card *card,
+ 	else
+ 		err = snd_usbmidi_create_endpoints(umidi, endpoints);
+ 	if (err < 0) {
+-		snd_usbmidi_free(umidi);
+ 		return err;
+ 	}
+ 


             reply	other threads:[~2016-03-06 12:02 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-05 23:38 Mike Pagano [this message]
  -- strict thread matches above, loose matches on Subject: below --
2018-05-29 10:34 [gentoo-commits] proj/linux-patches:4.1 commit in: / Mike Pagano
2018-01-23  9:37 Alice Ferrazzi
2017-12-15 20:22 Alice Ferrazzi
2017-12-08 14:48 Mike Pagano
2017-12-07 18:53 Mike Pagano
2017-10-18 11:51 Mike Pagano
2017-09-13 19:38 Mike Pagano
2017-08-06 18:01 Mike Pagano
2017-04-14 19:17 Mike Pagano
2017-03-14 11:39 Mike Pagano
2017-03-02 16:31 Mike Pagano
2017-03-02 16:31 Mike Pagano
2017-02-24 16:11 Mike Pagano
2017-01-18 23:50 Alice Ferrazzi
2017-01-10  4:02 Alice Ferrazzi
2016-12-08  0:43 Mike Pagano
2016-11-30 11:45 Mike Pagano
2016-11-23 11:25 Mike Pagano
2016-10-28 10:19 Mike Pagano
2016-10-12 19:52 Mike Pagano
2016-09-18 12:47 Mike Pagano
2016-08-22 23:29 Mike Pagano
2016-08-10 12:55 Mike Pagano
2016-07-31 16:01 Mike Pagano
2016-07-15 14:18 Mike Pagano
2016-07-13 23:38 Mike Pagano
2016-07-02 15:31 Mike Pagano
2016-07-01 19:56 Mike Pagano
2016-06-23 11:45 Mike Pagano
2016-06-08 11:17 Mike Pagano
2016-05-24 12:39 Mike Pagano
2016-05-12  0:12 Mike Pagano
2016-04-28 18:56 Mike Pagano
2016-04-22 18:06 Mike Pagano
2016-04-20 11:23 Mike Pagano
2016-04-06 11:23 Mike Pagano
2016-03-22 22:47 Mike Pagano
2016-03-17 22:52 Mike Pagano
2016-02-16 15:28 Mike Pagano
2016-01-31 23:29 Mike Pagano
2016-01-23 18:30 Mike Pagano
2016-01-20 13:54 Mike Pagano
2015-12-15 11:17 Mike Pagano
2015-12-10 13:54 Mike Pagano
2015-11-10  0:30 Mike Pagano
2015-11-05 23:29 Mike Pagano
2015-11-05 23:29 Mike Pagano
2015-10-27 13:19 Mike Pagano
2015-10-26 20:51 Mike Pagano
2015-10-26 20:49 Mike Pagano
2015-10-03 16:07 Mike Pagano
2015-10-02 12:08 Mike Pagano
2015-09-29 17:50 Mike Pagano
2015-09-28 23:57 Mike Pagano
2015-09-21 22:16 Mike Pagano
2015-09-14 15:20 Mike Pagano
2015-08-17 15:38 Mike Pagano
2015-08-12 14:17 Mike Pagano
2015-08-10 23:42 Mike Pagano
2015-08-03 19:01 Mike Pagano
2015-07-22 10:31 Mike Pagano
2015-07-22 10:09 Mike Pagano
2015-07-19 18:55 Mike Pagano
2015-07-17 15:24 Mike Pagano
2015-07-10 23:47 Mike Pagano
2015-07-01 15:33 Mike Pagano
2015-06-27 19:50 Mike Pagano
2015-06-26 22:36 Mike Pagano
2015-06-20 17:37 Mike Pagano
2015-06-08 17:59 Mike Pagano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1457221107.4a919eff2d079c34d6f84bf9073c32ef11af9864.mpagano@gentoo \
    --to=mpagano@gentoo.org \
    --cc=gentoo-commits@lists.gentoo.org \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox