]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - net/sunrpc/xprtrdma/frwr_ops.c
xprtrdma: Add unique trace points for posting Local Invalidate WRs
[linux.git] / net / sunrpc / xprtrdma / frwr_ops.c
index 0e740bae2d801414efe351d7ee0dc28f1b583410..9901a811f59833ebf24d4f1c4303de7867231681 100644 (file)
@@ -88,15 +88,8 @@ void frwr_release_mr(struct rpcrdma_mr *mr)
        kfree(mr);
 }
 
-/* MRs are dynamically allocated, so simply clean up and release the MR.
- * A replacement MR will subsequently be allocated on demand.
- */
-static void
-frwr_mr_recycle_worker(struct work_struct *work)
+static void frwr_mr_recycle(struct rpcrdma_xprt *r_xprt, struct rpcrdma_mr *mr)
 {
-       struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr, mr_recycle);
-       struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
-
        trace_xprtrdma_mr_recycle(mr);
 
        if (mr->mr_dir != DMA_NONE) {
@@ -106,14 +99,40 @@ frwr_mr_recycle_worker(struct work_struct *work)
                mr->mr_dir = DMA_NONE;
        }
 
-       spin_lock(&r_xprt->rx_buf.rb_mrlock);
+       spin_lock(&r_xprt->rx_buf.rb_lock);
        list_del(&mr->mr_all);
        r_xprt->rx_stats.mrs_recycled++;
-       spin_unlock(&r_xprt->rx_buf.rb_mrlock);
+       spin_unlock(&r_xprt->rx_buf.rb_lock);
 
        frwr_release_mr(mr);
 }
 
+/* MRs are dynamically allocated, so simply clean up and release the MR.
+ * A replacement MR will subsequently be allocated on demand.
+ */
+static void
+frwr_mr_recycle_worker(struct work_struct *work)
+{
+       struct rpcrdma_mr *mr = container_of(work, struct rpcrdma_mr,
+                                            mr_recycle);
+
+       frwr_mr_recycle(mr->mr_xprt, mr);
+}
+
+/* frwr_recycle - Discard MRs
+ * @req: request to reset
+ *
+ * Used after a reconnect. These MRs could be in flight, we can't
+ * tell. Safe thing to do is release them.
+ */
+void frwr_recycle(struct rpcrdma_req *req)
+{
+       struct rpcrdma_mr *mr;
+
+       while ((mr = rpcrdma_mr_pop(&req->rl_registered)))
+               frwr_mr_recycle(mr->mr_xprt, mr);
+}
+
 /* frwr_reset - Place MRs back on the free list
  * @req: request to reset
  *
@@ -551,7 +570,6 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         */
        bad_wr = NULL;
        rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
-       trace_xprtrdma_post_send(req, rc);
 
        /* The final LOCAL_INV WR in the chain is supposed to
         * do the wake. If it was never posted, the wake will
@@ -564,6 +582,7 @@ void frwr_unmap_sync(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
 
        /* Recycle MRs in the LOCAL_INV chain that did not get posted.
         */
+       trace_xprtrdma_post_linv(req, rc);
        while (bad_wr) {
                frwr = container_of(bad_wr, struct rpcrdma_frwr,
                                    fr_invwr);
@@ -654,12 +673,12 @@ void frwr_unmap_async(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
         */
        bad_wr = NULL;
        rc = ib_post_send(r_xprt->rx_ia.ri_id->qp, first, &bad_wr);
-       trace_xprtrdma_post_send(req, rc);
        if (!rc)
                return;
 
        /* Recycle MRs in the LOCAL_INV chain that did not get posted.
         */
+       trace_xprtrdma_post_linv(req, rc);
        while (bad_wr) {
                frwr = container_of(bad_wr, struct rpcrdma_frwr, fr_invwr);
                mr = container_of(frwr, struct rpcrdma_mr, frwr);