
From: Matt Mackall <mpm@selenic.com>

Basically, when the primary pool is 7/8th full, we shut off the firehose
and go into a trickle mode to keep the pool fresh.  Saves CPU for everyone
and should make the contention drop off the charts too (though the trickle
factor might need adjusting again for Origin-class machines).



 drivers/char/random.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+)

diff -puN drivers/char/random.c~random-lock-contention drivers/char/random.c
--- 25/drivers/char/random.c~random-lock-contention	2003-09-07 18:24:30.000000000 -0700
+++ 25-akpm/drivers/char/random.c	2003-09-07 18:24:30.000000000 -0700
@@ -253,6 +253,7 @@
 #include <linux/genhd.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/percpu.h>
 
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -281,6 +282,15 @@ static int random_read_wakeup_thresh = 6
 static int random_write_wakeup_thresh = 128;
 
 /*
+ * When the input pool goes over trickle_thresh, start dropping most
+ * samples to avoid wasting CPU time and reduce lock contention.
+ */
+
+static int trickle_thresh = DEFAULT_POOL_SIZE * 7;
+
+static DEFINE_PER_CPU(int, trickle_count) = 0;
+
+/*
  * A pool of size .poolwords is stirred with a primitive polynomial
  * of degree .poolwords over GF(2).  The taps for various sizes are
  * defined below.  They are chosen to be evenly spaced (minimum RMS
@@ -778,6 +788,11 @@ static void add_timer_randomness(struct 
 	__s32		delta, delta2, delta3;
 	int		entropy = 0;
 
+	/* if over the trickle threshold, use only 1 in 4096 samples */
+	if ( random_state->entropy_count > trickle_thresh &&
+	     (__get_cpu_var(trickle_count)++ & 0xfff))
+		return;
+
 #if defined (__i386__) || defined (__x86_64__)
 	if (cpu_has_tsc) {
 		__u32 high;

_
