iscsi: start all sessions for a target node on the same lcore
This ensures against races, when an existing session to a target node stalls, causing the initiator to create a new session. These new session's connection may get migrated to a different core than the core of the stalled session. In practice, this does not happen, but is a common occurrence when debugging the iSCSI target using gdb. Signed-off-by: Jim Harris <james.r.harris@intel.com> Change-Id: I1864c2ca0c330dc4faeeb1312adac7a02c8281dc
This commit is contained in:
parent
2029c9faf9
commit
f167fac386
@ -92,7 +92,7 @@ void spdk_iscsi_conn_idle_do_work(void *arg);
|
|||||||
|
|
||||||
static void spdk_iscsi_conn_full_feature_migrate(struct spdk_event *event);
|
static void spdk_iscsi_conn_full_feature_migrate(struct spdk_event *event);
|
||||||
static struct spdk_event *spdk_iscsi_conn_get_migrate_event(struct spdk_iscsi_conn *conn,
|
static struct spdk_event *spdk_iscsi_conn_get_migrate_event(struct spdk_iscsi_conn *conn,
|
||||||
int lcore);
|
int *lcore);
|
||||||
static void spdk_iscsi_conn_stop_poller(struct spdk_iscsi_conn *conn, spdk_event_fn fn_after_stop,
|
static void spdk_iscsi_conn_stop_poller(struct spdk_iscsi_conn *conn, spdk_event_fn fn_after_stop,
|
||||||
int lcore);
|
int lcore);
|
||||||
|
|
||||||
@ -630,9 +630,38 @@ spdk_iscsi_conn_check_shutdown(struct rte_timer *timer, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct spdk_event *
|
static struct spdk_event *
|
||||||
spdk_iscsi_conn_get_migrate_event(struct spdk_iscsi_conn *conn, int lcore)
|
spdk_iscsi_conn_get_migrate_event(struct spdk_iscsi_conn *conn, int *_lcore)
|
||||||
{
|
{
|
||||||
struct spdk_event *event;
|
struct spdk_event *event;
|
||||||
|
struct spdk_iscsi_tgt_node *target;
|
||||||
|
int lcore;
|
||||||
|
|
||||||
|
lcore = spdk_iscsi_conn_allocate_reactor(conn->portal->cpumask);
|
||||||
|
if (conn->sess->session_type == SESSION_TYPE_NORMAL) {
|
||||||
|
target = conn->sess->target;
|
||||||
|
pthread_mutex_lock(&target->mutex);
|
||||||
|
target->num_active_conns++;
|
||||||
|
if (target->num_active_conns == 1) {
|
||||||
|
/**
|
||||||
|
* This is the only active connection for this target node.
|
||||||
|
* Save the lcore in the target node so it can be used for
|
||||||
|
* any other connections to this target node.
|
||||||
|
*/
|
||||||
|
target->lcore = lcore;
|
||||||
|
} else {
|
||||||
|
/**
|
||||||
|
* There are other active connections for this target node.
|
||||||
|
* Ignore the lcore specified by the allocator and use the
|
||||||
|
* the target node's lcore to ensure this connection runs on
|
||||||
|
* the same lcore as other connections for this target node.
|
||||||
|
*/
|
||||||
|
lcore = target->lcore;
|
||||||
|
}
|
||||||
|
pthread_mutex_unlock(&target->mutex);
|
||||||
|
}
|
||||||
|
if (_lcore != NULL) {
|
||||||
|
*_lcore = lcore;
|
||||||
|
}
|
||||||
|
|
||||||
event = spdk_event_allocate(lcore, spdk_iscsi_conn_full_feature_migrate, conn, NULL, NULL);
|
event = spdk_event_allocate(lcore, spdk_iscsi_conn_full_feature_migrate, conn, NULL, NULL);
|
||||||
|
|
||||||
@ -647,7 +676,14 @@ static void
|
|||||||
spdk_iscsi_conn_stop_poller(struct spdk_iscsi_conn *conn, spdk_event_fn fn_after_stop, int lcore)
|
spdk_iscsi_conn_stop_poller(struct spdk_iscsi_conn *conn, spdk_event_fn fn_after_stop, int lcore)
|
||||||
{
|
{
|
||||||
struct spdk_event *event;
|
struct spdk_event *event;
|
||||||
|
struct spdk_iscsi_tgt_node *target;
|
||||||
|
|
||||||
|
if (conn->sess->session_type == SESSION_TYPE_NORMAL) {
|
||||||
|
target = conn->sess->target;
|
||||||
|
pthread_mutex_lock(&target->mutex);
|
||||||
|
target->num_active_conns--;
|
||||||
|
pthread_mutex_unlock(&target->mutex);
|
||||||
|
}
|
||||||
rte_atomic32_dec(&g_num_connections[spdk_app_get_current_core()]);
|
rte_atomic32_dec(&g_num_connections[spdk_app_get_current_core()]);
|
||||||
spdk_net_framework_clear_socket_association(conn->sock);
|
spdk_net_framework_clear_socket_association(conn->sock);
|
||||||
event = spdk_event_allocate(lcore, fn_after_stop, conn, NULL, NULL);
|
event = spdk_event_allocate(lcore, fn_after_stop, conn, NULL, NULL);
|
||||||
@ -664,7 +700,7 @@ void spdk_shutdown_iscsi_conns(void)
|
|||||||
*/
|
*/
|
||||||
STAILQ_FOREACH_SAFE(conn, &g_idle_conn_list_head, link, tmp) {
|
STAILQ_FOREACH_SAFE(conn, &g_idle_conn_list_head, link, tmp) {
|
||||||
STAILQ_REMOVE(&g_idle_conn_list_head, conn, spdk_iscsi_conn, link);
|
STAILQ_REMOVE(&g_idle_conn_list_head, conn, spdk_iscsi_conn, link);
|
||||||
spdk_event_call(spdk_iscsi_conn_get_migrate_event(conn, rte_get_master_lcore()));
|
spdk_event_call(spdk_iscsi_conn_get_migrate_event(conn, NULL));
|
||||||
conn->is_idle = 0;
|
conn->is_idle = 0;
|
||||||
del_idle_conn(conn);
|
del_idle_conn(conn);
|
||||||
}
|
}
|
||||||
@ -1255,8 +1291,7 @@ spdk_iscsi_conn_login_do_work(void *arg)
|
|||||||
* did, migrate it to a dedicated reactor for the target node.
|
* did, migrate it to a dedicated reactor for the target node.
|
||||||
*/
|
*/
|
||||||
if (conn->login_phase == ISCSI_FULL_FEATURE_PHASE) {
|
if (conn->login_phase == ISCSI_FULL_FEATURE_PHASE) {
|
||||||
lcore = spdk_iscsi_conn_allocate_reactor(conn->portal->cpumask);
|
event = spdk_iscsi_conn_get_migrate_event(conn, &lcore);
|
||||||
event = spdk_iscsi_conn_get_migrate_event(conn, lcore);
|
|
||||||
rte_atomic32_dec(&g_num_connections[spdk_app_get_current_core()]);
|
rte_atomic32_dec(&g_num_connections[spdk_app_get_current_core()]);
|
||||||
rte_atomic32_inc(&g_num_connections[lcore]);
|
rte_atomic32_inc(&g_num_connections[lcore]);
|
||||||
spdk_net_framework_clear_socket_association(conn->sock);
|
spdk_net_framework_clear_socket_association(conn->sock);
|
||||||
@ -1321,7 +1356,7 @@ void spdk_iscsi_conn_idle_do_work(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tconn->pending_activate_event) {
|
if (tconn->pending_activate_event) {
|
||||||
uint32_t lcore;
|
int lcore;
|
||||||
|
|
||||||
spdk_trace_record(TRACE_ISCSI_CONN_ACTIVE, tconn->id, 0, 0, 0);
|
spdk_trace_record(TRACE_ISCSI_CONN_ACTIVE, tconn->id, 0, 0, 0);
|
||||||
|
|
||||||
@ -1332,10 +1367,9 @@ void spdk_iscsi_conn_idle_do_work(void *arg)
|
|||||||
tconn->is_idle = 0;
|
tconn->is_idle = 0;
|
||||||
del_idle_conn(tconn);
|
del_idle_conn(tconn);
|
||||||
/* migrate work item to new core */
|
/* migrate work item to new core */
|
||||||
lcore = spdk_iscsi_conn_allocate_reactor(tconn->portal->cpumask);
|
|
||||||
rte_atomic32_inc(&g_num_connections[lcore]);
|
|
||||||
spdk_net_framework_clear_socket_association(tconn->sock);
|
spdk_net_framework_clear_socket_association(tconn->sock);
|
||||||
spdk_event_call(spdk_iscsi_conn_get_migrate_event(tconn, lcore));
|
spdk_event_call(spdk_iscsi_conn_get_migrate_event(tconn, &lcore));
|
||||||
|
rte_atomic32_inc(&g_num_connections[lcore]);
|
||||||
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "add conn id = %d, cid = %d poller = %p to lcore = %d active\n",
|
SPDK_TRACELOG(SPDK_TRACE_DEBUG, "add conn id = %d, cid = %d poller = %p to lcore = %d active\n",
|
||||||
tconn->id, tconn->cid, &tconn->poller, lcore);
|
tconn->id, tconn->cid, &tconn->poller, lcore);
|
||||||
}
|
}
|
||||||
@ -1355,7 +1389,7 @@ __add_idle_conn(spdk_event_t e)
|
|||||||
* process.
|
* process.
|
||||||
*/
|
*/
|
||||||
if (conn->state == ISCSI_CONN_STATE_EXITING) {
|
if (conn->state == ISCSI_CONN_STATE_EXITING) {
|
||||||
spdk_event_call(spdk_iscsi_conn_get_migrate_event(conn, rte_get_master_lcore()));
|
spdk_event_call(spdk_iscsi_conn_get_migrate_event(conn, NULL));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +67,12 @@ struct spdk_iscsi_tgt_node {
|
|||||||
int queue_depth;
|
int queue_depth;
|
||||||
|
|
||||||
struct spdk_scsi_dev *dev;
|
struct spdk_scsi_dev *dev;
|
||||||
|
/**
|
||||||
|
* Counts number of active iSCSI connections associated with this
|
||||||
|
* target node.
|
||||||
|
*/
|
||||||
|
uint32_t num_active_conns;
|
||||||
|
int lcore;
|
||||||
|
|
||||||
int maxmap;
|
int maxmap;
|
||||||
struct spdk_iscsi_tgt_node_map map[MAX_TARGET_MAP];
|
struct spdk_iscsi_tgt_node_map map[MAX_TARGET_MAP];
|
||||||
|
Loading…
Reference in New Issue
Block a user