diff options
author | Neale Ranns <nranns@cisco.com> | 2016-11-16 11:47:44 +0000 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2016-11-17 18:46:20 +0000 |
commit | 0bd36eac4758f785ae9e2c006894b6935f0f70f2 (patch) | |
tree | 227e36c8ef714012699486ea78890ca14d77ddad /vnet/vnet/dpo/load_balance.c | |
parent | 4ee3a65b93282aec6d2016f174529d7ac5e364e1 (diff) |
Fixup Path weights of 0
A path wight of 0 is a meaningless value. We can either reject it and thus expect CLI/API clients to always write a non-zero value, or we can accept it and assume the intent was a weight of 1 - this fix does the latter.
Change-Id: Ide736dbbb8376f85441f5a67388d5e3acad4d34e
Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'vnet/vnet/dpo/load_balance.c')
-rw-r--r-- | vnet/vnet/dpo/load_balance.c | 61 |
1 files changed, 52 insertions, 9 deletions
diff --git a/vnet/vnet/dpo/load_balance.c b/vnet/vnet/dpo/load_balance.c index 8abfc436d67..a244776ffb8 100644 --- a/vnet/vnet/dpo/load_balance.c +++ b/vnet/vnet/dpo/load_balance.c @@ -375,6 +375,19 @@ ip_multipath_normalize_next_hops (load_balance_path_t * raw_next_hops, n_adj_left -= n; error += fabs (nf - n); nhs[i].path_weight = n; + + if (0 == nhs[i].path_weight) + { + /* + * when the weight skew is high (norm is small) and n == nf. + * without this correction the path with a low weight would have + * no represenation in the load-balanace - don't want that. + * If the weight skew is high so the load-balance has many buckets + * to allow it. pays ya money takes ya choice. + */ + error = n_adj; + break; + } } nhs[0].path_weight += n_adj_left; @@ -565,15 +578,45 @@ load_balance_multipath_update (const dpo_id_t *dpo, } else { - /* - * we are not crossing the threshold. we can write the new on the - * old, whether they be inline or not. - */ - load_balance_fill_buckets(lb, nhs, - load_balance_get_buckets(lb), - n_buckets); - CLIB_MEMORY_BARRIER(); - load_balance_set_n_buckets(lb, n_buckets); + if (n_buckets <= LB_NUM_INLINE_BUCKETS) + { + /* + * we are not crossing the threshold and it's still inline buckets. + * we can write the new on the old.. + */ + load_balance_fill_buckets(lb, nhs, + load_balance_get_buckets(lb), + n_buckets); + CLIB_MEMORY_BARRIER(); + load_balance_set_n_buckets(lb, n_buckets); + } + else + { + /* + * we are not crossing the threshold. We need a new bucket array to + * hold the increased number of choices. + */ + dpo_id_t *new_buckets, *old_buckets, *tmp_dpo; + + new_buckets = NULL; + old_buckets = load_balance_get_buckets(lb); + + vec_validate_aligned(new_buckets, + n_buckets - 1, + CLIB_CACHE_LINE_BYTES); + + load_balance_fill_buckets(lb, nhs, new_buckets, n_buckets); + CLIB_MEMORY_BARRIER(); + lb->lb_buckets = new_buckets; + CLIB_MEMORY_BARRIER(); + load_balance_set_n_buckets(lb, n_buckets); + + vec_foreach(tmp_dpo, old_buckets) + { + dpo_reset(tmp_dpo); + } + vec_free(old_buckets); + } } /* |