aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
authorLukas Czerner <lczerner@redhat.com>2012-11-30 05:42:41 -0500
committerJens Axboe <axboe@kernel.dk>2012-11-30 05:48:05 -0500
commit7b5a35225b0d4fd779cf79d7624e63d1957f6c4d (patch)
tree5e2324e3b657b8ead9c0cdd58c6ed5d79f8e76f8 /drivers/block/loop.c
parenteed8c02e680c04cd737e0a9cef74e68d8eb0cefa (diff)
loop: Limit the number of requests in the bio list
Currently there is not limitation of number of requests in the loop bio list. This can lead into some nasty situations when the caller spawns tons of bio requests taking huge amount of memory. This is even more obvious with discard where blkdev_issue_discard() will submit all bios for the range and wait for them to finish afterwards. On really big loop devices and slow backing file system this can lead to OOM situation as reported by Dave Chinner. With this patch we will wait in loop_make_request() if the number of bios in the loop bio list would exceed 'nr_congestion_on'. We'll wake up the process as we process the bios form the list. Some threshold hysteresis is in place to avoid high frequency oscillation. Signed-off-by: Lukas Czerner <lczerner@redhat.com> Reported-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index e9d594fd12cb..800aec7927de 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -463,6 +463,7 @@ out:
463 */ 463 */
464static void loop_add_bio(struct loop_device *lo, struct bio *bio) 464static void loop_add_bio(struct loop_device *lo, struct bio *bio)
465{ 465{
466 lo->lo_bio_count++;
466 bio_list_add(&lo->lo_bio_list, bio); 467 bio_list_add(&lo->lo_bio_list, bio);
467} 468}
468 469
@@ -471,6 +472,7 @@ static void loop_add_bio(struct loop_device *lo, struct bio *bio)
471 */ 472 */
472static struct bio *loop_get_bio(struct loop_device *lo) 473static struct bio *loop_get_bio(struct loop_device *lo)
473{ 474{
475 lo->lo_bio_count--;
474 return bio_list_pop(&lo->lo_bio_list); 476 return bio_list_pop(&lo->lo_bio_list);
475} 477}
476 478
@@ -489,6 +491,10 @@ static void loop_make_request(struct request_queue *q, struct bio *old_bio)
489 goto out; 491 goto out;
490 if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY))) 492 if (unlikely(rw == WRITE && (lo->lo_flags & LO_FLAGS_READ_ONLY)))
491 goto out; 493 goto out;
494 if (lo->lo_bio_count >= q->nr_congestion_on)
495 wait_event_lock_irq(lo->lo_req_wait,
496 lo->lo_bio_count < q->nr_congestion_off,
497 lo->lo_lock);
492 loop_add_bio(lo, old_bio); 498 loop_add_bio(lo, old_bio);
493 wake_up(&lo->lo_event); 499 wake_up(&lo->lo_event);
494 spin_unlock_irq(&lo->lo_lock); 500 spin_unlock_irq(&lo->lo_lock);
@@ -546,6 +552,8 @@ static int loop_thread(void *data)
546 continue; 552 continue;
547 spin_lock_irq(&lo->lo_lock); 553 spin_lock_irq(&lo->lo_lock);
548 bio = loop_get_bio(lo); 554 bio = loop_get_bio(lo);
555 if (lo->lo_bio_count < lo->lo_queue->nr_congestion_off)
556 wake_up(&lo->lo_req_wait);
549 spin_unlock_irq(&lo->lo_lock); 557 spin_unlock_irq(&lo->lo_lock);
550 558
551 BUG_ON(!bio); 559 BUG_ON(!bio);
@@ -873,6 +881,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
873 lo->transfer = transfer_none; 881 lo->transfer = transfer_none;
874 lo->ioctl = NULL; 882 lo->ioctl = NULL;
875 lo->lo_sizelimit = 0; 883 lo->lo_sizelimit = 0;
884 lo->lo_bio_count = 0;
876 lo->old_gfp_mask = mapping_gfp_mask(mapping); 885 lo->old_gfp_mask = mapping_gfp_mask(mapping);
877 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS)); 886 mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
878 887
@@ -1660,6 +1669,7 @@ static int loop_add(struct loop_device **l, int i)
1660 lo->lo_number = i; 1669 lo->lo_number = i;
1661 lo->lo_thread = NULL; 1670 lo->lo_thread = NULL;
1662 init_waitqueue_head(&lo->lo_event); 1671 init_waitqueue_head(&lo->lo_event);
1672 init_waitqueue_head(&lo->lo_req_wait);
1663 spin_lock_init(&lo->lo_lock); 1673 spin_lock_init(&lo->lo_lock);
1664 disk->major = LOOP_MAJOR; 1674 disk->major = LOOP_MAJOR;
1665 disk->first_minor = i << part_shift; 1675 disk->first_minor = i << part_shift;