]> git.hungrycats.org Git - linux/commitdiff
[PATCH] dev/random: Fix latency in rekeying sequence number
authorTheodore Y. Ts'o <tytso@mit.edu>
Tue, 24 Aug 2004 04:44:18 +0000 (21:44 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 24 Aug 2004 04:44:18 +0000 (21:44 -0700)
Based on reports from Ingo's Latency Tracer that the TCP sequence number
rekey code is causing latency problems, I've moved the sequence number
rekey to be done out of a workqueue.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/char/random.c

index a162ddd65f1525ff30b2696a5e0f7f8f48327753..27c7c90347efbbc0a0a6d78030914377f20370de 100644 (file)
@@ -2247,30 +2247,35 @@ static struct keydata {
 static spinlock_t ip_lock = SPIN_LOCK_UNLOCKED;
 static unsigned int ip_cnt;
 
-static struct keydata *__check_and_rekey(time_t time)
+static void rekey_seq_generator(void *private_)
 {
        struct keydata *keyptr;
+       struct timeval  tv;
+
+       do_gettimeofday(&tv);
+
        spin_lock_bh(&ip_lock);
        keyptr = &ip_keydata[ip_cnt&1];
-       if (!keyptr->rekey_time || (time - keyptr->rekey_time) > REKEY_INTERVAL) {
-               keyptr = &ip_keydata[1^(ip_cnt&1)];
-               keyptr->rekey_time = time;
-               get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
-               keyptr->count = (ip_cnt&COUNT_MASK)<<HASH_BITS;
-               mb();
-               ip_cnt++;
-       }
+
+       keyptr = &ip_keydata[1^(ip_cnt&1)];
+       keyptr->rekey_time = tv.tv_sec;
+       get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
+       keyptr->count = (ip_cnt&COUNT_MASK)<<HASH_BITS;
+       mb();
+       ip_cnt++;
+
        spin_unlock_bh(&ip_lock);
-       return keyptr;
 }
 
+static DECLARE_WORK(rekey_work, rekey_seq_generator, NULL);
+
 static inline struct keydata *check_and_rekey(time_t time)
 {
        struct keydata *keyptr = &ip_keydata[ip_cnt&1];
 
        rmb();
        if (!keyptr->rekey_time || (time - keyptr->rekey_time) > REKEY_INTERVAL) {
-               keyptr = __check_and_rekey(time);
+               schedule_work(&rekey_work);
        }
 
        return keyptr;