nfs41: sunrpc: add a struct svc_xprt pointer to struct svc_serv for backchannel use
[safe/jmp/linux-2.6] / net / sunrpc / xprtrdma / verbs.c
index e3fe905..465aafc 100644 (file)
@@ -276,7 +276,9 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
        struct rpcrdma_xprt *xprt = id->context;
        struct rpcrdma_ia *ia = &xprt->rx_ia;
        struct rpcrdma_ep *ep = &xprt->rx_ep;
+#ifdef RPC_DEBUG
        struct sockaddr_in *addr = (struct sockaddr_in *) &ep->rep_remote_addr;
+#endif
        struct ib_qp_attr attr;
        struct ib_qp_init_attr iattr;
        int connstate = 0;
@@ -284,6 +286,7 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
        switch (event->event) {
        case RDMA_CM_EVENT_ADDR_RESOLVED:
        case RDMA_CM_EVENT_ROUTE_RESOLVED:
+               ia->ri_async_rc = 0;
                complete(&ia->ri_done);
                break;
        case RDMA_CM_EVENT_ADDR_ERROR:
@@ -322,12 +325,11 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
                connstate = -ENODEV;
 connected:
-               dprintk("RPC:       %s: %s: %u.%u.%u.%u:%u"
-                       " (ep 0x%p event 0x%x)\n",
+               dprintk("RPC:       %s: %s: %pI4:%u (ep 0x%p event 0x%x)\n",
                        __func__,
                        (event->event <= 11) ? conn[event->event] :
                                                "unknown connection error",
-                       NIPQUAD(addr->sin_addr.s_addr),
+                       &addr->sin_addr.s_addr,
                        ntohs(addr->sin_port),
                        ep, event->event);
                atomic_set(&rpcx_to_rdmax(ep->rep_xprt)->rx_buf.rb_credits, 1);
@@ -338,13 +340,31 @@ connected:
                wake_up_all(&ep->rep_connect_wait);
                break;
        default:
-               ia->ri_async_rc = -EINVAL;
-               dprintk("RPC:       %s: unexpected CM event %X\n",
+               dprintk("RPC:       %s: unexpected CM event %d\n",
                        __func__, event->event);
-               complete(&ia->ri_done);
                break;
        }
 
+#ifdef RPC_DEBUG
+       if (connstate == 1) {
+               int ird = attr.max_dest_rd_atomic;
+               int tird = ep->rep_remote_cma.responder_resources;
+               printk(KERN_INFO "rpcrdma: connection to %pI4:%u "
+                       "on %s, memreg %d slots %d ird %d%s\n",
+                       &addr->sin_addr.s_addr,
+                       ntohs(addr->sin_port),
+                       ia->ri_id->device->name,
+                       ia->ri_memreg_strategy,
+                       xprt->rx_buf.rb_max_requests,
+                       ird, ird < 4 && ird < tird / 2 ? " (low!)" : "");
+       } else if (connstate < 0) {
+               printk(KERN_INFO "rpcrdma: connection to %pI4:%u closed (%d)\n",
+                       &addr->sin_addr.s_addr,
+                       ntohs(addr->sin_port),
+                       connstate);
+       }
+#endif
+
        return 0;
 }
 
@@ -355,6 +375,8 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
        struct rdma_cm_id *id;
        int rc;
 
+       init_completion(&ia->ri_done);
+
        id = rdma_create_id(rpcrdma_conn_upcall, xprt, RDMA_PS_TCP);
        if (IS_ERR(id)) {
                rc = PTR_ERR(id);
@@ -363,26 +385,28 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt,
                return id;
        }
 
-       ia->ri_async_rc = 0;
+       ia->ri_async_rc = -ETIMEDOUT;
        rc = rdma_resolve_addr(id, NULL, addr, RDMA_RESOLVE_TIMEOUT);
        if (rc) {
                dprintk("RPC:       %s: rdma_resolve_addr() failed %i\n",
                        __func__, rc);
                goto out;
        }
-       wait_for_completion(&ia->ri_done);
+       wait_for_completion_interruptible_timeout(&ia->ri_done,
+                               msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
        rc = ia->ri_async_rc;
        if (rc)
                goto out;
 
-       ia->ri_async_rc = 0;
+       ia->ri_async_rc = -ETIMEDOUT;
        rc = rdma_resolve_route(id, RDMA_RESOLVE_TIMEOUT);
        if (rc) {
                dprintk("RPC:       %s: rdma_resolve_route() failed %i\n",
                        __func__, rc);
                goto out;
        }
-       wait_for_completion(&ia->ri_done);
+       wait_for_completion_interruptible_timeout(&ia->ri_done,
+                               msecs_to_jiffies(RDMA_RESOLVE_TIMEOUT) + 1);
        rc = ia->ri_async_rc;
        if (rc)
                goto out;
@@ -427,8 +451,6 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        struct ib_device_attr devattr;
        struct rpcrdma_ia *ia = &xprt->rx_ia;
 
-       init_completion(&ia->ri_done);
-
        ia->ri_id = rpcrdma_create_id(xprt, ia, addr);
        if (IS_ERR(ia->ri_id)) {
                rc = PTR_ERR(ia->ri_id);
@@ -565,6 +587,7 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        return 0;
 out2:
        rdma_destroy_id(ia->ri_id);
+       ia->ri_id = NULL;
 out1:
        return rc;
 }
@@ -585,15 +608,17 @@ rpcrdma_ia_close(struct rpcrdma_ia *ia)
                dprintk("RPC:       %s: ib_dereg_mr returned %i\n",
                        __func__, rc);
        }
-       if (ia->ri_id != NULL && !IS_ERR(ia->ri_id) && ia->ri_id->qp)
-               rdma_destroy_qp(ia->ri_id);
+       if (ia->ri_id != NULL && !IS_ERR(ia->ri_id)) {
+               if (ia->ri_id->qp)
+                       rdma_destroy_qp(ia->ri_id);
+               rdma_destroy_id(ia->ri_id);
+               ia->ri_id = NULL;
+       }
        if (ia->ri_pd != NULL && !IS_ERR(ia->ri_pd)) {
                rc = ib_dealloc_pd(ia->ri_pd);
                dprintk("RPC:       %s: ib_dealloc_pd returned %i\n",
                        __func__, rc);
        }
-       if (ia->ri_id != NULL && !IS_ERR(ia->ri_id))
-               rdma_destroy_id(ia->ri_id);
 }
 
 /*
@@ -751,21 +776,16 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
                if (rc)
                        dprintk("RPC:       %s: rpcrdma_ep_disconnect"
                                " returned %i\n", __func__, rc);
+               rdma_destroy_qp(ia->ri_id);
+               ia->ri_id->qp = NULL;
        }
 
-       ep->rep_func = NULL;
-
        /* padding - could be done in rpcrdma_buffer_destroy... */
        if (ep->rep_pad_mr) {
                rpcrdma_deregister_internal(ia, ep->rep_pad_mr, &ep->rep_pad);
                ep->rep_pad_mr = NULL;
        }
 
