diff options
author | phk <phk@FreeBSD.org> | 2005-07-25 21:12:54 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 2005-07-25 21:12:54 +0000 |
commit | 388b4d6c8dc46d6be4f2e6790d5fbba31397395d (patch) | |
tree | b5a3ad06f201c8a0483edb1b180808aaca8995ad /sys/geom | |
parent | 3491fe3f14f725fbdd8fb97c38c5748a7abf0cb0 (diff) | |
download | FreeBSD-src-388b4d6c8dc46d6be4f2e6790d5fbba31397395d.zip FreeBSD-src-388b4d6c8dc46d6be4f2e6790d5fbba31397395d.tar.gz |
By design I left a tiny race in updating the I/O statistics based on
the assumption that performance was more important that beancounter
quality statistics.
As it transpires the microoptimization is not measurable in the
real world and the inconsistent statistics confuse users, so revert
the decision.
MT6 candidate: possibly
MT5 candidate: possibly
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/geom_io.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/sys/geom/geom_io.c b/sys/geom/geom_io.c index b923867..ca7e1f0 100644 --- a/sys/geom/geom_io.c +++ b/sys/geom/geom_io.c @@ -268,15 +268,18 @@ g_io_request(struct bio *bp, struct g_consumer *cp) bp->bio_flags |= BIO_ONQUEUE; binuptime(&bp->bio_t0); - if (g_collectstats & 4) - g_bioq_lock(&g_bio_run_down); + + /* + * The statistics collection is lockless, as such, but we + * can not update one instance of the statistics from more + * than one thread at a time, so grab the lock first. + */ + g_bioq_lock(&g_bio_run_down); if (g_collectstats & 1) devstat_start_transaction(pp->stat, &bp->bio_t0); if (g_collectstats & 2) devstat_start_transaction(cp->stat, &bp->bio_t0); - if (!(g_collectstats & 4)) - g_bioq_lock(&g_bio_run_down); pp->nstart++; cp->nstart++; TAILQ_INSERT_TAIL(&g_bio_run_down.bio_queue, bp, bio_queue); @@ -322,14 +325,17 @@ g_io_deliver(struct bio *bp, int error) bp->bio_bcount = bp->bio_length; bp->bio_resid = bp->bio_bcount - bp->bio_completed; - if (g_collectstats & 4) - g_bioq_lock(&g_bio_run_up); + /* + * The statistics collection is lockless, as such, but we + * can not update one instance of the statistics from more + * than one thread at a time, so grab the lock first. + */ + g_bioq_lock(&g_bio_run_up); if (g_collectstats & 1) devstat_end_transaction_bio(pp->stat, bp); if (g_collectstats & 2) devstat_end_transaction_bio(cp->stat, bp); - if (!(g_collectstats & 4)) - g_bioq_lock(&g_bio_run_up); + cp->nend++; pp->nend++; if (error != ENOMEM) { |