ucs_status_t ucp_ep_create(ucp_worker_h worker, const ucp_address_t *address, ucp_ep_h *ep_p) { char peer_name[UCP_WORKER_NAME_MAX]; uint8_t addr_indices[UCP_MAX_LANES]; ucp_address_entry_t *address_list; unsigned address_count; ucs_status_t status; uint64_t dest_uuid; ucp_ep_h ep; UCS_ASYNC_BLOCK(&worker->async); status = ucp_address_unpack(address, &dest_uuid, peer_name, sizeof(peer_name), &address_count, &address_list); if (status != UCS_OK) { ucs_error("failed to unpack remote address: %s", ucs_status_string(status)); goto out; } ep = ucp_worker_ep_find(worker, dest_uuid); if (ep != NULL) { /* TODO handle a case where the existing endpoint is incomplete */ *ep_p = ep; status = UCS_OK; goto out_free_address; } /* allocate endpoint */ status = ucp_ep_new(worker, dest_uuid, peer_name, "from api call", &ep); if (status != UCS_OK) { goto out_free_address; } /* initialize transport endpoints */ status = ucp_wireup_init_lanes(ep, address_count, address_list, addr_indices); if (status != UCS_OK) { goto err_destroy_ep; } /* send initial wireup message */ if (!(ep->flags & UCP_EP_FLAG_LOCAL_CONNECTED)) { status = ucp_wireup_send_request(ep); if (status != UCS_OK) { goto err_destroy_ep; } } *ep_p = ep; goto out_free_address; err_destroy_ep: ucp_ep_destroy(ep); out_free_address: ucs_free(address_list); out: UCS_ASYNC_UNBLOCK(&worker->async); return status; }
ucs_status_t ucp_ep_create(ucp_worker_h worker, const ucp_address_t *address, ucp_ep_h *ep_p) { char peer_name[UCP_WORKER_NAME_MAX]; ucs_status_t status; uint64_t dest_uuid; unsigned address_count; ucp_address_entry_t *address_list; ucp_ep_h ep; UCS_ASYNC_BLOCK(&worker->async); status = ucp_address_unpack(address, &dest_uuid, peer_name, sizeof(peer_name), &address_count, &address_list); if (status != UCS_OK) { ucs_error("failed to unpack remote address: %s", ucs_status_string(status)); goto out; } ep = ucp_worker_ep_find(worker, dest_uuid); if (ep != NULL) { /* TODO handle a case where the existing endpoint is incomplete */ ucs_debug("returning existing ep %p which is already connected to %"PRIx64, ep, ep->dest_uuid); *ep_p = ep; status = UCS_OK; goto out_free_address; } status = ucp_ep_create_connected(worker, dest_uuid, peer_name, address_count, address_list, " from api call", &ep); if (status != UCS_OK) { goto out_free_address; } /* send initial wireup message */ if (!(ep->flags & UCP_EP_FLAG_LOCAL_CONNECTED)) { status = ucp_wireup_send_request(ep); if (status != UCS_OK) { goto err_destroy_ep; } } *ep_p = ep; goto out_free_address; err_destroy_ep: ucp_ep_destroy(ep); out_free_address: ucs_free(address_list); out: UCS_ASYNC_UNBLOCK(&worker->async); return status; }
static void ucp_wireup_msg_dump(ucp_worker_h worker, uct_am_trace_type_t type, uint8_t id, const void *data, size_t length, char *buffer, size_t max) { ucp_context_h context = worker->context; const ucp_wireup_msg_t *msg = data; char peer_name[UCP_WORKER_NAME_MAX + 1]; ucp_address_entry_t *address_list, *ae; ucp_tl_resource_desc_t *rsc; unsigned address_count; ucp_lane_index_t lane; uint64_t uuid; char *p, *end; ucp_address_unpack(msg + 1, &uuid, peer_name, sizeof(peer_name), &address_count, &address_list); p = buffer; end = buffer + max; snprintf(p, end - p, "WIREUP %s [%s uuid 0x%"PRIx64"]", (msg->type == UCP_WIREUP_MSG_REQUEST ) ? "REQ" : (msg->type == UCP_WIREUP_MSG_REPLY ) ? "REP" : (msg->type == UCP_WIREUP_MSG_ACK ) ? "ACK" : "", peer_name, uuid); p += strlen(p); for (ae = address_list; ae < address_list + address_count; ++ae) { for (rsc = context->tl_rscs; rsc < context->tl_rscs + context->num_tls; ++rsc) { if (ae->tl_name_csum == rsc->tl_name_csum) { snprintf(p, end - p, " "UCT_TL_RESOURCE_DESC_FMT, UCT_TL_RESOURCE_DESC_ARG(&rsc->tl_rsc)); p += strlen(p); break; } } snprintf(p, end - p, "/md[%d]", ae->md_index); p += strlen(p); for (lane = 0; lane < UCP_MAX_LANES; ++lane) { if (msg->tli[lane] == (ae - address_list)) { snprintf(p, end - p, "/lane[%d]", lane); p += strlen(p); } } } ucs_free(address_list); }
static ucs_status_t ucp_wireup_msg_handler(void *arg, void *data, size_t length, void *desc) { ucp_worker_h worker = arg; ucp_wireup_msg_t *msg = data; char peer_name[UCP_WORKER_NAME_MAX]; ucp_address_entry_t *address_list; unsigned address_count; ucs_status_t status; uint64_t uuid; UCS_ASYNC_BLOCK(&worker->async); status = ucp_address_unpack(msg + 1, &uuid, peer_name, UCP_WORKER_NAME_MAX, &address_count, &address_list); if (status != UCS_OK) { ucs_error("failed to unpack address: %s", ucs_status_string(status)); goto out; } if (msg->type == UCP_WIREUP_MSG_ACK) { ucs_assert(address_count == 0); ucp_wireup_process_ack(worker, uuid); } else if (msg->type == UCP_WIREUP_MSG_REQUEST) { ucp_wireup_process_request(worker, msg, uuid, peer_name, address_count, address_list); } else if (msg->type == UCP_WIREUP_MSG_REPLY) { ucp_wireup_process_reply(worker, msg, uuid, address_count, address_list); } else { ucs_bug("invalid wireup message"); } ucs_free(address_list); out: UCS_ASYNC_UNBLOCK(&worker->async); return UCS_OK; }