提交 e3881a68 编写于 作者: L Lars Ellenberg 提交者: Linus Torvalds

[PATCH] md: pass down BIO_RW_SYNC in raid{1,10}

md raidX make_request functions strip off the BIO_RW_SYNC flag, thus
introducing additional latency.

Fixing this in raid1 and raid10 seems to be straightforward enough.

For our particular usage case in DRBD, passing this flag improved some
initialization time from ~5 minutes to ~5 seconds.
Acked-by: NNeilBrown <neilb@suse.de>
Signed-off-by: NLars Ellenberg <lars@linbit.com>
Acked-by: NJens Axboe <jens.axboe@oracle.com>
Cc: <stable@kernel.org>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NLinus Torvalds <torvalds@osdl.org>
上级 664c0d3d
...@@ -775,6 +775,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -775,6 +775,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
struct bio_list bl; struct bio_list bl;
struct page **behind_pages = NULL; struct page **behind_pages = NULL;
const int rw = bio_data_dir(bio); const int rw = bio_data_dir(bio);
const int do_sync = bio_sync(bio);
int do_barriers; int do_barriers;
/* /*
...@@ -835,7 +836,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -835,7 +836,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset; read_bio->bi_sector = r1_bio->sector + mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; read_bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_end_io = raid1_end_read_request; read_bio->bi_end_io = raid1_end_read_request;
read_bio->bi_rw = READ; read_bio->bi_rw = READ | do_sync;
read_bio->bi_private = r1_bio; read_bio->bi_private = r1_bio;
generic_make_request(read_bio); generic_make_request(read_bio);
...@@ -906,7 +907,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -906,7 +907,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset; mbio->bi_sector = r1_bio->sector + conf->mirrors[i].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[i].rdev->bdev; mbio->bi_bdev = conf->mirrors[i].rdev->bdev;
mbio->bi_end_io = raid1_end_write_request; mbio->bi_end_io = raid1_end_write_request;
mbio->bi_rw = WRITE | do_barriers; mbio->bi_rw = WRITE | do_barriers | do_sync;
mbio->bi_private = r1_bio; mbio->bi_private = r1_bio;
if (behind_pages) { if (behind_pages) {
...@@ -941,6 +942,8 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -941,6 +942,8 @@ static int make_request(request_queue_t *q, struct bio * bio)
blk_plug_device(mddev->queue); blk_plug_device(mddev->queue);
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
if (do_sync)
md_wakeup_thread(mddev->thread);
#if 0 #if 0
while ((bio = bio_list_pop(&bl)) != NULL) while ((bio = bio_list_pop(&bl)) != NULL)
generic_make_request(bio); generic_make_request(bio);
...@@ -1541,6 +1544,7 @@ static void raid1d(mddev_t *mddev) ...@@ -1541,6 +1544,7 @@ static void raid1d(mddev_t *mddev)
* We already have a nr_pending reference on these rdevs. * We already have a nr_pending reference on these rdevs.
*/ */
int i; int i;
const int do_sync = bio_sync(r1_bio->master_bio);
clear_bit(R1BIO_BarrierRetry, &r1_bio->state); clear_bit(R1BIO_BarrierRetry, &r1_bio->state);
clear_bit(R1BIO_Barrier, &r1_bio->state); clear_bit(R1BIO_Barrier, &r1_bio->state);
for (i=0; i < conf->raid_disks; i++) for (i=0; i < conf->raid_disks; i++)
...@@ -1561,7 +1565,7 @@ static void raid1d(mddev_t *mddev) ...@@ -1561,7 +1565,7 @@ static void raid1d(mddev_t *mddev)
conf->mirrors[i].rdev->data_offset; conf->mirrors[i].rdev->data_offset;
bio->bi_bdev = conf->mirrors[i].rdev->bdev; bio->bi_bdev = conf->mirrors[i].rdev->bdev;
bio->bi_end_io = raid1_end_write_request; bio->bi_end_io = raid1_end_write_request;
bio->bi_rw = WRITE; bio->bi_rw = WRITE | do_sync;
bio->bi_private = r1_bio; bio->bi_private = r1_bio;
r1_bio->bios[i] = bio; r1_bio->bios[i] = bio;
generic_make_request(bio); generic_make_request(bio);
...@@ -1593,6 +1597,7 @@ static void raid1d(mddev_t *mddev) ...@@ -1593,6 +1597,7 @@ static void raid1d(mddev_t *mddev)
(unsigned long long)r1_bio->sector); (unsigned long long)r1_bio->sector);
raid_end_bio_io(r1_bio); raid_end_bio_io(r1_bio);
} else { } else {
const int do_sync = bio_sync(r1_bio->master_bio);
r1_bio->bios[r1_bio->read_disk] = r1_bio->bios[r1_bio->read_disk] =
mddev->ro ? IO_BLOCKED : NULL; mddev->ro ? IO_BLOCKED : NULL;
r1_bio->read_disk = disk; r1_bio->read_disk = disk;
...@@ -1608,7 +1613,7 @@ static void raid1d(mddev_t *mddev) ...@@ -1608,7 +1613,7 @@ static void raid1d(mddev_t *mddev)
bio->bi_sector = r1_bio->sector + rdev->data_offset; bio->bi_sector = r1_bio->sector + rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio->bi_bdev = rdev->bdev;
bio->bi_end_io = raid1_end_read_request; bio->bi_end_io = raid1_end_read_request;
bio->bi_rw = READ; bio->bi_rw = READ | do_sync;
bio->bi_private = r1_bio; bio->bi_private = r1_bio;
unplug = 1; unplug = 1;
generic_make_request(bio); generic_make_request(bio);
......
...@@ -782,6 +782,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -782,6 +782,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
int i; int i;
int chunk_sects = conf->chunk_mask + 1; int chunk_sects = conf->chunk_mask + 1;
const int rw = bio_data_dir(bio); const int rw = bio_data_dir(bio);
const int do_sync = bio_sync(bio);
struct bio_list bl; struct bio_list bl;
unsigned long flags; unsigned long flags;
...@@ -863,7 +864,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -863,7 +864,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
mirror->rdev->data_offset; mirror->rdev->data_offset;
read_bio->bi_bdev = mirror->rdev->bdev; read_bio->bi_bdev = mirror->rdev->bdev;
read_bio->bi_end_io = raid10_end_read_request; read_bio->bi_end_io = raid10_end_read_request;
read_bio->bi_rw = READ; read_bio->bi_rw = READ | do_sync;
read_bio->bi_private = r10_bio; read_bio->bi_private = r10_bio;
generic_make_request(read_bio); generic_make_request(read_bio);
...@@ -909,7 +910,7 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -909,7 +910,7 @@ static int make_request(request_queue_t *q, struct bio * bio)
conf->mirrors[d].rdev->data_offset; conf->mirrors[d].rdev->data_offset;
mbio->bi_bdev = conf->mirrors[d].rdev->bdev; mbio->bi_bdev = conf->mirrors[d].rdev->bdev;
mbio->bi_end_io = raid10_end_write_request; mbio->bi_end_io = raid10_end_write_request;
mbio->bi_rw = WRITE; mbio->bi_rw = WRITE | do_sync;
mbio->bi_private = r10_bio; mbio->bi_private = r10_bio;
atomic_inc(&r10_bio->remaining); atomic_inc(&r10_bio->remaining);
...@@ -922,6 +923,9 @@ static int make_request(request_queue_t *q, struct bio * bio) ...@@ -922,6 +923,9 @@ static int make_request(request_queue_t *q, struct bio * bio)
blk_plug_device(mddev->queue); blk_plug_device(mddev->queue);
spin_unlock_irqrestore(&conf->device_lock, flags); spin_unlock_irqrestore(&conf->device_lock, flags);
if (do_sync)
md_wakeup_thread(mddev->thread);
return 0; return 0;
} }
...@@ -1563,6 +1567,7 @@ static void raid10d(mddev_t *mddev) ...@@ -1563,6 +1567,7 @@ static void raid10d(mddev_t *mddev)
(unsigned long long)r10_bio->sector); (unsigned long long)r10_bio->sector);
raid_end_bio_io(r10_bio); raid_end_bio_io(r10_bio);
} else { } else {
const int do_sync = bio_sync(r10_bio->master_bio);
rdev = conf->mirrors[mirror].rdev; rdev = conf->mirrors[mirror].rdev;
if (printk_ratelimit()) if (printk_ratelimit())
printk(KERN_ERR "raid10: %s: redirecting sector %llu to" printk(KERN_ERR "raid10: %s: redirecting sector %llu to"
...@@ -1574,7 +1579,7 @@ static void raid10d(mddev_t *mddev) ...@@ -1574,7 +1579,7 @@ static void raid10d(mddev_t *mddev)
bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr bio->bi_sector = r10_bio->devs[r10_bio->read_slot].addr
+ rdev->data_offset; + rdev->data_offset;
bio->bi_bdev = rdev->bdev; bio->bi_bdev = rdev->bdev;
bio->bi_rw = READ; bio->bi_rw = READ | do_sync;
bio->bi_private = r10_bio; bio->bi_private = r10_bio;
bio->bi_end_io = raid10_end_read_request; bio->bi_end_io = raid10_end_read_request;
unplug = 1; unplug = 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册