--- /dev/null
+From 7e31a0159461818a1bda49662921b98a29c1187b Mon Sep 17 00:00:00 2001
+From: Takashi Iwai <tiwai@suse.de>
+Date: Mon, 22 Feb 2016 15:18:13 +0100
+Subject: ALSA: hda - Apply clock gate workaround to Skylake, too
+
+From: Takashi Iwai <tiwai@suse.de>
+
+commit 7e31a0159461818a1bda49662921b98a29c1187b upstream.
+
+Some Skylake machines show the codec probe errors in certain
+situations, e.g. HP Z240 desktop fails to probe the onboard Realtek
+codec at reloading the snd-hda-intel module like:
+ snd_hda_intel 0000:00:1f.3: spurious response 0x200:0x2, last cmd=0x000000
+ snd_hda_intel 0000:00:1f.3: azx_get_response timeout, switching to polling mode: lastcmd=0x000f0000
+ snd_hda_intel 0000:00:1f.3: No response from codec, disabling MSI: last cmd=0x000f0000
+ snd_hda_intel 0000:00:1f.3: Codec #0 probe error; disabling it...
+ hdaudio hdaudioC0D2: no AFG or MFG node found
+ snd_hda_intel 0000:00:1f.3: no codecs initialized
+
+Also, HP G470 G3 suffers from the similar problem, as reported in
+bugzilla below. On this machine, the codec probe error appears even
+at a fresh boot.
+
+As Libin suggested, the same workaround used for Broxton in the commit
+[6639484ddaf6: ALSA: hda - disable dynamic clock gating on Broxton
+ before reset] can be applied for Skylake in order to fix this problem.
+The Intel HW team also confirmed that this is needed for SKL.
+
+This patch makes the workaround applied to both SKL and BXT
+platforms. The referred macros are moved and one superfluous macro
+(IS_BROXTON()) is another one (IS_BXT()) as well.
+
+Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=112731
+Suggested-by: Libin Yang <libin.yang@linux.intel.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/hda_intel.c | 16 +++++++---------
+ 1 file changed, 7 insertions(+), 9 deletions(-)
+
+--- a/sound/pci/hda/hda_intel.c
++++ b/sound/pci/hda/hda_intel.c
+@@ -357,7 +357,10 @@ enum {
+ ((pci)->device == 0x0d0c) || \
+ ((pci)->device == 0x160c))
+
+-#define IS_BROXTON(pci) ((pci)->device == 0x5a98)
++#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
++#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
++#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
++#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
+
+ static char *driver_short_names[] = {
+ [AZX_DRIVER_ICH] = "HDA Intel",
+@@ -534,13 +537,13 @@ static void hda_intel_init_chip(struct a
+
+ if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
+ snd_hdac_set_codec_wakeup(bus, true);
+- if (IS_BROXTON(pci)) {
++ if (IS_SKL_PLUS(pci)) {
+ pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
+ val = val & ~INTEL_HDA_CGCTL_MISCBDCGE;
+ pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
+ }
+ azx_init_chip(chip, full_reset);
+- if (IS_BROXTON(pci)) {
++ if (IS_SKL_PLUS(pci)) {
+ pci_read_config_dword(pci, INTEL_HDA_CGCTL, &val);
+ val = val | INTEL_HDA_CGCTL_MISCBDCGE;
+ pci_write_config_dword(pci, INTEL_HDA_CGCTL, val);
+@@ -549,7 +552,7 @@ static void hda_intel_init_chip(struct a
+ snd_hdac_set_codec_wakeup(bus, false);
+
+ /* reduce dma latency to avoid noise */
+- if (IS_BROXTON(pci))
++ if (IS_BXT(pci))
+ bxt_reduce_dma_latency(chip);
+ }
+
+@@ -971,11 +974,6 @@ static int azx_resume(struct device *dev
+ /* put codec down to D3 at hibernation for Intel SKL+;
+ * otherwise BIOS may still access the codec and screw up the driver
+ */
+-#define IS_SKL(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0xa170)
+-#define IS_SKL_LP(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x9d70)
+-#define IS_BXT(pci) ((pci)->vendor == 0x8086 && (pci)->device == 0x5a98)
+-#define IS_SKL_PLUS(pci) (IS_SKL(pci) || IS_SKL_LP(pci) || IS_BXT(pci))
+-
+ static int azx_freeze_noirq(struct device *dev)
+ {
+ struct pci_dev *pci = to_pci_dev(dev);
--- /dev/null
+From 3b43b71f05d3ecd01c4116254666d9492301697d Mon Sep 17 00:00:00 2001
+From: Kai-Heng Feng <kaihengfeng@gmail.com>
+Date: Thu, 25 Feb 2016 15:19:38 +0800
+Subject: ALSA: hda - Fixing background noise on Dell Inspiron 3162
+
+From: Kai-Heng Feng <kaihengfeng@gmail.com>
+
+commit 3b43b71f05d3ecd01c4116254666d9492301697d upstream.
+
+After login to the desktop on Dell Inspiron 3162,
+there's a very loud background noise comes from the builtin speaker.
+The noise does not go away even if the speaker is muted.
+
+The noise disappears after using the aamix fixup.
+
+Codec: Realtek ALC3234
+Address: 0
+AFG Function Id: 0x1 (unsol 1)
+ Vendor Id: 0x10ec0255
+ Subsystem Id: 0x10280725
+ Revision Id: 0x100002
+ No Modem Function Group found
+
+BugLink: http://bugs.launchpad.net/bugs/1549620
+Signed-off-by: Kai-Heng Feng <kai.heng.feng@canonical.com>
+Signed-off-by: Takashi Iwai <tiwai@suse.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ sound/pci/hda/patch_realtek.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/sound/pci/hda/patch_realtek.c
++++ b/sound/pci/hda/patch_realtek.c
+@@ -4749,6 +4749,7 @@ enum {
+ ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE,
+ ALC293_FIXUP_LENOVO_SPK_NOISE,
+ ALC233_FIXUP_LENOVO_LINE2_MIC_HOTKEY,
++ ALC255_FIXUP_DELL_SPK_NOISE,
+ };
+
+ static const struct hda_fixup alc269_fixups[] = {
+@@ -5368,6 +5369,12 @@ static const struct hda_fixup alc269_fix
+ .type = HDA_FIXUP_FUNC,
+ .v.func = alc233_fixup_lenovo_line2_mic_hotkey,
+ },
++ [ALC255_FIXUP_DELL_SPK_NOISE] = {
++ .type = HDA_FIXUP_FUNC,
++ .v.func = alc_fixup_disable_aamix,
++ .chained = true,
++ .chain_id = ALC255_FIXUP_DELL1_MIC_NO_PRESENCE
++ },
+ };
+
+ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
+@@ -5410,6 +5417,7 @@ static const struct snd_pci_quirk alc269
+ SND_PCI_QUIRK(0x1028, 0x06df, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+ SND_PCI_QUIRK(0x1028, 0x06e0, "Dell", ALC293_FIXUP_DISABLE_AAMIX_MULTIJACK),
+ SND_PCI_QUIRK(0x1028, 0x0704, "Dell XPS 13", ALC256_FIXUP_DELL_XPS_13_HEADPHONE_NOISE),
++ SND_PCI_QUIRK(0x1028, 0x0725, "Dell Inspiron 3162", ALC255_FIXUP_DELL_SPK_NOISE),
+ SND_PCI_QUIRK(0x1028, 0x164a, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x164b, "Dell", ALC293_FIXUP_DELL1_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
--- /dev/null
+From bb143f814ea488769ca2e79e0b376139cb5f134b Mon Sep 17 00:00:00 2001
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Tue, 23 Feb 2016 11:55:16 +0530
+Subject: ARCv2: SMP: Emulate IPI to self using software triggered interrupt
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+commit bb143f814ea488769ca2e79e0b376139cb5f134b upstream.
+
+ARConnect/MCIP Inter-Core-Interrupt module can't send interrupt to
+local core. So use core intc capability to trigger software
+interrupt to self, using an unsued IRQ #21.
+
+This showed up as csd deadlock with LTP trace_sched on a dual core
+system. This test acts as scheduler fuzzer, triggering all sorts of
+schedulting activity. Trouble starts with IPI to self, which doesn't get
+delivered (effectively lost due to H/w capability), but the msg intended
+to be sent remain enqueued in per-cpu @ipi_data.
+
+All subsequent IPIs to this core from other cores get elided due to the
+IPI coalescing optimization in ipi_send_msg_one() where a pending msg
+implies an IPI already sent and assumes other core is yet to ack it.
+After the elided IPI, other core simply goes into csd_lock_wait()
+but never comes out as this core never sees the interrupt.
+
+Fixes STAR 9001008624
+
+Cc: Peter Zijlstra <peterz@infradead.org>
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/include/asm/irqflags-arcv2.h | 11 +++++++++++
+ arch/arc/kernel/entry-arcv2.S | 11 ++++++-----
+ arch/arc/kernel/mcip.c | 15 +++++++++++++++
+ 3 files changed, 32 insertions(+), 5 deletions(-)
+
+--- a/arch/arc/include/asm/irqflags-arcv2.h
++++ b/arch/arc/include/asm/irqflags-arcv2.h
+@@ -22,6 +22,7 @@
+ #define AUX_IRQ_CTRL 0x00E
+ #define AUX_IRQ_ACT 0x043 /* Active Intr across all levels */
+ #define AUX_IRQ_LVL_PEND 0x200 /* Pending Intr across all levels */
++#define AUX_IRQ_HINT 0x201 /* For generating Soft Interrupts */
+ #define AUX_IRQ_PRIORITY 0x206
+ #define ICAUSE 0x40a
+ #define AUX_IRQ_SELECT 0x40b
+@@ -112,6 +113,16 @@ static inline int arch_irqs_disabled(voi
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+ }
+
++static inline void arc_softirq_trigger(int irq)
++{
++ write_aux_reg(AUX_IRQ_HINT, irq);
++}
++
++static inline void arc_softirq_clear(int irq)
++{
++ write_aux_reg(AUX_IRQ_HINT, 0);
++}
++
+ #else
+
+ .macro IRQ_DISABLE scratch
+--- a/arch/arc/kernel/entry-arcv2.S
++++ b/arch/arc/kernel/entry-arcv2.S
+@@ -45,11 +45,12 @@ VECTOR reserved ; Reserved slots
+ VECTOR handle_interrupt ; (16) Timer0
+ VECTOR handle_interrupt ; unused (Timer1)
+ VECTOR handle_interrupt ; unused (WDT)
+-VECTOR handle_interrupt ; (19) ICI (inter core interrupt)
+-VECTOR handle_interrupt
+-VECTOR handle_interrupt
+-VECTOR handle_interrupt
+-VECTOR handle_interrupt ; (23) End of fixed IRQs
++VECTOR handle_interrupt ; (19) Inter core Interrupt (IPI)
++VECTOR handle_interrupt ; (20) perf Interrupt
++VECTOR handle_interrupt ; (21) Software Triggered Intr (Self IPI)
++VECTOR handle_interrupt ; unused
++VECTOR handle_interrupt ; (23) unused
++# End of fixed IRQs
+
+ .rept CONFIG_ARC_NUMBER_OF_INTERRUPTS - 8
+ VECTOR handle_interrupt
+--- a/arch/arc/kernel/mcip.c
++++ b/arch/arc/kernel/mcip.c
+@@ -11,9 +11,12 @@
+ #include <linux/smp.h>
+ #include <linux/irq.h>
+ #include <linux/spinlock.h>
++#include <asm/irqflags-arcv2.h>
+ #include <asm/mcip.h>
+ #include <asm/setup.h>
+
++#define SOFTIRQ_IRQ 21
++
+ static char smp_cpuinfo_buf[128];
+ static int idu_detected;
+
+@@ -22,6 +25,7 @@ static DEFINE_RAW_SPINLOCK(mcip_lock);
+ static void mcip_setup_per_cpu(int cpu)
+ {
+ smp_ipi_irq_setup(cpu, IPI_IRQ);
++ smp_ipi_irq_setup(cpu, SOFTIRQ_IRQ);
+ }
+
+ static void mcip_ipi_send(int cpu)
+@@ -29,6 +33,12 @@ static void mcip_ipi_send(int cpu)
+ unsigned long flags;
+ int ipi_was_pending;
+
++ /* ARConnect can only send IPI to others */
++ if (unlikely(cpu == raw_smp_processor_id())) {
++ arc_softirq_trigger(SOFTIRQ_IRQ);
++ return;
++ }
++
+ /*
+ * NOTE: We must spin here if the other cpu hasn't yet
+ * serviced a previous message. This can burn lots
+@@ -63,6 +73,11 @@ static void mcip_ipi_clear(int irq)
+ unsigned long flags;
+ unsigned int __maybe_unused copy;
+
++ if (unlikely(irq == SOFTIRQ_IRQ)) {
++ arc_softirq_clear(irq);
++ return;
++ }
++
+ raw_spin_lock_irqsave(&mcip_lock, flags);
+
+ /* Who sent the IPI */
--- /dev/null
+From cbfe74a753e877b49dc54e9b04d5d42230ca0aed Mon Sep 17 00:00:00 2001
+From: Vineet Gupta <vgupta@synopsys.com>
+Date: Fri, 8 Jan 2016 12:29:10 +0530
+Subject: ARCv2: STAR 9000950267: Handle return from intr to Delay Slot #2
+
+From: Vineet Gupta <vgupta@synopsys.com>
+
+commit cbfe74a753e877b49dc54e9b04d5d42230ca0aed upstream.
+
+Returning to delay slot, riding an interrupti, had one loose end.
+AUX_USER_SP used for restoring user mode SP upon RTIE was not being
+setup from orig task's saved value, causing task to use wrong SP,
+leading to ProtV errors.
+
+The reason being:
+ - INTERRUPT_EPILOGUE returns to a kernel trampoline, thus not expected to restore it
+ - EXCEPTION_EPILOGUE is not used at all
+
+Fix that by restoring AUX_USER_SP explicitly in the trampoline.
+
+This was broken in the original workaround, but the error scenarios got
+reduced considerably since v3.14 due to following:
+
+ 1. The Linuxthreads.old based userspace at the time caused many more
+ exceptions in delay slot than the current NPTL based one.
+ Infact with current userspace the error doesn't happen at all.
+
+ 2. Return from interrupt (delay slot or otherwise) doesn't get exercised much
+ after commit 4de0e52867d8 ("Really Re-enable interrupts to avoid deadlocks")
+ since IRQ_ACTIVE.active being clear means most returns are as if from pure
+ kernel (even for active interrupts)
+
+Infact the issue only happened in an experimental branch where I was tinkering with
+reverted 4de0e52867d8
+
+Fixes: 4255b07f2c9c ("ARCv2: STAR 9000793984: Handle return from intr to Delay Slot")
+Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/arc/kernel/entry-arcv2.S | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+--- a/arch/arc/kernel/entry-arcv2.S
++++ b/arch/arc/kernel/entry-arcv2.S
+@@ -211,7 +211,11 @@ debug_marker_syscall:
+ ; (since IRQ NOT allowed in DS in ARCv2, this can only happen if orig
+ ; entry was via Exception in DS which got preempted in kernel).
+ ;
+-; IRQ RTIE won't reliably restore DE bit and/or BTA, needs handling
++; IRQ RTIE won't reliably restore DE bit and/or BTA, needs workaround
++;
++; Solution is return from Intr w/o any delay slot quirks into a kernel trampoline
++; and from pure kernel mode return to delay slot which handles DS bit/BTA correctly
++
+ .Lintr_ret_to_delay_slot:
+ debug_marker_ds:
+
+@@ -222,18 +226,23 @@ debug_marker_ds:
+ ld r2, [sp, PT_ret]
+ ld r3, [sp, PT_status32]
+
++ ; STAT32 for Int return created from scratch
++ ; (No delay dlot, disable Further intr in trampoline)
++
+ bic r0, r3, STATUS_U_MASK|STATUS_DE_MASK|STATUS_IE_MASK|STATUS_L_MASK
+ st r0, [sp, PT_status32]
+
+ mov r1, .Lintr_ret_to_delay_slot_2
+ st r1, [sp, PT_ret]
+
++ ; Orig exception PC/STAT32 safekept @orig_r0 and @event stack slots
+ st r2, [sp, 0]
+ st r3, [sp, 4]
+
+ b .Lisr_ret_fast_path
+
+ .Lintr_ret_to_delay_slot_2:
++ ; Trampoline to restore orig exception PC/STAT32/BTA/AUX_USER_SP
+ sub sp, sp, SZ_PT_REGS
+ st r9, [sp, -4]
+
+@@ -243,11 +252,19 @@ debug_marker_ds:
+ ld r9, [sp, 4]
+ sr r9, [erstatus]
+
++ ; restore AUX_USER_SP if returning to U mode
++ bbit0 r9, STATUS_U_BIT, 1f
++ ld r9, [sp, PT_sp]
++ sr r9, [AUX_USER_SP]
++
++1:
+ ld r9, [sp, 8]
+ sr r9, [erbta]
+
+ ld r9, [sp, -4]
+ add sp, sp, SZ_PT_REGS
++
++ ; return from pure kernel mode to delay slot
+ rtie
+
+ END(ret_from_exception)
--- /dev/null
+From e912e685f372ab62a2405a1acd923597f524e94a Mon Sep 17 00:00:00 2001
+From: Oliver Neukum <oneukum@suse.com>
+Date: Mon, 18 Jan 2016 15:45:18 +0100
+Subject: cdc-acm:exclude Samsung phone 04e8:685d
+
+From: Oliver Neukum <oneukum@suse.com>
+
+commit e912e685f372ab62a2405a1acd923597f524e94a upstream.
+
+This phone needs to be handled by a specialised firmware tool
+and is reported to crash irrevocably if cdc-acm takes it.
+
+Signed-off-by: Oliver Neukum <oneukum@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/usb/class/cdc-acm.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -1841,6 +1841,11 @@ static const struct usb_device_id acm_id
+ },
+ #endif
+
++ /*Samsung phone in firmware update mode */
++ { USB_DEVICE(0x04e8, 0x685d),
++ .driver_info = IGNORE_DEVICE,
++ },
++
+ /* Exclude Infineon Flash Loader utility */
+ { USB_DEVICE(0x058b, 0x0041),
+ .driver_info = IGNORE_DEVICE,
--- /dev/null
+From 8eee1d3ed5b6fc8e14389567c9a6f53f82bb7224 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Mon, 1 Feb 2016 11:33:21 -0500
+Subject: libata: fix sff host state machine locking while polling
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 8eee1d3ed5b6fc8e14389567c9a6f53f82bb7224 upstream.
+
+The bulk of ATA host state machine is implemented by
+ata_sff_hsm_move(). The function is called from either the interrupt
+handler or, if polling, a work item. Unlike from the interrupt path,
+the polling path calls the function without holding the host lock and
+ata_sff_hsm_move() selectively grabs the lock.
+
+This is completely broken. If an IRQ triggers while polling is in
+progress, the two can easily race and end up accessing the hardware
+and updating state machine state at the same time. This can put the
+state machine in an illegal state and lead to a crash like the
+following.
+
+ kernel BUG at drivers/ata/libata-sff.c:1302!
+ invalid opcode: 0000 [#1] SMP DEBUG_PAGEALLOC KASAN
+ Modules linked in:
+ CPU: 1 PID: 10679 Comm: syz-executor Not tainted 4.5.0-rc1+ #300
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
+ task: ffff88002bd00000 ti: ffff88002e048000 task.ti: ffff88002e048000
+ RIP: 0010:[<ffffffff83a83409>] [<ffffffff83a83409>] ata_sff_hsm_move+0x619/0x1c60
+ ...
+ Call Trace:
+ <IRQ>
+ [<ffffffff83a84c31>] __ata_sff_port_intr+0x1e1/0x3a0 drivers/ata/libata-sff.c:1584
+ [<ffffffff83a85611>] ata_bmdma_port_intr+0x71/0x400 drivers/ata/libata-sff.c:2877
+ [< inline >] __ata_sff_interrupt drivers/ata/libata-sff.c:1629
+ [<ffffffff83a85bf3>] ata_bmdma_interrupt+0x253/0x580 drivers/ata/libata-sff.c:2902
+ [<ffffffff81479f98>] handle_irq_event_percpu+0x108/0x7e0 kernel/irq/handle.c:157
+ [<ffffffff8147a717>] handle_irq_event+0xa7/0x140 kernel/irq/handle.c:205
+ [<ffffffff81484573>] handle_edge_irq+0x1e3/0x8d0 kernel/irq/chip.c:623
+ [< inline >] generic_handle_irq_desc include/linux/irqdesc.h:146
+ [<ffffffff811a92bc>] handle_irq+0x10c/0x2a0 arch/x86/kernel/irq_64.c:78
+ [<ffffffff811a7e4d>] do_IRQ+0x7d/0x1a0 arch/x86/kernel/irq.c:240
+ [<ffffffff86653d4c>] common_interrupt+0x8c/0x8c arch/x86/entry/entry_64.S:520
+ <EOI>
+ [< inline >] rcu_lock_acquire include/linux/rcupdate.h:490
+ [< inline >] rcu_read_lock include/linux/rcupdate.h:874
+ [<ffffffff8164b4a1>] filemap_map_pages+0x131/0xba0 mm/filemap.c:2145
+ [< inline >] do_fault_around mm/memory.c:2943
+ [< inline >] do_read_fault mm/memory.c:2962
+ [< inline >] do_fault mm/memory.c:3133
+ [< inline >] handle_pte_fault mm/memory.c:3308
+ [< inline >] __handle_mm_fault mm/memory.c:3418
+ [<ffffffff816efb16>] handle_mm_fault+0x2516/0x49a0 mm/memory.c:3447
+ [<ffffffff8127dc16>] __do_page_fault+0x376/0x960 arch/x86/mm/fault.c:1238
+ [<ffffffff8127e358>] trace_do_page_fault+0xe8/0x420 arch/x86/mm/fault.c:1331
+ [<ffffffff8126f514>] do_async_page_fault+0x14/0xd0 arch/x86/kernel/kvm.c:264
+ [<ffffffff86655578>] async_page_fault+0x28/0x30 arch/x86/entry/entry_64.S:986
+
+Fix it by ensuring that the polling path is holding the host lock
+before entering ata_sff_hsm_move() so that all hardware accesses and
+state updates are performed under the host lock.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-and-tested-by: Dmitry Vyukov <dvyukov@google.com>
+Link: http://lkml.kernel.org/g/CACT4Y+b_JsOxJu2EZyEf+mOXORc_zid5V1-pLZSroJVxyWdSpw@mail.gmail.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/libata-sff.c | 32 +++++++++++---------------------
+ 1 file changed, 11 insertions(+), 21 deletions(-)
+
+--- a/drivers/ata/libata-sff.c
++++ b/drivers/ata/libata-sff.c
+@@ -997,12 +997,9 @@ static inline int ata_hsm_ok_in_wq(struc
+ 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 a
+ } 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 a
+ }
+ } 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_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
+ 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);
+ }
+
+ /**
--- /dev/null
+From 4fa11ec726a32ea6dd768dbb2e2af3453a98ec0a Mon Sep 17 00:00:00 2001
+From: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
+Date: Tue, 12 Jan 2016 14:30:19 +0530
+Subject: mac80211: Requeue work after scan complete for all VIF types.
+
+From: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
+
+commit 4fa11ec726a32ea6dd768dbb2e2af3453a98ec0a upstream.
+
+During a sw scan ieee80211_iface_work ignores work items for all vifs.
+However after the scan complete work is requeued only for STA, ADHOC
+and MESH iftypes.
+
+This occasionally results in event processing getting delayed/not
+processed for iftype AP when it coexists with a STA. This can result
+in data halt and eventually disconnection on the AP interface.
+
+Signed-off-by: Sachin Kulkarni <Sachin.Kulkarni@imgtec.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/mac80211/ibss.c | 1 -
+ net/mac80211/mesh.c | 11 -----------
+ net/mac80211/mesh.h | 4 ----
+ net/mac80211/mlme.c | 2 --
+ net/mac80211/scan.c | 12 +++++++++++-
+ 5 files changed, 11 insertions(+), 19 deletions(-)
+
+--- a/net/mac80211/ibss.c
++++ b/net/mac80211/ibss.c
+@@ -1732,7 +1732,6 @@ void ieee80211_ibss_notify_scan_complete
+ if (sdata->vif.type != NL80211_IFTYPE_ADHOC)
+ continue;
+ sdata->u.ibss.last_scan_completed = jiffies;
+- ieee80211_queue_work(&local->hw, &sdata->work);
+ }
+ mutex_unlock(&local->iflist_mtx);
+ }
+--- a/net/mac80211/mesh.c
++++ b/net/mac80211/mesh.c
+@@ -1370,17 +1370,6 @@ out:
+ sdata_unlock(sdata);
+ }
+
+-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
+-{
+- struct ieee80211_sub_if_data *sdata;
+-
+- rcu_read_lock();
+- list_for_each_entry_rcu(sdata, &local->interfaces, list)
+- if (ieee80211_vif_is_mesh(&sdata->vif) &&
+- ieee80211_sdata_running(sdata))
+- ieee80211_queue_work(&local->hw, &sdata->work);
+- rcu_read_unlock();
+-}
+
+ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
+ {
+--- a/net/mac80211/mesh.h
++++ b/net/mac80211/mesh.h
+@@ -362,14 +362,10 @@ static inline bool mesh_path_sel_is_hwmp
+ return sdata->u.mesh.mesh_pp_id == IEEE80211_PATH_PROTOCOL_HWMP;
+ }
+
+-void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local);
+-
+ void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata);
+ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata);
+ void ieee80211s_stop(void);
+ #else
+-static inline void
+-ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) {}
+ static inline bool mesh_path_sel_is_hwmp(struct ieee80211_sub_if_data *sdata)
+ { return false; }
+ static inline void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata)
+--- a/net/mac80211/mlme.c
++++ b/net/mac80211/mlme.c
+@@ -4003,8 +4003,6 @@ static void ieee80211_restart_sta_timer(
+ if (!ieee80211_hw_check(&sdata->local->hw, CONNECTION_MONITOR))
+ ieee80211_queue_work(&sdata->local->hw,
+ &sdata->u.mgd.monitor_work);
+- /* and do all the other regular work too */
+- ieee80211_queue_work(&sdata->local->hw, &sdata->work);
+ }
+ }
+
+--- a/net/mac80211/scan.c
++++ b/net/mac80211/scan.c
+@@ -314,6 +314,7 @@ static void __ieee80211_scan_completed(s
+ bool was_scanning = local->scanning;
+ struct cfg80211_scan_request *scan_req;
+ struct ieee80211_sub_if_data *scan_sdata;
++ struct ieee80211_sub_if_data *sdata;
+
+ lockdep_assert_held(&local->mtx);
+
+@@ -373,7 +374,16 @@ static void __ieee80211_scan_completed(s
+
+ ieee80211_mlme_notify_scan_completed(local);
+ ieee80211_ibss_notify_scan_completed(local);
+- ieee80211_mesh_notify_scan_completed(local);
++
++ /* Requeue all the work that might have been ignored while
++ * the scan was in progress; if there was none this will
++ * just be a no-op for the particular interface.
++ */
++ list_for_each_entry_rcu(sdata, &local->interfaces, list) {
++ if (ieee80211_sdata_running(sdata))
++ ieee80211_queue_work(&sdata->local->hw, &sdata->work);
++ }
++
+ if (was_scanning)
+ ieee80211_start_next_roc(local);
+ }
--- /dev/null
+From 3f416f22d1e21709a631189ba169f76fd267b374 Mon Sep 17 00:00:00 2001
+From: Jiri Olsa <jolsa@kernel.org>
+Date: Wed, 20 Jan 2016 12:56:34 +0100
+Subject: perf stat: Do not clean event's private stats
+
+From: Jiri Olsa <jolsa@kernel.org>
+
+commit 3f416f22d1e21709a631189ba169f76fd267b374 upstream.
+
+Mel reported stddev reporting was broken due to following commit:
+
+ 106a94a0f8c2 ("perf stat: Introduce read_counters function")
+
+This commit merged interval and overall counters reading into single
+read_counters function.
+
+The old interval code cleaned the stddev data for some reason (it's
+never displayed in interval mode) and the mentioned commit kept on
+cleaning the stddev data in merged function, which resulted in the
+stddev not being displayed.
+
+Removing the wrong stddev data cleanup init_stats call.
+
+Reported-and-Tested-by: Mel Gorman <mgorman@techsingularity.net>
+Signed-off-by: Jiri Olsa <jolsa@kernel.org>
+Cc: David Ahern <dsahern@gmail.com>
+Cc: Namhyung Kim <namhyung@kernel.org>
+Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
+Fixes: 106a94a0f8c2 ("perf stat: Introduce read_counters function")
+Link: http://lkml.kernel.org/r/1453290995-18485-4-git-send-email-jolsa@kernel.org
+Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ tools/perf/util/stat.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+--- a/tools/perf/util/stat.c
++++ b/tools/perf/util/stat.c
+@@ -310,7 +310,6 @@ int perf_stat_process_counter(struct per
+ int i, ret;
+
+ aggr->val = aggr->ena = aggr->run = 0;
+- init_stats(ps->res_stats);
+
+ if (counter->per_pkg)
+ zero_per_pkg(counter);
--- /dev/null
+From cb43285ff7039fe3c4b0bc476e6d6569c31104f3 Mon Sep 17 00:00:00 2001
+From: Quinn Tran <quinn.tran@qlogic.com>
+Date: Thu, 4 Feb 2016 11:45:16 -0500
+Subject: qla2xxx: Fix stale pointer access.
+
+From: Quinn Tran <quinn.tran@qlogic.com>
+
+commit cb43285ff7039fe3c4b0bc476e6d6569c31104f3 upstream.
+
+[ Upstream Commit 84e32a06f4f8756ce9ec3c8dc7e97896575f0771 ]
+
+Commit 84e32a0 ("qla2xxx: Use pci_enable_msix_range() instead of
+pci_enable_msix()") introduced a regression when target mode is enabled.
+In qla24xx_enable_msix(), ha->max_rsp_queues was incorrectly set
+to a value higher than the number of response queues allocated causing
+an invalid dereference. Specifically here in qla2x00_init_rings():
+ *rsp->in_ptr = 0;
+
+Add additional check to make sure the pointer is valid. following
+call stack will be seen
+
+---- 8< ----
+RIP: 0010:[<ffffffffa02ccadc>] [<ffffffffa02ccadc>] qla2x00_init_rings+0xdc/0x320 [qla2xxx]
+RSP: 0018:ffff880429447dd8 EFLAGS: 00010082
+....
+Call Trace:
+[<ffffffffa02ceb40>] qla2x00_abort_isp+0x170/0x6b0 [qla2xxx]
+[<ffffffffa02c6f77>] qla2x00_do_dpc+0x357/0x7f0 [qla2xxx]
+[<ffffffffa02c6c20>] ? qla2x00_relogin+0x260/0x260 [qla2xxx]
+[<ffffffff8107d2c9>] kthread+0xc9/0xe0
+[<ffffffff8107d200>] ? flush_kthread_worker+0x90/0x90
+[<ffffffff8172cc6f>] ret_from_fork+0x3f/0x70
+[<ffffffff8107d200>] ? flush_kthread_worker+0x90/0x90
+---- 8< ----
+
+Signed-off-by: Quinn Tran <quinn.tran@qlogic.com>
+Signed-off-by: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/scsi/qla2xxx/qla_init.c | 10 +++++-----
+ drivers/scsi/qla2xxx/qla_isr.c | 4 ++--
+ drivers/scsi/qla2xxx/qla_mid.c | 4 ++--
+ drivers/scsi/qla2xxx/qla_os.c | 6 ++++++
+ drivers/scsi/qla2xxx/qla_tmpl.c | 16 ++++++++++++++++
+ 5 files changed, 31 insertions(+), 9 deletions(-)
+
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -2192,7 +2192,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;
+@@ -2209,7 +2209,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;
+@@ -4961,7 +4961,7 @@ qla25xx_init_queues(struct qla_hw_data *
+
+ 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)
+@@ -4976,8 +4976,8 @@ qla25xx_init_queues(struct qla_hw_data *
+ }
+ 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)
+--- a/drivers/scsi/qla2xxx/qla_isr.c
++++ b/drivers/scsi/qla2xxx/qla_isr.c
+@@ -3018,9 +3018,9 @@ qla24xx_enable_msix(struct qla_hw_data *
+ "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) {
+--- a/drivers/scsi/qla2xxx/qla_mid.c
++++ b/drivers/scsi/qla2xxx/qla_mid.c
+@@ -600,7 +600,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
+ /* 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,
+@@ -614,7 +614,7 @@ qla25xx_delete_queues(struct scsi_qla_ho
+ /* 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,
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -397,6 +397,9 @@ static void qla2x00_free_queues(struct q
+ 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);
+ }
+@@ -404,6 +407,9 @@ static void qla2x00_free_queues(struct q
+ 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);
+ }
+--- 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_
+ 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_
+ } 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_
+ 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_
+ } 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);
--- /dev/null
+From 041bd12e272c53a35c54c13875839bcb98c999ce Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Tue, 9 Feb 2016 16:11:26 -0500
+Subject: Revert "workqueue: make sure delayed work run in local cpu"
+
+From: Tejun Heo <tj@kernel.org>
+
+commit 041bd12e272c53a35c54c13875839bcb98c999ce upstream.
+
+This reverts commit 874bbfe600a660cba9c776b3957b1ce393151b76.
+
+Workqueue used to implicity guarantee that work items queued without
+explicit CPU specified are put on the local CPU. Recent changes in
+timer broke the guarantee and led to vmstat breakage which was fixed
+by 176bed1de5bf ("vmstat: explicitly schedule per-cpu work on the CPU
+we need it to run on").
+
+vmstat is the most likely to expose the issue and it's quite possible
+that there are other similar problems which are a lot more difficult
+to trigger. As a preventive measure, 874bbfe600a6 ("workqueue: make
+sure delayed work run in local cpu") was applied to restore the local
+CPU guarnatee. Unfortunately, the change exposed a bug in timer code
+which got fixed by 22b886dd1018 ("timers: Use proper base migration in
+add_timer_on()"). Due to code restructuring, the commit couldn't be
+backported beyond certain point and stable kernels which only had
+874bbfe600a6 started crashing.
+
+The local CPU guarantee was accidental more than anything else and we
+want to get rid of it anyway. As, with the vmstat case fixed,
+874bbfe600a6 is causing more problems than it's fixing, it has been
+decided to take the chance and officially break the guarantee by
+reverting the commit. A debug feature will be added to force foreign
+CPU assignment to expose cases relying on the guarantee and fixes for
+the individual cases will be backported to stable as necessary.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Fixes: 874bbfe600a6 ("workqueue: make sure delayed work run in local cpu")
+Link: http://lkml.kernel.org/g/20160120211926.GJ10810@quack.suse.cz
+Cc: Mike Galbraith <umgwanakikbuti@gmail.com>
+Cc: Henrique de Moraes Holschuh <hmh@hmh.eng.br>
+Cc: Daniel Bilik <daniel.bilik@neosystem.cz>
+Cc: Jan Kara <jack@suse.cz>
+Cc: Shaohua Li <shli@fb.com>
+Cc: Sasha Levin <sasha.levin@oracle.com>
+Cc: Ben Hutchings <ben@decadent.org.uk>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Cc: Daniel Bilik <daniel.bilik@neosystem.cz>
+Cc: Jiri Slaby <jslaby@suse.cz>
+Cc: Michal Hocko <mhocko@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -1468,13 +1468,13 @@ static void __queue_delayed_work(int cpu
+ 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);
+ }
+
+ /**
--- /dev/null
+From 6736fde9672ff6717ac576e9bba2fd5f3dfec822 Mon Sep 17 00:00:00 2001
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 26 Jan 2016 11:29:03 +0100
+Subject: rfkill: fix rfkill_fop_read wait_event usage
+
+From: Johannes Berg <johannes.berg@intel.com>
+
+commit 6736fde9672ff6717ac576e9bba2fd5f3dfec822 upstream.
+
+The code within wait_event_interruptible() is called with
+!TASK_RUNNING, so mustn't call any functions that can sleep,
+like mutex_lock().
+
+Since we re-check the list_empty() in a loop after the wait,
+it's safe to simply use list_empty() without locking.
+
+This bug has existed forever, but was only discovered now
+because all userspace implementations, including the default
+'rfkill' tool, use poll() or select() to get a readable fd
+before attempting to read.
+
+Fixes: c64fb01627e24 ("rfkill: create useful userspace interface")
+Reported-by: Dmitry Vyukov <dvyukov@google.com>
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/rfkill/core.c | 16 ++++------------
+ 1 file changed, 4 insertions(+), 12 deletions(-)
+
+--- a/net/rfkill/core.c
++++ b/net/rfkill/core.c
+@@ -1095,17 +1095,6 @@ static unsigned int rfkill_fop_poll(stru
+ return res;
+ }
+
+-static bool rfkill_readable(struct rfkill_data *data)
+-{
+- bool r;
+-
+- mutex_lock(&data->mtx);
+- r = !list_empty(&data->events);
+- mutex_unlock(&data->mtx);
+-
+- return r;
+-}
+-
+ static ssize_t rfkill_fop_read(struct file *file, char __user *buf,
+ size_t count, loff_t *pos)
+ {
+@@ -1122,8 +1111,11 @@ static ssize_t rfkill_fop_read(struct fi
+ goto out;
+ }
+ mutex_unlock(&data->mtx);
++ /* since we re-check and it just compares pointers,
++ * using !list_empty() without locking isn't a problem
++ */
+ ret = wait_event_interruptible(data->read_wait,
+- rfkill_readable(data));
++ !list_empty(&data->events));
+ mutex_lock(&data->mtx);
+
+ if (ret)
sd-optimal-i-o-size-is-in-bytes-not-sectors.patch
staging-speakup-fix-getting-port-information.patch
revert-staging-panel-usleep_range-is-preferred-over-udelay.patch
+cdc-acm-exclude-samsung-phone-04e8-685d.patch
+perf-stat-do-not-clean-event-s-private-stats.patch
+tick-nohz-set-the-correct-expiry-when-switching-to-nohz-lowres-mode.patch
+rfkill-fix-rfkill_fop_read-wait_event-usage.patch
+mac80211-requeue-work-after-scan-complete-for-all-vif-types.patch
+workqueue-handle-numa_no_node-for-unbound-pool_workqueue-lookup.patch
+revert-workqueue-make-sure-delayed-work-run-in-local-cpu.patch
+alsa-hda-apply-clock-gate-workaround-to-skylake-too.patch
+alsa-hda-fixing-background-noise-on-dell-inspiron-3162.patch
+target-fix-lun_reset-active-i-o-handling-for-ack_kref.patch
+target-fix-lun_reset-active-tmr-descriptor-handling.patch
+target-fix-tas-handling-for-multi-session-se_node_acls.patch
+target-fix-remote-port-tmr-abort-se_cmd-fabric-stop.patch
+target-fix-race-with-scf_send_delayed_tas-handling.patch
+spi-atmel-fix-gpio-chip-select-in-case-of-non-dt-platform.patch
+qla2xxx-fix-stale-pointer-access.patch
+libata-fix-sff-host-state-machine-locking-while-polling.patch
+arcv2-star-9000950267-handle-return-from-intr-to-delay-slot-2.patch
+arcv2-smp-emulate-ipi-to-self-using-software-triggered-interrupt.patch
--- /dev/null
+From 70f340df24518d36eeaefb6652d492f250115c19 Mon Sep 17 00:00:00 2001
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+Date: Wed, 27 Jan 2016 17:48:32 +0100
+Subject: spi: atmel: fix gpio chip-select in case of non-DT platform
+
+From: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+
+commit 70f340df24518d36eeaefb6652d492f250115c19 upstream.
+
+The non-DT platform that uses this driver (actually the AVR32) was taking a bad
+branch for determining if the IP would use gpio for CS.
+Adding the presence of DT as a condition fixes this issue.
+
+Fixes: 4820303480a1 ("spi: atmel: add support for the internal chip-select of the spi controller")
+Reported-by: Mans Rullgard <mans@mansr.com>
+Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
+[nicolas.ferre@atmel.com: extract from ml discussion]
+Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
+Tested-by: Mans Rullgard <mans@mansr.com>
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/spi/spi-atmel.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/spi/spi-atmel.c
++++ b/drivers/spi/spi-atmel.c
+@@ -1571,6 +1571,7 @@ static int atmel_spi_probe(struct platfo
+
+ as->use_cs_gpios = true;
+ if (atmel_spi_is_v2(as) &&
++ pdev->dev.of_node &&
+ !of_get_property(pdev->dev.of_node, "cs-gpios", NULL)) {
+ as->use_cs_gpios = false;
+ master->num_chipselect = 4;
--- /dev/null
+From febe562c20dfa8f33bee7d419c6b517986a5aa33 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Mon, 11 Jan 2016 21:31:09 -0800
+Subject: target: Fix LUN_RESET active I/O handling for ACK_KREF
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit febe562c20dfa8f33bee7d419c6b517986a5aa33 upstream.
+
+This patch fixes a NULL pointer se_cmd->cmd_kref < 0
+refcount bug during TMR LUN_RESET with active se_cmd
+I/O, that can be triggered during se_cmd descriptor
+shutdown + release via core_tmr_drain_state_list() code.
+
+To address this bug, add common __target_check_io_state()
+helper for ABORT_TASK + LUN_RESET w/ CMD_T_COMPLETE
+checking, and set CMD_T_ABORTED + obtain ->cmd_kref for
+both cases ahead of last target_put_sess_cmd() after
+TFO->aborted_task() -> transport_cmd_finish_abort()
+callback has completed.
+
+It also introduces SCF_ACK_KREF to determine when
+transport_cmd_finish_abort() needs to drop the second
+extra reference, ahead of calling target_put_sess_cmd()
+for the final kref_put(&se_cmd->cmd_kref).
+
+It also updates transport_cmd_check_stop() to avoid
+holding se_cmd->t_state_lock while dropping se_cmd
+device state via target_remove_from_state_list(), now
+that core_tmr_drain_state_list() is holding the
+se_device lock while checking se_cmd state from
+within TMR logic.
+
+Finally, move transport_put_cmd() release of SGL +
+TMR + extended CDB memory into target_free_cmd_mem()
+in order to avoid potential resource leaks in TMR
+ABORT_TASK + LUN_RESET code-paths. Also update
+target_release_cmd_kref() accordingly.
+
+Reviewed-by: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Sagi Grimberg <sagig@mellanox.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <mchristi@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_tmr.c | 69 ++++++++++++++++++++++-----------
+ drivers/target/target_core_transport.c | 67 +++++++++++++-------------------
+ include/target/target_core_base.h | 1
+ 3 files changed, 76 insertions(+), 61 deletions(-)
+
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -107,6 +107,34 @@ static int target_check_cdb_and_preempt(
+ return 1;
+ }
+
++static bool __target_check_io_state(struct se_cmd *se_cmd)
++{
++ struct se_session *sess = se_cmd->se_sess;
++
++ assert_spin_locked(&sess->sess_cmd_lock);
++ WARN_ON_ONCE(!irqs_disabled());
++ /*
++ * If command already reached CMD_T_COMPLETE state within
++ * target_complete_cmd(), this se_cmd has been passed to
++ * fabric driver and will not be aborted.
++ *
++ * Otherwise, obtain a local se_cmd->cmd_kref now for TMR
++ * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as
++ * long as se_cmd->cmd_kref is still active unless zero.
++ */
++ spin_lock(&se_cmd->t_state_lock);
++ if (se_cmd->transport_state & CMD_T_COMPLETE) {
++ pr_debug("Attempted to abort io tag: %llu already complete,"
++ " skipping\n", se_cmd->tag);
++ spin_unlock(&se_cmd->t_state_lock);
++ return false;
++ }
++ se_cmd->transport_state |= CMD_T_ABORTED;
++ spin_unlock(&se_cmd->t_state_lock);
++
++ return kref_get_unless_zero(&se_cmd->cmd_kref);
++}
++
+ void core_tmr_abort_task(
+ struct se_device *dev,
+ struct se_tmr_req *tmr,
+@@ -130,34 +158,22 @@ void core_tmr_abort_task(
+ if (tmr->ref_task_tag != ref_tag)
+ continue;
+
+- if (!kref_get_unless_zero(&se_cmd->cmd_kref))
+- continue;
+-
+ printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
+ se_cmd->se_tfo->get_fabric_name(), ref_tag);
+
+- spin_lock(&se_cmd->t_state_lock);
+- if (se_cmd->transport_state & CMD_T_COMPLETE) {
+- printk("ABORT_TASK: ref_tag: %llu already complete,"
+- " skipping\n", ref_tag);
+- spin_unlock(&se_cmd->t_state_lock);
++ if (!__target_check_io_state(se_cmd)) {
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+-
+ target_put_sess_cmd(se_cmd);
+-
+ goto out;
+ }
+- se_cmd->transport_state |= CMD_T_ABORTED;
+- spin_unlock(&se_cmd->t_state_lock);
+-
+ list_del_init(&se_cmd->se_cmd_list);
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
+ cancel_work_sync(&se_cmd->work);
+ transport_wait_for_tasks(se_cmd);
+
+- target_put_sess_cmd(se_cmd);
+ transport_cmd_finish_abort(se_cmd, true);
++ target_put_sess_cmd(se_cmd);
+
+ printk("ABORT_TASK: Sending TMR_FUNCTION_COMPLETE for"
+ " ref_tag: %llu\n", ref_tag);
+@@ -242,8 +258,10 @@ static void core_tmr_drain_state_list(
+ struct list_head *preempt_and_abort_list)
+ {
+ LIST_HEAD(drain_task_list);
++ struct se_session *sess;
+ struct se_cmd *cmd, *next;
+ unsigned long flags;
++ int rc;
+
+ /*
+ * Complete outstanding commands with TASK_ABORTED SAM status.
+@@ -282,6 +300,16 @@ static void core_tmr_drain_state_list(
+ if (prout_cmd == cmd)
+ continue;
+
++ sess = cmd->se_sess;
++ if (WARN_ON_ONCE(!sess))
++ continue;
++
++ spin_lock(&sess->sess_cmd_lock);
++ rc = __target_check_io_state(cmd);
++ spin_unlock(&sess->sess_cmd_lock);
++ if (!rc)
++ continue;
++
+ list_move_tail(&cmd->state_list, &drain_task_list);
+ cmd->state_active = false;
+ }
+@@ -289,7 +317,7 @@ static void core_tmr_drain_state_list(
+
+ while (!list_empty(&drain_task_list)) {
+ cmd = list_entry(drain_task_list.next, struct se_cmd, state_list);
+- list_del(&cmd->state_list);
++ list_del_init(&cmd->state_list);
+
+ pr_debug("LUN_RESET: %s cmd: %p"
+ " ITT/CmdSN: 0x%08llx/0x%08x, i_state: %d, t_state: %d"
+@@ -313,16 +341,11 @@ static void core_tmr_drain_state_list(
+ * loop above, but we do it down here given that
+ * cancel_work_sync may block.
+ */
+- if (cmd->t_state == TRANSPORT_COMPLETE)
+- cancel_work_sync(&cmd->work);
+-
+- spin_lock_irqsave(&cmd->t_state_lock, flags);
+- target_stop_cmd(cmd, &flags);
+-
+- cmd->transport_state |= CMD_T_ABORTED;
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ cancel_work_sync(&cmd->work);
++ transport_wait_for_tasks(cmd);
+
+ core_tmr_handle_tas_abort(tmr_nacl, cmd, tas);
++ target_put_sess_cmd(cmd);
+ }
+ }
+
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -528,9 +528,6 @@ void transport_deregister_session(struct
+ }
+ EXPORT_SYMBOL(transport_deregister_session);
+
+-/*
+- * Called with cmd->t_state_lock held.
+- */
+ static void target_remove_from_state_list(struct se_cmd *cmd)
+ {
+ struct se_device *dev = cmd->se_dev;
+@@ -555,10 +552,6 @@ static int transport_cmd_check_stop(stru
+ {
+ unsigned long flags;
+
+- spin_lock_irqsave(&cmd->t_state_lock, flags);
+- if (write_pending)
+- cmd->t_state = TRANSPORT_WRITE_PENDING;
+-
+ if (remove_from_lists) {
+ target_remove_from_state_list(cmd);
+
+@@ -568,6 +561,10 @@ static int transport_cmd_check_stop(stru
+ cmd->se_lun = NULL;
+ }
+
++ spin_lock_irqsave(&cmd->t_state_lock, flags);
++ if (write_pending)
++ cmd->t_state = TRANSPORT_WRITE_PENDING;
++
+ /*
+ * Determine if frontend context caller is requesting the stopping of
+ * this command for frontend exceptions.
+@@ -621,6 +618,8 @@ static void transport_lun_remove_cmd(str
+
+ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
+ {
++ bool ack_kref = (cmd->se_cmd_flags & SCF_ACK_KREF);
++
+ if (cmd->se_cmd_flags & SCF_SE_LUN_CMD)
+ transport_lun_remove_cmd(cmd);
+ /*
+@@ -632,7 +631,7 @@ void transport_cmd_finish_abort(struct s
+
+ if (transport_cmd_check_stop_to_fabric(cmd))
+ return;
+- if (remove)
++ if (remove && ack_kref)
+ transport_put_cmd(cmd);
+ }
+
+@@ -700,7 +699,7 @@ void target_complete_cmd(struct se_cmd *
+ * Check for case where an explicit ABORT_TASK has been received
+ * and transport_wait_for_tasks() will be waiting for completion..
+ */
+- if (cmd->transport_state & CMD_T_ABORTED &&
++ if (cmd->transport_state & CMD_T_ABORTED ||
+ cmd->transport_state & CMD_T_STOP) {
+ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+ complete_all(&cmd->t_transport_stop_comp);
+@@ -2213,20 +2212,14 @@ static inline void transport_free_pages(
+ }
+
+ /**
+- * transport_release_cmd - free a command
+- * @cmd: command to free
++ * transport_put_cmd - release a reference to a command
++ * @cmd: command to release
+ *
+- * This routine unconditionally frees a command, and reference counting
+- * or list removal must be done in the caller.
++ * This routine releases our reference to the command and frees it if possible.
+ */
+-static int transport_release_cmd(struct se_cmd *cmd)
++static int transport_put_cmd(struct se_cmd *cmd)
+ {
+ BUG_ON(!cmd->se_tfo);
+-
+- if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
+- core_tmr_release_req(cmd->se_tmr_req);
+- if (cmd->t_task_cdb != cmd->__t_task_cdb)
+- kfree(cmd->t_task_cdb);
+ /*
+ * If this cmd has been setup with target_get_sess_cmd(), drop
+ * the kref and call ->release_cmd() in kref callback.
+@@ -2234,18 +2227,6 @@ static int transport_release_cmd(struct
+ return target_put_sess_cmd(cmd);
+ }
+
+-/**
+- * transport_put_cmd - release a reference to a command
+- * @cmd: command to release
+- *
+- * This routine releases our reference to the command and frees it if possible.
+- */
+-static int transport_put_cmd(struct se_cmd *cmd)
+-{
+- transport_free_pages(cmd);
+- return transport_release_cmd(cmd);
+-}
+-
+ void *transport_kmap_data_sg(struct se_cmd *cmd)
+ {
+ struct scatterlist *sg = cmd->t_data_sg;
+@@ -2443,14 +2424,13 @@ static void transport_write_pending_qf(s
+
+ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+ {
+- unsigned long flags;
+ int ret = 0;
+
+ if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
+ if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
+- transport_wait_for_tasks(cmd);
++ transport_wait_for_tasks(cmd);
+
+- ret = transport_release_cmd(cmd);
++ ret = transport_put_cmd(cmd);
+ } else {
+ if (wait_for_tasks)
+ transport_wait_for_tasks(cmd);
+@@ -2459,11 +2439,8 @@ int transport_generic_free_cmd(struct se
+ * has already added se_cmd to state_list, but fabric has
+ * failed command before I/O submission.
+ */
+- if (cmd->state_active) {
+- spin_lock_irqsave(&cmd->t_state_lock, flags);
++ if (cmd->state_active)
+ target_remove_from_state_list(cmd);
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+- }
+
+ if (cmd->se_lun)
+ transport_lun_remove_cmd(cmd);
+@@ -2508,6 +2485,16 @@ out:
+ }
+ EXPORT_SYMBOL(target_get_sess_cmd);
+
++static void target_free_cmd_mem(struct se_cmd *cmd)
++{
++ transport_free_pages(cmd);
++
++ if (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)
++ core_tmr_release_req(cmd->se_tmr_req);
++ if (cmd->t_task_cdb != cmd->__t_task_cdb)
++ kfree(cmd->t_task_cdb);
++}
++
+ static void target_release_cmd_kref(struct kref *kref)
+ {
+ struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
+@@ -2517,17 +2504,20 @@ static void target_release_cmd_kref(stru
+ spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+ if (list_empty(&se_cmd->se_cmd_list)) {
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
++ target_free_cmd_mem(se_cmd);
+ se_cmd->se_tfo->release_cmd(se_cmd);
+ return;
+ }
+ if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
++ target_free_cmd_mem(se_cmd);
+ complete(&se_cmd->cmd_wait_comp);
+ return;
+ }
+ list_del(&se_cmd->se_cmd_list);
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
++ target_free_cmd_mem(se_cmd);
+ se_cmd->se_tfo->release_cmd(se_cmd);
+ }
+
+@@ -2539,6 +2529,7 @@ int target_put_sess_cmd(struct se_cmd *s
+ struct se_session *se_sess = se_cmd->se_sess;
+
+ if (!se_sess) {
++ target_free_cmd_mem(se_cmd);
+ se_cmd->se_tfo->release_cmd(se_cmd);
+ return 1;
+ }
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -138,6 +138,7 @@ enum se_cmd_flags_table {
+ SCF_COMPARE_AND_WRITE = 0x00080000,
+ SCF_COMPARE_AND_WRITE_POST = 0x00100000,
+ SCF_PASSTHROUGH_PROT_SG_TO_MEM_NOALLOC = 0x00200000,
++ SCF_ACK_KREF = 0x00400000,
+ };
+
+ /* struct se_dev_entry->lun_flags and struct se_lun->lun_access */
--- /dev/null
+From a6d9bb1c9605cd4f44e2d8290dc4d0e88f20292d Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Mon, 11 Jan 2016 21:53:05 -0800
+Subject: target: Fix LUN_RESET active TMR descriptor handling
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit a6d9bb1c9605cd4f44e2d8290dc4d0e88f20292d upstream.
+
+This patch fixes a NULL pointer se_cmd->cmd_kref < 0
+refcount bug during TMR LUN_RESET with active TMRs,
+triggered during se_cmd + se_tmr_req descriptor
+shutdown + release via core_tmr_drain_tmr_list().
+
+To address this bug, go ahead and obtain a local
+kref_get_unless_zero(&se_cmd->cmd_kref) for active I/O
+to set CMD_T_ABORTED, and transport_wait_for_tasks()
+followed by the final target_put_sess_cmd() to drop
+the local ->cmd_kref.
+
+Also add two new checks within target_tmr_work() to
+avoid CMD_T_ABORTED -> TFO->queue_tm_rsp() callbacks
+ahead of invoking the backend -> fabric put in
+transport_cmd_check_stop_to_fabric().
+
+For good measure, also change core_tmr_release_req()
+to use list_del_init() ahead of se_tmr_req memory
+free.
+
+Reviewed-by: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Sagi Grimberg <sagig@mellanox.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <mchristi@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_tmr.c | 22 +++++++++++++++++++++-
+ drivers/target/target_core_transport.c | 17 +++++++++++++++++
+ 2 files changed, 38 insertions(+), 1 deletion(-)
+
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -68,7 +68,7 @@ void core_tmr_release_req(struct se_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);
+ }
+
+@@ -194,9 +194,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..
+@@ -222,17 +224,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);
+@@ -246,7 +262,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);
+ }
+ }
+
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -2891,8 +2891,17 @@ static void target_tmr_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);
+@@ -2925,9 +2934,17 @@ static void target_tmr_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);
+ }
+
--- /dev/null
+From 310d3d314be7f0a84011ebdc4bdccbcae9755a87 Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Fri, 5 Feb 2016 14:51:36 -0800
+Subject: target: Fix race with SCF_SEND_DELAYED_TAS handling
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 310d3d314be7f0a84011ebdc4bdccbcae9755a87 upstream.
+
+This patch fixes a race between setting of SCF_SEND_DELAYED_TAS
+in transport_send_task_abort(), and check of the same bit in
+transport_check_aborted_status().
+
+It adds a __transport_check_aborted_status() version that is
+used by target_execute_cmd() when se_cmd->t_state_lock is
+held, and a transport_check_aborted_status() wrapper for
+all other existing callers.
+
+Also, it handles the case where the check happens before
+transport_send_task_abort() gets called. For this, go
+ahead and set SCF_SEND_DELAYED_TAS early when necessary,
+and have transport_send_task_abort() send the abort.
+
+Cc: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Sagi Grimberg <sagig@mellanox.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <mchristi@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_transport.c | 53 +++++++++++++++++++++++++--------
+ 1 file changed, 41 insertions(+), 12 deletions(-)
+
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -1849,19 +1849,21 @@ static bool target_handle_task_attr(stru
+ return true;
+ }
+
++static int __transport_check_aborted_status(struct se_cmd *, int);
++
+ void target_execute_cmd(struct se_cmd *cmd)
+ {
+ /*
+- * If the received CDB has aleady been aborted stop processing it here.
+- */
+- if (transport_check_aborted_status(cmd, 1))
+- return;
+-
+- /*
+ * Determine if frontend context caller is requesting the stopping of
+ * this command for frontend exceptions.
++ *
++ * If the received CDB has aleady been aborted stop processing it here.
+ */
+ spin_lock_irq(&cmd->t_state_lock);
++ if (__transport_check_aborted_status(cmd, 1)) {
++ spin_unlock_irq(&cmd->t_state_lock);
++ return;
++ }
+ if (cmd->transport_state & CMD_T_STOP) {
+ pr_debug("%s:%d CMD_T_STOP for ITT: 0x%08llx\n",
+ __func__, __LINE__, cmd->tag);
+@@ -2902,28 +2904,49 @@ transport_send_check_condition_and_sense
+ }
+ EXPORT_SYMBOL(transport_send_check_condition_and_sense);
+
+-int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
++static int __transport_check_aborted_status(struct se_cmd *cmd, int send_status)
++ __releases(&cmd->t_state_lock)
++ __acquires(&cmd->t_state_lock)
+ {
++ assert_spin_locked(&cmd->t_state_lock);
++ WARN_ON_ONCE(!irqs_disabled());
++
+ if (!(cmd->transport_state & CMD_T_ABORTED))
+ return 0;
+-
+ /*
+ * If cmd has been aborted but either no status is to be sent or it has
+ * already been sent, just return
+ */
+- if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS))
++ if (!send_status || !(cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS)) {
++ if (send_status)
++ cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS;
+ return 1;
++ }
+
+- pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB: 0x%02x ITT: 0x%08llx\n",
+- cmd->t_task_cdb[0], cmd->tag);
++ pr_debug("Sending delayed SAM_STAT_TASK_ABORTED status for CDB:"
++ " 0x%02x ITT: 0x%08llx\n", cmd->t_task_cdb[0], cmd->tag);
+
+ cmd->se_cmd_flags &= ~SCF_SEND_DELAYED_TAS;
+ cmd->scsi_status = SAM_STAT_TASK_ABORTED;
+ trace_target_cmd_complete(cmd);
++
++ spin_unlock_irq(&cmd->t_state_lock);
+ cmd->se_tfo->queue_status(cmd);
++ spin_lock_irq(&cmd->t_state_lock);
+
+ return 1;
+ }
++
++int transport_check_aborted_status(struct se_cmd *cmd, int send_status)
++{
++ int ret;
++
++ spin_lock_irq(&cmd->t_state_lock);
++ ret = __transport_check_aborted_status(cmd, send_status);
++ spin_unlock_irq(&cmd->t_state_lock);
++
++ return ret;
++}
+ EXPORT_SYMBOL(transport_check_aborted_status);
+
+ void transport_send_task_abort(struct se_cmd *cmd)
+@@ -2945,11 +2968,17 @@ void transport_send_task_abort(struct se
+ */
+ if (cmd->data_direction == DMA_TO_DEVICE) {
+ if (cmd->se_tfo->write_pending_status(cmd) != 0) {
+- cmd->transport_state |= CMD_T_ABORTED;
++ spin_lock_irqsave(&cmd->t_state_lock, flags);
++ if (cmd->se_cmd_flags & SCF_SEND_DELAYED_TAS) {
++ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ goto send_abort;
++ }
+ cmd->se_cmd_flags |= SCF_SEND_DELAYED_TAS;
++ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+ return;
+ }
+ }
++send_abort:
+ cmd->scsi_status = SAM_STAT_TASK_ABORTED;
+
+ transport_lun_remove_cmd(cmd);
--- /dev/null
+From 0f4a943168f31d29a1701908931acaba518b131a Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Tue, 19 Jan 2016 15:23:02 -0800
+Subject: target: Fix remote-port TMR ABORT + se_cmd fabric stop
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 0f4a943168f31d29a1701908931acaba518b131a upstream.
+
+To address the bug where fabric driver level shutdown
+of se_cmd occurs at the same time when TMR CMD_T_ABORTED
+is happening resulting in a -1 ->cmd_kref, this patch
+adds a CMD_T_FABRIC_STOP bit that is used to determine
+when TMR + driver I_T nexus shutdown is happening
+concurrently.
+
+It changes target_sess_cmd_list_set_waiting() to obtain
+se_cmd->cmd_kref + set CMD_T_FABRIC_STOP, and drop local
+reference in target_wait_for_sess_cmds() and invoke extra
+target_put_sess_cmd() during Task Aborted Status (TAS)
+when necessary.
+
+Also, it adds a new target_wait_free_cmd() wrapper around
+transport_wait_for_tasks() for the special case within
+transport_generic_free_cmd() to set CMD_T_FABRIC_STOP,
+and is now aware of CMD_T_ABORTED + CMD_T_TAS status
+bits to know when an extra transport_put_cmd() during
+TAS is required.
+
+Note transport_generic_free_cmd() is expected to block on
+cmd->cmd_wait_comp in order to follow what iscsi-target
+expects during iscsi_conn context se_cmd shutdown.
+
+Cc: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Sagi Grimberg <sagig@mellanox.com>
+Cc: Christoph Hellwig <hch@lst.de>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <mchristi@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@daterainc.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_tmr.c | 54 ++++++++----
+ drivers/target/target_core_transport.c | 145 +++++++++++++++++++++++++--------
+ include/target/target_core_base.h | 2
+ 3 files changed, 150 insertions(+), 51 deletions(-)
+
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -75,16 +75,18 @@ void core_tmr_release_req(struct se_tmr_
+ kfree(tmr);
+ }
+
+-static void core_tmr_handle_tas_abort(
+- struct se_session *tmr_sess,
+- struct se_cmd *cmd,
+- int tas)
++static void core_tmr_handle_tas_abort(struct se_cmd *cmd, int tas)
+ {
+- bool remove = true;
++ unsigned long flags;
++ bool remove = true, send_tas;
+ /*
+ * TASK ABORTED status (TAS) bit support
+ */
+- if (tmr_sess && tmr_sess != cmd->se_sess && tas) {
++ spin_lock_irqsave(&cmd->t_state_lock, flags);
++ send_tas = (cmd->transport_state & CMD_T_TAS);
++ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++
++ if (send_tas) {
+ remove = false;
+ transport_send_task_abort(cmd);
+ }
+@@ -107,7 +109,8 @@ static int target_check_cdb_and_preempt(
+ return 1;
+ }
+
+-static bool __target_check_io_state(struct se_cmd *se_cmd)
++static bool __target_check_io_state(struct se_cmd *se_cmd,
++ struct se_session *tmr_sess, int tas)
+ {
+ struct se_session *sess = se_cmd->se_sess;
+
+@@ -115,21 +118,32 @@ static bool __target_check_io_state(stru
+ WARN_ON_ONCE(!irqs_disabled());
+ /*
+ * If command already reached CMD_T_COMPLETE state within
+- * target_complete_cmd(), this se_cmd has been passed to
+- * fabric driver and will not be aborted.
++ * target_complete_cmd() or CMD_T_FABRIC_STOP due to shutdown,
++ * this se_cmd has been passed to fabric driver and will
++ * not be aborted.
+ *
+ * Otherwise, obtain a local se_cmd->cmd_kref now for TMR
+ * ABORT_TASK + LUN_RESET for CMD_T_ABORTED processing as
+ * long as se_cmd->cmd_kref is still active unless zero.
+ */
+ spin_lock(&se_cmd->t_state_lock);
+- if (se_cmd->transport_state & CMD_T_COMPLETE) {
+- pr_debug("Attempted to abort io tag: %llu already complete,"
++ if (se_cmd->transport_state & (CMD_T_COMPLETE | CMD_T_FABRIC_STOP)) {
++ pr_debug("Attempted to abort io tag: %llu already complete or"
++ " fabric stop, skipping\n", se_cmd->tag);
++ spin_unlock(&se_cmd->t_state_lock);
++ return false;
++ }
++ if (sess->sess_tearing_down || se_cmd->cmd_wait_set) {
++ pr_debug("Attempted to abort io tag: %llu already shutdown,"
+ " skipping\n", se_cmd->tag);
+ spin_unlock(&se_cmd->t_state_lock);
+ return false;
+ }
+ se_cmd->transport_state |= CMD_T_ABORTED;
++
++ if ((tmr_sess != se_cmd->se_sess) && tas)
++ se_cmd->transport_state |= CMD_T_TAS;
++
+ spin_unlock(&se_cmd->t_state_lock);
+
+ return kref_get_unless_zero(&se_cmd->cmd_kref);
+@@ -161,7 +175,7 @@ void core_tmr_abort_task(
+ printk("ABORT_TASK: Found referenced %s task_tag: %llu\n",
+ se_cmd->se_tfo->get_fabric_name(), ref_tag);
+
+- if (!__target_check_io_state(se_cmd)) {
++ if (!__target_check_io_state(se_cmd, se_sess, 0)) {
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ target_put_sess_cmd(se_cmd);
+ goto out;
+@@ -230,7 +244,8 @@ static void core_tmr_drain_tmr_list(
+
+ spin_lock(&sess->sess_cmd_lock);
+ spin_lock(&cmd->t_state_lock);
+- if (!(cmd->transport_state & CMD_T_ACTIVE)) {
++ if (!(cmd->transport_state & CMD_T_ACTIVE) ||
++ (cmd->transport_state & CMD_T_FABRIC_STOP)) {
+ spin_unlock(&cmd->t_state_lock);
+ spin_unlock(&sess->sess_cmd_lock);
+ continue;
+@@ -240,15 +255,22 @@ static void core_tmr_drain_tmr_list(
+ spin_unlock(&sess->sess_cmd_lock);
+ continue;
+ }
++ if (sess->sess_tearing_down || cmd->cmd_wait_set) {
++ 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");
++ spin_unlock(&sess->sess_cmd_lock);
+ continue;
+ }
++ spin_unlock(&sess->sess_cmd_lock);
++
+ list_move_tail(&tmr_p->tmr_list, &drain_tmr_list);
+ }
+ spin_unlock_irqrestore(&dev->se_tmr_lock, flags);
+@@ -325,7 +347,7 @@ static void core_tmr_drain_state_list(
+ continue;
+
+ spin_lock(&sess->sess_cmd_lock);
+- rc = __target_check_io_state(cmd);
++ rc = __target_check_io_state(cmd, tmr_sess, tas);
+ spin_unlock(&sess->sess_cmd_lock);
+ if (!rc)
+ continue;
+@@ -364,7 +386,7 @@ static void core_tmr_drain_state_list(
+ cancel_work_sync(&cmd->work);
+ transport_wait_for_tasks(cmd);
+
+- core_tmr_handle_tas_abort(tmr_sess, cmd, tas);
++ core_tmr_handle_tas_abort(cmd, tas);
+ target_put_sess_cmd(cmd);
+ }
+ }
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -2422,18 +2422,33 @@ static void transport_write_pending_qf(s
+ }
+ }
+
++static bool
++__transport_wait_for_tasks(struct se_cmd *, bool, bool *, bool *,
++ unsigned long *flags);
++
++static void target_wait_free_cmd(struct se_cmd *cmd, bool *aborted, bool *tas)
++{
++ unsigned long flags;
++
++ spin_lock_irqsave(&cmd->t_state_lock, flags);
++ __transport_wait_for_tasks(cmd, true, aborted, tas, &flags);
++ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++}
++
+ int transport_generic_free_cmd(struct se_cmd *cmd, int wait_for_tasks)
+ {
+ int ret = 0;
++ bool aborted = false, tas = false;
+
+ if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD)) {
+ if (wait_for_tasks && (cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
+- transport_wait_for_tasks(cmd);
++ target_wait_free_cmd(cmd, &aborted, &tas);
+
+- ret = transport_put_cmd(cmd);
++ if (!aborted || tas)
++ ret = transport_put_cmd(cmd);
+ } else {
+ if (wait_for_tasks)
+- transport_wait_for_tasks(cmd);
++ target_wait_free_cmd(cmd, &aborted, &tas);
+ /*
+ * Handle WRITE failure case where transport_generic_new_cmd()
+ * has already added se_cmd to state_list, but fabric has
+@@ -2445,7 +2460,20 @@ int transport_generic_free_cmd(struct se
+ if (cmd->se_lun)
+ transport_lun_remove_cmd(cmd);
+
+- ret = transport_put_cmd(cmd);
++ if (!aborted || tas)
++ ret = transport_put_cmd(cmd);
++ }
++ /*
++ * If the task has been internally aborted due to TMR ABORT_TASK
++ * or LUN_RESET, target_core_tmr.c is responsible for performing
++ * the remaining calls to target_put_sess_cmd(), and not the
++ * callers of this function.
++ */
++ if (aborted) {
++ pr_debug("Detected CMD_T_ABORTED for ITT: %llu\n", cmd->tag);
++ wait_for_completion(&cmd->cmd_wait_comp);
++ cmd->se_tfo->release_cmd(cmd);
++ ret = 1;
+ }
+ return ret;
+ }
+@@ -2500,6 +2528,7 @@ static void target_release_cmd_kref(stru
+ struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
+ struct se_session *se_sess = se_cmd->se_sess;
+ unsigned long flags;
++ bool fabric_stop;
+
+ spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+ if (list_empty(&se_cmd->se_cmd_list)) {
+@@ -2508,13 +2537,19 @@ static void target_release_cmd_kref(stru
+ se_cmd->se_tfo->release_cmd(se_cmd);
+ return;
+ }
+- if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
++
++ spin_lock(&se_cmd->t_state_lock);
++ fabric_stop = (se_cmd->transport_state & CMD_T_FABRIC_STOP);
++ spin_unlock(&se_cmd->t_state_lock);
++
++ if (se_cmd->cmd_wait_set || fabric_stop) {
++ list_del_init(&se_cmd->se_cmd_list);
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ target_free_cmd_mem(se_cmd);
+ complete(&se_cmd->cmd_wait_comp);
+ return;
+ }
+- list_del(&se_cmd->se_cmd_list);
++ list_del_init(&se_cmd->se_cmd_list);
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+
+ target_free_cmd_mem(se_cmd);
+@@ -2546,6 +2581,7 @@ void target_sess_cmd_list_set_waiting(st
+ {
+ struct se_cmd *se_cmd;
+ unsigned long flags;
++ int rc;
+
+ spin_lock_irqsave(&se_sess->sess_cmd_lock, flags);
+ if (se_sess->sess_tearing_down) {
+@@ -2555,8 +2591,15 @@ void target_sess_cmd_list_set_waiting(st
+ se_sess->sess_tearing_down = 1;
+ list_splice_init(&se_sess->sess_cmd_list, &se_sess->sess_wait_list);
+
+- list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list)
+- se_cmd->cmd_wait_set = 1;
++ list_for_each_entry(se_cmd, &se_sess->sess_wait_list, se_cmd_list) {
++ rc = kref_get_unless_zero(&se_cmd->cmd_kref);
++ if (rc) {
++ se_cmd->cmd_wait_set = 1;
++ spin_lock(&se_cmd->t_state_lock);
++ se_cmd->transport_state |= CMD_T_FABRIC_STOP;
++ spin_unlock(&se_cmd->t_state_lock);
++ }
++ }
+
+ spin_unlock_irqrestore(&se_sess->sess_cmd_lock, flags);
+ }
+@@ -2569,15 +2612,25 @@ void target_wait_for_sess_cmds(struct se
+ {
+ struct se_cmd *se_cmd, *tmp_cmd;
+ unsigned long flags;
++ bool tas;
+
+ list_for_each_entry_safe(se_cmd, tmp_cmd,
+ &se_sess->sess_wait_list, se_cmd_list) {
+- list_del(&se_cmd->se_cmd_list);
++ list_del_init(&se_cmd->se_cmd_list);
+
+ pr_debug("Waiting for se_cmd: %p t_state: %d, fabric state:"
+ " %d\n", se_cmd, se_cmd->t_state,
+ se_cmd->se_tfo->get_cmd_state(se_cmd));
+
++ spin_lock_irqsave(&se_cmd->t_state_lock, flags);
++ tas = (se_cmd->transport_state & CMD_T_TAS);
++ spin_unlock_irqrestore(&se_cmd->t_state_lock, flags);
++
++ if (!target_put_sess_cmd(se_cmd)) {
++ if (tas)
++ target_put_sess_cmd(se_cmd);
++ }
++
+ wait_for_completion(&se_cmd->cmd_wait_comp);
+ pr_debug("After cmd_wait_comp: se_cmd: %p t_state: %d"
+ " fabric state: %d\n", se_cmd, se_cmd->t_state,
+@@ -2599,53 +2652,75 @@ void transport_clear_lun_ref(struct se_l
+ wait_for_completion(&lun->lun_ref_comp);
+ }
+
+-/**
+- * transport_wait_for_tasks - wait for completion to occur
+- * @cmd: command to wait
+- *
+- * Called from frontend fabric context to wait for storage engine
+- * to pause and/or release frontend generated struct se_cmd.
+- */
+-bool transport_wait_for_tasks(struct se_cmd *cmd)
++static bool
++__transport_wait_for_tasks(struct se_cmd *cmd, bool fabric_stop,
++ bool *aborted, bool *tas, unsigned long *flags)
++ __releases(&cmd->t_state_lock)
++ __acquires(&cmd->t_state_lock)
+ {
+- unsigned long flags;
+
+- spin_lock_irqsave(&cmd->t_state_lock, flags);
++ assert_spin_locked(&cmd->t_state_lock);
++ WARN_ON_ONCE(!irqs_disabled());
++
++ if (fabric_stop)
++ cmd->transport_state |= CMD_T_FABRIC_STOP;
++
++ if (cmd->transport_state & CMD_T_ABORTED)
++ *aborted = true;
++
++ if (cmd->transport_state & CMD_T_TAS)
++ *tas = true;
++
+ if (!(cmd->se_cmd_flags & SCF_SE_LUN_CMD) &&
+- !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
+ return false;
+- }
+
+ if (!(cmd->se_cmd_flags & SCF_SUPPORTED_SAM_OPCODE) &&
+- !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB)) {
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ !(cmd->se_cmd_flags & SCF_SCSI_TMR_CDB))
+ return false;
+- }
+
+- if (!(cmd->transport_state & CMD_T_ACTIVE)) {
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ if (!(cmd->transport_state & CMD_T_ACTIVE))
++ return false;
++
++ if (fabric_stop && *aborted)
+ return false;
+- }
+
+ cmd->transport_state |= CMD_T_STOP;
+
+- pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08llx i_state: %d, t_state: %d, CMD_T_STOP\n",
+- cmd, cmd->tag, cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
++ pr_debug("wait_for_tasks: Stopping %p ITT: 0x%08llx i_state: %d,"
++ " t_state: %d, CMD_T_STOP\n", cmd, cmd->tag,
++ cmd->se_tfo->get_cmd_state(cmd), cmd->t_state);
+
+- spin_unlock_irqrestore(&cmd->t_state_lock, flags);
++ spin_unlock_irqrestore(&cmd->t_state_lock, *flags);
+
+ wait_for_completion(&cmd->t_transport_stop_comp);
+
+- spin_lock_irqsave(&cmd->t_state_lock, flags);
++ spin_lock_irqsave(&cmd->t_state_lock, *flags);
+ cmd->transport_state &= ~(CMD_T_ACTIVE | CMD_T_STOP);
+
+- pr_debug("wait_for_tasks: Stopped wait_for_completion(&cmd->t_transport_stop_comp) for ITT: 0x%08llx\n",
+- cmd->tag);
++ pr_debug("wait_for_tasks: Stopped wait_for_completion(&cmd->"
++ "t_transport_stop_comp) for ITT: 0x%08llx\n", cmd->tag);
++
++ return true;
++}
++
++/**
++ * transport_wait_for_tasks - wait for completion to occur
++ * @cmd: command to wait
++ *
++ * Called from frontend fabric context to wait for storage engine
++ * to pause and/or release frontend generated struct se_cmd.
++ */
++bool transport_wait_for_tasks(struct se_cmd *cmd)
++{
++ unsigned long flags;
++ bool ret, aborted = false, tas = false;
+
++ spin_lock_irqsave(&cmd->t_state_lock, flags);
++ ret = __transport_wait_for_tasks(cmd, false, &aborted, &tas, &flags);
+ spin_unlock_irqrestore(&cmd->t_state_lock, flags);
+
+- return true;
++ return ret;
+ }
+ EXPORT_SYMBOL(transport_wait_for_tasks);
+
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -491,6 +491,8 @@ struct se_cmd {
+ #define CMD_T_DEV_ACTIVE (1 << 7)
+ #define CMD_T_REQUEST_STOP (1 << 8)
+ #define CMD_T_BUSY (1 << 9)
++#define CMD_T_TAS (1 << 10)
++#define CMD_T_FABRIC_STOP (1 << 11)
+ spinlock_t t_state_lock;
+ struct kref cmd_kref;
+ struct completion t_transport_stop_comp;
--- /dev/null
+From ebde1ca5a908b10312db4ecd7553e3ba039319ab Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Sat, 16 Jan 2016 12:49:49 -0800
+Subject: target: Fix TAS handling for multi-session se_node_acls
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit ebde1ca5a908b10312db4ecd7553e3ba039319ab upstream.
+
+This patch fixes a bug in TMR task aborted status (TAS)
+handling when multiple sessions are connected to the
+same target WWPN endpoint and se_node_acl descriptor,
+resulting in TASK_ABORTED status to not be generated
+for aborted se_cmds on the remote port.
+
+This is due to core_tmr_handle_tas_abort() incorrectly
+comparing se_node_acl instead of se_session, for which
+the multi-session case is expected to be sharing the
+same se_node_acl.
+
+Instead, go ahead and update core_tmr_handle_tas_abort()
+to compare tmr_sess + cmd->se_sess in order to determine
+if the LUN_RESET was received on a different I_T nexus,
+and TASK_ABORTED status response needs to be generated.
+
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Cc: Quinn Tran <quinn.tran@qlogic.com>
+Cc: Himanshu Madhani <himanshu.madhani@qlogic.com>
+Cc: Sagi Grimberg <sagig@mellanox.com>
+Cc: Hannes Reinecke <hare@suse.de>
+Cc: Andy Grover <agrover@redhat.com>
+Cc: Mike Christie <mchristi@redhat.com>
+Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/target/target_core_tmr.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+--- a/drivers/target/target_core_tmr.c
++++ b/drivers/target/target_core_tmr.c
+@@ -76,7 +76,7 @@ void core_tmr_release_req(struct se_tmr_
+ }
+
+ static void core_tmr_handle_tas_abort(
+- struct se_node_acl *tmr_nacl,
++ struct se_session *tmr_sess,
+ struct se_cmd *cmd,
+ int tas)
+ {
+@@ -84,7 +84,7 @@ static void core_tmr_handle_tas_abort(
+ /*
+ * TASK ABORTED status (TAS) bit support
+ */
+- if ((tmr_nacl && (tmr_nacl != cmd->se_sess->se_node_acl)) && tas) {
++ if (tmr_sess && tmr_sess != cmd->se_sess && tas) {
+ remove = false;
+ transport_send_task_abort(cmd);
+ }
+@@ -273,7 +273,7 @@ static void core_tmr_drain_tmr_list(
+ static void core_tmr_drain_state_list(
+ struct se_device *dev,
+ struct se_cmd *prout_cmd,
+- struct se_node_acl *tmr_nacl,
++ struct se_session *tmr_sess,
+ int tas,
+ struct list_head *preempt_and_abort_list)
+ {
+@@ -364,7 +364,7 @@ static void core_tmr_drain_state_list(
+ cancel_work_sync(&cmd->work);
+ transport_wait_for_tasks(cmd);
+
+- core_tmr_handle_tas_abort(tmr_nacl, cmd, tas);
++ core_tmr_handle_tas_abort(tmr_sess, cmd, tas);
+ target_put_sess_cmd(cmd);
+ }
+ }
+@@ -377,6 +377,7 @@ int core_tmr_lun_reset(
+ {
+ struct se_node_acl *tmr_nacl = NULL;
+ struct se_portal_group *tmr_tpg = NULL;
++ struct se_session *tmr_sess = NULL;
+ int tas;
+ /*
+ * TASK_ABORTED status bit, this is configurable via ConfigFS
+@@ -395,8 +396,9 @@ int core_tmr_lun_reset(
+ * or struct se_device passthrough..
+ */
+ if (tmr && tmr->task_cmd && tmr->task_cmd->se_sess) {
+- tmr_nacl = tmr->task_cmd->se_sess->se_node_acl;
+- tmr_tpg = tmr->task_cmd->se_sess->se_tpg;
++ tmr_sess = tmr->task_cmd->se_sess;
++ tmr_nacl = tmr_sess->se_node_acl;
++ tmr_tpg = tmr_sess->se_tpg;
+ if (tmr_nacl && tmr_tpg) {
+ pr_debug("LUN_RESET: TMR caller fabric: %s"
+ " initiator port %s\n",
+@@ -409,7 +411,7 @@ int core_tmr_lun_reset(
+ dev->transport->name, tas);
+
+ core_tmr_drain_tmr_list(dev, tmr, preempt_and_abort_list);
+- core_tmr_drain_state_list(dev, prout_cmd, tmr_nacl, tas,
++ core_tmr_drain_state_list(dev, prout_cmd, tmr_sess, tas,
+ preempt_and_abort_list);
+
+ /*
--- /dev/null
+From 1ca8ec532fc2d986f1f4a319857bb18e0c9739b4 Mon Sep 17 00:00:00 2001
+From: Wanpeng Li <kernellwp@gmail.com>
+Date: Wed, 27 Jan 2016 19:26:07 +0800
+Subject: tick/nohz: Set the correct expiry when switching to nohz/lowres mode
+
+From: Wanpeng Li <kernellwp@gmail.com>
+
+commit 1ca8ec532fc2d986f1f4a319857bb18e0c9739b4 upstream.
+
+commit 0ff53d096422 sets the next tick interrupt to the last jiffies update,
+i.e. in the past, because the forward operation is invoked before the set
+operation. There is no resulting damage (yet), but we get an extra pointless
+tick interrupt.
+
+Revert the order so we get the next tick interrupt in the future.
+
+Fixes: commit 0ff53d096422 "tick: sched: Force tick interrupt and get rid of softirq magic"
+Signed-off-by: Wanpeng Li <wanpeng.li@hotmail.com>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Frederic Weisbecker <fweisbec@gmail.com>
+Link: http://lkml.kernel.org/r/1453893967-3458-1-git-send-email-wanpeng.li@hotmail.com
+Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/time/tick-sched.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/kernel/time/tick-sched.c
++++ b/kernel/time/tick-sched.c
+@@ -977,9 +977,9 @@ static void tick_nohz_switch_to_nohz(voi
+ /* Get the next period */
+ next = tick_init_jiffy_update();
+
+- hrtimer_forward_now(&ts->sched_timer, tick_period);
+ hrtimer_set_expires(&ts->sched_timer, next);
+- tick_program_event(next, 1);
++ hrtimer_forward_now(&ts->sched_timer, tick_period);
++ tick_program_event(hrtimer_get_expires(&ts->sched_timer), 1);
+ tick_nohz_activate(ts, NOHZ_MODE_LOWRES);
+ }
+
--- /dev/null
+From d6e022f1d207a161cd88e08ef0371554680ffc46 Mon Sep 17 00:00:00 2001
+From: Tejun Heo <tj@kernel.org>
+Date: Wed, 3 Feb 2016 13:54:25 -0500
+Subject: workqueue: handle NUMA_NO_NODE for unbound pool_workqueue lookup
+
+From: Tejun Heo <tj@kernel.org>
+
+commit d6e022f1d207a161cd88e08ef0371554680ffc46 upstream.
+
+When looking up the pool_workqueue to use for an unbound workqueue,
+workqueue assumes that the target CPU is always bound to a valid NUMA
+node. However, currently, when a CPU goes offline, the mapping is
+destroyed and cpu_to_node() returns NUMA_NO_NODE.
+
+This has always been broken but hasn't triggered often enough before
+874bbfe600a6 ("workqueue: make sure delayed work run in local cpu").
+After the commit, workqueue forcifully assigns the local CPU for
+delayed work items without explicit target CPU to fix a different
+issue. This widens the window where CPU can go offline while a
+delayed work item is pending causing delayed work items dispatched
+with target CPU set to an already offlined CPU. The resulting
+NUMA_NO_NODE mapping makes workqueue try to queue the work item on a
+NULL pool_workqueue and thus crash.
+
+While 874bbfe600a6 has been reverted for a different reason making the
+bug less visible again, it can still happen. Fix it by mapping
+NUMA_NO_NODE to the default pool_workqueue from unbound_pwq_by_node().
+This is a temporary workaround. The long term solution is keeping CPU
+-> NODE mapping stable across CPU off/online cycles which is being
+worked on.
+
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Reported-by: Mike Galbraith <umgwanakikbuti@gmail.com>
+Cc: Tang Chen <tangchen@cn.fujitsu.com>
+Cc: Rafael J. Wysocki <rafael@kernel.org>
+Cc: Len Brown <len.brown@intel.com>
+Link: http://lkml.kernel.org/g/1454424264.11183.46.camel@gmail.com
+Link: http://lkml.kernel.org/g/1453702100-2597-1-git-send-email-tangchen@cn.fujitsu.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -568,6 +568,16 @@ static struct pool_workqueue *unbound_pw
+ int node)
+ {
+ 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]);
+ }
+