svn commit: r218678 - projects/graid/head/sys/geom/raid
Alexander Motin
mav at FreeBSD.org
Mon Feb 14 11:56:46 UTC 2011
Author: mav
Date: Mon Feb 14 11:56:45 2011
New Revision: 218678
URL: http://svn.freebsd.org/changeset/base/218678
Log:
Rework idle events scheduling. Call idle() trasfotmation method for the
volume with no active payload requests with fixed period of idle_threshold,
instead of measuring that time from the last (probably internal) activity.
That change allows to reach full rebuild/resync speed supported by the disk.
Also it makes tunables closer related to some real world values.
Maximum speed for idle disk now is rebuild_slab_size * rebuild_cluster_idle
per idle_threshold interval. With present settings it is 100MB/s.
When disk is busy - rebuild does one rebuild_slab_size sized transaction
every rebuild_fair_io payload requests. Now it is 1MB per 20 requests.
Modified:
projects/graid/head/sys/geom/raid/g_raid.c
projects/graid/head/sys/geom/raid/g_raid.h
Modified: projects/graid/head/sys/geom/raid/g_raid.c
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.c Mon Feb 14 09:58:47 2011 (r218677)
+++ projects/graid/head/sys/geom/raid/g_raid.c Mon Feb 14 11:56:45 2011 (r218678)
@@ -1047,6 +1047,7 @@ g_raid_iodone(struct bio *bp, int error)
bioq_remove(&vol->v_inflight, bp);
if (vol->v_pending_lock && g_raid_is_in_locked_range(vol, bp))
g_raid_finish_with_locked_ranges(vol, bp);
+ getmicrouptime(&vol->v_last_done);
g_io_deliver(bp, error);
}
@@ -1273,6 +1274,7 @@ g_raid_worker(void *arg)
struct g_raid_event *ep;
struct g_raid_volume *vol;
struct bio *bp;
+ struct timeval now, t;
int timeout, rv;
sc = arg;
@@ -1296,38 +1298,59 @@ g_raid_worker(void *arg)
else if ((bp = bioq_takefirst(&sc->sc_queue)) != NULL)
;
else {
- /*
- * Two steps to avoid overflows at HZ=1000
- * and idle timeouts > 2.1s. Some rounding errors
- * can occur, but they are < 1tick, which is deemed to
- * be close enough for this purpose.
- */
- int micpertic = 1000000 / hz;
- timeout = g_raid_idle_threshold / micpertic;
- sx_xunlock(&sc->sc_lock);
- MSLEEP(rv, sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "-",
- timeout);
- sx_xlock(&sc->sc_lock);
- goto process;
+ getmicrouptime(&now);
+ t = now;
+ TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
+ if (bioq_first(&vol->v_inflight) == NULL &&
+ timevalcmp(&vol->v_last_done, &t, < ))
+ t = vol->v_last_done;
+ }
+ timevalsub(&t, &now);
+ timeout = g_raid_idle_threshold +
+ t.tv_sec * 1000000 + t.tv_usec;
+ if (timeout > 0) {
+ /*
+ * Two steps to avoid overflows at HZ=1000
+ * and idle timeouts > 2.1s. Some rounding
+ * errors can occur, but they are < 1tick,
+ * which is deemed to be close enough for
+ * this purpose.
+ */
+ int micpertic = 1000000 / hz;
+ timeout = (timeout + micpertic - 1) / micpertic;
+ sx_xunlock(&sc->sc_lock);
+ MSLEEP(rv, sc, &sc->sc_queue_mtx,
+ PRIBIO | PDROP, "-", timeout);
+ sx_xlock(&sc->sc_lock);
+ goto process;
+ } else
+ rv = EWOULDBLOCK;
}
mtx_unlock(&sc->sc_queue_mtx);
process:
- if (ep != NULL)
+ if (ep != NULL) {
g_raid_handle_event(sc, ep);
- if (bp != NULL) {
+ } else if (bp != NULL) {
if (bp->bio_to != NULL &&
bp->bio_to->geom == sc->sc_geom)
g_raid_start_request(bp);
else
g_raid_disk_done_request(bp);
- }
- if (rv == EWOULDBLOCK) {
+ } else if (rv == EWOULDBLOCK) {
TAILQ_FOREACH(vol, &sc->sc_volumes, v_next) {
if (vol->v_writes == 0 && vol->v_dirty)
g_raid_clean(vol, -1);
if (bioq_first(&vol->v_inflight) == NULL &&
- vol->v_tr)
- G_RAID_TR_IDLE(vol->v_tr);
+ vol->v_tr) {
+ t.tv_sec = g_raid_idle_threshold / 1000000;
+ t.tv_usec = g_raid_idle_threshold % 1000000;
+ timevaladd(&t, &vol->v_last_done);
+ getmicrouptime(&now);
+ if (timevalcmp(&t, &now, <= )) {
+ G_RAID_TR_IDLE(vol->v_tr);
+ vol->v_last_done = now;
+ }
+ }
}
}
if (sc->sc_stopping == G_RAID_DESTROY_HARD)
Modified: projects/graid/head/sys/geom/raid/g_raid.h
==============================================================================
--- projects/graid/head/sys/geom/raid/g_raid.h Mon Feb 14 09:58:47 2011 (r218677)
+++ projects/graid/head/sys/geom/raid/g_raid.h Mon Feb 14 11:56:45 2011 (r218678)
@@ -32,6 +32,7 @@
#include <sys/param.h>
#include <sys/kobj.h>
#include <sys/bio.h>
+#include <sys/time.h>
#define G_RAID_CLASS_NAME "RAID"
@@ -250,6 +251,7 @@ struct g_raid_volume {
LIST_HEAD(, g_raid_lock) v_locks; /* List of locked regions. */
int v_pending_lock; /* writes to locked region */
int v_dirty; /* Volume is DIRTY. */
+ struct timeval v_last_done; /* Time of the last I/O. */
time_t v_last_write; /* Time of the last write. */
u_int v_writes; /* Number of active writes. */
struct root_hold_token *v_rootmount; /* Root mount delay token. */
More information about the svn-src-projects
mailing list