aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.com>2017-06-18 00:38:57 -0400
committerJens Axboe <axboe@kernel.dk>2017-06-18 14:40:59 -0400
commit47e0fb461fca1a68a566c82fcc006cc787312d8c (patch)
tree5362bdaeb18fdbe069062d33cb27622088698374
parent011067b05668b05aae88e5a24cff0ca0a67ca0b0 (diff)
blk: make the bioset rescue_workqueue optional.
This patch converts bioset_create() to not create a workqueue by default, so alloctions will never trigger punt_bios_to_rescuer(). It also introduces a new flag BIOSET_NEED_RESCUER which tells bioset_create() to preserve the old behavior. All callers of bioset_create() that are inside block device drivers, are given the BIOSET_NEED_RESCUER flag. biosets used by filesystems or other top-level users do not need rescuing as the bio can never be queued behind other bios. This includes fs_bio_set, blkdev_dio_pool, btrfs_bioset, xfs_ioend_bioset, and one allocated by target_core_iblock.c. biosets used by md/raid do not need rescuing as their usage was recently audited and revised to never risk deadlock. It is hoped that most, if not all, of the remaining biosets can end up being the non-rescued version. Reviewed-by: Christoph Hellwig <hch@lst.de> Credit-to: Ming Lei <ming.lei@redhat.com> (minor fixes) Reviewed-by: Ming Lei <ming.lei@redhat.com> Signed-off-by: NeilBrown <neilb@suse.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--block/bio.c13
-rw-r--r--block/blk-core.c3
-rw-r--r--drivers/block/drbd/drbd_main.c4
-rw-r--r--drivers/md/bcache/super.c8
-rw-r--r--drivers/md/dm-crypt.c3
-rw-r--r--drivers/md/dm-io.c3
-rw-r--r--drivers/md/dm.c5
-rw-r--r--include/linux/bio.h1
8 files changed, 30 insertions, 10 deletions
diff --git a/block/bio.c b/block/bio.c
index 84b313bd3ce8..2bd064906e06 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -363,6 +363,8 @@ static void punt_bios_to_rescuer(struct bio_set *bs)
363 struct bio_list punt, nopunt; 363 struct bio_list punt, nopunt;
364 struct bio *bio; 364 struct bio *bio;
365 365
366 if (WARN_ON_ONCE(!bs->rescue_workqueue))
367 return;
366 /* 368 /*
367 * In order to guarantee forward progress we must punt only bios that 369 * In order to guarantee forward progress we must punt only bios that
368 * were allocated from this bio_set; otherwise, if there was a bio on 370 * were allocated from this bio_set; otherwise, if there was a bio on
@@ -474,7 +476,8 @@ struct bio *bio_alloc_bioset(gfp_t gfp_mask, unsigned int nr_iovecs,
474 476
475 if (current->bio_list && 477 if (current->bio_list &&
476 (!bio_list_empty(&current->bio_list[0]) || 478 (!bio_list_empty(&current->bio_list[0]) ||
477 !bio_list_empty(&current->bio_list[1]))) 479 !bio_list_empty(&current->bio_list[1])) &&
480 bs->rescue_workqueue)
478 gfp_mask &= ~__GFP_DIRECT_RECLAIM; 481 gfp_mask &= ~__GFP_DIRECT_RECLAIM;
479 482
480 p = mempool_alloc(bs->bio_pool, gfp_mask); 483 p = mempool_alloc(bs->bio_pool, gfp_mask);
@@ -1925,7 +1928,8 @@ EXPORT_SYMBOL(bioset_free);
1925 * bioset_create - Create a bio_set 1928 * bioset_create - Create a bio_set
1926 * @pool_size: Number of bio and bio_vecs to cache in the mempool 1929 * @pool_size: Number of bio and bio_vecs to cache in the mempool
1927 * @front_pad: Number of bytes to allocate in front of the returned bio 1930 * @front_pad: Number of bytes to allocate in front of the returned bio
1928 * @flags: Flags to modify behavior, currently only %BIOSET_NEED_BVECS 1931 * @flags: Flags to modify behavior, currently %BIOSET_NEED_BVECS
1932 * and %BIOSET_NEED_RESCUER
1929 * 1933 *
1930 * Description: 1934 * Description:
1931 * Set up a bio_set to be used with @bio_alloc_bioset. Allows the caller 1935 * Set up a bio_set to be used with @bio_alloc_bioset. Allows the caller
@@ -1936,6 +1940,8 @@ EXPORT_SYMBOL(bioset_free);
1936 * or things will break badly. 1940 * or things will break badly.
1937 * If %BIOSET_NEED_BVECS is set in @flags, a separate pool will be allocated 1941 * If %BIOSET_NEED_BVECS is set in @flags, a separate pool will be allocated
1938 * for allocating iovecs. This pool is not needed e.g. for bio_clone_fast(). 1942 * for allocating iovecs. This pool is not needed e.g. for bio_clone_fast().
1943 * If %BIOSET_NEED_RESCUER is set, a workqueue is created which can be used to
1944 * dispatch queued requests when the mempool runs out of space.
1939 * 1945 *
1940 */ 1946 */
1941struct bio_set *bioset_create(unsigned int pool_size, 1947struct bio_set *bioset_create(unsigned int pool_size,
@@ -1971,6 +1977,9 @@ struct bio_set *bioset_create(unsigned int pool_size,
1971 goto bad; 1977 goto bad;
1972 } 1978 }
1973 1979
1980 if (!(flags & BIOSET_NEED_RESCUER))
1981 return bs;
1982
1974 bs->rescue_workqueue = alloc_workqueue("bioset", WQ_MEM_RECLAIM, 0); 1983 bs->rescue_workqueue = alloc_workqueue("bioset", WQ_MEM_RECLAIM, 0);
1975 if (!bs->rescue_workqueue) 1984 if (!bs->rescue_workqueue)
1976 goto bad; 1985 goto bad;
diff --git a/block/blk-core.c b/block/blk-core.c
index 62cf92550512..9bd10c46a538 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -790,7 +790,8 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
790 if (q->id < 0) 790 if (q->id < 0)
791 goto fail_q; 791 goto fail_q;
792 792
793 q->bio_split = bioset_create(BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS); 793 q->bio_split = bioset_create(BIO_POOL_SIZE, 0, (BIOSET_NEED_BVECS |
794 BIOSET_NEED_RESCUER));
794 if (!q->bio_split) 795 if (!q->bio_split)
795 goto fail_id; 796 goto fail_id;
796 797
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index b395fe391171..bdf51b6977cf 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2165,7 +2165,9 @@ static int drbd_create_mempools(void)
2165 goto Enomem; 2165 goto Enomem;
2166 2166
2167 /* mempools */ 2167 /* mempools */
2168 drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0, BIOSET_NEED_BVECS); 2168 drbd_md_io_bio_set = bioset_create(DRBD_MIN_POOL_PAGES, 0,
2169 BIOSET_NEED_BVECS |
2170 BIOSET_NEED_RESCUER);
2169 if (drbd_md_io_bio_set == NULL) 2171 if (drbd_md_io_bio_set == NULL)
2170 goto Enomem; 2172 goto Enomem;
2171 2173
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index abd6e825b39b..8352fad765f6 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -782,7 +782,9 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
782 782
783 minor *= BCACHE_MINORS; 783 minor *= BCACHE_MINORS;
784 784
785 if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio), BIOSET_NEED_BVECS)) || 785 if (!(d->bio_split = bioset_create(4, offsetof(struct bbio, bio),
786 BIOSET_NEED_BVECS |
787 BIOSET_NEED_RESCUER)) ||
786 !(d->disk = alloc_disk(BCACHE_MINORS))) { 788 !(d->disk = alloc_disk(BCACHE_MINORS))) {
787 ida_simple_remove(&bcache_minor, minor); 789 ida_simple_remove(&bcache_minor, minor);
788 return -ENOMEM; 790 return -ENOMEM;
@@ -1516,7 +1518,9 @@ struct cache_set *bch_cache_set_alloc(struct cache_sb *sb)
1516 sizeof(struct bbio) + sizeof(struct bio_vec) * 1518 sizeof(struct bbio) + sizeof(struct bio_vec) *
1517 bucket_pages(c))) || 1519 bucket_pages(c))) ||
1518 !(c->fill_iter = mempool_create_kmalloc_pool(1, iter_size)) || 1520 !(c->fill_iter = mempool_create_kmalloc_pool(1, iter_size)) ||
1519 !(c->bio_split = bioset_create(4, offsetof(struct bbio, bio), BIOSET_NEED_BVECS)) || 1521 !(c->bio_split = bioset_create(4, offsetof(struct bbio, bio),
1522 BIOSET_NEED_BVECS |
1523 BIOSET_NEED_RESCUER)) ||
1520 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) || 1524 !(c->uuids = alloc_bucket_pages(GFP_KERNEL, c)) ||
1521 !(c->moving_gc_wq = alloc_workqueue("bcache_gc", 1525 !(c->moving_gc_wq = alloc_workqueue("bcache_gc",
1522 WQ_MEM_RECLAIM, 0)) || 1526 WQ_MEM_RECLAIM, 0)) ||
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 237ff8e9752a..9e1b72e8f7ef 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -2677,7 +2677,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
2677 goto bad; 2677 goto bad;
2678 } 2678 }
2679 2679
2680 cc->bs = bioset_create(MIN_IOS, 0, BIOSET_NEED_BVECS); 2680 cc->bs = bioset_create(MIN_IOS, 0, (BIOSET_NEED_BVECS |
2681 BIOSET_NEED_RESCUER));
2681 if (!cc->bs) { 2682 if (!cc->bs) {
2682 ti->error = "Cannot allocate crypt bioset"; 2683 ti->error = "Cannot allocate crypt bioset";
2683 goto bad; 2684 goto bad;
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 5c4121024d92..81248a8a8b57 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -58,7 +58,8 @@ struct dm_io_client *dm_io_client_create(void)
58 if (!client->pool) 58 if (!client->pool)
59 goto bad; 59 goto bad;
60 60
61 client->bios = bioset_create(min_ios, 0, BIOSET_NEED_BVECS); 61 client->bios = bioset_create(min_ios, 0, (BIOSET_NEED_BVECS |
62 BIOSET_NEED_RESCUER));
62 if (!client->bios) 63 if (!client->bios)
63 goto bad; 64 goto bad;
64 65
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 3394a311de3d..fbd06b9f9467 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1036,7 +1036,8 @@ static void flush_current_bio_list(struct blk_plug_cb *cb, bool from_schedule)
1036 1036
1037 while ((bio = bio_list_pop(&list))) { 1037 while ((bio = bio_list_pop(&list))) {
1038 struct bio_set *bs = bio->bi_pool; 1038 struct bio_set *bs = bio->bi_pool;
1039 if (unlikely(!bs) || bs == fs_bio_set) { 1039 if (unlikely(!bs) || bs == fs_bio_set ||
1040 !bs->rescue_workqueue) {
1040 bio_list_add(&current->bio_list[i], bio); 1041 bio_list_add(&current->bio_list[i], bio);
1041 continue; 1042 continue;
1042 } 1043 }
@@ -2660,7 +2661,7 @@ struct dm_md_mempools *dm_alloc_md_mempools(struct mapped_device *md, enum dm_qu
2660 BUG(); 2661 BUG();
2661 } 2662 }
2662 2663
2663 pools->bs = bioset_create(pool_size, front_pad, 0); 2664 pools->bs = bioset_create(pool_size, front_pad, BIOSET_NEED_RESCUER);
2664 if (!pools->bs) 2665 if (!pools->bs)
2665 goto out; 2666 goto out;
2666 2667
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 985dc645637e..32c786baa10a 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -376,6 +376,7 @@ static inline struct bio *bio_next_split(struct bio *bio, int sectors,
376extern struct bio_set *bioset_create(unsigned int, unsigned int, int flags); 376extern struct bio_set *bioset_create(unsigned int, unsigned int, int flags);
377enum { 377enum {
378 BIOSET_NEED_BVECS = BIT(0), 378 BIOSET_NEED_BVECS = BIT(0),
379 BIOSET_NEED_RESCUER = BIT(1),
379}; 380};
380extern void bioset_free(struct bio_set *); 381extern void bioset_free(struct bio_set *);
381extern mempool_t *biovec_create_pool(int pool_entries); 382extern mempool_t *biovec_create_pool(int pool_entries);