staging: lustre: Allocate the correct number of rtr buffers
[deliverable/linux.git] / drivers / staging / lustre / lnet / lnet / router.c
index c1e7bc5e60fcc3fdf7c2c6f49c7298dbd0b3dc65..198ff03156c1d3f41a7653b6f7d2bbd200625935 100644 (file)
@@ -1359,6 +1359,7 @@ lnet_rtrpool_free_bufs(lnet_rtrbufpool_t *rbp, int cpt)
        lnet_net_lock(cpt);
        lnet_drop_routed_msgs_locked(&rbp->rbp_msgs, cpt);
        list_splice_init(&rbp->rbp_bufs, &tmp);
+       rbp->rbp_req_nbuffers = 0;
        rbp->rbp_nbuffers = 0;
        rbp->rbp_credits = 0;
        rbp->rbp_mincredits = 0;
@@ -1379,20 +1380,33 @@ lnet_rtrpool_adjust_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt)
        lnet_rtrbuf_t *rb;
        int num_rb;
        int num_buffers = 0;
+       int old_req_nbufs;
        int npages = rbp->rbp_npages;
 
+       lnet_net_lock(cpt);
        /*
         * If we are called for less buffers than already in the pool, we
-        * just lower the nbuffers number and excess buffers will be
+        * just lower the req_nbuffers number and excess buffers will be
         * thrown away as they are returned to the free list.  Credits
         * then get adjusted as well.
+        * If we already have enough buffers allocated to serve the
+        * increase requested, then we can treat that the same way as we
+        * do the decrease.
         */
-       if (nbufs <= rbp->rbp_nbuffers) {
-               lnet_net_lock(cpt);
-               rbp->rbp_nbuffers = nbufs;
+       num_rb = nbufs - rbp->rbp_nbuffers;
+       if (nbufs <= rbp->rbp_req_nbuffers || num_rb <= 0) {
+               rbp->rbp_req_nbuffers = nbufs;
                lnet_net_unlock(cpt);
                return 0;
        }
+       /*
+        * store the older value of rbp_req_nbuffers and then set it to
+        * the new request to prevent lnet_return_rx_credits_locked() from
+        * freeing buffers that we need to keep around
+        */
+       old_req_nbufs = rbp->rbp_req_nbuffers;
+       rbp->rbp_req_nbuffers = nbufs;
+       lnet_net_unlock(cpt);
 
        INIT_LIST_HEAD(&rb_list);
 
@@ -1401,19 +1415,21 @@ lnet_rtrpool_adjust_bufs(lnet_rtrbufpool_t *rbp, int nbufs, int cpt)
         * allocated successfully then join this list to the rbp buffer
         * list. If not then free all allocated buffers.
         */
-       num_rb = rbp->rbp_nbuffers;
-
-       while (num_rb < nbufs) {
+       while (num_rb-- > 0) {
                rb = lnet_new_rtrbuf(rbp, cpt);
                if (!rb) {
                        CERROR("Failed to allocate %d route bufs of %d pages\n",
                               nbufs, npages);
+
+                       lnet_net_lock(cpt);
+                       rbp->rbp_req_nbuffers = old_req_nbufs;
+                       lnet_net_unlock(cpt);
+
                        goto failed;
                }
 
                list_add(&rb->rb_list, &rb_list);
                num_buffers++;
-               num_rb++;
        }
 
        lnet_net_lock(cpt);
This page took 0.028627 seconds and 5 git commands to generate.