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.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) Index: linux-3.17/drivers/md/dm.c =================================================================== --- linux-3.17.orig/drivers/md/dm.c 2014-10-10 15:55:39.000000000 +0200 +++ linux-3.17/drivers/md/dm.c 2014-10-10 20:26:00.000000000 +0200 @@ -215,6 +215,8 @@ struct dm_md_mempools { #define RESERVED_BIO_BASED_IOS 16 #define RESERVED_REQUEST_BASED_IOS 256 #define RESERVED_MAX_IOS 1024 +#define DEFAULT_NR_REQUESTS 1024 + static struct kmem_cache *_io_cache; static struct kmem_cache *_rq_tio_cache; @@ -581,6 +583,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; @@ -596,6 +604,10 @@ static void start_io_acct(struct dm_io * rw = bio_data_dir(bio); sync = rw_is_sync(bio->bi_rw); + 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); @@ -631,12 +643,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); } @@ -1989,6 +2000,7 @@ static void dm_init_md_queue(struct mapp blk_queue_make_request(md->queue, dm_request); blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); blk_queue_merge_bvec(md->queue, dm_merge_bvec); + md->queue->nr_requests = DEFAULT_NR_REQUESTS; } /*