Exemple #1
0
static UCS_CLASS_INIT_FUNC(uct_tcp_ep_t, uct_tcp_iface_t *iface,
                           int fd, const struct sockaddr_in *dest_addr)
{
    ucs_status_t status;

    UCS_CLASS_CALL_SUPER_INIT(uct_base_ep_t, &iface->super)

    self->buf = ucs_malloc(iface->config.buf_size, "tcp_buf");
    if (self->buf == NULL) {
        return UCS_ERR_NO_MEMORY;
    }

    self->events = 0;
    self->offset = 0;
    self->length = 0;
    ucs_queue_head_init(&self->pending_q);

    if (fd == -1) {
        status = ucs_tcpip_socket_create(&self->fd);
        if (status != UCS_OK) {
            goto err;
        }

        /* TODO use non-blocking connect */
        status = uct_tcp_socket_connect(self->fd, dest_addr);
        if (status != UCS_OK) {
            goto err_close;
        }
    } else {
        self->fd = fd;
    }

    status = ucs_sys_fcntl_modfl(self->fd, O_NONBLOCK, 0);
    if (status != UCS_OK) {
        goto err_close;
    }

    status = uct_tcp_iface_set_sockopt(iface, self->fd);
    if (status != UCS_OK) {
        goto err_close;
    }

    uct_tcp_ep_epoll_ctl(self, EPOLL_CTL_ADD);

    UCS_ASYNC_BLOCK(iface->super.worker->async);
    ucs_list_add_tail(&iface->ep_list, &self->list);
    UCS_ASYNC_UNBLOCK(iface->super.worker->async);

    ucs_debug("tcp_ep %p: created on iface %p, fd %d", self, iface, self->fd);
    return UCS_OK;

err_close:
    close(self->fd);
err:
    return status;
}
Exemple #2
0
void uct_dc_ep_cleanup(uct_ep_h tl_ep, ucs_class_t *cls)
{
    uct_dc_ep_t *ep       = ucs_derived_of(tl_ep, uct_dc_ep_t);
    uct_dc_iface_t *iface = ucs_derived_of(ep->super.super.iface, uct_dc_iface_t);

    UCS_CLASS_CLEANUP_CALL(cls, ep);

    if (uct_dc_ep_fc_wait_for_grant(ep)) {
        ucs_trace("not releasing dc_ep %p - waiting for grant", ep);
        ep->state = UCT_DC_EP_INVALID;
        ucs_list_add_tail(&iface->tx.gc_list, &ep->list);
    } else {
        ucs_free(ep);
    }
}
Exemple #3
0
void __ucs_wtimer_add(ucs_twheel_t *t, ucs_wtimer_t *timer, ucs_time_t delta)
{
    uint64_t slot;

    timer->is_active = 1;
    slot = delta>>t->res_order;
    if (ucs_unlikely(slot == 0)) {
        /* nothing really wrong with adding timer to the current slot. However
         * we want to guard against the case we spend to much time in hi res
         * timer processing */
        ucs_fatal("Timer resolution is too low. Min resolution %lf usec, wanted %lf usec",
                ucs_time_to_usec(t->res), ucs_time_to_usec(delta));
    }
    ucs_assert(slot > 0);

    if (ucs_unlikely(slot >= t->num_slots)) {
        slot = t->num_slots - 1;
    }

    slot = (t->current + slot) % t->num_slots;
    ucs_assert(slot != t->current);

    ucs_list_add_tail(&t->wheel[slot], &timer->list);
}
Exemple #4
0
static UCS_CLASS_INIT_FUNC(uct_rdmacm_ep_t, uct_iface_t *tl_iface,
                           const ucs_sock_addr_t *sockaddr,
                           const void *priv_data, size_t length)
{
    uct_rdmacm_iface_t *iface = ucs_derived_of(tl_iface, uct_rdmacm_iface_t);
    char ip_port_str[UCS_SOCKADDR_STRING_LEN];
    uct_rdmacm_priv_data_hdr_t hdr;
    ucs_status_t status;

    UCS_CLASS_CALL_SUPER_INIT(uct_base_ep_t, &iface->super);

    if (iface->is_server) {
        /* TODO allow an interface to be used both for server and client */
        return UCS_ERR_UNSUPPORTED;
    }

    /* Initialize these fields before calling rdma_resolve_addr to avoid a race
     * where they are used before being initialized (from the async thread
     * - after an RDMA_CM_EVENT_ROUTE_RESOLVED event) */
    hdr.length           = length;
    self->priv_data      = ucs_malloc(sizeof(hdr) + length, "client private data");
    if (self->priv_data == NULL) {
        status = UCS_ERR_NO_MEMORY;
        goto err;
    }

    memcpy(self->priv_data, &hdr, sizeof(hdr));
    memcpy(self->priv_data + sizeof(hdr), priv_data, length);

    /* Save the remote address */
    if (sockaddr->addr->sa_family == AF_INET) {
        memcpy(&self->remote_addr, sockaddr->addr, sizeof(struct sockaddr_in));
    } else if (sockaddr->addr->sa_family == AF_INET6) {
        memcpy(&self->remote_addr, sockaddr->addr, sizeof(struct sockaddr_in6));
    } else {
        ucs_error("rdmacm ep: unknown remote sa_family=%d", sockaddr->addr->sa_family);
        status = UCS_ERR_IO_ERROR;
        goto err_free_mem;
    }

    self->slow_prog_id = UCS_CALLBACKQ_ID_NULL;

    /* The interface can point at one endpoint at a time and therefore, the
     * connection establishment cannot be done in parallel for several endpoints */
    /* TODO support connection establishment on parallel endpoints on the same iface */
    if (iface->ep == NULL) {
        iface->ep = self;
        self->is_on_pending = 0;

        /* After rdma_resolve_addr(), the client will wait for an
         * RDMA_CM_EVENT_ADDR_RESOLVED event on the event_channel
         * to proceed with the connection establishment.
         * This event will be retrieved from the event_channel by the async thread.
         * All endpoints share the interface's event_channel but can use it serially. */
        status = uct_rdmacm_ep_resolve_addr(self);
        if (status != UCS_OK) {
            goto err_free_mem;
        }
    } else {
        /* Add the ep to the pending queue */
        UCS_ASYNC_BLOCK(iface->super.worker->async);
        ucs_list_add_tail(&iface->pending_eps_list, &self->list_elem);
        self->is_on_pending = 1;
        UCS_ASYNC_UNBLOCK(iface->super.worker->async);
    }

    ucs_debug("created an RDMACM endpoint on iface %p. event_channel: %p, "
              "iface cm_id: %p remote addr: %s",
               iface, iface->event_ch, iface->cm_id,
               ucs_sockaddr_str((struct sockaddr *)sockaddr->addr,
                                ip_port_str, UCS_SOCKADDR_STRING_LEN));
    return UCS_OK;

err_free_mem:
    ucs_free(self->priv_data);
err:
    return status;
}