Module Name:    src
Committed By:   martin
Date:           Sun Nov  2 09:47:04 UTC 2014

Modified Files:
        src/doc [netbsd-7]: CHANGES
        src/sys/dev [netbsd-7]: rndpseudo.c
        src/sys/kern [netbsd-7]: kern_rndq.c kern_rndsink.c
        src/sys/sys [netbsd-7]: rnd.h

Log Message:
Pull up following revision(s) (requested by tls in ticket #173):
        doc/CHANGES: revision 1.2004
        sys/sys/rnd.h: revision 1.43
        sys/kern/kern_rndq.c: revision 1.28
        sys/kern/kern_rndsink.c: revision 1.10
        sys/dev/rndpseudo.c: revision 1.23
Fixes and enhancements for polled entropy sources:
        Add explicit enable/disable hooks for callout-driven sources (be more
        power friendly).
        Make "skew" source polled so it runs only when there is entropy
        demand.
        Adjust entropy collection from polled sources so it's processed
        sooner.


To generate a diff of this commit:
cvs rdiff -u -r1.1967.2.2 -r1.1967.2.3 src/doc/CHANGES
cvs rdiff -u -r1.21 -r1.21.2.1 src/sys/dev/rndpseudo.c
cvs rdiff -u -r1.26.2.1 -r1.26.2.2 src/sys/kern/kern_rndq.c
cvs rdiff -u -r1.8 -r1.8.6.1 src/sys/kern/kern_rndsink.c
cvs rdiff -u -r1.41 -r1.41.2.1 src/sys/sys/rnd.h

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

Modified files:

Index: src/doc/CHANGES
diff -u src/doc/CHANGES:1.1967.2.2 src/doc/CHANGES:1.1967.2.3
--- src/doc/CHANGES:1.1967.2.2	Thu Sep 11 13:54:54 2014
+++ src/doc/CHANGES	Sun Nov  2 09:47:03 2014
@@ -1,4 +1,4 @@
-# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.1967.2.2 $>
+# LIST OF CHANGES FROM LAST RELEASE:			<$Revision: 1.1967.2.3 $>
 #
 #
 # [Note: This file does not mention every change made to the NetBSD source tree.
@@ -21,7 +21,7 @@
 #
 # See htutils/changes/changes2html script for more details.
 #
-LIST OF CHANGES FROM PREVIOUS RELEASES:			<$Revision: 1.1967.2.2 $>
+LIST OF CHANGES FROM PREVIOUS RELEASES:			<$Revision: 1.1967.2.3 $>
 
 
 Changes from NetBSD 6.0 to NetBSD 7.0:
@@ -83,6 +83,12 @@ Changes from NetBSD 6.0 to NetBSD 7.0:
 	kernel, libc: Add MurmurHash2 function. [rmind 20120708]
 	atf(7): Import 0.16.  [jmmv 20120711]
 	dhcpcd(8): Import dhcpcd-5.6.1. [roy 20120712]
+	rnd(9): Add explicit enable/disable hooks for callout-driven
+		sources (be more power friendly). [tls 20141026]
+	rnd(9): Make "skew" source polled so it runs only when there
+	        is entropy demand. [tls 20141026]
+	rnd(9): Adjust entropy collection from polled sources so it's
+		processed sooner. [tls 20141026]
 	kernel: Add support for sensors to provide entropy to rnd(4)
 		[pgoyette 20120715]
 	tdvfb(4): Add 3Dfx Voodoo2 driver. [rkujawa 20120719]

Index: src/sys/dev/rndpseudo.c
diff -u src/sys/dev/rndpseudo.c:1.21 src/sys/dev/rndpseudo.c:1.21.2.1
--- src/sys/dev/rndpseudo.c:1.21	Sun Aug 10 16:44:35 2014
+++ src/sys/dev/rndpseudo.c	Sun Nov  2 09:47:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rndpseudo.c,v 1.21 2014/08/10 16:44:35 tls Exp $	*/
+/*	$NetBSD: rndpseudo.c,v 1.21.2.1 2014/11/02 09:47:04 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997-2013 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.21 2014/08/10 16:44:35 tls Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.21.2.1 2014/11/02 09:47:04 martin Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_compat_netbsd.h"
@@ -526,6 +526,20 @@ krndsource_to_rndsource_est(krndsource_t
 	re->dv_total = kr->value_delta.outbits;
 }
 
+static void
+krs_setflags(krndsource_t *kr, uint32_t flags, uint32_t mask)
+{
+	uint32_t oflags = kr->flags;
+
+	kr->flags &= ~mask;
+	kr->flags |= (flags & mask);
+
+	if (oflags & RND_FLAG_HASENABLE &&
+            ((oflags & RND_FLAG_NO_COLLECT) != (flags & RND_FLAG_NO_COLLECT))) {
+		kr->enable(kr, !(flags & RND_FLAG_NO_COLLECT));
+	}
+}
+
 int
 rnd_ioctl(struct file *fp, u_long cmd, void *addr)
 {
@@ -536,7 +550,7 @@ rnd_ioctl(struct file *fp, u_long cmd, v
 	rndstat_est_name_t *rsetnm;
 	rndctl_t *rctl;
 	rnddata_t *rnddata;
-	u_int32_t count, start;
+	uint32_t count, start;
 	int ret = 0;
 	int estimate_ok = 0, estimate = 0;
 
@@ -736,12 +750,9 @@ rnd_ioctl(struct file *fp, u_long cmd, v
 		if (rctl->type != 0xff) {
 			while (kr != NULL) {
 				if (kr->type == rctl->type) {
-					kr->flags &= ~rctl->mask;
-
-					kr->flags |=
-					    (rctl->flags & rctl->mask);
+					krs_setflags(kr,
+						     rctl->flags, rctl->mask);
 				}
-
 				kr = kr->list.le_next;
 			}
 			mutex_spin_exit(&rndpool_mtx);
@@ -755,9 +766,7 @@ rnd_ioctl(struct file *fp, u_long cmd, v
 			if (strncmp(kr->name, rctl->name,
 				    MIN(sizeof(kr->name),
                                         sizeof(rctl->name))) == 0) {
-				kr->flags &= ~rctl->mask;
-				kr->flags |= (rctl->flags & rctl->mask);
-
+				krs_setflags(kr, rctl->flags, rctl->mask);
 				mutex_spin_exit(&rndpool_mtx);
 				return (0);
 			}

Index: src/sys/kern/kern_rndq.c
diff -u src/sys/kern/kern_rndq.c:1.26.2.1 src/sys/kern/kern_rndq.c:1.26.2.2
--- src/sys/kern/kern_rndq.c:1.26.2.1	Mon Aug 11 15:38:27 2014
+++ src/sys/kern/kern_rndq.c	Sun Nov  2 09:47:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_rndq.c,v 1.26.2.1 2014/08/11 15:38:27 martin Exp $	*/
+/*	$NetBSD: kern_rndq.c,v 1.26.2.2 2014/11/02 09:47:04 martin 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.26.2.1 2014/08/11 15:38:27 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.26.2.2 2014/11/02 09:47:04 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/atomic.h>
@@ -160,7 +160,7 @@ static krndsource_t rnd_source_anonymous
 krndsource_t rnd_printf_source, rnd_autoconf_source;
 
 void *rnd_process, *rnd_wakeup;
-struct callout skew_callout;
+struct callout skew_callout, skew_stop_callout;
 
 void	      		rnd_wakeup_readers(void);
 static inline uint32_t	rnd_counter(void);
@@ -283,6 +283,8 @@ rnd_getmore(size_t byteswanted)
 			KASSERT(rs->getarg != NULL);
 			rs->get(byteswanted, rs->getarg);
 #ifdef RND_VERBOSE
+			rnd_printf("rnd: entropy estimate %zu bits\n",
+				   rndpool_get_entropy_count(&rnd_pool));
 			rnd_printf("rnd: asking source %s for %zu bytes\n",
 			       rs->name, byteswanted);
 #endif
@@ -426,6 +428,44 @@ rnd_dv_estimate(krndsource_t *rs, uint32
 }
 
 #if defined(__HAVE_CPU_COUNTER)
+kmutex_t                        rnd_skew_mtx;
+
+static void rnd_skew(void *);
+
+static void
+rnd_skew_enable(krndsource_t *rs, bool enabled)
+{
+	mutex_spin_enter(&rnd_skew_mtx);
+	if (enabled) {
+		rnd_skew(rs);
+	} else {
+		callout_stop(&skew_callout);
+	}
+	mutex_spin_exit(&rnd_skew_mtx);
+}
+
+static void
+rnd_skew_stop(void *arg)
+{
+	mutex_spin_enter(&rnd_skew_mtx);
+	callout_stop(&skew_callout);
+	mutex_spin_exit(&rnd_skew_mtx);
+}
+
+static void
+rnd_skew_get(size_t bytes, void *priv)
+{
+	krndsource_t *skewsrcp = priv;
+	if (RND_ENABLED(skewsrcp)) {
+		/* Measure for 30s */
+		if (mutex_tryenter(&rnd_skew_mtx)) {
+			callout_schedule(&skew_stop_callout, hz * 30);
+			callout_schedule(&skew_callout, 1);
+			mutex_spin_exit(&rnd_skew_mtx);
+		}
+	}
+}
+
 static void
 rnd_skew(void *arg)
 {
@@ -433,34 +473,35 @@ rnd_skew(void *arg)
 	static int live, flipflop;
 
 	/*
-	 * Only one instance of this callout will ever be scheduled
-	 * at a time (it is only ever scheduled by itself).  So no
-	 * locking is required here.
-	 */
-
-	/*
 	 * Even on systems with seemingly stable clocks, the
 	 * delta-time entropy estimator seems to think we get 1 bit here
-	 * about every 2 calls.  That seems like too much.  Instead,
-	 * we feed the rnd_counter() value to the value estimator as well,
-	 * to take advantage of the additional LZ test on estimated values.
+	 * about every 2 calls.
 	 *
 	 */
 	if (__predict_false(!live)) {
+		/* XXX must be spin, taken with rndpool_mtx held */
+		mutex_init(&rnd_skew_mtx, MUTEX_DEFAULT, IPL_VM);
+		rndsource_setcb(&skewsrc, rnd_skew_get, &skewsrc);
+		rndsource_setenable(&skewsrc, rnd_skew_enable);
 		rnd_attach_source(&skewsrc, "callout", RND_TYPE_SKEW,
 				  RND_FLAG_COLLECT_VALUE|
-				  RND_FLAG_ESTIMATE_VALUE);
+				  RND_FLAG_ESTIMATE_VALUE|
+				  RND_FLAG_HASCB|RND_FLAG_HASENABLE);
 		live = 1;
+		return;
 	}
