xprtrdma: Remove rpcrdma_buffer::rb_mrlock
[linux-2.6-block.git] / net / sunrpc / xprtrdma / verbs.c
index 5e0b774ed522f8cf273a18586d1ba2198faf452e..52444c4d1be2e9aa20f69c4b13d24f82ef3987cf 100644 (file)
@@ -77,6 +77,7 @@
 static void rpcrdma_sendctx_put_locked(struct rpcrdma_sendctx *sc);
 static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf);
+static void rpcrdma_mr_free(struct rpcrdma_mr *mr);
 static struct rpcrdma_regbuf *
 rpcrdma_regbuf_alloc(size_t size, enum dma_data_direction direction,
                     gfp_t flags);
@@ -408,7 +409,7 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
        struct rpcrdma_req *req;
        struct rpcrdma_rep *rep;
 
-       cancel_delayed_work_sync(&buf->rb_refresh_worker);
+       cancel_work_sync(&buf->rb_refresh_worker);
 
        /* This is similar to rpcrdma_ep_destroy, but:
         * - Don't cancel the connect worker.
@@ -949,7 +950,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
                struct rpcrdma_mr *mr;
                int rc;
 
-               mr = kzalloc(sizeof(*mr), GFP_KERNEL);
+               mr = kzalloc(sizeof(*mr), GFP_NOFS);
                if (!mr)
                        break;
 
@@ -961,10 +962,10 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
 
                mr->mr_xprt = r_xprt;
 
-               spin_lock(&buf->rb_mrlock);
+               spin_lock(&buf->rb_lock);
                list_add(&mr->mr_list, &buf->rb_mrs);
                list_add(&mr->mr_all, &buf->rb_all_mrs);
-               spin_unlock(&buf->rb_mrlock);
+               spin_unlock(&buf->rb_lock);
        }
 
        r_xprt->rx_stats.mrs_allocated += count;
@@ -975,7 +976,7 @@ static void
 rpcrdma_mr_refresh_worker(struct work_struct *work)
 {
        struct rpcrdma_buffer *buf = container_of(work, struct rpcrdma_buffer,
-                                                 rb_refresh_worker.work);
+                                                 rb_refresh_worker);
        struct rpcrdma_xprt *r_xprt = container_of(buf, struct rpcrdma_xprt,
                                                   rx_buf);
 
@@ -1022,6 +1023,7 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
        if (!req->rl_recvbuf)
                goto out4;
 
+       INIT_LIST_HEAD(&req->rl_free_mrs);
        INIT_LIST_HEAD(&req->rl_registered);
        spin_lock(&buffer->rb_lock);
        list_add(&req->rl_all, &buffer->rb_allreqs);
@@ -1082,12 +1084,10 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
 
        buf->rb_max_requests = r_xprt->rx_ep.rep_max_requests;
        buf->rb_bc_srv_max_requests = 0;
-       spin_lock_init(&buf->rb_mrlock);
        spin_lock_init(&buf->rb_lock);
        INIT_LIST_HEAD(&buf->rb_mrs);
        INIT_LIST_HEAD(&buf->rb_all_mrs);
-       INIT_DELAYED_WORK(&buf->rb_refresh_worker,
-                         rpcrdma_mr_refresh_worker);
+       INIT_WORK(&buf->rb_refresh_worker, rpcrdma_mr_refresh_worker);
 
        rpcrdma_mrs_create(r_xprt);
 
@@ -1131,11 +1131,13 @@ static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep)
  * This function assumes that the caller prevents concurrent device
  * unload and transport tear-down.
  */
-void
-rpcrdma_req_destroy(struct rpcrdma_req *req)
+void rpcrdma_req_destroy(struct rpcrdma_req *req)
 {
        list_del(&req->rl_all);
 
+       while (!list_empty(&req->rl_free_mrs))
+               rpcrdma_mr_free(rpcrdma_mr_pop(&req->rl_free_mrs));
+
        rpcrdma_regbuf_free(req->rl_recvbuf);
        rpcrdma_regbuf_free(req->rl_sendbuf);
        rpcrdma_regbuf_free(req->rl_rdmabuf);
@@ -1151,18 +1153,18 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
        unsigned int count;
 
        count = 0;
-       spin_lock(&buf->rb_mrlock);
+       spin_lock(&buf->rb_lock);
        while ((mr = list_first_entry_or_null(&buf->rb_all_mrs,
                                              struct rpcrdma_mr,
                                              mr_all)) != NULL) {
                list_del(&mr->mr_all);
-               spin_unlock(&buf->rb_mrlock);
+               spin_unlock(&buf->rb_lock);
 
                frwr_release_mr(mr);
                count++;
-               spin_lock(&buf->rb_mrlock);
+               spin_lock(&buf->rb_lock);
        }
-       spin_unlock(&buf->rb_mrlock);
+       spin_unlock(&buf->rb_lock);
        r_xprt->rx_stats.mrs_allocated = 0;
 }
 
@@ -1177,7 +1179,7 @@ rpcrdma_mrs_destroy(struct rpcrdma_buffer *buf)
 void
 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
-       cancel_delayed_work_sync(&buf->rb_refresh_worker);
+       cancel_work_sync(&buf->rb_refresh_worker);
 
        rpcrdma_sendctxs_destroy(buf);
 
@@ -1215,22 +1217,10 @@ rpcrdma_mr_get(struct rpcrdma_xprt *r_xprt)
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_mr *mr;
 
-       spin_lock(&buf->rb_mrlock);
+       spin_lock(&buf->rb_lock);
        mr = rpcrdma_mr_pop(&buf->rb_mrs);
-       spin_unlock(&buf->rb_mrlock);
-       if (!mr)
-               goto out_nomrs;
+       spin_unlock(&buf->rb_lock);
        return mr;
-
-out_nomrs:
-       trace_xprtrdma_nomrs(r_xprt);
-       if (r_xprt->rx_ep.rep_connected != -ENODEV)
-               schedule_delayed_work(&buf->rb_refresh_worker, 0);
-
-       /* Allow the reply handler and refresh worker to run */
-       cond_resched();
-
-       return NULL;
 }
 
 /**
@@ -1241,7 +1231,6 @@ out_nomrs:
 void rpcrdma_mr_put(struct rpcrdma_mr *mr)
 {
        struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
-       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
 
        if (mr->mr_dir != DMA_NONE) {
                trace_xprtrdma_mr_unmap(mr);
@@ -1250,9 +1239,18 @@ void rpcrdma_mr_put(struct rpcrdma_mr *mr)
                mr->mr_dir = DMA_NONE;
        }
 
-       spin_lock(&buf->rb_mrlock);
+       rpcrdma_mr_push(mr, &mr->mr_req->rl_free_mrs);
+}
+
+static void rpcrdma_mr_free(struct rpcrdma_mr *mr)
+{
+       struct rpcrdma_xprt *r_xprt = mr->mr_xprt;
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
+
+       mr->mr_req = NULL;
+       spin_lock(&buf->rb_lock);
        rpcrdma_mr_push(mr, &buf->rb_mrs);
-       spin_unlock(&buf->rb_mrlock);
+       spin_unlock(&buf->rb_lock);
 }
 
 /**