Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src Fixes and enhancements for polled entropy sources:
details: https://anonhg.NetBSD.org/src/rev/b33d6870622f
branches: trunk
changeset: 333273:b33d6870622f
user: tls <tls%NetBSD.org@localhost>
date: Sun Oct 26 18:22:32 2014 +0000
description:
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.
diffstat:
doc/CHANGES | 8 +++-
sys/dev/rndpseudo.c | 31 +++++++++-----
sys/kern/kern_rndq.c | 101 +++++++++++++++++++++++++++++++++++------------
sys/kern/kern_rndsink.c | 14 +++--
sys/sys/rnd.h | 10 ++++-
5 files changed, 119 insertions(+), 45 deletions(-)
diffs (truncated from 361 to 300 lines):
diff -r ac4c427cf84c -r b33d6870622f doc/CHANGES
--- a/doc/CHANGES Sun Oct 26 17:39:16 2014 +0000
+++ b/doc/CHANGES Sun Oct 26 18:22:32 2014 +0000
@@ -1,4 +1,4 @@
-# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.2003 $>
+# LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.2004 $>
#
#
# [Note: This file does not mention every change made to the NetBSD source tree.
@@ -83,3 +83,9 @@
openpam(3): update to 20140912 (ourouparia) [christos 20141024]
pppd(8): updated to version 2.4.7. [christos 20141025]
acpi(4): Updated ACPICA to 20140926. [christos 20141025]
+ 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]
diff -r ac4c427cf84c -r b33d6870622f sys/dev/rndpseudo.c
--- a/sys/dev/rndpseudo.c Sun Oct 26 17:39:16 2014 +0000
+++ b/sys/dev/rndpseudo.c Sun Oct 26 18:22:32 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: rndpseudo.c,v 1.22 2014/09/05 09:23:14 matt Exp $ */
+/* $NetBSD: rndpseudo.c,v 1.23 2014/10/26 18:22:32 tls 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.22 2014/09/05 09:23:14 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rndpseudo.c,v 1.23 2014/10/26 18:22:32 tls Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -526,6 +526,20 @@
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 @@
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 @@
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 @@
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);
}
diff -r ac4c427cf84c -r b33d6870622f sys/kern/kern_rndq.c
--- a/sys/kern/kern_rndq.c Sun Oct 26 17:39:16 2014 +0000
+++ b/sys/kern/kern_rndq.c Sun Oct 26 18:22:32 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_rndq.c,v 1.27 2014/08/11 14:07:55 riastradh Exp $ */
+/* $NetBSD: kern_rndq.c,v 1.28 2014/10/26 18:22:32 tls 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.27 2014/08/11 14:07:55 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndq.c,v 1.28 2014/10/26 18:22:32 tls Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -160,7 +160,7 @@
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 @@
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 @@
}
#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 @@
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 @@
*/
#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 @@
* 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 @@
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 @@
#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);
diff -r ac4c427cf84c -r b33d6870622f sys/kern/kern_rndsink.c
--- a/sys/kern/kern_rndsink.c Sun Oct 26 17:39:16 2014 +0000
+++ b/sys/kern/kern_rndsink.c Sun Oct 26 18:22:32 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_rndsink.c,v 1.9 2014/09/05 05:57:21 matt Exp $ */
+/* $NetBSD: kern_rndsink.c,v 1.10 2014/10/26 18:22:32 tls 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.9 2014/09/05 05:57:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_rndsink.c,v 1.10 2014/10/26 18:22:32 tls Exp $");
#include <sys/param.h>
Home |
Main Index |
Thread Index |
Old Index