Beispiel #1
0
static inline ucs_status_t uct_ud_verbs_iface_poll_rx(uct_ud_verbs_iface_t *iface)
{
    uct_ib_iface_recv_desc_t *desc;
    struct ibv_wc wc[UCT_IB_MAX_WC];
    int i, ret;
    char *packet;


    ret = ibv_poll_cq(iface->super.super.recv_cq, UCT_IB_MAX_WC, wc);
    if (ret == 0) {
        return UCS_ERR_NO_PROGRESS;
    } 
    if (ucs_unlikely(ret < 0)) {
        ucs_fatal("Failed to poll receive CQ");
    }

    for (i = 0; i < ret; ++i) {
        if (ucs_unlikely(wc[i].status != IBV_WC_SUCCESS)) {
            ucs_fatal("Receive completion with error: %s", ibv_wc_status_str(wc[i].status));
        }

        desc = (void*)wc[i].wr_id;
        ucs_trace_data("pkt rcvd: buf=%p len=%d", desc, wc[i].byte_len);
        packet = uct_ib_iface_recv_desc_hdr(&iface->super.super, desc);
        VALGRIND_MAKE_MEM_DEFINED(packet, wc[i].byte_len);

        uct_ud_ep_process_rx(&iface->super, 
                             (uct_ud_neth_t *)(packet + UCT_IB_GRH_LEN),
                             wc[i].byte_len - UCT_IB_GRH_LEN,
                             (uct_ud_recv_skb_t *)desc); 
    }
    iface->super.rx.available += ret;
    uct_ud_verbs_iface_post_recv(iface);
    return UCS_OK;
}
Beispiel #2
0
static UCS_CLASS_INIT_FUNC(uct_ud_verbs_iface_t, uct_pd_h pd, uct_worker_h worker,
                           const char *dev_name, size_t rx_headroom,
                           const uct_iface_config_t *tl_config)
{
    uct_ud_iface_config_t *config = ucs_derived_of(tl_config,
                                                   uct_ud_iface_config_t);
    ucs_trace_func("");

    UCS_CLASS_CALL_SUPER_INIT(uct_ud_iface_t, &uct_ud_verbs_iface_ops, pd,
                              worker, dev_name, rx_headroom, 0, config);

    self->super.ops.async_progress = uct_ud_verbs_iface_async_progress;
    self->super.ops.tx_skb         = uct_ud_verbs_ep_tx_ctl_skb;

    if (self->super.config.rx_max_batch < UCT_IB_MAX_WC) {
        ucs_warn("max batch is too low (%d < %d), performance may be impacted",
                self->super.config.rx_max_batch,
                UCT_IB_MAX_WC);
    }

    while (self->super.rx.available >= self->super.config.rx_max_batch) {
        uct_ud_verbs_iface_post_recv(self);
    }
    
    memset(&self->tx.wr_inl, 0, sizeof(self->tx.wr_inl));
    self->tx.wr_inl.opcode            = IBV_WR_SEND;
    self->tx.wr_inl.wr_id             = 0xBEEBBEEB;
    self->tx.wr_inl.wr.ud.remote_qkey = UCT_IB_QKEY;
    self->tx.wr_inl.imm_data          = 0;
    self->tx.wr_inl.next              = 0;
    self->tx.wr_inl.sg_list           = self->tx.sge;
    self->tx.wr_inl.num_sge           = UCT_UD_MAX_SGE;

    memset(&self->tx.wr_skb, 0, sizeof(self->tx.wr_skb));
    self->tx.wr_skb.opcode            = IBV_WR_SEND;
    self->tx.wr_skb.wr_id             = 0xFAAFFAAF;
    self->tx.wr_skb.wr.ud.remote_qkey = UCT_IB_QKEY;
    self->tx.wr_skb.imm_data          = 0;
    self->tx.wr_skb.next              = 0;
    self->tx.wr_skb.sg_list           = self->tx.sge;
    self->tx.wr_skb.num_sge           = 1;

    /* TODO: add progress on first ep creation */
    uct_worker_progress_register(worker, uct_ud_verbs_iface_progress, self);
    uct_ud_leave(&self->super);
    return UCS_OK;
}
Beispiel #3
0
static UCS_CLASS_INIT_FUNC(uct_ud_verbs_iface_t, uct_pd_h pd, uct_worker_h worker,
                           const char *dev_name, size_t rx_headroom,
                           const uct_iface_config_t *tl_config)
{
    uct_ud_iface_config_t *config = ucs_derived_of(tl_config, uct_ud_iface_config_t);
    ucs_trace_func("");

    UCS_CLASS_CALL_SUPER_INIT(uct_ud_iface_t, &uct_ud_verbs_iface_ops, pd,
                              worker, dev_name, rx_headroom, 0, config);

    while (self->super.rx.available >= self->super.config.rx_max_batch) {
        uct_ud_verbs_iface_post_recv(self);
    }
    
    memset(&self->tx.wr_inl, 0, sizeof(self->tx.wr_inl));
    self->tx.wr_inl.opcode            = IBV_WR_SEND;
    self->tx.wr_inl.wr_id             = 0xBEEBBEEB;
    self->tx.wr_inl.wr.ud.remote_qkey = UCT_UD_QKEY;
    self->tx.wr_inl.imm_data          = 0;
    self->tx.wr_inl.next              = 0;
    self->tx.wr_inl.sg_list           = self->tx.sge;
    self->tx.wr_inl.num_sge           = UCT_UD_MAX_SGE;

    memset(&self->tx.wr_bcp, 0, sizeof(self->tx.wr_bcp));
    self->tx.wr_bcp.opcode            = IBV_WR_SEND;
    self->tx.wr_bcp.wr_id             = 0xFAAFFAAF;
    self->tx.wr_bcp.wr.ud.remote_qkey = UCT_UD_QKEY;
    self->tx.wr_bcp.imm_data          = 0;
    self->tx.wr_bcp.next              = 0;
    self->tx.wr_bcp.sg_list           = self->tx.sge;
    self->tx.wr_bcp.num_sge           = 1;

    memset(&self->tx.wr_ctl, 0, sizeof(self->tx.wr_ctl));
    self->tx.wr_ctl.opcode            = IBV_WR_SEND;
    self->tx.wr_ctl.wr_id             = 0xCCCCCCCC;
    self->tx.wr_ctl.wr.ud.remote_qkey = UCT_UD_QKEY;
    self->tx.wr_ctl.imm_data          = 0;
    self->tx.wr_ctl.next              = 0;
    self->tx.wr_ctl.sg_list           = self->tx.sge;
    self->tx.wr_ctl.num_sge           = 1;
    /* TODO: add progress on first ep creation */
    ucs_notifier_chain_add(&worker->progress_chain, uct_ud_verbs_iface_progress,
                           self);
    return UCS_OK;
}