Exemplo n.º 1
0
static int
fi_ibv_rdm_tagged_find_max_inline_size(struct ibv_pd *pd,
				       struct ibv_context *context)
{
	struct ibv_qp_init_attr qp_attr;
	struct ibv_qp *qp = NULL;
	struct ibv_cq *cq = ibv_create_cq(context, 1, NULL, NULL, 0);
	assert(cq);
	int max_inline = 2;
	int rst = 0;

	memset(&qp_attr, 0, sizeof(qp_attr));
	qp_attr.send_cq = cq;
	qp_attr.recv_cq = cq;
	qp_attr.qp_type = IBV_QPT_RC;
	qp_attr.cap.max_send_wr = 1;
	qp_attr.cap.max_recv_wr = 1;
	qp_attr.cap.max_send_sge = 1;
	qp_attr.cap.max_recv_sge = 1;

	do {
		if (qp)
			ibv_destroy_qp(qp);
		qp_attr.cap.max_inline_data = max_inline;
		qp = ibv_create_qp(pd, &qp_attr);
		if (qp)
			rst = max_inline;
	} while (qp && (max_inline *= 2));

	if (rst != 0) {
		int pos = rst, neg = max_inline;
		do {
			max_inline = pos + (neg - pos) / 2;
			if (qp)
				ibv_destroy_qp(qp);

			qp_attr.cap.max_inline_data = max_inline;
			qp = ibv_create_qp(pd, &qp_attr);
			if (qp)
				pos = max_inline;
			else
				neg = max_inline;

		} while (neg - pos > 2);

		rst = pos;
	}

	if (qp) {
		ibv_destroy_qp(qp);
	}

	if (cq) {
		ibv_destroy_cq(cq);
	}

	return rst;
}
Exemplo n.º 2
0
Arquivo: rping.c Projeto: hkimura/pib
static void rping_free_qp(struct rping_cb *cb)
{
	ibv_destroy_qp(cb->qp);
	ibv_destroy_cq(cb->cq);
	ibv_destroy_comp_channel(cb->channel);
	ibv_dealloc_pd(cb->pd);
}
Exemplo n.º 3
0
int rdma_create_qp(struct rdma_cm_id *id, struct ibv_pd *pd,
		   struct ibv_qp_init_attr *qp_init_attr)
{
	struct cma_id_private *id_priv;
	struct ibv_qp *qp;
	int ret;

	id_priv = container_of(id, struct cma_id_private, id);
	if (id->verbs != pd->context)
		return ERR(EINVAL);

	qp = ibv_create_qp(pd, qp_init_attr);
	if (!qp)
		return ERR(ENOMEM);

	if (ucma_is_ud_ps(id->ps))
		ret = ucma_init_ud_qp(id_priv, qp);
	else
		ret = ucma_init_conn_qp(id_priv, qp);
	if (ret)
		goto err;

	id->qp = qp;
	return 0;
err:
	ibv_destroy_qp(qp);
	return ret;
}
Exemplo n.º 4
0
static void
rdma_trans_destroy(void *a)
{
	Rdmatrans *rdma;
	struct ibv_qp_attr attr;

	rdma = a;
	if (rdma->connected)
		rdma_disconnect(rdma->cm_id);
	if (rdma->qp) {
		attr.qp_state = IBV_QPS_ERR;
		ibv_modify_qp(rdma->qp, &attr, IBV_QP_STATE);
		ibv_destroy_qp(rdma->qp);
	}
	if (rdma->cq)
		ibv_destroy_cq(rdma->cq);
	if (rdma->ch)
		ibv_destroy_comp_channel(rdma->ch);
	if (rdma->snd_mr)
		ibv_dereg_mr(rdma->snd_mr);
	if (rdma->snd_buf)
		free(rdma->snd_buf);
	if (rdma->rcv_mr)
		ibv_dereg_mr(rdma->rcv_mr);
	if (rdma->rcv_buf)
		free(rdma->rcv_buf);
	if (rdma->pd)
		ibv_dealloc_pd(rdma->pd);
	if (rdma->cm_id)
		rdma_destroy_id(rdma->cm_id);
}
Exemplo n.º 5
0
static ucs_status_t uct_rc_verbs_ep_tag_qp_create(uct_rc_verbs_iface_t *iface,
                                                  uct_rc_verbs_ep_t *ep)
{
#if HAVE_IBV_EX_HW_TM
    struct ibv_qp_cap cap;
    ucs_status_t status;
    int ret;

    if (UCT_RC_VERBS_TM_ENABLED(iface)) {
        /* Send queue of this QP will be used by FW for HW RNDV. Driver requires
         * such a QP to be initialized with zero send queue length. */
        status = uct_rc_iface_qp_create(&iface->super, IBV_QPT_RC, &ep->tm_qp,
                                        &cap, iface->tm.xrq.srq, 0);
        if (status != UCS_OK) {
            return status;
        }

        status = uct_rc_iface_qp_init(&iface->super, ep->tm_qp);
        if (status != UCS_OK) {
            ret = ibv_destroy_qp(ep->tm_qp);
            if (ret) {
                ucs_warn("ibv_destroy_qp() returned %d: %m", ret);
            }
            return status;
        }
        uct_rc_iface_add_ep(&iface->super, &ep->super, ep->tm_qp->qp_num);
    }
#endif
    return UCS_OK;
}
Exemplo n.º 6
0
static void free_sa_qp_cache(void)
{
    struct mca_btl_openib_sa_qp_cache *cache, *tmp;

    cache = sa_qp_cache;
    while (NULL != cache) {
        /* free cache data */
        if (cache->device_name)
            free(cache->device_name);
        if (NULL != cache->qp)
            ibv_destroy_qp(cache->qp);
        if (NULL != cache->ah)
            ibv_destroy_ah(cache->ah);
        if (NULL != cache->cq)
            ibv_destroy_cq(cache->cq);
        if (NULL != cache->mr)
            ibv_dereg_mr(cache->mr);
        if (NULL != cache->pd)
            ibv_dealloc_pd(cache->pd);
        tmp = cache->next;
        free(cache);
        cache = tmp;
    }
    sa_qp_cache = NULL;
}
Exemplo n.º 7
0
/* destroy ud context */
void mv2_ud_destroy_ctx (mv2_ud_ctx_t *ctx)
{
    if (ctx->qp) {
        ibv_destroy_qp(ctx->qp);
    }
    MPIU_Free(ctx);
}
Exemplo n.º 8
0
/*
 * It seems you can't probe a device / port to see if it supports a
 * specific type of QP.  You just have to try to make it and see if it
 * works.  This is a short helper function to try to make a QP of a
 * specific type and return whether it worked.
 */
