Skip to content

Commit

Permalink
Optimise the add_to_tree in mtrie
Browse files Browse the repository at this point in the history
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
  • Loading branch information
divakardhar committed Aug 30, 2016
1 parent f2f19eb commit c0f4500
Showing 1 changed file with 41 additions and 62 deletions.
103 changes: 41 additions & 62 deletions dp-core/vr_ip_mtrie.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit c0f4500

Please sign in to comment.