Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src-draft/trunk]: src/sys/arch/mips/cavium/dev Be a little more judicious wi...



details:   https://anonhg.NetBSD.org/src-all/rev/7a0beefe72d1
branches:  trunk
changeset: 932645:7a0beefe72d1
user:      Taylor R Campbell <riastradh%NetBSD.org@localhost>
date:      Wed May 13 16:07:07 2020 +0000

description:
Be a little more judicious with delays in octeon_rnm.

- Use cycle count busy loops, not microsecond delays.
- Yield if requested in the loop.

diffstat:

 sys/arch/mips/cavium/dev/octeon_rnm.c |  54 +++++++++++++++++++++++++---------
 1 files changed, 39 insertions(+), 15 deletions(-)

diffs (116 lines):

diff -r 1b32749f3ec0 -r 7a0beefe72d1 sys/arch/mips/cavium/dev/octeon_rnm.c
--- a/sys/arch/mips/cavium/dev/octeon_rnm.c     Wed May 13 07:38:50 2020 +0000
+++ b/sys/arch/mips/cavium/dev/octeon_rnm.c     Wed May 13 16:07:07 2020 +0000
@@ -105,9 +105,10 @@
 
 //#define      OCTEON_RNM_DEBUG
 
-#define        ENT_DELAY_CLOCK 8       /* cycles for each RO sample */
+#define        ENT_DELAY_CLOCK 8       /* cycles for each 64-bit RO sample batch */
 #define        RNG_DELAY_CLOCK 81      /* cycles for each SHA-1 output */
 #define        NROGROUPS       16
+#define        RNG_FIFO_WORDS  (512/sizeof(uint64_t))
 
 struct octeon_rnm_softc {
        bus_space_tag_t         sc_bust;
@@ -126,6 +127,7 @@
 static void octeon_rnm_raw_entropy(struct octeon_rnm_softc *, unsigned);
 static uint64_t octeon_rnm_load(struct octeon_rnm_softc *);
 static void octeon_rnm_iobdma(struct octeon_rnm_softc *, uint64_t *, unsigned);
+static void octeon_rnm_delay(uint32_t);
 
 CFATTACH_DECL_NEW(octeon_rnm, sizeof(struct octeon_rnm_softc),
     octeon_rnm_match, octeon_rnm_attach, NULL, NULL);
@@ -173,7 +175,7 @@
 
        /*
         * Reset the core, enable the RNG engine without entropy, wait
-        * 81 cycles for it to warm up (round up to 1us), and get a
+        * 81 cycles for it to produce a single sample, and draw the
         * deterministic sample to test.
         *
         * XXX Verify that the output matches the SHA-1 computation
@@ -181,7 +183,7 @@
         */
        octeon_rnm_reset(sc);
        octeon_rnm_conditioned_deterministic(sc);
-       delay(1);
+       octeon_rnm_delay(RNG_DELAY_CLOCK*1);
        sample = octeon_rnm_load(sc);
        if (sample != expected)
                aprint_error_dev(self, "self-test: read %016"PRIx64","
@@ -196,6 +198,7 @@
        octeon_rnm_reset(sc);
        sc->sc_rogroup = 0;
        octeon_rnm_raw_entropy(sc, sc->sc_rogroup);
+       octeon_rnm_delay(ENT_DELAY_CLOCK*RNG_FIFO_WORDS);
 
        /* Attach the rndsource.  */
        rndsource_setcb(&sc->sc_rndsrc, octeon_rnm_rng, sc);
@@ -212,22 +215,18 @@
        struct octeon_rnm_softc *sc = vsc;
        size_t needed = NBBY*nbytes;
 
-       /*
-        * Sample all of the ring oscillators at least once, while
-        * preventing concurrent access to the FIFO out of paranoia.
-        */
+       /* Sample the ring oscillators round-robin.  */
        mutex_enter(&sc->sc_lock);
        for (; needed; needed -= MIN(needed, NBBY*sizeof(sample)/BPB)) {
                /*
-                * Make sure the FIFO is full.  We need 8 cycles for
-                * every 64 bits = 8 bytes, and the FIFO has 512 bytes,
-                * for a total of 512 cycles; round that up to 2us,
-                * under the assumption that the CPU runs at no less
-                * than 256 MHz.
+                * Switch to the next RO group once we drain the FIFO.
+                * By the time rnd_add_data is done, we will have
+                * processed all 512 bytes of the FIFO.  We assume it
+                * takes at least one cycle per byte (realistically,
+                * more like ~80cpb to draw from the FIFO and then
+                * process it with rnd_add_data), so there is no need
+                * for any other delays.
                 */
-               delay(2);
-
-               /* Switch to the next RO group once we drain the FIFO.  */
                sc->sc_rogroup++;
                sc->sc_rogroup %= NROGROUPS;
                octeon_rnm_raw_entropy(sc, sc->sc_rogroup);
@@ -249,6 +248,14 @@
 #endif
                rnd_add_data(&sc->sc_rndsrc, sample, sizeof sample,
                    NBBY*sizeof(sample)/BPB);
+
+               /* Yield if requested.  */
+               if (__predict_false(curcpu()->ci_schedstate.spc_flags &
+                       SPCF_SHOULDYIELD)) {
+                       mutex_exit(&sc->sc_lock);
+                       preempt();
+                       mutex_enter(&sc->sc_lock);
+               }
        }
        mutex_exit(&sc->sc_lock);
 
@@ -357,3 +364,20 @@
        for (; nwords --> 0; scraddr += 8)
                *buf++ = octeon_cvmseg_read_8(scraddr);
 }
+
+/*
+ * octeon_rnm_delay(ncycles)
+ *
+ *     Wait ncycles, at most UINT32_MAX/2 so we behave reasonably even
+ *     if the cycle counter rolls over.
+ */
+static void
+octeon_rnm_delay(uint32_t ncycles)
+{
+       uint32_t deadline = mips3_cp0_count_read() + ncycles;
+
+       KASSERT(ncycles <= UINT32_MAX/2);
+
+       while ((deadline - mips3_cp0_count_read()) < ncycles)
+               continue;
+}



Home | Main Index | Thread Index | Old Index