linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "R. Scott Bailey" <rscottbailey@comcast.net>
To: mingo@redhat.com, neilb@cse.unsw.edu.au
Cc: linux-kernel@vger.kernel.org, linux-raid@vger.kernel.org,
	scott.bailey@eds.com
Subject: PATCH: raid1 on alpha
Date: Thu, 13 Mar 2003 23:31:02 -0500	[thread overview]
Message-ID: <002d01c2e9e2$855de880$0201a8c0@spiffy> (raw)

Driven by desperation :-) I have churned out a patch that works around a
long-standing problem with software RAID1 on Alpha platforms. gcc (at least
2.95 and 3.2) generated code for alpha apparently has a problem that is
exercised by the form of the loops in raid1_read_balance.

My admittedly lame patch, against 2.4.20, has been working for my SMP
Alphaserver 4100 for a couple of weeks now without ill effect. (Everything,
including root, on LVM on RAID1.) But I think I cut a corner or two in order
to get it working and keep it simple. I'm hoping a more artful/knowledgeable
programmer can massage this so it is acceptable for inclusion in the
mainline kernels.

Cheers,

	Scott Bailey
	scott.bailey@eds.com | rscottbailey@comcast.net


--- linux-2.4.20/drivers/md/raid1.c	2003-01-17 17:43:45.000000000 -0500
+++ linux-2.4.20-rsb/drivers/md/raid1.c	2003-01-17 17:43:20.000000000 -0500
@@ -11,6 +11,7 @@
  *
  * Fixes to reconstruction by Jakob Østergaard" <jakob@ostenfeld.dk>
  * Various fixes by Neil Brown <neilb@cse.unsw.edu.au>
+ * Spastic hacks on raid1_read_balance by Scott Bailey
<scott.bailey@eds.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -475,6 +476,8 @@
 	int new_disk = conf->last_used;
 	const int sectors = bh->b_size >> 9;
 	const unsigned long this_sector = bh->b_rsector;
+	const int max_disk = conf->raid_disks;
+	const int loop_disk = max_disk - 1; /* optimizer is stooopid */
 	int disk = new_disk;
 	unsigned long new_distance;
 	unsigned long current_distance;
@@ -488,22 +491,18 @@


 	/* make sure that disk is operational */
-	while( !conf->mirrors[new_disk].operational) {
-		if (new_disk <= 0) new_disk = conf->raid_disks;
-		new_disk--;
-		if (new_disk == disk) {
-			/*
-			 * This means no working disk was found
-			 * Nothing much to do, lets not change anything
-			 * and hope for the best...
-			 */
-
-			new_disk = conf->last_used;
+	/* RSB: if not, be simple-minded and choose first readable disk */

-			goto rb_out;
+	if (!conf->mirrors[new_disk].operational) {
+		for (disk = loop_disk; disk >= 0; disk--) {
+			if ((conf->mirrors[disk].operational) &&
+				(!conf->mirrors[disk].write_only)) break;
 		}
+		if (disk < 0) /* If no usable disk was found */
+			goto rb_out;
+		new_disk = disk;
 	}
-	disk = new_disk;
+
 	/* now disk == new_disk == starting point for search */

 	/*
@@ -519,35 +518,26 @@
 	 * This is for kicking those idling disks so that
 	 * they would find work near some hotspot.
 	 */
-
-	if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) {
-		conf->sect_count = 0;

-#if defined(CONFIG_SPARC64) && (__GNUC__ == 2) && (__GNUC_MINOR__ == 92)
-		/* Work around a compiler bug in egcs-2.92.11 19980921 */
-		new_disk = *(volatile int *)&new_disk;
-#endif
-		do {
-			if (new_disk<=0)
-				new_disk = conf->raid_disks;
-			new_disk--;
-			if (new_disk == disk)
-				break;
-		} while ((conf->mirrors[new_disk].write_only) ||
-			 (!conf->mirrors[new_disk].operational));
+	/*
+	 * RSB: Instead of making a scan for some other disk explicitly, just
+	 * mark the head position as being at start of the disk. Then the next
+	 * loop checking for "close" disks is almost certain to pick somebody
+	 * else. Except for hot spots at front of disk, sigh.
+	 */

-		goto rb_out;
+	if (conf->sect_count >= conf->mirrors[new_disk].sect_limit) {
+		conf->sect_count = 0;
+		conf->mirrors[new_disk].head_position = 0;
 	}

-	current_distance = abs(this_sector -
-				conf->mirrors[disk].head_position);
-
 	/* Find the disk which is closest */
+	/* current_distance is initialized to guaranteed worse-than-worst
+	   so that we can simplify loop logic */
+
+	current_distance = conf->mirrors[0].sect_limit + 1;

-	do {
-		if (disk <= 0)
-			disk = conf->raid_disks;
-		disk--;
+	for (disk = loop_disk; disk >= 0; disk--) {

 		if ((conf->mirrors[disk].write_only) ||
 				(!conf->mirrors[disk].operational))
@@ -561,7 +551,7 @@
 			current_distance = new_distance;
 			new_disk = disk;
 		}
-	} while (disk != conf->last_used);
+	}

 rb_out:
 	conf->mirrors[new_disk].head_position = this_sector + sectors;

-
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

                 reply	other threads:[~2003-03-14  4:31 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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='002d01c2e9e2$855de880$0201a8c0@spiffy' \
    --to=rscottbailey@comcast.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-raid@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=neilb@cse.unsw.edu.au \
    --cc=scott.bailey@eds.com \
    /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).