aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2008-01-31 07:38:19 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-31 22:27:53 -0500
commit7d0742da1c8f5df3a34030f0170b30d1a052be80 (patch)
treef5717a37a9b4fe27abfa7886996d7051c57b91b9 /net/ipv4
parentc52fbb410b2662a7bbc5cbe5969d73c733151498 (diff)
[NETFILTER]: nf_conntrack_expect: use RCU for expectation hash
Use RCU for expectation hash. This doesn't buy much for conntrack runtime performance, but allows to reduce the use of nf_conntrack_lock for /proc and nf_netlink_conntrack. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 543c02b74c96..2fdcd9233a03 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -191,10 +191,12 @@ struct ct_expect_iter_state {
191static struct hlist_node *ct_expect_get_first(struct seq_file *seq) 191static struct hlist_node *ct_expect_get_first(struct seq_file *seq)
192{ 192{
193 struct ct_expect_iter_state *st = seq->private; 193 struct ct_expect_iter_state *st = seq->private;
194 struct hlist_node *n;
194 195
195 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) { 196 for (st->bucket = 0; st->bucket < nf_ct_expect_hsize; st->bucket++) {
196 if (!hlist_empty(&nf_ct_expect_hash[st->bucket])) 197 n = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
197 return nf_ct_expect_hash[st->bucket].first; 198 if (n)
199 return n;
198 } 200 }
199 return NULL; 201 return NULL;
200} 202}
@@ -204,11 +206,11 @@ static struct hlist_node *ct_expect_get_next(struct seq_file *seq,
204{ 206{
205 struct ct_expect_iter_state *st = seq->private; 207 struct ct_expect_iter_state *st = seq->private;
206 208
207 head = head->next; 209 head = rcu_dereference(head->next);
208 while (head == NULL) { 210 while (head == NULL) {
209 if (++st->bucket >= nf_ct_expect_hsize) 211 if (++st->bucket >= nf_ct_expect_hsize)
210 return NULL; 212 return NULL;
211 head = nf_ct_expect_hash[st->bucket].first; 213 head = rcu_dereference(nf_ct_expect_hash[st->bucket].first);
212 } 214 }
213 return head; 215 return head;
214} 216}
@@ -225,7 +227,7 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos)
225 227
226static void *exp_seq_start(struct seq_file *seq, loff_t *pos) 228static void *exp_seq_start(struct seq_file *seq, loff_t *pos)
227{ 229{
228 read_lock_bh(&nf_conntrack_lock); 230 rcu_read_lock();
229 return ct_expect_get_idx(seq, *pos); 231 return ct_expect_get_idx(seq, *pos);
230} 232}
231 233
@@ -237,7 +239,7 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
237 239
238static void exp_seq_stop(struct seq_file *seq, void *v) 240static void exp_seq_stop(struct seq_file *seq, void *v)
239{ 241{
240 read_unlock_bh(&nf_conntrack_lock); 242 rcu_read_unlock();
241} 243}
242 244
243static int exp_seq_show(struct seq_file *s, void *v) 245static int exp_seq_show(struct seq_file *s, void *v)