static int pscom_psm_peek() { unsigned read_progress = 0; psm_mq_req_t req; psm_mq_status_t status; psm_error_t ret; do { ret = psm_mq_ipeek(pspsm_mq, &req, /* status */ NULL); if (ret == PSM_MQ_INCOMPLETE) return read_progress; if (ret != PSM_OK) goto err; ret = psm_mq_test(&req, &status); if (ret != PSM_OK) goto err; read_progress += pscom_psm_process(&status); } while (1); err: pspsm_err(psm_error_get_string(ret)); pspsm_dprint(1, "pscom_psm_peek: %s", pspsm_err_str); return read_progress; }
int ompi_mtl_psm_cancel(struct mca_mtl_base_module_t* mtl, struct mca_mtl_request_t *mtl_request, int flag) { psm_error_t err; psm_mq_status_t status; mca_mtl_psm_request_t *mtl_psm_request = (mca_mtl_psm_request_t*) mtl_request; /* PSM does not support canceling sends */ if(OMPI_MTL_PSM_ISEND == mtl_psm_request->type) { return OMPI_SUCCESS; } err = psm_mq_cancel(&mtl_psm_request->psm_request); if(PSM_OK == err) { err = psm_mq_test(&mtl_psm_request->psm_request, &status); if(PSM_OK == err) { mtl_request->ompi_req->req_status._cancelled = true; mtl_psm_request->super.completion_callback(&mtl_psm_request->super); return OMPI_SUCCESS; } else { return OMPI_ERROR; } } else if(PSM_MQ_INCOMPLETE == err) { return OMPI_SUCCESS; } return OMPI_ERROR; }
static ssize_t psmx_ep_cancel(fid_t fid, void *context) { struct psmx_fid_ep *ep; psm_mq_status_t status; struct fi_context *fi_context = context; uint64_t flags; struct psmx_cq_event *event; int err; ep = container_of(fid, struct psmx_fid_ep, ep.fid); if (!ep->domain) return -FI_EBADF; if (!fi_context) return -FI_EINVAL; switch (PSMX_CTXT_TYPE(fi_context)) { case PSMX_TRECV_CONTEXT: flags = FI_RECV | FI_TAGGED; break; case PSMX_RECV_CONTEXT: case PSMX_MULTI_RECV_CONTEXT: flags = FI_RECV | FI_MSG; break; default: return -FI_EOPNOTSUPP; } err = psm_mq_cancel((psm_mq_req_t *)&PSMX_CTXT_REQ(fi_context)); if (err == PSM_OK) { err = psm_mq_test((psm_mq_req_t *)&PSMX_CTXT_REQ(fi_context), &status); if (err == PSM_OK && ep->recv_cq) { event = psmx_cq_create_event( ep->recv_cq, status.context, NULL, /* buf */ flags, 0, /* len */ 0, /* data */ 0, /* tag */ 0 /* olen */, -FI_ECANCELED); if (event) psmx_cq_enqueue_event(ep->recv_cq, event); else return -FI_ENOMEM; } } return psmx_errno(err); }
static ssize_t psmx_ep_cancel(fid_t fid, void *context) { struct psmx_fid_ep *fid_ep; psm_mq_status_t status; struct fi_context *fi_context = context; int err; fid_ep = container_of(fid, struct psmx_fid_ep, ep.fid); if (!fid_ep->domain) return -EBADF; if (!fi_context) return -EINVAL; err = psm_mq_cancel((psm_mq_req_t *)&PSMX_CTXT_REQ(fi_context)); if (err == PSM_OK) err = psm_mq_test((psm_mq_req_t *)&PSMX_CTXT_REQ(fi_context), &status); return psmx_errno(err); }
int ompi_mtl_psm_progress( void ) { psm_error_t err; mca_mtl_psm_request_t* mtl_psm_request; psm_mq_status_t psm_status; psm_mq_req_t req; int completed = 1; do { err = psm_mq_ipeek(ompi_mtl_psm.mq, &req, NULL); if (err == PSM_MQ_INCOMPLETE) { return completed; } else if (err != PSM_OK) { goto error; } completed++; err = psm_mq_test(&req, &psm_status); if (err != PSM_OK) { goto error; } mtl_psm_request = (mca_mtl_psm_request_t*) psm_status.context; if (mtl_psm_request->type == OMPI_MTL_PSM_IRECV) { ompi_mtl_datatype_unpack(mtl_psm_request->convertor, mtl_psm_request->buf, psm_status.msg_length); mtl_psm_request->super.ompi_req->req_status.MPI_SOURCE = PSM_GET_MQRANK(psm_status.msg_tag); mtl_psm_request->super.ompi_req->req_status.MPI_TAG = PSM_GET_MQUTAG(psm_status.msg_tag); mtl_psm_request->super.ompi_req->req_status._ucount = psm_status.nbytes; } if(mtl_psm_request->type == OMPI_MTL_PSM_ISEND) { if (mtl_psm_request->free_after) { free(mtl_psm_request->buf); } } switch (psm_status.error_code) { case PSM_OK: mtl_psm_request->super.ompi_req->req_status.MPI_ERROR = OMPI_SUCCESS; break; case PSM_MQ_TRUNCATION: mtl_psm_request->super.ompi_req->req_status.MPI_ERROR = MPI_ERR_TRUNCATE; break; default: mtl_psm_request->super.ompi_req->req_status.MPI_ERROR = MPI_ERR_INTERN; } mtl_psm_request->super.completion_callback(&mtl_psm_request->super); } while (1); error: opal_show_help("help-mtl-psm.txt", "error polling network", true, psm_error_get_string(err)); return 1; }
int psmx_eq_poll_mq(struct psmx_fid_eq *eq, struct psmx_fid_domain *domain_if_null_eq) { psm_mq_req_t psm_req; psm_mq_status_t psm_status; struct fi_context *fi_context; struct psmx_fid_domain *domain; struct psmx_fid_ep *tmp_ep; struct psmx_fid_eq *tmp_eq; struct psmx_fid_cntr *tmp_cntr; struct psmx_event *event; int multi_recv; int err; if (eq) domain = eq->domain; else domain = domain_if_null_eq; while (1) { err = psm_mq_ipeek(domain->psm_mq, &psm_req, NULL); if (err == PSM_OK) { err = psm_mq_test(&psm_req, &psm_status); fi_context = psm_status.context; tmp_ep = PSMX_CTXT_EP(fi_context); tmp_eq = NULL; tmp_cntr = NULL; multi_recv = 0; switch (PSMX_CTXT_TYPE(fi_context)) { case PSMX_NOCOMP_SEND_CONTEXT: tmp_ep->pending_sends--; if (!tmp_ep->send_cntr_event_flag) tmp_cntr = tmp_ep->send_cntr; break; case PSMX_NOCOMP_RECV_CONTEXT: if (!tmp_ep->recv_cntr_event_flag) tmp_cntr = tmp_ep->recv_cntr; break; case PSMX_NOCOMP_WRITE_CONTEXT: tmp_ep->pending_writes--; if (!tmp_ep->write_cntr_event_flag) tmp_cntr = tmp_ep->write_cntr; break; case PSMX_NOCOMP_READ_CONTEXT: tmp_ep->pending_reads--; if (!tmp_ep->read_cntr_event_flag) tmp_cntr = tmp_ep->read_cntr; break; case PSMX_INJECT_CONTEXT: tmp_ep->pending_sends--; if (!tmp_ep->send_cntr_event_flag) tmp_cntr = tmp_ep->send_cntr; free(fi_context); break; case PSMX_INJECT_WRITE_CONTEXT: tmp_ep->pending_writes--; if (!tmp_ep->write_cntr_event_flag) tmp_cntr = tmp_ep->write_cntr; free(fi_context); break; case PSMX_SEND_CONTEXT: tmp_ep->pending_sends--; tmp_eq = tmp_ep->send_eq; tmp_cntr = tmp_ep->send_cntr; break; case PSMX_RECV_CONTEXT: tmp_eq = tmp_ep->recv_eq; tmp_cntr = tmp_ep->recv_cntr; break; case PSMX_MULTI_RECV_CONTEXT: multi_recv = 1; tmp_eq = tmp_ep->recv_eq; tmp_cntr = tmp_ep->recv_cntr; break; case PSMX_READ_CONTEXT: tmp_ep->pending_reads--; tmp_eq = tmp_ep->send_eq; tmp_cntr = tmp_ep->read_cntr; break; case PSMX_WRITE_CONTEXT: tmp_ep->pending_writes--; tmp_eq = tmp_ep->send_eq; tmp_cntr = tmp_ep->write_cntr; break; } if (tmp_eq) { event = psmx_eq_create_event_from_status(tmp_eq, &psm_status); if (!event) return -ENOMEM; psmx_eq_enqueue_event(tmp_eq, event); } if (tmp_cntr) tmp_cntr->cntr.ops->add(&tmp_cntr->cntr, 1); if (multi_recv) { struct psmx_multi_recv *req; psm_mq_req_t psm_req; req = PSMX_CTXT_USER(fi_context); req->offset += psm_status.nbytes; if (req->offset + req->min_buf_size <= req->len) { err = psm_mq_irecv(tmp_ep->domain->psm_mq, req->tag, req->tagsel, req->flag, req->buf + req->offset, req->len - req->offset, (void *)fi_context, &psm_req); if (err != PSM_OK) return psmx_errno(err); PSMX_CTXT_REQ(fi_context) = psm_req; } else { if (tmp_eq) { event = psmx_eq_create_event( tmp_eq, req->context, req->buf, FI_MULTI_RECV, req->len, req->len - req->offset, /* data */ 0, /* tag */ 0, /* olen */ 0); /* err */ if (!event) return -ENOMEM; psmx_eq_enqueue_event(tmp_eq, event); } free(req); } } if (!eq || tmp_eq == eq) return 1; } else if (err == PSM_MQ_NO_COMPLETIONS) { return 0; } else { return psmx_errno(err); } } }