linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: "George Spelvin" <linux@horizon.com>
To: penberg@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux@horizon.com
Subject: Re: [PATCH] Make /proc/slabinfo 0400
Date: 7 Mar 2011 12:49:34 -0500	[thread overview]
Message-ID: <20110307174934.15811.qmail@science.horizon.com> (raw)
In-Reply-To: <20110307141948.11415.qmail@science.horizon.com>

To go with my earlier code, here's a (proof of concept) more efficient
random number generator for a series of small values.  A bit more code,
but a lot less calls to half_md4_transform.

diff --git a/drivers/char/random.c b/drivers/char/random.c
index 773007d..6b3fd4e 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1658,6 +1658,84 @@ unsigned int get_random_int(void)
 	return ret;
 }
 
+struct random_mod_state {
+	unsigned int x, lim;	/* Invariant: 0 <= x < lim, and random */
+	__u8 const *seed;
+	unsigned len;
+};
+
+void
+get_random_mod_start(struct random_mod_state *s)
+{
+	s->x = 0;
+	s->lim = 0;
+	s->len = 0;
+
+	preempt_disable();	/* For access to percpu variables */
+}
+
+/*
+ * Return a random 0 <= x < m.  This is exacctly uniformly distributed,
+ * which "random() % m" is not, and it is economical with seed entropy.
+ * For example, this can shuffle 27 elements (27! > 2^93) with only
+ * one call to half_md4_transform.
+ *
+ * This is limited to 24-bit moduli m; larger values risk overflow.
+ */
+unsigned
+get_random_mod(struct random_mod_state *s, unsigned m)
+{
+        unsigned x = s->x, lim = x->lim;
+
+        for (;;) {
+		unsigned k;
+
+		/* Ensure lim >= m */
+		while (lim < m) {
+			/* Invoke underlying random bit source */
+			if (!s->len--) {
+				__u32 *h = __get_cpu_var(get_random_int_hash);
+				struct keydata const *keyptr = get_keyptr();
+				cycles_t c = get_cycles();
+
+				/* Throw in some extra seed material */
+				h[0] += (__u32)c;
+				h[1] += (__u32)(c>>16>>16); /* 32-bit safe */
+				h[2] += current->pid + jiffies;
+
+				half_md4_transform(h, keyptr->secret);
+
+				/* And use last 12 bytes as random numbers */
+				s->seed = (__u8 *)(h + 1);
+				s->len = 11;	/* Pre-decremented */
+			}
+			/* Add one byte to state */
+			x = x<<8 | *s->seed++;
+			lim <<= 8;
+		}
+		/*
+		 * Core loop.  We occasionally have to discard and regenerate
+		 * to ensure uniformity.
+		 */
+		k = lim % m;
+		if (x >= k) {
+			x -= k;		lim -= k;
+			/* Final result: Return x % m, keep x / m */
+			s->x = x/m;	s->lim = lim/m;
+			return x % m;
+		}
+		/* Non-uniform: keep fractional part and try again */
+		lim = k;
+	}
+}
+
+void
+get_random_mod_stop(struct random_mod_state *s)
+{
+	(void)s;
+	preempt_enable();	/* Drop lock on s->seed */
+}
+
 /*
  * randomize_range() returns a start address such that
  *

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org.  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>

  reply	other threads:[~2011-03-07 17:49 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-07 14:19 [PATCH] Make /proc/slabinfo 040 George Spelvin
2011-03-07 17:49 ` George Spelvin [this message]
  -- strict thread matches above, loose matches on Subject: below --
2011-03-03 17:50 [PATCH] Make /proc/slabinfo 0400 Dan Rosenberg
2011-03-03 18:17 ` Dave Hansen
2011-03-03 18:29   ` Dan Rosenberg
2011-03-03 20:58 ` Matt Mackall
2011-03-03 21:16   ` Dan Rosenberg
2011-03-03 21:44     ` Matt Mackall
2011-03-03 22:30       ` Dan Rosenberg
2011-03-03 23:08         ` Matt Mackall
2011-03-04  0:32           ` Dave Hansen
2011-03-04  0:50         ` Theodore Tso
2011-03-04  6:52           ` Pekka Enberg
2011-03-04 17:36             ` Dave Hansen
2011-03-04 17:48               ` Linus Torvalds
2011-03-04 18:14                 ` Matt Mackall
2011-03-04 20:02                   ` Pekka Enberg
2011-03-04 20:31                     ` Matt Mackall
2011-03-04 20:42                       ` Dan Rosenberg
2011-03-04 20:56                         ` Pekka Enberg
2011-03-04 21:08                           ` Dan Rosenberg
2011-03-04 21:30                             ` Pekka Enberg
2011-03-04 21:44                               ` Dan Rosenberg
2011-03-04 22:10                                 ` Pekka Enberg
2011-03-04 22:14                                   ` Pekka Enberg
2011-03-04 23:02                                     ` Matt Mackall
2011-03-05 16:25                                       ` Ted Ts'o
2011-03-06 13:19                                         ` Alan Cox
2011-03-07 14:56                                           ` Dan Rosenberg
2011-03-07 16:02                                             ` Matt Mackall
2011-03-04 20:37                     ` Dan Rosenberg
2011-03-04 20:58                       ` Pekka Enberg
2011-03-04 21:10                         ` Dan Rosenberg
2011-03-06  0:42                           ` Jesper Juhl
2011-03-06  0:57                             ` Dan Rosenberg
2011-03-06  1:09                             ` Matt Mackall
2011-03-06  1:15                               ` Jesper Juhl
2011-03-07 16:40                                 ` Christoph Lameter
2011-03-04 21:12                         ` Matt Mackall
2011-03-04 11:58           ` Alan Cox

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=20110307174934.15811.qmail@science.horizon.com \
    --to=linux@horizon.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=penberg@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).