diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:18:12 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:18:12 -0500 |
commit | 529983ecabeae3d8e61c9e27079154b1b8544dcd (patch) | |
tree | eb440806ba098ed3abf629bcb57c53e5a61e7b17 /net/xfrm | |
parent | b754a4fd8f58d245c9b5e92914cce09c4309cb67 (diff) |
netns xfrm: per-netns xfrm_state_hmask
Since hashtables are per-netns, they can be independently resized.
Signed-off-by: Alexey Dobriyan <adobriyan@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_state.c | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 66ca1ef7f8eb..de08ed9a4775 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -44,7 +44,6 @@ u32 sysctl_xfrm_acq_expires __read_mostly = 30; | |||
44 | 44 | ||
45 | static DEFINE_SPINLOCK(xfrm_state_lock); | 45 | static DEFINE_SPINLOCK(xfrm_state_lock); |
46 | 46 | ||
47 | static unsigned int xfrm_state_hmask __read_mostly; | ||
48 | static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; | 47 | static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; |
49 | static unsigned int xfrm_state_num; | 48 | static unsigned int xfrm_state_num; |
50 | static unsigned int xfrm_state_genid; | 49 | static unsigned int xfrm_state_genid; |
@@ -64,20 +63,20 @@ static inline unsigned int xfrm_dst_hash(xfrm_address_t *daddr, | |||
64 | u32 reqid, | 63 | u32 reqid, |
65 | unsigned short family) | 64 | unsigned short family) |
66 | { | 65 | { |
67 | return __xfrm_dst_hash(daddr, saddr, reqid, family, xfrm_state_hmask); | 66 | return __xfrm_dst_hash(daddr, saddr, reqid, family, init_net.xfrm.state_hmask); |
68 | } | 67 | } |
69 | 68 | ||
70 | static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr, | 69 | static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr, |
71 | xfrm_address_t *saddr, | 70 | xfrm_address_t *saddr, |
72 | unsigned short family) | 71 | unsigned short family) |
73 | { | 72 | { |
74 | return __xfrm_src_hash(daddr, saddr, family, xfrm_state_hmask); | 73 | return __xfrm_src_hash(daddr, saddr, family, init_net.xfrm.state_hmask); |
75 | } | 74 | } |
76 | 75 | ||
77 | static inline unsigned int | 76 | static inline unsigned int |
78 | xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) | 77 | xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) |
79 | { | 78 | { |
80 | return __xfrm_spi_hash(daddr, spi, proto, family, xfrm_state_hmask); | 79 | return __xfrm_spi_hash(daddr, spi, proto, family, init_net.xfrm.state_hmask); |
81 | } | 80 | } |
82 | 81 | ||
83 | static void xfrm_hash_transfer(struct hlist_head *list, | 82 | static void xfrm_hash_transfer(struct hlist_head *list, |
@@ -113,7 +112,7 @@ static void xfrm_hash_transfer(struct hlist_head *list, | |||
113 | 112 | ||
114 | static unsigned long xfrm_hash_new_size(void) | 113 | static unsigned long xfrm_hash_new_size(void) |
115 | { | 114 | { |
116 | return ((xfrm_state_hmask + 1) << 1) * | 115 | return ((init_net.xfrm.state_hmask + 1) << 1) * |
117 | sizeof(struct hlist_head); | 116 | sizeof(struct hlist_head); |
118 | } | 117 | } |
119 | 118 | ||
@@ -147,19 +146,19 @@ static void xfrm_hash_resize(struct work_struct *__unused) | |||
147 | spin_lock_bh(&xfrm_state_lock); | 146 | spin_lock_bh(&xfrm_state_lock); |
148 | 147 | ||
149 | nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; | 148 | nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; |
150 | for (i = xfrm_state_hmask; i >= 0; i--) | 149 | for (i = init_net.xfrm.state_hmask; i >= 0; i--) |
151 | xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi, | 150 | xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi, |
152 | nhashmask); | 151 | nhashmask); |
153 | 152 | ||
154 | odst = init_net.xfrm.state_bydst; | 153 | odst = init_net.xfrm.state_bydst; |
155 | osrc = init_net.xfrm.state_bysrc; | 154 | osrc = init_net.xfrm.state_bysrc; |
156 | ospi = init_net.xfrm.state_byspi; | 155 | ospi = init_net.xfrm.state_byspi; |
157 | ohashmask = xfrm_state_hmask; | 156 | ohashmask = init_net.xfrm.state_hmask; |
158 | 157 | ||
159 | init_net.xfrm.state_bydst = ndst; | 158 | init_net.xfrm.state_bydst = ndst; |
160 | init_net.xfrm.state_bysrc = nsrc; | 159 | init_net.xfrm.state_bysrc = nsrc; |
161 | init_net.xfrm.state_byspi = nspi; | 160 | init_net.xfrm.state_byspi = nspi; |
162 | xfrm_state_hmask = nhashmask; | 161 | init_net.xfrm.state_hmask = nhashmask; |
163 | 162 | ||
164 | spin_unlock_bh(&xfrm_state_lock); | 163 | spin_unlock_bh(&xfrm_state_lock); |
165 | 164 | ||
@@ -582,7 +581,7 @@ xfrm_state_flush_secctx_check(u8 proto, struct xfrm_audit *audit_info) | |||
582 | { | 581 | { |
583 | int i, err = 0; | 582 | int i, err = 0; |
584 | 583 | ||
585 | for (i = 0; i <= xfrm_state_hmask; i++) { | 584 | for (i = 0; i <= init_net.xfrm.state_hmask; i++) { |
586 | struct hlist_node *entry; | 585 | struct hlist_node *entry; |
587 | struct xfrm_state *x; | 586 | struct xfrm_state *x; |
588 | 587 | ||
@@ -617,7 +616,7 @@ int xfrm_state_flush(u8 proto, struct xfrm_audit *audit_info) | |||
617 | if (err) | 616 | if (err) |
618 | goto out; | 617 | goto out; |
619 | 618 | ||
620 | for (i = 0; i <= xfrm_state_hmask; i++) { | 619 | for (i = 0; i <= init_net.xfrm.state_hmask; i++) { |
621 | struct hlist_node *entry; | 620 | struct hlist_node *entry; |
622 | struct xfrm_state *x; | 621 | struct xfrm_state *x; |
623 | restart: | 622 | restart: |
@@ -652,7 +651,7 @@ void xfrm_sad_getinfo(struct xfrmk_sadinfo *si) | |||
652 | { | 651 | { |
653 | spin_lock_bh(&xfrm_state_lock); | 652 | spin_lock_bh(&xfrm_state_lock); |
654 | si->sadcnt = xfrm_state_num; | 653 | si->sadcnt = xfrm_state_num; |
655 | si->sadhcnt = xfrm_state_hmask; | 654 | si->sadhcnt = init_net.xfrm.state_hmask; |
656 | si->sadhmcnt = xfrm_state_hashmax; | 655 | si->sadhmcnt = xfrm_state_hashmax; |
657 | spin_unlock_bh(&xfrm_state_lock); | 656 | spin_unlock_bh(&xfrm_state_lock); |
658 | } | 657 | } |
@@ -754,8 +753,8 @@ __xfrm_state_locate(struct xfrm_state *x, int use_spi, int family) | |||
754 | static void xfrm_hash_grow_check(int have_hash_collision) | 753 | static void xfrm_hash_grow_check(int have_hash_collision) |
755 | { | 754 | { |
756 | if (have_hash_collision && | 755 | if (have_hash_collision && |
757 | (xfrm_state_hmask + 1) < xfrm_state_hashmax && | 756 | (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax && |
758 | xfrm_state_num > xfrm_state_hmask) | 757 | xfrm_state_num > init_net.xfrm.state_hmask) |
759 | schedule_work(&xfrm_hash_work); | 758 | schedule_work(&xfrm_hash_work); |
760 | } | 759 | } |
761 | 760 | ||
@@ -1444,7 +1443,7 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq) | |||
1444 | { | 1443 | { |
1445 | int i; | 1444 | int i; |
1446 | 1445 | ||
1447 | for (i = 0; i <= xfrm_state_hmask; i++) { | 1446 | for (i = 0; i <= init_net.xfrm.state_hmask; i++) { |
1448 | struct hlist_node *entry; | 1447 | struct hlist_node *entry; |
1449 | struct xfrm_state *x; | 1448 | struct xfrm_state *x; |
1450 | 1449 | ||
@@ -2088,7 +2087,7 @@ int __net_init xfrm_state_init(struct net *net) | |||
2088 | net->xfrm.state_byspi = xfrm_hash_alloc(sz); | 2087 | net->xfrm.state_byspi = xfrm_hash_alloc(sz); |
2089 | if (!net->xfrm.state_byspi) | 2088 | if (!net->xfrm.state_byspi) |
2090 | goto out_byspi; | 2089 | goto out_byspi; |
2091 | xfrm_state_hmask = ((sz / sizeof(struct hlist_head)) - 1); | 2090 | net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1); |
2092 | 2091 | ||
2093 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); | 2092 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); |
2094 | return 0; | 2093 | return 0; |
@@ -2107,7 +2106,7 @@ void xfrm_state_fini(struct net *net) | |||
2107 | 2106 | ||
2108 | WARN_ON(!list_empty(&net->xfrm.state_all)); | 2107 | WARN_ON(!list_empty(&net->xfrm.state_all)); |
2109 | 2108 | ||
2110 | sz = (xfrm_state_hmask + 1) * sizeof(struct hlist_head); | 2109 | sz = (net->xfrm.state_hmask + 1) * sizeof(struct hlist_head); |
2111 | WARN_ON(!hlist_empty(net->xfrm.state_byspi)); | 2110 | WARN_ON(!hlist_empty(net->xfrm.state_byspi)); |
2112 | xfrm_hash_free(net->xfrm.state_byspi, sz); | 2111 | xfrm_hash_free(net->xfrm.state_byspi, sz); |
2113 | WARN_ON(!hlist_empty(net->xfrm.state_bysrc)); | 2112 | WARN_ON(!hlist_empty(net->xfrm.state_bysrc)); |