|
@@ -568,6 +568,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
|
struct ib_device_attr *devattr = &ia->ri_devattr;
|
|
struct ib_device_attr *devattr = &ia->ri_devattr;
|
|
struct ib_cq *sendcq, *recvcq;
|
|
struct ib_cq *sendcq, *recvcq;
|
|
struct ib_cq_init_attr cq_attr = {};
|
|
struct ib_cq_init_attr cq_attr = {};
|
|
|
|
+ unsigned int max_qp_wr;
|
|
int rc, err;
|
|
int rc, err;
|
|
|
|
|
|
if (devattr->max_sge < RPCRDMA_MAX_IOVS) {
|
|
if (devattr->max_sge < RPCRDMA_MAX_IOVS) {
|
|
@@ -576,18 +577,27 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (devattr->max_qp_wr <= RPCRDMA_BACKWARD_WRS) {
|
|
|
|
+ dprintk("RPC: %s: insufficient wqe's available\n",
|
|
|
|
+ __func__);
|
|
|
|
+ return -ENOMEM;
|
|
|
|
+ }
|
|
|
|
+ max_qp_wr = devattr->max_qp_wr - RPCRDMA_BACKWARD_WRS;
|
|
|
|
+
|
|
/* check provider's send/recv wr limits */
|
|
/* check provider's send/recv wr limits */
|
|
- if (cdata->max_requests > devattr->max_qp_wr)
|
|
|
|
- cdata->max_requests = devattr->max_qp_wr;
|
|
|
|
|
|
+ if (cdata->max_requests > max_qp_wr)
|
|
|
|
+ cdata->max_requests = max_qp_wr;
|
|
|
|
|
|
ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall;
|
|
ep->rep_attr.event_handler = rpcrdma_qp_async_error_upcall;
|
|
ep->rep_attr.qp_context = ep;
|
|
ep->rep_attr.qp_context = ep;
|
|
ep->rep_attr.srq = NULL;
|
|
ep->rep_attr.srq = NULL;
|
|
ep->rep_attr.cap.max_send_wr = cdata->max_requests;
|
|
ep->rep_attr.cap.max_send_wr = cdata->max_requests;
|
|
|
|
+ ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
|
|
rc = ia->ri_ops->ro_open(ia, ep, cdata);
|
|
rc = ia->ri_ops->ro_open(ia, ep, cdata);
|
|
if (rc)
|
|
if (rc)
|
|
return rc;
|
|
return rc;
|
|
ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
|
|
ep->rep_attr.cap.max_recv_wr = cdata->max_requests;
|
|
|
|
+ ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
|
|
ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_IOVS;
|
|
ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_IOVS;
|
|
ep->rep_attr.cap.max_recv_sge = 1;
|
|
ep->rep_attr.cap.max_recv_sge = 1;
|
|
ep->rep_attr.cap.max_inline_data = 0;
|
|
ep->rep_attr.cap.max_inline_data = 0;
|