static bool make_qp(struct ibv_pd *pd, struct ibv_cq *cq, enum ibv_qp_type type)
{
    struct ibv_qp_init_attr qpia;
    struct ibv_qp *qp;

    memset(&qpia, 0, sizeof(qpia));
    qpia.qp_context = NULL;
    qpia.send_cq = cq;
    qpia.recv_cq = cq;
    qpia.srq = NULL;
    qpia.cap.max_send_wr = 1;
    qpia.cap.max_recv_wr = 1;
    qpia.cap.max_send_sge = 1;
    qpia.cap.max_recv_sge = 1;
    qpia.cap.max_inline_data = 0;
    qpia.qp_type = type;
    qpia.sq_sig_all = 0;
    
    qp = ibv_create_qp(pd, &qpia);
    if (NULL != qp) {
        ibv_destroy_qp(qp);
        return true;
    }

    return false;
}
Exemplo n.º 9
0
int
rd_close_qp(CONNECTION *con)
{
    if (con->qp)
        ibv_destroy_qp(con->qp);

    return 0;
}
Exemplo n.º 10
0
int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp)
{  fprintf(stderr, "%s:%s:%d \n", __func__, __FILE__, __LINE__);
	int ret;

	ret = ibv_destroy_qp(qp->real_qp);
	if (ret)
		return ret;

	free(qp);
	return 0;
}
Exemplo n.º 11
0
static int fio_rdmaio_close_file(struct thread_data *td, struct fio_file *f)
{
	struct rdmaio_data *rd = td->io_ops->data;
	struct ibv_send_wr *bad_wr;

	/* unregister rdma buffer */

	/*
	 * Client sends notification to the server side
	 */
	/* refer to: http://linux.die.net/man/7/rdma_cm */
	if ((rd->is_client == 1) && ((rd->rdma_protocol == FIO_RDMA_MEM_WRITE)
				     || (rd->rdma_protocol ==
					 FIO_RDMA_MEM_READ))) {
		if (ibv_post_send(rd->qp, &rd->sq_wr, &bad_wr) != 0) {
			log_err("fio: ibv_post_send fail");
			return 1;
		}

		dprint(FD_IO, "fio: close information sent success\n");
		rdma_poll_wait(td, IBV_WC_SEND);
	}

	if (rd->is_client == 1)
		rdma_disconnect(rd->cm_id);
	else {
		rdma_disconnect(rd->child_cm_id);
#if 0
		rdma_disconnect(rd->cm_id);
#endif
	}

#if 0
	if (get_next_channel_event(td, rd->cm_channel, RDMA_CM_EVENT_DISCONNECTED) != 0) {
		log_err("fio: wait for RDMA_CM_EVENT_DISCONNECTED\n");
		return 1;
	}
#endif

	ibv_destroy_cq(rd->cq);
	ibv_destroy_qp(rd->qp);

	if (rd->is_client == 1)
		rdma_destroy_id(rd->cm_id);
	else {
		rdma_destroy_id(rd->child_cm_id);
		rdma_destroy_id(rd->cm_id);
	}

	ibv_destroy_comp_channel(rd->channel);
	ibv_dealloc_pd(rd->pd);

	return 0;
}
Exemplo n.º 12
0
Arquivo: ib_md.c Projeto: alinask/ucx
static void uct_ib_md_umr_qp_destroy(uct_ib_md_t *md)
{
#if HAVE_EXP_UMR
    if (md->umr_qp != NULL) {
        ibv_destroy_qp(md->umr_qp);
    }
    if (md->umr_cq != NULL) {
        ibv_destroy_cq(md->umr_cq);
    }
#endif
}
Exemplo n.º 13
0
int __ibv_destroy_qp_1_0(struct ibv_qp_1_0 *qp)
{
	int ret;

	ret = ibv_destroy_qp(qp->real_qp);
	if (ret)
		return ret;

	free(qp);
	return 0;
}
Exemplo n.º 14
0
int BClientContext::destroy_context () {
	if (qp)				TEST_NZ(ibv_destroy_qp (qp));
	if (recv_memory_mr)		TEST_NZ (ibv_dereg_mr (recv_memory_mr));	
	if (lock_result_mr)		TEST_NZ (ibv_dereg_mr (lock_result_mr));
		
	if (cq)						TEST_NZ (ibv_destroy_cq (cq));
	if (pd)						TEST_NZ (ibv_dealloc_pd (pd));
	if (ib_ctx)					TEST_NZ (ibv_close_device (ib_ctx));
	if (sockfd >= 0)			TEST_NZ (close (sockfd));
	
	return 0;
}
Exemplo n.º 15
0
static void uct_rc_verbs_ep_tag_qp_destroy(uct_rc_verbs_ep_t *ep)
{
#if HAVE_IBV_EX_HW_TM
    uct_rc_verbs_iface_t *iface = ucs_derived_of(ep->super.super.super.iface,
                                                 uct_rc_verbs_iface_t);
    if (UCT_RC_VERBS_TM_ENABLED(iface)) {
        if (ibv_destroy_qp(ep->tm_qp)) {
            ucs_warn("failed to destroy TM RNDV QP: %m");
        }
        uct_rc_iface_remove_ep(&iface->super, ep->tm_qp->qp_num);
    }
#endif
}
Exemplo n.º 16
0
static int resources_destroy(struct resources *res)
{
	int rc = 0;

	if (res->qp) {
		if (ibv_destroy_qp(res->qp)) {
			fprintf(stderr, "failed to destroy QP\n");
			rc = 1;
		}
	}

	if (res->mr) {
		if (ibv_dereg_mr(res->mr)) {
			fprintf(stderr, "failed to deregister MR\n");
			rc = 1;
		}
	}

	if (res->buf)
		free(res->buf);

	if (res->cq) {
		if (ibv_destroy_cq(res->cq)) {
			fprintf(stderr, "failed to destroy CQ\n");
			rc = 1;
		}
	}

	if (res->pd) {
		if (ibv_dealloc_pd(res->pd)) {
			fprintf(stderr, "failed to deallocate PD\n");
			rc = 1;
		}
	}

	if (res->ib_ctx) {
		if (ibv_close_device(res->ib_ctx)) {
			fprintf(stderr, "failed to close device context\n");
			rc = 1;
		}
	}

	if (res->sock >= 0) {
		if (close(res->sock)) {
			fprintf(stderr, "failed to close socket\n");
			rc = 1;
		}
	}

	return rc;
}
Exemplo n.º 17
0
void fi_ibv_free_xrc_conn_setup(struct fi_ibv_xrc_ep *ep)
{
	assert(ep->conn_setup);

	if (ep->conn_setup->rsvd_ini_qpn)
		ibv_destroy_qp(ep->conn_setup->rsvd_ini_qpn);
	if (ep->conn_setup->rsvd_tgt_qpn)
		ibv_destroy_qp(ep->conn_setup->rsvd_tgt_qpn);

	free(ep->conn_setup);
	ep->conn_setup = NULL;

	/*Free RDMA CM IDs releasing their associated resources, RDMA CM
	 * is used for connection setup only with XRC */
	if (ep->base_ep.id) {
		rdma_destroy_id(ep->base_ep.id);
		ep->base_ep.id = NULL;
	}
	if (ep->tgt_id) {
		rdma_destroy_id(ep->tgt_id);
		ep->tgt_id = NULL;
	}
}
Exemplo n.º 18
0
static inline int fi_ibv_get_qp_cap(struct ibv_context *ctx,
				    struct fi_info *info)
{
	struct ibv_pd *pd;
	struct ibv_cq *cq;
	struct ibv_qp *qp;
	struct ibv_qp_init_attr init_attr;
	int ret = 0;

