diff options
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r-- | net/xfrm/xfrm_state.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 39b8bf3a9ded..84bbf8474f3e 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -614,6 +614,14 @@ out: | |||
614 | return x; | 614 | return x; |
615 | } | 615 | } |
616 | 616 | ||
617 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
618 | { | ||
619 | if (have_hash_collision && | ||
620 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
621 | xfrm_state_num > xfrm_state_hmask) | ||
622 | schedule_work(&xfrm_hash_work); | ||
623 | } | ||
624 | |||
617 | static void __xfrm_state_insert(struct xfrm_state *x) | 625 | static void __xfrm_state_insert(struct xfrm_state *x) |
618 | { | 626 | { |
619 | unsigned int h; | 627 | unsigned int h; |
@@ -642,10 +650,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
642 | 650 | ||
643 | xfrm_state_num++; | 651 | xfrm_state_num++; |
644 | 652 | ||
645 | if (x->bydst.next != NULL && | 653 | xfrm_hash_grow_check(x->bydst.next != NULL); |
646 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
647 | xfrm_state_num > xfrm_state_hmask) | ||
648 | schedule_work(&xfrm_hash_work); | ||
649 | } | 654 | } |
650 | 655 | ||
651 | /* xfrm_state_lock is held */ | 656 | /* xfrm_state_lock is held */ |
@@ -753,6 +758,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
753 | h = xfrm_src_hash(daddr, saddr, family); | 758 | h = xfrm_src_hash(daddr, saddr, family); |
754 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 759 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
755 | wake_up(&km_waitq); | 760 | wake_up(&km_waitq); |
761 | |||
762 | xfrm_state_num++; | ||
763 | |||
764 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
756 | } | 765 | } |
757 | 766 | ||
758 | return x; | 767 | return x; |