Module Name:    src
Committed By:   riastradh
Date:           Tue Apr 14 13:23:25 UTC 2015

Modified Files:
        src/sys/kern: kern_rndq.c

Log Message:
Gather global pool and sources state into a cacheline-aligned struct.


To generate a diff of this commit:
cvs rdiff -u -r1.57 -r1.58 src/sys/kern/kern_rndq.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/kern_rndq.c
diff -u src/sys/kern/kern_rndq.c:1.57 src/sys/kern/kern_rndq.c:1.58
--- src/sys/kern/kern_rndq.c:1.57	Tue Apr 14 13:15:36 2015
+++ src/sys/kern/kern_rndq.c	Tue Apr 14 13:23:25 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_rndq.c,v 1.57 2015/04/14 13:15:36 riastradh Exp $	*/
+/*	$NetBSD: kern_rndq.c,v 1.58 2015/04/14 13:23:25 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.57 2015/04/14 13:15:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.58 2015/04/14 13:23:25 riastradh Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -125,15 +125,13 @@ static struct {
 static pool_cache_t rnd_mempc;
 
 /*
- * Our random pool.  This is defined here rather than using the general
- * purpose one defined in rndpool.c.
- *
- * Samples are collected and queued into a separate mutex-protected queue
- * (rnd_samples, see above), and processed in a timeout routine; therefore,
- * the mutex protecting the random pool is at IPL_SOFTCLOCK() as well.
+ * Global entropy pool and sources.
  */
-static rndpool_t rnd_pool;
-static kmutex_t  rndpool_mtx;
+static struct {
+	kmutex_t		lock;
+	rndpool_t		pool;
+	LIST_HEAD(, krndsource)	sources;
+} rnd_global __cacheline_aligned;
 
 /*
  * This source is used to easily "remove" queue entries when the source
@@ -176,8 +174,6 @@ static rngtest_t	rnd_rt;
 static uint8_t		rnd_testbits[sizeof(rnd_rt.rt_b)];
 #endif
 
-static LIST_HEAD(, krndsource)	rnd_sources;
-
 static rndsave_t	*boot_rsp;
 
 static inline void
@@ -272,19 +268,19 @@ rnd_getmore(size_t byteswanted)
 {
 	krndsource_t *rs;
 
-	mutex_spin_enter(&rndpool_mtx);
-	LIST_FOREACH(rs, &rnd_sources, list) {
+	mutex_spin_enter(&rnd_global.lock);
+	LIST_FOREACH(rs, &rnd_global.sources, list) {
 		if (!ISSET(rs->flags, RND_FLAG_HASCB))
 			continue;
 		KASSERT(rs->get != NULL);
 		KASSERT(rs->getarg != NULL);
 		rs->get(byteswanted, rs->getarg);
 		rnd_printf_verbose("rnd: entropy estimate %zu bits\n",
-		    rndpool_get_entropy_count(&rnd_pool));
+		    rndpool_get_entropy_count(&rnd_global.pool));
 		rnd_printf_verbose("rnd: asking source %s for %zu bytes\n",
 		    rs->name, byteswanted);
 	}
-	mutex_spin_exit(&rndpool_mtx);
+	mutex_spin_exit(&rnd_global.lock);
 }
 
 /*
@@ -298,10 +294,10 @@ rnd_wakeup_readers(void)
 	 * XXX This bookkeeping shouldn't be here -- this is not where
 	 * the rnd_initial_entropy state change actually happens.
 	 */
-	mutex_spin_enter(&rndpool_mtx);
-	const size_t entropy_count = rndpool_get_entropy_count(&rnd_pool);
+	mutex_spin_enter(&rnd_global.lock);
+	const size_t entropy_count = rndpool_get_entropy_count(&rnd_global.pool);
 	if (entropy_count < RND_ENTROPY_THRESHOLD * 8) {
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 		return;
 	} else {
 #ifdef RND_VERBOSE
@@ -311,7 +307,7 @@ rnd_wakeup_readers(void)
 #endif
 		rnd_initial_entropy = 1;
 	}
