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