static void uct_cm_iface_progress(void *arg) { uct_cm_pending_req_priv_t *priv; uct_cm_iface_t *iface = arg; uct_cm_enter(iface); uct_pending_queue_dispatch(priv, &iface->notify_q, iface->num_outstanding < iface->config.max_outstanding); uct_cm_leave(iface); ucs_callbackq_remove(&uct_cm_iface_worker(iface)->progress_q, uct_cm_iface_progress, iface); }
static UCS_CLASS_CLEANUP_FUNC(uct_cm_iface_t) { ucs_trace_func(""); ucs_async_unset_event_handler(self->cmdev->fd); uct_cm_enter(self); while (self->num_outstanding > 0) { ib_cm_destroy_id(uct_cm_iface_outstanding_pop(self)); } ib_cm_destroy_id(self->listen_id); ib_cm_close_device(self->cmdev); uct_cm_leave(self); ucs_free(self->outstanding); }
static UCS_CLASS_CLEANUP_FUNC(uct_cm_iface_t) { ucs_trace_func(""); ucs_async_unset_event_handler(self->cmdev->fd); uct_cm_enter(self); while (self->num_outstanding > 0) { ib_cm_destroy_id(uct_cm_iface_outstanding_pop(self)); } ib_cm_destroy_id(self->listen_id); ib_cm_close_device(self->cmdev); uct_cm_leave(self); /* At this point all outstanding have been removed, and no further events * can be added. */ ucs_callbackq_remove_all(&uct_cm_iface_worker(self)->progress_q, uct_cm_iface_progress, self); ucs_free(self->outstanding); }
ssize_t uct_cm_ep_am_bcopy(uct_ep_h tl_ep, uint8_t am_id, uct_pack_callback_t pack_cb, void *arg) { uct_cm_iface_t *iface = ucs_derived_of(tl_ep->iface, uct_cm_iface_t); uct_cm_ep_t *ep = ucs_derived_of(tl_ep, uct_cm_ep_t); struct ib_cm_sidr_req_param req; struct ibv_sa_path_rec path; struct ib_cm_id *id; ucs_status_t status; uct_cm_hdr_t *hdr; size_t payload_len; size_t total_len; int ret; UCT_CHECK_AM_ID(am_id); uct_cm_enter(iface); if (iface->num_outstanding >= iface->config.max_outstanding) { status = UCS_ERR_NO_RESOURCE; goto err; } /* Allocate temporary contiguous buffer */ hdr = ucs_malloc(IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE, "cm_send_buf"); if (hdr == NULL) { status = UCS_ERR_NO_MEMORY; goto err; } payload_len = pack_cb(hdr + 1, arg); hdr->am_id = am_id; hdr->length = payload_len; total_len = sizeof(*hdr) + payload_len; status = uct_cm_ep_fill_path_rec(ep, &path); if (status != UCS_OK) { goto err_free; } /* Fill SIDR request */ memset(&req, 0, sizeof req); req.path = &path; req.service_id = ep->dest_addr.id; req.timeout_ms = iface->config.timeout_ms; req.private_data = hdr; req.private_data_len = total_len; req.max_cm_retries = iface->config.retry_count; /* Create temporary ID for this message. Will be released when getting REP. */ ret = ib_cm_create_id(iface->cmdev, &id, NULL); if (ret) { ucs_error("ib_cm_create_id() failed: %m"); status = UCS_ERR_IO_ERROR; goto err_free; } uct_cm_dump_path(&path); ret = ib_cm_send_sidr_req(id, &req); if (ret) { ucs_error("ib_cm_send_sidr_req() failed: %m"); status = UCS_ERR_IO_ERROR; goto err_destroy_id; } iface->outstanding[iface->num_outstanding++] = id; UCT_TL_EP_STAT_OP(&ep->super, AM, BCOPY, payload_len); uct_cm_leave(iface); uct_cm_iface_trace_data(iface, UCT_AM_TRACE_TYPE_SEND, hdr, "TX: SIDR_REQ [dlid %d svc 0x%"PRIx64"]", ntohs(path.dlid), req.service_id); ucs_free(hdr); return payload_len; err_destroy_id: ib_cm_destroy_id(id); err_free: ucs_free(hdr); err: uct_cm_leave(iface); return status; }