From 5676273b1553c5920c90592f49a1d8fce560f24d Mon Sep 17 00:00:00 2001 From: Marian Chereji Date: Tue, 7 Oct 2014 19:28:06 +0300 Subject: dpa_offload: Relocate dpa_classifier entry in index management list For HASH tables sometimes when a user modifies the key of an entry the entry needs to be moved to a different bucket. The index management list is sorted so that indexes are always ascending. When tempering with the position of an entry in the internal Cc nodes for a HASH table, the position of the entry in the index management list must also be updated. Change-Id: If4b48282c407ed248dfd389cc0c8ae856fb7db75 Signed-off-by: Marian Chereji Reviewed-on: http://git.am.freescale.net:8181/23700 Tested-by: Review Code-CDREVIEW Reviewed-by: Radu-Andrei Bulie Reviewed-by: Matthew Weigel diff --git a/drivers/staging/fsl_dpa_offload/dpa_classifier.c b/drivers/staging/fsl_dpa_offload/dpa_classifier.c index e360e09..8380d30 100644 --- a/drivers/staging/fsl_dpa_offload/dpa_classifier.c +++ b/drivers/staging/fsl_dpa_offload/dpa_classifier.c @@ -942,6 +942,8 @@ static int hash_table_modify_entry( struct dpa_cls_tbl_shadow_entry *shadow_entry; struct dpa_cls_tbl_action *local_action; + struct list_head *list_current; + struct dpa_cls_tbl_entry *index_entry; hash_set_index = crc64_ecma_seed(); hash_set_index = crc64_ecma(key->byte, @@ -1026,6 +1028,29 @@ static int hash_table_modify_entry( } ptable->int_cc_node[ptable->entry[entry_id].int_cc_node_index].used--; + /* Update position in used entries list */ + list_del(&ptable->entry[entry_id].list_node); + /* Calculate the new position in the index management list where + * this entry should go */ + if ((list_empty(&ptable->entry_list)) || + (hash_set_index >= ptable->int_cc_nodes_count - 1)) + /* Just add to the tail of the list. */ + list_current = &ptable->entry_list; + else { + /* Sort the index management list based on + * [cc_node_index] and [entry_index]. In other words, + * add the current entry before the first entry of the + * next cc node */ + list_for_each(list_current, &ptable->entry_list) { + index_entry = list_entry(list_current, + struct dpa_cls_tbl_entry, + list_node); + if (index_entry->int_cc_node_index > + hash_set_index) + break; + } + } + /* Insert the new key */ ptable->entry[entry_id].int_cc_node_index = (unsigned int)hash_set_index; @@ -1046,6 +1071,9 @@ static int hash_table_modify_entry( return -EBUSY; } + /* Add the index entry back to the index management list */ + list_add_tail(&ptable->entry[entry_id].list_node, list_current); + ptable->int_cc_node[hash_set_index].used++; } else { if (!action) { -- cgit v0.10.2