	pd = ibv_alloc_pd(ctx);
	if (!pd) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_alloc_pd", errno);
		return -errno;
	}

	cq = ibv_create_cq(ctx, 1, NULL, NULL, 0);
	if (!cq) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_create_cq", errno);
		ret = -errno;
		goto err1;
	}

	memset(&init_attr, 0, sizeof init_attr);
	init_attr.send_cq = cq;
	init_attr.recv_cq = cq;
	init_attr.cap.max_send_wr = verbs_default_tx_size;
	init_attr.cap.max_recv_wr = verbs_default_rx_size;
	init_attr.cap.max_send_sge = verbs_default_tx_iov_limit;
	init_attr.cap.max_recv_sge = verbs_default_rx_iov_limit;
	init_attr.cap.max_inline_data = verbs_default_inline_size;

	init_attr.qp_type = IBV_QPT_RC;

	qp = ibv_create_qp(pd, &init_attr);
	if (!qp) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_create_qp", errno);
		ret = -errno;
		goto err2;
	}

	info->tx_attr->inject_size = init_attr.cap.max_inline_data;

	ibv_destroy_qp(qp);
err2:
	ibv_destroy_cq(cq);
err1:
	ibv_dealloc_pd(pd);

	return ret;
}
Exemplo n.º 19
0
/** ========================================================================= */
static void destroy_sa_qp(struct oib_port *port)
{
    int i;

    // if the user just unregistered trap messages those messages may still
    // be on this list, wait 5 seconds for the thread to handle the response.
    for (i = 0; i < 5000; i++) {    
        if (!LIST_EMPTY(&port->pending_reg_msg_head)) {
            usleep(1000);
        }
        else {
            DBGPRINT("destroy_sa_qp: wait %d ms for LIST_EMPTY\n", i);
            break;
        }
    }

    stop_ud_cq_monitor(port);

    join_port_thread(port);

    /* Free any remaining unregistration messages */
    if (!LIST_EMPTY(&port->pending_reg_msg_head)) {
        OUTPUT_ERROR("Ignoring Pending Notice un-registation requests\n");
        oib_sa_remove_all_pending_reg_msgs(port);
    }

    if (port->sa_ah)
       ibv_destroy_ah(port->sa_ah);

    if (port->sa_qp)
        ibv_destroy_qp(port->sa_qp);

    for (i = 0; i<port->num_userspace_recv_buf; i++)
    	if (port->recv_bufs)
            ibv_dereg_mr(port->recv_bufs[i].mr);

    if (port->sa_qp_pd)
        ibv_dealloc_pd(port->sa_qp_pd);

    if (port->sa_qp_cq)
        ibv_destroy_cq(port->sa_qp_cq);

    if (port->recv_bufs) {
        free(port->recv_bufs);
        port->recv_bufs = NULL;
    }

    if (port->sa_qp_comp_channel)
        ibv_destroy_comp_channel(port->sa_qp_comp_channel);
}
Exemplo n.º 20
0
static void
rdmasniff_cleanup(pcap_t *handle)
{
	struct pcap_rdmasniff *priv = handle->priv;

	ibv_dereg_mr(priv->mr);
	ibv_destroy_flow(priv->flow);
	ibv_destroy_qp(priv->qp);
	ibv_destroy_cq(priv->cq);
	ibv_dealloc_pd(priv->pd);
	ibv_destroy_comp_channel(priv->channel);
	ibv_close_device(priv->context);
	free(priv->oneshot_buffer);

	pcap_cleanup_live_common(handle);
}
Exemplo n.º 21
0
static ucs_status_t uct_ib_mlx5_check_dc(uct_ib_device_t *dev)
{
    ucs_status_t status = UCS_OK;
    struct ibv_context *ctx = dev->ibv_context;
    struct ibv_qp_init_attr_ex qp_attr = {};
    struct mlx5dv_qp_init_attr dv_attr = {};
    struct ibv_pd *pd;
    struct ibv_cq *cq;
    struct ibv_qp *qp;

    pd = ibv_alloc_pd(ctx);
    if (pd == NULL) {
        ucs_error("ibv_alloc_pd() failed: %m");
        return UCS_ERR_IO_ERROR;
    }

    cq = ibv_create_cq(ctx, 1, NULL, NULL, 0);
    if (cq == NULL) {
        ucs_error("ibv_create_cq() failed: %m");
        status = UCS_ERR_IO_ERROR;
        goto err_cq;
    }

    qp_attr.send_cq              = cq;
    qp_attr.recv_cq              = cq;
    qp_attr.cap.max_send_wr      = 1;
    qp_attr.cap.max_send_sge     = 1;
    qp_attr.qp_type              = IBV_QPT_DRIVER;
    qp_attr.comp_mask            = IBV_QP_INIT_ATTR_PD;
    qp_attr.pd                   = pd;

    dv_attr.comp_mask            = MLX5DV_QP_INIT_ATTR_MASK_DC;
    dv_attr.dc_init_attr.dc_type = MLX5DV_DCTYPE_DCI;

    /* create DCI qp successful means DC is supported */
    qp = mlx5dv_create_qp(ctx, &qp_attr, &dv_attr);
    if (qp) {
        ibv_destroy_qp(qp);
        dev->flags |= UCT_IB_DEVICE_FLAG_DC;
    }

    ibv_destroy_cq(cq);
err_cq:
    ibv_dealloc_pd(pd);
    return status;
}
Exemplo n.º 22
0
int
resource_destroy(resource_t *res)
{
    int rc = 0;

    // Delete QP
    if (res->qp && ibv_destroy_qp(res->qp)){
	fprintf(stderr, "failed to destroy QP\n");
	rc = 1;
    }
    // Deregister MR
    if(res->mr_list && res->mr_size > 0){
	int i;
	for(i=0; i<res->mr_size; i++){
	    ibv_dereg_mr(res->mr_list[i]);
	}
	free(res->mr_list);
    }
    if(res->buf){
	free(res->buf);
    }
    // Delete CQ
    if (res->scq && ibv_destroy_cq(res->scq)){
	fprintf(stderr, "failed to destroy SCQ\n");
	rc = 1;
    }
    if (res->rcq && ibv_destroy_cq(res->rcq)){
	fprintf(stderr, "failed to destroy RCQ\n");
	rc = 1;
    }
    if(res->comp_ch && ibv_destroy_comp_channel(res->comp_ch)){
	fprintf(stderr, "failed to destroy Complete CH\n");
	rc = 1;
    }
    // Deallocate PD
    if (res->pd && ibv_dealloc_pd(res->pd)){
	fprintf(stderr, "failed to deallocate PD\n");
	rc = 1;
    }
    if (res->ib_ctx && ibv_close_device(res->ib_ctx)){
	fprintf(stderr, "failed to close device context\n");
	rc = 1;
    }
    return rc;
}
Exemplo n.º 23
0
Arquivo: psoib.c Projeto: JonBau/pscom
void psoib_con_cleanup(psoib_con_info_t *con_info, hca_info_t *hca_info)
{
    if (!hca_info) hca_info = &default_hca;

    list_del_init(&con_info->next_con_info);

    if (con_info->send.bufs.mr) {
	psoib_vapi_free(hca_info, &con_info->send.bufs);
	con_info->send.bufs.mr = 0;
    }
    if (con_info->recv.bufs.mr) {
	psoib_vapi_free(hca_info, &con_info->recv.bufs);
	con_info->recv.bufs.mr = 0;
    }
    if (con_info->qp) {
	ibv_destroy_qp(con_info->qp);
	con_info->qp = 0;
    }
}
Exemplo n.º 24
0
static int destroy_ctx_resources(struct pingpong_context *ctx)  {

	int test_result = 0;

	if (ibv_destroy_qp(ctx->qp)) {
		fprintf(stderr, "failed to destroy QP\n");
		test_result = 1;
	}
	
	if (ibv_destroy_cq(ctx->cq)) {
		fprintf(stderr, "failed to destroy CQ\n");
		test_result = 1;
	}
	
	if (ibv_dereg_mr(ctx->mr)) {
		fprintf(stderr, "failed to deregister MR\n");
		test_result = 1;
	}

	if (ctx->channel) {
		if (ibv_destroy_comp_channel(ctx->channel)) {
			fprintf(stderr, "failed to destroy channel \n");
			test_result = 1;
		}
	}
	
	if (ibv_dealloc_pd(ctx->pd)) {
		fprintf(stderr, "failed to deallocate PD\n");
		test_result = 1;
	}

	if (ibv_close_device(ctx->context)) {
		fprintf(stderr, "failed to close device context\n");
		test_result = 1;
	}

	free(ctx->buf);
	free(ctx);
	free(tstamp);

	return test_result;
}
Exemplo n.º 25
0
static int destroy_ctx_resources(struct pingpong_context *ctx,int num_qps)  {

	int i;
	int test_result = 0;

	for (i = 0; i < num_qps; i++) {
		if (ibv_destroy_qp(ctx->qp[i])) {
			fprintf(stderr, "failed to destroy QP\n");
			test_result = 1;
		}
	}
	
	if (ibv_destroy_cq(ctx->cq)) {
		fprintf(stderr, "failed to destroy CQ\n");
		test_result = 1;
	}
	
	if (ibv_dereg_mr(ctx->mr)) {
		fprintf(stderr, "failed to deregister MR\n");
		test_result = 1;
	}
	
	if (ibv_dealloc_pd(ctx->pd)) {
		fprintf(stderr, "failed to deallocate PD\n");
		test_result = 1;
	}

	if (ibv_close_device(ctx->context)) {
		fprintf(stderr, "failed to close device context\n");
		test_result = 1;
	}

	free(ctx->buf);
	free(ctx->qp);
	free(ctx->scnt);
	free(ctx->ccnt);
	free(ctx);

	return test_result;
}
Exemplo n.º 26
0
void release_resources(void)
{
    int i;
   
    // Destroy the registration cache

    reg_cache_destroy(nprocs);

    for(i = 0; i < nprocs ; i++) {
        if (me != i) {
            if(ibv_destroy_qp(conn.qp[i])) {
                printf("Exiting\n");
                exit(1);
            }
        }
    }
#if 0
    if(ibv_destroy_cq(hca.cq)) {
        fprintf(stderr,"Couldn't destroy cq %s\n",
                ibv_get_device_name(hca.ib_dev));
    }
    if(ibv_dealloc_pd(hca.pd)) {
        fprintf(stderr,"Couldn't free pd %s\n",
                ibv_get_device_name(hca.ib_dev));
    }
#endif

    free(conn.qp);
    free(conn.lid);
    free(conn.qp_num);

    free(rbuf.qp_num);
    free(rbuf.lid);
#if 0
    free(rbuf.rkey); 
    free(rbuf.buf);
#endif
}
/* In case if XRC recv qp was closed and sender still don't know about it
 * we need close the qp, reset the ib_adrr status to CLOSED and start everything
 * from scratch.
 */