-
+	mutex_spin_enter(&rnd_skew_mtx);
 	flipflop = !flipflop;
 
-	if (flipflop) {
-		rnd_add_uint32(&skewsrc, rnd_counter());
-		callout_schedule(&skew_callout, hz / 10);
-	} else {
-		callout_schedule(&skew_callout, 1);
+	if (RND_ENABLED(&skewsrc)) {
+		if (flipflop) {
+			rnd_add_uint32(&skewsrc, rnd_counter());
+			callout_schedule(&skew_callout, hz / 10);
+		} else {
+			callout_schedule(&skew_callout, 1);
+		}
 	}
+	mutex_spin_exit(&rnd_skew_mtx);
 }
 #endif
 
@@ -527,7 +568,9 @@ rnd_init(void)
 	 */
 #if defined(__HAVE_CPU_COUNTER)
 	callout_init(&skew_callout, CALLOUT_MPSAFE);
+	callout_init(&skew_stop_callout, CALLOUT_MPSAFE);
 	callout_setfunc(&skew_callout, rnd_skew, NULL);
+	callout_setfunc(&skew_stop_callout, rnd_skew_stop, NULL);
 	rnd_skew(NULL);
 #endif
 
@@ -835,15 +878,16 @@ rnd_add_data_ts(krndsource_t *rs, const 
 	 * is adding entropy at a rate of at least 1 bit every 10 seconds,
 	 * mark it as "fast" and add its samples in bulk.
 	 */
-	if (__predict_true(rs->flags & RND_FLAG_FAST)) {
+	if (__predict_true(rs->flags & RND_FLAG_FAST) ||
+	    (todo >= RND_SAMPLE_COUNT)) {
 		sample_count = RND_SAMPLE_COUNT;
 	} else {
-		if (!cold && rnd_initial_entropy) {
+		if (!(rs->flags & RND_FLAG_HASCB) &&
+		    !cold && rnd_initial_entropy) {
 			struct timeval upt;
 
 			getmicrouptime(&upt);
-			if ((todo >= RND_SAMPLE_COUNT) ||
-			    (upt.tv_sec > 0  && rs->total > upt.tv_sec * 10) ||
+			if ( (upt.tv_sec > 0  && rs->total > upt.tv_sec * 10) ||
 			    (upt.tv_sec > 10 && rs->total > upt.tv_sec) ||
 			    (upt.tv_sec > 100 &&
 			      rs->total > upt.tv_sec / 10)) {
@@ -1083,10 +1127,10 @@ rnd_process_events(void)
 		wake++;
 	} else {
 		rnd_empty = 1;
-		rnd_getmore((RND_POOLBITS - pool_entropy) / 8);
+		rnd_getmore(howmany((RND_POOLBITS - pool_entropy), NBBY));
 #ifdef RND_VERBOSE
-		rnd_printf("rnd: empty, asking for %d bits\n",
-		       (int)((RND_POOLBITS - pool_entropy) / 8));
+		rnd_printf("rnd: empty, asking for %d bytes\n",
+		       (int)(howmany((RND_POOLBITS - pool_entropy), NBBY)));
 #endif
 	}
 	mutex_spin_exit(&rndpool_mtx);
@@ -1201,6 +1245,11 @@ rnd_extract_data_locked(void *p, u_int32
 #endif
 	entropy_count = rndpool_get_entropy_count(&rnd_pool);
 	if (entropy_count < (RND_ENTROPY_THRESHOLD * 2 + len) * NBBY) {
+#ifdef RND_VERBOSE
+		rnd_printf("rnd: empty, asking for %d bytes\n",
+			   (int)(howmany((RND_POOLBITS - entropy_count),
+				 NBBY)));
+#endif
 		rnd_getmore(howmany((RND_POOLBITS - entropy_count), NBBY));
 	}
 	return rndpool_extract_data(&rnd_pool, p, len, flags);

Index: src/sys/kern/kern_rndsink.c
diff -u src/sys/kern/kern_rndsink.c:1.8 src/sys/kern/kern_rndsink.c:1.8.6.1
--- src/sys/kern/kern_rndsink.c:1.8	Sat Mar  1 14:15:15 2014
+++ src/sys/kern/kern_rndsink.c	Sun Nov  2 09:47:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kern_rndsink.c,v 1.8 2014/03/01 14:15:15 riastradh Exp $	*/
+/*	$NetBSD: kern_rndsink.c,v 1.8.6.1 2014/11/02 09:47:04 martin Exp $	*/
 
 /*-
  * Copyright (c) 2013 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_rndsink.c,v 1.8 2014/03/01 14:15:15 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndsink.c,v 1.8.6.1 2014/11/02 09:47:04 martin Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -214,15 +214,17 @@ rndsinks_enqueue(struct rndsink *rndsink
 	 * XXX This should request only rndsink->rs_bytes bytes of
 	 * entropy, but that might get buffered up indefinitely because
 	 * kern_rndq has no bound on the duration before it will
-	 * process queued entropy samples.  For now, request refilling
-	 * the pool altogether so that the buffer will fill up and get
-	 * processed.  Later, we ought to (a) bound the duration before
+	 * process queued entropy samples.  To work around this, we are
+	 * a little too incestuous with kern_rndq: we avoid marking polled
+	 * sources "fast" there, and know here that for non-fast sources,
+	 * that code will buffer two ints worth of data per source.
+	 * Later, we ought to (a) bound the duration before
 	 * queued entropy samples get processed, and (b) add a target
 	 * or something -- as soon as we get that much from the entropy
 	 * sources, distribute it.
 	 */
 	mutex_spin_enter(&rndpool_mtx);
-	rnd_getmore(RND_POOLBITS / NBBY);
+	rnd_getmore(MAX(rndsink->rsink_bytes, 2 * sizeof(uint32_t)));
 	mutex_spin_exit(&rndpool_mtx);
 
 	switch (rndsink->rsink_state) {

Index: src/sys/sys/rnd.h
diff -u src/sys/sys/rnd.h:1.41 src/sys/sys/rnd.h:1.41.2.1
--- src/sys/sys/rnd.h:1.41	Sun Aug 10 16:44:36 2014
+++ src/sys/sys/rnd.h	Sun Nov  2 09:47:04 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rnd.h,v 1.41 2014/08/10 16:44:36 tls Exp $	*/
+/*	$NetBSD: rnd.h,v 1.41.2.1 2014/11/02 09:47:04 martin Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -105,6 +105,7 @@ typedef struct {
 #define RND_FLAG_COLLECT_VALUE	0x00002000	/* use value as input */
 #define RND_FLAG_ESTIMATE_TIME	0x00004000	/* estimate entropy on time */
 #define RND_FLAG_ESTIMATE_VALUE	0x00008000	/* estimate entropy on value */
+#define	RND_FLAG_HASENABLE	0x00010000	/* has enable/disable fns */
 #define RND_FLAG_DEFAULT	(RND_FLAG_COLLECT_VALUE|RND_FLAG_COLLECT_TIME|\
 				 RND_FLAG_ESTIMATE_TIME)
 
@@ -150,6 +151,7 @@ typedef struct krndsource {
         size_t          test_cnt;       /* how much test data accumulated? */
 	void		(*get)(size_t, void *);	/* pool wants N bytes (badly) */
 	void		*getarg;	/* argument to get-function */
+	void		(*enable)(struct krndsource *, bool); /* turn on/off */
 	rngtest_t	*test;		/* test data for RNG type sources */
 } krndsource_t;
 
@@ -160,6 +162,12 @@ rndsource_setcb(struct krndsource *const
 	rs->getarg = arg;
 }
 
+static inline void
+rndsource_setenable(struct krndsource *const rs, void *const cb)
+{
+	rs->enable = cb;
+}
+
 typedef struct {
         uint32_t        cursor;         /* current add point in the pool */
         uint32_t        rotate;         /* how many bits to rotate by */

Reply via email to