From 2e1756de877df622680b05be421cb27a884db167 Mon Sep 17 00:00:00 2001 From: Alberto Compagno Date: Fri, 24 May 2019 16:33:56 +0200 Subject: [HICN-197] Supporting multiple local faces for the same prefix. Fixed buffer deallocation when data are pushed from the application. Change-Id: Ibc9625e420d0c8579be3d7f1310a08a5e37f765a Signed-off-by: Alberto Compagno --- hicn-plugin/src/cache_policies/cs_lru.c | 6 +++ hicn-plugin/src/data_push_node.c | 8 +--- hicn-plugin/src/hashtb.c | 3 +- hicn-plugin/src/interest_hitcs_node.c | 2 +- hicn-plugin/src/pcs.h | 66 ++++++++++++++++++++++++++++----- 5 files changed, 66 insertions(+), 19 deletions(-) diff --git a/hicn-plugin/src/cache_policies/cs_lru.c b/hicn-plugin/src/cache_policies/cs_lru.c index f35bee3c9..1f1d14667 100644 --- a/hicn-plugin/src/cache_policies/cs_lru.c +++ b/hicn-plugin/src/cache_policies/cs_lru.c @@ -149,6 +149,12 @@ hicn_cs_lru_update_head (hicn_pit_cs_t * pit, hicn_hash_node_t * pnode, } 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)); } diff --git a/hicn-plugin/src/data_push_node.c b/hicn-plugin/src/data_push_node.c index 8f9ecbb8e..ff28b4dea 100644 --- a/hicn-plugin/src/data_push_node.c +++ b/hicn-plugin/src/data_push_node.c @@ -141,21 +141,16 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt, /* Store the original packet buffer in the CS node */ pitp->u.cs.cs_pkt_buf = vlib_get_buffer_index (vm, b0); - pitp->u.cs.cs_rxface = hicnb0->face_dpo_id; - /* Set up the hash node and insert it */ hicn_hashtb_init_node (rt->pitcs->pcs_table, nodep, nameptr, namelen); - nodep->hn_flags |= HICN_HASH_NODE_CS_FLAGS; - pitp->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG; - hicn_hash_entry_t *hash_entry; ret = hicn_pcs_cs_insert_update (vm, rt->pitcs, pitp, nodep, &hash_entry, hicnb0->name_hash, &node_id0, &dpo_ctx_id0, &vft_id0, &is_cs0, &hash_entry_id, &bucket_id, - &bucket_is_overflow); + &bucket_is_overflow, &(hicnb0->face_dpo_id)); if (ret != HICN_ERROR_NONE) { @@ -177,7 +172,6 @@ hicn_new_data (vlib_main_t * vm, hicn_data_push_runtime_t * rt, } else { - hash_entry->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY; prep_buffer_for_cs (vm, b0, isv6); } } diff --git a/hicn-plugin/src/hashtb.c b/hicn-plugin/src/hashtb.c index 0bdb91c0d..5d41b7aa9 100644 --- a/hicn-plugin/src/hashtb.c +++ b/hicn-plugin/src/hashtb.c @@ -485,7 +485,8 @@ loop_buckets: * If we are doing lookup for a data, do not take a * lock in case of a hit with a CS entry */ - bucket->hb_entries[i].locks++; + if (!(*is_cs)) + bucket->hb_entries[i].locks++; *bucket_is_overflow = is_overflow; ret = HICN_ERROR_HASHTB_EXIST; goto done; diff --git a/hicn-plugin/src/interest_hitcs_node.c b/hicn-plugin/src/interest_hitcs_node.c index aad7ed74e..af9db2863 100644 --- a/hicn-plugin/src/interest_hitcs_node.c +++ b/hicn-plugin/src/interest_hitcs_node.c @@ -180,7 +180,7 @@ hicn_interest_hitcs_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node, { if (PREDICT_TRUE (!(hash_entry0->he_flags & HICN_HASH_ENTRY_FLAG_DELETED))) - hicn_pcs_cs_update (vm, rt->pitcs, pitp, node0); + hicn_pcs_cs_update (vm, rt->pitcs, pitp, pitp, node0); /* * Retrieve the incoming iface and forward diff --git a/hicn-plugin/src/pcs.h b/hicn-plugin/src/pcs.h index b9b40a3fb..491476221 100644 --- a/hicn-plugin/src/pcs.h +++ b/hicn-plugin/src/pcs.h @@ -113,7 +113,7 @@ typedef struct __attribute__ ((packed)) hicn_cs_entry_s u32 cs_lru_next; /* Reserved for implementing cache policy different than LRU */ - /* 40B + 56B = 96B */ + /* 40B + (64 - 40)B = 64B */ u8 opaque[HICN_CS_ENTRY_OPAQUE_SIZE]; @@ -174,7 +174,7 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs, always_inline void hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, - hicn_pcs_entry_t * entry, hicn_hash_node_t * node); + hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, hicn_hash_node_t * node); always_inline void hicn_pcs_cs_delete (vlib_main_t * vm, hicn_pit_cs_t * pitcs, @@ -196,7 +196,7 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_hash_entry_t ** hash_entry, u64 hashval, u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, - u8 * bucket_is_overflow); + u8 * bucket_is_overflow, dpo_id_t * inface); always_inline int hicn_pcs_pit_insert (hicn_pit_cs_t * pitcs, hicn_pcs_entry_t * entry, @@ -356,7 +356,8 @@ hicn_pcs_delete_internal (hicn_pit_cs_t * pitcs, if (hash_entry->he_flags & HICN_HASH_ENTRY_FLAG_CS_ENTRY) { pitcs->pcs_cs_dealloc++; - + vlib_buffer_t *b0 = vlib_get_buffer (vm, pcs->u.cs.cs_pkt_buf); + ASSERT(b0->ref_count == 1); /* Free any associated packet buffer */ vlib_buffer_free_one (vm, pcs->u.cs.cs_pkt_buf); pcs->u.cs.cs_pkt_buf = ~0; @@ -449,12 +450,12 @@ hicn_pit_to_cs (vlib_main_t * vm, hicn_pit_cs_t * pitcs, always_inline void hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, - hicn_pcs_entry_t * entry, hicn_hash_node_t * node) + hicn_pcs_entry_t * old_entry, hicn_pcs_entry_t * entry, hicn_hash_node_t * node) { hicn_cs_policy_t *policy_state; hicn_cs_policy_vft_t *policy_vft; - dpo_id_t *face_dpo = (dpo_id_t *) & (entry->u.cs.cs_rxface); + dpo_id_t *face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface); policy_state = &pitcs->policy_state; policy_vft = &pitcs->policy_vft; @@ -468,8 +469,45 @@ hicn_pcs_cs_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, policy_vft = &prod_face->policy_vft; } } - /* Update the CS LRU, moving this item to the head */ - policy_vft->hicn_cs_update (pitcs, node, entry, policy_state); + + if (dpo_cmp(&entry->u.cs.cs_rxface, &old_entry->u.cs.cs_rxface) !=0) + { + /* Dequeue content from the old queue */ + policy_vft->hicn_cs_dequeue(pitcs, node, old_entry, policy_state); + + dpo_copy(&old_entry->u.cs.cs_rxface, &entry->u.cs.cs_rxface); + face_dpo = (dpo_id_t *) & (old_entry->u.cs.cs_rxface); + policy_state = &pitcs->policy_state; + policy_vft = &pitcs->policy_vft; + + if (face_dpo->dpoi_type == hicn_face_ip_type) + { + hicn_face_t *face = hicn_dpoi_get_from_idx (face_dpo->dpoi_index); + if (face->shared.flags & HICN_FACE_FLAGS_APPFACE_PROD) + { + hicn_face_prod_t *prod_face = (hicn_face_prod_t *) face->data; + policy_state = &prod_face->policy; + policy_vft = &prod_face->policy_vft; + } + } + + policy_vft->hicn_cs_insert (pitcs, node, old_entry, policy_state); + + if (policy_state->count > policy_state->max) + { + hicn_hash_node_t *node; + hicn_pcs_entry_t *pcs_entry; + hicn_hash_entry_t *hash_entry; + policy_vft->hicn_cs_delete_get (pitcs, policy_state, + &node, &pcs_entry, &hash_entry); + + hicn_pcs_cs_delete (vm, pitcs, &pcs_entry, &node, hash_entry, NULL, + NULL); + } + } + else + /* Update the CS LRU, moving this item to the head */ + policy_vft->hicn_cs_update (pitcs, node, old_entry, policy_state); } always_inline void @@ -534,6 +572,11 @@ hicn_pcs_cs_insert (vlib_main_t * vm, hicn_pit_cs_t * pitcs, if (PREDICT_TRUE (ret == HICN_ERROR_NONE)) { + /* Mark the entry as a CS entry */ + node->hn_flags |= HICN_HASH_NODE_CS_FLAGS; + entry->shared.entry_flags |= HICN_PCS_ENTRY_CS_FLAG; + (*hash_entry)->he_flags |= HICN_HASH_ENTRY_FLAG_CS_ENTRY; + hicn_cs_policy_t *policy_state; hicn_cs_policy_vft_t *policy_vft; @@ -579,12 +622,13 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, hicn_hash_entry_t ** hash_entry, u64 hashval, u32 * node_id, u8 * dpo_ctx_id, u8 * vft_id, u8 * is_cs, u8 * hash_entry_id, u32 * bucket_id, - u8 * bucket_is_overflow) + u8 * bucket_is_overflow, dpo_id_t * inface) { int ret; ASSERT (entry == hicn_hashtb_node_data (node)); + entry->u.cs.cs_rxface = *inface; ret = hicn_pcs_cs_insert (vm, pitcs, entry, node, hash_entry, hashval, node_id, dpo_ctx_id, vft_id, is_cs, hash_entry_id, bucket_id, @@ -605,8 +649,10 @@ hicn_pcs_cs_insert_update (vlib_main_t * vm, hicn_pit_cs_t * pitcs, pitp->shared.create_time = entry->shared.create_time; pitp->shared.expire_time = entry->shared.expire_time; pitp->u.cs.cs_pkt_buf = entry->u.cs.cs_pkt_buf; - hicn_pcs_cs_update (vm, pitcs, pitp, existing_node); + + hicn_pcs_cs_update (vm, pitcs, pitp, entry, existing_node); } + return (ret); } -- cgit 1.2.3-korg