summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarian Chereji <marian.chereji@freescale.com>2014-10-07 16:28:06 (GMT)
committerMatthew Weigel <Matthew.Weigel@freescale.com>2014-12-11 18:40:48 (GMT)
commit5676273b1553c5920c90592f49a1d8fce560f24d (patch)
tree6a6bdc80eac5fca0288f05c064dc90cec892cc00
parentba6f0b25373a4d1321571c7b691b6e5f4f9f65f4 (diff)
downloadlinux-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>
-rw-r--r--drivers/staging/fsl_dpa_offload/dpa_classifier.c28
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) {