]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - net/sunrpc/xprtrdma/verbs.c
xprtrdma: Honor ->send_request API contract
[karo-tx-linux.git] / net / sunrpc / xprtrdma / verbs.c
index b044d98a1370207422d129689bb43b35766fc76f..db935ed3ac75aa6b3de8afc0707849a624341b8f 100644 (file)
@@ -379,8 +379,6 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        struct rpcrdma_ia *ia = &xprt->rx_ia;
        int rc;
 
-       ia->ri_dma_mr = NULL;
-
        ia->ri_id = rpcrdma_create_id(xprt, ia, addr);
        if (IS_ERR(ia->ri_id)) {
                rc = PTR_ERR(ia->ri_id);
@@ -391,47 +389,29 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt, struct sockaddr *addr, int memreg)
        ia->ri_pd = ib_alloc_pd(ia->ri_device);
        if (IS_ERR(ia->ri_pd)) {
                rc = PTR_ERR(ia->ri_pd);
-               dprintk("RPC:       %s: ib_alloc_pd() failed %i\n",
-                       __func__, rc);
+               pr_err("rpcrdma: ib_alloc_pd() returned %d\n", rc);
                goto out2;
        }
 
-       if (memreg == RPCRDMA_FRMR) {
-               if (!(ia->ri_device->attrs.device_cap_flags &
-                               IB_DEVICE_MEM_MGT_EXTENSIONS) ||
-                   (ia->ri_device->attrs.max_fast_reg_page_list_len == 0)) {
-                       dprintk("RPC:       %s: FRMR registration "
-                               "not supported by HCA\n", __func__);
-                       memreg = RPCRDMA_MTHCAFMR;
-               }
-       }
-       if (memreg == RPCRDMA_MTHCAFMR) {
-               if (!ia->ri_device->alloc_fmr) {
-                       dprintk("RPC:       %s: MTHCAFMR registration "
-                               "not supported by HCA\n", __func__);
-                       rc = -EINVAL;
-                       goto out3;
-               }
-       }
-
        switch (memreg) {
        case RPCRDMA_FRMR:
-               ia->ri_ops = &rpcrdma_frwr_memreg_ops;
-               break;
-       case RPCRDMA_ALLPHYSICAL:
-               ia->ri_ops = &rpcrdma_physical_memreg_ops;
-               break;
+               if (frwr_is_supported(ia)) {
+                       ia->ri_ops = &rpcrdma_frwr_memreg_ops;
+                       break;
+               }
+               /*FALLTHROUGH*/
        case RPCRDMA_MTHCAFMR:
-               ia->ri_ops = &rpcrdma_fmr_memreg_ops;
-               break;
+               if (fmr_is_supported(ia)) {
+                       ia->ri_ops = &rpcrdma_fmr_memreg_ops;
+                       break;
+               }
+               /*FALLTHROUGH*/
        default:
-               printk(KERN_ERR "RPC: Unsupported memory "
-                               "registration mode: %d\n", memreg);
-               rc = -ENOMEM;
+               pr_err("rpcrdma: Unsupported memory registration mode: %d\n",
+                      memreg);
+               rc = -EINVAL;
                goto out3;
        }
-       dprintk("RPC:       %s: memory registration strategy is '%s'\n",
-               __func__, ia->ri_ops->ro_displayname);
 
        return 0;
 
@@ -585,8 +565,6 @@ rpcrdma_ep_create(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia,
 out2:
        ib_free_cq(sendcq);
 out1:
-       if (ia->ri_dma_mr)
-               ib_dereg_mr(ia->ri_dma_mr);
        return rc;
 }
 
