diff options
author | Alexey Dobriyan <adobriyan@gmail.com> | 2008-11-25 20:19:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-25 20:19:07 -0500 |
commit | 630827338585022b851ec0a6335df8e436c900e4 (patch) | |
tree | d40fcd9a94157171f14b481e7571ae255c6aab8f /net/xfrm/xfrm_state.c | |
parent | 0bf7c5b019518d3fe9cb96b9c97bf44d251472c3 (diff) |
netns xfrm: per-netns xfrm_hash_work
All of this is implicit passing which netns's hashes should be 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.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 7ecf6eeff84a..1b2a72c8429c 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -109,16 +109,16 @@ static void xfrm_hash_transfer(struct hlist_head *list, | |||
109 | } | 109 | } |
110 | } | 110 | } |
111 | 111 | ||
112 | static unsigned long xfrm_hash_new_size(void) | 112 | static unsigned long xfrm_hash_new_size(unsigned int state_hmask) |
113 | { | 113 | { |
114 | return ((init_net.xfrm.state_hmask + 1) << 1) * | 114 | return ((state_hmask + 1) << 1) * sizeof(struct hlist_head); |
115 | sizeof(struct hlist_head); | ||
116 | } | 115 | } |
117 | 116 | ||
118 | static DEFINE_MUTEX(hash_resize_mutex); | 117 | static DEFINE_MUTEX(hash_resize_mutex); |
119 | 118 | ||
120 | static void xfrm_hash_resize(struct work_struct *__unused) | 119 | static void xfrm_hash_resize(struct work_struct *work) |
121 | { | 120 | { |
121 | struct net *net = container_of(work, struct net, xfrm.state_hash_work); | ||
122 | struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi; | 122 | struct hlist_head *ndst, *nsrc, *nspi, *odst, *osrc, *ospi; |
123 | unsigned long nsize, osize; | 123 | unsigned long nsize, osize; |
124 | unsigned int nhashmask, ohashmask; | 124 | unsigned int nhashmask, ohashmask; |
@@ -126,7 +126,7 @@ static void xfrm_hash_resize(struct work_struct *__unused) | |||
126 | 126 | ||
127 | mutex_lock(&hash_resize_mutex); | 127 | mutex_lock(&hash_resize_mutex); |
128 | 128 | ||
129 | nsize = xfrm_hash_new_size(); | 129 | nsize = xfrm_hash_new_size(net->xfrm.state_hmask); |
130 | ndst = xfrm_hash_alloc(nsize); | 130 | ndst = xfrm_hash_alloc(nsize); |
131 | if (!ndst) | 131 | if (!ndst) |
132 | goto out_unlock; | 132 | goto out_unlock; |
@@ -145,19 +145,19 @@ static void xfrm_hash_resize(struct work_struct *__unused) | |||
145 | spin_lock_bh(&xfrm_state_lock); | 145 | spin_lock_bh(&xfrm_state_lock); |
146 | 146 | ||
147 | nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; | 147 | nhashmask = (nsize / sizeof(struct hlist_head)) - 1U; |
148 | for (i = init_net.xfrm.state_hmask; i >= 0; i--) | 148 | for (i = net->xfrm.state_hmask; i >= 0; i--) |
149 | xfrm_hash_transfer(init_net.xfrm.state_bydst+i, ndst, nsrc, nspi, | 149 | xfrm_hash_transfer(net->xfrm.state_bydst+i, ndst, nsrc, nspi, |
150 | nhashmask); | 150 | nhashmask); |
151 | 151 | ||
152 | odst = init_net.xfrm.state_bydst; | 152 | odst = net->xfrm.state_bydst; |
153 | osrc = init_net.xfrm.state_bysrc; | 153 | osrc = net->xfrm.state_bysrc; |
154 | ospi = init_net.xfrm.state_byspi; | 154 | ospi = net->xfrm.state_byspi; |
155 | ohashmask = init_net.xfrm.state_hmask; | 155 | ohashmask = net->xfrm.state_hmask; |
156 | 156 | ||
157 | init_net.xfrm.state_bydst = ndst; | 157 | net->xfrm.state_bydst = ndst; |
158 | init_net.xfrm.state_bysrc = nsrc; | 158 | net->xfrm.state_bysrc = nsrc; |
159 | init_net.xfrm.state_byspi = nspi; | 159 | net->xfrm.state_byspi = nspi; |
160 | init_net.xfrm.state_hmask = nhashmask; | 160 | net->xfrm.state_hmask = nhashmask; |
161 | 161 | ||
162 | spin_unlock_bh(&xfrm_state_lock); | 162 | spin_unlock_bh(&xfrm_state_lock); |
163 | 163 | ||
@@ -170,8 +170,6 @@ out_unlock: | |||
170 | mutex_unlock(&hash_resize_mutex); | 170 | mutex_unlock(&hash_resize_mutex); |
171 | } | 171 | } |
172 | 172 | ||
173 | static DECLARE_WORK(xfrm_hash_work, xfrm_hash_resize); | ||
174 | |||
175 | DECLARE_WAIT_QUEUE_HEAD(km_waitq); | 173 | DECLARE_WAIT_QUEUE_HEAD(km_waitq); |
176 | EXPORT_SYMBOL(km_waitq); | 174 | EXPORT_SYMBOL(km_waitq); |
177 | 175 | ||
@@ -754,7 +752,7 @@ static void xfrm_hash_grow_check(int have_hash_collision) | |||
754 | if (have_hash_collision && | 752 | if (have_hash_collision && |
755 | (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax && | 753 | (init_net.xfrm.state_hmask + 1) < xfrm_state_hashmax && |
756 | init_net.xfrm.state_num > init_net.xfrm.state_hmask) | 754 | init_net.xfrm.state_num > init_net.xfrm.state_hmask) |
757 | schedule_work(&xfrm_hash_work); | 755 | schedule_work(&init_net.xfrm.state_hash_work); |
758 | } | 756 | } |
759 | 757 | ||
760 | struct xfrm_state * | 758 | struct xfrm_state * |
@@ -2089,6 +2087,7 @@ int __net_init xfrm_state_init(struct net *net) | |||
2089 | net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1); | 2087 | net->xfrm.state_hmask = ((sz / sizeof(struct hlist_head)) - 1); |
2090 | 2088 | ||
2091 | net->xfrm.state_num = 0; | 2089 | net->xfrm.state_num = 0; |
2090 | INIT_WORK(&net->xfrm.state_hash_work, xfrm_hash_resize); | ||
2092 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); | 2091 | INIT_WORK(&xfrm_state_gc_work, xfrm_state_gc_task); |
2093 | return 0; | 2092 | return 0; |
2094 | 2093 | ||