예제 #1
0
파일: ud_verbs.c 프로젝트: igor-ivanov/ucx
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;
}
예제 #2
0
파일: ud_mlx5.c 프로젝트: tonycurtis/ucx
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;
}
예제 #3
0
파일: ud_verbs.c 프로젝트: igor-ivanov/ucx
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;
}
예제 #4
0
파일: ud_verbs.c 프로젝트: biddisco/ucx
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;
}