-	mutex_spin_exit(&rndpool_mtx);
+	mutex_spin_exit(&rnd_global.lock);
 
 	rndsinks_distribute();
 }
@@ -508,11 +504,11 @@ rnd_init(void)
 	 */
 	c = rnd_counter();
 
-	LIST_INIT(&rnd_sources);
+	LIST_INIT(&rnd_global.sources);
 	SIMPLEQ_INIT(&rnd_samples.q);
 
-	rndpool_init(&rnd_pool);
-	mutex_init(&rndpool_mtx, MUTEX_DEFAULT, IPL_VM);
+	rndpool_init(&rnd_global.pool);
+	mutex_init(&rnd_global.lock, MUTEX_DEFAULT, IPL_VM);
 
 	rnd_mempc = pool_cache_init(sizeof(rnd_sample_t), 0, 0, 0,
 				    "rndsample", NULL, IPL_VM,
@@ -533,11 +529,11 @@ rnd_init(void)
 	 * XXX more things to add would be nice.
 	 */
 	if (c) {
-		mutex_spin_enter(&rndpool_mtx);
-		rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
+		mutex_spin_enter(&rnd_global.lock);
+		rndpool_add_data(&rnd_global.pool, &c, sizeof(c), 1);
 		c = rnd_counter();
-		rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
-		mutex_spin_exit(&rndpool_mtx);
+		rndpool_add_data(&rnd_global.pool, &c, sizeof(c), 1);
+		mutex_spin_exit(&rnd_global.lock);
 	}
 
 	/*
@@ -547,7 +543,7 @@ rnd_init(void)
  	 *
 	 */
 #if defined(__HAVE_CPU_COUNTER)
-	/* IPL_VM because taken while rndpool_mtx is held.  */
+	/* IPL_VM because taken while rnd_global.lock is held.  */
 	mutex_init(&rnd_skew.lock, MUTEX_DEFAULT, IPL_VM);
 	callout_init(&rnd_skew.callout, CALLOUT_MPSAFE);
 	callout_init(&rnd_skew.stop_callout, CALLOUT_MPSAFE);
@@ -564,15 +560,15 @@ rnd_init(void)
 	rnd_printf_verbose("rnd: initialised (%u)%s", RND_POOLBITS,
 	    c ? " with counter\n" : "\n");
 	if (boot_rsp != NULL) {
-		mutex_spin_enter(&rndpool_mtx);
-		rndpool_add_data(&rnd_pool, boot_rsp->data,
+		mutex_spin_enter(&rnd_global.lock);
+		rndpool_add_data(&rnd_global.pool, boot_rsp->data,
 		    sizeof(boot_rsp->data),
 		    MIN(boot_rsp->entropy, RND_POOLBITS / 2));
-		if (rndpool_get_entropy_count(&rnd_pool) >
+		if (rndpool_get_entropy_count(&rnd_global.pool) >
 		    RND_ENTROPY_THRESHOLD * 8) {
                 	rnd_initial_entropy = 1;
 		}
-                mutex_spin_exit(&rndpool_mtx);
+                mutex_spin_exit(&rnd_global.lock);
 		rnd_printf("rnd: seeded with %d bits\n",
 		    MIN(boot_rsp->entropy, RND_POOLBITS / 2));
 		memset(boot_rsp, 0, sizeof(*boot_rsp));
@@ -674,8 +670,8 @@ rnd_attach_source(krndsource_t *rs, cons
 
 	rs->state = rnd_sample_allocate(rs);
 
-	mutex_spin_enter(&rndpool_mtx);
-	LIST_INSERT_HEAD(&rnd_sources, rs, list);
+	mutex_spin_enter(&rnd_global.lock);
+	LIST_INSERT_HEAD(&rnd_global.sources, rs, list);
 
 #ifdef RND_VERBOSE
 	rnd_printf_verbose("rnd: %s attached as an entropy source (",
@@ -696,8 +692,8 @@ rnd_attach_source(krndsource_t *rs, cons
 	 * entropy per source-attach timestamp.  I am skeptical,
 	 * but we count 1 bit per source here.
 	 */
-	rndpool_add_data(&rnd_pool, &ts, sizeof(ts), 1);
-	mutex_spin_exit(&rndpool_mtx);
+	rndpool_add_data(&rnd_global.pool, &ts, sizeof(ts), 1);
+	mutex_spin_exit(&rnd_global.lock);
 }
 
 /*
@@ -708,9 +704,9 @@ rnd_detach_source(krndsource_t *source)
 {
 	rnd_sample_t *sample;
 
-	mutex_spin_enter(&rndpool_mtx);
+	mutex_spin_enter(&rnd_global.lock);
 	LIST_REMOVE(source, list);
-	mutex_spin_exit(&rndpool_mtx);
+	mutex_spin_exit(&rnd_global.lock);
 
 	/*
 	 * If there are samples queued up "remove" them from the sample queue
@@ -822,9 +818,9 @@ rnd_add_data(krndsource_t *rs, const voi
 	 * timestamp, just directly add the data.
 	 */
 	if (__predict_false(rs == NULL)) {
-		mutex_spin_enter(&rndpool_mtx);
-		rndpool_add_data(&rnd_pool, data, len, entropy);
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
+		rndpool_add_data(&rnd_global.pool, data, len, entropy);
+		mutex_spin_exit(&rnd_global.lock);
 	} else {
 		rnd_add_data_ts(rs, data, len, entropy, rnd_counter());
 	}
@@ -1035,9 +1031,9 @@ rnd_process_events(void)
 	mutex_spin_exit(&rnd_samples.lock);
 
 	/* Don't thrash the rndpool mtx either.  Hold, add all samples. */
-	mutex_spin_enter(&rndpool_mtx);
+	mutex_spin_enter(&rnd_global.lock);
 
-	pool_entropy = rndpool_get_entropy_count(&rnd_pool);
+	pool_entropy = rndpool_get_entropy_count(&rnd_global.pool);
 
 	while ((sample = SIMPLEQ_FIRST(&dq_samples))) {
 		int sample_count;
@@ -1080,13 +1076,13 @@ rnd_process_events(void)
 		}
 
 		if (source->flags & RND_FLAG_COLLECT_VALUE) {
-			rndpool_add_data(&rnd_pool, sample->values,
+			rndpool_add_data(&rnd_global.pool, sample->values,
 					 sample_count *
 					     sizeof(sample->values[1]),
 					 0);
 		}
 		if (source->flags & RND_FLAG_COLLECT_TIME) {
-			rndpool_add_data(&rnd_pool, sample->ts,
+			rndpool_add_data(&rnd_global.pool, sample->ts,
 					 sample_count *
 					     sizeof(sample->ts[1]),
 					 0);
@@ -1096,8 +1092,8 @@ rnd_process_events(void)
 		source->total += sample->entropy;
 skip:		SIMPLEQ_INSERT_TAIL(&df_samples, sample, next);
 	}
-	rndpool_set_entropy_count(&rnd_pool, pool_entropy);
-	mutex_spin_exit(&rndpool_mtx);
+	rndpool_set_entropy_count(&rnd_global.pool, pool_entropy);
+	mutex_spin_exit(&rnd_global.lock);
 
 	/*
 	 * If we filled the pool past the threshold, wake anyone
@@ -1145,10 +1141,10 @@ rnd_extract_data(void *p, uint32_t len, 
 	int entropy_count;
 	uint32_t retval;
 
-	mutex_spin_enter(&rndpool_mtx);
+	mutex_spin_enter(&rnd_global.lock);
 	if (__predict_false(!timed_in)) {
 		if (boottime.tv_sec) {
-			rndpool_add_data(&rnd_pool, &boottime,
+			rndpool_add_data(&rnd_global.pool, &boottime,
 					 sizeof(boottime), 0);
 		}
 		timed_in++;
@@ -1157,19 +1153,19 @@ rnd_extract_data(void *p, uint32_t len, 
 		uint32_t c;
 
 		rnd_printf_verbose("rnd: WARNING! initial entropy low (%u).\n",
-		       rndpool_get_entropy_count(&rnd_pool));
+		       rndpool_get_entropy_count(&rnd_global.pool));
 		/* Try once again to put something in the pool */
 		c = rnd_counter();
-		rndpool_add_data(&rnd_pool, &c, sizeof(c), 1);
+		rndpool_add_data(&rnd_global.pool, &c, sizeof(c), 1);
 	}
 
 #ifdef DIAGNOSTIC
 	while (!rnd_tested) {
-		entropy_count = rndpool_get_entropy_count(&rnd_pool);
+		entropy_count = rndpool_get_entropy_count(&rnd_global.pool);
 		rnd_printf_verbose("rnd: starting statistical RNG test,"
 		    " entropy = %d.\n",
 		    entropy_count);
-		if (rndpool_extract_data(&rnd_pool, rnd_rt.rt_b,
+		if (rndpool_extract_data(&rnd_global.pool, rnd_rt.rt_b,
 		    sizeof(rnd_rt.rt_b), RND_EXTRACT_ANY)
 		    != sizeof(rnd_rt.rt_b)) {
 			panic("rnd: could not get bits for statistical test");
@@ -1195,18 +1191,18 @@ rnd_extract_data(void *p, uint32_t len, 
 			continue;
 		}
 		memset(&rnd_rt, 0, sizeof(rnd_rt));
-		rndpool_add_data(&rnd_pool, rnd_testbits, sizeof(rnd_testbits),
-				 entropy_count);
+		rndpool_add_data(&rnd_global.pool, rnd_testbits,
+		    sizeof(rnd_testbits), entropy_count);
 		memset(rnd_testbits, 0, sizeof(rnd_testbits));
 		rnd_printf_verbose("rnd: statistical RNG test done,"
 		    " entropy = %d.\n",
-		    rndpool_get_entropy_count(&rnd_pool));
+		    rndpool_get_entropy_count(&rnd_global.pool));
 		rnd_tested++;
 	}
 #endif
-	entropy_count = rndpool_get_entropy_count(&rnd_pool);
-	retval = rndpool_extract_data(&rnd_pool, p, len, flags);
-	mutex_spin_exit(&rndpool_mtx);
+	entropy_count = rndpool_get_entropy_count(&rnd_global.pool);
+	retval = rndpool_extract_data(&rnd_global.pool, p, len, flags);
+	mutex_spin_exit(&rnd_global.lock);
 
 	if (entropy_count < (RND_ENTROPY_THRESHOLD * 2 + len) * NBBY) {
 		rnd_printf_verbose("rnd: empty, asking for %d bytes\n",
@@ -1256,10 +1252,10 @@ rnd_tryextract(void *buffer, size_t byte
 	KASSERT(bytes <= RNDSINK_MAX_BYTES);
 	bits_needed = ((bytes + RND_ENTROPY_THRESHOLD) * NBBY);
 
-	mutex_spin_enter(&rndpool_mtx);
-	if (bits_needed <= rndpool_get_entropy_count(&rnd_pool)) {
+	mutex_spin_enter(&rnd_global.lock);
+	if (bits_needed <= rndpool_get_entropy_count(&rnd_global.pool)) {
 		const uint32_t extracted __diagused =
-		    rndpool_extract_data(&rnd_pool, buffer, bytes,
+		    rndpool_extract_data(&rnd_global.pool, buffer, bytes,
 			RND_EXTRACT_GOOD);
 
 		KASSERT(extracted == bytes);
@@ -1267,10 +1263,10 @@ rnd_tryextract(void *buffer, size_t byte
 	} else {
 		/* XXX Figure the threshold into this...  */
 		bytes_requested = howmany((bits_needed -
-			rndpool_get_entropy_count(&rnd_pool)), NBBY);
+			rndpool_get_entropy_count(&rnd_global.pool)), NBBY);
 		KASSERT(0 < bytes_requested);
 	}
-	mutex_spin_exit(&rndpool_mtx);
+	mutex_spin_exit(&rnd_global.lock);
 
 	if (0 < bytes_requested)
 		rnd_getmore(bytes_requested);
@@ -1308,12 +1304,12 @@ rnd_seed(void *base, size_t len)
 	if (rnd_ready) {
 		rnd_printf_verbose("rnd: ready,"
 		    " feeding in seed data directly.\n");
-		mutex_spin_enter(&rndpool_mtx);
-		rndpool_add_data(&rnd_pool, boot_rsp->data,
+		mutex_spin_enter(&rnd_global.lock);
+		rndpool_add_data(&rnd_global.pool, boot_rsp->data,
 				 sizeof(boot_rsp->data),
 				 MIN(boot_rsp->entropy, RND_POOLBITS / 2));
 		memset(boot_rsp, 0, sizeof(*boot_rsp));
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 	} else {
 		rnd_printf_verbose("rnd: not ready, deferring seed feed.\n");
 	}
@@ -1409,15 +1405,16 @@ rnd_system_ioctl(struct file *fp, u_long
 
 	switch (cmd) {
 	case RNDGETENTCNT:
-		mutex_spin_enter(&rndpool_mtx);
-		*(uint32_t *)addr = rndpool_get_entropy_count(&rnd_pool);
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
+		*(uint32_t *)addr = rndpool_get_entropy_count(&rnd_global.pool);
+		mutex_spin_exit(&rnd_global.lock);
 		break;
 
 	case RNDGETPOOLSTAT:
-		mutex_spin_enter(&rndpool_mtx);
-		rndpool_get_stats(&rnd_pool, addr, sizeof(rndpoolstat_t));
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
+		rndpool_get_stats(&rnd_global.pool, addr,
+		    sizeof(rndpoolstat_t));
+		mutex_spin_exit(&rnd_global.lock);
 		break;
 
 	case RNDGETSRCNUM:
@@ -1429,12 +1426,12 @@ rnd_system_ioctl(struct file *fp, u_long
 		if (rst->count > RND_MAXSTATCOUNT)
 			return (EINVAL);
 
-		mutex_spin_enter(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
 		/*
 		 * Find the starting source by running through the
 		 * list of sources.
 		 */
-		kr = LIST_FIRST(&rnd_sources);
+		kr = LIST_FIRST(&rnd_global.sources);
 		start = rst->start;
 		while (kr != NULL && start >= 1) {
 			kr = LIST_NEXT(kr, list);
@@ -1453,7 +1450,7 @@ rnd_system_ioctl(struct file *fp, u_long
 
 		rst->count = count;
 
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 		break;
 
 	case RNDGETESTNUM:
@@ -1465,12 +1462,12 @@ rnd_system_ioctl(struct file *fp, u_long
 		if (rset->count > RND_MAXSTATCOUNT)
 			return (EINVAL);
 
-		mutex_spin_enter(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
 		/*
 		 * Find the starting source by running through the
 		 * list of sources.
 		 */
-		kr = LIST_FIRST(&rnd_sources);
+		kr = LIST_FIRST(&rnd_global.sources);
 		start = rset->start;
 		while (kr != NULL && start > 1) {
 			kr = LIST_NEXT(kr, list);
@@ -1488,27 +1485,27 @@ rnd_system_ioctl(struct file *fp, u_long
 
 		rset->count = count;
 
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 		break;
 
 	case RNDGETSRCNAME:
 		/*
 		 * Scan through the list, trying to find the name.
 		 */
-		mutex_spin_enter(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
 		rstnm = (rndstat_name_t *)addr;
-		kr = LIST_FIRST(&rnd_sources);
+		kr = LIST_FIRST(&rnd_global.sources);
 		while (kr != NULL) {
 			if (strncmp(kr->name, rstnm->name,
 				    MIN(sizeof(kr->name),
 					sizeof(rstnm->name))) == 0) {
 				krndsource_to_rndsource(kr, &rstnm->source);
-				mutex_spin_exit(&rndpool_mtx);
+				mutex_spin_exit(&rnd_global.lock);
 				return (0);
 			}
 			kr = LIST_NEXT(kr, list);
 		}
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 
 		ret = ENOENT;		/* name not found */
 
@@ -1518,21 +1515,21 @@ rnd_system_ioctl(struct file *fp, u_long
 		/*
 		 * Scan through the list, trying to find the name.
 		 */
-		mutex_spin_enter(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
 		rsetnm = (rndstat_est_name_t *)addr;
-		kr = LIST_FIRST(&rnd_sources);
+		kr = LIST_FIRST(&rnd_global.sources);
 		while (kr != NULL) {
 			if (strncmp(kr->name, rsetnm->name,
 				    MIN(sizeof(kr->name),
 					sizeof(rsetnm->name))) == 0) {
 				krndsource_to_rndsource_est(kr,
 							    &rsetnm->source);
-				mutex_spin_exit(&rndpool_mtx);
+				mutex_spin_exit(&rnd_global.lock);
 				return (0);
 			}
 			kr = LIST_NEXT(kr, list);
 		}
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 
 		ret = ENOENT;           /* name not found */
 
@@ -1543,9 +1540,9 @@ rnd_system_ioctl(struct file *fp, u_long
 		 * Set flags to enable/disable entropy counting and/or
 		 * collection.
 		 */
-		mutex_spin_enter(&rndpool_mtx);
+		mutex_spin_enter(&rnd_global.lock);
 		rctl = (rndctl_t *)addr;
-		kr = LIST_FIRST(&rnd_sources);
+		kr = LIST_FIRST(&rnd_global.sources);
 
 		/*
 		 * Flags set apply to all sources of this type.
@@ -1558,7 +1555,7 @@ rnd_system_ioctl(struct file *fp, u_long
 				}
 				kr = LIST_NEXT(kr, list);
 			}
-			mutex_spin_exit(&rndpool_mtx);
+			mutex_spin_exit(&rnd_global.lock);
 			return (0);
 		}
 
@@ -1570,13 +1567,13 @@ rnd_system_ioctl(struct file *fp, u_long
 				    MIN(sizeof(kr->name),
                                         sizeof(rctl->name))) == 0) {
 				krs_setflags(kr, rctl->flags, rctl->mask);
-				mutex_spin_exit(&rndpool_mtx);
+				mutex_spin_exit(&rnd_global.lock);
 				return (0);
 			}
 			kr = LIST_NEXT(kr, list);
 		}
 
-		mutex_spin_exit(&rndpool_mtx);
+		mutex_spin_exit(&rnd_global.lock);
 		ret = ENOENT;		/* name not found */
 
 		break;
@@ -1605,10 +1602,10 @@ rnd_system_ioctl(struct file *fp, u_long
 				estimate = 0;
 			}
 
-			mutex_spin_enter(&rndpool_mtx);
-			rndpool_add_data(&rnd_pool, rnddata->data,
+			mutex_spin_enter(&rnd_global.lock);
+			rndpool_add_data(&rnd_global.pool, rnddata->data,
 					 rnddata->len, estimate);
-			mutex_spin_exit(&rndpool_mtx);
+			mutex_spin_exit(&rnd_global.lock);
 
 			rnd_wakeup_readers();
 		} else {

Reply via email to