diff options
author | Patrick McHardy <kaber@trash.net> | 2007-07-07 22:28:14 -0700 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-10 22:17:40 -0700 |
commit | f205c5e0c28aa7e0fb6eaaa66e97928f9d9e6994 (patch) | |
tree | 7ad04d827c5c2d24ac804346d95853ebceab0bfd /net/ipv4/netfilter | |
parent | 8e5105a0c36a059dfd0f0bb9e73ee7c97d306247 (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/netfilter')
-rw-r--r-- | net/ipv4/netfilter/nf_conntrack_l3proto_ipv4_compat.c | 17 |
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 89f933e81035..888f27fd884f 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 { unsigned int bucket; }; -static struct list_head *ct_get_first(struct seq_file *seq) +static struct hlist_node *ct_get_first(struct seq_file *seq) { struct ct_iter_state *st = seq->private; for (st->bucket = 0; st->bucket < nf_conntrack_htable_size; st->bucket++) { - if (!list_empty(&nf_conntrack_hash[st->bucket])) - return nf_conntrack_hash[st->bucket].next; + if (!hlist_empty(&nf_conntrack_hash[st->bucket])) + return nf_conntrack_hash[st->bucket].first; } return NULL; } -static struct list_head *ct_get_next(struct seq_file *seq, struct list_head *head) +static struct hlist_node *ct_get_next(struct seq_file *seq, + struct hlist_node *head) { struct ct_iter_state *st = seq->private; head = head->next; - while (head == &nf_conntrack_hash[st->bucket]) { + while (head == NULL) { if (++st->bucket >= nf_conntrack_htable_size) return NULL; - head = nf_conntrack_hash[st->bucket].next; + head = nf_conntrack_hash[st->bucket].first; } return head; } -static struct list_head *ct_get_idx(struct seq_file *seq, loff_t pos) +static struct hlist_node *ct_get_idx(struct seq_file *seq, loff_t pos) { - struct list_head *head = ct_get_first(seq); + struct hlist_node *head = ct_get_first(seq); if (head) while (pos && (head = ct_get_next(seq, head))) |