diff options
author | Patrick McHardy <kaber@trash.net> | 2008-01-31 07:38:38 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-31 22:27:54 -0500 |
commit | 76507f69c44ed199a1a68086145398459e55835d (patch) | |
tree | 2e83a70fa50f3432ca63eeef84e038c72d254d10 /net/ipv4 | |
parent | 7d0742da1c8f5df3a34030f0170b30d1a052be80 (diff) |
[NETFILTER]: nf_conntrack: use RCU for conntrack hash
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.c | 18 |
1 files changed, 12 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 2fdcd9233a03..0ee87edbd286 100644 --- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c +++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | |||
@@ -39,12 +39,14 @@ struct ct_iter_state { | |||
39 | static struct hlist_node *ct_get_first(struct seq_file *seq) | 39 | static struct hlist_node *ct_get_first(struct seq_file *seq) |
40 | { | 40 | { |
41 | struct ct_iter_state *st = seq->private; | 41 | struct ct_iter_state *st = seq->private; |
42 | struct hlist_node *n; | ||
42 | 43 | ||
43 | for (st->bucket = 0; | 44 | for (st->bucket = 0; |
44 | st->bucket < nf_conntrack_htable_size; | 45 | st->bucket < nf_conntrack_htable_size; |
45 | st->bucket++) { | 46 | st->bucket++) { |
46 | if (!hlist_empty(&nf_conntrack_hash[st->bucket])) | 47 | n = rcu_dereference(nf_conntrack_hash[st->bucket].first); |
47 | return nf_conntrack_hash[st->bucket].first; | 48 | if (n) |
49 | return n; | ||
48 | } | 50 | } |
49 | return NULL; | 51 | return NULL; |
50 | } | 52 | } |
@@ -54,11 +56,11 @@ static struct hlist_node *ct_get_next(struct seq_file *seq, | |||
54 | { | 56 | { |
55 | struct ct_iter_state *st = seq->private; | 57 | struct ct_iter_state *st = seq->private; |
56 | 58 | ||
57 | head = head->next; | 59 | head = rcu_dereference(head->next); |
58 | while (head == NULL) { | 60 | while (head == NULL) { |
59 | if (++st->bucket >= nf_conntrack_htable_size) | 61 | if (++st->bucket >= nf_conntrack_htable_size) |
60 | return NULL; | 62 | return NULL; |
61 | head = nf_conntrack_hash[st->bucket].first; | 63 | head = rcu_dereference(nf_conntrack_hash[st->bucket].first); |
62 | } | 64 | } |
63 | return head; | 65 | return head; |
64 | } | 66 | } |
@@ -74,8 +76,9 @@ static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos) | |||
74 | } | 76 | } |
75 | 77 | ||
76 | static void *ct_seq_start(struct seq_file *seq, loff_t *pos) | 78 | static void *ct_seq_start(struct seq_file *seq, loff_t *pos) |
79 | __acquires(RCU) | ||
77 | { | 80 | { |
78 | read_lock_bh(&nf_conntrack_lock); | 81 | rcu_read_lock(); |
79 | return ct_get_idx(seq, *pos); | 82 | return ct_get_idx(seq, *pos); |
80 | } | 83 | } |
81 | 84 | ||
@@ -86,8 +89,9 @@ static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
86 | } | 89 | } |
87 | 90 | ||
88 | static void ct_seq_stop(struct seq_file *s, void *v) | 91 | static void ct_seq_stop(struct seq_file *s, void *v) |
92 | __releases(RCU) | ||
89 | { | 93 | { |
90 | read_unlock_bh(&nf_conntrack_lock); | 94 | rcu_read_unlock(); |
91 | } | 95 | } |
92 | 96 | ||
93 | static int ct_seq_show(struct seq_file *s, void *v) | 97 | static int ct_seq_show(struct seq_file *s, void *v) |
@@ -226,6 +230,7 @@ static struct hlist_node *ct_expect_get_idx(struct seq_file *seq, loff_t pos) | |||
226 | } | 230 | } |
227 | 231 | ||
228 | static void *exp_seq_start(struct seq_file *seq, loff_t *pos) | 232 | static void *exp_seq_start(struct seq_file *seq, loff_t *pos) |
233 | __acquires(RCU) | ||
229 | { | 234 | { |
230 | rcu_read_lock(); | 235 | rcu_read_lock(); |
231 | return ct_expect_get_idx(seq, *pos); | 236 | return ct_expect_get_idx(seq, *pos); |
@@ -238,6 +243,7 @@ static void *exp_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
238 | } | 243 | } |
239 | 244 | ||
240 | static void exp_seq_stop(struct seq_file *seq, void *v) | 245 | static void exp_seq_stop(struct seq_file *seq, void *v) |
246 | __releases(RCU) | ||
241 | { | 247 | { |
242 | rcu_read_unlock(); | 248 | rcu_read_unlock(); |
243 | } | 249 | } |