--- /dev/null
+From 5259a06ef97068b710f45d092a587e8d740f750f Mon Sep 17 00:00:00 2001
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+Date: Tue, 28 Jan 2014 17:56:30 -0800
+Subject: target: Fix percpu_ref_put race in transport_lun_remove_cmd
+
+From: Nicholas Bellinger <nab@linux-iscsi.org>
+
+commit 5259a06ef97068b710f45d092a587e8d740f750f upstream.
+
+This patch fixes a percpu_ref_put race for se_lun->lun_ref in
+transport_lun_remove_cmd() where ->lun_ref could end up being
+put more than once per command via different target completion
+and fabric release contexts.
+
+It adds a cmpxchg() for se_cmd->lun_ref_active to ensure that
+percpu_ref_put() is only ever called once per se_cmd.
+
+This bug was manifesting itself as a LUN shutdown regression
+bug in >= v3.13 code, where percpu_ref_kill() would end up
+hanging indefinately due to the incorrect percpu_ref count.
+
+(Change se_cmd->lun_ref_active from bool -> int to force at
+ least a 4-byte cmpxchg with MIPS ll/sc ins. - Fengguang)
+
+Reported-by: Tommy Apel <tommyapeldk@gmail.com>
+Cc: Tommy Apel <tommyapeldk@gmail.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 | 5 +++--
+ include/target/target_core_base.h | 2 +-
+ 2 files changed, 4 insertions(+), 3 deletions(-)
+
+--- a/drivers/target/target_core_transport.c
++++ b/drivers/target/target_core_transport.c
+@@ -568,10 +568,11 @@ static void transport_lun_remove_cmd(str
+ {
+ struct se_lun *lun = cmd->se_lun;
+
+- if (!lun || !cmd->lun_ref_active)
++ if (!lun)
+ return;
+
+- percpu_ref_put(&lun->lun_ref);
++ if (cmpxchg(&cmd->lun_ref_active, true, false))
++ percpu_ref_put(&lun->lun_ref);
+ }
+
+ void transport_cmd_finish_abort(struct se_cmd *cmd, int remove)
+--- a/include/target/target_core_base.h
++++ b/include/target/target_core_base.h
+@@ -497,7 +497,7 @@ struct se_cmd {
+ void *priv;
+
+ /* Used for lun->lun_ref counting */
+- bool lun_ref_active;
++ int lun_ref_active;
+ };
+
+ struct se_ua {