[NETFILTER]: nf_conntrack: optimize __nf_conntrack_find()
Ignoring specific entries in __nf_conntrack_find() is only needed by NAT for nf_conntrack_tuple_taken(). Remove it from __nf_conntrack_find() and make nf_conntrack_tuple_taken() search the hash itself. Saves 54 bytes of text in the hotpath on x86_64: __nf_conntrack_find | -54 # 321 -> 267, # inlines: 3 -> 2, size inlines: 181 -> 127 nf_conntrack_tuple_taken | +305 # 15 -> 320, lexblocks: 0 -> 3, # inlines: 0 -> 3, size inlines: 0 -> 181 nf_conntrack_find_get | -2 # 90 -> 88 3 functions changed, 305 bytes added, 56 bytes removed, diff: +249 Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
f8ba1affa1
commit
ba419aff2c
@@ -178,8 +178,7 @@ extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
|
|||||||
unsigned int size);
|
unsigned int size);
|
||||||
|
|
||||||
extern struct nf_conntrack_tuple_hash *
|
extern struct nf_conntrack_tuple_hash *
|
||||||
__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
|
__nf_conntrack_find(const struct nf_conntrack_tuple *tuple);
|
||||||
const struct nf_conn *ignored_conntrack);
|
|
||||||
|
|
||||||
extern void nf_conntrack_hash_insert(struct nf_conn *ct);
|
extern void nf_conntrack_hash_insert(struct nf_conn *ct);
|
||||||
|
|
||||||
|
@@ -246,16 +246,14 @@ static void death_by_timeout(unsigned long ul_conntrack)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct nf_conntrack_tuple_hash *
|
struct nf_conntrack_tuple_hash *
|
||||||
__nf_conntrack_find(const struct nf_conntrack_tuple *tuple,
|
__nf_conntrack_find(const struct nf_conntrack_tuple *tuple)
|
||||||
const struct nf_conn *ignored_conntrack)
|
|
||||||
{
|
{
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
struct hlist_node *n;
|
struct hlist_node *n;
|
||||||
unsigned int hash = hash_conntrack(tuple);
|
unsigned int hash = hash_conntrack(tuple);
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
|
hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
|
||||||
if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
|
if (nf_ct_tuple_equal(tuple, &h->tuple)) {
|
||||||
nf_ct_tuple_equal(tuple, &h->tuple)) {
|
|
||||||
NF_CT_STAT_INC(found);
|
NF_CT_STAT_INC(found);
|
||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
@@ -274,7 +272,7 @@ nf_conntrack_find_get(const struct nf_conntrack_tuple *tuple)
|
|||||||
struct nf_conn *ct;
|
struct nf_conn *ct;
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
h = __nf_conntrack_find(tuple, NULL);
|
h = __nf_conntrack_find(tuple);
|
||||||
if (h) {
|
if (h) {
|
||||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
|
if (unlikely(!atomic_inc_not_zero(&ct->ct_general.use)))
|
||||||
@@ -395,12 +393,22 @@ nf_conntrack_tuple_taken(const struct nf_conntrack_tuple *tuple,
|
|||||||
const struct nf_conn *ignored_conntrack)
|
const struct nf_conn *ignored_conntrack)
|
||||||
{
|
{
|
||||||
struct nf_conntrack_tuple_hash *h;
|
struct nf_conntrack_tuple_hash *h;
|
||||||
|
struct hlist_node *n;
|
||||||
|
unsigned int hash = hash_conntrack(tuple);
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
h = __nf_conntrack_find(tuple, ignored_conntrack);
|
hlist_for_each_entry_rcu(h, n, &nf_conntrack_hash[hash], hnode) {
|
||||||
|
if (nf_ct_tuplehash_to_ctrack(h) != ignored_conntrack &&
|
||||||
|
nf_ct_tuple_equal(tuple, &h->tuple)) {
|
||||||
|
NF_CT_STAT_INC(found);
|
||||||
|
rcu_read_unlock();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
NF_CT_STAT_INC(searched);
|
||||||
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
return h != NULL;
|
return 0;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
|
EXPORT_SYMBOL_GPL(nf_conntrack_tuple_taken);
|
||||||
|
|
||||||
|
@@ -1222,9 +1222,9 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
|
|||||||
|
|
||||||
spin_lock_bh(&nf_conntrack_lock);
|
spin_lock_bh(&nf_conntrack_lock);
|
||||||
if (cda[CTA_TUPLE_ORIG])
|
if (cda[CTA_TUPLE_ORIG])
|
||||||
h = __nf_conntrack_find(&otuple, NULL);
|
h = __nf_conntrack_find(&otuple);
|
||||||
else if (cda[CTA_TUPLE_REPLY])
|
else if (cda[CTA_TUPLE_REPLY])
|
||||||
h = __nf_conntrack_find(&rtuple, NULL);
|
h = __nf_conntrack_find(&rtuple);
|
||||||
|
|
||||||
if (h == NULL) {
|
if (h == NULL) {
|
||||||
struct nf_conntrack_tuple master;
|
struct nf_conntrack_tuple master;
|
||||||
@@ -1239,7 +1239,7 @@ ctnetlink_new_conntrack(struct sock *ctnl, struct sk_buff *skb,
|
|||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
|
||||||
master_h = __nf_conntrack_find(&master, NULL);
|
master_h = __nf_conntrack_find(&master);
|
||||||
if (master_h == NULL) {
|
if (master_h == NULL) {
|
||||||
err = -ENOENT;
|
err = -ENOENT;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
|
@@ -124,7 +124,7 @@ static int count_them(struct xt_connlimit_data *data,
|
|||||||
|
|
||||||
/* check the saved connections */
|
/* check the saved connections */
|
||||||
list_for_each_entry_safe(conn, tmp, hash, list) {
|
list_for_each_entry_safe(conn, tmp, hash, list) {
|
||||||
found = __nf_conntrack_find(&conn->tuple, NULL);
|
found = __nf_conntrack_find(&conn->tuple);
|
||||||
found_ct = NULL;
|
found_ct = NULL;
|
||||||
|
|
||||||
if (found != NULL)
|
if (found != NULL)
|
||||||
|
Reference in New Issue
Block a user