Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 9 Oct 2004 22:37:39 GMT
From:      Robert Watson <rwatson@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 62928 for review
Message-ID:  <200410092237.i99Mbd61027942@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=62928

Change 62928 by rwatson@rwatson_fledge on 2004/10/09 22:36:38

	Integrate netperf_socket:
	
	- Loop back /dev/random locking strategy revitalization from
	  rwatson_netperf.

Affected files ...

.. //depot/projects/netperf_socket/sys/dev/random/randomdev_soft.c#5 integrate
.. //depot/projects/netperf_socket/sys/ufs/ffs/fs.h#6 integrate

Differences ...

==== //depot/projects/netperf_socket/sys/dev/random/randomdev_soft.c#5 (text+ko) ====

@@ -1,5 +1,6 @@
 /*-
  * Copyright (c) 2000-2004 Mark R V Murray
+ * Copyright (c) 2004 Robert N. M. Watson
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -72,9 +73,14 @@
 
 MALLOC_DEFINE(M_ENTROPY, "entropy", "Entropy harvesting buffers");
 
+/*
+ * The harvest mutex protects the consistency of the entropy fifos and
+ * empty fifo.
+ */
+struct mtx	harvest_mtx;
+
 /* Lockable FIFO queue holding entropy buffers */
 struct entropyfifo {
-	struct mtx lock;
 	int count;
 	STAILQ_HEAD(harvestlist, harvest) head;
 };
@@ -166,7 +172,6 @@
 	/* Initialise the harvest fifos */
 	STAILQ_INIT(&emptyfifo.head);
 	emptyfifo.count = 0;
-	mtx_init(&emptyfifo.lock, "entropy harvest buffers", NULL, MTX_SPIN);
 	for (i = 0; i < EMPTYBUFFERS; i++) {
 		np = malloc(sizeof(struct harvest), M_ENTROPY, M_WAITOK);
 		STAILQ_INSERT_TAIL(&emptyfifo.head, np, next);
@@ -174,10 +179,10 @@
 	for (e = RANDOM_START; e < ENTROPYSOURCE; e++) {
 		STAILQ_INIT(&harvestfifo[e].head);
 		harvestfifo[e].count = 0;
-		mtx_init(&harvestfifo[e].lock, "entropy harvest", NULL,
-		    MTX_SPIN);
 	}
 
+	mtx_init(&harvest_mtx, "entropy harvest mutex", NULL, MTX_SPIN);
+
 	/* Start the hash/reseed thread */
 	error = kthread_create(random_kthread, NULL,
 	    &random_kthread_proc, RFHIGHPID, 0, "yarrow");
@@ -211,18 +216,18 @@
 		STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
 		free(np, M_ENTROPY);
 	}
-	mtx_destroy(&emptyfifo.lock);
 	for (e = RANDOM_START; e < ENTROPYSOURCE; e++) {
 		while (!STAILQ_EMPTY(&harvestfifo[e].head)) {
 			np = STAILQ_FIRST(&harvestfifo[e].head);
 			STAILQ_REMOVE_HEAD(&harvestfifo[e].head, next);
 			free(np, M_ENTROPY);
 		}
-		mtx_destroy(&harvestfifo[e].lock);
 	}
 
 	random_yarrow_deinit_alg();
 
+	mtx_destroy(&harvest_mtx);
+
 	sysctl_ctx_free(&random_clist);
 }
 