static void xoob_restart_connect(mca_btl_base_endpoint_t *endpoint)
{
    BTL_VERBOSE(("Restarting the connection for the endpoint"));
    OPAL_THREAD_LOCK(&endpoint->ib_addr->addr_lock);
    switch (endpoint->ib_addr->status) {
        case MCA_BTL_IB_ADDR_CONNECTED:
            /* so we have the send qp, we just need the recive site.
             * Send request for SRQ numbers */
            BTL_VERBOSE(("Restart The IB addr: sid %" PRIx64 " lid %d"
                         "in MCA_BTL_IB_ADDR_CONNECTED status,"
                         " Changing to MCA_BTL_IB_ADDR_CLOSED and starting from scratch\n",
                         endpoint->ib_addr->subnet_id,endpoint->ib_addr->lid));
            /* Switching back to closed and starting from scratch */
            endpoint->ib_addr->status = MCA_BTL_IB_ADDR_CLOSED;
            /* destroy the qp */
            /* the reciver site was alredy closed so all pending list must be clean ! */
            assert (opal_list_is_empty(&endpoint->qps->no_wqe_pending_frags[0]));
            assert (opal_list_is_empty(&endpoint->qps->no_wqe_pending_frags[1]));
            if(ibv_destroy_qp(endpoint->qps[0].qp->lcl_qp))
                BTL_ERROR(("Failed to destroy QP"));
        case MCA_BTL_IB_ADDR_CLOSED:
        case MCA_BTL_IB_ADDR_CONNECTING:
            BTL_VERBOSE(("Restart The IB addr: sid %" PRIx64 " lid %d"
                         "in MCA_BTL_IB_ADDR_CONNECTING or MCA_BTL_IB_ADDR_CLOSED status,"
                         " starting from scratch\n",
                         endpoint->ib_addr->subnet_id,endpoint->ib_addr->lid));
            OPAL_THREAD_UNLOCK(&endpoint->ib_addr->addr_lock);
            /* xoob_module_start_connect() should automaticly handle all other cases */
            if (OMPI_SUCCESS != xoob_module_start_connect(NULL, endpoint))
                BTL_ERROR(("Failed to restart connection from MCA_BTL_IB_ADDR_CONNECTING/CLOSED"));
            break;
        default :
            BTL_ERROR(("Invalid endpoint status %d", endpoint->ib_addr->status));
            OPAL_THREAD_UNLOCK(&endpoint->ib_addr->addr_lock);
    }
}
Exemplo n.º 28
0
static inline int fi_ibv_get_qp_cap(struct ibv_context *ctx,
				    struct ibv_device_attr *device_attr,
				    struct fi_info *info)
{
	struct ibv_pd *pd;
	struct ibv_cq *cq;
	struct ibv_qp *qp;
	struct ibv_qp_init_attr init_attr;
	int ret = 0;

