svcrdma: remove rdma_create_qp() failure recovery logic
[linux-2.6-block.git] / net / sunrpc / xprtrdma / svc_rdma_transport.c
index 02db8d9cc994163b876f84b4cc5cdf0e39b5ebc0..374feb44afeacefd7c4f49fea3839b25fd0ba7c4 100644 (file)
@@ -1,4 +1,5 @@
 /*
+ * Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved.
  * Copyright (c) 2005-2007 Network Appliance, Inc. All rights reserved.
  *
  * This software is available to you under a choice of one of two
@@ -91,6 +92,7 @@ struct svc_xprt_class svc_rdma_class = {
        .xcl_owner = THIS_MODULE,
        .xcl_ops = &svc_rdma_ops,
        .xcl_max_payload = RPCSVC_MAXPAYLOAD_TCP,
+       .xcl_ident = XPRT_TRANSPORT_RDMA,
 };
 
 struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt)
@@ -162,7 +164,6 @@ struct svc_rdma_req_map *svc_rdma_get_req_map(void)
                schedule_timeout_uninterruptible(msecs_to_jiffies(500));
        }
        map->count = 0;
-       map->frmr = NULL;
        return map;
 }
 
@@ -338,22 +339,21 @@ static void process_context(struct svcxprt_rdma *xprt,
 
        switch (ctxt->wr_op) {
        case IB_WR_SEND:
-               if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags))
-                       svc_rdma_put_frmr(xprt, ctxt->frmr);
+               BUG_ON(ctxt->frmr);
                svc_rdma_put_context(ctxt, 1);
                break;
 
        case IB_WR_RDMA_WRITE:
+               BUG_ON(ctxt->frmr);
                svc_rdma_put_context(ctxt, 0);
                break;
 
        case IB_WR_RDMA_READ:
        case IB_WR_RDMA_READ_WITH_INV:
+               svc_rdma_put_frmr(xprt, ctxt->frmr);
                if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) {
                        struct svc_rdma_op_ctxt *read_hdr = ctxt->read_hdr;
                        BUG_ON(!read_hdr);
-                       if (test_bit(RDMACTXT_F_FAST_UNREG, &ctxt->flags))
-                               svc_rdma_put_frmr(xprt, ctxt->frmr);
                        spin_lock_bh(&xprt->sc_rq_dto_lock);
                        set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags);
                        list_add_tail(&read_hdr->dto_q,
@@ -365,6 +365,7 @@ static void process_context(struct svcxprt_rdma *xprt,
                break;
 
        default:
+               BUG_ON(1);
                printk(KERN_ERR "svcrdma: unexpected completion type, "
                       "opcode=%d\n",
                       ctxt->wr_op);
@@ -380,29 +381,42 @@ static void process_context(struct svcxprt_rdma *xprt,
 static void sq_cq_reap(struct svcxprt_rdma *xprt)
 {
        struct svc_rdma_op_ctxt *ctxt = NULL;
-       struct ib_wc wc;
+       struct ib_wc wc_a[6];
+       struct ib_wc *wc;
        struct ib_cq *cq = xprt->sc_sq_cq;
        int ret;
 
+       memset(wc_a, 0, sizeof(wc_a));
+
        if (!test_and_clear_bit(RDMAXPRT_SQ_PENDING, &xprt->sc_flags))
                return;
 
        ib_req_notify_cq(xprt->sc_sq_cq, IB_CQ_NEXT_COMP);
        atomic_inc(&rdma_stat_sq_poll);
-       while ((ret = ib_poll_cq(cq, 1, &wc)) > 0) {
-               if (wc.status != IB_WC_SUCCESS)
-                       /* Close the transport */
-                       set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
+       while ((ret = ib_poll_cq(cq, ARRAY_SIZE(wc_a), wc_a)) > 0) {
+               int i;
 
-               /* Decrement used SQ WR count */
-               atomic_dec(&xprt->sc_sq_count);
-               wake_up(&xprt->sc_send_wait);
+               for (i = 0; i < ret; i++) {
+                       wc = &wc_a[i];
+                       if (wc->status != IB_WC_SUCCESS) {
+                               dprintk("svcrdma: sq wc err status %d\n",
+                                       wc->status);
 
-               ctxt = (struct svc_rdma_op_ctxt *)(unsigned long)wc.wr_id;
-               if (ctxt)
-                       process_context(xprt, ctxt);
+                               /* Close the transport */
+                               set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags);
+                       }
 
-               svc_xprt_put(&xprt->sc_xprt);
+                       /* Decrement used SQ WR count */
+                       atomic_dec(&xprt->sc_sq_count);
+                       wake_up(&xprt->sc_send_wait);
+
+                       ctxt = (struct svc_rdma_op_ctxt *)
+                               (unsigned long)wc->wr_id;
+                       if (ctxt)
+                               process_context(xprt, ctxt);
+
+                       svc_xprt_put(&xprt->sc_xprt);
+               }
        }
 
        if (ctxt)
@@ -929,23 +943,8 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
 
        ret = rdma_create_qp(newxprt->sc_cm_id, newxprt->sc_pd, &qp_attr);
        if (ret) {
-               /*
-                * XXX: This is a hack. We need a xx_request_qp interface
-                * that will adjust the qp_attr's with a best-effort
-                * number
-                */
-               qp_attr.cap.max_send_sge -= 2;
-               qp_attr.cap.max_recv_sge -= 2;
-               ret = rdma_create_qp(newxprt->sc_cm_id, newxprt->sc_pd,
-                                    &qp_attr);
-               if (ret) {
-                       dprintk("svcrdma: failed to create QP, ret=%d\n", ret);
-                       goto errout;
-               }
-               newxprt->sc_max_sge = qp_attr.cap.max_send_sge;
-               newxprt->sc_max_sge = qp_attr.cap.max_recv_sge;
-               newxprt->sc_sq_depth = qp_attr.cap.max_send_wr;
-               newxprt->sc_max_requests = qp_attr.cap.max_recv_wr;
+               dprintk("svcrdma: failed to create QP, ret=%d\n", ret);
+               goto errout;
        }
        newxprt->sc_qp = newxprt->sc_cm_id->qp;
 
@@ -995,7 +994,11 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt)
                        need_dma_mr = 0;
                break;
        case RDMA_TRANSPORT_IB:
-               if (!(devattr.device_cap_flags & IB_DEVICE_LOCAL_DMA_LKEY)) {
+               if (!(newxprt->sc_dev_caps & SVCRDMA_DEVCAP_FAST_REG)) {
+                       need_dma_mr = 1;
+                       dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
+               } else if (!(devattr.device_cap_flags &
+                            IB_DEVICE_LOCAL_DMA_LKEY)) {
                        need_dma_mr = 1;
                        dma_mr_acc = IB_ACCESS_LOCAL_WRITE;
                } else
@@ -1192,14 +1195,7 @@ static int svc_rdma_has_wspace(struct svc_xprt *xprt)
                container_of(xprt, struct svcxprt_rdma, sc_xprt);
 
        /*
-        * If there are fewer SQ WR available than required to send a
-        * simple response, return false.
-        */
-       if ((rdma->sc_sq_depth - atomic_read(&rdma->sc_sq_count) < 3))
-               return 0;
-
-       /*
-        * ...or there are already waiters on the SQ,
+        * If there are already waiters on the SQ,
         * return false.
         */
        if (waitqueue_active(&rdma->sc_send_wait))