Retire nstart/nend counters.

Those counters were abused for decade to workaround broken orphanization
process in different classes by delaying the call while there are active
requests.  But from one side it did not close all the races, while from
another was quite expensive on SMP due to trashing twice per request cache
lines of consumer and provider and requiring locks.  It lost its sense
after I manually went through all the GEOM classes in base and made
orphanization wait for either provider close or request completion.

Consumer counters are still used under INVARIANTS to detect premature
consumer close and detach.  Provider counters are removed completely.

Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2019-12-30 00:46:10 +00:00
parent a2ea78495a
commit 9794a803fd
4 changed files with 13 additions and 10 deletions

View File

@ -218,7 +218,8 @@ struct g_provider {
off_t stripesize;
off_t stripeoffset;
struct devstat *stat;
u_int nstart, nend;
u_int spare1;
u_int spare2;
u_int flags;
#define G_PF_WITHER 0x2
#define G_PF_ORPHAN 0x4

View File

@ -241,10 +241,7 @@ one_event(void)
g_topology_assert();
mtx_lock(&g_eventlock);
TAILQ_FOREACH(pp, &g_doorstep, orphan) {
if (pp->nstart == pp->nend)
break;
}
pp = TAILQ_FIRST(&g_doorstep);
if (pp != NULL) {
G_VALID_PROVIDER(pp);
TAILQ_REMOVE(&g_doorstep, pp, orphan);
@ -299,7 +296,7 @@ g_run_events()
} else {
g_topology_unlock();
msleep(&g_wait_event, &g_eventlock, PRIBIO | PDROP,
"-", TAILQ_EMPTY(&g_doorstep) ? 0 : hz / 10);
"-", 0);
}
}
/* NOTREACHED */

View File

@ -580,8 +580,9 @@ g_io_request(struct bio *bp, struct g_consumer *cp)
devstat_start_transaction(pp->stat, &bp->bio_t0);
if (g_collectstats & G_STATS_CONSUMERS)
devstat_start_transaction(cp->stat, &bp->bio_t0);
pp->nstart++;
#ifdef INVARIANTS
cp->nstart++;
#endif
mtx_unlock(mtxp);
if (direct) {
@ -691,8 +692,9 @@ g_io_deliver(struct bio *bp, int error)
devstat_end_transaction_bio_bt(pp->stat, bp, &now);
if (g_collectstats & G_STATS_CONSUMERS)
devstat_end_transaction_bio_bt(cp->stat, bp, &now);
#ifdef INVARIANTS
cp->nend++;
pp->nend++;
#endif
mtx_unlock(mtxp);
if (error != ENOMEM) {

View File

@ -939,6 +939,9 @@ g_access(struct g_consumer *cp, int dcr, int dcw, int dce)
KASSERT(cp->acw + dcw >= 0, ("access resulting in negative acw"));
KASSERT(cp->ace + dce >= 0, ("access resulting in negative ace"));
KASSERT(dcr != 0 || dcw != 0 || dce != 0, ("NOP access request"));
KASSERT(cp->acr + dcr != 0 || cp->acw + dcw != 0 ||
cp->ace + dce != 0 || cp->nstart == cp->nend,
("Last close with active requests"));
KASSERT(gp->access != NULL, ("NULL geom->access"));
/*
@ -1426,8 +1429,10 @@ db_show_geom_consumer(int indent, struct g_consumer *cp)
}
gprintln(" access: r%dw%de%d", cp->acr, cp->acw, cp->ace);
gprintln(" flags: 0x%04x", cp->flags);
#ifdef INVARIANTS
gprintln(" nstart: %u", cp->nstart);
gprintln(" nend: %u", cp->nend);
#endif
} else {
gprintf("consumer: %p (%s), access=r%dw%de%d", cp,
cp->provider != NULL ? cp->provider->name : "none",
@ -1459,8 +1464,6 @@ db_show_geom_provider(int indent, struct g_provider *pp)
provider_flags_to_string(pp, flags, sizeof(flags)),
pp->flags);
gprintln(" error: %d", pp->error);
gprintln(" nstart: %u", pp->nstart);
gprintln(" nend: %u", pp->nend);
if (LIST_EMPTY(&pp->consumers))
gprintln(" consumers: none");
} else {