static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, u32 max_num_sg, struct ib_udata *udata) { struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_mem *mr; int err; if (mr_type != IB_MR_TYPE_MEM_REG) return ERR_PTR(-EINVAL); mr = rxe_alloc(&rxe->mr_pool); if (!mr) { err = -ENOMEM; goto err1; } rxe_add_index(mr); rxe_add_ref(pd); err = rxe_mem_init_fast(pd, max_num_sg, mr); if (err) goto err2; return &mr->ibmr; err2: rxe_drop_ref(pd); rxe_drop_index(mr); rxe_drop_ref(mr); err1: return ERR_PTR(err); }
static struct ib_mr *rxe_get_dma_mr(struct ib_pd *ibpd, int access) { struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_mem *mr; int err; mr = rxe_alloc(&rxe->mr_pool); if (!mr) { err = -ENOMEM; goto err1; } rxe_add_index(mr); rxe_add_ref(pd); err = rxe_mem_init_dma(pd, access, mr); if (err) goto err2; return &mr->ibmr; err2: rxe_drop_ref(pd); rxe_drop_index(mr); rxe_drop_ref(mr); err1: return ERR_PTR(err); }
static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, u64 start, u64 length, u64 iova, int access, struct ib_udata *udata) { int err; struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_mem *mr; mr = rxe_alloc(&rxe->mr_pool); if (!mr) { err = -ENOMEM; goto err2; } rxe_add_index(mr); rxe_add_ref(pd); err = rxe_mem_init_user(pd, start, length, iova, access, udata, mr); if (err) goto err3; return &mr->ibmr; err3: rxe_drop_ref(pd); rxe_drop_index(mr); rxe_drop_ref(mr); err2: return ERR_PTR(err); }
static struct ib_cq *rxe_create_cq(struct ib_device *dev, const struct ib_cq_init_attr *attr, struct ib_ucontext *context, struct ib_udata *udata) { int err; struct rxe_dev *rxe = to_rdev(dev); struct rxe_cq *cq; if (attr->flags) return ERR_PTR(-EINVAL); err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector, udata); if (err) goto err1; cq = rxe_alloc(&rxe->cq_pool); if (!cq) { err = -ENOMEM; goto err1; } err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, context, udata); if (err) goto err2; return &cq->ibcq; err2: rxe_drop_ref(cq); err1: return ERR_PTR(err); }
static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd, struct ib_ah_attr *attr) { int err; struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_ah *ah; err = rxe_av_chk_attr(rxe, attr); if (err) goto err1; ah = rxe_alloc(&rxe->ah_pool); if (!ah) { err = -ENOMEM; goto err1; } rxe_add_ref(pd); ah->pd = pd; err = rxe_init_av(rxe, attr, &ah->av); if (err) goto err2; return &ah->ibah; err2: rxe_drop_ref(pd); rxe_drop_ref(ah); err1: return ERR_PTR(err); }
static struct ib_ucontext *rxe_alloc_ucontext(struct ib_device *dev, struct ib_udata *udata) { struct rxe_dev *rxe = to_rdev(dev); struct rxe_ucontext *uc; uc = rxe_alloc(&rxe->uc_pool); return uc ? &uc->ibuc : ERR_PTR(-ENOMEM); }
static struct ib_pd *rxe_alloc_pd(struct ib_device *dev, struct ib_ucontext *context, struct ib_udata *udata) { struct rxe_dev *rxe = to_rdev(dev); struct rxe_pd *pd; pd = rxe_alloc(&rxe->pd_pool); return pd ? &pd->ibpd : ERR_PTR(-ENOMEM); }
static struct ib_qp *rxe_create_qp(struct ib_pd *ibpd, struct ib_qp_init_attr *init, struct ib_udata *udata) { int err; struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_qp *qp; struct rxe_create_qp_resp __user *uresp = NULL; if (udata) { if (udata->outlen < sizeof(*uresp)) return ERR_PTR(-EINVAL); uresp = udata->outbuf; } err = rxe_qp_chk_init(rxe, init); if (err) goto err1; qp = rxe_alloc(&rxe->qp_pool); if (!qp) { err = -ENOMEM; goto err1; } if (udata) { if (udata->inlen) { err = -EINVAL; goto err2; } qp->is_user = 1; } rxe_add_index(qp); err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibpd, udata); if (err) goto err3; return &qp->ibqp; err3: rxe_drop_index(qp); err2: rxe_drop_ref(qp); err1: return ERR_PTR(err); }
static struct ib_cq *rxe_create_cq(struct ib_device *dev, const struct ib_cq_init_attr *attr, struct ib_udata *udata) { int err; struct rxe_dev *rxe = to_rdev(dev); struct rxe_cq *cq; struct rxe_create_cq_resp __user *uresp = NULL; if (udata) { if (udata->outlen < sizeof(*uresp)) return ERR_PTR(-EINVAL); uresp = udata->outbuf; } if (attr->flags) return ERR_PTR(-EINVAL); err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector); if (err) goto err1; cq = rxe_alloc(&rxe->cq_pool); if (!cq) { err = -ENOMEM; goto err1; } err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, udata, uresp); if (err) goto err2; return &cq->ibcq; err2: rxe_drop_ref(cq); err1: return ERR_PTR(err); }
static struct ib_srq *rxe_create_srq(struct ib_pd *ibpd, struct ib_srq_init_attr *init, struct ib_udata *udata) { int err; struct rxe_dev *rxe = to_rdev(ibpd->device); struct rxe_pd *pd = to_rpd(ibpd); struct rxe_srq *srq; struct ib_ucontext *context = udata ? ibpd->uobject->context : NULL; err = rxe_srq_chk_attr(rxe, NULL, &init->attr, IB_SRQ_INIT_MASK); if (err) goto err1; srq = rxe_alloc(&rxe->srq_pool); if (!srq) { err = -ENOMEM; goto err1; } rxe_add_index(srq); rxe_add_ref(pd); srq->pd = pd; err = rxe_srq_from_init(rxe, srq, init, context, udata); if (err) goto err2; return &srq->ibsrq; err2: rxe_drop_ref(pd); rxe_drop_index(srq); rxe_drop_ref(srq); err1: return ERR_PTR(err); }