aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/dpo/load_balance_map.c
diff options
context:
space:
mode:
authorDamjan Marion <damarion@cisco.com>2016-12-19 23:05:39 +0100
committerDamjan Marion <damarion@cisco.com>2016-12-28 12:25:14 +0100
commit7cd468a3d7dee7d6c92f69a0bb7061ae208ec727 (patch)
tree5de62f8dbd3a752f5a676ca600e43d2652d1ff1a /vnet/vnet/dpo/load_balance_map.c
parent696f1adec0df3b8f161862566dd9c86174302658 (diff)
Reorganize source tree to use single autotools instance
Change-Id: I7b51f88292e057c6443b12224486f2d0c9f8ae23 Signed-off-by: Damjan Marion <damarion@cisco.com>
Diffstat (limited to 'vnet/vnet/dpo/load_balance_map.c')
-rw-r--r--vnet/vnet/dpo/load_balance_map.c575
1 files changed, 0 insertions, 575 deletions
diff --git a/vnet/vnet/dpo/load_balance_map.c b/vnet/vnet/dpo/load_balance_map.c
deleted file mode 100644
index 70ce1bf7c39..00000000000
--- a/vnet/vnet/dpo/load_balance_map.c
+++ /dev/null
@@ -1,575 +0,0 @@
-/*
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @brief
- */
-#include <vnet/fib/fib_path.h>
-#include <vnet/fib/fib_node_list.h>
-#include <vnet/dpo/load_balance_map.h>
-#include <vnet/dpo/load_balance.h>
-
-/**
- * A hash-table of load-balance maps by path index.
- * this provides the fast lookup of the LB map when a path goes down
- */
-static uword *lb_maps_by_path_index;
-
-/**
- * A hash-table of load-balance maps by set of paths.
- * This provides the LB map sharing.
- * LB maps do not necessarily use all the paths in the list, since
- * the entry that is requesting the map, may not have an out-going
- * label for each of the paths.
- */
-static uword *load_balance_map_db;
-
-typedef enum load_balance_map_path_flags_t_
-{
- LOAD_BALANCE_MAP_PATH_UP = (1 << 0),
- LOAD_BALANCE_MAP_PATH_USABLE = (1 << 1),
-} __attribute__ ((packed)) load_balance_map_path_flags_t;
-
-typedef struct load_balance_map_path_t_ {
- /**
- * Index of the path
- */
- fib_node_index_t lbmp_index;
-
- /**
- * Sibling Index in the list of all maps with this path index
- */
- fib_node_index_t lbmp_sibling;
-
- /**
- * the normalised wegiht of the path
- */
- u32 lbmp_weight;
-
- /**
- * The sate of the path
- */
- load_balance_map_path_flags_t lbmp_flags;
-} load_balance_map_path_t;
-
-/**
- * The global pool of LB maps
- */
-load_balance_map_t *load_balance_map_pool;
-
-/*
- * Debug macro
- */
-#ifdef FIB_DEBUG
-#define LOAD_BALANCE_MAP_DBG(_pl, _fmt, _args...) \
- { \
- clib_warning("lbm: FIXME" _fmt, \
- ##_args); \
- }
-#else
-#define LOAD_BALANCE_MAP_DBG(_pl, _fmt, _args...)
-#endif
-
-static index_t
-load_balance_map_get_index (load_balance_map_t *lbm)
-{
- return (lbm - load_balance_map_pool);
-}
-
-u8*
-format_load_balance_map (u8 *s, va_list ap)
-{
- index_t lbmi = va_arg(ap, index_t);
- u32 indent = va_arg(ap, u32);
- load_balance_map_t *lbm;
- u32 n_buckets, ii;
-
- lbm = load_balance_map_get(lbmi);
- n_buckets = vec_len(lbm->lbm_buckets);
-
- s = format(s, "load-balance-map: index:%d buckets:%d", lbmi, n_buckets);
- s = format(s, "\n%U index:", format_white_space, indent+2);
- for (ii = 0; ii < n_buckets; ii++)
- {
- s = format(s, "%5d", ii);
- }
- s = format(s, "\n%U map:", format_white_space, indent+2);
- for (ii = 0; ii < n_buckets; ii++)
- {
- s = format(s, "%5d", lbm->lbm_buckets[ii]);
- }
-
- return (s);
-}
-
-
-static uword
-load_balance_map_hash (load_balance_map_t *lbm)
-{
- u32 old_lbm_hash, new_lbm_hash, hash;
- load_balance_map_path_t *lb_path;
-
- new_lbm_hash = old_lbm_hash = vec_len(lbm->lbm_paths);
-
- vec_foreach (lb_path, lbm->lbm_paths)
- {
- hash = lb_path->lbmp_index;
- hash_mix32(hash, old_lbm_hash, new_lbm_hash);
- }
-
- return (new_lbm_hash);
-}
-
-always_inline uword
-load_balance_map_db_hash_key_from_index (uword index)
-{
- return 1 + 2*index;
-}
-
-always_inline uword
-load_balance_map_db_hash_key_is_index (uword key)
-{
- return key & 1;
-}
-
-always_inline uword
-load_balance_map_db_hash_key_2_index (uword key)
-{
- ASSERT (load_balance_map_db_hash_key_is_index (key));
- return key / 2;
-}
-
-static load_balance_map_t*
-load_balance_map_db_get_from_hash_key (uword key)
-{
- load_balance_map_t *lbm;
-
- if (load_balance_map_db_hash_key_is_index (key))
- {
- index_t lbm_index;
-
- lbm_index = load_balance_map_db_hash_key_2_index(key);
- lbm = load_balance_map_get(lbm_index);
- }
- else
- {
- lbm = uword_to_pointer (key, load_balance_map_t *);
- }
-
- return (lbm);
-}
-
-static uword
-load_balance_map_db_hash_key_sum (hash_t * h,
- uword key)
-{
- load_balance_map_t *lbm;
-
- lbm = load_balance_map_db_get_from_hash_key(key);
-
- return (load_balance_map_hash(lbm));
-}
-
-static uword
-load_balance_map_db_hash_key_equal (hash_t * h,
- uword key1,
- uword key2)
-{
- load_balance_map_t *lbm1, *lbm2;
-
- lbm1 = load_balance_map_db_get_from_hash_key(key1);
- lbm2 = load_balance_map_db_get_from_hash_key(key2);
-
- return (load_balance_map_hash(lbm1) ==
- load_balance_map_hash(lbm2));
-}
-
-static index_t
-load_balance_map_db_find (load_balance_map_t *lbm)
-{
- uword *p;
-
- p = hash_get(load_balance_map_db, lbm);
-
- if (NULL != p)
- {
- return p[0];
- }
-
- return (FIB_NODE_INDEX_INVALID);
-}
-
-static void
-load_balance_map_db_insert (load_balance_map_t *lbm)
-{
- load_balance_map_path_t *lbmp;
- fib_node_list_t list;
- uword *p;
-
- ASSERT(FIB_NODE_INDEX_INVALID == load_balance_map_db_find(lbm));
-
- /*
- * insert into the DB based on the set of paths.
- */
- hash_set (load_balance_map_db,
- load_balance_map_db_hash_key_from_index(
- load_balance_map_get_index(lbm)),
- load_balance_map_get_index(lbm));
-
- /*
- * insert into each per-path list.
- */
- vec_foreach(lbmp, lbm->lbm_paths)
- {
- p = hash_get(lb_maps_by_path_index, lbmp->lbmp_index);
-
- if (NULL == p)
- {
- list = fib_node_list_create();
- hash_set(lb_maps_by_path_index, lbmp->lbmp_index, list);
- }
- else
- {
- list = p[0];
- }
-
- lbmp->lbmp_sibling =
- fib_node_list_push_front(list,
- 0, FIB_NODE_TYPE_FIRST,
- load_balance_map_get_index(lbm));
- }
-
- LOAD_BALANCE_MAP_DBG(lbm, "DB-inserted");
-}
-
-static void
-load_balance_map_db_remove (load_balance_map_t *lbm)
-{
- load_balance_map_path_t *lbmp;
- uword *p;
-
- ASSERT(FIB_NODE_INDEX_INVALID != load_balance_map_db_find(lbm));
-
- hash_unset(load_balance_map_db,
- load_balance_map_db_hash_key_from_index(
- load_balance_map_get_index(lbm)));
-
- /*
- * remove from each per-path list.
- */
- vec_foreach(lbmp, lbm->lbm_paths)
- {
- p = hash_get(lb_maps_by_path_index, lbmp->lbmp_index);
-
- ASSERT(NULL != p);
-
- fib_node_list_remove(p[0], lbmp->lbmp_sibling);
- }
-
- LOAD_BALANCE_MAP_DBG(lbm, "DB-removed");
-}
-
-/**
- * @brief from the paths that are usable, fill the Map.
- */
-static void
-load_balance_map_fill (load_balance_map_t *lbm)
-{
- load_balance_map_path_t *lbmp;
- u32 n_buckets, bucket, ii, jj;
- u16 *tmp_buckets;
-
- tmp_buckets = NULL;
- n_buckets = vec_len(lbm->lbm_buckets);
-
- /*
- * run throught the set of paths once, and build a vector of the
- * indices that are usable. we do this is a scratch space, since we
- * need to refer to it multiple times as we build the real buckets.
- */
- vec_validate(tmp_buckets, n_buckets-1);
-
- bucket = jj = 0;
- vec_foreach (lbmp, lbm->lbm_paths)
- {
- if (fib_path_is_resolved(lbmp->lbmp_index))
- {
- for (ii = 0; ii < lbmp->lbmp_weight; ii++)
- {
- tmp_buckets[jj++] = bucket++;
- }
- }
- else
- {
- bucket += lbmp->lbmp_weight;
- }
- }
- _vec_len(tmp_buckets) = jj;
-
- /*
- * If the number of temporaries written is as many as we need, implying
- * all paths were up, then we can simply copy the scratch area over the
- * actual buckets' memory
- */
- if (jj == n_buckets)
- {
- memcpy(lbm->lbm_buckets,
- tmp_buckets,
- sizeof(lbm->lbm_buckets[0]) * n_buckets);
- }
- else
- {
- /*
- * one or more paths are down.
- */
- if (0 == vec_len(tmp_buckets))
- {
- /*
- * if the scratch area is empty, then no paths are usable.
- * they will all drop. so use them all, lest we account drops
- * against only one.
- */
- for (bucket = 0; bucket < n_buckets; bucket++)
- {
- lbm->lbm_buckets[bucket] = bucket;
- }
- }
- else
- {
- bucket = jj = 0;
- vec_foreach (lbmp, lbm->lbm_paths)
- {
- if (fib_path_is_resolved(lbmp->lbmp_index))
- {
- for (ii = 0; ii < lbmp->lbmp_weight; ii++)
- {
- lbm->lbm_buckets[bucket] = bucket;
- bucket++;
- }
- }
- else
- {
- /*
- * path is unusable
- * cycle through the scratch space selecting a index.
- * this means we load balance, in the intended ratio,
- * over the paths that are still usable.
- */
- for (ii = 0; ii < lbmp->lbmp_weight; ii++)
- {
- lbm->lbm_buckets[bucket] = tmp_buckets[jj];
- jj = (jj + 1) % vec_len(tmp_buckets);
- bucket++;
- }
- }
- }
- }
- }
-
- vec_free(tmp_buckets);
-}
-
-static load_balance_map_t*
-load_balance_map_alloc (const load_balance_path_t *paths)
-{
- load_balance_map_t *lbm;
- u32 ii;
-
- pool_get_aligned(load_balance_map_pool, lbm, CLIB_CACHE_LINE_BYTES);
- memset(lbm, 0, sizeof(*lbm));
-
- vec_validate(lbm->lbm_paths, vec_len(paths)-1);
-
- vec_foreach_index(ii, paths)
- {
- lbm->lbm_paths[ii].lbmp_index = paths[ii].path_index;
- lbm->lbm_paths[ii].lbmp_weight = paths[ii].path_weight;
- }
-
- return (lbm);
-}
-
-static load_balance_map_t *
-load_balance_map_init (load_balance_map_t *lbm,
- u32 n_buckets,
- u32 sum_of_weights)
-{
- lbm->lbm_sum_of_norm_weights = sum_of_weights;
- vec_validate(lbm->lbm_buckets, n_buckets-1);
-
- load_balance_map_db_insert(lbm);
-
- load_balance_map_fill(lbm);
-
- return (lbm);
-}
-
-index_t
-load_balance_map_add_or_lock (u32 n_buckets,
- u32 sum_of_weights,
- const load_balance_path_t *paths)
-{
- load_balance_map_t *tmp, *lbm;
- index_t lbmi;
-
- tmp = load_balance_map_alloc(paths);
-
- lbmi = load_balance_map_db_find(tmp);
-
- if (INDEX_INVALID == lbmi)
- {
- lbm = load_balance_map_init(tmp, n_buckets, sum_of_weights);
- }
- else
- {
- lbm = load_balance_map_get(lbmi);
- }
-
- lbm->lbm_locks++;
-
- return (load_balance_map_get_index(lbm));
-}
-
-void
-load_balance_map_lock (index_t lbmi)
-{
- load_balance_map_t *lbm;
-
- lbm = load_balance_map_get(lbmi);
-
- lbm->lbm_locks++;
-}
-
-void
-load_balance_map_unlock (index_t lbmi)
-{
- load_balance_map_t *lbm;
-
- if (INDEX_INVALID == lbmi)
- {
- return;
- }
-
- lbm = load_balance_map_get(lbmi);
-
- lbm->lbm_locks--;
-
- if (0 == lbm->lbm_locks)
- {
- load_balance_map_db_remove(lbm);
- vec_free(lbm->lbm_paths);
- vec_free(lbm->lbm_buckets);
- pool_put(load_balance_map_pool, lbm);
- }
-}
-
-static int
-load_balance_map_path_state_change_walk (fib_node_ptr_t *fptr,
- void *ctx)
-{
- load_balance_map_t *lbm;
-
- lbm = load_balance_map_get(fptr->fnp_index);
-
- load_balance_map_fill(lbm);
-
- return (!0);
-}
-
-/**
- * @brief the state of a path has changed (it has no doubt gone down).
- * This is the trigger to perform a PIC edge cutover and update the maps
- * to exclude this path.
- */
-void
-load_balance_map_path_state_change (fib_node_index_t path_index)
-{
- uword *p;
-
- /*
- * re-stripe the buckets for each affect MAP
- */
- p = hash_get(lb_maps_by_path_index, path_index);
-
- if (NULL == p)
- return;
-
- fib_node_list_walk(p[0], load_balance_map_path_state_change_walk, NULL);
-}
-
-/**
- * @brief Make/add a new or lock an existing Load-balance map
- */
-void
-load_balance_map_module_init (void)
-{
- load_balance_map_db =
- hash_create2 (/* elts */ 0,
- /* user */ 0,
- /* value_bytes */ sizeof (index_t),
- load_balance_map_db_hash_key_sum,
- load_balance_map_db_hash_key_equal,
- /* format pair/arg */
- 0, 0);
-
- lb_maps_by_path_index = hash_create(0, sizeof(fib_node_list_t));
-}
-
-void
-load_balance_map_show_mem (void)
-{
- fib_show_memory_usage("Load-Balance Map",
- pool_elts(load_balance_map_pool),
- pool_len(load_balance_map_pool),
- sizeof(load_balance_map_t));
-}
-
-static clib_error_t *
-load_balance_map_show (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- index_t lbmi = INDEX_INVALID;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "%d", &lbmi))
- ;
- else
- break;
- }
-
- if (INDEX_INVALID != lbmi)
- {
- vlib_cli_output (vm, "%U", format_load_balance_map, lbmi, 0);
- }
- else
- {
- load_balance_map_t *lbm;
-
- pool_foreach(lbm, load_balance_map_pool,
- ({
- vlib_cli_output (vm, "%U", format_load_balance_map,
- load_balance_map_get_index(lbm), 0);
- }));
- }
-
- return 0;
-}
-
-VLIB_CLI_COMMAND (load_balance_map_show_command, static) = {
- .path = "show load-balance-map",
- .short_help = "show load-balance-map [<index>]",
- .function = load_balance_map_show,
-};