aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-08-01 18:33:20 -0400
committerNeilBrown <neilb@suse.de>2012-08-01 18:33:20 -0400
commitf54a9d0e59c4bea3db733921ca9147612a6f292c (patch)
treee17aa5d2a7220cfe7466cc4f8c74af5ed672a591 /drivers/md
parent46a06401f6ba13e59d24746fa9ffa6773b69eee3 (diff)
md/raid1: submit IO from originating thread instead of md thread.
queuing writes to the md thread means that all requests go through the one processor which may not be able to keep up with very high request rates. So use the plugging infrastructure to submit all requests on unplug. If a 'schedule' is needed, we fall back on the old approach of handing the requests to the thread for it to handle. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/bitmap.c2
-rw-r--r--drivers/md/raid1.c57
2 files changed, 55 insertions, 4 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index 15dbe03117e4..94e7f6ba2e11 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1305,7 +1305,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect
1305 prepare_to_wait(&bitmap->overflow_wait, &__wait, 1305 prepare_to_wait(&bitmap->overflow_wait, &__wait,
1306 TASK_UNINTERRUPTIBLE); 1306 TASK_UNINTERRUPTIBLE);
1307 spin_unlock_irq(&bitmap->counts.lock); 1307 spin_unlock_irq(&bitmap->counts.lock);
1308 io_schedule(); 1308 schedule();
1309 finish_wait(&bitmap->overflow_wait, &__wait); 1309 finish_wait(&bitmap->overflow_wait, &__wait);
1310 continue; 1310 continue;
1311 } 1311 }
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 36a8fc059ac3..9f01870d031c 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -870,6 +870,44 @@ do_sync_io:
870 pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); 870 pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size);
871} 871}
872 872
873struct raid1_plug_cb {
874 struct blk_plug_cb cb;
875 struct bio_list pending;
876 int pending_cnt;
877};
878
879static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule)
880{
881 struct raid1_plug_cb *plug = container_of(cb, struct raid1_plug_cb,
882 cb);
883 struct mddev *mddev = plug->cb.data;
884 struct r1conf *conf = mddev->private;
885 struct bio *bio;
886
887 if (from_schedule) {
888 spin_lock_irq(&conf->device_lock);
889 bio_list_merge(&conf->pending_bio_list, &plug->pending);
890 conf->pending_count += plug->pending_cnt;
891 spin_unlock_irq(&conf->device_lock);
892 md_wakeup_thread(mddev->thread);
893 kfree(plug);
894 return;
895 }
896
897 /* we aren't scheduling, so we can do the write-out directly. */
898 bio = bio_list_get(&plug->pending);
899 bitmap_unplug(mddev->bitmap);
900 wake_up(&conf->wait_barrier);
901
902 while (bio) { /* submit pending writes */
903 struct bio *next = bio->bi_next;
904 bio->bi_next = NULL;
905 generic_make_request(bio);
906 bio = next;
907 }
908 kfree(plug);
909}
910
873static void make_request(struct mddev *mddev, struct bio * bio) 911static void make_request(struct mddev *mddev, struct bio * bio)
874{ 912{
875 struct r1conf *conf = mddev->private; 913 struct r1conf *conf = mddev->private;
@@ -883,6 +921,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
883 const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); 921 const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
884 const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); 922 const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
885 struct md_rdev *blocked_rdev; 923 struct md_rdev *blocked_rdev;
924 struct blk_plug_cb *cb;
925 struct raid1_plug_cb *plug = NULL;
886 int first_clone; 926 int first_clone;
887 int sectors_handled; 927 int sectors_handled;
888 int max_sectors; 928 int max_sectors;
@@ -1185,11 +1225,22 @@ read_again:
1185 mbio->bi_private = r1_bio; 1225 mbio->bi_private = r1_bio;
1186 1226
1187 atomic_inc(&r1_bio->remaining); 1227 atomic_inc(&r1_bio->remaining);
1228
1229 cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug));
1230 if (cb)
1231 plug = container_of(cb, struct raid1_plug_cb, cb);
1232 else
1233 plug = NULL;
1188 spin_lock_irqsave(&conf->device_lock, flags); 1234 spin_lock_irqsave(&conf->device_lock, flags);
1189 bio_list_add(&conf->pending_bio_list, mbio); 1235 if (plug) {
1190 conf->pending_count++; 1236 bio_list_add(&plug->pending, mbio);
1237 plug->pending_cnt++;
1238 } else {
1239 bio_list_add(&conf->pending_bio_list, mbio);
1240 conf->pending_count++;
1241 }
1191 spin_unlock_irqrestore(&conf->device_lock, flags); 1242 spin_unlock_irqrestore(&conf->device_lock, flags);
1192 if (!mddev_check_plugged(mddev)) 1243 if (!plug)
1193 md_wakeup_thread(mddev->thread); 1244 md_wakeup_thread(mddev->thread);
1194 } 1245 }
1195 /* Mustn't call r1_bio_write_done before this next test, 1246 /* Mustn't call r1_bio_write_done before this next test,