The race condition can be observed with the following sequence of events: - For every active sessions, issue an ISCSI_ERR_CONN_FAILED nl msg (This will eventually put all active connections into the actor_list ready to execute the session_conn_reopen procedure) - Asynchronously after a few seconds, call the iscsi_host_remove procedure (This will notify iscsid with the ISCSI_ERR_INVALID_HOST nl message)
The current code actually handles this by advancing the INVALID_HOST session_conn_error actor scheduing to the head via the actor_schedule_head procedure. However, if the current actor thread was call-backed from the actor_poll loop, then this head scheduling will actually put the INVALID_HOST actor onto the poll_list instead of the actor_list. If there are subsequent elements in the actor_list which triggers the reopen path, then the conn_context for the INVALID_HOST for that particular connection will get flushed (+ actor_delete). This will then lockup the libiscsi's iscsi_host_remove call as it will wait indefinitely on all sessions to be removed. The fix is to put this head scheduling to the head of the actor_list regardless of poll mode or not. This will allow all INVALID_PATH actors to have a chance to get executed before any subsequent reopen actors. Signed-off-by: Eddie Wai <eddie....@broadcom.com> --- usr/actor.c | 13 ++++++------- 1 files changed, 6 insertions(+), 7 deletions(-) diff --git a/usr/actor.c b/usr/actor.c index e88d197..45f3a51 100644 --- a/usr/actor.c +++ b/usr/actor.c @@ -112,14 +112,13 @@ actor_schedule_private(actor_t *thread, uint32_t ttschedule, int head) * state to scheduled, else add current time to ttschedule and * insert in the queue at the correct point */ if (delay_time == 0) { - if (poll_in_progress) { + /* For head addition, it must go onto the head of the + actor_list regardless if poll is in progress or not + */ + if (poll_in_progress && !head) { thread->state = ACTOR_POLL_WAITING; - if (head) - list_add(&thread->list, - &poll_list); - else - list_add_tail(&thread->list, - &poll_list); + list_add_tail(&thread->list, + &poll_list); } else { thread->state = ACTOR_SCHEDULED; if (head) -- 1.7.0.5 -- You received this message because you are subscribed to the Google Groups "open-iscsi" group. To post to this group, send email to open-is...@googlegroups.com. To unsubscribe from this group, send email to open-iscsi+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/open-iscsi?hl=en.