@@ -600,8 +578,6 @@ out1:
 void
 rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
 {
-       int rc;
-
        dprintk("RPC:       %s: entering, connected is %d\n",
                __func__, ep->rep_connected);
 
@@ -615,12 +591,6 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
 
        ib_free_cq(ep->rep_attr.recv_cq);
        ib_free_cq(ep->rep_attr.send_cq);
-
-       if (ia->ri_dma_mr) {
-               rc = ib_dereg_mr(ia->ri_dma_mr);
-               dprintk("RPC:       %s: ib_dereg_mr returned %i\n",
-                       __func__, rc);
-       }
 }
 
 /*
@@ -777,6 +747,41 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
        ib_drain_qp(ia->ri_id->qp);
 }
 
+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_mw *mw;
+
+       spin_lock(&buf->rb_recovery_lock);
+       while (!list_empty(&buf->rb_stale_mrs)) {
+               mw = list_first_entry(&buf->rb_stale_mrs,
+                                     struct rpcrdma_mw, mw_list);
+               list_del_init(&mw->mw_list);
+               spin_unlock(&buf->rb_recovery_lock);
+
+               dprintk("RPC:       %s: recovering MR %p\n", __func__, mw);
+               mw->mw_xprt->rx_ia.ri_ops->ro_recover_mr(mw);
+
+               spin_lock(&buf->rb_recovery_lock);
+       };
+       spin_unlock(&buf->rb_recovery_lock);
+}
+
+void
+rpcrdma_defer_mr_recovery(struct rpcrdma_mw *mw)
+{
+       struct rpcrdma_xprt *r_xprt = mw->mw_xprt;
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+
+       spin_lock(&buf->rb_recovery_lock);
+       list_add(&mw->mw_list, &buf->rb_stale_mrs);
+       spin_unlock(&buf->rb_recovery_lock);
+
+       schedule_delayed_work(&buf->rb_recovery_worker, 0);
+}
+
 struct rpcrdma_req *
 rpcrdma_create_req(struct rpcrdma_xprt *r_xprt)
 {
@@ -837,8 +842,12 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
 
        buf->rb_max_requests = r_xprt->rx_data.max_requests;
        buf->rb_bc_srv_max_requests = 0;
-       spin_lock_init(&buf->rb_lock);
        atomic_set(&buf->rb_credits, 1);
+       spin_lock_init(&buf->rb_lock);
+       spin_lock_init(&buf->rb_recovery_lock);
+       INIT_LIST_HEAD(&buf->rb_stale_mrs);
+       INIT_DELAYED_WORK(&buf->rb_recovery_worker,
+                         rpcrdma_mr_recovery_worker);
 
        rc = ia->ri_ops->ro_init(r_xprt);
        if (rc)
@@ -862,7 +871,7 @@ rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        }
 
        INIT_LIST_HEAD(&buf->rb_recv_bufs);
-       for (i = 0; i < buf->rb_max_requests + 2; i++) {
+       for (i = 0; i < buf->rb_max_requests; i++) {
                struct rpcrdma_rep *rep;
 
                rep = rpcrdma_create_rep(r_xprt);
@@ -923,6 +932,8 @@ rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
        struct rpcrdma_ia *ia = rdmab_to_ia(buf);
 
+       cancel_delayed_work_sync(&buf->rb_recovery_worker);
+
        while (!list_empty(&buf->rb_recv_bufs)) {
                struct rpcrdma_rep *rep;
 
@@ -978,8 +989,6 @@ rpcrdma_put_mw(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mw *mw)
 
 /*
  * Get a set of request/reply buffers.
- *
- * Reply buffer (if available) is attached to send buffer upon return.
  */
 struct rpcrdma_req *
 rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
@@ -998,13 +1007,13 @@ rpcrdma_buffer_get(struct rpcrdma_buffer *buffers)
 
 out_reqbuf:
        spin_unlock(&buffers->rb_lock);
-       pr_warn("RPC:       %s: out of request buffers\n", __func__);
+       pr_warn("rpcrdma: out of request buffers (%p)\n", buffers);
        return NULL;
 out_repbuf:
+       list_add(&req->rl_free, &buffers->rb_send_bufs);
        spin_unlock(&buffers->rb_lock);
-       pr_warn("RPC:       %s: out of reply buffers\n", __func__);
-       req->rl_reply = NULL;
-       return req;
+       pr_warn("rpcrdma: out of reply buffers (%p)\n", buffers);
+       return NULL;
 }
 
 /*
@@ -1060,14 +1069,6 @@ rpcrdma_recv_buffer_put(struct rpcrdma_rep *rep)
  * Wrappers for internal-use kmalloc memory registration, used by buffer code.
  */
 
-void
-rpcrdma_mapping_error(struct rpcrdma_mr_seg *seg)
-{
-       dprintk("RPC:       map_one: offset %p iova %llx len %zu\n",
-               seg->mr_offset,
-               (unsigned long long)seg->mr_dma, seg->mr_dmalen);
-}
-
 /**
  * rpcrdma_alloc_regbuf - kmalloc and register memory for SEND/RECV buffers
  * @ia: controlling rpcrdma_ia
@@ -1150,7 +1151,7 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
        if (rep) {
                rc = rpcrdma_ep_post_recv(ia, ep, rep);
                if (rc)
-                       goto out;
+                       return rc;
                req->rl_reply = NULL;
        }
 
@@ -1175,10 +1176,12 @@ rpcrdma_ep_post(struct rpcrdma_ia *ia,
 
        rc = ib_post_send(ia->ri_id->qp, &send_wr, &send_wr_fail);
        if (rc)
-               dprintk("RPC:       %s: ib_post_send returned %i\n", __func__,
-                       rc);
-out:
-       return rc;
+               goto out_postsend_err;
+       return 0;
+
+out_postsend_err:
+       pr_err("rpcrdma: RDMA Send ib_post_send returned %i\n", rc);
+       return -ENOTCONN;
 }
 
 /*
@@ -1203,11 +1206,13 @@ rpcrdma_ep_post_recv(struct rpcrdma_ia *ia,
                                   DMA_BIDIRECTIONAL);
 
        rc = ib_post_recv(ia->ri_id->qp, &recv_wr, &recv_wr_fail);
-
        if (rc)
-               dprintk("RPC:       %s: ib_post_recv returned %i\n", __func__,
-                       rc);
-       return rc;
+               goto out_postrecv;
+       return 0;
+
+out_postrecv:
+       pr_err("rpcrdma: ib_post_recv returned %i\n", rc);
+       return -ENOTCONN;
 }
 
 /**