[XFRM]: Fix xfrm_state_num going negative.
authorDavid S. Miller <davem@sunset.davemloft.net>
Fri, 13 Oct 2006 05:03:24 +0000 (22:03 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 16 Oct 2006 06:14:18 +0000 (23:14 -0700)
Missing counter bump when hashing in a new ACQ
xfrm_state.

Now that we have two spots to do the hash grow
check, break it out into a helper function.

Signed-off-by: David S. Miller <davem@davemloft.net>
net/xfrm/xfrm_state.c

index 39b8bf3..84bbf84 100644 (file)
@@ -614,6 +614,14 @@ out:
        return x;
 }
 
+static void xfrm_hash_grow_check(int have_hash_collision)
+{
+       if (have_hash_collision &&
+           (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
+           xfrm_state_num > xfrm_state_hmask)
+               schedule_work(&xfrm_hash_work);
+}
+
 static void __xfrm_state_insert(struct xfrm_state *x)
 {
        unsigned int h;
@@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x)
 
        xfrm_state_num++;
 
-       if (x->bydst.next != NULL &&
-           (xfrm_state_hmask + 1) < xfrm_state_hashmax &&
-           xfrm_state_num > xfrm_state_hmask)
-               schedule_work(&xfrm_hash_work);
+       xfrm_hash_grow_check(x->bydst.next != NULL);
 }
 
 /* xfrm_state_lock is held */
@@ -753,6 +758,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re
                h = xfrm_src_hash(daddr, saddr, family);
                hlist_add_head(&x->bysrc, xfrm_state_bysrc+h);
                wake_up(&km_waitq);
+
+               xfrm_state_num++;
+
+               xfrm_hash_grow_check(x->bydst.next != NULL);
        }
 
        return x;