3.2.71-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Joe Thornber <e...@redhat.com>

commit a822c83e47d97cdef38c4352e1ef62d9f46cfe98 upstream.

Given the pool's cell_sort_array holds 8192 pointers it triggers an
order 5 allocation via kmalloc.  This order 5 allocation is prone to
failure as system memory gets more fragmented over time.

Fix this by allocating the cell_sort_array using vmalloc.

Signed-off-by: Joe Thornber <e...@redhat.com>
Signed-off-by: Mike Snitzer <snit...@redhat.com>
[bwh: Backported to 3.2: make a similar change in prison_{create,destroy}()]
Signed-off-by: Ben Hutchings <b...@decadent.org.uk>
---
 drivers/md/dm-thin.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/module.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
 
 #define        DM_MSG_PREFIX   "thin"
 
@@ -158,9 +159,7 @@ static struct bio_prison *prison_create(
 {
        unsigned i;
        uint32_t nr_buckets = calc_nr_buckets(nr_cells);
-       size_t len = sizeof(struct bio_prison) +
-               (sizeof(struct hlist_head) * nr_buckets);
-       struct bio_prison *prison = kmalloc(len, GFP_KERNEL);
+       struct bio_prison *prison = kmalloc(sizeof(*prison), GFP_KERNEL);
 
        if (!prison)
                return NULL;
@@ -173,9 +172,15 @@ static struct bio_prison *prison_create(
                return NULL;
        }
 
+       prison->cells = vmalloc(sizeof(*prison->cells) * nr_buckets);
+       if (!prison->cells) {
+               mempool_destroy(prison->cell_pool);
+               kfree(prison);
+               return NULL;
+       }
+
        prison->nr_buckets = nr_buckets;
        prison->hash_mask = nr_buckets - 1;
-       prison->cells = (struct hlist_head *) (prison + 1);
        for (i = 0; i < nr_buckets; i++)
                INIT_HLIST_HEAD(prison->cells + i);
 
@@ -184,6 +189,7 @@ static struct bio_prison *prison_create(
 
 static void prison_destroy(struct bio_prison *prison)
 {
+       vfree(prison->cells);
        mempool_destroy(prison->cell_pool);
        kfree(prison);
 }

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to