	pd = ibv_alloc_pd(ctx);
	if (!pd) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_alloc_pd", errno);
		return -errno;
	}

	cq = ibv_create_cq(ctx, 1, NULL, NULL, 0);
	if (!cq) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_create_cq", errno);
		ret = -errno;
		goto err1;
	}

	/* TODO: serialize access to string buffers */
	fi_read_file(FI_CONF_DIR, "def_tx_ctx_size",
			def_tx_ctx_size, sizeof def_tx_ctx_size);
	fi_read_file(FI_CONF_DIR, "def_rx_ctx_size",
			def_rx_ctx_size, sizeof def_rx_ctx_size);
	fi_read_file(FI_CONF_DIR, "def_tx_iov_limit",
			def_tx_iov_limit, sizeof def_tx_iov_limit);
	fi_read_file(FI_CONF_DIR, "def_rx_iov_limit",
			def_rx_iov_limit, sizeof def_rx_iov_limit);
	fi_read_file(FI_CONF_DIR, "def_inject_size",
			def_inject_size, sizeof def_inject_size);

	memset(&init_attr, 0, sizeof init_attr);
	init_attr.send_cq = cq;
	init_attr.recv_cq = cq;
	init_attr.cap.max_send_wr = MIN(atoi(def_tx_ctx_size), device_attr->max_qp_wr);
	init_attr.cap.max_recv_wr = MIN(atoi(def_rx_ctx_size), device_attr->max_qp_wr);
	init_attr.cap.max_send_sge = MIN(atoi(def_tx_iov_limit), device_attr->max_sge);
	init_attr.cap.max_recv_sge = MIN(atoi(def_rx_iov_limit), device_attr->max_sge);
	init_attr.cap.max_inline_data = atoi(def_inject_size);
	init_attr.qp_type = IBV_QPT_RC;

	qp = ibv_create_qp(pd, &init_attr);
	if (!qp) {
		VERBS_INFO_ERRNO(FI_LOG_FABRIC, "ibv_create_qp", errno);
		ret = -errno;
		goto err2;
	}

	info->tx_attr->inject_size	= init_attr.cap.max_inline_data;
	info->tx_attr->iov_limit 	= init_attr.cap.max_send_sge;
	info->tx_attr->size	 	= init_attr.cap.max_send_wr;

	info->rx_attr->iov_limit 	= init_attr.cap.max_recv_sge;
	/*
	 * On some HW ibv_create_qp can increase max_recv_wr value more than
	 * it really supports. So, alignment with device capability is needed.
	 */
	info->rx_attr->size	 	= MIN(init_attr.cap.max_recv_wr,
						device_attr->max_qp_wr);

	ibv_destroy_qp(qp);
