aboutsummaryrefslogtreecommitdiff
path: root/sys/geom/mirror/g_mirror.c
diff options
context:
space:
mode:
authorPawel Jakub Dawidek <pjd@FreeBSD.org>2004-11-05 10:55:04 +0000
committerPawel Jakub Dawidek <pjd@FreeBSD.org>2004-11-05 10:55:04 +0000
commit14089dae44a181a4a4e09284790fdb3525a58e87 (patch)
tree583d45195237cf1ae77d3d48e295c71c697cd86e /sys/geom/mirror/g_mirror.c
parenta2222839a574d4744cb3b23916c55a1ffc398b87 (diff)
downloadsrc-14089dae44a181a4a4e09284790fdb3525a58e87.tar.gz
src-14089dae44a181a4a4e09284790fdb3525a58e87.zip
Notes
Diffstat (limited to 'sys/geom/mirror/g_mirror.c')
-rw-r--r--sys/geom/mirror/g_mirror.c50
1 files changed, 37 insertions, 13 deletions
diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c
index a6bab1c6aa9f..a1b402e2af75 100644
--- a/sys/geom/mirror/g_mirror.c
+++ b/sys/geom/mirror/g_mirror.c
@@ -39,7 +39,6 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/bitstring.h>
#include <vm/uma.h>
-#include <machine/atomic.h>
#include <geom/geom.h>
#include <sys/proc.h>
#include <sys/kthread.h>
@@ -58,6 +57,10 @@ static u_int g_mirror_timeout = 4;
TUNABLE_INT("kern.geom.mirror.timeout", &g_mirror_timeout);
SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, timeout, CTLFLAG_RW, &g_mirror_timeout,
0, "Time to wait on all mirror components");
+static u_int g_mirror_idletime = 5;
+TUNABLE_INT("kern.geom.mirror.idletime", &g_mirror_idletime);
+SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, idletime, CTLFLAG_RW,
+ &g_mirror_idletime, 0, "Mark components as clean when idling");
static u_int g_mirror_reqs_per_sync = 5;
SYSCTL_UINT(_kern_geom_mirror, OID_AUTO, reqs_per_sync, CTLFLAG_RW,
&g_mirror_reqs_per_sync, 0,
@@ -1496,14 +1499,35 @@ g_mirror_worker(void *arg)
goto sleep;
}
if (bp == NULL) {
- if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
- "m:w1", hz * 5) == EWOULDBLOCK) {
+#define G_MIRROR_IS_IDLE(sc) ((sc)->sc_idle || \
+ ((sc)->sc_provider != NULL && \
+ (sc)->sc_provider->acw == 0))
+ if (G_MIRROR_IS_IDLE(sc)) {
/*
- * No I/O requests in 5 seconds, so mark
- * components as clean.
+ * If we're already in idle state, sleep without
+ * a timeout.
*/
- if (!sc->sc_idle)
+ MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
+ "m:w1", 0);
+ G_MIRROR_DEBUG(5, "%s: I'm here 3.", __func__);
+ } else {
+ u_int idletime;
+
+ idletime = g_mirror_idletime;
+ if (idletime == 0)
+ idletime = 1;
+ idletime *= hz;
+ if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
+ "m:w2", idletime) == EWOULDBLOCK) {
+ G_MIRROR_DEBUG(5, "%s: I'm here 4.",
+ __func__);
+ /*
+ * No I/O requests in 5 seconds, so mark
+ * components as clean.
+ */
g_mirror_idle(sc);
+ }
+ G_MIRROR_DEBUG(5, "%s: I'm here 5.", __func__);
}
continue;
}
@@ -1518,26 +1542,26 @@ g_mirror_worker(void *arg)
g_mirror_sync_request(bp);
sleep:
- sps = atomic_load_acq_int(&g_mirror_syncs_per_sec);
+ sps = g_mirror_syncs_per_sec;
if (sps == 0) {
- G_MIRROR_DEBUG(5, "%s: I'm here 5.", __func__);
+ G_MIRROR_DEBUG(5, "%s: I'm here 6.", __func__);
continue;
}
mtx_lock(&sc->sc_queue_mtx);
if (bioq_first(&sc->sc_queue) != NULL) {
mtx_unlock(&sc->sc_queue_mtx);
- G_MIRROR_DEBUG(5, "%s: I'm here 4.", __func__);
+ G_MIRROR_DEBUG(5, "%s: I'm here 7.", __func__);
continue;
}
timeout = hz / sps;
if (timeout == 0)
timeout = 1;
- MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w2",
+ MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "m:w3",
timeout);
} else {
g_mirror_register_request(bp);
}
- G_MIRROR_DEBUG(5, "%s: I'm here 6.", __func__);
+ G_MIRROR_DEBUG(5, "%s: I'm here 8.", __func__);
}
}
@@ -2501,8 +2525,8 @@ g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md)
/*
* Run timeout.
*/
- timeout = atomic_load_acq_int(&g_mirror_timeout);
- callout_reset(&sc->sc_callout, timeout * hz, g_mirror_go, sc);
+ timeout = g_mirror_timeout * hz;
+ callout_reset(&sc->sc_callout, timeout, g_mirror_go, sc);
return (sc->sc_geom);
}