int MPID_nem_tcp_ckpt_restart_vc(MPIDI_VC_t *vc) { int mpi_errno = MPI_SUCCESS; MPIDI_CH3_Pkt_t upkt; MPIDI_nem_tcp_pkt_unpause_t * const pkt = (MPIDI_nem_tcp_pkt_unpause_t *)&upkt; MPIR_Request *sreq; MPIR_FUNC_VERBOSE_STATE_DECL(MPID_STATE_MPID_NEM_TCP_CKPT_RESTART_VC); MPIR_FUNC_VERBOSE_ENTER(MPID_STATE_MPID_NEM_TCP_CKPT_RESTART_VC); pkt->type = MPIDI_NEM_PKT_NETMOD; pkt->subtype = MPIDI_NEM_TCP_PKT_UNPAUSE; mpi_errno = MPID_nem_tcp_iStartContigMsg_paused(vc, pkt, sizeof(pkt), NULL, 0, &sreq); if (mpi_errno) MPIR_ERR_POP(mpi_errno); if (sreq != NULL) { if (sreq->status.MPI_ERROR != MPI_SUCCESS) { mpi_errno = sreq->status.MPI_ERROR; MPIR_Request_free(sreq); MPIR_ERR_INTERNALANDJUMP(mpi_errno, "Failed to send checkpoint unpause pkt."); } MPIR_Request_free(sreq); } fn_exit: MPIR_FUNC_VERBOSE_EXIT(MPID_STATE_MPID_NEM_TCP_CKPT_RESTART_VC); return mpi_errno; fn_fail: goto fn_exit; }
/* XXX DJG FIXME at some point this should poll, much like the newtcp module. But then we have that whole pollfd array to manage, which we don't really need until this proof-of-concept proves itself. */ int MPID_nem_lmt_vmsplice_progress(void) { int mpi_errno = MPI_SUCCESS; struct lmt_vmsplice_node *prev = NULL; struct lmt_vmsplice_node *free_me = NULL; struct lmt_vmsplice_node *cur = outstanding_head; MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_LMT_VMSPLICE_PROGRESS); MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_LMT_VMSPLICE_PROGRESS); while (cur) { int complete = 0; switch (MPIDI_Request_get_type(cur->req)) { case MPIDI_REQUEST_TYPE_RECV: mpi_errno = do_readv(cur->req, cur->pipe_fd, cur->req->dev.iov, &cur->req->dev.iov_offset, &cur->req->dev.iov_count, &complete); /* FIXME: set the error status of the req and complete it, rather than POP */ if (mpi_errno) MPIR_ERR_POP(mpi_errno); break; case MPIDI_REQUEST_TYPE_SEND: mpi_errno = do_vmsplice(cur->req, cur->pipe_fd, cur->req->dev.iov, &cur->req->dev.iov_offset, &cur->req->dev.iov_count, &complete); /* FIXME: set the error status of the req and complete it, rather than POP */ if (mpi_errno) MPIR_ERR_POP(mpi_errno); break; default: MPIR_ERR_INTERNALANDJUMP(mpi_errno, "unexpected request type"); break; } if (complete) { MPL_DBG_MSG(MPIDI_CH3_DBG_CHANNEL, VERBOSE, ".... complete"); /* remove the node from the list */ if (cur == outstanding_head) { outstanding_head = cur->next; prev = NULL; free_me = cur; cur = cur->next; } else { prev->next = cur->next; prev = cur; free_me = cur; cur = cur->next; } if (free_me) MPL_free(free_me); --MPID_nem_local_lmt_pending; } if (!cur) break; /* we might have made cur NULL above */ prev = cur; cur = cur->next; } fn_exit: MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_LMT_VMSPLICE_PROGRESS); return mpi_errno; fn_fail: goto fn_exit; }
int MPID_nem_ptl_poll(int is_blocking_poll) { int mpi_errno = MPI_SUCCESS; ptl_event_t event; int ret; MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_PTL_POLL); /* MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_PTL_POLL); */ while (1) { int ctl_event = FALSE; /* Check the rptls EQ first. It should never return an event. */ ret = MPID_nem_ptl_rptl_eqget(MPIDI_nem_ptl_rpt_eq, &event); MPIU_Assert(ret == PTL_EQ_EMPTY); /* check EQs for events */ ret = MPID_nem_ptl_rptl_eqget(MPIDI_nem_ptl_eq, &event); MPIR_ERR_CHKANDJUMP(ret == PTL_EQ_DROPPED, mpi_errno, MPI_ERR_OTHER, "**eqdropped"); if (ret == PTL_EQ_EMPTY) { ret = MPID_nem_ptl_rptl_eqget(MPIDI_nem_ptl_get_eq, &event); MPIR_ERR_CHKANDJUMP(ret == PTL_EQ_DROPPED, mpi_errno, MPI_ERR_OTHER, "**eqdropped"); if (ret == PTL_EQ_EMPTY) { ret = MPID_nem_ptl_rptl_eqget(MPIDI_nem_ptl_control_eq, &event); MPIR_ERR_CHKANDJUMP(ret == PTL_EQ_DROPPED, mpi_errno, MPI_ERR_OTHER, "**eqdropped"); if (ret == PTL_EQ_EMPTY) { ret = MPID_nem_ptl_rptl_eqget(MPIDI_nem_ptl_origin_eq, &event); MPIR_ERR_CHKANDJUMP(ret == PTL_EQ_DROPPED, mpi_errno, MPI_ERR_OTHER, "**eqdropped"); } else { ctl_event = TRUE; } /* all EQs are empty */ if (ret == PTL_EQ_EMPTY) break; } } MPIR_ERR_CHKANDJUMP1(ret, mpi_errno, MPI_ERR_OTHER, "**ptleqget", "**ptleqget %s", MPID_nem_ptl_strerror(ret)); MPL_DBG_MSG_FMT(MPIDI_CH3_DBG_CHANNEL, VERBOSE, (MPL_DBG_FDEST, "Received event %s pt_idx=%d ni_fail=%s list=%s user_ptr=%p hdr_data=%#lx mlength=%lu rlength=%lu", MPID_nem_ptl_strevent(&event), event.pt_index, MPID_nem_ptl_strnifail(event.ni_fail_type), MPID_nem_ptl_strlist(event.ptl_list), event.user_ptr, event.hdr_data, event.mlength, event.rlength)); MPIR_ERR_CHKANDJUMP2(event.ni_fail_type != PTL_NI_OK && event.ni_fail_type != PTL_NI_NO_MATCH, mpi_errno, MPI_ERR_OTHER, "**ptlni_fail", "**ptlni_fail %s %s", MPID_nem_ptl_strevent(&event), MPID_nem_ptl_strnifail(event.ni_fail_type)); /* special case for events on the control portal */ if (ctl_event) { mpi_errno = MPID_nem_ptl_nm_ctl_event_handler(&event); if (mpi_errno) MPIR_ERR_POP(mpi_errno); continue; } switch (event.type) { case PTL_EVENT_PUT: if (event.ptl_list == PTL_OVERFLOW_LIST) break; case PTL_EVENT_PUT_OVERFLOW: case PTL_EVENT_GET: case PTL_EVENT_SEND: case PTL_EVENT_REPLY: case PTL_EVENT_SEARCH: { MPID_Request * const req = event.user_ptr; MPL_DBG_MSG_P(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "req = %p", req); MPL_DBG_MSG_P(MPIDI_CH3_DBG_CHANNEL, VERBOSE, "REQ_PTL(req)->event_handler = %p", REQ_PTL(req)->event_handler); if (REQ_PTL(req)->event_handler) { mpi_errno = REQ_PTL(req)->event_handler(&event); if (mpi_errno) MPIR_ERR_POP(mpi_errno); } break; } case PTL_EVENT_AUTO_FREE: mpi_errno = append_overflow((size_t)event.user_ptr); if (mpi_errno) MPIR_ERR_POP(mpi_errno); break; case PTL_EVENT_AUTO_UNLINK: overflow_me_handle[(size_t)event.user_ptr] = PTL_INVALID_HANDLE; break; case PTL_EVENT_LINK: /* ignore */ break; case PTL_EVENT_ACK: default: MPL_error_printf("Received unexpected event type: %d %s", event.type, MPID_nem_ptl_strevent(&event)); MPIR_ERR_INTERNALANDJUMP(mpi_errno, "Unexpected event type"); } } fn_exit: /* MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_PTL_POLL); */ return mpi_errno; fn_fail: goto fn_exit; }