1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-20 11:11:24 +00:00

- Mark all raid3 components as clean after kern.geom.raid3.idletime seconds.

- Make kern.geom.raid3.timeout variable tunable.
This commit is contained in:
Pawel Jakub Dawidek 2004-11-05 13:12:58 +00:00
parent 9da3072cae
commit 4d006a98d1
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137258
2 changed files with 82 additions and 2 deletions

View File

@ -55,8 +55,13 @@ TUNABLE_INT("kern.geom.raid3.debug", &g_raid3_debug);
SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, debug, CTLFLAG_RW, &g_raid3_debug, 0,
"Debug level");
static u_int g_raid3_timeout = 4;
TUNABLE_INT("kern.geom.raid3.timeout", &g_raid3_timeout);
SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, timeout, CTLFLAG_RW, &g_raid3_timeout,
0, "Time to wait on all raid3 components");
static u_int g_raid3_idletime = 5;
TUNABLE_INT("kern.geom.raid3.idletime", &g_raid3_idletime);
SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, idletime, CTLFLAG_RW,
&g_raid3_idletime, 0, "Mark components as clean when idling");
static u_int g_raid3_reqs_per_sync = 5;
SYSCTL_UINT(_kern_geom_raid3, OID_AUTO, reqs_per_sync, CTLFLAG_RW,
&g_raid3_reqs_per_sync, 0,
@ -736,6 +741,48 @@ g_raid3_bump_syncid(struct g_raid3_softc *sc)
}
}
static void
g_raid3_idle(struct g_raid3_softc *sc)
{
struct g_raid3_disk *disk;
u_int i;
if (sc->sc_provider == NULL || sc->sc_provider->acw == 0)
return;
sc->sc_idle = 1;
g_topology_lock();
for (i = 0; i < sc->sc_ndisks; i++) {
disk = &sc->sc_disks[i];
if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE)
continue;
G_RAID3_DEBUG(1, "Disk %s (device %s) marked as clean.",
g_raid3_get_diskname(disk), sc->sc_name);
disk->d_flags &= ~G_RAID3_DISK_FLAG_DIRTY;
g_raid3_update_metadata(disk);
}
g_topology_unlock();
}
static void
g_raid3_unidle(struct g_raid3_softc *sc)
{
struct g_raid3_disk *disk;
u_int i;
sc->sc_idle = 0;
g_topology_lock();
for (i = 0; i < sc->sc_ndisks; i++) {
disk = &sc->sc_disks[i];
if (disk->d_state != G_RAID3_DISK_STATE_ACTIVE)
continue;
G_RAID3_DEBUG(1, "Disk %s (device %s) marked as dirty.",
g_raid3_get_diskname(disk), sc->sc_name);
disk->d_flags |= G_RAID3_DISK_FLAG_DIRTY;
g_raid3_update_metadata(disk);
}
g_topology_unlock();
}
/*
* Treat bio_driver1 field in parent bio as list head and field bio_caller1
* in child bio as pointer to the next element on the list.
@ -1429,6 +1476,9 @@ g_raid3_register_request(struct bio *pbp)
{
struct g_raid3_disk_sync *sync;
if (sc->sc_idle)
g_raid3_unidle(sc);
ndisks = sc->sc_ndisks;
if (sc->sc_syncdisk == NULL)
@ -1704,8 +1754,36 @@ g_raid3_worker(void *arg)
goto sleep;
}
if (bp == NULL) {
MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP, "r3:w1", 0);
G_RAID3_DEBUG(5, "%s: I'm here 3.", __func__);
#define G_RAID3_IS_IDLE(sc) ((sc)->sc_idle || \
((sc)->sc_provider != NULL && \
(sc)->sc_provider->acw == 0))
if (G_RAID3_IS_IDLE(sc)) {
/*
* If we're already in idle state, sleep without
* a timeout.
*/
MSLEEP(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
"r3:w1", 0);
G_RAID3_DEBUG(5, "%s: I'm here 3.", __func__);
} else {
u_int idletime;
idletime = g_raid3_idletime;
if (idletime == 0)
idletime = 1;
idletime *= hz;
if (msleep(sc, &sc->sc_queue_mtx, PRIBIO | PDROP,
"r3:w2", idletime) == EWOULDBLOCK) {
G_RAID3_DEBUG(5, "%s: I'm here 4.",
__func__);
/*
* No I/O requests in 'idletime'
* seconds, so mark components as clean.
*/
g_raid3_idle(sc);
}
G_RAID3_DEBUG(5, "%s: I'm here 5.", __func__);
}
continue;
}
nreqs++;
@ -2635,6 +2713,7 @@ g_raid3_create(struct g_class *mp, const struct g_raid3_metadata *md)
sc->sc_round_robin = 0;
sc->sc_flags = md->md_mflags;
sc->sc_bump_syncid = 0;
sc->sc_idle = 0;
for (n = 0; n < sc->sc_ndisks; n++)
sc->sc_disks[n].d_state = G_RAID3_DISK_STATE_NODISK;
bioq_init(&sc->sc_queue);

View File

@ -190,6 +190,7 @@ struct g_raid3_softc {
u_int sc_syncid; /* Synchronization ID. */
int sc_bump_syncid;
struct g_raid3_device_sync sc_sync;
int sc_idle; /* DIRTY flags removed. */
TAILQ_HEAD(, g_raid3_event) sc_events;
struct mtx sc_events_mtx;