#include <linux/workqueue.h>
 #include <rdma/ib_verbs.h>
 #include <rdma/rdma_cm.h>
+#include <rdma/rw.h>
 #include <linux/sunrpc/svc_rdma.h>
 #include <linux/export.h>
 #include "xprt_rdma.h"
        struct ib_qp_init_attr qp_attr;
        struct ib_device *dev;
        struct sockaddr *sap;
-       unsigned int i;
+       unsigned int i, ctxts;
        int ret = 0;
 
        listen_rdma = container_of(xprt, struct svcxprt_rdma, sc_xprt);
                newxprt->sc_max_bc_requests = 2;
        }
        newxprt->sc_fc_credits = cpu_to_be32(newxprt->sc_max_requests);
-       newxprt->sc_sq_depth = newxprt->sc_rq_depth;
+       ctxts = rdma_rw_mr_factor(dev, newxprt->sc_port_num, RPCSVC_MAXPAGES);
+       ctxts *= newxprt->sc_max_requests;
+       newxprt->sc_sq_depth = newxprt->sc_rq_depth + ctxts;
+       if (newxprt->sc_sq_depth > dev->attrs.max_qp_wr) {
+               pr_warn("svcrdma: reducing send depth to %d\n",
+                       dev->attrs.max_qp_wr);
+               newxprt->sc_sq_depth = dev->attrs.max_qp_wr;
+       }
        atomic_set(&newxprt->sc_sq_avail, newxprt->sc_sq_depth);
 
        if (!svc_rdma_prealloc_ctxts(newxprt))
        qp_attr.event_handler = qp_event_handler;
        qp_attr.qp_context = &newxprt->sc_xprt;
        qp_attr.port_num = newxprt->sc_port_num;
-       qp_attr.cap.max_rdma_ctxs = newxprt->sc_max_requests;
-       qp_attr.cap.max_send_wr = newxprt->sc_sq_depth;
+       qp_attr.cap.max_rdma_ctxs = ctxts;
+       qp_attr.cap.max_send_wr = newxprt->sc_sq_depth - ctxts;
        qp_attr.cap.max_recv_wr = newxprt->sc_rq_depth;
        qp_attr.cap.max_send_sge = newxprt->sc_max_sge;
        qp_attr.cap.max_recv_sge = newxprt->sc_max_sge;
        dprintk("    remote address  : %pIS:%u\n", sap, rpc_get_port(sap));
        dprintk("    max_sge         : %d\n", newxprt->sc_max_sge);
        dprintk("    sq_depth        : %d\n", newxprt->sc_sq_depth);
+       dprintk("    rdma_rw_ctxs    : %d\n", ctxts);
        dprintk("    max_requests    : %d\n", newxprt->sc_max_requests);
        dprintk("    ord             : %d\n", newxprt->sc_ord);