Merge tag 'mac80211-for-davem-2016-07-06' of git://git.kernel.org/pub/scm/linux/kerne...
[cascardo/linux.git] / net / sunrpc / xprtrdma / verbs.c
index f5ed9f9..b044d98 100644 (file)
@@ -203,15 +203,6 @@ out_fail:
        goto out_schedule;
 }
 
-static void
-rpcrdma_flush_cqs(struct rpcrdma_ep *ep)
-{
-       struct ib_wc wc;
-
-       while (ib_poll_cq(ep->rep_attr.recv_cq, 1, &wc) > 0)
-               rpcrdma_receive_wc(NULL, &wc);
-}
-
 static int
 rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
 {
@@ -373,23 +364,6 @@ out:
        return ERR_PTR(rc);
 }
 
-/*
- * Drain any cq, prior to teardown.
- */
-static void
-rpcrdma_clean_cq(struct ib_cq *cq)
-{
-       struct ib_wc wc;
-       int count = 0;
-
-       while (1 == ib_poll_cq(cq, 1, &wc))
-               ++count;
-
-       if (count)
-               dprintk("RPC:       %s: flushed %d events (last 0x%x)\n",
-                       __func__, count, wc.opcode);
-}
-
 /*
  * Exported functions.
  */
@@ -459,7 +433,6 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        dprintk("RPC:       %s: memory registration strategy is '%s'\n",
                __func__, ia->ri_ops->ro_displayname);
 
-       rwlock_init(&ia->ri_qplock);
        return 0;
 
 out3:
@@ -515,7 +488,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
                        __func__);
                return -ENOMEM;
        }
-       max_qp_wr = ia->ri_device->attrs.max_qp_wr - RPCRDMA_BACKWARD_WRS;
+       max_qp_wr = ia->ri_device->attrs.max_qp_wr - RPCRDMA_BACKWARD_WRS - 1;
 
        /* check provider's send/recv wr limits */
        if (cdata->max_requests > max_qp_wr)
@@ -526,11 +499,13 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
        ep->rep_attr.srq = NULL;
        ep->rep_attr.cap.max_send_wr = cdata->max_requests;
        ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
+       ep->rep_attr.cap.max_send_wr += 1;      /* drain cqe */
        rc = ia->ri_ops->ro_open(ia, ep, cdata);
        if (rc)
                return rc;
        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_recv_wr += 1;      /* drain cqe */
        ep->rep_attr.cap.max_send_sge = RPCRDMA_MAX_IOVS;
        ep->rep_attr.cap.max_recv_sge = 1;
        ep->rep_attr.cap.max_inline_data = 0;
@@ -578,6 +553,7 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
        ep->rep_attr.recv_cq = recvcq;
 
        /* Initialize cma parameters */
+       memset(&ep->rep_remote_cma, 0, sizeof(ep->rep_remote_cma));
 
        /* RPC/RDMA does not use private data */
        ep->rep_remote_cma.private_data = NULL;
@@ -591,7 +567,16 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
                ep->rep_remote_cma.responder_resources =
                                                ia->ri_device->attrs.max_qp_rd_atom;
 
-       ep->rep_remote_cma.retry_count = 7;
+       /* Limit transport retries so client can detect server
+        * GID changes quickly. RPC layer handles re-establishing
+        * transport connection and retransmission.
+        */
+       ep->rep_remote_cma.retry_count = 6;
+
+       /* RPC-over-RDMA handles its own flow control. In addition,
+        * make all RNR NAKs visible so we know that RPC-over-RDMA
+        * flow control is working correctly (no NAKs should be seen).
+        */
        ep->rep_remote_cma.flow_control = 0;
        ep->rep_remote_cma.rnr_retry_count = 0;
 
@@ -622,13 +607,8 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
 
        cancel_delayed_work_sync(&ep->rep_connect_worker);
 
-       if (ia->ri_id->qp)
-               rpcrdma_ep_disconnect(ep, ia);
-
-       rpcrdma_clean_cq(ep->rep_attr.recv_cq);
-       rpcrdma_clean_cq(ep->rep_attr.send_cq);
-
        if (ia->ri_id->qp) {
+               rpcrdma_ep_disconnect(ep, ia);
                rdma_destroy_qp(ia->ri_id);
                ia->ri_id->qp = NULL;
        }
@@ -659,7 +639,6 @@ retry:
                dprintk("RPC:       %s: reconnecting...\n", __func__);
 
                rpcrdma_ep_disconnect(ep, ia);
-               rpcrdma_flush_cqs(ep);
 
                xprt = container_of(ia, struct rpcrdma_xprt, rx_ia);
                id = rpcrdma_create_id(xprt, ia,
@@ -692,10 +671,8 @@ retry:
                        goto out;
                }
 
-               write_lock(&ia->ri_qplock);
                old = ia->ri_id;
                ia->ri_id = id;
-               write_unlock(&ia->ri_qplock);
 
                rdma_destroy_qp(old);
                rpcrdma_destroy_id(old);
@@ -785,7 +762,6 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
 {
        int rc;
 
-       rpcrdma_flush_cqs(ep);
        rc = rdma_disconnect(ia->ri_id);
        if (!rc) {
                /* returns without wait if not connected */
@@ -797,6 +773,8 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
                dprintk("RPC:       %s: rdma_disconnect %i\n", __func__, rc);
                ep->rep_connected = rc;
        }
+
+       ib_drain_qp(ia->ri_id->qp);
 }
 
 struct rpcrdma_req *
@@ -1271,25 +1249,3 @@ out_rc:
        rpcrdma_recv_buffer_put(rep);
        return rc;
 }
-
-/* How many chunk list items fit within our inline buffers?
- */
-unsigned int
-rpcrdma_max_segments(struct rpcrdma_xprt *r_xprt)
-{
-       struct rpcrdma_create_data_internal *cdata = &r_xprt->rx_data;
-       int bytes, segments;
-
-       bytes = min_t(unsigned int, cdata->inline_wsize, cdata->inline_rsize);
-       bytes -= RPCRDMA_HDRLEN_MIN;
-       if (bytes < sizeof(struct rpcrdma_segment) * 2) {
-               pr_warn("RPC:       %s: inline threshold too small\n",
-                       __func__);
-               return 0;
-       }
-
-       segments = 1 << (fls(bytes / sizeof(struct rpcrdma_segment)) - 1);
-       dprintk("RPC:       %s: max chunk list size = %d segments\n",
-               __func__, segments);
-       return segments;
-}