err2:
	ibv_destroy_cq(cq);
err1:
	ibv_dealloc_pd(pd);

	return ret;
}
Exemplo n.º 29
0
RDMAChannel::~RDMAChannel() {
  CHECK(!ibv_destroy_qp(qp_)) << "Failed to destroy QP";
}
Exemplo n.º 30
0
int rdma_backend_qp_state_rtr(RdmaBackendDev *backend_dev, RdmaBackendQP *qp,
                              uint8_t qp_type, uint8_t sgid_idx,
                              union ibv_gid *dgid, uint32_t dqpn,
                              uint32_t rq_psn, uint32_t qkey, bool use_qkey)
{
    struct ibv_qp_attr attr = {};
    union ibv_gid ibv_gid = {
        .global.interface_id = dgid->global.interface_id,
        .global.subnet_prefix = dgid->global.subnet_prefix
    };
    int rc, attr_mask;

    attr.qp_state = IBV_QPS_RTR;
    attr_mask = IBV_QP_STATE;

    qp->sgid_idx = sgid_idx;

    switch (qp_type) {
    case IBV_QPT_RC:
        attr.path_mtu               = IBV_MTU_1024;
        attr.dest_qp_num            = dqpn;
        attr.max_dest_rd_atomic     = 1;
        attr.min_rnr_timer          = 12;
        attr.ah_attr.port_num       = backend_dev->port_num;
        attr.ah_attr.is_global      = 1;
        attr.ah_attr.grh.hop_limit  = 1;
        attr.ah_attr.grh.dgid       = ibv_gid;
        attr.ah_attr.grh.sgid_index = qp->sgid_idx;
        attr.rq_psn                 = rq_psn;

        attr_mask |= IBV_QP_AV | IBV_QP_PATH_MTU | IBV_QP_DEST_QPN |
                     IBV_QP_RQ_PSN | IBV_QP_MAX_DEST_RD_ATOMIC |
                     IBV_QP_MIN_RNR_TIMER;

        trace_rdma_backend_rc_qp_state_rtr(qp->ibqp->qp_num,
                                           be64_to_cpu(ibv_gid.global.
                                                       subnet_prefix),
                                           be64_to_cpu(ibv_gid.global.
                                                       interface_id),
                                           qp->sgid_idx, dqpn, rq_psn);
        break;

    case IBV_QPT_UD:
        if (use_qkey) {
            attr.qkey = qkey;
            attr_mask |= IBV_QP_QKEY;
        }
        trace_rdma_backend_ud_qp_state_rtr(qp->ibqp->qp_num, use_qkey ? qkey :
                                           0);
        break;
    }

    rc = ibv_modify_qp(qp->ibqp, &attr, attr_mask);
    if (rc) {
        rdma_error_report("ibv_modify_qp fail, rc=%d, errno=%d", rc, errno);
        return -EIO;
    }

    return 0;
}

