static struct svc_rdma_fastreg_mr *rdma_alloc_frmr(struct svcxprt_rdma *xprt) { struct ib_mr *mr; struct scatterlist *sg; struct svc_rdma_fastreg_mr *frmr; u32 num_sg; frmr = kmalloc(sizeof(*frmr), GFP_KERNEL); if (!frmr) goto err; num_sg = min_t(u32, RPCSVC_MAXPAGES, xprt->sc_frmr_pg_list_len); mr = ib_alloc_mr(xprt->sc_pd, IB_MR_TYPE_MEM_REG, num_sg); if (IS_ERR(mr)) goto err_free_frmr; sg = kcalloc(RPCSVC_MAXPAGES, sizeof(*sg), GFP_KERNEL); if (!sg) goto err_free_mr; sg_init_table(sg, RPCSVC_MAXPAGES); frmr->mr = mr; frmr->sg = sg; INIT_LIST_HEAD(&frmr->frmr_list); return frmr; err_free_mr: ib_dereg_mr(mr); err_free_frmr: kfree(frmr); err: return ERR_PTR(-ENOMEM); }
static int __frwr_reset_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r) { struct rpcrdma_frmr *f = &r->frmr; int rc; rc = ib_dereg_mr(f->fr_mr); if (rc) { pr_warn("rpcrdma: ib_dereg_mr status %d, frwr %p orphaned\n", rc, r); return rc; } f->fr_mr = ib_alloc_mr(ia->ri_pd, IB_MR_TYPE_MEM_REG, ia->ri_max_frmr_depth); if (IS_ERR(f->fr_mr)) { pr_warn("rpcrdma: ib_alloc_mr status %ld, frwr %p orphaned\n", PTR_ERR(f->fr_mr), r); return PTR_ERR(f->fr_mr); } dprintk("RPC: %s: recovered FRMR %p\n", __func__, f); f->fr_state = FRMR_IS_INVALID; return 0; }
static int frwr_op_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mw *r) { unsigned int depth = ia->ri_max_frmr_depth; struct rpcrdma_frmr *f = &r->frmr; int rc; f->fr_mr = ib_alloc_mr(ia->ri_pd, IB_MR_TYPE_MEM_REG, depth); if (IS_ERR(f->fr_mr)) goto out_mr_err; r->mw_sg = kcalloc(depth, sizeof(*r->mw_sg), GFP_KERNEL); if (!r->mw_sg) goto out_list_err; sg_init_table(r->mw_sg, depth); init_completion(&f->fr_linv_done); return 0; out_mr_err: rc = PTR_ERR(f->fr_mr); dprintk("RPC: %s: ib_alloc_mr status %i\n", __func__, rc); return rc; out_list_err: rc = -ENOMEM; dprintk("RPC: %s: sg allocation failure\n", __func__); ib_dereg_mr(f->fr_mr); return rc; }
static int __frwr_mr_reset(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr) { struct rpcrdma_frwr *frwr = &mr->frwr; int rc; rc = ib_dereg_mr(frwr->fr_mr); if (rc) { pr_warn("rpcrdma: ib_dereg_mr status %d, frwr %p orphaned\n", rc, mr); return rc; } frwr->fr_mr = ib_alloc_mr(ia->ri_pd, ia->ri_mrtype, ia->ri_max_frwr_depth); if (IS_ERR(frwr->fr_mr)) { pr_warn("rpcrdma: ib_alloc_mr status %ld, frwr %p orphaned\n", PTR_ERR(frwr->fr_mr), mr); return PTR_ERR(frwr->fr_mr); } dprintk("RPC: %s: recovered FRWR %p\n", __func__, frwr); frwr->fr_state = FRWR_IS_INVALID; return 0; }
static struct rds_ib_mr *rds_ib_alloc_frmr(struct rds_ib_device *rds_ibdev, int npages) { struct rds_ib_mr_pool *pool; struct rds_ib_mr *ibmr = NULL; struct rds_ib_frmr *frmr; int err = 0; if (npages <= RDS_MR_8K_MSG_SIZE) pool = rds_ibdev->mr_8k_pool; else pool = rds_ibdev->mr_1m_pool; ibmr = rds_ib_try_reuse_ibmr(pool); if (ibmr) return ibmr; ibmr = kzalloc_node(sizeof(*ibmr), GFP_KERNEL, rdsibdev_to_node(rds_ibdev)); if (!ibmr) { err = -ENOMEM; goto out_no_cigar; } frmr = &ibmr->u.frmr; frmr->mr = ib_alloc_mr(rds_ibdev->pd, IB_MR_TYPE_MEM_REG, pool->fmr_attr.max_pages); if (IS_ERR(frmr->mr)) { pr_warn("RDS/IB: %s failed to allocate MR", __func__); goto out_no_cigar; } ibmr->pool = pool; if (pool->pool_type == RDS_IB_MR_8K_POOL) rds_ib_stats_inc(s_ib_rdma_mr_8k_alloc); else rds_ib_stats_inc(s_ib_rdma_mr_1m_alloc); if (atomic_read(&pool->item_count) > pool->max_items_soft) pool->max_items_soft = pool->max_items; frmr->fr_state = FRMR_IS_FREE; return ibmr; out_no_cigar: kfree(ibmr); atomic_dec(&pool->item_count); return ERR_PTR(err); }