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 <shuhei.matsumoto.xt@hitachi.com>
Change-Id: I500474a27659438473b0eea598d35c90624a1d10
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1930
Community-CI: Mellanox Build Bot
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Paul Luse <paul.e.luse@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Ziye Yang <ziye.yang@intel.com>
This commit is contained in:
Shuhei Matsumoto 2020-04-19 10:16:58 +09:00 committed by Tomasz Zawadzki
parent 8109f45e1d
commit d421876f98

View File

@ -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++;
}
}