dm: limit the number of bios in progress Limit the number of bios in progress to the nr_requests value. The default value is 1024. Signed-off-by: Mikulas Patocka --- drivers/md/dm-core.h | 1 + drivers/md/dm.c | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 3 deletions(-) Index: linux-4.13-rc5/drivers/md/dm.c =================================================================== --- linux-4.13-rc5.orig/drivers/md/dm.c +++ linux-4.13-rc5/drivers/md/dm.c @@ -523,6 +523,12 @@ static void update_in_flight(struct mapp atomic_read(&md->pending[rw][1])); } +static bool limit_reached(struct mapped_device *md, int sync) +{ + return atomic_read(&md->pending[0][sync]) + + atomic_read(&md->pending[1][sync]) >= md->queue->nr_requests; +} + static void start_io_acct(struct dm_io *io) { struct mapped_device *md = io->md; @@ -538,6 +544,10 @@ static void start_io_acct(struct dm_io * rw = bio_data_dir(bio); sync = op_is_sync(bio->bi_opf); + if (unlikely(limit_reached(md, sync))) + ___wait_event(md->wait, !limit_reached(md, sync), + TASK_UNINTERRUPTIBLE, 1, 0, io_schedule()); + atomic_inc(&md->pending[rw][sync]); update_in_flight(md, rw); @@ -571,12 +581,11 @@ static void end_io_acct(struct dm_io *io update_in_flight(md, rw); - pending += atomic_read(&md->pending[rw][sync^1]); pending += atomic_read(&md->pending[rw^1][sync]); - pending += atomic_read(&md->pending[rw^1][sync^1]); /* nudge anyone waiting on suspend queue */ - if (!pending) + if (unlikely(waitqueue_active(&md->wait)) && + pending < md->queue->nr_requests) wake_up(&md->wait); } @@ -2117,6 +2126,7 @@ int dm_setup_md_queue(struct mapped_devi case DM_TYPE_DAX_BIO_BASED: dm_init_normal_md_queue(md); blk_queue_make_request(md->queue, dm_make_request); + md->queue->nr_requests = DEFAULT_NR_REQUESTS; /* * DM handles splitting bios as needed. Free the bio_split bioset * since it won't be used (saves 1 process per bio-based DM device). Index: linux-4.13-rc5/drivers/md/dm-core.h =================================================================== --- linux-4.13-rc5.orig/drivers/md/dm-core.h +++ linux-4.13-rc5/drivers/md/dm-core.h @@ -18,6 +18,7 @@ #include "dm.h" #define DM_RESERVED_MAX_IOS 1024 +#define DEFAULT_NR_REQUESTS 1024 struct dm_kobject_holder { struct kobject kobj;