random: clean up interrupt entropy accounting for archs w/o cycle counters

For architectures that don't have cycle counters, the algorithm for
deciding when to avoid giving entropy credit due to back-to-back timer
interrupts didn't make any sense, since we were checking every 64
interrupts.  Change it so that we only give an entropy credit if the
majority of the interrupts are not based on the timer.

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Cc: George Spelvin <linux@horizon.com>
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 364a800..dfe918a 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -548,9 +548,9 @@
 struct fast_pool {
 	__u32		pool[4];
 	unsigned long	last;
-	unsigned short	count;
+	unsigned char	count;
+	unsigned char	notimer_count;
 	unsigned char	rotate;
-	unsigned char	last_timer_intr;
 };
 
 /*
@@ -850,15 +850,23 @@
 	input[3] = ip >> 32;
 
 	fast_mix(fast_pool, input);
+	if ((irq_flags & __IRQF_TIMER) == 0)
+		fast_pool->notimer_count++;
 
-	if ((fast_pool->count & 63) && !time_after(now, fast_pool->last + HZ))
-		return;
+	if (cycles) {
+		if ((fast_pool->count < 64) &&
+		    !time_after(now, fast_pool->last + HZ))
+			return;
+	} else {
+		/* CPU does not have a cycle counting register :-( */
+		if (fast_pool->count < 64)
+			return;
+	}
 
 	r = nonblocking_pool.initialized ? &input_pool : &nonblocking_pool;
-	if (!spin_trylock(&r->lock)) {
-		fast_pool->count--;
+	if (!spin_trylock(&r->lock))
 		return;
-	}
+
 	fast_pool->last = now;
 	__mix_pool_bytes(r, &fast_pool->pool, sizeof(fast_pool->pool));
 
@@ -874,19 +882,15 @@
 	spin_unlock(&r->lock);
 
 	/*
-	 * If we don't have a valid cycle counter, and we see
-	 * back-to-back timer interrupts, then skip giving credit for
-	 * any entropy, otherwise credit 1 bit.
+	 * If we have a valid cycle counter or if the majority of
+	 * interrupts collected were non-timer interrupts, then give
+	 * an entropy credit of 1 bit.  Yes, this is being very
+	 * conservative.
 	 */
-	credit++;
-	if (cycles == 0) {
-		if (irq_flags & __IRQF_TIMER) {
-			if (fast_pool->last_timer_intr)
-				credit--;
-			fast_pool->last_timer_intr = 1;
-		} else
-			fast_pool->last_timer_intr = 0;
-	}
+	if (cycles || (fast_pool->notimer_count >= 32))
+		credit++;
+
+	fast_pool->count = fast_pool->notimer_count = 0;
 
 	credit_entropy_bits(r, credit);
 }