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; }
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); }
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; }
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); }
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; }
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; }
/* destroy ud context */ void mv2_ud_destroy_ctx (mv2_ud_ctx_t *ctx) { if (ctx->qp) { ibv_destroy_qp(ctx->qp); } MPIU_Free(ctx); }
/* * 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; }
int rd_close_qp(CONNECTION *con) { if (con->qp) ibv_destroy_qp(con->qp); return 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; }
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; }
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 }
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; }
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; }
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 }
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; }
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; } }
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; }
/** ========================================================================= */ 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); }
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); }
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; }
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; }
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; } }
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; }
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; }
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); } }
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; }
RDMAChannel::~RDMAChannel() { CHECK(!ibv_destroy_qp(qp_)) << "Failed to destroy QP"; }
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; }