diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-07-23 18:30:31 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2015-07-24 17:19:44 -0400 |
| commit | 007d038bdf95ccfe2491d0078be54040d110fd06 (patch) | |
| tree | a422ccc909a36f60ec4ff5dfbf976ae077c78e36 | |
| parent | e54198657b65625085834847ab6271087323ffea (diff) | |
iscsi-target: Fix iser explicit logout TX kthread leak
This patch fixes a regression introduced with the following commit
in v4.0-rc1 code, where an explicit iser-target logout would result
in ->tx_thread_active being incorrectly cleared by the logout post
handler, and subsequent TX kthread leak:
commit 88dcd2dab5c23b1c9cfc396246d8f476c872f0ca
Author: Nicholas Bellinger <nab@linux-iscsi.org>
Date: Thu Feb 26 22:19:15 2015 -0800
iscsi-target: Convert iscsi_thread_set usage to kthread.h
To address this bug, change iscsit_logout_post_handler_closesession()
and iscsit_logout_post_handler_samecid() to only cmpxchg() on
->tx_thread_active for traditional iscsi/tcp connections.
This is required because iscsi/tcp connections are invoking logout
post handler logic directly from TX kthread context, while iser
connections are invoking logout post handler logic from a seperate
workqueue context.
Cc: Sagi Grimberg <sagig@mellanox.com>
Cc: <stable@vger.kernel.org> # v3.10+
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 202a42858f25..cd77a064c772 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -4544,7 +4544,18 @@ static void iscsit_logout_post_handler_closesession( | |||
| 4544 | struct iscsi_conn *conn) | 4544 | struct iscsi_conn *conn) |
| 4545 | { | 4545 | { |
| 4546 | struct iscsi_session *sess = conn->sess; | 4546 | struct iscsi_session *sess = conn->sess; |
| 4547 | int sleep = cmpxchg(&conn->tx_thread_active, true, false); | 4547 | int sleep = 1; |
| 4548 | /* | ||
| 4549 | * Traditional iscsi/tcp will invoke this logic from TX thread | ||
| 4550 | * context during session logout, so clear tx_thread_active and | ||
| 4551 | * sleep if iscsit_close_connection() has not already occured. | ||
| 4552 | * | ||
| 4553 | * Since iser-target invokes this logic from it's own workqueue, | ||
| 4554 | * always sleep waiting for RX/TX thread shutdown to complete | ||
| 4555 | * within iscsit_close_connection(). | ||
| 4556 | */ | ||
| 4557 | if (conn->conn_transport->transport_type == ISCSI_TCP) | ||
| 4558 | sleep = cmpxchg(&conn->tx_thread_active, true, false); | ||
| 4548 | 4559 | ||
| 4549 | atomic_set(&conn->conn_logout_remove, 0); | 4560 | atomic_set(&conn->conn_logout_remove, 0); |
| 4550 | complete(&conn->conn_logout_comp); | 4561 | complete(&conn->conn_logout_comp); |
| @@ -4558,7 +4569,10 @@ static void iscsit_logout_post_handler_closesession( | |||
| 4558 | static void iscsit_logout_post_handler_samecid( | 4569 | static void iscsit_logout_post_handler_samecid( |
| 4559 | struct iscsi_conn *conn) | 4570 | struct iscsi_conn *conn) |
| 4560 | { | 4571 | { |
| 4561 | int sleep = cmpxchg(&conn->tx_thread_active, true, false); | 4572 | int sleep = 1; |
| 4573 | |||
| 4574 | if (conn->conn_transport->transport_type == ISCSI_TCP) | ||
| 4575 | sleep = cmpxchg(&conn->tx_thread_active, true, false); | ||
| 4562 | 4576 | ||
| 4563 | atomic_set(&conn->conn_logout_remove, 0); | 4577 | atomic_set(&conn->conn_logout_remove, 0); |
| 4564 | complete(&conn->conn_logout_comp); | 4578 | complete(&conn->conn_logout_comp); |
