diff options
author | Marian Chereji <marian.chereji@freescale.com> | 2014-10-07 16:28:06 (GMT) |
---|---|---|
committer | Matthew Weigel <Matthew.Weigel@freescale.com> | 2014-12-11 18:40:48 (GMT) |
commit | 5676273b1553c5920c90592f49a1d8fce560f24d (patch) | |
tree | 6a6bdc80eac5fca0288f05c064dc90cec892cc00 /drivers | |
parent | ba6f0b25373a4d1321571c7b691b6e5f4f9f65f4 (diff) | |
download | linux-fsl-qoriq-5676273b1553c5920c90592f49a1d8fce560f24d.tar.xz |
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 <marian.chereji@freescale.com>
Reviewed-on: http://git.am.freescale.net:8181/23700
Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
Reviewed-by: Radu-Andrei Bulie <Radu.Bulie@freescale.com>
Reviewed-by: Matthew Weigel <Matthew.Weigel@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/staging/fsl_dpa_offload/dpa_classifier.c | 28 |
1 files changed, 28 insertions, 0 deletions
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) { |