예제 #1
0
파일: ibsendtrap.c 프로젝트: 2asoft/freebsd
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(&notice, 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, &notice));
}
예제 #2
0
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);
}