void uct_ugni_proccess_datagram_pipe(int event_id, void *arg) { uct_ugni_udt_iface_t *iface = (uct_ugni_udt_iface_t *)arg; uct_ugni_udt_ep_t *ep; uct_ugni_udt_desc_t *datagram; ucs_status_t status; void *user_desc; gni_return_t ugni_rc; uint64_t id; ucs_trace_func(""); uct_ugni_device_lock(&iface->super.cdm); ugni_rc = GNI_PostDataProbeById(uct_ugni_udt_iface_nic_handle(iface), &id); uct_ugni_device_unlock(&iface->super.cdm); while (GNI_RC_SUCCESS == ugni_rc) { status = recieve_datagram(iface, id, &ep); if (UCS_INPROGRESS == status) { if (ep != NULL){ ucs_trace_data("Processing reply"); datagram = ep->posted_desc; status = processs_datagram(iface, datagram); if (UCS_OK != status) { user_desc = uct_ugni_udt_get_user_desc(datagram, iface); uct_recv_desc(user_desc) = &iface->release_desc; } else { ucs_mpool_put(datagram); } ep->posted_desc = NULL; uct_ugni_check_flush(ep->desc_flush_group); } else { ucs_trace_data("Processing wildcard"); datagram = iface->desc_any; status = processs_datagram(iface, datagram); if (UCS_OK != status) { UCT_TL_IFACE_GET_TX_DESC(&iface->super.super, &iface->free_desc, iface->desc_any, iface->desc_any=NULL); user_desc = uct_ugni_udt_get_user_desc(datagram, iface); uct_recv_desc(user_desc) = &iface->release_desc; } status = uct_ugni_udt_ep_any_post(iface); if (UCS_OK != status) { /* We can't continue if we can't post the first receive */ ucs_error("Failed to post wildcard request"); return; } } } uct_ugni_device_lock(&iface->super.cdm); ugni_rc = GNI_PostDataProbeById(uct_ugni_udt_iface_nic_handle(iface), &id); uct_ugni_device_unlock(&iface->super.cdm); } ucs_async_pipe_drain(&iface->event_pipe); pthread_mutex_lock(&iface->device_lock); iface->events_ready = 0; pthread_mutex_unlock(&iface->device_lock); ucs_trace("Signaling device thread to resume monitoring"); pthread_cond_signal(&iface->device_condition); }
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; } status = uct_ugni_udt_ep_any_post(iface); if (ucs_unlikely(UCS_OK != status)) { ucs_error("Failed to post uct_ugni_udt_ep_any_post"); goto exit; } } else { /* Ack message */ ucs_assert_always(NULL != ep); if (header->type == UCT_UGNI_UDT_PAYLOAD) { /* data message was received */ 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) {
static UCS_CLASS_INIT_FUNC(uct_ugni_udt_iface_t, uct_md_h md, uct_worker_h worker, const uct_iface_params_t *params, const uct_iface_config_t *tl_config) { uct_ugni_iface_config_t *config = ucs_derived_of(tl_config, uct_ugni_iface_config_t); ucs_status_t status; uct_ugni_udt_desc_t *desc; gni_return_t ugni_rc; int rc; UCS_CLASS_CALL_SUPER_INIT(uct_ugni_iface_t, md, worker, params, &uct_ugni_udt_iface_ops, &config->super UCS_STATS_ARG(NULL)); /* Setting initial configuration */ self->config.udt_seg_size = GNI_DATAGRAM_MAXSIZE; self->config.rx_headroom = params->rx_headroom; self->release_desc.cb = uct_ugni_udt_iface_release_desc; status = ucs_async_pipe_create(&self->event_pipe); if (UCS_OK != status) { ucs_error("Pipe creation failed"); goto exit; } status = ucs_mpool_init(&self->free_desc, 0, uct_ugni_udt_get_diff(self) + self->config.udt_seg_size * 2, uct_ugni_udt_get_diff(self), UCS_SYS_CACHE_LINE_SIZE, /* alignment */ 128, /* grow */ config->mpool.max_bufs, /* max buffers */ &uct_ugni_udt_desc_mpool_ops, "UGNI-UDT-DESC"); if (UCS_OK != status) { ucs_error("Mpool creation failed"); goto clean_pipe; } ugni_rc = GNI_EpCreate(uct_ugni_udt_iface_nic_handle(self), NULL, &self->ep_any); if (GNI_RC_SUCCESS != ugni_rc) { ucs_error("GNI_EpCreate failed, Error status: %s %d", gni_err_str[ugni_rc], ugni_rc); status = UCS_ERR_NO_DEVICE; goto clean_free_desc; } UCT_TL_IFACE_GET_TX_DESC(&self->super.super, &self->free_desc, desc, goto clean_ep); ucs_debug("First wildcard desc is %p", desc); /* Init any desc */ self->desc_any = desc; status = uct_ugni_udt_ep_any_post(self); if (UCS_OK != status) { /* We can't continue if we can't post the first receive */ ucs_error("Failed to post wildcard request"); goto clean_any_desc; } status = ucs_async_set_event_handler(self->super.super.worker->async->mode, ucs_async_pipe_rfd(&self->event_pipe), POLLIN, uct_ugni_proccess_datagram_pipe, self, self->super.super.worker->async); if (UCS_OK != status) { goto clean_cancel_desc; } pthread_mutex_init(&self->device_lock, NULL); pthread_cond_init(&self->device_condition, NULL); self->events_ready = 0; rc = pthread_create(&self->event_thread, NULL, uct_ugni_udt_device_thread, self); if(0 != rc) { goto clean_remove_event; } return UCS_OK; clean_remove_event: ucs_async_pipe_destroy(&self->event_pipe); clean_cancel_desc: uct_ugni_udt_clean_wildcard(self); clean_any_desc: ucs_mpool_put(self->desc_any); clean_ep: ugni_rc = GNI_EpDestroy(self->ep_any); if (GNI_RC_SUCCESS != ugni_rc) { ucs_warn("GNI_EpDestroy failed, Error status: %s %d", gni_err_str[ugni_rc], ugni_rc); } clean_free_desc: ucs_mpool_cleanup(&self->free_desc, 1); clean_pipe: ucs_async_pipe_destroy(&self->event_pipe); exit: uct_ugni_cleanup_base_iface(&self->super); ucs_error("Failed to activate interface"); return status; }