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:
parent
9da3072cae
commit
4d006a98d1
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=137258
@ -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);
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user