diff options
author | Luca Muscariello <lumuscar@cisco.com> | 2022-06-30 13:58:25 +0200 |
---|---|---|
committer | Mauro Sardara <msardara@cisco.com> | 2022-07-01 12:11:33 +0200 |
commit | 012843b1c0bc0838e69085ed83a79ec8b6f97360 (patch) | |
tree | 4fa320673884488e4a1bf879ec144e99f134a3fb /hicn-plugin/src/cache_policies | |
parent | 6b94663b2455e212009a544ae23bb6a8c55407f8 (diff) |
Revision and refactor of the VPP plugin with fixes for the
packet generator. Hash table for the packet cache has been
changed with the bihash.
Co-authored-by: Mauro Sardara <msardara@cisco.com>
Signed-off-by: Luca Muscariello <muscariello@ieee.org>
Change-Id: I0e0191a9f109d37081d32cc55d577ea43533f8c0
Signed-off-by: Mauro Sardara <msardara@cisco.com>
Diffstat (limited to 'hicn-plugin/src/cache_policies')
-rw-r--r-- | hicn-plugin/src/cache_policies/cs_lru.c | 204 | ||||
-rw-r--r-- | hicn-plugin/src/cache_policies/cs_lru.h | 40 | ||||
-rw-r--r-- | hicn-plugin/src/cache_policies/cs_policy.h | 184 |
3 files changed, 248 insertions, 180 deletions
diff --git a/hicn-plugin/src/cache_policies/cs_lru.c b/hicn-plugin/src/cache_policies/cs_lru.c index e65f487e1..07c4916fb 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.c +++ b/hicn-plugin/src/cache_policies/cs_lru.c @@ -13,7 +13,6 @@ * limitations under the License. */ -#include "../hashtb.h" #include "../strategy_dpo_manager.h" #include "../error.h" #include "cs_lru.h" @@ -32,129 +31,112 @@ hicn_cs_policy_vft_t hicn_cs_lru = { * Insert a new CS element at the head of the CS LRU */ void -hicn_cs_lru_insert (hicn_pit_cs_t *p, hicn_hash_node_t *node, - hicn_pcs_entry_t *pcs, hicn_cs_policy_t *policy_state) +hicn_cs_lru_insert (hicn_cs_policy_t *lru_policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) { - hicn_hash_node_t *lrunode; hicn_pcs_entry_t *lrupcs; u32 idx; - idx = hicn_hashtb_node_idx_from_node (p->pcs_table, node); + idx = hicn_pcs_entry_get_index (pcs, pcs_entry); - if (policy_state->head != 0) + if (lru_policy->head != HICN_CS_POLICY_END_OF_CHAIN) { - lrunode = hicn_hashtb_node_from_idx (p->pcs_table, policy_state->head); - lrupcs = hicn_pit_get_data (lrunode); + lrupcs = hicn_pcs_entry_get_entry_from_index (pcs, lru_policy->head); - ASSERT (lrupcs->u.cs.cs_lru_prev == 0); + ASSERT (lrupcs->u.cs.cs_lru_prev == HICN_CS_POLICY_END_OF_CHAIN); lrupcs->u.cs.cs_lru_prev = idx; - pcs->u.cs.cs_lru_prev = 0; - pcs->u.cs.cs_lru_next = policy_state->head; + pcs_entry->u.cs.cs_lru_prev = HICN_CS_POLICY_END_OF_CHAIN; + pcs_entry->u.cs.cs_lru_next = lru_policy->head; - policy_state->head = idx; + lru_policy->head = idx; } else { - ASSERT (policy_state->tail == 0); /* We think the list is - * empty */ + // The list should be empty + ASSERT (lru_policy->tail == HICN_CS_POLICY_END_OF_CHAIN); - policy_state->head = policy_state->tail = idx; + lru_policy->head = lru_policy->tail = idx; - pcs->u.cs.cs_lru_next = pcs->u.cs.cs_lru_prev = 0; + pcs_entry->u.cs.cs_lru_next = pcs_entry->u.cs.cs_lru_prev = + HICN_CS_POLICY_END_OF_CHAIN; } - policy_state->count++; + lru_policy->count++; } void -hicn_cs_lru_delete_get (hicn_pit_cs_t *p, hicn_cs_policy_t *policy_state, - hicn_hash_node_t **nodep, hicn_pcs_entry_t **pcs_entry, - hicn_hash_entry_t **hash_entry) +hicn_cs_lru_delete_get (hicn_cs_policy_t *lru_policy, const hicn_pit_cs_t *pcs, + hicn_pcs_entry_t **pcs_entry) { - *nodep = hicn_hashtb_node_from_idx (p->pcs_table, policy_state->tail); - *pcs_entry = hicn_pit_get_data (*nodep); - - *hash_entry = hicn_hashtb_get_entry ( - p->pcs_table, (*nodep)->entry_idx, (*nodep)->bucket_id, - (*nodep)->hn_flags & HICN_HASH_NODE_OVERFLOW_BUCKET); + *pcs_entry = hicn_pcs_entry_get_entry_from_index (pcs, lru_policy->tail); } /* * Dequeue an LRU element, for example when it has expired. */ void -hicn_cs_lru_dequeue (hicn_pit_cs_t *pit, hicn_hash_node_t *pnode, - hicn_pcs_entry_t *pcs, hicn_cs_policy_t *lru) +hicn_cs_lru_dequeue (hicn_cs_policy_t *lru_policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) { - hicn_hash_node_t *lrunode; hicn_pcs_entry_t *lrupcs; - if (pcs->u.cs.cs_lru_prev != 0) + if (pcs_entry->u.cs.cs_lru_prev != HICN_CS_POLICY_END_OF_CHAIN) { /* Not already on the head of the LRU */ - lrunode = - hicn_hashtb_node_from_idx (pit->pcs_table, pcs->u.cs.cs_lru_prev); - lrupcs = hicn_pit_get_data (lrunode); + lrupcs = + hicn_pcs_entry_get_entry_from_index (pcs, pcs_entry->u.cs.cs_lru_prev); - lrupcs->u.cs.cs_lru_next = pcs->u.cs.cs_lru_next; + lrupcs->u.cs.cs_lru_next = pcs_entry->u.cs.cs_lru_next; } else { - ASSERT (lru->head == - hicn_hashtb_node_idx_from_node (pit->pcs_table, pnode)); - lru->head = pcs->u.cs.cs_lru_next; + ASSERT (lru_policy->head == hicn_pcs_entry_get_index (pcs, pcs_entry)); + lru_policy->head = pcs_entry->u.cs.cs_lru_next; } - if (pcs->u.cs.cs_lru_next != 0) + if (pcs_entry->u.cs.cs_lru_next != HICN_CS_POLICY_END_OF_CHAIN) { /* Not already the end of the LRU */ - lrunode = - hicn_hashtb_node_from_idx (pit->pcs_table, pcs->u.cs.cs_lru_next); - lrupcs = hicn_pit_get_data (lrunode); + lrupcs = + hicn_pcs_entry_get_entry_from_index (pcs, pcs_entry->u.cs.cs_lru_next); - lrupcs->u.cs.cs_lru_prev = pcs->u.cs.cs_lru_prev; + lrupcs->u.cs.cs_lru_prev = pcs_entry->u.cs.cs_lru_prev; } else { /* This was the last LRU element */ - ASSERT (lru->tail == - hicn_hashtb_node_idx_from_node (pit->pcs_table, pnode)); - lru->tail = pcs->u.cs.cs_lru_prev; + ASSERT (lru_policy->tail == hicn_pcs_entry_get_index (pcs, pcs_entry)); + lru_policy->tail = pcs_entry->u.cs.cs_lru_prev; } - pcs->u.cs.cs_lru_next = pcs->u.cs.cs_lru_prev = 0; - lru->count--; + pcs_entry->u.cs.cs_lru_next = pcs_entry->u.cs.cs_lru_prev = + HICN_CS_POLICY_END_OF_CHAIN; + lru_policy->count--; } /* - * Move a CS LRU element to the head, probably after it's been used. + * Move a CS LRU element to the head. The element must be part of the LRU list. */ void -hicn_cs_lru_update_head (hicn_pit_cs_t *pit, hicn_hash_node_t *pnode, - hicn_pcs_entry_t *pcs, hicn_cs_policy_t *lru) +hicn_cs_lru_update_head (hicn_cs_policy_t *lru_policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) { - if (pcs->u.cs.cs_lru_prev != 0) + if (pcs_entry->u.cs.cs_lru_prev != HICN_CS_POLICY_END_OF_CHAIN) { /* * Not already on the head of the LRU, detach it from its * current position */ - hicn_cs_lru_dequeue (pit, pnode, pcs, lru); + hicn_cs_lru_dequeue (lru_policy, pcs, pcs_entry); /* Now detached from the list; attach at head */ - hicn_cs_lru_insert (pit, pnode, pcs, lru); + hicn_cs_lru_insert (lru_policy, pcs, pcs_entry); } else { - /* The element is already dequeue */ - if (pcs->u.cs.cs_lru_next == 0) - { - /* Now detached from the list; attach at head */ - hicn_cs_lru_insert (pit, pnode, pcs, lru); - } - ASSERT (lru->head == - hicn_hashtb_node_idx_from_node (pit->pcs_table, pnode)); + // The element must be already at the head of the LRU + ASSERT (lru_policy->head == hicn_pcs_entry_get_index (pcs, pcs_entry)); } } @@ -164,96 +146,86 @@ hicn_cs_lru_update_head (hicn_pit_cs_t *pit, hicn_hash_node_t *pnode, * CS's limit. Return the number of removed nodes. */ int -hicn_cs_lru_trim (hicn_pit_cs_t *pit, u32 *node_list, int sz, - hicn_cs_policy_t *lru) +hicn_cs_lru_trim (hicn_cs_policy_t *lru_policy, hicn_pit_cs_t *pcs, + u32 *node_list, size_t sz) { - hicn_hash_node_t *lrunode; hicn_pcs_entry_t *lrupcs; u32 idx; int i; - idx = lru->tail; + idx = lru_policy->tail; - for (i = 0; i < sz; i++) + for (i = 0; i < sz && idx > 0; i++) { - - if (idx == 0) - { - break; - } - lrunode = hicn_hashtb_node_from_idx (pit->pcs_table, idx); - lrupcs = hicn_pit_get_data (lrunode); + lrupcs = hicn_pcs_entry_get_entry_from_index (pcs, idx); node_list[i] = idx; idx = lrupcs->u.cs.cs_lru_prev; - lrupcs->u.cs.cs_lru_prev = 0; - lrupcs->u.cs.cs_lru_next = 0; + lrupcs->u.cs.cs_lru_prev = HICN_CS_POLICY_END_OF_CHAIN; + lrupcs->u.cs.cs_lru_next = HICN_CS_POLICY_END_OF_CHAIN; } - lru->count -= i; + lru_policy->count -= i; + lru_policy->tail = idx; - lru->tail = idx; - if (idx != 0) + if (idx != HICN_CS_POLICY_END_OF_CHAIN) { - lrunode = hicn_hashtb_node_from_idx (pit->pcs_table, idx); - lrupcs = hicn_pit_get_data (lrunode); - - lrupcs->u.cs.cs_lru_next = 0; + lrupcs = hicn_pcs_entry_get_entry_from_index (pcs, idx); + lrupcs->u.cs.cs_lru_next = HICN_CS_POLICY_END_OF_CHAIN; } else { /* If the tail is empty, the whole lru is empty */ - lru->head = 0; + lru_policy->head = HICN_CS_POLICY_END_OF_CHAIN; } - return (i); + return i; } int -hicn_cs_lru_flush (vlib_main_t *vm, struct hicn_pit_cs_s *pitcs, - hicn_cs_policy_t *state) +hicn_cs_lru_flush (hicn_cs_policy_t *lru_policy, hicn_pit_cs_t *pcs) { - if (state->head == 0 && state->tail == 0) + if (lru_policy->head == HICN_CS_POLICY_END_OF_CHAIN && + lru_policy->tail == HICN_CS_POLICY_END_OF_CHAIN) return 0; - hicn_hash_node_t *lrunode; - hicn_pcs_entry_t *lrupcs; + hicn_pcs_entry_t *pcs_entry; u32 idx; int i = 0; - idx = state->tail; + idx = lru_policy->tail; - while (idx != 0) + while (idx != HICN_CS_POLICY_END_OF_CHAIN) { - lrunode = hicn_hashtb_node_from_idx (pitcs->pcs_table, idx); - lrupcs = hicn_pit_get_data (lrunode); - - u64 hashval = 0; - hicn_hashtb_fullhash ((u8 *) &(lrunode->hn_key.ks.key), - lrunode->hn_keysize, &hashval); - hicn_hash_bucket_t *bucket = NULL; - if ((hashval & (pitcs->pcs_table->ht_bucket_count - 1)) == - lrunode->bucket_id) - { - // The bucket is in the non overflown - bucket = pitcs->pcs_table->ht_buckets + lrunode->bucket_id; - } - else - { - bucket = pool_elt_at_index (pitcs->pcs_table->ht_overflow_buckets, - lrunode->bucket_id); - } - hicn_hash_entry_t *hash_entry = - &(bucket->hb_entries[lrunode->entry_idx]); - hash_entry->locks++; - hicn_pcs_cs_delete (vm, pitcs, &lrupcs, &lrunode, hash_entry, NULL, - NULL); - idx = state->tail; + // Get tail entry + pcs_entry = hicn_pcs_entry_get_entry_from_index (pcs, idx); + + // Delete entry from the PCS. This will also update the LRU. + hicn_pcs_entry_remove_lock (pcs, pcs_entry); + + // Set index to the new tail (updated in the previous call) + idx = lru_policy->tail; + + // Advance counter i++; } - return (i); + return i; +} + +hicn_cs_policy_t +hicn_cs_lru_create (u32 max_elts) +{ + hicn_cs_policy_t policy = { + .vft = hicn_cs_lru, + .head = HICN_CS_POLICY_END_OF_CHAIN, + .tail = HICN_CS_POLICY_END_OF_CHAIN, + .count = 0, + .max = max_elts, + }; + + return policy; } /* diff --git a/hicn-plugin/src/cache_policies/cs_lru.h b/hicn-plugin/src/cache_policies/cs_lru.h index 35b82ff2c..1e67cb547 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.h +++ b/hicn-plugin/src/cache_policies/cs_lru.h @@ -17,7 +17,6 @@ #define __LRU_H__ #include "../pcs.h" -#include "../hashtb.h" #include "cs_policy.h" /** @@ -28,39 +27,46 @@ extern hicn_cs_policy_vft_t hicn_cs_lru; -/* - * Insert a new CS element at the head of the CS LRU +/** + * @brief Insert a new CS element at the head of the CS LRU + * + * @param policy the cs insertion/eviction policy - LRU + * @param pcs the PCS table + * @param pcs_entry the PCS entry to insert + * @return 0 on success, -1 on overflow */ -void hicn_cs_lru_insert (hicn_pit_cs_t *pcs, hicn_hash_node_t *pnode, - hicn_pcs_entry_t *entry, hicn_cs_policy_t *lru); +void hicn_cs_lru_insert (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry); /* * Dequeue an LRU element, for example when it has expired. */ -void hicn_cs_lru_dequeue (hicn_pit_cs_t *pcs, hicn_hash_node_t *pnode, - hicn_pcs_entry_t *entry, hicn_cs_policy_t *lru); +void hicn_cs_lru_dequeue (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry); /* * Move a CS LRU element to the head, probably after it's been used. */ -void hicn_cs_lru_update_head (hicn_pit_cs_t *pcs, hicn_hash_node_t *pnode, - hicn_pcs_entry_t *entry, hicn_cs_policy_t *lru); +void hicn_cs_lru_update_head (hicn_cs_policy_t *lru, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *entry); -void hicn_cs_lru_delete_get (hicn_pit_cs_t *p, hicn_cs_policy_t *policy, - hicn_hash_node_t **node, hicn_pcs_entry_t **pcs, - hicn_hash_entry_t **hash_entry); +void hicn_cs_lru_delete_get (hicn_cs_policy_t *policy, + const hicn_pit_cs_t *pcs, + hicn_pcs_entry_t **pcs_entry); /* * Remove a batch of nodes from the CS LRU, copying their node indexes into * the caller's array. We expect this is done when the LRU size exceeds the * CS's limit. Return the number of removed nodes. */ -int hicn_cs_lru_trim (hicn_pit_cs_t *pcs, u32 *node_list, int sz, - hicn_cs_policy_t *lru); +int hicn_cs_lru_trim (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + u32 *node_list, size_t sz); + +int hicn_cs_lru_flush (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs); + +hicn_cs_policy_t hicn_cs_lru_create (u32 max_elts); -int hicn_cs_lru_flush (vlib_main_t *vm, struct hicn_pit_cs_s *pitcs, - hicn_cs_policy_t *state); -#endif /* // __LRU_H__ */ +#endif /* __LRU_H__ */ /* * fd.io coding-style-patch-verification: ON diff --git a/hicn-plugin/src/cache_policies/cs_policy.h b/hicn-plugin/src/cache_policies/cs_policy.h index 73f3de107..5280a59c2 100644 --- a/hicn-plugin/src/cache_policies/cs_policy.h +++ b/hicn-plugin/src/cache_policies/cs_policy.h @@ -16,7 +16,9 @@ #ifndef __HICN_CS_POLICY_H__ #define __HICN_CS_POLICY_H__ -#include "../hashtb.h" +#include <vppinfra/types.h> +#include <vppinfra/clib.h> +#include <stddef.h> /** * @file cs_policy.h @@ -24,25 +26,10 @@ * This file provides the needed structures to implement a CS policy */ -/* - * Structure - */ -typedef struct hicn_cs_policy_s -{ - u32 max; - u32 count; - - /* Indexes to hashtable nodes forming CS LRU */ - u32 head; - u32 tail; - -} hicn_cs_policy_t; - /* Forward declaration */ -struct hicn_pit_cs_s; -struct hicn_hash_node_s; -struct hicn_pcs_entry_s; -struct hicn_cs_policy_s; +typedef struct hicn_pit_cs_s hicn_pit_cs_t; +typedef struct hicn_pcs_entry_s hicn_pcs_entry_t; +typedef struct hicn_cs_policy_s hicn_cs_policy_t; /** * @brief Definition of the virtual functin table for a cache policy. @@ -51,40 +38,143 @@ struct hicn_cs_policy_s; * - insert: add a new element * - update: update the position of an existing element * - dequeue: remove an element from the list - * - delete_get: return the next element that should be removed trim + * - delete_get: return the next element that should be removed + * - trim: trim last sz elements from the list * - flush: clean the cs */ typedef struct hicn_cs_policy_vft_s { - void (*hicn_cs_insert) (struct hicn_pit_cs_s *p, - struct hicn_hash_node_s *node, - struct hicn_pcs_entry_s *pcs, - hicn_cs_policy_t *policy); - - void (*hicn_cs_update) (struct hicn_pit_cs_s *p, - struct hicn_hash_node_s *node, - struct hicn_pcs_entry_s *pcs, - hicn_cs_policy_t *policy); - - void (*hicn_cs_dequeue) (struct hicn_pit_cs_s *p, - struct hicn_hash_node_s *node, - struct hicn_pcs_entry_s *pcs, - hicn_cs_policy_t *policy); - - void (*hicn_cs_delete_get) (struct hicn_pit_cs_s *p, - hicn_cs_policy_t *policy, - struct hicn_hash_node_s **node, - struct hicn_pcs_entry_s **pcs, - struct hicn_hash_entry_s **hash_entry); - - int (*hicn_cs_trim) (struct hicn_pit_cs_s *p, u32 *node_list, int sz, - hicn_cs_policy_t *policy); - - int (*hicn_cs_flush) (vlib_main_t *vm, struct hicn_pit_cs_s *p, - hicn_cs_policy_t *policy_state); + void (*hicn_cs_insert) (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry); + + void (*hicn_cs_update) (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry); + + void (*hicn_cs_dequeue) (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry); + + void (*hicn_cs_delete_get) (hicn_cs_policy_t *policy, + const hicn_pit_cs_t *pcs, + hicn_pcs_entry_t **pcs_entry); + + int (*hicn_cs_trim) (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + u32 *node_list, size_t sz); + + int (*hicn_cs_flush) (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs); } hicn_cs_policy_vft_t; -#endif /* // __HICN_POLICY_H__ */ +/* + * CS policy + */ +typedef struct hicn_cs_policy_s +{ +#define HICN_CS_POLICY_END_OF_CHAIN (u32) (~0) + + /* + * VFT implementing the CS eviction/insertion policy. This must be the first + * element of the structure. + */ + hicn_cs_policy_vft_t vft; + + /* + * Max number of element in CS + */ + u32 max; + + /* + * Number of element in CS + */ + u32 count; + + /* + * Head element of the CS (i.e. the most recent element used for LRU) + */ + u32 head; + + /* + * Tail element of the LRU (i.e. the next element to evict for LRU) + */ + u32 tail; +} hicn_cs_policy_t; + +/* + * Get the max number of element in the CS + */ +always_inline u32 +hicn_cs_policy_get_max (const hicn_cs_policy_t *policy) +{ + return policy->max; +} + +/* + * Get the number of element in the CS + */ +always_inline u32 +hicn_cs_policy_get_count (const hicn_cs_policy_t *policy) +{ + return policy->count; +} + +/* + * Get the head element of the CS + */ +always_inline u32 +hicn_cs_policy_get_head (const hicn_cs_policy_t *policy) +{ + return policy->head; +} + +/* + * Get the tail element of the CS + */ +always_inline u32 +hicn_cs_policy_get_tail (const hicn_cs_policy_t *policy) +{ + return policy->tail; +} + +always_inline void +hicn_cs_policy_insert (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) +{ + return policy->vft.hicn_cs_insert (policy, pcs, pcs_entry); +} + +always_inline void +hicn_cs_policy_update (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) +{ + return policy->vft.hicn_cs_update (policy, pcs, pcs_entry); +} + +always_inline void +hicn_cs_policy_dequeue (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + hicn_pcs_entry_t *pcs_entry) +{ + return policy->vft.hicn_cs_dequeue (policy, pcs, pcs_entry); +} + +always_inline void +hicn_cs_policy_delete_get (hicn_cs_policy_t *policy, const hicn_pit_cs_t *pcs, + hicn_pcs_entry_t **pcs_entry) +{ + return policy->vft.hicn_cs_delete_get (policy, pcs, pcs_entry); +} + +always_inline int +hicn_cs_policy_trim (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs, + u32 *node_list, int sz) +{ + return policy->vft.hicn_cs_trim (policy, pcs, node_list, sz); +} + +always_inline int +hicn_cs_policy_flush (hicn_cs_policy_t *policy, hicn_pit_cs_t *pcs) +{ + return policy->vft.hicn_cs_flush (policy, pcs); +} + +#endif /* __HICN_POLICY_H__ */ /* * fd.io coding-style-patch-verification: ON |