Commit 21d8c49e01a0c1c6eb6c750cd04110db4a539284

Authored by David S. Miller
1 parent 8849b720e9

ipv4: Call fib_select_default() only when actually necessary.

fib_select_default() is a complete NOP, and completely pointless
to invoke, when we have no more than 1 default route installed.

And this is far and away the common case.

So remember how many prefixlen==0 routes we have in the routing
table, and elide the call when we have no more than one of those.

This cuts output route creation time by 157 cycles on Niagara2+.

In order to add the new int to fib_table, we have to correct the type
of ->tb_data[] to unsigned long, otherwise the private area will be
unaligned on 64-bit systems.

Signed-off-by: David S. Miller <davem@davemloft.net>
Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>

Showing 3 changed files with 12 additions and 2 deletions Side-by-side Diff

include/net/ip_fib.h
... ... @@ -160,7 +160,8 @@
160 160 struct hlist_node tb_hlist;
161 161 u32 tb_id;
162 162 int tb_default;
163   - unsigned char tb_data[0];
  163 + int tb_num_default;
  164 + unsigned long tb_data[0];
164 165 };
165 166  
166 167 extern int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
... ... @@ -1332,6 +1332,9 @@
1332 1332 }
1333 1333 }
1334 1334  
  1335 + if (!plen)
  1336 + tb->tb_num_default++;
  1337 +
1335 1338 list_add_tail_rcu(&new_fa->fa_list,
1336 1339 (fa ? &fa->fa_list : fa_head));
1337 1340  
... ... @@ -1697,6 +1700,9 @@
1697 1700  
1698 1701 list_del_rcu(&fa->fa_list);
1699 1702  
  1703 + if (!plen)
  1704 + tb->tb_num_default--;
  1705 +
1700 1706 if (list_empty(fa_head)) {
1701 1707 hlist_del_rcu(&li->hlist);
1702 1708 free_leaf_info(li);
... ... @@ -1987,6 +1993,7 @@
1987 1993  
1988 1994 tb->tb_id = id;
1989 1995 tb->tb_default = -1;
  1996 + tb->tb_num_default = 0;
1990 1997  
1991 1998 t = (struct trie *) tb->tb_data;
1992 1999 memset(t, 0, sizeof(*t));
... ... @@ -2615,7 +2615,9 @@
2615 2615 fib_select_multipath(&res);
2616 2616 else
2617 2617 #endif
2618   - if (!res.prefixlen && res.type == RTN_UNICAST && !fl4.flowi4_oif)
  2618 + if (!res.prefixlen &&
  2619 + res.table->tb_num_default > 1 &&
  2620 + res.type == RTN_UNICAST && !fl4.flowi4_oif)
2619 2621 fib_select_default(&res);
2620 2622  
2621 2623 if (!fl4.saddr)