static ucs_status_t recieve_datagram(uct_ugni_udt_iface_t *iface, uint64_t id, uct_ugni_udt_ep_t **ep_out) { uint32_t rem_addr, rem_id; gni_post_state_t post_state; gni_return_t ugni_rc; uct_ugni_udt_ep_t *ep; gni_ep_handle_t gni_ep; uct_ugni_udt_desc_t *desc; uct_ugni_udt_header_t *header; ucs_trace_func("iface=%p, id=%lx", iface, id); if (UCT_UGNI_UDT_ANY == id) { ep = NULL; gni_ep = iface->ep_any; desc = iface->desc_any; } else { ep = ucs_derived_of(uct_ugni_iface_lookup_ep(&iface->super, id), uct_ugni_udt_ep_t); gni_ep = ep->super.ep; desc = ep->posted_desc; } *ep_out = ep; uct_ugni_device_lock(&iface->super.cdm); ugni_rc = GNI_EpPostDataWaitById(gni_ep, id, -1, &post_state, &rem_addr, &rem_id); uct_ugni_device_unlock(&iface->super.cdm); if (ucs_unlikely(GNI_RC_SUCCESS != ugni_rc)) { ucs_error("GNI_EpPostDataWaitById, id=%lu Error status: %s %d", id, gni_err_str[ugni_rc], ugni_rc); return UCS_ERR_IO_ERROR; } if (GNI_POST_TERMINATED == post_state) { return UCS_ERR_CANCELED; } if (GNI_POST_COMPLETED != post_state) { ucs_error("GNI_EpPostDataWaitById gave unexpected response: %u", post_state); return UCS_ERR_IO_ERROR; } if (UCT_UGNI_UDT_ANY != id) { --iface->super.outstanding; } header = uct_ugni_udt_get_rheader(desc, iface); ucs_trace("Got datagram id: %lu type: %i len: %i am_id: %i", id, header->type, header->length, header->am_id); if (UCT_UGNI_UDT_PAYLOAD != header->type) { /* ack message, no data */ ucs_assert_always(NULL != ep); ucs_mpool_put(ep->posted_desc); uct_ugni_check_flush(ep->desc_flush_group); ep->posted_desc = NULL; return UCS_OK; } return UCS_INPROGRESS; }
static void uct_ugni_udt_progress(void *arg) { uint32_t rem_addr, rem_id; uint64_t id; void *payload; void *user_desc; ucs_status_t status; uct_ugni_udt_desc_t *desc; uct_ugni_udt_header_t *header; uct_ugni_udt_iface_t * iface = (uct_ugni_udt_iface_t *)arg; uct_ugni_udt_ep_t *ep; gni_ep_handle_t ugni_ep; gni_post_state_t post_state; gni_return_t ugni_rc; pthread_mutex_lock(&uct_ugni_global_lock); ugni_rc = GNI_PostDataProbeById(iface->super.nic_handle, &id); if (ucs_unlikely(GNI_RC_SUCCESS != ugni_rc)) { if (GNI_RC_NO_MATCH != ugni_rc) { ucs_error("GNI_PostDataProbeById , Error status: %s %d", gni_err_str[ugni_rc], ugni_rc); } goto exit; } if (UCT_UGNI_UDT_ANY == id) { /* New incomming message */ ep = NULL; ugni_ep = iface->ep_any; desc = iface->desc_any; } else { /* Ack message */ ep = ucs_derived_of(uct_ugni_iface_lookup_ep(&iface->super, id), uct_ugni_udt_ep_t); if (ucs_unlikely(NULL == ep)) { ucs_error("Can not lookup ep with id %"PRIx64,id); goto exit; } ugni_ep = ep->super.ep; desc = ep->posted_desc; } ugni_rc = GNI_EpPostDataWaitById(ugni_ep, id, -1, &post_state, &rem_addr, &rem_id); if (ucs_unlikely(GNI_RC_SUCCESS != ugni_rc)) { ucs_error("GNI_EpPostDataWaitById, Error status: %s %d", gni_err_str[ugni_rc], ugni_rc); goto exit; } header = uct_ugni_udt_get_rheader(desc, iface); payload = uct_ugni_udt_get_rpayload(desc, iface); user_desc = uct_ugni_udt_get_user_desc(desc, iface); if (UCT_UGNI_UDT_ANY == id) { /* New incomming message */ ucs_assert_always(header->type == UCT_UGNI_UDT_PAYLOAD); uct_iface_trace_am(&iface->super.super, UCT_AM_TRACE_TYPE_RECV, header->am_id, payload, header->length, "RX: AM"); status = uct_iface_invoke_am(&iface->super.super, header->am_id, payload, header->length, user_desc); if (UCS_OK != status) { uct_ugni_udt_desc_t *new_desc; /* set iface for a later release call */ uct_recv_desc_iface(user_desc) = &iface->super.super.super; /* Allocate a new element */ UCT_TL_IFACE_GET_TX_DESC(&iface->super.super, &iface->free_desc, new_desc, goto exit); /* set the new desc */ iface->desc_any = new_desc; }