]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Reduce random driver lock contention
authorAndrew Morton <akpm@osdl.org>
Tue, 9 Sep 2003 17:21:30 +0000 (10:21 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Tue, 9 Sep 2003 17:21:30 +0000 (10:21 -0700)
From: Matt Mackall <mpm@selenic.com>

The new locking in the random driver is consuming 60% of CPU resources in
Anton's monster power5 boxes.

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

index ef3fd221dd7718950ea685972226001508fe3afd..c36d2ea46b073d33de71cbd84f6bab791ceedce4 100644 (file)
 #include <linux/genhd.h>
 #include <linux/interrupt.h>
 #include <linux/spinlock.h>
+#include <linux/percpu.h>
 
 #include <asm/processor.h>
 #include <asm/uaccess.h>
@@ -280,6 +281,15 @@ static int random_read_wakeup_thresh = 64;
  */
 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
@@ -778,6 +788,11 @@ static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
        __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;