
From: Matt Mackall <mpm@selenic.com>

As we no longer allow resizing of pools, it makes sense to allocate and
initialize them statically.  Remove create_entropy_store and simplify
rand_initialize.

Signed-off-by: Matt Mackall <mpm@selenic.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/char/random.c |  203 ++++++++++++++++--------------------------
 1 files changed, 79 insertions(+), 124 deletions(-)

diff -puN drivers/char/random.c~random-pt3-static-allocation-of-pools drivers/char/random.c
--- 25/drivers/char/random.c~random-pt3-static-allocation-of-pools	2005-03-07 20:41:48.000000000 -0800
+++ 25-akpm/drivers/char/random.c	2005-03-07 21:14:20.000000000 -0800
@@ -295,42 +295,37 @@ static struct poolinfo {
 	int poolwords;
 	int tap1, tap2, tap3, tap4, tap5;
 } poolinfo_table[] = {
+	/* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
+	{ 128,	103,	76,	51,	25,	1 },
+	/* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
+	{ 32,	26,	20,	14,	7,	1 },
+#if 0
 	/* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1  -- 115 */
 	{ 2048,	1638,	1231,	819,	411,	1 },
 
 	/* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
 	{ 1024,	817,	615,	412,	204,	1 },
-#if 0				/* Alternate polynomial */
+
 	/* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
 	{ 1024,	819,	616,	410,	207,	2 },
-#endif
 
 	/* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
 	{ 512,	411,	308,	208,	104,	1 },
-#if 0				/* Alternates */
+
 	/* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
 	{ 512,	409,	307,	206,	102,	2 },
 	/* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
 	{ 512,	409,	309,	205,	103,	2 },
-#endif
 
 	/* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
 	{ 256,	205,	155,	101,	52,	1 },
 
-	/* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
-	{ 128,	103,	76,	51,	25,	1 },
-#if 0	/* Alternate polynomial */
 	/* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
 	{ 128,	103,	78,	51,	27,	2 },
-#endif
 
 	/* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
 	{ 64,	52,	39,	26,	14,	1 },
-
-	/* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
-	{ 32,	26,	20,	14,	7,	1 },
-
-	{ 0,	0,	0,	0,	0,	0 },
+#endif
 };
 
 #define POOLBITS	poolwords*32
@@ -382,9 +377,6 @@ static struct poolinfo {
 /*
  * Static global variables
  */
-static struct entropy_store *input_pool; /* The default global store */
-static struct entropy_store *blocking_pool; /* secondary store */
-static struct entropy_store *nonblocking_pool; /* For urandom */
 static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
 static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
 
@@ -392,7 +384,8 @@ static DECLARE_WAIT_QUEUE_HEAD(random_wr
  * Forward procedure declarations
  */
 #ifdef CONFIG_SYSCTL
-static void sysctl_init_random(struct entropy_store *random_state);
+struct entropy_store;
+static void sysctl_init_random(struct entropy_store *pool);
 #endif
 
 static inline __u32 rol32(__u32 word, int shift)
@@ -406,9 +399,9 @@ module_param(debug, bool, 0644);
 #define DEBUG_ENT(fmt, arg...) do { if (debug) \
 	printk(KERN_DEBUG "random %04d %04d %04d: " \
 	fmt,\
-	input_pool->entropy_count,\
-	blocking_pool->entropy_count,\
-	nonblocking_pool->entropy_count,\
+	input_pool.entropy_count,\
+	blocking_pool.entropy_count,\
+	nonblocking_pool.entropy_count,\
 	## arg); } while (0)
 #else
 #define DEBUG_ENT(fmt, arg...) do {} while (0)
@@ -423,7 +416,7 @@ module_param(debug, bool, 0644);
 
 struct entropy_store {
 	/* mostly-read data: */
-	struct poolinfo poolinfo;
+	struct poolinfo *poolinfo;
 	__u32 *pool;
 	const char *name;
 
@@ -434,48 +427,30 @@ struct entropy_store {
 	int input_rotate;
 };
 
-/*
- * Initialize the entropy store.  The input argument is the size of
- * the random pool.
- *
- * Returns an negative error if there is a problem.
- */
-static int create_entropy_store(int size, const char *name,
-				struct entropy_store **ret_bucket)
-{
-	struct entropy_store *r;
-	struct poolinfo *p;
-	int poolwords;
-
-	poolwords = (size + 3) / 4; /* Convert bytes->words */
-	/* The pool size must be a multiple of 16 32-bit words */
-	poolwords = ((poolwords + 15) / 16) * 16;
+static __u32 input_pool_data[INPUT_POOL_WORDS];
+static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
+static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
+
+static struct entropy_store input_pool = {
+	.poolinfo = &poolinfo_table[0],
+	.name = "input",
+	.lock = SPIN_LOCK_UNLOCKED,
+	.pool = input_pool_data
+};
 
-	for (p = poolinfo_table; p->poolwords; p++) {
-		if (poolwords == p->poolwords)
-			break;
-	}
-	if (p->poolwords == 0)
-		return -EINVAL;
+static struct entropy_store blocking_pool = {
+	.poolinfo = &poolinfo_table[1],
+	.name = "blocking",
+	.lock = SPIN_LOCK_UNLOCKED,
+	.pool = blocking_pool_data
+};
 
-	r = kmalloc(sizeof(struct entropy_store), GFP_KERNEL);
-	if (!r)
-		return -ENOMEM;
-
-	memset (r, 0, sizeof(struct entropy_store));
-	r->poolinfo = *p;
-
-	r->pool = kmalloc(POOLBYTES, GFP_KERNEL);
-	if (!r->pool) {
-		kfree(r);
-		return -ENOMEM;
-	}
-	memset(r->pool, 0, POOLBYTES);
-	spin_lock_init(&r->lock);
-	r->name = name;
-	*ret_bucket = r;
-	return 0;
-}
+static struct entropy_store nonblocking_pool = {
+	.poolinfo = &poolinfo_table[1],
+	.name = "nonblocking",
+	.lock = SPIN_LOCK_UNLOCKED,
+	.pool = nonblocking_pool_data
+};
 
 /*
  * This function adds a byte into the entropy "pool".  It does not
@@ -495,16 +470,16 @@ static void __add_entropy_words(struct e
 		0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
 	unsigned long i, add_ptr, tap1, tap2, tap3, tap4, tap5;
 	int new_rotate, input_rotate;
-	int wordmask = r->poolinfo.poolwords - 1;
+	int wordmask = r->poolinfo->poolwords - 1;
 	__u32 w, next_w;
 	unsigned long flags;
 
 	/* Taps are constant, so we can load them without holding r->lock.  */
-	tap1 = r->poolinfo.tap1;
-	tap2 = r->poolinfo.tap2;
-	tap3 = r->poolinfo.tap3;
-	tap4 = r->poolinfo.tap4;
-	tap5 = r->poolinfo.tap5;
+	tap1 = r->poolinfo->tap1;
+	tap2 = r->poolinfo->tap2;
+	tap3 = r->poolinfo->tap3;
+	tap4 = r->poolinfo->tap4;
+	tap5 = r->poolinfo->tap5;
 	next_w = *in++;
 
 	spin_lock_irqsave(&r->lock, flags);
@@ -570,8 +545,8 @@ static void credit_entropy_store(struct 
 		DEBUG_ENT("negative entropy/overflow (%d+%d)\n",
 			  r->entropy_count, nbits);
 		r->entropy_count = 0;
-	} else if (r->entropy_count + nbits > r->poolinfo.POOLBITS) {
-		r->entropy_count = r->poolinfo.POOLBITS;
+	} else if (r->entropy_count + nbits > r->poolinfo->POOLBITS) {
+		r->entropy_count = r->poolinfo->POOLBITS;
 	} else {
 		r->entropy_count += nbits;
 		if (nbits)
@@ -660,7 +635,7 @@ static void batch_entropy_store(u32 a, u
 static void batch_entropy_process(void *private_)
 {
 	struct entropy_store *r	= (struct entropy_store *) private_, *p;
-	int max_entropy = r->poolinfo.POOLBITS;
+	int max_entropy = r->poolinfo->POOLBITS;
 	unsigned head, tail;
 
 	/* Mixing into the pool is expensive, so copy over the batch
@@ -682,8 +657,9 @@ static void batch_entropy_process(void *
 	p = r;
 	while (head != tail) {
 		if (r->entropy_count >= max_entropy) {
-			r = (r == blocking_pool) ? input_pool : blocking_pool;
-			max_entropy = r->poolinfo.POOLBITS;
+			r = (r == &blocking_pool) ? &input_pool :
+				&blocking_pool;
+			max_entropy = r->poolinfo->POOLBITS;
 		}
 		add_entropy_words(r, batch_entropy_copy[tail].data, 2);
 		credit_entropy_store(r, batch_entropy_copy[tail].credit);
@@ -727,7 +703,7 @@ static void add_timer_randomness(struct 
 
 	preempt_disable();
 	/* if over the trickle threshold, use only 1 in 4096 samples */
-	if (input_pool->entropy_count > trickle_thresh &&
+	if (input_pool.entropy_count > trickle_thresh &&
 	    (__get_cpu_var(trickle_count)++ & 0xfff))
 		goto out;
 
@@ -1226,7 +1202,7 @@ static inline void xfer_secondary_pool(s
 				       size_t nbytes, __u32 *tmp)
 {
 	if (r->entropy_count < nbytes * 8 &&
-	    r->entropy_count < r->poolinfo.POOLBITS) {
+	    r->entropy_count < r->poolinfo->POOLBITS) {
 		int bytes = max_t(int, random_read_wakeup_thresh / 8,
 				min_t(int, nbytes, TMP_BUF_SIZE));
 
@@ -1234,7 +1210,7 @@ static inline void xfer_secondary_pool(s
 			  "(%d of %d requested)\n",
 			  r->name, bytes * 8, nbytes * 8, r->entropy_count);
 
-		bytes=extract_entropy(input_pool, tmp, bytes,
+		bytes=extract_entropy(&input_pool, tmp, bytes,
 				      EXTRACT_ENTROPY_LIMIT);
 		add_entropy_words(r, tmp, (bytes + 3) / 4);
 		credit_entropy_store(r, bytes*8);
@@ -1263,8 +1239,8 @@ static ssize_t extract_entropy(struct en
 	unsigned long cpuflags;
 
 	/* Redundant, but just in case... */
-	if (r->entropy_count > r->poolinfo.POOLBITS)
-		r->entropy_count = r->poolinfo.POOLBITS;
+	if (r->entropy_count > r->poolinfo->POOLBITS)
+		r->entropy_count = r->poolinfo->POOLBITS;
 
 	if (flags & EXTRACT_ENTROPY_SECONDARY)
 		xfer_secondary_pool(r, nbytes, tmp);
@@ -1323,7 +1299,7 @@ static ssize_t extract_entropy(struct en
 		 * attempts to find previous ouputs), unless the hash
 		 * function can be inverted.
 		 */
-		for (i = 0, x = 0; i < r->poolinfo.poolwords; i += 16, x+=2) {
+		for (i = 0, x = 0; i < r->poolinfo->poolwords; i += 16, x+=2) {
 			HASH_TRANSFORM(tmp, r->pool+i);
 			add_entropy_words(r, &tmp[x%HASH_BUFFER_SIZE], 1);
 		}
@@ -1377,21 +1353,8 @@ static ssize_t extract_entropy(struct en
  */
 void get_random_bytes(void *buf, int nbytes)
 {
-	struct entropy_store *r = nonblocking_pool;
-	int flags = EXTRACT_ENTROPY_SECONDARY;
-
-	if (!r)
-		r = blocking_pool;
-	if (!r) {
-		r = input_pool;
-		flags = 0;
-	}
-	if (!r) {
-		printk(KERN_NOTICE "get_random_bytes called before "
-				   "random driver initialization\n");
-		return;
-	}
-	extract_entropy(r, (char *) buf, nbytes, flags);
+	extract_entropy(&nonblocking_pool, (char *) buf, nbytes,
+			EXTRACT_ENTROPY_SECONDARY);
 }
 
 EXPORT_SYMBOL(get_random_bytes);
@@ -1422,21 +1385,13 @@ static void init_std_data(struct entropy
 
 static int __init rand_initialize(void)
 {
-	if (create_entropy_store(INPUT_POOL_WORDS, "input", &input_pool))
-		goto err;
-	if (batch_entropy_init(BATCH_ENTROPY_SIZE, input_pool))
-		goto err;
-	if (create_entropy_store(OUTPUT_POOL_WORDS, "blocking",
-				 &blocking_pool))
-		goto err;
-	if (create_entropy_store(OUTPUT_POOL_WORDS, "nonblocking",
-				 &nonblocking_pool))
+	if (batch_entropy_init(BATCH_ENTROPY_SIZE, &input_pool))
 		goto err;
-	init_std_data(input_pool);
-	init_std_data(blocking_pool);
-	init_std_data(nonblocking_pool);
+	init_std_data(&input_pool);
+	init_std_data(&blocking_pool);
+	init_std_data(&nonblocking_pool);
 #ifdef CONFIG_SYSCTL
-	sysctl_init_random(input_pool);
+	sysctl_init_random(&input_pool);
 #endif
 	return 0;
 err:
@@ -1492,7 +1447,7 @@ random_read(struct file * file, char __u
 
 		DEBUG_ENT("reading %d bits\n", n*8);
 
-		n = extract_entropy(blocking_pool, buf, n,
+		n = extract_entropy(&blocking_pool, buf, n,
 				    EXTRACT_ENTROPY_USER |
 				    EXTRACT_ENTROPY_LIMIT |
 				    EXTRACT_ENTROPY_SECONDARY);
@@ -1509,7 +1464,7 @@ random_read(struct file * file, char __u
 			DEBUG_ENT("sleeping?\n");
 
 			wait_event_interruptible(random_read_wait,
-				input_pool->entropy_count >=
+				input_pool.entropy_count >=
 						 random_read_wakeup_thresh);
 
 			DEBUG_ENT("awake\n");
@@ -1549,12 +1504,12 @@ urandom_read(struct file * file, char __
 	int flags = EXTRACT_ENTROPY_USER;
 	unsigned long cpuflags;
 
-	spin_lock_irqsave(&input_pool->lock, cpuflags);
-	if (input_pool->entropy_count > input_pool->poolinfo.POOLBITS)
+	spin_lock_irqsave(&input_pool.lock, cpuflags);
+	if (input_pool.entropy_count > input_pool.poolinfo->POOLBITS)
 		flags |= EXTRACT_ENTROPY_SECONDARY;
-	spin_unlock_irqrestore(&input_pool->lock, cpuflags);
+	spin_unlock_irqrestore(&input_pool.lock, cpuflags);
 
-	return extract_entropy(nonblocking_pool, buf, nbytes, flags);
+	return extract_entropy(&nonblocking_pool, buf, nbytes, flags);
 }
 
 static unsigned int
@@ -1565,9 +1520,9 @@ random_poll(struct file *file, poll_tabl
 	poll_wait(file, &random_read_wait, wait);
 	poll_wait(file, &random_write_wait, wait);
 	mask = 0;
-	if (input_pool->entropy_count >= random_read_wakeup_thresh)
+	if (input_pool.entropy_count >= random_read_wakeup_thresh)
 		mask |= POLLIN | POLLRDNORM;
-	if (input_pool->entropy_count < random_write_wakeup_thresh)
+	if (input_pool.entropy_count < random_write_wakeup_thresh)
 		mask |= POLLOUT | POLLWRNORM;
 	return mask;
 }
@@ -1593,7 +1548,7 @@ random_write(struct file * file, const c
 		c -= bytes;
 		p += bytes;
 
-		add_entropy_words(input_pool, buf, (bytes + 3) / 4);
+		add_entropy_words(&input_pool, buf, (bytes + 3) / 4);
 	}
 	if (p == buffer) {
 		return (ssize_t)ret;
@@ -1615,7 +1570,7 @@ random_ioctl(struct inode * inode, struc
 
 	switch (cmd) {
 	case RNDGETENTCNT:
-		ent_count = input_pool->entropy_count;
+		ent_count = input_pool.entropy_count;
 		if (put_user(ent_count, p))
 			return -EFAULT;
 		return 0;
@@ -1624,12 +1579,12 @@ random_ioctl(struct inode * inode, struc
 			return -EPERM;
 		if (get_user(ent_count, p))
 			return -EFAULT;
-		credit_entropy_store(input_pool, ent_count);
+		credit_entropy_store(&input_pool, ent_count);
 		/*
 		 * Wake up waiting processes if we have enough
 		 * entropy.
 		 */
-		if (input_pool->entropy_count >= random_read_wakeup_thresh)
+		if (input_pool.entropy_count >= random_read_wakeup_thresh)
 			wake_up_interruptible(&random_read_wait);
 		return 0;
 	case RNDADDENTROPY:
@@ -1645,12 +1600,12 @@ random_ioctl(struct inode * inode, struc
 				      size, &file->f_pos);
 		if (retval < 0)
 			return retval;
-		credit_entropy_store(input_pool, ent_count);
+		credit_entropy_store(&input_pool, ent_count);
 		/*
 		 * Wake up waiting processes if we have enough
 		 * entropy.
 		 */
-		if (input_pool->entropy_count >= random_read_wakeup_thresh)
+		if (input_pool.entropy_count >= random_read_wakeup_thresh)
 			wake_up_interruptible(&random_read_wait);
 		return 0;
 	case RNDZAPENTCNT:
@@ -1658,9 +1613,9 @@ random_ioctl(struct inode * inode, struc
 		/* Clear the entropy pool counters. */
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
-		init_std_data(input_pool);
-		init_std_data(blocking_pool);
-		init_std_data(nonblocking_pool);
+		init_std_data(&input_pool);
+		init_std_data(&blocking_pool);
+		init_std_data(&nonblocking_pool);
 		return 0;
 	default:
 		return -EINVAL;
@@ -1843,7 +1798,7 @@ static void sysctl_init_random(struct en
 {
 	min_read_thresh = 8;
 	min_write_thresh = 0;
-	max_read_thresh = max_write_thresh = pool->poolinfo.POOLBITS;
+	max_read_thresh = max_write_thresh = pool->poolinfo->POOLBITS;
 	random_table[1].data = &pool->entropy_count;
 }
 #endif 	/* CONFIG_SYSCTL */
_