int rdma_backend_qp_state_rts(RdmaBackendQP *qp, uint8_t qp_type,
                              uint32_t sq_psn, uint32_t qkey, bool use_qkey)
{
    struct ibv_qp_attr attr = {};
    int rc, attr_mask;

    attr.qp_state = IBV_QPS_RTS;
    attr.sq_psn = sq_psn;
    attr_mask = IBV_QP_STATE | IBV_QP_SQ_PSN;

    switch (qp_type) {
    case IBV_QPT_RC:
        attr.timeout       = 14;
        attr.retry_cnt     = 7;
        attr.rnr_retry     = 7;
        attr.max_rd_atomic = 1;

        attr_mask |= IBV_QP_TIMEOUT | IBV_QP_RETRY_CNT | IBV_QP_RNR_RETRY |
                     IBV_QP_MAX_QP_RD_ATOMIC;
        trace_rdma_backend_rc_qp_state_rts(qp->ibqp->qp_num, sq_psn);
        break;

    case IBV_QPT_UD:
        if (use_qkey) {
            attr.qkey = qkey;
            attr_mask |= IBV_QP_QKEY;
        }
        trace_rdma_backend_ud_qp_state_rts(qp->ibqp->qp_num, sq_psn,
                                           use_qkey ? qkey : 0);
        break;
    }

    rc = ibv_modify_qp(qp->ibqp, &attr, attr_mask);
    if (rc) {
        rdma_error_report("ibv_modify_qp fail, rc=%d, errno=%d", rc, errno);
        return -EIO;
    }

    return 0;
}

