aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/target
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2014-06-09 19:36:51 -0400
committerNicholas Bellinger <nab@linux-iscsi.org>2014-06-10 00:19:31 -0400
commita95d6511303b848da45ee27b35018bb58087bdc6 (patch)
treeeefd06649a284d2c84db54e423488ce55b1c59f2 /drivers/target
parentf15e9cd910c4d9da7de43f2181f362082fc45f0f (diff)
target: Use complete_all for se_cmd->t_transport_stop_comp
This patch fixes a bug where multiple waiters on ->t_transport_stop_comp occurs due to a concurrent ABORT_TASK and session reset both invoking transport_wait_for_tasks(), while waiting for the associated se_cmd descriptor backend processing to complete. For this case, complete_all() should be invoked in order to wake up both waiters in core_tmr_abort_task() + transport_generic_free_cmd() process contexts. Cc: Thomas Glanzmann <thomas@glanzmann.de> Cc: Charalampos Pournaris <charpour@gmail.com> Cc: stable@vger.kernel.org # 3.10+ Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r--drivers/target/target_core_transport.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c
index 195435bf1140..15dbf6e97289 100644
--- a/drivers/target/target_core_transport.c
+++ b/drivers/target/target_core_transport.c
@@ -562,7 +562,7 @@ static int transport_cmd_check_stop(struct se_cmd *cmd, bool remove_from_lists,
562 562
563 spin_unlock_irqrestore(&cmd->t_state_lock, flags); 563 spin_unlock_irqrestore(&cmd->t_state_lock, flags);
564 564
565 complete(&cmd->t_transport_stop_comp); 565 complete_all(&cmd->t_transport_stop_comp);
566 return 1; 566 return 1;
567 } 567 }
568 568
@@ -687,7 +687,7 @@ void target_complete_cmd(struct se_cmd *cmd, u8 scsi_status)
687 if (cmd->transport_state & CMD_T_ABORTED && 687 if (cmd->transport_state & CMD_T_ABORTED &&
688 cmd->transport_state & CMD_T_STOP) { 688 cmd->transport_state & CMD_T_STOP) {
689 spin_unlock_irqrestore(&cmd->t_state_lock, flags); 689 spin_unlock_irqrestore(&cmd->t_state_lock, flags);
690 complete(&cmd->t_transport_stop_comp); 690 complete_all(&cmd->t_transport_stop_comp);
691 return; 691 return;
692 } else if (!success) { 692 } else if (!success) {
693 INIT_WORK(&cmd->work, target_complete_failure_work); 693 INIT_WORK(&cmd->work, target_complete_failure_work);
@@ -1761,7 +1761,7 @@ void target_execute_cmd(struct se_cmd *cmd)
1761 cmd->se_tfo->get_task_tag(cmd)); 1761 cmd->se_tfo->get_task_tag(cmd));
1762 1762
1763 spin_unlock_irq(&cmd->t_state_lock); 1763 spin_unlock_irq(&cmd->t_state_lock);
1764 complete(&cmd->t_transport_stop_comp); 1764 complete_all(&cmd->t_transport_stop_comp);
1765 return; 1765 return;
1766 } 1766 }
1767 1767