From c0f4500be160b05416974815bc82fda4f1d2a4ce Mon Sep 17 00:00:00 2001 From: Divakar Date: Fri, 26 Aug 2016 20:09:43 +0530 Subject: [PATCH] Optimise the add_to_tree in mtrie In addition to the changes in https://review.opencontrail.org/#/c/23405/ these changes do the following 1) Update the prefix len in both Bucket and leaf at single place 2) Initialise the invalid Labels to 0xFFFFF. 3) Simplifying the logic of "fin" iterations closes-bug: #1605748 Change-Id: I417dc918a3186dc9e18ef03b75e53465f0f23fc7 --- dp-core/vr_ip_mtrie.c | 103 +++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 62 deletions(-) diff --git a/dp-core/vr_ip_mtrie.c b/dp-core/vr_ip_mtrie.c index ab276473f..e2aaa96fb 100644 --- a/dp-core/vr_ip_mtrie.c +++ b/dp-core/vr_ip_mtrie.c @@ -317,33 +317,34 @@ add_to_tree(struct ip_bucket_entry *ent, int level, struct vr_route_req *rt) struct ip_bucket *bkt; struct mtrie_bkt_info *ip_bkt_info; + if (ent->entry_prefix_len > rt->rtr_req.rtr_prefix_len) + return; + + + ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; + + if (ENTRY_IS_NEXTHOP(ent)) { + /* a less specific entry, which needs to be replaced */ + set_entry_to_nh(ent, rt->rtr_nh); + ent->entry_label_flags = rt->rtr_req.rtr_label_flags; + ent->entry_label = rt->rtr_req.rtr_label; + ent->entry_bridge_index = rt->rtr_req.rtr_index; + + return; + } + if (level >= (ip_bkt_get_max_level(rt->rtr_req.rtr_family) - 1)) - /* assert here ? */ return; ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family); - /* assured that the first one is a bucket */ + /* Assured that this is valid bucket now */ bkt = entry_to_bucket(ent); level++; for (i = 0; i < ip_bkt_info[level].bi_size; i++) { ent = index_to_entry(bkt, i); - - if (ent->entry_prefix_len <= rt->rtr_req.rtr_prefix_len) { - ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; - - if (ENTRY_IS_NEXTHOP(ent)) { - /* a less specific entry, which needs to be replaced */ - set_entry_to_nh(ent, rt->rtr_nh); - ent->entry_label_flags = rt->rtr_req.rtr_label_flags; - ent->entry_label = rt->rtr_req.rtr_label; - ent->entry_bridge_index = rt->rtr_req.rtr_index; - } - } - - if (ENTRY_IS_BUCKET(ent)) - add_to_tree(ent, level, rt); + add_to_tree(ent, level, rt); } return; @@ -390,11 +391,11 @@ mtrie_reset_entry(struct ip_bucket_entry *ent, int level, static int __mtrie_add(struct ip_mtrie *mtrie, struct vr_route_req *rt) { - int ret, index = 0, level, err_level = 0; - unsigned char i, fin = 0; - struct ip_bucket *bkt; - struct ip_bucket_entry *ent, *err_ent = NULL; - struct vr_nexthop *nh, *err_nh = NULL; + int ret, index = 0, level, err_level = 0, fin; + unsigned char i; + struct ip_bucket *bkt; + struct ip_bucket_entry *ent, *err_ent = NULL; + struct vr_nexthop *nh, *err_nh = NULL; struct mtrie_bkt_info *ip_bkt_info = ip_bkt_info_get(rt->rtr_req.rtr_family); ent = &mtrie->root; @@ -432,48 +433,20 @@ __mtrie_add(struct ip_mtrie *mtrie, struct vr_route_req *rt) * cover all the indices for which this route is the best * prefix match */ + + fin = ip_bkt_info[level].bi_size; + if ((rt->rtr_req.rtr_prefix_len > (ip_bkt_info[level].bi_pfx_len - ip_bkt_info[level].bi_bits)) && (rt->rtr_req.rtr_prefix_len <= ip_bkt_info[level].bi_pfx_len)) { fin = 1 << (ip_bkt_info[level].bi_pfx_len - rt->rtr_req.rtr_prefix_len); } - - for (i = index; i <= (ip_bkt_info[level].bi_size-1); i++) { + i = index; + for (; ((i <= (ip_bkt_info[level].bi_size-1)) && fin); + i++, fin--) { ent = index_to_entry(bkt, i); - - if (ent->entry_prefix_len <= rt->rtr_req.rtr_prefix_len) { - ent->entry_prefix_len = rt->rtr_req.rtr_prefix_len; - - if (ENTRY_IS_NEXTHOP(ent)) { - /* a less specific entry, which needs to be replaced */ - set_entry_to_nh(ent, rt->rtr_nh); - ent->entry_label_flags = rt->rtr_req.rtr_label_flags; - ent->entry_label = rt->rtr_req.rtr_label; - ent->entry_bridge_index = rt->rtr_req.rtr_index; - } - } - - if (ENTRY_IS_BUCKET(ent)) - add_to_tree(ent, level, rt); - - /* - * Run through the loop 'fin' times only - * If fin is 0, it actually means 256 ('char' overflow), so run the - * loop 256 times - */ - if (fin) { - fin--; - if (fin == 0) - break; - } - - /* - * Bailout at the last index, - * the below check takes care of overflow - */ - if (i == (ip_bkt_info[level].bi_size-1)) - break; + add_to_tree(ent, level, rt); } break; @@ -760,8 +733,11 @@ mtrie_delete(struct vr_rtable * _unused, struct vr_route_req *rt) rt->rtr_req.rtr_index = lreq.rtr_req.rtr_index; } - if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) - rt->rtr_req.rtr_label = -1; + if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) { + rt->rtr_req.rtr_label = 0xFFFFF; + } else { + rt->rtr_req.rtr_label &= 0xFFFFF; + } __mtrie_delete(rt, &rtable->root, 0); vrouter_put_nexthop(rt->rtr_nh); @@ -1053,8 +1029,11 @@ mtrie_add(struct vr_rtable * _unused, struct vr_route_req *rt) rt->rtr_req.rtr_index = tmp_req.rtr_req.rtr_index; } - if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) - rt->rtr_req.rtr_label = -1; + if (!(rt->rtr_req.rtr_label_flags & VR_RT_LABEL_VALID_FLAG)) { + rt->rtr_req.rtr_label = 0xFFFFF; + } else { + rt->rtr_req.rtr_label &= 0xFFFFF; + } ret = __mtrie_add(mtrie, rt); vrouter_put_nexthop(rt->rtr_nh); @@ -1111,7 +1090,7 @@ mtrie_alloc_vrf(unsigned int vrf_id, unsigned int family) mtrie->root.entry_bridge_index = VR_BE_INVALID_INDEX; mtrie_table = vn_rtable[index]; mtrie_table[vrf_id] = mtrie; - mtrie->root.entry_label = -1; + mtrie->root.entry_label = 0xFFFFF; } return mtrie;