int rdma_backend_query_qp(RdmaBackendQP *qp, struct ibv_qp_attr *attr,
                          int attr_mask, struct ibv_qp_init_attr *init_attr)
{
    if (!qp->ibqp) {
        attr->qp_state = IBV_QPS_RTS;
        return 0;
    }

    return ibv_query_qp(qp->ibqp, attr, attr_mask, init_attr);
}

void rdma_backend_destroy_qp(RdmaBackendQP *qp, RdmaDeviceResources *dev_res)
{
    if (qp->ibqp) {
        ibv_destroy_qp(qp->ibqp);
    }
    g_slist_foreach(qp->cqe_ctx_list.list, free_cqe_ctx, dev_res);
    rdma_protected_gslist_destroy(&qp->cqe_ctx_list);
}

int rdma_backend_create_srq(RdmaBackendSRQ *srq, RdmaBackendPD *pd,
                            uint32_t max_wr, uint32_t max_sge,
                            uint32_t srq_limit)
{
    struct ibv_srq_init_attr srq_init_attr = {};

    srq_init_attr.attr.max_wr = max_wr;
    srq_init_attr.attr.max_sge = max_sge;
    srq_init_attr.attr.srq_limit = srq_limit;

    srq->ibsrq = ibv_create_srq(pd->ibpd, &srq_init_attr);
    if (!srq->ibsrq) {
        rdma_error_report("ibv_create_srq failed, errno=%d", errno);
        return -EIO;
    }

    rdma_protected_gslist_init(&srq->cqe_ctx_list);

    return 0;
}

int rdma_backend_query_srq(RdmaBackendSRQ *srq, struct ibv_srq_attr *srq_attr)
{
    if (!srq->ibsrq) {
        return -EINVAL;
    }

    return ibv_query_srq(srq->ibsrq, srq_attr);
}

int rdma_backend_modify_srq(RdmaBackendSRQ *srq, struct ibv_srq_attr *srq_attr,
                int srq_attr_mask)
{
    if (!srq->ibsrq) {
        return -EINVAL;
    }

    return ibv_modify_srq(srq->ibsrq, srq_attr, srq_attr_mask);
}

void rdma_backend_destroy_srq(RdmaBackendSRQ *srq, RdmaDeviceResources *dev_res)
{
    if (srq->ibsrq) {
        ibv_destroy_srq(srq->ibsrq);
    }
    g_slist_foreach(srq->cqe_ctx_list.list, free_cqe_ctx, dev_res);
    rdma_protected_gslist_destroy(&srq->cqe_ctx_list);
}

#define CHK_ATTR(req, dev, member, fmt) ({ \
    trace_rdma_check_dev_attr(#member, dev.member, req->member); \
    if (req->member > dev.member) { \
        rdma_warn_report("%s = "fmt" is higher than host device capability "fmt, \
                         #member, req->member, dev.member); \
        req->member = dev.member; \
    } \
})

static int init_device_caps(RdmaBackendDev *backend_dev,
                            struct ibv_device_attr *dev_attr)
{
    struct ibv_device_attr bk_dev_attr;
    int rc;

    rc = ibv_query_device(backend_dev->context, &bk_dev_attr);
    if (rc) {
        rdma_error_report("ibv_query_device fail, rc=%d, errno=%d", rc, errno);
        return -EIO;
    }

    dev_attr->max_sge = MAX_SGE;
    dev_attr->max_srq_sge = MAX_SGE;

    CHK_ATTR(dev_attr, bk_dev_attr, max_mr_size, "%" PRId64);
    CHK_ATTR(dev_attr, bk_dev_attr, max_qp, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_sge, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_cq, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_mr, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_pd, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_qp_rd_atom, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_qp_init_rd_atom, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_ah, "%d");
    CHK_ATTR(dev_attr, bk_dev_attr, max_srq, "%d");

    return 0;
}

static inline void build_mad_hdr(struct ibv_grh *grh, union ibv_gid *sgid,
                                 union ibv_gid *my_gid, int paylen)
{
    grh->paylen = htons(paylen);
    grh->sgid = *sgid;
    grh->dgid = *my_gid;
}