svn commit: r197309 - head/sys/kern
Attilio Rao
attilio at FreeBSD.org
Fri Sep 18 13:48:38 UTC 2009
Author: attilio
Date: Fri Sep 18 13:48:38 2009
New Revision: 197309
URL: http://svn.freebsd.org/changeset/base/197309
Log:
Don't allocate new unnecessary pages when devstat_alloc() looses the
run for re-acuiring the lock, but recheck if new pages are allocatable
from the pool and free the previously allocated ones.
Tested by: pho, Giovanni Trematerra
<giovanni dot trematerra at gmail dot com>
Modified:
head/sys/kern/subr_devstat.c
Modified: head/sys/kern/subr_devstat.c
==============================================================================
--- head/sys/kern/subr_devstat.c Fri Sep 18 13:44:39 2009 (r197308)
+++ head/sys/kern/subr_devstat.c Fri Sep 18 13:48:38 2009 (r197309)
@@ -469,7 +469,7 @@ static struct devstat *
devstat_alloc(void)
{
struct devstat *dsp;
- struct statspage *spp;
+ struct statspage *spp, *spp2;
u_int u;
static int once;
@@ -479,6 +479,7 @@ devstat_alloc(void)
UID_ROOT, GID_WHEEL, 0400, DEVSTAT_DEVICE_NAME);
once = 1;
}
+ spp2 = NULL;
mtx_lock(&devstat_mutex);
for (;;) {
TAILQ_FOREACH(spp, &pagelist, list) {
@@ -487,24 +488,30 @@ devstat_alloc(void)
}
if (spp != NULL)
break;
- /*
- * We had no free slot in any of our pages, drop the mutex
- * and get another page. In theory we could have more than
- * one process doing this at the same time and consequently
- * we may allocate more pages than we will need. That is
- * Just Too Bad[tm], we can live with that.
- */
mtx_unlock(&devstat_mutex);
- spp = malloc(sizeof *spp, M_DEVSTAT, M_ZERO | M_WAITOK);
- spp->stat = malloc(PAGE_SIZE, M_DEVSTAT, M_ZERO | M_WAITOK);
- spp->nfree = statsperpage;
- mtx_lock(&devstat_mutex);
+ spp2 = malloc(sizeof *spp, M_DEVSTAT, M_ZERO | M_WAITOK);
+ spp2->stat = malloc(PAGE_SIZE, M_DEVSTAT, M_ZERO | M_WAITOK);
+ spp2->nfree = statsperpage;
+
/*
- * It would make more sense to add the new page at the head
- * but the order on the list determine the sequence of the
- * mapping so we can't do that.
+ * If free statspages were added while the lock was released
+ * just reuse them.
*/
- TAILQ_INSERT_TAIL(&pagelist, spp, list);
+ mtx_lock(&devstat_mutex);
+ TAILQ_FOREACH(spp, &pagelist, list)
+ if (spp->nfree > 0)
+ break;
+ if (spp == NULL) {
+ spp = spp2;
+
+ /*
+ * It would make more sense to add the new page at the
+ * head but the order on the list determine the
+ * sequence of the mapping so we can't do that.
+ */
+ TAILQ_INSERT_TAIL(&pagelist, spp, list);
+ } else
+ break;
}
dsp = spp->stat;
for (u = 0; u < statsperpage; u++) {
@@ -515,6 +522,10 @@ devstat_alloc(void)
spp->nfree--;
dsp->allocated = 1;
mtx_unlock(&devstat_mutex);
+ if (spp2 != NULL && spp2 != spp) {
+ free(spp2->stat, M_DEVSTAT);
+ free(spp2, M_DEVSTAT);
+ }
return (dsp);
}
More information about the svn-src-head
mailing list