summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorle <le@FreeBSD.org>2004-03-19 10:28:34 +0000
committerle <le@FreeBSD.org>2004-03-19 10:28:34 +0000
commit9594cbf80177fc0be18e4e86999a7245729d2658 (patch)
tree71c76a01a83ed3994c0915df88b8aa6e8a0bb941 /sys/dev
parentb893e6c496141ad1b9c9ac7424743d98fc89da5e (diff)
downloadFreeBSD-src-9594cbf80177fc0be18e4e86999a7245729d2658.zip
FreeBSD-src-9594cbf80177fc0be18e4e86999a7245729d2658.tar.gz
When doing round-robin reads from a multi-plex volume, only switch to the
next plex if the sector to be read isn't nearby the last read sector. Submitted by: Vsevolod Lobko <seva@ip.net.ua> via ru@ Approved by: grog (mentor)
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/vinum/vinumobj.h1
-rw-r--r--sys/dev/vinum/vinumrequest.c16
-rw-r--r--sys/dev/vinum/vinumvar.h7
3 files changed, 20 insertions, 4 deletions
diff --git a/sys/dev/vinum/vinumobj.h b/sys/dev/vinum/vinumobj.h
index 81087f3..0d5b800 100644
--- a/sys/dev/vinum/vinumobj.h
+++ b/sys/dev/vinum/vinumobj.h
@@ -275,6 +275,7 @@ struct _plex
#ifdef _KERNEL
struct rangelock *lock; /* ranges of locked addresses */
struct mtx *lockmtx; /* lock mutex, one of plexmutex [] */
+ daddr_t last_addr; /* last address read from this plex */
dev_t dev; /* associated device */
#endif
};
diff --git a/sys/dev/vinum/vinumrequest.c b/sys/dev/vinum/vinumrequest.c
index eda4c2a..0915f8c 100644
--- a/sys/dev/vinum/vinumrequest.c
+++ b/sys/dev/vinum/vinumrequest.c
@@ -234,10 +234,18 @@ vinumstart(struct buf *bp, int reviveok)
if (vol != NULL) {
plexno = vol->preferred_plex; /* get the plex to use */
if (plexno < 0) { /* round robin */
- plexno = vol->last_plex_read;
- vol->last_plex_read++;
- if (vol->last_plex_read >= vol->plexes) /* got the the end? */
- vol->last_plex_read = 0; /* wrap around */
+ for (plexno = 0; plexno < vol->plexes; plexno++)
+ if (abs(bp->b_blkno - PLEX[vol->plex[plexno]].last_addr) <= ROUNDROBIN_SWITCH)
+ break;
+ if (plexno >= vol->plexes) {
+ vol->last_plex_read++;
+ if (vol->last_plex_read >= vol->plexes)
+ vol->last_plex_read = 0;
+ plexno = vol->last_plex_read;
+ } else {
+ vol->last_plex_read = plexno;
+ };
+ PLEX[vol->plex[plexno]].last_addr = bp->b_blkno;
}
status = build_read_request(rq, plexno); /* build a request */
} else {
diff --git a/sys/dev/vinum/vinumvar.h b/sys/dev/vinum/vinumvar.h
index 807439c..8e7edd8 100644
--- a/sys/dev/vinum/vinumvar.h
+++ b/sys/dev/vinum/vinumvar.h
@@ -361,6 +361,13 @@ enum parityop {
rebuildandcheckparity, /* rebuildparity with the -v option */
};
+/*
+ * When doing round-robin reads from a multi-plex volume, switch to the
+ * next plex if the difference of the last read sector and the next sector
+ * to be read is this many sectors.
+ */
+#define ROUNDROBIN_SWITCH 128 /* 64k */
+
#ifdef VINUMDEBUG
/* Debugging stuff */
enum debugflags {
OpenPOWER on IntegriCloud