-       if (ia->ri_id->qp) {
-               rdma_destroy_qp(ia->ri_id);
-               ia->ri_id->qp = NULL;
-       }
-
        rpcrdma_clean_cq(ep->rep_cq);
        rc = ib_destroy_cq(ep->rep_cq);
        if (rc)
@@ -784,9 +804,8 @@ rpcrdma_ep_connect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
        struct rdma_cm_id *id;
        int rc = 0;
        int retry_count = 0;
-       int reconnect = (ep->rep_connected != 0);
 
-       if (reconnect) {
+       if (ep->rep_connected != 0) {
                struct rpcrdma_xprt *xprt;
 retry:
                rc = rpcrdma_ep_disconnect(ep, ia);
@@ -817,6 +836,7 @@ retry:
                        goto out;
                }
                /* END TEMP */
+               rdma_destroy_qp(ia->ri_id);
                rdma_destroy_id(ia->ri_id);
                ia->ri_id = id;
        }
@@ -850,9 +870,6 @@ if (strnicmp(ia->ri_id->device->dma_device->bus->name, "pci", 3) == 0) {
                goto out;
        }
 
-       if (reconnect)
-               return 0;
-
        wait_event_interruptible(ep->rep_connect_wait, ep->rep_connected != 0);
 
        /*
@@ -1478,7 +1495,8 @@ rpcrdma_register_frmr_external(struct rpcrdma_mr_seg *seg,
        frmr_wr.wr.fast_reg.page_shift = PAGE_SHIFT;
        frmr_wr.wr.fast_reg.length = i << PAGE_SHIFT;
        frmr_wr.wr.fast_reg.access_flags = (writing ?
-                               IB_ACCESS_REMOTE_WRITE : IB_ACCESS_REMOTE_READ);
+                               IB_ACCESS_REMOTE_WRITE | IB_ACCESS_LOCAL_WRITE :
+                               IB_ACCESS_REMOTE_READ);
        frmr_wr.wr.fast_reg.rkey = seg1->mr_chunk.rl_mw->r.frmr.fr_mr->rkey;
        DECR_CQCOUNT(&r_xprt->rx_ep);