Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/kern entropy: Record number of time and data samples for...
details: https://anonhg.NetBSD.org/src/rev/6ff549b20c2b
branches: trunk
changeset: 949756:6ff549b20c2b
user: riastradh <riastradh%NetBSD.org@localhost>
date: Sat Jan 16 02:21:26 2021 +0000
description:
entropy: Record number of time and data samples for userland.
This more or less follows the semantics of the RNDGETESTNUM and
RNDGETESTNAME ioctls to restore useful `rndctl -lv' output.
Specifically: We count the number of time or data samples entered
with rnd_add_*. Previously it would count the total number of 32-bit
words in the data, rather than the number of rnd_add_* calls that
enter data, but I think the number of calls makes more sense here.
diffstat:
sys/kern/kern_entropy.c | 81 ++++++++++++++++++++++++++++++++++++++----------
1 files changed, 64 insertions(+), 17 deletions(-)
diffs (169 lines):
diff -r 35658e9e5c4b -r 6ff549b20c2b sys/kern/kern_entropy.c
--- a/sys/kern/kern_entropy.c Sat Jan 16 02:20:00 2021 +0000
+++ b/sys/kern/kern_entropy.c Sat Jan 16 02:21:26 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_entropy.c,v 1.27 2021/01/13 23:53:23 riastradh Exp $ */
+/* $NetBSD: kern_entropy.c,v 1.28 2021/01/16 02:21:26 riastradh Exp $ */
/*-
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -75,7 +75,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.27 2021/01/13 23:53:23 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_entropy.c,v 1.28 2021/01/16 02:21:26 riastradh Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -141,7 +141,9 @@
* Per-CPU rndsource state.
*/
struct rndsource_cpu {
- unsigned rc_nbits; /* bits of entropy added */
+ unsigned rc_entropybits;
+ unsigned rc_timesamples;
+ unsigned rc_datasamples;
};
/*
@@ -250,11 +252,12 @@
static int filt_entropy_read_event(struct knote *, long);
static void entropy_request(size_t);
static void rnd_add_data_1(struct krndsource *, const void *, uint32_t,
- uint32_t);
+ uint32_t, uint32_t);
static unsigned rndsource_entropybits(struct krndsource *);
static void rndsource_entropybits_cpu(void *, void *, struct cpu_info *);
static void rndsource_to_user(struct krndsource *, rndsource_t *);
static void rndsource_to_user_est(struct krndsource *, rndsource_est_t *);
+static void rndsource_to_user_est_cpu(void *, void *, struct cpu_info *);
/*
* entropy_timer()
@@ -1545,6 +1548,8 @@
/* Initialize the random source. */
memset(rs->name, 0, sizeof(rs->name)); /* paranoia */
strlcpy(rs->name, name, sizeof(rs->name));
+ memset(&rs->time_delta, 0, sizeof(rs->time_delta));
+ memset(&rs->value_delta, 0, sizeof(rs->value_delta));
rs->total = 0;
rs->type = type;
rs->flags = flags;
@@ -1817,17 +1822,27 @@
/* If we are collecting data, enter them. */
if (ISSET(flags, RND_FLAG_COLLECT_VALUE))
- rnd_add_data_1(rs, buf, len, entropybits);
+ rnd_add_data_1(rs, buf, len, entropybits,
+ RND_FLAG_COLLECT_VALUE);
/* If we are collecting timings, enter one. */
if (ISSET(flags, RND_FLAG_COLLECT_TIME)) {
extra = entropy_timer();
- rnd_add_data_1(rs, &extra, sizeof extra, 0);
+ rnd_add_data_1(rs, &extra, sizeof extra, 0,
+ RND_FLAG_COLLECT_TIME);
}
}
+static unsigned
+add_sat(unsigned a, unsigned b)
+{
+ unsigned c = a + b;
+
+ return (c < a ? UINT_MAX : c);
+}
+
/*
- * rnd_add_data_1(rs, buf, len, entropybits)
+ * rnd_add_data_1(rs, buf, len, entropybits, flag)
*
* Internal subroutine to call either entropy_enter_intr, if we're
* in interrupt context, or entropy_enter if not, and to count the
@@ -1835,7 +1850,7 @@
*/
static void
rnd_add_data_1(struct krndsource *rs, const void *buf, uint32_t len,
- uint32_t entropybits)
+ uint32_t entropybits, uint32_t flag)
{
bool fullyused;
@@ -1859,15 +1874,34 @@
if (E->stage < ENTROPY_HOT) {
if (E->stage >= ENTROPY_WARM)
mutex_enter(&E->lock);
- rs->total += MIN(UINT_MAX - rs->total, entropybits);
+ rs->total = add_sat(rs->total, entropybits);
+ switch (flag) {
+ case RND_FLAG_COLLECT_TIME:
+ rs->time_delta.insamples =
+ add_sat(rs->time_delta.insamples, 1);
+ break;
+ case RND_FLAG_COLLECT_VALUE:
+ rs->value_delta.insamples =
+ add_sat(rs->value_delta.insamples, 1);
+ break;
+ }
if (E->stage >= ENTROPY_WARM)
mutex_exit(&E->lock);
} else {
struct rndsource_cpu *rc = percpu_getref(rs->state);
- unsigned nbits = rc->rc_nbits;
- nbits += MIN(UINT_MAX - nbits, entropybits);
- atomic_store_relaxed(&rc->rc_nbits, nbits);
+ atomic_store_relaxed(&rc->rc_entropybits,
+ add_sat(rc->rc_entropybits, entropybits));
+ switch (flag) {
+ case RND_FLAG_COLLECT_TIME:
+ atomic_store_relaxed(&rc->rc_timesamples,
+ add_sat(rc->rc_timesamples, 1));
+ break;
+ case RND_FLAG_COLLECT_VALUE:
+ atomic_store_relaxed(&rc->rc_datasamples,
+ add_sat(rc->rc_datasamples, 1));
+ break;
+ }
percpu_putref(rs->state);
}
}
@@ -1912,7 +1946,7 @@
unsigned *nbitsp = cookie;
unsigned cpu_nbits;
- cpu_nbits = atomic_load_relaxed(&rc->rc_nbits);
+ cpu_nbits = atomic_load_relaxed(&rc->rc_entropybits);
*nbitsp += MIN(UINT_MAX - *nbitsp, cpu_nbits);
}
@@ -1957,11 +1991,24 @@
/* Copy out the rndsource description. */
rndsource_to_user(rs, &urse->rt);
- /* Zero out the statistics because we don't do estimation. */
- urse->dt_samples = 0;
+ /* Gather the statistics. */
+ urse->dt_samples = rs->time_delta.insamples;
urse->dt_total = 0;
- urse->dv_samples = 0;
- urse->dv_total = 0;
+ urse->dv_samples = rs->value_delta.insamples;
+ urse->dv_total = urse->rt.total;
+ percpu_foreach(rs->state, rndsource_to_user_est_cpu, urse);
+}
+
+static void
+rndsource_to_user_est_cpu(void *ptr, void *cookie, struct cpu_info *ci)
+{
+ struct rndsource_cpu *rc = ptr;
+ rndsource_est_t *urse = cookie;
+
+ urse->dt_samples = add_sat(urse->dt_samples,
+ atomic_load_relaxed(&rc->rc_timesamples));
+ urse->dv_samples = add_sat(urse->dv_samples,
+ atomic_load_relaxed(&rc->rc_datasamples));
}
/*
Home |
Main Index |
Thread Index |
Old Index