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; }
static void __ep_destruct(void *obj) { int __attribute__((unused)) ret; struct gnix_fid_domain *domain; struct gnix_nic *nic; struct gnix_fid_av *av; struct gnix_cm_nic *cm_nic; gnix_ht_key_t *key_ptr; struct gnix_fid_ep *ep = (struct gnix_fid_ep *) obj; GNIX_TRACE(FI_LOG_EP_CTRL, "\n"); /* * clean up any vc hash table or vector, * remove entry from addr_to_ep ht. * any outstanding GNI internal requests on * the VC's will be completed prior to * destroying the VC entries in the ht. */ if (ep->type == FI_EP_RDM) { key_ptr = (gnix_ht_key_t *)&ep->my_name.gnix_addr; ret = _gnix_ht_remove(ep->cm_nic->addr_to_ep_ht, *key_ptr); if (ep->vc_ht != NULL) { ret = _gnix_ht_destroy(ep->vc_ht); if (ret == FI_SUCCESS) { free(ep->vc_ht); ep->vc_ht = NULL; } else { GNIX_WARN(FI_LOG_EP_CTRL, "_gnix_ht_destroy returned %s\n", fi_strerror(-ret)); } } } if (ep->send_cq) { _gnix_cq_poll_nic_rem(ep->send_cq, ep->nic); _gnix_ref_put(ep->send_cq); } if (ep->recv_cq) { _gnix_cq_poll_nic_rem(ep->recv_cq, ep->nic); _gnix_ref_put(ep->recv_cq); } if (ep->send_cntr) { _gnix_cntr_poll_nic_rem(ep->send_cntr, ep->nic); _gnix_ref_put(ep->send_cntr); } if (ep->recv_cntr) { _gnix_cntr_poll_nic_rem(ep->recv_cntr, ep->nic); _gnix_ref_put(ep->recv_cntr); } if (ep->read_cntr) { _gnix_cntr_poll_nic_rem(ep->read_cntr, ep->nic); _gnix_ref_put(ep->read_cntr); } if (ep->write_cntr) { _gnix_cntr_poll_nic_rem(ep->write_cntr, ep->nic); _gnix_ref_put(ep->write_cntr); } if (ep->stx_ctx) _gnix_ref_put(ep->stx_ctx); domain = ep->domain; assert(domain != NULL); _gnix_ref_put(domain); cm_nic = ep->cm_nic; assert(cm_nic != NULL); nic = ep->nic; assert(nic != NULL); av = ep->av; if (av != NULL) _gnix_ref_put(av); /* There is no other choice here, we need to assert if we can't free */ ret = _gnix_nic_free(nic); assert(ret == FI_SUCCESS); ep->nic = NULL; /* This currently always returns FI_SUCCESS */ ret = _gnix_cm_nic_free(cm_nic); assert(ret == FI_SUCCESS); /* * Free fab_reqs */ __fr_freelist_destroy(ep); free(ep); }