diff options
author | Roland Dreier <roland@purestorage.com> | 2012-10-31 09:16:46 -0700 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2012-11-01 00:38:44 -0700 |
commit | d5627acba9ae584cf4928af19f7ddf5f6837de32 (patch) | |
tree | 4247438e4a6ab7ef76c68a6d35093db95eca1451 /drivers/target/iscsi/iscsi_target_core.h | |
parent | 3e03989b5868acf69a391a424dc71fcd6cc48167 (diff) | |
download | op-kernel-dev-d5627acba9ae584cf4928af19f7ddf5f6837de32.zip op-kernel-dev-d5627acba9ae584cf4928af19f7ddf5f6837de32.tar.gz |
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_core.h')
-rw-r--r-- | drivers/target/iscsi/iscsi_target_core.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/drivers/target/iscsi/iscsi_target_core.h b/drivers/target/iscsi/iscsi_target_core.h index 2ba9f9b..21048db 100644 --- a/drivers/target/iscsi/iscsi_target_core.h +++ b/drivers/target/iscsi/iscsi_target_core.h @@ -486,6 +486,7 @@ struct iscsi_tmr_req { }; struct iscsi_conn { + wait_queue_head_t queues_wq; /* Authentication Successful for this connection */ u8 auth_complete; /* State connection is currently in */ |