This is a note to let you know that I've just added the patch titled

    md/raid1: r1buf_pool_alloc: free allocate pages when subsequent allocation 
fails.

to the 3.10-stable tree which can be found at:
    
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     
md-raid1-r1buf_pool_alloc-free-allocate-pages-when-subsequent-allocation-fails.patch
and it can be found in the queue-3.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.


>From da1aab3dca9aa88ae34ca392470b8943159e25fe Mon Sep 17 00:00:00 2001
From: NeilBrown <ne...@suse.de>
Date: Wed, 9 Apr 2014 12:25:43 +1000
Subject: md/raid1: r1buf_pool_alloc: free allocate pages when subsequent 
allocation fails.

From: NeilBrown <ne...@suse.de>

commit da1aab3dca9aa88ae34ca392470b8943159e25fe upstream.

When performing a user-request check/repair (MD_RECOVERY_REQUEST is set)
on a raid1, we allocate multiple bios each with their own set of pages.

If the page allocations for one bio fails, we currently do *not* free
the pages allocated for the previous bios, nor do we free the bio itself.

This patch frees all the already-allocate pages, and makes sure that
all the bios are freed as well.

This bug can cause a memory leak which can ultimately OOM a machine.
It was introduced in 3.10-rc1.

Fixes: a07876064a0b73ab5ef1ebcf14b1cf0231c07858
Cc: Kent Overstreet <koverstr...@google.com>
Reported-by: Russell King - ARM Linux <li...@arm.linux.org.uk>
Signed-off-by: NeilBrown <ne...@suse.de>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 drivers/md/raid1.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -94,6 +94,7 @@ static void * r1buf_pool_alloc(gfp_t gfp
        struct pool_info *pi = data;
        struct r1bio *r1_bio;
        struct bio *bio;
+       int need_pages;
        int i, j;
 
        r1_bio = r1bio_pool_alloc(gfp_flags, pi);
@@ -116,15 +117,15 @@ static void * r1buf_pool_alloc(gfp_t gfp
         * RESYNC_PAGES for each bio.
         */
        if (test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery))
-               j = pi->raid_disks;
+               need_pages = pi->raid_disks;
        else
-               j = 1;
-       while(j--) {
+               need_pages = 1;
+       for (j = 0; j < need_pages; j++) {
                bio = r1_bio->bios[j];
                bio->bi_vcnt = RESYNC_PAGES;
 
                if (bio_alloc_pages(bio, gfp_flags))
-                       goto out_free_bio;
+                       goto out_free_pages;
        }
        /* If not user-requests, copy the page pointers to all bios */
        if (!test_bit(MD_RECOVERY_REQUESTED, &pi->mddev->recovery)) {
@@ -138,6 +139,14 @@ static void * r1buf_pool_alloc(gfp_t gfp
 
        return r1_bio;
 
+out_free_pages:
+       while (--j >= 0) {
+               struct bio_vec *bv;
+
+               bio_for_each_segment_all(bv, r1_bio->bios[j], i)
+                       __free_page(bv->bv_page);
+       }
+
 out_free_bio:
        while (++j < pi->raid_disks)
                bio_put(r1_bio->bios[j]);


Patches currently in stable-queue which might be from ne...@suse.de are

queue-3.10/md-raid1-r1buf_pool_alloc-free-allocate-pages-when-subsequent-allocation-fails.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to