From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <andrey.chilikin@intel.com>
Received: from mga02.intel.com (mga02.intel.com [134.134.136.20])
 by dpdk.org (Postfix) with ESMTP id E58C7B62
 for <dev@dpdk.org>; Tue,  5 May 2015 18:03:30 +0200 (CEST)
Received: from fmsmga002.fm.intel.com ([10.253.24.26])
 by orsmga101.jf.intel.com with ESMTP; 05 May 2015 09:03:18 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.13,373,1427785200"; d="scan'208";a="721043202"
Received: from irsmsx152.ger.corp.intel.com ([163.33.192.66])
 by fmsmga002.fm.intel.com with ESMTP; 05 May 2015 09:03:17 -0700
Received: from irsmsx106.ger.corp.intel.com ([169.254.8.204]) by
 IRSMSX152.ger.corp.intel.com ([169.254.6.7]) with mapi id 14.03.0224.002;
 Tue, 5 May 2015 17:03:16 +0100
From: "Chilikin, Andrey" <andrey.chilikin@intel.com>
To: Vladimir Medvedkin <medvedkinv@gmail.com>, "dev@dpdk.org" <dev@dpdk.org>
Thread-Topic: [dpdk-dev] [PATCH v2] Add toeplitz hash algorithm used by RSS
Thread-Index: AQHQhzav/ZJ9PSesFk6LhY3AS/Lmdp1thwyQ
Date: Tue, 5 May 2015 16:03:16 +0000
Message-ID: <AAC06825A3B29643AF5372F5E0DDF053350C754D@IRSMSX106.ger.corp.intel.com>
References: <1428519973-10550-1-git-send-email-medvedkinv@gmail.com>
 <1430832011-17764-1-git-send-email-medvedkinv@gmail.com>
In-Reply-To: <1430832011-17764-1-git-send-email-medvedkinv@gmail.com>
Accept-Language: en-GB, en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-originating-ip: [163.33.239.181]
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Subject: Re: [dpdk-dev] [PATCH v2] Add toeplitz hash algorithm used by RSS
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: patches and discussions about DPDK <dev.dpdk.org>
List-Unsubscribe: <http://dpdk.org/ml/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://dpdk.org/ml/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <http://dpdk.org/ml/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Tue, 05 May 2015 16:03:31 -0000

Hi Vladimir,

Why limit Toeplitz hash calculation to predefined tuples and length? Should=
 it be more general, something like
rte_softrss_be(void *input, uint32_t input_len, const uint8_t *rss_key) to =
enable hash calculation for an input of any size? It would be useful for di=
stributing packets using some non-standard tuples, like hashing on QinQ or =
adding IP protocol to hash calculation to separate UDP and TCP flows or eve=
n some other fields from a packet, for example, tunnel ID from VXLAN header=
s. By the way, i40e already supports RSS for SCTP in addition to TCP and UD=
P and includes Verification Tag as well as SCTP source and destination port=
s for RSS hash.

