From d421876f98ca23e476ebcd2f91102e2183fd5622 Mon Sep 17 00:00:00 2001 From: Shuhei Matsumoto Date: Sun, 19 Apr 2020 10:16:58 +0900 Subject: [PATCH] lib/iscsi: Fix conn->state not go back to EXITING by using spdk_thread_send_msg Updating conn->state had not been guarded by any mutex. When SPDK iSCSI target has multiple SPDK threads, iscsi_drop_conns() may update conn->state by a thread different from the thread of conn->pg. This patch ensures conn->state is updated by the thread of conn->pg by sending a message to the thread. This fix is not perfect but connection reschedule is done only once per connection when moving to the full feature phase. So this fix will be simple and enough for now. Signed-off-by: Shuhei Matsumoto Change-Id: I500474a27659438473b0eea598d35c90624a1d10 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1930 Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins Reviewed-by: Changpeng Liu Reviewed-by: Jim Harris Reviewed-by: Paul Luse Reviewed-by: Ben Walker Reviewed-by: Ziye Yang --- lib/iscsi/conn.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/lib/iscsi/conn.c b/lib/iscsi/conn.c index 808c8b556..5c77a5cd9 100644 --- a/lib/iscsi/conn.c +++ b/lib/iscsi/conn.c @@ -895,13 +895,27 @@ shutdown_iscsi_conns(void) g_shutdown_timer = SPDK_POLLER_REGISTER(iscsi_conn_check_shutdown, NULL, 1000); } +/* Do not set conn->state if the connection has already started exiting. + * This ensures we do not move a connection from EXITED state back to EXITING. + */ +static void +_iscsi_conn_drop(void *ctx) +{ + struct spdk_iscsi_conn *conn = ctx; + + if (conn->state < ISCSI_CONN_STATE_EXITING) { + conn->state = ISCSI_CONN_STATE_EXITING; + } +} + int iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match, int drop_all) { struct spdk_iscsi_conn *xconn; - const char *xconn_match; - int i, num; + const char *xconn_match; + struct spdk_thread *thread; + int i, num; SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "iscsi_drop_conns\n"); @@ -947,12 +961,9 @@ iscsi_drop_conns(struct spdk_iscsi_conn *conn, const char *conn_match, SPDK_DEBUGLOG(SPDK_LOG_ISCSI, "CID=%u\n", xconn->cid); - /* Do not set xconn->state if the connection has already started exiting. - * This ensures we do not move a connection from EXITED state back to EXITING. - */ - if (xconn->state < ISCSI_CONN_STATE_EXITING) { - xconn->state = ISCSI_CONN_STATE_EXITING; - } + thread = spdk_io_channel_get_thread(spdk_io_channel_from_ctx(conn->pg)); + spdk_thread_send_msg(thread, _iscsi_conn_drop, conn); + num++; } }