linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Paul Clements <paul.clements@steeleye.com>
To: Neil Brown <neilb@cse.unsw.edu.au>
Cc: linux-raid@vger.kernel.org
Subject: [PATCH 2/3] md bitmap async writes for raid1
Date: Thu, 17 Mar 2005 15:55:17 -0500	[thread overview]
Message-ID: <4239EEB5.7020901@steeleye.com> (raw)
In-Reply-To: <4239EE55.7040804@steeleye.com>

[-- Attachment #1: Type: text/plain, Size: 45 bytes --]

This patch implements async writes in raid1.

[-- Attachment #2: md_async_4_0_raid1.diff --]
[-- Type: text/plain, Size: 7222 bytes --]


Signed-Off-By: Paul Clements <paul.clements@steeleye.com>

 drivers/md/raid1.c         |  107 ++++++++++++++++++++++++++++++++++++++++++---
 include/linux/raid/raid1.h |    2 
 2 files changed, 102 insertions(+), 7 deletions(-)
diff -purN --exclude core --exclude-from /export/public/clemep/tmp/dontdiff linux-2.6.11-rc3-mm2-patch-all-write-mostly-max-dev-bug-bitmap-bug-fix/drivers/md/raid1.c linux-2.6.11-rc3-mm2-patch-all-write-mostly-async-write-bitmap-bug-fix/drivers/md/raid1.c
--- linux-2.6.11-rc3-mm2-patch-all-write-mostly-max-dev-bug-bitmap-bug-fix/drivers/md/raid1.c	Thu Mar 10 10:05:35 2005
+++ linux-2.6.11-rc3-mm2-patch-all-write-mostly-async-write-bitmap-bug-fix/drivers/md/raid1.c	Sat Mar 12 08:38:20 2005
@@ -35,7 +35,7 @@
 #include <linux/raid/raid1.h>
 #include <linux/raid/bitmap.h>
 
-#define DEBUG 0
+#define DEBUG 0
 #if DEBUG
 #define PRINTK(x...) printk(x)
 #else
@@ -222,8 +222,17 @@ static void raid_end_bio_io(r1bio_t *r1_
 {
 	struct bio *bio = r1_bio->master_bio;
 
-	bio_endio(bio, bio->bi_size,
-		test_bit(R1BIO_Uptodate, &r1_bio->state) ? 0 : -EIO);
+	/* if nobody has done the final endio yet, do it now */
+	if (!test_and_set_bit(R1BIO_AsyncPhase, &r1_bio->state)) {
+		PRINTK(KERN_DEBUG "raid1: sync end %s on sectors %llu-%llu\n",
+			(bio_data_dir(bio) == WRITE) ? "write" : "read",
+			(unsigned long long) bio->bi_sector,
+			(unsigned long long) bio->bi_sector +
+				(bio->bi_size >> 9) - 1);
+	
+		bio_endio(bio, bio->bi_size,
+			test_bit(R1BIO_Uptodate, &r1_bio->state) ? 0 : -EIO);
+	}
 	free_r1bio(r1_bio);
 }
 
@@ -292,7 +301,7 @@ static int raid1_end_write_request(struc
 {
 	int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags);
 	r1bio_t * r1_bio = (r1bio_t *)(bio->bi_private);
-	int mirror;
+	int mirror, async, wonly = 1; /* assume write only if rdev missing */
 	conf_t *conf = mddev_to_conf(r1_bio->mddev);
 
 	if (bio->bi_size)
@@ -323,16 +332,39 @@ static int raid1_end_write_request(struc
 
 	update_head_pos(mirror, r1_bio);
 
+	async = test_bit(R1BIO_AsyncIO, &r1_bio->state);
+	if (conf->mirrors[mirror].rdev)
+		wonly = test_bit(WriteMostly, &conf->mirrors[mirror].rdev->flags);
+	/* In async mode, we ACK the master bio once the I/O has safely
+	 * reached the non-writeonly disk. Setting the AsyncPhase bit
+	 * ensures that this gets done only once -- we don't ever want to
+	 * return -EIO here, instead we'll wait */
+	if (async && !wonly && test_bit(R1BIO_Uptodate, &r1_bio->state) &&
+	    !test_and_set_bit(R1BIO_AsyncPhase, &r1_bio->state)) {
+		struct bio *mbio = r1_bio->master_bio;
+		PRINTK(KERN_DEBUG "raid1: async end write sectors %llu-%llu\n",
+			(unsigned long long) mbio->bi_sector,
+			(unsigned long long) mbio->bi_sector +
+			(mbio->bi_size >> 9) - 1);
+		bio_endio(mbio, mbio->bi_size, 0);
+	}
 	/*
 	 *
 	 * Let's see if all mirrored write operations have finished
 	 * already.
 	 */
 	if (atomic_dec_and_test(&r1_bio->remaining)) {
+		if (async) {
+			int i = bio->bi_vcnt;
+			/* free extra copy of the data pages */
+			while (i--)
+				__free_page(bio->bi_io_vec[i].bv_page);
+		}
 		/* clear the bitmap if all writes complete successfully */
 		bitmap_endwrite(r1_bio->mddev->bitmap, r1_bio->sector,
 				r1_bio->sectors,
-				!test_bit(R1BIO_Degraded, &r1_bio->state));
+				!test_bit(R1BIO_Degraded, &r1_bio->state),
+				async);
 		md_write_end(r1_bio->mddev);
 		raid_end_bio_io(r1_bio);
 	}
@@ -553,6 +585,38 @@ static void device_barrier(conf_t *conf,
 	spin_unlock_irq(&conf->resync_lock);
 }
 
+/* duplicate the data pages for async I/O */
+static struct page **alloc_async_pages(struct bio *bio)
+{
+	int i;
+	struct bio_vec *bvec;
+	struct page **pages = kmalloc(bio->bi_vcnt * sizeof(struct page *),
+					GFP_NOIO);
+	if (unlikely(!pages))
+		goto do_sync_io;
+
+	BUG_ON(bio->bi_idx != 0);
+	bio_for_each_segment(bvec, bio, i) {
+		pages[i] = alloc_page(GFP_NOIO);
+		if (unlikely(!pages[i]))
+			goto do_sync_io;
+		memcpy(kmap(pages[i]) + bvec->bv_offset,
+			kmap(bvec->bv_page) + bvec->bv_offset, bvec->bv_len);
+		kunmap(pages[i]);
+		kunmap(bvec->bv_page);
+	}
+
+	return pages;
+
+do_sync_io:
+	if (pages)
+		for (i = 0; i < bio->bi_vcnt && pages[i]; i++)
+			__free_page(pages[i]);
+	kfree(pages);
+	PRINTK("%dB async alloc failed, doing sync I/O\n", bio->bi_size);
+	return NULL;
+}
+
 static int make_request(request_queue_t *q, struct bio * bio)
 {
 	mddev_t *mddev = q->queuedata;
@@ -565,6 +629,7 @@ static int make_request(request_queue_t 
 	struct bitmap *bitmap = mddev->bitmap;
 	unsigned long flags;
 	struct bio_list bl;
+	struct page **async_pages = NULL;
 
 
 	/*
@@ -668,6 +733,12 @@ static int make_request(request_queue_t 
 		set_bit(R1BIO_Degraded, &r1_bio->state);
 	}
 
+	/* do async I/O ? */
+	if (bitmap &&
+	    atomic_read(&bitmap->async_writes) < bitmap->async_max_writes &&
+	    (async_pages = alloc_async_pages(bio)))
+		set_bit(R1BIO_AsyncIO, &r1_bio->state);
+
 	atomic_set(&r1_bio->remaining, 0);
 
 	bio_list_init(&bl);
@@ -685,19 +756,30 @@ static int make_request(request_queue_t 
 		mbio->bi_rw = WRITE;
 		mbio->bi_private = r1_bio;
 
+		if (test_bit(R1BIO_AsyncIO, &r1_bio->state)) {
+			struct bio_vec *bvec;
+			int j;
+
+			BUG_ON(!async_pages);
+			bio_for_each_segment(bvec, mbio, j)
+				bvec->bv_page = async_pages[j];
+		}
+
 		atomic_inc(&r1_bio->remaining);
 
 		bio_list_add(&bl, mbio);
 	}
+	kfree(async_pages); /* the async pages are attached to the bios now */
 
-	bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors);
+	bitmap_startwrite(bitmap, bio->bi_sector, r1_bio->sectors,
+				test_bit(R1BIO_AsyncIO, &r1_bio->state));
 	spin_lock_irqsave(&conf->device_lock, flags);
 	bio_list_merge(&conf->pending_bio_list, &bl);
 	bio_list_init(&bl);
 
 	blk_plug_device(mddev->queue);
 	spin_unlock_irqrestore(&conf->device_lock, flags);
-	
+
 #if 0
 	while ((bio = bio_list_pop(&bl)) != NULL) 
 		generic_make_request(bio);
@@ -1458,6 +1540,17 @@ out:
 static int stop(mddev_t *mddev)
 {
 	conf_t *conf = mddev_to_conf(mddev);
+	struct bitmap *bitmap = mddev->bitmap;
+	int async_wait = 0;
+
+	/* wait for async writes to complete */
+	while (bitmap && atomic_read(&bitmap->async_writes) > 0) {
+		async_wait++;
+		printk(KERN_INFO "raid1: async writes in progress on device %s, waiting to stop (%d)\n", mdname(mddev), async_wait);
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(HZ); /* wait a second */
+		/* need to kick something here to make sure I/O goes? */
+	}
 
 	md_unregister_thread(mddev->thread);
 	mddev->thread = NULL;
diff -purN --exclude core --exclude-from /export/public/clemep/tmp/dontdiff linux-2.6.11-rc3-mm2-patch-all-write-mostly-max-dev-bug-bitmap-bug-fix/include/linux/raid/raid1.h linux-2.6.11-rc3-mm2-patch-all-write-mostly-async-write-bitmap-bug-fix/include/linux/raid/raid1.h
--- linux-2.6.11-rc3-mm2-patch-all-write-mostly-max-dev-bug-bitmap-bug-fix/include/linux/raid/raid1.h	Fri Feb 18 14:45:25 2005
+++ linux-2.6.11-rc3-mm2-patch-all-write-mostly-async-write-bitmap-bug-fix/include/linux/raid/raid1.h	Mon Feb 21 16:48:38 2005
@@ -107,4 +107,6 @@ struct r1bio_s {
 #define	R1BIO_Uptodate	0
 #define	R1BIO_IsSync	1
 #define	R1BIO_Degraded	2
+#define R1BIO_AsyncPhase 3
+#define R1BIO_AsyncIO   4
 #endif

  reply	other threads:[~2005-03-17 20:55 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-03-09 22:18 [PATCH 1/2] md bitmap bug fixes Paul Clements
2005-03-09 22:19 ` [PATCH 2/2] " Paul Clements
2005-03-14  4:43 ` [PATCH 1/2] " Neil Brown
2005-03-14  9:44   ` Lars Marowsky-Bree
2005-03-14 10:22     ` Neil Brown
2005-03-14 11:24       ` Lars Marowsky-Bree
2005-03-14 22:54         ` Neil Brown
2005-03-18 10:33           ` Lars Marowsky-Bree
2005-03-18 12:52             ` Peter T. Breuer
2005-03-18 13:42               ` Lars Marowsky-Bree
2005-03-18 14:50                 ` Peter T. Breuer
2005-03-18 17:03                   ` Paul Clements
2005-03-18 18:43                     ` Peter T. Breuer
2005-03-18 19:01                       ` Mario Holbe
2005-03-18 19:33                         ` Peter T. Breuer
2005-03-18 20:24                           ` Mario Holbe
2005-03-18 21:01                             ` Andy Smith
2005-03-19 11:43                             ` Peter T. Breuer
2005-03-19 12:58                               ` Lars Marowsky-Bree
2005-03-19 13:27                                 ` Peter T. Breuer
2005-03-19 14:07                                   ` Lars Marowsky-Bree
2005-03-19 15:06                                     ` Peter T. Breuer
2005-03-19 15:24                                       ` Mario Holbe
2005-03-19 15:58                                         ` Peter T. Breuer
2005-03-19 16:24                                       ` Lars Marowsky-Bree
2005-03-19 17:19                                         ` Peter T. Breuer
2005-03-19 17:36                                           ` Lars Marowsky-Bree
2005-03-19 17:44                                         ` Guy
2005-03-19 17:54                                           ` Lars Marowsky-Bree
2005-03-19 18:05                                             ` Guy
2005-03-19 20:29                                             ` berk walker
2005-03-19 18:11                                           ` Peter T. Breuer
2005-03-18 19:43                       ` Paul Clements
2005-03-19 12:10                         ` Peter T. Breuer
2005-03-21 16:07                           ` Paul Clements
2005-03-21 18:56                             ` Luca Berra
2005-03-21 19:58                               ` Paul Clements
2005-03-21 20:45                                 ` Peter T. Breuer
2005-03-21 21:09                                   ` Gil
2005-03-21 21:19                                   ` Paul Clements
2005-03-21 22:15                                     ` Peter T. Breuer
2005-03-22 22:35                                     ` Peter T. Breuer
2005-03-21 21:32                                   ` Guy
2005-03-22  9:35                                 ` Luca Berra
2005-03-22 10:02                                   ` Peter T. Breuer
2005-03-23 20:31                                     ` Luca Berra
2005-03-25 18:51                                       ` Peter T. Breuer
2005-03-25 20:54                                         ` berk walker
2005-03-25 20:56                                           ` berk walker
2005-03-18 17:16                 ` Luca Berra
2005-03-18 17:57                   ` Lars Marowsky-Bree
2005-03-18 21:46                   ` Michael Tokarev
2005-03-19  9:05                     ` Lars Marowsky-Bree
2005-03-19 12:16                     ` Peter T. Breuer
2005-03-19 12:34                       ` Michael Tokarev
2005-03-19 12:53                         ` Peter T. Breuer
2005-03-19 16:08                           ` "Robust Read" (was: [PATCH 1/2] md bitmap bug fixes) Michael Tokarev
2005-03-19 17:03                             ` "Robust Read" Peter T. Breuer
2005-03-19 20:20                               ` Michael Tokarev
2005-03-19 20:56                                 ` Peter T. Breuer
2005-03-19 22:05                                   ` Michael Tokarev
2005-03-19 22:30                                     ` Peter T. Breuer
2005-03-15  4:24   ` [PATCH 1/2] md bitmap bug fixes Paul Clements
2005-03-17 20:51   ` [PATCH 0/3] md bitmap-based asynchronous writes Paul Clements
2005-03-17 20:53     ` [PATCH 1/3] md bitmap async write enabling Paul Clements
2005-03-17 20:55       ` Paul Clements [this message]
2005-03-17 20:56         ` [PATCH 3/3] mdadm: bitmap async writes Paul Clements
2005-03-21  4:21     ` [PATCH 0/3] md bitmap-based asynchronous writes Neil Brown
2005-03-21 16:31       ` Paul Clements
2005-03-21 22:09         ` Neil Brown
2005-03-22  8:35           ` Peter T. Breuer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4239EEB5.7020901@steeleye.com \
    --to=paul.clements@steeleye.com \
    --cc=linux-raid@vger.kernel.org \
    --cc=neilb@cse.unsw.edu.au \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).