Commit 04d15190 authored by Xin Zhao's avatar Xin Zhao
Browse files

Bug-fix: modify free_ops_before_completion function

Originally free_ops_before_completion functions only
works with active target. Here we modify it to accomodate
passive target as well.

Also, everytime we trigger free_ops_before_completion,
we lose the chance to do real Win_flush_local operation
and must do a Win_flush instead. Here we transfer
Win_flush_local to Win_flush if disable_flush_local flag
is set, and unset that flag after the current flush
is fone.

No reviewer.
parent 097c9628
......@@ -466,30 +466,47 @@ int MPIDI_CH3I_RMA_Free_ops_before_completion(MPID_Win * win_ptr)
int i, made_progress = 0;
int mpi_errno = MPI_SUCCESS;
/* If we are in an free_ops_before_completion, the window must be holding
* up resources. If it isn't, we are in the wrong window and
* incorrectly entered this function. */
MPIU_ERR_CHKANDJUMP(win_ptr->non_empty_slots == 0, mpi_errno, MPI_ERR_OTHER,
"**rmanoop");
/* make nonblocking progress once */
mpi_errno = MPIDI_CH3I_RMA_Make_progress_win(win_ptr, &made_progress);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
if (win_ptr->states.access_state == MPIDI_RMA_FENCE_ISSUED ||
win_ptr->states.access_state == MPIDI_RMA_PSCW_ISSUED) {
mpi_errno = issue_ops_win(win_ptr, &made_progress);
if (mpi_errno != MPI_SUCCESS) {MPIU_ERR_POP(mpi_errno);}
}
if (win_ptr->states.access_state != MPIDI_RMA_FENCE_GRANTED)
win_ptr->states.access_state == MPIDI_RMA_PSCW_ISSUED ||
win_ptr->states.access_state == MPIDI_RMA_LOCK_ALL_ISSUED)
goto fn_exit;
/* find targets that have operations */
for (i = 0; i < win_ptr->num_slots; i++) {
if (win_ptr->slots[i].target_list != NULL) {
curr_target = win_ptr->slots[i].target_list;
while (curr_target != NULL && curr_target->read_op_list == NULL
&& curr_target->write_op_list == NULL)
while (curr_target != NULL) {
if (curr_target->read_op_list != NULL ||
curr_target->write_op_list != NULL) {
if (win_ptr->states.access_state == MPIDI_RMA_PER_TARGET ||
win_ptr->states.access_state == MPIDI_RMA_LOCK_ALL_CALLED) {
if (curr_target->access_state == MPIDI_RMA_LOCK_GRANTED)
break;
}
else {
break;
}
}
curr_target = curr_target->next;
}
if (curr_target != NULL) break;
}
}
if (curr_target == NULL) goto fn_exit;
/* After we do this, all following Win_flush_local
must do a Win_flush instead. */
curr_target->disable_flush_local = 1;
if (curr_target->read_op_list != NULL) {
......@@ -507,6 +524,9 @@ int MPIDI_CH3I_RMA_Free_ops_before_completion(MPID_Win * win_ptr)
MPID_Request_release(curr_op->request);
MPL_LL_DELETE(*op_list, *op_list_tail, curr_op);
MPIDI_CH3I_Win_op_free(win_ptr, curr_op);
win_ptr->active_req_cnt--;
if (*op_list == NULL) {
if (read_flag == 1) {
op_list = &curr_target->write_op_list;
......
......@@ -1221,8 +1221,17 @@ int MPIDI_Win_flush_local(int dest, MPID_Win * win_ptr)
}
/* Set sync_flag in sync struct. */
if (target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH_LOCAL)
target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH_LOCAL;
if (target->disable_flush_local) {
if (target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH) {
target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH;
target->sync.have_remote_incomplete_ops = 0;
target->sync.outstanding_acks++;
}
}
else {
if (target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH_LOCAL)
target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH_LOCAL;
}
/* Issue out all operations. */
mpi_errno = MPIDI_CH3I_RMA_Make_progress_target(win_ptr, dest,
......@@ -1237,15 +1246,20 @@ int MPIDI_Win_flush_local(int dest, MPID_Win * win_ptr)
&remote_completed);
if (mpi_errno != MPI_SUCCESS)
MPIU_ERR_POP(mpi_errno);
if (!local_completed) {
if ((target->disable_flush_local && !remote_completed) ||
(!target->disable_flush_local && !local_completed)) {
mpi_errno = wait_progress_engine();
if (mpi_errno != MPI_SUCCESS)
MPIU_ERR_POP(mpi_errno);
}
} while (!local_completed);
} while ((target->disable_flush_local && !remote_completed) ||
(!target->disable_flush_local && !local_completed));
finish_flush_local:
if (target != NULL) {
/* reset disable_flush_local flag in target to 0 */
target->disable_flush_local = 0;
/* ENDING synchronization: correctly decrement the following counters. */
win_ptr->accumulated_ops_cnt -= target->accumulated_ops_cnt;
target->accumulated_ops_cnt = 0;
......@@ -1589,6 +1603,8 @@ int MPIDI_Win_flush_local_all(MPID_Win * win_ptr)
int i, made_progress = 0;
int local_completed = 0, remote_completed = 0;
MPIDI_RMA_Target_t *curr_target = NULL;
int enable_flush_local_cnt = 0, disable_flush_local_cnt = 0;
int remote_completed_cnt = 0, local_completed_cnt = 0;
int mpi_errno = MPI_SUCCESS;
MPIDI_STATE_DECL(MPID_STATE_MPIDI_WIN_FLUSH_LOCAL_ALL);
......@@ -1615,8 +1631,19 @@ int MPIDI_Win_flush_local_all(MPID_Win * win_ptr)
for (i = 0; i < win_ptr->num_slots; i++) {
curr_target = win_ptr->slots[i].target_list;
while (curr_target != NULL) {
if (curr_target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH_LOCAL) {
curr_target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH_LOCAL;
if (curr_target->disable_flush_local) {
if (curr_target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH) {
curr_target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH;
curr_target->sync.have_remote_incomplete_ops = 0;
curr_target->sync.outstanding_acks++;
}
disable_flush_local_cnt++;
}
else {
if (curr_target->sync.sync_flag < MPIDI_RMA_SYNC_FLUSH_LOCAL) {
curr_target->sync.sync_flag = MPIDI_RMA_SYNC_FLUSH_LOCAL;
}
enable_flush_local_cnt++;
}
/* ENDING synchronization: correctly decrement the following counters. */
......@@ -1630,20 +1657,51 @@ int MPIDI_Win_flush_local_all(MPID_Win * win_ptr)
mpi_errno = MPIDI_CH3I_RMA_Make_progress_win(win_ptr, &made_progress);
if (mpi_errno != MPI_SUCCESS) MPIU_ERR_POP(mpi_errno);
/* Wait for local completion. */
/* wait for remote completion for those targets that disable flush_local,
* and wait for local completion for other targets */
do {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_win(win_ptr, &local_completed,
&remote_completed);
if (mpi_errno != MPI_SUCCESS)
MPIU_ERR_POP(mpi_errno);
if (!local_completed) {
for (i = 0; i < win_ptr->num_slots; i++) {
curr_target = win_ptr->slots[i].target_list;
while (curr_target != NULL) {
mpi_errno = MPIDI_CH3I_RMA_Cleanup_ops_target(win_ptr, curr_target,
&local_completed,
&remote_completed);
if (mpi_errno != MPI_SUCCESS)
MPIU_ERR_POP(mpi_errno);
if (curr_target->disable_flush_local) {
if (remote_completed) {
remote_completed_cnt++;
}
}
else {
if (local_completed) {
local_completed_cnt++;
}
}
curr_target = curr_target->next;
}
}
if (remote_completed_cnt < disable_flush_local_cnt ||
local_completed_cnt < enable_flush_local_cnt) {
mpi_errno = wait_progress_engine();
if (mpi_errno != MPI_SUCCESS)
MPIU_ERR_POP(mpi_errno);
}
} while (!local_completed);
} while (remote_completed_cnt < disable_flush_local_cnt ||
local_completed_cnt < enable_flush_local_cnt);
finish_flush_local_all:
/* reset disable_flush_local flag in target to 0 */
for (i = 0; i < win_ptr->num_slots; i++) {
curr_target = win_ptr->slots[i].target_list;
while (curr_target != NULL) {
curr_target->disable_flush_local = 0;
curr_target = curr_target->next;
}
}
/* ENDING synchronization: correctly decrement the following counter. */
win_ptr->accumulated_ops_cnt = 0;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment