aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm/xfrm_state.c
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@gmail.com>2008-11-25 20:18:12 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-25 20:18:12 -0500
commit529983ecabeae3d8e61c9e27079154b1b8544dcd (patch)
treeeb440806ba098ed3abf629bcb57c53e5a61e7b17 /net/xfrm/xfrm_state.c
parentb754a4fd8f58d245c9b5e92914cce09c4309cb67 (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/xfrm_state.c')
-rw-r--r--net/xfrm/xfrm_state.c31
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
45static DEFINE_SPINLOCK(xfrm_state_lock); 45static DEFINE_SPINLOCK(xfrm_state_lock);
46 46
47static unsigned int xfrm_state_hmask __read_mostly;
48static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024; 47static unsigned int xfrm_state_hashmax __read_mostly = 1 * 1024 * 1024;
49static unsigned int xfrm_state_num; 48static unsigned int xfrm_state_num;
50static unsigned int xfrm_state_genid; 49static 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
70static inline unsigned int xfrm_src_hash(xfrm_address_t *daddr, 69static 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
77static inline unsigned int 76static inline unsigned int
78xfrm_spi_hash(xfrm_address_t *daddr, __be32 spi, u8 proto, unsigned short family) 77xfrm_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
83static void xfrm_hash_transfer(struct hlist_head *list, 82static void xfrm_hash_transfer(struct hlist_head *list,
@@ -113,7 +112,7 @@ static void xfrm_hash_transfer(struct hlist_head *list,
113 112
114static unsigned long xfrm_hash_new_size(void) 113static 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;
623restart: 622restart:
@@ -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)
754static void xfrm_hash_grow_check(int have_hash_collision) 753static 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));