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