@@ -230,52 +235,52 @@
 static void
 random_kthread(void *arg __unused)
 {
+	STAILQ_HEAD(, harvest) local_queue;
 	struct harvest *event = NULL;
-	int found, active;
+	int active;
 	enum esource source;
 
+	STAILQ_INIT(&local_queue);
+
 	/* Process until told to stop */
 	for (; random_kthread_control == 0;) {
 
 		active = 0;
 
 		/* Cycle through all the entropy sources */
+		mtx_lock_spin(&harvest_mtx);
 		for (source = RANDOM_START; source < ENTROPYSOURCE; source++) {
-
-			found = 0;
-
-			/* Lock up queue draining */
-			mtx_lock_spin(&harvestfifo[source].lock);
-
-			if (!STAILQ_EMPTY(&harvestfifo[source].head)) {
-
+			/*
+			 * Drain entropy source records into a thread-local
+			 * queue for processing while not holding the mutex.
+			 */
+			while ((event =
+			    STAILQ_FIRST(&harvestfifo[source].head)) != NULL) {
 				/* Get a harvested entropy event */
 				harvestfifo[source].count--;
-				event = STAILQ_FIRST(&harvestfifo[source].head);
 				STAILQ_REMOVE_HEAD(&harvestfifo[source].head,
 				    next);
-
-				active = found = 1;
-
+				STAILQ_INSERT_TAIL(&local_queue, event, next);
 			}
-			/* Unlock the queue */
-			mtx_unlock_spin(&harvestfifo[source].lock);
+		}
 
-			/* Deal with the event and dispose of it */
-			if (found) {
-
+		/*
+		 * Deal with events, if any, dropping the mutex as we process
+		 * each event.  Then push the events back into the empty
+		 * fifo.
+		 */
+		if (!STAILQ_EMPTY(&local_queue)) {
+			mtx_unlock_spin(&harvest_mtx);
+			STAILQ_FOREACH(event, &local_queue, next)
 				random_process_event(event);
-
-				/* Lock the empty event buffer fifo */
-				mtx_lock_spin(&emptyfifo.lock);
-
+			mtx_lock_spin(&harvest_mtx);
+			while ((event = STAILQ_FIRST(&local_queue)) != NULL) {
+				STAILQ_REMOVE_HEAD(&local_queue, next);
 				STAILQ_INSERT_TAIL(&emptyfifo.head, event,
 				    next);
-
-				mtx_unlock_spin(&emptyfifo.lock);
-
 			}
 		}
+		mtx_unlock_spin(&harvest_mtx);
 
 		/* Found nothing, so don't belabour the issue */
 		if (!active)
@@ -300,30 +305,17 @@
 	if (harvestfifo[origin].count >= RANDOM_FIFO_MAX)
 		return;
 
-	/* Lock the particular fifo */
-	mtx_lock_spin(&harvestfifo[origin].lock);
+	mtx_lock_spin(&harvest_mtx);
 
 	/*
 	 * Don't make the harvest queues too big - help to prevent low-grade
 	 * entropy swamping
 	 */
 	if (harvestfifo[origin].count < RANDOM_FIFO_MAX) {
-
-		/* Lock the empty event buffer fifo */
-		mtx_lock_spin(&emptyfifo.lock);
-
-		if (!STAILQ_EMPTY(&emptyfifo.head)) {
-			event = STAILQ_FIRST(&emptyfifo.head);
+		event = STAILQ_FIRST(&emptyfifo.head);
+		if (event != NULL) {
+			/* Add the harvested data to the fifo */
 			STAILQ_REMOVE_HEAD(&emptyfifo.head, next);
-		} else
-			event = NULL;
-
-		mtx_unlock_spin(&emptyfifo.lock);
-
-		/* If we didn't obtain a buffer, tough */
-		if (event) {
-
-			/* Add the harvested data to the fifo */
 			harvestfifo[origin].count++;
 			event->somecounter = somecounter;
 			event->size = count;
@@ -339,8 +331,7 @@
 			    event, next);
 		}
 	}
-	mtx_unlock_spin(&harvestfifo[origin].lock);
-
+	mtx_unlock_spin(&harvest_mtx);
 }
 
 void

==== //depot/projects/netperf_socket/sys/ufs/ffs/fs.h#6 (text+ko) ====

@@ -27,7 +27,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)fs.h	8.13 (Berkeley) 3/21/95
- * $FreeBSD: src/sys/ufs/ffs/fs.h,v 1.44 2004/08/19 11:09:13 jhb Exp $
+ * $FreeBSD: src/sys/ufs/ffs/fs.h,v 1.45 2004/10/09 20:16:06 njl Exp $
  */
 
 #ifndef _UFS_FFS_FS_H_
@@ -486,7 +486,7 @@
  * Turn filesystem block numbers into disk block addresses.
  * This maps filesystem blocks to device size blocks.
  */
-#define fsbtodb(fs, b)	((b) << (fs)->fs_fsbtodb)
+#define	fsbtodb(fs, b)	((daddr_t)(b) << (fs)->fs_fsbtodb)
 #define	dbtofsb(fs, b)	((b) >> (fs)->fs_fsbtodb)
 
 /*


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