Skip to content

Commit

Permalink
gre: optimize hash lookup
Browse files Browse the repository at this point in the history
Instead of keeping candidate tunnel device from all categories,
keep only one candidate with best score. This optimizes stack
usage and speeds up exit code.

Signed-off-by: Timo Teras <timo.teras@iki.fi>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Timo Teras authored and David S. Miller committed Jan 27, 2009
1 parent 3eacdf5 commit afcf124
Showing 1 changed file with 40 additions and 29 deletions.
69 changes: 40 additions & 29 deletions net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
int link = dev->ifindex;
unsigned h0 = HASH(remote);
unsigned h1 = HASH(key);
struct ip_tunnel *t, *sel[4] = { NULL, NULL, NULL, NULL };
struct ip_tunnel *t, *cand = NULL;
struct ipgre_net *ign = net_generic(net, ipgre_net_id);
int dev_type = (gre_proto == htons(ETH_P_TEB)) ?
ARPHRD_ETHER : ARPHRD_IPGRE;
int idx;
int score, cand_score = 4;

for (t = ign->tunnels_r_l[h0^h1]; t; t = t->next) {
if (local != t->parms.iph.saddr ||
Expand All @@ -189,15 +189,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;

idx = 0;
score = 0;
if (t->parms.link != link)
idx |= 1;
score |= 1;
if (t->dev->type != dev_type)
idx |= 2;
if (idx == 0)
score |= 2;
if (score == 0)
return t;
if (sel[idx] == NULL)
sel[idx] = t;

if (score < cand_score) {
cand = t;
cand_score = score;
}
}

for (t = ign->tunnels_r[h0^h1]; t; t = t->next) {
Expand All @@ -210,15 +213,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;

idx = 0;
score = 0;
if (t->parms.link != link)
idx |= 1;
score |= 1;
if (t->dev->type != dev_type)
idx |= 2;
if (idx == 0)
score |= 2;
if (score == 0)
return t;
if (sel[idx] == NULL)
sel[idx] = t;

if (score < cand_score) {
cand = t;
cand_score = score;
}
}

for (t = ign->tunnels_l[h1]; t; t = t->next) {
Expand All @@ -233,15 +239,18 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;

idx = 0;
score = 0;
if (t->parms.link != link)
idx |= 1;
score |= 1;
if (t->dev->type != dev_type)
idx |= 2;
if (idx == 0)
score |= 2;
if (score == 0)
return t;
if (sel[idx] == NULL)
sel[idx] = t;

if (score < cand_score) {
cand = t;
cand_score = score;
}
}

for (t = ign->tunnels_wc[h1]; t; t = t->next) {
Expand All @@ -253,20 +262,22 @@ static struct ip_tunnel * ipgre_tunnel_lookup(struct net_device *dev,
t->dev->type != dev_type)
continue;

idx = 0;
score = 0;
if (t->parms.link != link)
idx |= 1;
score |= 1;
if (t->dev->type != dev_type)
idx |= 2;
if (idx == 0)
score |= 2;
if (score == 0)
return t;
if (sel[idx] == NULL)
sel[idx] = t;

if (score < cand_score) {
cand = t;
cand_score = score;
}
}

for (idx = 1; idx < ARRAY_SIZE(sel); idx++)
if (sel[idx] != NULL)
return sel[idx];
if (cand != NULL)
return cand;

if (ign->fb_tunnel_dev->flags & IFF_UP)
return netdev_priv(ign->fb_tunnel_dev);
Expand Down

0 comments on commit afcf124

Please sign in to comment.