Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Sep 2009 13:48:38 +0000 (UTC)
From:      Attilio Rao <attilio@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r197309 - head/sys/kern
Message-ID:  <200909181348.n8IDmc4V092414@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200909181348.n8IDmc4V092414>