struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt) { struct svc_rdma_op_ctxt *ctxt = NULL; spin_lock(&xprt->sc_ctxt_lock); xprt->sc_ctxt_used++; if (list_empty(&xprt->sc_ctxts)) goto out_empty; ctxt = list_first_entry(&xprt->sc_ctxts, struct svc_rdma_op_ctxt, list); list_del(&ctxt->list); spin_unlock(&xprt->sc_ctxt_lock); out: ctxt->count = 0; ctxt->mapped_sges = 0; return ctxt; out_empty: /* Either pre-allocation missed the mark, or send * queue accounting is broken. */ spin_unlock(&xprt->sc_ctxt_lock); ctxt = alloc_ctxt(xprt, GFP_NOIO); if (ctxt) goto out; spin_lock(&xprt->sc_ctxt_lock); xprt->sc_ctxt_used--; spin_unlock(&xprt->sc_ctxt_lock); WARN_ONCE(1, "svcrdma: empty RDMA ctxt list?\n"); return NULL; }
static bool svc_rdma_prealloc_ctxts(struct svcxprt_rdma *xprt) { unsigned int i; /* Each RPC/RDMA credit can consume a number of send * and receive WQEs. One ctxt is allocated for each. */ i = xprt->sc_sq_depth + xprt->sc_rq_depth; while (i--) { struct svc_rdma_op_ctxt *ctxt; ctxt = alloc_ctxt(xprt, GFP_KERNEL); if (!ctxt) { dprintk("svcrdma: No memory for RDMA ctxt\n"); return false; } list_add(&ctxt->free, &xprt->sc_ctxts); } return true; }
static bool svc_rdma_prealloc_ctxts(struct svcxprt_rdma *xprt) { unsigned int i; /* Each RPC/RDMA credit can consume one Receive and * one Send WQE at the same time. */ i = xprt->sc_sq_depth + xprt->sc_rq_depth; while (i--) { struct svc_rdma_op_ctxt *ctxt; ctxt = alloc_ctxt(xprt, GFP_KERNEL); if (!ctxt) { dprintk("svcrdma: No memory for RDMA ctxt\n"); return false; } list_add(&ctxt->list, &xprt->sc_ctxts); } return true; }