ucs_status_t uct_ud_verbs_ep_create_connected(uct_iface_h iface_h, const struct sockaddr *addr, uct_ep_h *new_ep_p) { uct_ud_verbs_iface_t *iface = ucs_derived_of(iface_h, uct_ud_verbs_iface_t); uct_ud_verbs_ep_t *ep; uct_ud_ep_t *new_ud_ep; const uct_sockaddr_ib_t *if_addr = (const uct_sockaddr_ib_t *)addr; uct_ud_send_skb_t *skb; struct ibv_ah *ah; ucs_status_t status; uct_ud_enter(&iface->super); status = uct_ud_ep_create_connected_common(&iface->super, if_addr, &new_ud_ep, &skb); if (status != UCS_OK) { return status; } ep = ucs_derived_of(new_ud_ep, uct_ud_verbs_ep_t); *new_ep_p = &ep->super.super.super; if (skb == NULL) { uct_ud_leave(&iface->super); return UCS_OK; } ucs_assert_always(ep->ah == NULL); ah = uct_ib_create_ah(&iface->super.super, if_addr->lid); if (ah == NULL) { ucs_error("failed to create address handle: %m"); status = UCS_ERR_INVALID_ADDR; goto err; } ep->ah = ah; ucs_trace_data("TX: CREQ (qp=%x lid=%d)", if_addr->qp_num, if_addr->lid); uct_ud_verbs_ep_tx_skb(iface, ep, skb, IBV_SEND_INLINE); uct_ud_iface_complete_tx_skb(&iface->super, &ep->super, skb); uct_ud_leave(&iface->super); return UCS_OK; err: uct_ud_ep_destroy_connected(&ep->super, if_addr); uct_ud_leave(&iface->super); *new_ep_p = NULL; return status; }
static ucs_status_t uct_ud_mlx5_ep_create_ah(uct_ud_mlx5_iface_t *iface, uct_ud_mlx5_ep_t *ep, const uct_sockaddr_ib_t *if_addr) { struct ibv_ah *ah; ah = uct_ib_create_ah(&iface->super.super, if_addr->lid); if (ah == NULL) { ucs_error("failed to create address handle: %m"); return UCS_ERR_INVALID_ADDR; } uct_ib_mlx5_get_av(ah, &ep->av); mlx5_av_base(&ep->av)->key.qkey.qkey = htonl(UCT_IB_QKEY); mlx5_av_base(&ep->av)->key.qkey.reserved = iface->super.qp->qp_num; mlx5_av_base(&ep->av)->dqp_dct = htonl(if_addr->qp_num | UCT_IB_MLX5_EXTENDED_UD_AV); ibv_destroy_ah(ah); return UCS_OK; }
ucs_status_t uct_ud_verbs_ep_connect_to_ep(uct_ep_h tl_ep, const struct sockaddr *addr) { ucs_status_t status; struct ibv_ah *ah; uct_ud_verbs_ep_t *ep = ucs_derived_of(tl_ep, uct_ud_verbs_ep_t); uct_ib_iface_t *iface = ucs_derived_of(tl_ep->iface, uct_ib_iface_t); const uct_sockaddr_ib_t *if_addr = (const uct_sockaddr_ib_t *)addr; status = uct_ud_ep_connect_to_ep(&ep->super, addr); if (status != UCS_OK) { return status; } ucs_assert_always(ep->ah == NULL); ah = uct_ib_create_ah(iface, if_addr->lid); if (ah == NULL) { ucs_error("failed to create address handle: %m"); return UCS_ERR_INVALID_ADDR; } ep->ah = ah; return UCS_OK; }
ucs_status_t uct_ud_verbs_ep_create_connected(uct_iface_h iface_h, const struct sockaddr *addr, uct_ep_h *new_ep_p) { uct_ud_ep_t *ready_ep; uct_ud_verbs_ep_t *ep; uct_ud_verbs_iface_t *iface = ucs_derived_of(iface_h, uct_ud_verbs_iface_t); uct_sockaddr_ib_t *if_addr = (uct_sockaddr_ib_t *)addr; uct_ud_send_skb_t *skb; struct ibv_ah *ah; ucs_status_t status; /* check if we can reuse half duplex ep */ ready_ep = uct_ud_iface_cep_lookup(&iface->super, if_addr, UCT_UD_EP_CONN_ID_MAX); if (ready_ep) { *new_ep_p = &ready_ep->super.super; return UCS_OK; } status = iface_h->ops.ep_create(iface_h, new_ep_p); if (status != UCS_OK) { return status; } ep = ucs_derived_of(*new_ep_p, uct_ud_verbs_ep_t); status = uct_ud_ep_connect_to_iface(&ep->super, addr); if (status != UCS_OK) { return status; } ucs_assert_always(ep->ah == NULL); ah = uct_ib_create_ah(&iface->super.super, if_addr->lid); if (ah == NULL) { ucs_error("failed to create address handle: %m"); status = UCS_ERR_INVALID_ADDR; goto err1; } ep->ah = ah; status = uct_ud_iface_cep_insert(&iface->super, if_addr, &ep->super, UCT_UD_EP_CONN_ID_MAX); if (status != UCS_OK) { goto err2; } skb = uct_ud_ep_prepare_creq(&ep->super); if (!skb) { status = UCS_ERR_NO_RESOURCE; goto err3; } iface->tx.sge[0].addr = (uintptr_t)skb->neth; iface->tx.sge[0].length = skb->len; uct_ud_verbs_iface_tx_ctl(iface, ep); ucs_trace_data("TX: CREQ (qp=%x lid=%d)", if_addr->qp_num, if_addr->lid); return UCS_OK; err3: uct_ud_iface_cep_rollback(&iface->super, if_addr, &ep->super); err2: ibv_destroy_ah(ep->ah); ep->ah = NULL; err1: uct_ud_ep_disconnect_from_iface(*new_ep_p); *new_ep_p = NULL; return status; }