table: add dedicated params struct for cuckoo hash

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>
This commit is contained in:
Jasvinder Singh 2018-05-08 15:17:18 +01:00 committed by Cristian Dumitrescu
parent 7959831b4d
commit 8ea4143883
11 changed files with 115 additions and 15 deletions

View File

@ -45,6 +45,7 @@ ifeq ($(CONFIG_RTE_LIBRTE_ACL),y)
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

View File

@ -18,6 +18,7 @@ headers = files('rte_table.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')

View File

@ -99,9 +99,6 @@ extern struct rte_table_ops rte_table_hash_key8_lru_ops;
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

View File

@ -10,8 +10,7 @@
#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
@ -35,7 +34,7 @@ struct rte_table_hash {
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;
@ -47,7 +46,7 @@ struct rte_table_hash {
};
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");
@ -82,7 +81,7 @@ rte_table_hash_cuckoo_create(void *params,
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;
@ -107,7 +106,7 @@ rte_table_hash_cuckoo_create(void *params,
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

View File

@ -0,0 +1,57 @@
/* 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

View File

@ -107,6 +107,10 @@ uint64_t test_hash(void *key,
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);

View File

@ -15,6 +15,7 @@
#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"
@ -151,6 +152,17 @@ app_main_loop_worker_pipeline_hash(void) {
.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:
@ -298,7 +310,7 @@ app_main_loop_worker_pipeline_hash(void) {
{
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,
@ -379,6 +391,18 @@ uint64_t test_hash(
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;

View File

@ -54,6 +54,17 @@ uint64_t pipeline_test_hash(void *key,
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;

View File

@ -6,6 +6,7 @@
#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>
@ -106,6 +107,11 @@ uint64_t pipeline_test_hash(
__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];

View File

@ -778,14 +778,14 @@ test_table_hash_cuckoo_combined(void)
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,
};

View File

@ -903,14 +903,14 @@ test_table_hash_cuckoo(void)
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,
};
@ -941,7 +941,7 @@ test_table_hash_cuckoo(void)
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,