Add dedicated parameter structure for cuckoo hash. The cuckoo hash from
librte_hash uses slightly different prototype for the hash function (no
key_mask parameter, 32-bit seed and return value) that require either
of the following approaches:
1/ Function pointer conversion: gcc 8.1 warning [1], misleading [2]
2/ Union within the parameter structure: pollutes a very generic API
parameter structure with some implementation dependent detail
(i.e. key mask not available for one of the available
implementations)
3/ Using opaque pointer for hash function: same issue from 2/
4/ Different parameter structure: avoid issue from 2/; hopefully,
it won't be long before librte_hash implements the key mask feature,
so the generic API structure could be used.
[1] http://www.dpdk.org/ml/archives/dev/2018-April/094950.html
[2] http://www.dpdk.org/ml/archives/dev/2018-April/096250.html
Fixes:
5a80bf0ae613 ("table: add cuckoo hash")
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_table_acl.h
endif
SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_table_hash.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_table_hash_cuckoo.h
SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_lru.h
ifeq ($(CONFIG_RTE_ARCH_X86),y)
SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_lru_x86.h
'rte_table_lpm.h',
'rte_table_lpm_ipv6.h',
'rte_table_hash.h',
+ 'rte_table_hash_cuckoo.h',
'rte_lru.h',
'rte_table_array.h',
'rte_table_stub.h')
extern struct rte_table_ops rte_table_hash_key16_lru_ops;
extern struct rte_table_ops rte_table_hash_key32_lru_ops;
-/** Cuckoo hash table operations */
-extern struct rte_table_ops rte_table_hash_cuckoo_ops;
-
#ifdef __cplusplus
}
#endif
#include <rte_malloc.h>
#include <rte_log.h>
-#include <rte_hash.h>
-#include "rte_table_hash.h"
+#include "rte_table_hash_cuckoo.h"
#ifdef RTE_TABLE_STATS_COLLECT
uint32_t key_size;
uint32_t entry_size;
uint32_t n_keys;
- rte_table_hash_op_hash f_hash;
+ rte_hash_function f_hash;
uint32_t seed;
uint32_t key_offset;
};
static int
-check_params_create_hash_cuckoo(struct rte_table_hash_params *params)
+check_params_create_hash_cuckoo(struct rte_table_hash_cuckoo_params *params)
{
if (params == NULL) {
RTE_LOG(ERR, TABLE, "NULL Input Parameters.\n");
int socket_id,
uint32_t entry_size)
{
- struct rte_table_hash_params *p = params;
+ struct rte_table_hash_cuckoo_params *p = params;
struct rte_hash *h_table;
struct rte_table_hash *t;
uint32_t total_size;
struct rte_hash_parameters hash_cuckoo_params = {
.entries = p->n_keys,
.key_len = p->key_size,
- .hash_func = (rte_hash_function)(p->f_hash),
+ .hash_func = p->f_hash,
.hash_func_init_val = p->seed,
.socket_id = socket_id,
.name = p->name
--- /dev/null
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2018 Intel Corporation
+ */
+
+#ifndef __INCLUDE_RTE_TABLE_HASH_CUCKOO_H__
+#define __INCLUDE_RTE_TABLE_HASH_CUCKOO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @file
+ * RTE Table Hash Cuckoo
+ *
+ ***/
+#include <stdint.h>
+
+#include <rte_hash.h>
+
+#include "rte_table.h"
+
+/** Hash table parameters */
+struct rte_table_hash_cuckoo_params {
+ /** Name */
+ const char *name;
+
+ /** Key size (number of bytes) */
+ uint32_t key_size;
+
+ /** Byte offset within packet meta-data where the key is located */
+ uint32_t key_offset;
+
+ /** Key mask */
+ uint8_t *key_mask;
+
+ /** Number of keys */
+ uint32_t n_keys;
+
+ /** Number of buckets */
+ uint32_t n_buckets;
+
+ /** Hash function */
+ rte_hash_function f_hash;
+
+ /** Seed value for the hash function */
+ uint32_t seed;
+};
+
+/** Cuckoo hash table operations */
+extern struct rte_table_ops rte_table_hash_cuckoo_ops;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
uint32_t key_size,
uint64_t seed);
+uint32_t test_hash_cuckoo(const void *key,
+ uint32_t key_size,
+ uint32_t seed);
+
void app_main_loop_worker(void);
void app_main_loop_worker_pipeline_stub(void);
void app_main_loop_worker_pipeline_hash(void);
#include <rte_port_ring.h>
#include <rte_table_hash.h>
#include <rte_hash.h>
+#include <rte_table_hash_cuckoo.h>
#include <rte_pipeline.h>
#include "main.h"
.seed = 0,
};
+ struct rte_table_hash_cuckoo_params table_hash_cuckoo_params = {
+ .name = "TABLE",
+ .key_size = key_size,
+ .key_offset = APP_METADATA_OFFSET(32),
+ .key_mask = NULL,
+ .n_keys = 1 << 24,
+ .n_buckets = 1 << 22,
+ .f_hash = test_hash_cuckoo,
+ .seed = 0,
+ };
+
/* Table configuration */
switch (app.pipeline_type) {
case e_APP_PIPELINE_HASH_KEY8_EXT:
{
struct rte_pipeline_table_params table_params = {
.ops = &rte_table_hash_cuckoo_ops,
- .arg_create = &table_hash_params,
+ .arg_create = &table_hash_cuckoo_params,
.f_action_hit = NULL,
.f_action_miss = NULL,
.arg_ah = NULL,
return signature;
}
+uint32_t test_hash_cuckoo(
+ const void *key,
+ __attribute__((unused)) uint32_t key_size,
+ __attribute__((unused)) uint32_t seed)
+{
+ const uint32_t *k32 = key;
+ uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
+ uint32_t signature = (ip_dst >> 2) | ((ip_dst & 0x3) << 30);
+
+ return signature;
+}
+
void
app_main_loop_rx_metadata(void) {
uint32_t i, j;
return signature;
}
+uint32_t pipeline_test_hash_cuckoo(const void *key,
+ __attribute__((unused)) uint32_t key_size,
+ __attribute__((unused)) uint32_t seed)
+{
+ const uint32_t *k32 = key;
+ uint32_t ip_dst = rte_be_to_cpu_32(k32[0]);
+ uint32_t signature = ip_dst;
+
+ return signature;
+}
+
static void
app_free_resources(void) {
int i;
#include <rte_table_lpm.h>
#include <rte_table_lpm_ipv6.h>
#include <rte_table_hash.h>
+#include <rte_table_hash_cuckoo.h>
#include <rte_table_array.h>
#include <rte_pipeline.h>
__attribute__((unused)) uint32_t key_size,
__attribute__((unused)) uint64_t seed);
+uint32_t pipeline_test_hash_cuckoo(
+ const void *key,
+ __attribute__((unused)) uint32_t key_size,
+ __attribute__((unused)) uint32_t seed);
+
/* Extern variables */
extern struct rte_pipeline *p;
extern struct rte_ring *rings_rx[N_PORTS];
int status, i;
/* Traffic flow */
- struct rte_table_hash_params cuckoo_params = {
+ struct rte_table_hash_cuckoo_params cuckoo_params = {
.name = "TABLE",
.key_size = 32,
.key_offset = APP_METADATA_OFFSET(32),
.key_mask = NULL,
.n_keys = 1 << 16,
.n_buckets = 1 << 16,
- .f_hash = pipeline_test_hash,
+ .f_hash = pipeline_test_hash_cuckoo,
.seed = 0,
};
uint32_t entry_size = 1;
/* Initialize params and create tables */
- struct rte_table_hash_params cuckoo_params = {
+ struct rte_table_hash_cuckoo_params cuckoo_params = {
.name = "TABLE",
.key_size = 32,
.key_offset = APP_METADATA_OFFSET(32),
.key_mask = NULL,
.n_keys = 1 << 16,
.n_buckets = 1 << 16,
- .f_hash = (rte_table_hash_op_hash)pipeline_test_hash,
+ .f_hash = pipeline_test_hash_cuckoo,
.seed = 0,
};
if (table != NULL)
return -4;
- cuckoo_params.f_hash = pipeline_test_hash;
+ cuckoo_params.f_hash = pipeline_test_hash_cuckoo;
cuckoo_params.name = NULL;
table = rte_table_hash_cuckoo_ops.f_create(&cuckoo_params,