Test(vc_management_auto, vc_connect) { int ret; struct gnix_vc *vc_conn; struct gnix_fid_ep *ep_priv[2]; gnix_ht_key_t key; enum gnix_vc_conn_state state; ep_priv[0] = container_of(ep[0], struct gnix_fid_ep, ep_fid); ep_priv[1] = container_of(ep[1], struct gnix_fid_ep, ep_fid); ret = _gnix_vc_alloc(ep_priv[0], gnix_addr[1], &vc_conn); cr_assert_eq(ret, FI_SUCCESS); memcpy(&key, &gni_addr[1], sizeof(gnix_ht_key_t)); ret = _gnix_ht_insert(ep_priv[0]->vc_ht, key, vc_conn); cr_assert_eq(ret, FI_SUCCESS); vc_conn->modes |= GNIX_VC_MODE_IN_HT; ret = _gnix_vc_connect(vc_conn); cr_assert_eq(ret, FI_SUCCESS); /* * since we asked for FI_PROGRESS_AUTO for control * we can just spin here. add a yield in case the * test is only being run on one cpu. */ state = GNIX_VC_CONN_NONE; while (state != GNIX_VC_CONNECTED) { pthread_yield(); state = _gnix_vc_state(vc_conn); } ret = _gnix_vc_disconnect(vc_conn); cr_assert_eq(ret, FI_SUCCESS); /* VC is destroyed by the EP */ }
static int gnix_ep_close(fid_t fid) { int ret = FI_SUCCESS; struct gnix_fid_ep *ep; struct gnix_fid_domain *domain; struct gnix_nic *nic; struct gnix_vc *vc; struct gnix_fid_av *av; struct gnix_cm_nic *cm_nic; struct dlist_entry *p, *head; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); ep = container_of(fid, struct gnix_fid_ep, ep_fid.fid); /* TODO: lots more stuff to do here */ if (ep->send_cq) { _gnix_cq_poll_nic_rem(ep->send_cq, ep->nic); atomic_dec(&ep->send_cq->ref_cnt); } if (ep->recv_cq) { _gnix_cq_poll_nic_rem(ep->recv_cq, ep->nic); atomic_dec(&ep->recv_cq->ref_cnt); } if (ep->send_cntr) { _gnix_cntr_poll_nic_rem(ep->send_cntr, ep->nic); atomic_dec(&ep->send_cntr->ref_cnt); } if (ep->recv_cntr) { _gnix_cntr_poll_nic_rem(ep->recv_cntr, ep->nic); atomic_dec(&ep->recv_cntr->ref_cnt); } if (ep->read_cntr) { _gnix_cntr_poll_nic_rem(ep->read_cntr, ep->nic); atomic_dec(&ep->read_cntr->ref_cnt); } if (ep->write_cntr) { _gnix_cntr_poll_nic_rem(ep->write_cntr, ep->nic); atomic_dec(&ep->write_cntr->ref_cnt); } domain = ep->domain; assert(domain != NULL); atomic_dec(&domain->ref_cnt); cm_nic = ep->cm_nic; assert(cm_nic != NULL); _gnix_cm_nic_free(cm_nic); nic = ep->nic; assert(nic != NULL); av = ep->av; if (av != NULL) atomic_dec(&av->ref_cnt); /* * destroy any vc's being used by this EP. */ head = &ep->wc_vc_list; for (p = head->next; p != head; p = p->next) { vc = container_of(p, struct gnix_vc, entry); dlist_remove(&vc->entry); if (vc->conn_state == GNIX_VC_CONNECTED) { ret = _gnix_vc_disconnect(vc); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_vc_disconnect returned %d\n", ret); goto err; } } ret = _gnix_vc_destroy(vc); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_vc_destroy returned %d\n", ret); goto err; } } /* * clean up any vc hash table or vector */ if (ep->type == FI_EP_RDM) { if (ep->vc_ht != NULL) { _gnix_ht_destroy(ep->vc_ht); free(ep->vc_ht); ep->vc_ht = NULL; } } ret = _gnix_nic_free(nic); if (ret != FI_SUCCESS) { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_vc_destroy call returned %d\n", ret); goto err; } ep->nic = NULL; /* * Free fab_reqs */ if (atomic_get(&ep->active_fab_reqs) != 0) { /* Should we just assert here? */ GNIX_WARN(FI_LOG_EP_CTRL, "Active requests while closing an endpoint."); } __fr_freelist_destroy(ep); free(ep); err: return ret; }