net: ipv6: avoid overhead when no custom FIB rules are installed
If the user hasn't installed any custom rules, don't go through the whole FIB rules layer. This is pretty similar tof4530fa574(ipv4: Avoid overhead when no custom FIB rules are installed). Using a micro-benchmark module [1], timing ip6_route_output() with get_cycles(), with 40,000 routes in the main routing table, before this patch: min=606 max=12911 count=627 average=1959 95th=4903 90th=3747 50th=1602 mad=821 table=254 avgdepth=21.8 maxdepth=39 value │ ┊ count 600 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 199 880 │▒▒▒░░░░░░░░░░░░░░░░ 43 1160 │▒▒▒░░░░░░░░░░░░░░░░░░░░ 48 1440 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░ 43 1720 │▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░ 59 2000 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 50 2280 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 26 2560 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 31 2840 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 28 3120 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 17 3400 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 17 3680 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8 3960 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 11 4240 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 4520 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6 4800 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9 After: min=544 max=11687 count=627 average=1776 95th=4546 90th=3585 50th=1227 mad=565 table=254 avgdepth=21.8 maxdepth=39 value │ ┊ count 540 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 201 800 │▒▒▒▒▒░░░░░░░░░░░░░░░░ 63 1060 │▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░ 68 1320 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░ 39 1580 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 32 1840 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 32 2100 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 34 2360 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 33 2620 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 26 2880 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 22 3140 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9 3400 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8 3660 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9 3920 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8 4180 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8 4440 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8 At the frequency of the host during the bench (~ 3.7 GHz), this is about a 100 ns difference on the median value. A next step would be to collapse local and main tables, as in0ddcf43d5d(ipv4: FIB Local/MAIN table collapse). [1]: https://github.com/vincentbernat/network-lab/blob/master/lab-routes-ipv6/kbench_mod.c Signed-off-by: Vincent Bernat <vincent@bernat.im> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Acked-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									f374771d0f
								
							
						
					
					
						commit
						feca7d8c13
					
				| @ -65,6 +65,7 @@ struct netns_ipv6 { | ||||
| 	unsigned int		 ip6_rt_gc_expire; | ||||
| 	unsigned long		 ip6_rt_last_gc; | ||||
| #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||||
| 	bool			 fib6_has_custom_rules; | ||||
| 	struct rt6_info         *ip6_prohibit_entry; | ||||
| 	struct rt6_info         *ip6_blk_hole_entry; | ||||
| 	struct fib6_table       *fib6_local_tbl; | ||||
|  | ||||
| @ -63,19 +63,32 @@ unsigned int fib6_rules_seq_read(struct net *net) | ||||
| struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6, | ||||
| 				   int flags, pol_lookup_t lookup) | ||||
| { | ||||
| 	struct fib_lookup_arg arg = { | ||||
| 		.lookup_ptr = lookup, | ||||
| 		.flags = FIB_LOOKUP_NOREF, | ||||
| 	}; | ||||
| 	if (net->ipv6.fib6_has_custom_rules) { | ||||
| 		struct fib_lookup_arg arg = { | ||||
| 			.lookup_ptr = lookup, | ||||
| 			.flags = FIB_LOOKUP_NOREF, | ||||
| 		}; | ||||
| 
 | ||||
| 	/* update flow if oif or iif point to device enslaved to l3mdev */ | ||||
| 	l3mdev_update_flow(net, flowi6_to_flowi(fl6)); | ||||
| 		/* update flow if oif or iif point to device enslaved to l3mdev */ | ||||
| 		l3mdev_update_flow(net, flowi6_to_flowi(fl6)); | ||||
| 
 | ||||
| 	fib_rules_lookup(net->ipv6.fib6_rules_ops, | ||||
| 			 flowi6_to_flowi(fl6), flags, &arg); | ||||
| 		fib_rules_lookup(net->ipv6.fib6_rules_ops, | ||||
| 				 flowi6_to_flowi(fl6), flags, &arg); | ||||
| 
 | ||||
| 	if (arg.result) | ||||
| 		return arg.result; | ||||
| 		if (arg.result) | ||||
| 			return arg.result; | ||||
| 	} else { | ||||
| 		struct rt6_info *rt; | ||||
| 
 | ||||
| 		rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, flags); | ||||
| 		if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN) | ||||
| 			return &rt->dst; | ||||
| 		ip6_rt_put(rt); | ||||
| 		rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, flags); | ||||
| 		if (rt->dst.error != -EAGAIN) | ||||
| 			return &rt->dst; | ||||
| 		ip6_rt_put(rt); | ||||
| 	} | ||||
| 
 | ||||
| 	dst_hold(&net->ipv6.ip6_null_entry->dst); | ||||
| 	return &net->ipv6.ip6_null_entry->dst; | ||||
| @ -245,6 +258,7 @@ static int fib6_rule_configure(struct fib_rule *rule, struct sk_buff *skb, | ||||
| 	rule6->dst.plen = frh->dst_len; | ||||
| 	rule6->tclass = frh->tos; | ||||
| 
 | ||||
| 	net->ipv6.fib6_has_custom_rules = true; | ||||
| 	err = 0; | ||||
| errout: | ||||
| 	return err; | ||||
|  | ||||
| @ -3934,6 +3934,7 @@ static int __net_init ip6_route_net_init(struct net *net) | ||||
| 			 ip6_template_metrics, true); | ||||
| 
 | ||||
| #ifdef CONFIG_IPV6_MULTIPLE_TABLES | ||||
| 	net->ipv6.fib6_has_custom_rules = false; | ||||
| 	net->ipv6.ip6_prohibit_entry = kmemdup(&ip6_prohibit_entry_template, | ||||
| 					       sizeof(*net->ipv6.ip6_prohibit_entry), | ||||
| 					       GFP_KERNEL); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user