diff options
Diffstat (limited to 'net/xfrm/xfrm_state.c')
-rw-r--r-- | net/xfrm/xfrm_state.c | 19 |
1 files changed, 15 insertions, 4 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 39b8bf3a9ded..899de9ed22a6 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -505,6 +505,14 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
505 | x->id.proto, family); | 505 | x->id.proto, family); |
506 | } | 506 | } |
507 | 507 | ||
508 | static void xfrm_hash_grow_check(int have_hash_collision) | ||
509 | { | ||
510 | if (have_hash_collision && | ||
511 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | ||
512 | xfrm_state_num > xfrm_state_hmask) | ||
513 | schedule_work(&xfrm_hash_work); | ||
514 | } | ||
515 | |||
508 | struct xfrm_state * | 516 | struct xfrm_state * |
509 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | 517 | xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, |
510 | struct flowi *fl, struct xfrm_tmpl *tmpl, | 518 | struct flowi *fl, struct xfrm_tmpl *tmpl, |
@@ -598,6 +606,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr, | |||
598 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; | 606 | x->lft.hard_add_expires_seconds = XFRM_ACQ_EXPIRES; |
599 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; | 607 | x->timer.expires = jiffies + XFRM_ACQ_EXPIRES*HZ; |
600 | add_timer(&x->timer); | 608 | add_timer(&x->timer); |
609 | xfrm_state_num++; | ||
610 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
601 | } else { | 611 | } else { |
602 | x->km.state = XFRM_STATE_DEAD; | 612 | x->km.state = XFRM_STATE_DEAD; |
603 | xfrm_state_put(x); | 613 | xfrm_state_put(x); |
@@ -642,10 +652,7 @@ static void __xfrm_state_insert(struct xfrm_state *x) | |||
642 | 652 | ||
643 | xfrm_state_num++; | 653 | xfrm_state_num++; |
644 | 654 | ||
645 | if (x->bydst.next != NULL && | 655 | 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 | } | 656 | } |
650 | 657 | ||
651 | /* xfrm_state_lock is held */ | 658 | /* xfrm_state_lock is held */ |
@@ -753,6 +760,10 @@ static struct xfrm_state *__find_acq_core(unsigned short family, u8 mode, u32 re | |||
753 | h = xfrm_src_hash(daddr, saddr, family); | 760 | h = xfrm_src_hash(daddr, saddr, family); |
754 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); | 761 | hlist_add_head(&x->bysrc, xfrm_state_bysrc+h); |
755 | wake_up(&km_waitq); | 762 | wake_up(&km_waitq); |
763 | |||
764 | xfrm_state_num++; | ||
765 | |||
766 | xfrm_hash_grow_check(x->bydst.next != NULL); | ||
756 | } | 767 | } |
757 | 768 | ||
758 | return x; | 769 | return x; |