OSDN Git Service

xprtrdma: Re-organize the switch() in rpcrdma_conn_upcall
[uclinux-h8/linux.git] / net / sunrpc / xprtrdma / verbs.c
index 5efeba0..c60172f 100644 (file)
@@ -219,38 +219,48 @@ rpcrdma_update_connect_private(struct rpcrdma_xprt *r_xprt,
        rpcrdma_set_max_header_sizes(r_xprt);
 }
 
+/**
+ * rpcrdma_cm_event_handler - Handle RDMA CM events
+ * @id: rdma_cm_id on which an event has occurred
+ * @event: details of the event
+ *
+ * Called with @id's mutex held. Returns 1 if caller should
+ * destroy @id, otherwise 0.
+ */
 static int
-rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
+rpcrdma_cm_event_handler(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;
-       int connstate = 0;
+       struct rpcrdma_xprt *r_xprt = id->context;
+       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       struct rpcrdma_ep *ep = &r_xprt->rx_ep;
+       struct rpc_xprt *xprt = &r_xprt->rx_xprt;
+
+       might_sleep();
 
-       trace_xprtrdma_conn_upcall(xprt, event);
+       trace_xprtrdma_cm_event(r_xprt, 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;
+               return 0;
        case RDMA_CM_EVENT_ADDR_ERROR:
                ia->ri_async_rc = -EPROTO;
                complete(&ia->ri_done);
-               break;
+               return 0;
        case RDMA_CM_EVENT_ROUTE_ERROR:
                ia->ri_async_rc = -ENETUNREACH;
                complete(&ia->ri_done);
-               break;
+               return 0;
        case RDMA_CM_EVENT_DEVICE_REMOVAL:
 #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
                pr_info("rpcrdma: removing device %s for %s:%s\n",
                        ia->ri_device->name,
-                       rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt));
+                       rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt));
 #endif
                set_bit(RPCRDMA_IAF_REMOVING, &ia->ri_flags);
                ep->rep_connected = -ENODEV;
-               xprt_force_disconnect(&xprt->rx_xprt);
+               xprt_force_disconnect(xprt);
                wait_for_completion(&ia->ri_remove_done);
 
                ia->ri_id = NULL;
@@ -258,42 +268,39 @@ rpcrdma_conn_upcall(struct rdma_cm_id *id, struct rdma_cm_event *event)
                /* Return 1 to ensure the core destroys the id. */
                return 1;
        case RDMA_CM_EVENT_ESTABLISHED:
-               ++xprt->rx_xprt.connect_cookie;
-               connstate = 1;
-               rpcrdma_update_connect_private(xprt, &event->param.conn);
+               ++xprt->connect_cookie;
+               ep->rep_connected = 1;
+               rpcrdma_update_connect_private(r_xprt, &event->param.conn);
                goto connected;
        case RDMA_CM_EVENT_CONNECT_ERROR:
-               connstate = -ENOTCONN;
+               ep->rep_connected = -ENOTCONN;
                goto connected;
        case RDMA_CM_EVENT_UNREACHABLE:
-               connstate = -ENETUNREACH;
+               ep->rep_connected = -ENETUNREACH;
                goto connected;
        case RDMA_CM_EVENT_REJECTED:
                dprintk("rpcrdma: connection to %s:%s rejected: %s\n",
-                       rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt),
+                       rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt),
                        rdma_reject_msg(id, event->status));
-               connstate = -ECONNREFUSED;
+               ep->rep_connected = -ECONNREFUSED;
                if (event->status == IB_CM_REJ_STALE_CONN)
-                       connstate = -EAGAIN;
+                       ep->rep_connected = -EAGAIN;
                goto connected;
        case RDMA_CM_EVENT_DISCONNECTED:
-               ++xprt->rx_xprt.connect_cookie;
-               connstate = -ECONNABORTED;
+               ++xprt->connect_cookie;
+               ep->rep_connected = -ECONNABORTED;
 connected:
-               xprt->rx_buf.rb_credits = 1;
-               ep->rep_connected = connstate;
                rpcrdma_conn_func(ep);
                wake_up_all(&ep->rep_connect_wait);
-               /*FALLTHROUGH*/
+               break;
        default:
-               dprintk("RPC:       %s: %s:%s on %s/%s (ep 0x%p): %s\n",
-                       __func__,
-                       rpcrdma_addrstr(xprt), rpcrdma_portstr(xprt),
-                       ia->ri_device->name, ia->ri_ops->ro_displayname,
-                       ep, rdma_event_msg(event->event));
                break;
        }
 
