static int send_144_node_desc_update(void) { ib_portid_t sm_port; ib_portid_t selfportid; int selfport; ib_rpc_t trap_rpc; ib_mad_notice_attr_t notice; if (ib_resolve_self(&selfportid, &selfport, NULL)) IBERROR("can't resolve self"); if (ib_resolve_smlid(&sm_port, 0)) IBERROR("can't resolve SM destination port"); memset(&trap_rpc, 0, sizeof(trap_rpc)); trap_rpc.mgtclass = IB_SMI_CLASS; trap_rpc.method = IB_MAD_METHOD_TRAP; trap_rpc.trid = mad_trid(); trap_rpc.attr.id = NOTICE; trap_rpc.datasz = IB_SMP_DATA_SIZE; trap_rpc.dataoffs = IB_SMP_DATA_OFFS; memset(¬ice, 0, sizeof(notice)); notice.generic_type = 0x80 | IB_NOTICE_TYPE_INFO; notice.g_or_v.generic.prod_type_lsb = cl_hton16(IB_NODE_TYPE_CA); notice.g_or_v.generic.trap_num = cl_hton16(144); notice.issuer_lid = cl_hton16(selfportid.lid); notice.data_details.ntc_144.lid = cl_hton16(selfportid.lid); notice.data_details.ntc_144.local_changes = TRAP_144_MASK_OTHER_LOCAL_CHANGES; notice.data_details.ntc_144.change_flgs = TRAP_144_MASK_NODE_DESCRIPTION_CHANGE; return (mad_send(&trap_rpc, &sm_port, NULL, ¬ice)); }
void rdma_backend_post_send(RdmaBackendDev *backend_dev, RdmaBackendQP *qp, uint8_t qp_type, struct ibv_sge *sge, uint32_t num_sge, uint8_t sgid_idx, union ibv_gid *sgid, union ibv_gid *dgid, uint32_t dqpn, uint32_t dqkey, void *ctx) { BackendCtx *bctx; struct ibv_sge new_sge[MAX_SGE]; uint32_t bctx_id; int rc; struct ibv_send_wr wr = {}, *bad_wr; if (!qp->ibqp) { /* This field is not initialized for QP0 and QP1 */ if (qp_type == IBV_QPT_SMI) { rdma_error_report("Got QP0 request"); complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_QP0, ctx); } else if (qp_type == IBV_QPT_GSI) { rc = mad_send(backend_dev, sgid_idx, sgid, sge, num_sge); if (rc) { complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_MAD_SEND, ctx); backend_dev->rdma_dev_res->stats.mad_tx_err++; } else { complete_work(IBV_WC_SUCCESS, 0, ctx); backend_dev->rdma_dev_res->stats.mad_tx++; } } return; } bctx = g_malloc0(sizeof(*bctx)); bctx->up_ctx = ctx; bctx->backend_qp = qp; rc = rdma_rm_alloc_cqe_ctx(backend_dev->rdma_dev_res, &bctx_id, bctx); if (unlikely(rc)) { complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_NOMEM, ctx); goto err_free_bctx; } rdma_protected_gslist_append_int32(&qp->cqe_ctx_list, bctx_id); rc = build_host_sge_array(backend_dev->rdma_dev_res, new_sge, sge, num_sge, &backend_dev->rdma_dev_res->stats.tx_len); if (rc) { complete_work(IBV_WC_GENERAL_ERR, rc, ctx); goto err_dealloc_cqe_ctx; } if (qp_type == IBV_QPT_UD) { wr.wr.ud.ah = create_ah(backend_dev, qp->ibpd, sgid_idx, dgid); if (!wr.wr.ud.ah) { complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_FAIL_BACKEND, ctx); goto err_dealloc_cqe_ctx; } wr.wr.ud.remote_qpn = dqpn; wr.wr.ud.remote_qkey = dqkey; } wr.num_sge = num_sge; wr.opcode = IBV_WR_SEND; wr.send_flags = IBV_SEND_SIGNALED; wr.sg_list = new_sge; wr.wr_id = bctx_id; rc = ibv_post_send(qp->ibqp, &wr, &bad_wr); if (rc) { rdma_error_report("ibv_post_send fail, qpn=0x%x, rc=%d, errno=%d", qp->ibqp->qp_num, rc, errno); complete_work(IBV_WC_GENERAL_ERR, VENDOR_ERR_FAIL_BACKEND, ctx); goto err_dealloc_cqe_ctx; } atomic_inc(&backend_dev->rdma_dev_res->stats.missing_cqe); backend_dev->rdma_dev_res->stats.tx++; return; err_dealloc_cqe_ctx: backend_dev->rdma_dev_res->stats.tx_err++; rdma_rm_dealloc_cqe_ctx(backend_dev->rdma_dev_res, bctx_id); err_free_bctx: g_free(bctx); }