ipv4: Inline fib_semantic_match into check_leaf
This elimiates a lot of pure overhead due to parameter passing. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									4c8237cd76
								
							
						
					
					
						commit
						3be0686b6e
					
				| @ -51,4 +51,11 @@ static inline void fib_result_assign(struct fib_result *res, | ||||
| 	res->fi = fi; | ||||
| } | ||||
| 
 | ||||
| struct fib_prop { | ||||
| 	int	error; | ||||
| 	u8	scope; | ||||
| }; | ||||
| 
 | ||||
| extern const struct fib_prop fib_props[RTN_MAX + 1]; | ||||
| 
 | ||||
| #endif /* _FIB_LOOKUP_H */ | ||||
|  | ||||
| @ -90,11 +90,7 @@ static DEFINE_SPINLOCK(fib_multipath_lock); | ||||
| #define endfor_nexthops(fi) } | ||||
| 
 | ||||
| 
 | ||||
| static const struct | ||||
| { | ||||
| 	int	error; | ||||
| 	u8	scope; | ||||
| } fib_props[RTN_MAX + 1] = { | ||||
| const struct fib_prop fib_props[RTN_MAX + 1] = { | ||||
| 	[RTN_UNSPEC] = { | ||||
| 		.error	= 0, | ||||
| 		.scope	= RT_SCOPE_NOWHERE, | ||||
| @ -902,68 +898,6 @@ failure: | ||||
| 	return ERR_PTR(err); | ||||
| } | ||||
| 
 | ||||
| /* Note! fib_semantic_match intentionally uses  RCU list functions. */ | ||||
| int fib_semantic_match(struct fib_table *tb, struct list_head *head, | ||||
| 		       const struct flowi *flp, struct fib_result *res, | ||||
| 		       int prefixlen, int fib_flags) | ||||
| { | ||||
| 	struct fib_alias *fa; | ||||
| 	int nh_sel = 0; | ||||
| 
 | ||||
| 	list_for_each_entry_rcu(fa, head, fa_list) { | ||||
| 		int err; | ||||
| 
 | ||||
| 		if (fa->fa_tos && | ||||
| 		    fa->fa_tos != flp->fl4_tos) | ||||
| 			continue; | ||||
| 
 | ||||
| 		if (fa->fa_scope < flp->fl4_scope) | ||||
| 			continue; | ||||
| 
 | ||||
| 		fib_alias_accessed(fa); | ||||
| 
 | ||||
| 		err = fib_props[fa->fa_type].error; | ||||
| 		if (err == 0) { | ||||
| 			struct fib_info *fi = fa->fa_info; | ||||
| 
 | ||||
| 			if (fi->fib_flags & RTNH_F_DEAD) | ||||
| 				continue; | ||||
| 
 | ||||
| 			for_nexthops(fi) { | ||||
| 				if (nh->nh_flags & RTNH_F_DEAD) | ||||
| 					continue; | ||||
| 				if (!flp->oif || flp->oif == nh->nh_oif) | ||||
| 					break; | ||||
| 			} | ||||
| #ifdef CONFIG_IP_ROUTE_MULTIPATH | ||||
| 			if (nhsel < fi->fib_nhs) { | ||||
| 				nh_sel = nhsel; | ||||
| 				goto out_fill_res; | ||||
| 			} | ||||
| #else | ||||
| 			if (nhsel < 1) | ||||
| 				goto out_fill_res; | ||||
| #endif | ||||
| 			endfor_nexthops(fi); | ||||
| 			continue; | ||||
| 		} | ||||
| 		return err; | ||||
| 	} | ||||
| 	return 1; | ||||
| 
 | ||||
| out_fill_res: | ||||
| 	res->prefixlen = prefixlen; | ||||
| 	res->nh_sel = nh_sel; | ||||
| 	res->type = fa->fa_type; | ||||
| 	res->scope = fa->fa_scope; | ||||
| 	res->fi = fa->fa_info; | ||||
| 	res->table = tb; | ||||
| 	res->fa_head = head; | ||||
| 	if (!(fib_flags & FIB_LOOKUP_NOREF)) | ||||
| 		atomic_inc(&res->fi->fib_clntref); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| /* Find appropriate source address to this destination */ | ||||
| 
 | ||||
| __be32 __fib_res_prefsrc(struct fib_result *res) | ||||
|  | ||||
| @ -1349,23 +1349,58 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l, | ||||
| 	struct hlist_node *node; | ||||
| 
 | ||||
| 	hlist_for_each_entry_rcu(li, node, hhead, hlist) { | ||||
| 		int err; | ||||
| 		struct fib_alias *fa; | ||||
| 		int plen = li->plen; | ||||
| 		__be32 mask = inet_make_mask(plen); | ||||
| 
 | ||||
| 		if (l->key != (key & ntohl(mask))) | ||||
| 			continue; | ||||
| 
 | ||||
| 		err = fib_semantic_match(tb, &li->falh, flp, res, plen, fib_flags); | ||||
| 		list_for_each_entry_rcu(fa, &li->falh, fa_list) { | ||||
| 			struct fib_info *fi = fa->fa_info; | ||||
| 			int nhsel, err; | ||||
| 
 | ||||
| 			if (fa->fa_tos && fa->fa_tos != flp->fl4_tos) | ||||
| 				continue; | ||||
| 			if (fa->fa_scope < flp->fl4_scope) | ||||
| 				continue; | ||||
| 			fib_alias_accessed(fa); | ||||
| 			err = fib_props[fa->fa_type].error; | ||||
| 			if (err) { | ||||
| #ifdef CONFIG_IP_FIB_TRIE_STATS | ||||
| 				t->stats.semantic_match_miss++; | ||||
| #endif | ||||
| 				return 1; | ||||
| 			} | ||||
| 			if (fi->fib_flags & RTNH_F_DEAD) | ||||
| 				continue; | ||||
| 			for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) { | ||||
| 				const struct fib_nh *nh = &fi->fib_nh[nhsel]; | ||||
| 
 | ||||
| 				if (nh->nh_flags & RTNH_F_DEAD) | ||||
| 					continue; | ||||
| 				if (flp->oif && flp->oif != nh->nh_oif) | ||||
| 					continue; | ||||
| 
 | ||||
| #ifdef CONFIG_IP_FIB_TRIE_STATS | ||||
| 		if (err <= 0) | ||||
| 			t->stats.semantic_match_passed++; | ||||
| 		else | ||||
| 			t->stats.semantic_match_miss++; | ||||
| 				t->stats.semantic_match_passed++; | ||||
| #endif | ||||
| 				res->prefixlen = plen; | ||||
| 				res->nh_sel = nhsel; | ||||
| 				res->type = fa->fa_type; | ||||
| 				res->scope = fa->fa_scope; | ||||
| 				res->fi = fi; | ||||
| 				res->table = tb; | ||||
| 				res->fa_head = &li->falh; | ||||
| 				if (!(fib_flags & FIB_LOOKUP_NOREF)) | ||||
| 					atomic_inc(&res->fi->fib_clntref); | ||||
| 				return 0; | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| #ifdef CONFIG_IP_FIB_TRIE_STATS | ||||
| 		t->stats.semantic_match_miss++; | ||||
| #endif | ||||
| 		if (err <= 0) | ||||
| 			return err; | ||||
| 	} | ||||
| 
 | ||||
| 	return 1; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user