Skip to content

Commit

Permalink
Merge "Hash table fixes"
Browse files Browse the repository at this point in the history
  • Loading branch information
Zuul authored and opencontrail-ci-admin committed Sep 2, 2016
2 parents a49695d + d65e4b9 commit 025a739
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 80 deletions.
2 changes: 1 addition & 1 deletion dp-core/vr_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ bridge_table_deinit(struct vr_rtable *rtable, struct rtable_fspec *fs,
if (!vn_rtable)
return;

vr_htable_trav(vn_rtable, 0, bridge_table_entry_free, NULL);
vr_htable_reset(vn_rtable, bridge_table_entry_free, NULL);

if (!soft_reset) {
vr_htable_delete(vn_rtable);
Expand Down
58 changes: 24 additions & 34 deletions dp-core/vr_flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,22 +300,6 @@ vr_flow_get_va(struct vrouter *router, uint64_t offset)
return vr_htable_get_address(router->vr_flow_table, offset);
}

static struct vr_flow_entry *
__vr_flow_get_entry(struct vrouter *router, int index)
{
struct vr_flow_entry *fe;

if (index < 0)
return NULL;

fe = (struct vr_flow_entry *)
__vr_htable_get_hentry_by_index(router->vr_flow_table, index);
if (fe && (fe->fe_flags & VR_FLOW_FLAG_ACTIVE))
return fe;

return NULL;
}

struct vr_flow_entry *
vr_flow_get_entry(struct vrouter *router, int index)
{
Expand Down Expand Up @@ -2240,31 +2224,37 @@ vr_flow_table_destroy(struct vrouter *router)
}

static void
vr_flow_table_reset(struct vrouter *router)
vr_flow_invalidate_entry(vr_htable_t htable, vr_hentry_t *ent,
unsigned int index, void *data)
{
unsigned int start, end, i;
struct vr_flow_entry *fe;
struct vr_forwarding_md fmd;
struct vr_flow_md flmd;
struct vrouter *router = (struct vrouter *)data;

start = end = 0;
end = vr_flow_entries + vr_oflow_entries;
if (!ent || !data)
return;

if (end) {
flmd.flmd_defer_data = NULL;
vr_init_forwarding_md(&fmd);
for (i = start; i < end; i++) {
fe = __vr_flow_get_entry(router, i);
if (fe) {
flmd.flmd_index = i;
flmd.flmd_flags = fe->fe_flags;
fe->fe_action = VR_FLOW_ACTION_DROP;
vr_flush_entry(router, fe, &flmd, &fmd);
vr_flow_reset_entry(router, fe);
}
}
}
fe = CONTAINER_OF(fe_hentry, struct vr_flow_entry, ent);
if (!(fe->fe_flags & VR_FLOW_FLAG_ACTIVE))
return;

flmd.flmd_defer_data = NULL;
flmd.flmd_index = index;
flmd.flmd_flags = fe->fe_flags;

vr_init_forwarding_md(&fmd);

fe->fe_action = VR_FLOW_ACTION_DROP;
vr_flush_entry(router, fe, &flmd, &fmd);
vr_flow_reset_entry(router, fe);
}

static void
vr_flow_table_reset(struct vrouter *router)
{
vr_htable_reset(router->vr_flow_table,
vr_flow_invalidate_entry, router);
vr_flow_table_info_reset(router);

return;
Expand Down
98 changes: 55 additions & 43 deletions dp-core/vr_htable.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct vr_htable {
struct vr_hentry_delete_data {
struct vr_htable *hd_table;
unsigned int hd_index;
unsigned short hd_count;
unsigned short hd_scheduled;
};

Expand Down Expand Up @@ -176,43 +177,6 @@ vr_htable_oentry_invalidate(struct vr_htable *table, vr_hentry_t *ent)
vr_htable_put_free_oentry(table, ent);
}

static void
__vr_htable_oentry_invalidate(struct vr_htable *table, vr_hentry_t *ent)
{
vr_hentry_t *prev, *head_ent;

if (!table || !ent)
return;

if (ent->hentry_flags & VR_HENTRY_FLAG_IN_FREE_LIST)
return;

if (ent->hentry_index >= table->ht_hentries) {
head_ent = __vr_htable_get_hentry_by_index((vr_htable_t)table,
ent->hentry_bucket_index);
for (prev = head_ent; prev; prev = prev->hentry_next) {
if (prev->hentry_next == ent) {

prev->hentry_next = ent->hentry_next;

if (prev->hentry_next) {
prev->hentry_next_index =
ent->hentry_next->hentry_index;
} else {
prev->hentry_next_index = VR_INVALID_HENTRY_INDEX;
}

break;
}
}

vr_htable_oentry_invalidate(table, ent);
}

return;
}


static void
vr_htable_hentry_defer_delete(struct vrouter *router, void *arg)
{
Expand Down Expand Up @@ -248,13 +212,15 @@ vr_htable_hentry_scheduled_delete(void *arg)
if (!head_ent)
return;

(void)__sync_bool_compare_and_swap(&delete_data->hd_scheduled, 1, 0);

/*
* We attempt to delete only those many entries that have been
* delete marked. If some new entries are delete marked while
* processing these, they will get scheduled in new work item
*/
count = __sync_fetch_and_sub(&delete_data->hd_scheduled,
delete_data->hd_scheduled);
count = delete_data->hd_count;
(void)__sync_sub_and_fetch(&delete_data->hd_count, count);

prev = head_ent;
ent = head_ent->hentry_next;
Expand Down Expand Up @@ -335,6 +301,52 @@ vr_htable_hentry_scheduled_delete(void *arg)
return;
}

void
vr_htable_reset(vr_htable_t htable, htable_trav_cb cb, void *data)
{
unsigned int i;
vr_hentry_t *ent, *next;
struct vr_htable *table = (struct vr_htable *)htable;

if (!table || !cb)
return;

for (i = 0; i < table->ht_hentries + table->ht_oentries; i++) {
ent = __vr_htable_get_hentry_by_index(htable, i);

cb(htable, ent, i, data);

if (ent->hentry_flags & VR_HENTRY_FLAG_VALID) {
ent->hentry_flags &= ~VR_HENTRY_FLAG_VALID;
(void)__sync_sub_and_fetch(&table->ht_used_entries, 1);
}


if ((i < table->ht_hentries) && ent->hentry_next) {
next = ent->hentry_next;
ent->hentry_next = NULL;
ent->hentry_next_index = VR_INVALID_HENTRY_INDEX;
ent = next;

while (ent) {
next = ent->hentry_next;

if (ent->hentry_flags & VR_HENTRY_FLAG_VALID) {
ent->hentry_flags &= ~VR_HENTRY_FLAG_VALID;
(void)__sync_sub_and_fetch(&table->ht_used_entries, 1);
}

vr_htable_oentry_invalidate(table, ent);

ent = next;
}
}
}

return;
}


void
vr_htable_release_hentry(vr_htable_t htable, vr_hentry_t *ent)
{
Expand All @@ -354,19 +366,19 @@ vr_htable_release_hentry(vr_htable_t htable, vr_hentry_t *ent)
if (ent->hentry_index < table->ht_hentries)
return;

if (vr_not_ready) {
__vr_htable_oentry_invalidate(table, ent);
if (vr_not_ready)
return;
}

ent->hentry_flags |= VR_HENTRY_FLAG_DELETE_MARKED;

head_ent = __vr_htable_get_hentry_by_index(htable, ent->hentry_bucket_index);
delete_index = head_ent->hentry_index / table->ht_bucket_size;
delete_data = vr_btable_get(table->ht_dtable, delete_index);

(void)__sync_add_and_fetch(&delete_data->hd_count, 1);

/* Schedule the deltion only if it is not already scheduled */
if (__sync_add_and_fetch(&delete_data->hd_scheduled, 1) == 1) {
if (__sync_bool_compare_and_swap(&delete_data->hd_scheduled, 0, 1)) {

delete_data->hd_table = (struct vr_htable *)htable;
delete_data->hd_index = head_ent->hentry_index;
Expand Down
2 changes: 1 addition & 1 deletion dp-core/vr_vif_bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ vif_bridge_deinit(struct vr_interface *vif)
if (!vif || !vif->vif_btable)
return;

vr_htable_trav(vif->vif_btable, 0, vif_bridge_free, NULL);
vr_htable_reset(vif->vif_btable, vif_bridge_free, NULL);
vr_htable_delete(vif->vif_btable);
vif->vif_btable = NULL;

Expand Down
3 changes: 2 additions & 1 deletion include/vr_htable.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ int vr_htable_find_duplicate_hentry_index(vr_htable_t , vr_hentry_t *);
vr_hentry_t *vr_htable_get_hentry_by_index(vr_htable_t , unsigned int );
vr_hentry_t *__vr_htable_get_hentry_by_index(vr_htable_t , unsigned int );
vr_hentry_t *vr_htable_find_free_hentry(vr_htable_t , void *, unsigned int );
void vr_htable_trav(vr_htable_t , unsigned int , htable_trav_cb , void *);
void vr_htable_trav(vr_htable_t, unsigned int , htable_trav_cb , void *);
void vr_htable_reset(vr_htable_t, htable_trav_cb , void *);
void vr_htable_release_hentry(vr_htable_t, vr_hentry_t *);
unsigned int vr_htable_size(vr_htable_t);
void *vr_htable_get_address(vr_htable_t, uint64_t);
Expand Down

0 comments on commit 025a739

Please sign in to comment.