Hash library used a function pointer to choose a different
key compare function, depending on the key size.
As a result, multiple processes could not use the same hash table,
as the function addresses vary from one process to another.
Instead, a jump table is used, so each process has its own
function addresses, accessing this table with an index stored
in the hash table (note that using a custom key compare function
is not supported in multi-process mode).
Fixes: 48a399119619 ("hash: replace with cuckoo hash implementation")
Signed-off-by: Pablo de Lara
Acked-by: Bruce Richardson
---
Changes in v2:
- Added missing const
- Added extra info in documentation
doc/guides/prog_guide/hash_lib.rst | 8
doc/guides/rel_notes/release_16_04.rst | 8
lib/librte_hash/rte_cuckoo_hash.c | 85 ++
3 files changed, 82 insertions(+), 19 deletions(-)
diff --git a/doc/guides/prog_guide/hash_lib.rst
b/doc/guides/prog_guide/hash_lib.rst
index 8f2cdbf..7944640 100644
--- a/doc/guides/prog_guide/hash_lib.rst
+++ b/doc/guides/prog_guide/hash_lib.rst
@@ -87,6 +87,14 @@ or stored in the hash table itself.
The example hash tables in the L2/L3 Forwarding sample applications defines
which port to forward a packet to based on a packet flow identified by the
five-tuple lookup.
However, this table could also be used for more sophisticated features and
provide many other functions and actions that could be performed on the packets
and flows.
+Multi-process support
+-
+
+The hash library can be used in a multi-process environment, minding that only
lookups are thread-safe.
+The only function that can only be used in single-process mode is
rte_hash_set_cmp_func(), which sets up
+a custom compare function, which is assigned to a function pointer (therefore,
it is not supported in
+multi-process mode).
+
Implementation Details
--
diff --git a/doc/guides/rel_notes/release_16_04.rst
b/doc/guides/rel_notes/release_16_04.rst
index 79d76e1..e6cc34d 100644
--- a/doc/guides/rel_notes/release_16_04.rst
+++ b/doc/guides/rel_notes/release_16_04.rst
@@ -404,6 +404,14 @@ Libraries
Fix crc32c hash functions to return a valid crc32c value for data lengths
not multiple of 4 bytes.
+* **hash: Fixed hash library to support multi-process mode.**
+
+ Fix hash library to support multi-process mode, using a jump table,
+ instead of storing a function pointer to the key compare function.
+ Multi-process mode only works with the built-in compare functions,
+ however a custom compare function (not in the jump table) can only
+ be used in single-process mode.
+
* **librte_port: Fixed segmentation fault for ring and ethdev writer nodrop.**
Fixed core dump issue on txq and swq when dropless is set to yes.
diff --git a/lib/librte_hash/rte_cuckoo_hash.c
b/lib/librte_hash/rte_cuckoo_hash.c
index 71b5b76..bdba557 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -102,6 +102,41 @@ EAL_REGISTER_TAILQ(rte_hash_tailq)
#define LCORE_CACHE_SIZE 8
+/*
+ * All different options to select a key compare function,
+ * based on the key size and custom function.
+ */
+enum cmp_jump_table_case {
+ KEY_CUSTOM = 0,
+ KEY_16_BYTES,
+ KEY_32_BYTES,
+ KEY_48_BYTES,
+ KEY_64_BYTES,
+ KEY_80_BYTES,
+ KEY_96_BYTES,
+ KEY_112_BYTES,
+ KEY_128_BYTES,
+ KEY_OTHER_BYTES,
+ NUM_KEY_CMP_CASES,
+};
+
+/*
+ * Table storing all different key compare functions
+ * (multi-process supported)
+ */
+const rte_hash_cmp_eq_t cmp_jump_table[NUM_KEY_CMP_CASES] = {
+ NULL,
+ rte_hash_k16_cmp_eq,
+ rte_hash_k32_cmp_eq,
+ rte_hash_k48_cmp_eq,
+ rte_hash_k64_cmp_eq,
+ rte_hash_k80_cmp_eq,
+ rte_hash_k96_cmp_eq,
+ rte_hash_k112_cmp_eq,
+ rte_hash_k128_cmp_eq,
+ memcmp
+};
+
struct lcore_cache {
unsigned len; /**< Cache len */
void *objs[LCORE_CACHE_SIZE]; /**< Cache objects */
@@ -115,7 +150,10 @@ struct rte_hash {
uint32_t key_len; /**< Length of hash key. */
rte_hash_function hash_func;/**< Function used to calculate hash. */
uint32_t hash_func_init_val;/**< Init value used by hash_func. */
- rte_hash_cmp_eq_t rte_hash_cmp_eq; /**< Function used to compare keys.
*/
+ rte_hash_cmp_eq_t rte_hash_custom_cmp_eq;
+ /**< Custom function used to compare keys. */
+ enum cmp_jump_table_case cmp_jump_table_idx;
+ /**< Indicates which compare function to use. */
uint32_t bucket_bitmask;/**< Bitmask for getting bucket index
from hash signature. */
uint32_t key_entry_size; /**< Size of each key entry. */
@@ -187,7 +225,16 @@ rte_hash_find_existing(const char *name)
void rte_hash_set_cmp_func(struct rte_hash *h, rte_hash_cmp_eq_t func)
{
-