From: "George Spelvin" <linux@horizon.com>
To: andi@firstfloor.org, tytso@mit.edu
Cc: ahferroin7@gmail.com, jepler@unpythonic.net,
linux-kernel@vger.kernel.org, linux@horizon.com,
linux@rasmusvillemoes.dk
Subject: [RFC PATCH 1/4] random: Reduce stack usage in _xfer_secondary_pool
Date: 16 Oct 2015 01:29:11 -0400 [thread overview]
Message-ID: <20151016052911.12487.qmail@ns.horizon.com> (raw)
In-Reply-To: <20151016052802.12363.qmail@ns.horizon.com>
Rather than asking extract_entropy to fill a large buffer, transfer
bytes in EXTRACT_SIZE chunks using multiple calls to extract_buf.
(Which is what extract_entropy does internally.)
Signed-off-by: George Spelvin <linux@horizon.com>
---
drivers/char/random.c | 48 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/drivers/char/random.c b/drivers/char/random.c
index d0da5d85..c8ad49ba 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -964,8 +964,9 @@ EXPORT_SYMBOL_GPL(add_disk_randomness);
*
*********************************************************************/
-static ssize_t extract_entropy(struct entropy_store *r, void *buf,
- size_t nbytes, int min, int rsvd);
+static size_t account(struct entropy_store *r, size_t nbytes, int min,
+ int reserved);
+static void extract_buf(struct entropy_store *r, __u8 out[EXTRACT_SIZE]);
/*
* This utility inline function is responsible for transferring entropy
@@ -994,23 +995,46 @@ static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
static void _xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
{
- __u32 tmp[OUTPUT_POOL_WORDS];
-
- /* For /dev/random's pool, always leave two wakeups' worth */
- int rsvd_bytes = r->limit ? 0 : random_read_wakeup_bits / 4;
+ u8 tmp[EXTRACT_SIZE];
int bytes = nbytes;
/* pull at least as much as a wakeup */
bytes = max_t(int, bytes, random_read_wakeup_bits / 8);
/* but never more than the buffer size */
- bytes = min_t(int, bytes, sizeof(tmp));
+ bytes = min_t(int, bytes, OUTPUT_POOL_WORDS*sizeof(u32));
+ /*
+ * FIXME: Move this to after account(), so it shows the true amount
+ * transferred?
+ */
trace_xfer_secondary_pool(r->name, bytes * 8, nbytes * 8,
ENTROPY_BITS(r), ENTROPY_BITS(r->pull));
- bytes = extract_entropy(r->pull, tmp, bytes,
- random_read_wakeup_bits / 8, rsvd_bytes);
- mix_pool_bytes(r, tmp, bytes);
- credit_entropy_bits(r, bytes*8);
+
+ /*
+ * This is the only place we call account() with non-zero
+ * "min" and "reserved" values. The minimum is used to
+ * enforce catastrophic reseeding: if we can't get at least
+ * random_read_wakeup_bits of entropy, don't bother reseeding
+ * at all, but wait until a useful amount is available.
+ *
+ * The "reserved" is used to prevent reads from /dev/urandom
+ * from emptying the unput pool; leave two wakeups' worth
+ * for /dev/random.
+ */
+ bytes = account(r->pull, bytes, random_read_wakeup_bits / 8,
+ r->limit ? 0 : random_read_wakeup_bits / 4);
+
+ /* Now to the actual transfer, in EXTRACT_SIZE units */
+ while (bytes) {
+ int i = min_t(int, bytes, EXTRACT_SIZE);
+
+ extract_buf(r->pull, tmp);
+ mix_pool_bytes(r, tmp, i);
+ credit_entropy_bits(r, i*8);
+ bytes -= i;
+ }
+
+ memzero_explicit(tmp, sizeof(tmp));
}
/*
@@ -1087,7 +1111,7 @@ retry:
*
* Note: we assume that .poolwords is a multiple of 16 words.
*/
-static void extract_buf(struct entropy_store *r, __u8 *out)
+static void extract_buf(struct entropy_store *r, __u8 out[EXTRACT_SIZE])
{
int i;
union {
--
2.6.1
next prev parent reply other threads:[~2015-10-16 5:29 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-10-10 18:45 Updated scalable urandom patchkit George Spelvin
2015-10-11 2:31 ` Theodore Ts'o
2015-10-11 2:53 ` Theodore Ts'o
2015-10-11 4:35 ` George Spelvin
2015-10-11 22:25 ` Theodore Ts'o
2015-10-12 0:16 ` George Spelvin
2015-10-12 4:05 ` Theodore Ts'o
2015-10-12 7:49 ` George Spelvin
2015-10-12 13:54 ` Theodore Ts'o
2015-10-12 20:30 ` George Spelvin
2015-10-12 20:34 ` George Spelvin
2015-10-13 2:46 ` Theodore Ts'o
2015-10-13 3:50 ` Raymond Jennings
2015-10-13 7:50 ` George Spelvin
2015-10-13 6:24 ` George Spelvin
2015-10-13 16:20 ` Andi Kleen
2015-10-13 21:10 ` George Spelvin
2015-10-14 2:15 ` Andi Kleen
2015-10-16 5:28 ` [RFC PATCH 0/4] Alternate sclable urandom patchset George Spelvin
2015-10-16 5:29 ` George Spelvin [this message]
2015-10-16 5:30 ` [RFC PATCH 2/4] random: Remove two unused arguments from extract_entropy() George Spelvin
2015-10-16 5:33 ` [RFC PATCH 3/4] random: Only do mixback once per read George Spelvin
2015-10-16 6:12 ` kbuild test robot
2015-10-16 8:11 ` George Spelvin
2015-10-16 6:23 ` kbuild test robot
2015-10-16 5:34 ` [RFC PATCH 4/4] random: Make non-blocking mixback non-blocking George Spelvin
2015-10-21 8:27 ` Updated scalable urandom patchkit George Spelvin
2015-10-21 11:47 ` Andi Kleen
2015-10-21 18:10 ` George Spelvin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20151016052911.12487.qmail@ns.horizon.com \
--to=linux@horizon.com \
--cc=ahferroin7@gmail.com \
--cc=andi@firstfloor.org \
--cc=jepler@unpythonic.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux@rasmusvillemoes.dk \
--cc=tytso@mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®