[PATCH 01/10] use seperate bioset for REQ_TYPE_BLOCK_PC

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mike Christie <michaelc@xxxxxxxxxxx>

If we are failing over a device or trying to do sg io to add a path to a
device where all paths are failed, we do not want to allocate bios from the
same bioset as the FS above it, because the device could have been internally
queueing IO while there were no paths and the fs bioset could be depleted.

Signed-off-by: Mike Christie <michaelc@xxxxxxxxxxx>
---
 fs/bio.c |   22 +++++++++++++++++++---
 1 files changed, 19 insertions(+), 3 deletions(-)

diff --git a/fs/bio.c b/fs/bio.c
index d59ddbf..0781e65 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -75,6 +75,10 @@ struct bio_set {
  * IO code that does not need private memory pools.
  */
 static struct bio_set *fs_bio_set;
+/*
+ * blk_bio_set is for block layer commands like REQ_TYPE_BLOCK_PC
+ */
+static struct bio_set *blk_bio_set;
 
 static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
 {
@@ -128,6 +132,11 @@ static void bio_fs_destructor(struct bio *bio)
 	bio_free(bio, fs_bio_set);
 }
 
+static void bio_blk_destructor(struct bio *bio)
+{
+	bio_free(bio, blk_bio_set);
+}
+
 void bio_init(struct bio *bio)
 {
 	memset(bio, 0, sizeof(*bio));
@@ -532,11 +541,12 @@ struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr,
 	bmd->userptr = (void __user *) uaddr;
 
 	ret = -ENOMEM;
-	bio = bio_alloc(GFP_KERNEL, end - start);
+	bio = bio_alloc_bioset(GFP_KERNEL, end - start, blk_bio_set);
 	if (!bio)
 		goto out_bmd;
 
 	bio->bi_rw |= (!write_to_vm << BIO_RW);
+	bio->bi_destructor = bio_blk_destructor;
 
 	ret = 0;
 	while (len) {
@@ -620,9 +630,10 @@ static struct bio *__bio_map_user_iov(struct request_queue *q,
 	if (!nr_pages)
 		return ERR_PTR(-EINVAL);
 
-	bio = bio_alloc(GFP_KERNEL, nr_pages);
+	bio = bio_alloc_bioset(GFP_KERNEL, nr_pages, blk_bio_set);
 	if (!bio)
 		return ERR_PTR(-ENOMEM);
+	bio->bi_destructor = bio_blk_destructor;
 
 	ret = -ENOMEM;
 	pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
@@ -805,9 +816,10 @@ static struct bio *__bio_map_kern(struct request_queue *q, void *data,
 	int offset, i;
 	struct bio *bio;
 
-	bio = bio_alloc(gfp_mask, nr_pages);
+	bio = bio_alloc_bioset(gfp_mask, nr_pages, blk_bio_set);
 	if (!bio)
 		return ERR_PTR(-ENOMEM);
+	bio->bi_destructor = bio_blk_destructor;
 
 	offset = offset_in_page(kaddr);
 	for (i = 0; i < nr_pages; i++) {
@@ -1172,6 +1184,10 @@ static int __init init_bio(void)
 	if (!fs_bio_set)
 		panic("bio: can't allocate bios\n");
 
+	blk_bio_set = bioset_create(BIO_POOL_SIZE, 2);
+	if (!blk_bio_set)
+		panic("Failed to create blk_bio_set");
+
 	bio_split_pool = mempool_create_kmalloc_pool(BIO_SPLIT_ENTRIES,
 						     sizeof(struct bio_pair));
 	if (!bio_split_pool)
-- 
1.5.1.2

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux