aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2007-07-08 01:28:14 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-07-11 01:17:40 -0400
commitf205c5e0c28aa7e0fb6eaaa66e97928f9d9e6994 (patch)
tree7ad04d827c5c2d24ac804346d95853ebceab0bfd /net/ipv4
parent8e5105a0c36a059dfd0f0bb9e73ee7c97d306247 (diff)
[NETFILTER]: nf_conntrack: use hlists for conntrack hash
Convert conntrack hash to hlists to reduce its size and cache footprint. Since the default hashsize to max. entries ratio sucks (1:16), this patch doesn't reduce the amount of memory used for the hash by default, but instead uses a better ratio of 1:8, which results in the same max. entries value. One thing worth noting is early_drop. It really should use LRU, so it now has to iterate over the entire chain to find the last unconfirmed entry. Since chains shouldn't be very long and the entire operation is very rare this shouldn't be a problem. 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.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
index 89f933e8103..888f27fd884 100644
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c
@@ -41,35 +41,36 @@ struct ct_iter_state {
41 unsigned int bucket; 41 unsigned int bucket;
42}; 42};
43 43
44static struct list_head *ct_get_first(struct seq_file *seq) 44static struct hlist_node *ct_get_first(struct seq_file *seq)
45{ 45{
46 struct ct_iter_state *st = seq->private; 46 struct ct_iter_state *st = seq->private;
47 47
48 for (st->bucket = 0; 48 for (st->bucket = 0;
49 st->bucket < nf_conntrack_htable_size; 49 st->bucket < nf_conntrack_htable_size;
50 st->bucket++) { 50 st->bucket++) {
51 if (!list_empty(&nf_conntrack_hash[st->bucket])) 51 if (!hlist_empty(&nf_conntrack_hash[st->bucket]))
52 return nf_conntrack_hash[st->bucket].next; 52 return nf_conntrack_hash[st->bucket].first;
53 } 53 }
54 return NULL; 54 return NULL;
55} 55}
56 56
57static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head) 57static struct hlist_node *ct_get_next(struct seq_file *seq,
58 struct hlist_node *head)
58{ 59{
59 struct ct_iter_state *st = seq->private; 60 struct ct_iter_state *st = seq->private;
60 61
61 head = head->next; 62 head = head->next;
62 while (head == &nf_conntrack_hash[st->bucket]) { 63 while (head == NULL) {
63 if (++st->bucket >= nf_conntrack_htable_size) 64 if (++st->bucket >= nf_conntrack_htable_size)
64 return NULL; 65 return NULL;
65 head = nf_conntrack_hash[st->bucket].next; 66 head = nf_conntrack_hash[st->bucket].first;
66 } 67 }
67 return head; 68 return head;
68} 69}
69 70
70static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) 71static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos)
71{ 72{
72 struct list_head *head = ct_get_first(seq); 73 struct hlist_node *head = ct_get_first(seq);
73 74
74 if (head) 75 if (head)
75 while (pos && (head = ct_get_next(seq, head))) 76 while (pos && (head = ct_get_next(seq, head)))