aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/raid5.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2006-03-27 04:18:17 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-27 11:45:03 -0500
commitf6344757a92e5466bf8c23a74ee8f972ff35cb05 (patch)
treedf390903800e7ea8dcf117d9b5a376e34fb1c741 /drivers/md/raid5.c
parentb3b46be38aef5c46a4e144f1bcb8d0cc6bf3ff97 (diff)
[PATCH] md: Remove bi_end_io call out from under a spinlock
raid5 overloads bi_phys_segments to count the number of blocks that the request was broken in to so that it knows when the bio is completely handled. Accessing this must always be done under a spinlock. In one case we also call bi_end_io under that spinlock, which probably isn't ideal as bi_end_io could be expensive (even though it isn't allowed to sleep). So we reducde the range of the spinlock to just accessing bi_phys_segments. Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/raid5.c')
-rw-r--r--drivers/md/raid5.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 59c8772ee4ee..dae740adaf65 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1743,6 +1743,7 @@ static int make_request(request_queue_t *q, struct bio * bi)
1743 sector_t logical_sector, last_sector; 1743 sector_t logical_sector, last_sector;
1744 struct stripe_head *sh; 1744 struct stripe_head *sh;
1745 const int rw = bio_data_dir(bi); 1745 const int rw = bio_data_dir(bi);
1746 int remaining;
1746 1747
1747 if (unlikely(bio_barrier(bi))) { 1748 if (unlikely(bio_barrier(bi))) {
1748 bio_endio(bi, bi->bi_size, -EOPNOTSUPP); 1749 bio_endio(bi, bi->bi_size, -EOPNOTSUPP);
@@ -1852,7 +1853,9 @@ static int make_request(request_queue_t *q, struct bio * bi)
1852 1853
1853 } 1854 }
1854 spin_lock_irq(&conf->device_lock); 1855 spin_lock_irq(&conf->device_lock);
1855 if (--bi->bi_phys_segments == 0) { 1856 remaining = --bi->bi_phys_segments;
1857 spin_unlock_irq(&conf->device_lock);
1858 if (remaining == 0) {
1856 int bytes = bi->bi_size; 1859 int bytes = bi->bi_size;
1857 1860
1858 if ( bio_data_dir(bi) == WRITE ) 1861 if ( bio_data_dir(bi) == WRITE )
@@ -1860,7 +1863,6 @@ static int make_request(request_queue_t *q, struct bio * bi)
1860 bi->bi_size = 0; 1863 bi->bi_size = 0;
1861 bi->bi_end_io(bi, bytes, 0); 1864 bi->bi_end_io(bi, bytes, 0);
1862 } 1865 }
1863 spin_unlock_irq(&conf->device_lock);
1864 return 0; 1866 return 0;
1865} 1867}
1866 1868