From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 5BBD311A4 for ; Tue, 4 Sep 2018 17:38:50 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 04 Sep 2018 08:38:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,329,1531810800"; d="scan'208";a="88869709" Received: from silpixa00397517.ir.intel.com (HELO silpixa00397517.ger.corp.intel.com) ([10.237.222.54]) by orsmga002.jf.intel.com with ESMTP; 04 Sep 2018 08:38:20 -0700 From: Kevin Laatz To: dev@dpdk.org Cc: cristian.dumitrescu@intel.com, jianbo.liu@arm.com, gavin.hu@arm.com, jerin.jacob@caviumnetworks.com, Kevin Laatz Date: Tue, 4 Sep 2018 16:38:22 +0100 Message-Id: <20180904153824.22985-1-kevin.laatz@intel.com> X-Mailer: git-send-email 2.9.5 Subject: [dpdk-dev] [PATCH 1/3] lib/librte_table: add hash_func header files X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 04 Sep 2018 15:38:51 -0000 This commit adds rte_table_hash_func.h and rte_table_hash_func_arm64.h to librte_table. This will replace hash_func.h and hash_func_arm64.h in the IP Pipeline application and in SoftNIC. This also adds a scalar implemetation of the x86_64 intrinsic for crc32 as a generic fallback. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kevin Laatz --- lib/librte_table/Makefile | 2 + lib/librte_table/meson.build | 2 + lib/librte_table/rte_table_hash_func.h | 244 +++++++++++++++++++++++++++ lib/librte_table/rte_table_hash_func_arm64.h | 21 +++ lib/librte_table/rte_table_version.map | 14 ++ 5 files changed, 283 insertions(+) create mode 100644 lib/librte_table/rte_table_hash_func.h create mode 100644 lib/librte_table/rte_table_hash_func_arm64.h diff --git a/lib/librte_table/Makefile b/lib/librte_table/Makefile index 276d476..f935678 100644 --- a/lib/librte_table/Makefile +++ b/lib/librte_table/Makefile @@ -46,6 +46,8 @@ 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_table_hash_func.h +SYMLINK-$(CONFIG_RTE_LIBRTE_TABLE)-include += rte_table_hash_func_arm64.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 diff --git a/lib/librte_table/meson.build b/lib/librte_table/meson.build index 8b2f841..6ae3cd6 100644 --- a/lib/librte_table/meson.build +++ b/lib/librte_table/meson.build @@ -19,6 +19,8 @@ headers = files('rte_table.h', 'rte_table_lpm_ipv6.h', 'rte_table_hash.h', 'rte_table_hash_cuckoo.h', + 'rte_table_hash_func.h', + 'rte_table_hash_func_arm64.h', 'rte_lru.h', 'rte_table_array.h', 'rte_table_stub.h') diff --git a/lib/librte_table/rte_table_hash_func.h b/lib/librte_table/rte_table_hash_func.h new file mode 100644 index 0000000..4eadbfb --- /dev/null +++ b/lib/librte_table/rte_table_hash_func.h @@ -0,0 +1,244 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2018 Intel Corporation + */ + +#ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_H__ +#define __INCLUDE_RTE_TABLE_HASH_FUNC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include + +static inline uint64_t +rte_crc32_u64_generic(uint64_t crc, uint64_t value) +{ + int i; + + crc = (crc & 0xFFFFFFFFLLU) ^ value; + for (i = 63; i >= 0; i--) { + uint64_t mask; + + mask = -(crc & 1LLU); + crc = (crc >> 1LLU) ^ (0x82F63B78LLU & mask); + } + + return crc; +} + +#if defined(RTE_ARCH_X86_64) + +#include + +static inline uint64_t +rte_crc32_u64(uint64_t crc, uint64_t v) +{ + return _mm_crc32_u64(crc, v); +} + +#elif defined(RTE_ARCH_ARM64) +#include "rte_table_hash_func_arm64.h" +#else + +static inline uin64_t +rte_crc32_u64(uint64_t crc, uint64_t v) +{ + return rte_crc32_u64_generic(crc, v); +} + +#endif + +static inline uint64_t +rte_table_hash_crc_key8(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t crc0; + + crc0 = rte_crc32_u64(seed, k[0] & m[0]); + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key16(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, crc0, crc1; + + k0 = k[0] & m[0]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key24(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, crc0, crc1; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc0 = rte_crc32_u64(crc0, k2); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key32(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc2 = rte_crc32_u64(k2, k[3] & m[3]); + crc3 = k2 >> 32; + + crc0 = rte_crc32_u64(crc0, crc1); + crc1 = rte_crc32_u64(crc2, crc3); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key40(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc2 = rte_crc32_u64(k2, k[3] & m[3]); + crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]); + + crc0 = rte_crc32_u64(crc0, crc1); + crc1 = rte_crc32_u64(crc2, crc3); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key48(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + k5 = k[5] & m[5]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc2 = rte_crc32_u64(k2, k[3] & m[3]); + crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]); + + crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2); + crc1 = rte_crc32_u64(crc3, k5); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key56(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + k5 = k[5] & m[5]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc2 = rte_crc32_u64(k2, k[3] & m[3]); + crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]); + + crc4 = rte_crc32_u64(k5, k[6] & m[6]); + crc5 = k5 >> 32; + + crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2); + crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5); + + crc0 ^= crc1; + + return crc0; +} + +static inline uint64_t +rte_table_hash_crc_key64(void *key, void *mask, __rte_unused uint32_t key_size, + uint64_t seed) +{ + uint64_t *k = key; + uint64_t *m = mask; + uint64_t k0, k2, k5, crc0, crc1, crc2, crc3, crc4, crc5; + + k0 = k[0] & m[0]; + k2 = k[2] & m[2]; + k5 = k[5] & m[5]; + + crc0 = rte_crc32_u64(k0, seed); + crc1 = rte_crc32_u64(k0 >> 32, k[1] & m[1]); + + crc2 = rte_crc32_u64(k2, k[3] & m[3]); + crc3 = rte_crc32_u64(k2 >> 32, k[4] & m[4]); + + crc4 = rte_crc32_u64(k5, k[6] & m[6]); + crc5 = rte_crc32_u64(k5 >> 32, k[7] & m[7]); + + crc0 = rte_crc32_u64(crc0, (crc1 << 32) ^ crc2); + crc1 = rte_crc32_u64(crc3, (crc4 << 32) ^ crc5); + + crc0 ^= crc1; + + return crc0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/librte_table/rte_table_hash_func_arm64.h b/lib/librte_table/rte_table_hash_func_arm64.h new file mode 100644 index 0000000..cd9e092 --- /dev/null +++ b/lib/librte_table/rte_table_hash_func_arm64.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2017-2018 Linaro Limited + */ + +#ifndef __INCLUDE_RTE_TABLE_HASH_FUNC_ARM64_H__ +#define __INCLUDE_RTE_TABLE_HASH_FUNC_ARM64_H__ + +#define _CRC32CX(crc, val) \ + __asm__("crc32cx %w[c], %w[c], %x[v]":[c] "+r" (crc):[v] "r" (val)) + +static inline uin64_t +rte_crc32_u64(uint64_t crc, uint64_t v) +{ + uint32_t crc32 = crc; + + _CRC32CX(crc32, v); + + return crc32; +} + +#endif diff --git a/lib/librte_table/rte_table_version.map b/lib/librte_table/rte_table_version.map index 6237252..dab339e 100644 --- a/lib/librte_table/rte_table_version.map +++ b/lib/librte_table/rte_table_version.map @@ -18,3 +18,17 @@ DPDK_17.11 { local: *; }; + +DPDK_18.11 { + global: + + rte_crc32_u64_generic; + rte_table_hash_crc_key8; + rte_table_hash_crc_key16; + rte_table_hash_crc_key24; + rte_table_hash_crc_key32; + rte_table_hash_crc_key40; + rte_table_hash_crc_key48; + rte_table_hash_crc_key56; + rte_table_hash_crc_key64; +} DPDK_17.11; -- 2.9.5