Regards,
Andrey

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Vladimir
> Medvedkin
> Sent: Tuesday, May 5, 2015 2:20 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2] Add toeplitz hash algorithm used by RSS
>=20
> Software implementation of the Toeplitz hash function used by RSS.
> Can be used either for packet distribution on single queue NIC or for
> simulating of RSS computation on specific NIC (for example after GRE head=
er
> decapsulating).
>=20
> v2 changes
> - Add ipv6 support
> - Various style fixes
>=20
> Signed-off-by: Vladimir Medvedkin <medvedkinv@gmail.com>
> ---
>  lib/librte_hash/Makefile    |   1 +
>  lib/librte_hash/rte_thash.h | 209
> ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 210 insertions(+)
>  create mode 100644 lib/librte_hash/rte_thash.h
>=20
> diff --git a/lib/librte_hash/Makefile b/lib/librte_hash/Makefile index
> 3696cb1..981230b 100644
> --- a/lib/librte_hash/Makefile
> +++ b/lib/librte_hash/Makefile
> @@ -49,6 +49,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_HASH) +=3D rte_fbk_hash.c
> SYMLINK-$(CONFIG_RTE_LIBRTE_HASH)-include :=3D rte_hash.h  SYMLINK-
> $(CONFIG_RTE_LIBRTE_HASH)-include +=3D rte_hash_crc.h  SYMLINK-
> $(CONFIG_RTE_LIBRTE_HASH)-include +=3D rte_jhash.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_HASH)-include +=3D rte_thash.h
>  SYMLINK-$(CONFIG_RTE_LIBRTE_HASH)-include +=3D rte_fbk_hash.h
>=20
>  # this lib needs eal
> diff --git a/lib/librte_hash/rte_thash.h b/lib/librte_hash/rte_thash.h ne=
w file
> mode 100644 index 0000000..42c7bf6
> --- /dev/null
> +++ b/lib/librte_hash/rte_thash.h
> @@ -0,0 +1,209 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> + *   All rights reserved.
> + *
> + *   Redistribution and use in source and binary forms, with or without
> + *   modification, are permitted provided that the following conditions
> + *   are met:
> + *
> + *     * Redistributions of source code must retain the above copyright
> + *       notice, this list of conditions and the following disclaimer.
> + *     * Redistributions in binary form must reproduce the above copyrig=
ht
> + *       notice, this list of conditions and the following disclaimer in
> + *       the documentation and/or other materials provided with the
> + *       distribution.
> + *     * Neither the name of Intel Corporation nor the names of its
> + *       contributors may be used to endorse or promote products derived
> + *       from this software without specific prior written permission.
> + *
> + *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
> CONTRIBUTORS
> + *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
> NOT
> + *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
> FITNESS FOR
> + *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
> COPYRIGHT
> + *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
> INCIDENTAL,
> + *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
> NOT
> + *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
> OF USE,
> + *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
> AND ON ANY
> + *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
> TORT
> + *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
> THE USE
> + *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
> DAMAGE.
> + */
> +
> +#ifndef _RTE_THASH_H
> +#define _RTE_THASH_H
> +
> +/**
> + * @file
> + *
> + * toeplitz hash functions.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +/**
> + * Software implementation of the Toeplitz hash function used by RSS.
> + * Can be used either for packet distribution on single queue NIC
> + * or for simulating of RSS computation on specific NIC (for example
> + * after GRE header decapsulating)
> + */
> +
> +#include <stdint.h>
> +#include <rte_byteorder.h>
> +#include <rte_vect.h>
> +
> +#ifdef __SSE3__
> +static const __m128i bswap_mask =3D {0x0405060700010203,
> +0x0C0D0E0F08090A0B}; #endif
> +
> +enum rte_thash_len {
> +	RTE_THASH_V4_L3	=3D 2,	/*calculate hash of ipv4 header
> only*/
> +	RTE_THASH_V4_L4	=3D 3,	/*calculate hash of ipv4 + transport
> headers*/
> +	RTE_THASH_V6_L3	=3D 8,	/*calculate hash of ipv6 header only
> */
> +	RTE_THASH_V6_L4	=3D 9,	/*calculate hash of ipv6 + transport
> headers */
> +};
> +
> +/**
> + * IPv4 tuple
> + * addreses and ports have to be CPU byte order  */ struct
> +rte_ipv4_tuple {
> +	uint32_t	src_addr;
> +	uint32_t	dst_addr;
> +	uint16_t	dport;
> +	uint16_t	sport;
> +};
> +
> +/**
> + * IPv6 tuple
> + * Addresses have to be filled by rte_thash_load_v6_addr()
> + * ports have to be CPU byte order
> + */
> +struct rte_ipv6_tuple {
> +	uint8_t		src_addr[16];
> +	uint8_t		dst_addr[16];
> +	uint16_t	dport;
> +	uint16_t	sport;
> +};
> +
> +union rte_thash_tuple {
> +	struct rte_ipv4_tuple	v4;
> +	struct rte_ipv6_tuple	v6;
> +} __attribute__((aligned(16)));
> +
> +/**
> + * Prepare special converted key to use with rte_softrss_be()
> + * @param orig
> + *   pointer to original RSS key
> + * @param targ
> + *   pointer to target RSS key
> + * @param len
> + *   RSS key length
> + */
> +static inline void
> +rte_convert_rss_key(const uint32_t *orig, uint32_t *targ, int len) {
> +	int i;
> +
> +	for (i =3D 0; i < (len >> 2); i++) {
> +		targ[i] =3D rte_be_to_cpu_32(orig[i]);
> +	}
> +}
> +
> +/**
> + * Prepare and load IPv6 address
> + * @param orig
> + *   Pointer to ipv6 address inside ipv6_hdr
> + * @param targ
> + *   Pointer to ipv6 address inside rte_ipv6_tuple
> + */
> +static inline void
> +rte_thash_load_v6_addr(const uint8_t *orig, uint8_t *targ) { #ifdef
> +__SSE3__
> +	__m128i ipv6 =3D _mm_loadu_si128((const __m128i *)orig);
> +	*(__m128i *)targ =3D _mm_shuffle_epi8(ipv6, bswap_mask); #else
> +	int i;
> +
> +	for (i =3D 0; i < 4; i++) {
> +		*((uint32_t *)targ + i) =3D
> +			rte_be_to_cpu_32(*((const uint32_t *)orig + i));
> +	}
> +#endif
> +}
> +
> +/**
> + * Generic implementation. Can be used with original rss_key
> + * @param input_tuple
> + *   Pointer to rte_thash_tuple union
> + * @param input_len
> + *   Length of input_tuple in 4-bytes chunks
> + *   RTE_THASH_V4_L3:	calculate hash of IPv4 src address and IPv4 dst
> address
> + *   RTE_THASH_V4_L4	calculate hash of IPv4 adresses and TCP|UDP
> ports
> + *   RTE_THASH_V6_L3:	calculate hash of IPv6 src address and IPv4 dst
> address
> + *   RTE_THASH_V6_L4	calculate hash of IPv6 adresses and TCP|UDP
> ports
> + * @param rss_key
> + *   Pointer to RSS hash key.
> + * @return
> + *   Calculated hash value.
> + */
> +static inline uint32_t
> +rte_softrss(union rte_thash_tuple *input_tuple, enum rte_thash_len
> input_len,
> +		const uint8_t *rss_key)
> +{
> +	uint32_t i, j, ret =3D 0;
> +
> +	for (j =3D 0; j < input_len; j++) {
> +		for (i =3D 0; i < 32; i++) {
> +			if (((uint32_t *)input_tuple)[j] & (1 << (31 - i))) {
> +				ret ^=3D rte_cpu_to_be_32(((const uint32_t
> *)rss_key)[j]) << i |
> +
> 	(uint32_t)((uint64_t)(rte_cpu_to_be_32(((const uint32_t
> *)rss_key)[j + 1])) >> (32 - i));
> +			}
> +		}
> +	}
> +	return ret;
> +}
> +
> +/**
> + * Optimized implementation.
> + * If you want the calculated hash value matches NIC RSS value
> + * you have to use special converted key.
> + * @param input_tuple
> + *   Pointer to rte_thash_tuple union
> + * @param input_len
> + *   Length of input_tuple in 4-bytes chunks
> + *   RTE_THASH_V4_L3:	calculate hash of IPv4 src address and IPv4 dst
> address
> + *   RTE_THASH_V4_L4	calculate hash of IPv4 adresses and TCP|UDP
> ports
> + *   RTE_THASH_V6_L3:	calculate hash of IPv6 src address and IPv4 dst
> address
> + *   RTE_THASH_V6_L4	calculate hash of IPv6 adresses and TCP|UDP
> ports
> + * @param *rss_key
> + *   Pointer to RSS hash key.
> + * @return
> + *   Calculated hash value.
> + */
> +static inline uint32_t
> +rte_softrss_be(union rte_thash_tuple *input_tuple, enum rte_thash_len
> input_len,
> +		const uint8_t *rss_key)
> +{
> +	uint32_t i, j, ret =3D 0;
> +
> +	for (j =3D 0; j < input_len; j++) {
> +		for (i =3D 0; i < 32; i++) {
> +			if (((uint32_t *)input_tuple)[j] & (1 << (31 - i))) {
> +				ret ^=3D ((const uint32_t *)rss_key)[j] << i |
> +					(uint32_t)((uint64_t)(((const uint32_t
> *)rss_key)[j + 1]) >> (32 - i));
> +			}
> +		}
> +	}
> +	return ret;
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_THASH_H */
> --
> 1.8.3.2