summaryrefslogtreecommitdiffstats
path: root/drivers/target/iscsi/iscsi_target_util.h
diff options
context:
space:
mode:
authorRoland Dreier <roland@purestorage.com>2012-10-31 09:16:46 -0700
committerNicholas Bellinger <nab@linux-iscsi.org>2012-11-01 00:38:44 -0700
commitd5627acba9ae584cf4928af19f7ddf5f6837de32 (patch)
tree4247438e4a6ab7ef76c68a6d35093db95eca1451 /drivers/target/iscsi/iscsi_target_util.h
parent3e03989b5868acf69a391a424dc71fcd6cc48167 (diff)
iscsi-target: Fix missed wakeup race in TX thread
The sleeping code in iscsi_target_tx_thread() is susceptible to the classic missed wakeup race: - TX thread finishes handle_immediate_queue() and handle_response_queue(), thinks both queues are empty. - Another thread adds a queue entry and does wake_up_process(), which does nothing because the TX thread is still awake. - TX thread does schedule_timeout() and sleeps forever. In practice this can kill an iSCSI connection if for example an initiator does single-threaded writes and the target misses the wakeup window when queueing an R2T; in this case the connection will be stuck until the initiator loses patience and does some task management operation (or kills the connection entirely). Fix this by converting to wait_event_interruptible(), which does not suffer from this sort of race. Signed-off-by: Roland Dreier <roland@purestorage.com> Cc: Andy Grover <agrover@redhat.com> Cc: Hannes Reinecke <hare@suse.de> Cc: Christoph Hellwig <hch@lst.de> Cc: stable@vger.kernel.org Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target/iscsi/iscsi_target_util.h')
-rw-r--r--drivers/target/iscsi/iscsi_target_util.h1
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/target/iscsi/iscsi_target_util.h b/drivers/target/iscsi/iscsi_target_util.h
index 44054bd3543..894d0f83792 100644
--- a/drivers/target/iscsi/iscsi_target_util.h
+++ b/drivers/target/iscsi/iscsi_target_util.h
@@ -25,6 +25,7 @@ extern struct iscsi_queue_req *iscsit_get_cmd_from_immediate_queue(struct iscsi_
extern void iscsit_add_cmd_to_response_queue(struct iscsi_cmd *, struct iscsi_conn *, u8);
extern struct iscsi_queue_req *iscsit_get_cmd_from_response_queue(struct iscsi_conn *);
extern void iscsit_remove_cmd_from_tx_queues(struct iscsi_cmd *, struct iscsi_conn *);
+extern bool iscsit_conn_all_queues_empty(struct iscsi_conn *);
extern void iscsit_free_queue_reqs_for_conn(struct iscsi_conn *);
extern void iscsit_release_cmd(struct iscsi_cmd *);
extern void iscsit_free_cmd(struct iscsi_cmd *);