+       dprintk("RPC:       %s: %s:%s on %s/%s: %s\n", __func__,
+               rpcrdma_addrstr(r_xprt), rpcrdma_portstr(r_xprt),
+               ia->ri_device->name, ia->ri_ops->ro_displayname,
+               rdma_event_msg(event->event));
        return 0;
 }
 
@@ -309,7 +316,7 @@ rpcrdma_create_id(struct rpcrdma_xprt *xprt, struct rpcrdma_ia *ia)
        init_completion(&ia->ri_done);
        init_completion(&ia->ri_remove_done);
 
-       id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_conn_upcall,
+       id = rdma_create_id(xprt->rx_xprt.xprt_net, rpcrdma_cm_event_handler,
                            xprt, RDMA_PS_TCP, IB_QPT_RC);
        if (IS_ERR(id)) {
                rc = PTR_ERR(id);
@@ -755,6 +762,7 @@ retry:
        }
 
        ep->rep_connected = 0;
+       rpcrdma_post_recvs(r_xprt, true);
 
        rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
        if (rc) {
@@ -773,8 +781,6 @@ retry:
 
        dprintk("RPC:       %s: connected\n", __func__);
 
-       rpcrdma_post_recvs(r_xprt, true);
-
 out:
        if (rc)
                ep->rep_connected = rc;
@@ -980,39 +986,6 @@ rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc)
 }
 
 static void
-rpcrdma_mr_recovery_worker(struct work_struct *work)
-{
-       struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer,
-                                                 rb_recovery_worker.work);
-       struct rpcrdma_mr *mr;
-
-       spin_lock(&buf->rb_recovery_lock);
-       while (!list_empty(&buf->rb_stale_mrs)) {
-               mr = rpcrdma_mr_pop(&buf->rb_stale_mrs);
-               spin_unlock(&buf->rb_recovery_lock);
-
-               trace_xprtrdma_recover_mr(mr);
-               mr->mr_xprt->rx_ia.ri_ops->ro_recover_mr(mr);
-
-               spin_lock(&buf->rb_recovery_lock);
-       }
-       spin_unlock(&buf->rb_recovery_lock);
-}
-
-void
-rpcrdma_mr_defer_recovery(struct rpcrdma_mr *mr)
-{
-       struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
-       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
-
-       spin_lock(&buf->rb_recovery_lock);
-       rpcrdma_mr_push(mr, &buf->rb_stale_mrs);
-       spin_unlock(&buf->rb_recovery_lock);
-
-       schedule_delayed_work(&buf->rb_recovery_worker, 0);
-}
-
-static void
 rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
 {
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
@@ -1021,7 +994,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
        LIST_HEAD(free);
        LIST_HEAD(all);
 
-       for (count = 0; count < 3; count++) {
+       for (count = 0; count < ia->ri_max_segs; count++) {
                struct rpcrdma_mr *mr;
                int rc;
 
@@ -1144,14 +1117,10 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        buf->rb_bc_srv_max_requests = 0;
        spin_lock_init(&buf->rb_mrlock);
        spin_lock_init(&buf->rb_lock);
-       spin_lock_init(&buf->rb_recovery_lock);
        INIT_LIST_HEAD(&buf->rb_mrs);
        INIT_LIST_HEAD(&buf->rb_all);
-       INIT_LIST_HEAD(&buf->rb_stale_mrs);
        INIT_DELAYED_WORK(&buf->rb_refresh_worker,
                          rpcrdma_mr_refresh_worker);
-       INIT_DELAYED_WORK(&buf->rb_recovery_worker,
-                         rpcrdma_mr_recovery_worker);
 
        rpcrdma_mrs_create(r_xprt);
 
@@ -1171,6 +1140,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
                list_add(&req->rl_list, &buf->rb_send_bufs);
        }
 
+       buf->rb_credits = 1;
        buf->rb_posted_receives = 0;
        INIT_LIST_HEAD(&buf->rb_recv_bufs);
 
@@ -1234,7 +1204,6 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
 void
 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
-       cancel_delayed_work_sync(&buf->rb_recovery_worker);
        cancel_delayed_work_sync(&buf->rb_refresh_worker);
 
        rpcrdma_sendctxs_destroy(buf);
@@ -1327,7 +1296,7 @@ rpcrdma_mr_unmap_and_put(struct rpcrdma_mr *mr)
 {
        struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
 
-       trace_xprtrdma_dma_unmap(mr);
+       trace_xprtrdma_mr_unmap(mr);
        ib_dma_unmap_sg(r_xprt->rx_ia.ri_device,
                        mr->mr_sg, mr->mr_nents, mr->mr_dir);
        __rpcrdma_mr_put(&r_xprt->rx_buf, mr);