[PATCH 02/21] target: Do not hold session command lock around command destructor

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch fixes the following kernel warning because it avoids that
IRQs are disabled while ft_release_cmd() is invoked (fc_seq_set_resp()
invokes spin_unlock_bh()):

WARNING: CPU: 3 PID: 117 at kernel/softirq.c:150 __local_bh_enable_ip+0xaa/0x110()
Call Trace:
 [<ffffffff814f71eb>] dump_stack+0x4f/0x7b
 [<ffffffff8105e56a>] warn_slowpath_common+0x8a/0xc0
 [<ffffffff8105e65a>] warn_slowpath_null+0x1a/0x20
 [<ffffffff81062b2a>] __local_bh_enable_ip+0xaa/0x110
 [<ffffffff814ff229>] _raw_spin_unlock_bh+0x39/0x40
 [<ffffffffa03a7f94>] fc_seq_set_resp+0xe4/0x100 [libfc]
 [<ffffffffa02e604a>] ft_free_cmd+0x4a/0x90 [tcm_fc]
 [<ffffffffa02e6972>] ft_release_cmd+0x12/0x20 [tcm_fc]
 [<ffffffffa042bd66>] target_release_cmd_kref+0x56/0x90 [target_core_mod]
 [<ffffffffa042caf0>] target_put_sess_cmd+0xc0/0x110 [target_core_mod]
 [<ffffffffa042cb81>] transport_release_cmd+0x41/0x70 [target_core_mod]
 [<ffffffffa042d975>] transport_generic_free_cmd+0x35/0x420 [target_core_mod]

Signed-off-by: Bart Van Assche <bart.vanassche@xxxxxxxxxxx>
---
 drivers/target/target_core_transport.c | 17 ++++++++++-------
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 1f4496f..fc8593e 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -2507,21 +2507,20 @@ out:
 EXPORT_SYMBOL(target_get_sess_cmd);
 
 static void target_release_cmd_kref(struct kref *kref)
-		__releases(&se_cmd->se_sess->sess_cmd_lock)
 {
 	struct se_cmd *se_cmd = container_of(kref, struct se_cmd, cmd_kref);
 	struct se_session *se_sess = se_cmd->se_sess;
 
 	if (list_empty(&se_cmd->se_cmd_list)) {
-		spin_unlock(&se_sess->sess_cmd_lock);
 		se_cmd->se_tfo->release_cmd(se_cmd);
 		return;
 	}
 	if (se_sess->sess_tearing_down && se_cmd->cmd_wait_set) {
-		spin_unlock(&se_sess->sess_cmd_lock);
 		complete(&se_cmd->cmd_wait_comp);
 		return;
 	}
+
+	spin_lock(&se_sess->sess_cmd_lock);
 	list_del(&se_cmd->se_cmd_list);
 	spin_unlock(&se_sess->sess_cmd_lock);
 
@@ -2534,13 +2533,17 @@ static void target_release_cmd_kref(struct kref *kref)
 int target_put_sess_cmd(struct se_cmd *se_cmd)
 {
 	struct se_session *se_sess = se_cmd->se_sess;
+	int ret;
 
-	if (!se_sess) {
+	if (se_sess) {
+		target_get_session(se_sess);
+		ret = kref_put(&se_cmd->cmd_kref, target_release_cmd_kref);
+		target_put_session(se_sess);
+	} else {
 		se_cmd->se_tfo->release_cmd(se_cmd);
-		return 1;
+		ret = 1;
 	}
-	return kref_put_spinlock_irqsave(&se_cmd->cmd_kref, target_release_cmd_kref,
-			&se_sess->sess_cmd_lock);
+	return ret;
 }
 EXPORT_SYMBOL(target_put_sess_cmd);
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux