From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 3C54B41D33; Tue, 21 Feb 2023 22:35:43 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2F0074067C; Tue, 21 Feb 2023 22:35:43 +0100 (CET) Received: from mail-ed1-f53.google.com (mail-ed1-f53.google.com [209.85.208.53]) by mails.dpdk.org (Postfix) with ESMTP id E3A8340042 for ; Tue, 21 Feb 2023 22:35:40 +0100 (CET) Received: by mail-ed1-f53.google.com with SMTP id cy6so17261952edb.5 for ; Tue, 21 Feb 2023 13:35:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=kkExeGeCRN4bDwUwdejNA1qOLCVpD1iACgxT/YIc0H4=; b=lBi1kRNuSFNeLDHxWokhBGH994fRugunTsbAkfgB9lbNSr/FBFUijuwKsl/RPp2k+G LvAtX0ABzH1TsLSc+/x/xPNmZFHqMS/7SXaTDNjyKKYrf2gjIOeu8c8UxDHIQWdxlQrB oG1kdRj0UnR6WpcCxpR3pV2dmRrjbU3juUfKaRcA6i6H384EDxC81qFOTb/vxWB1+t8B YDdjrzEl9q88x9yBTx/LmctLCo4s3Gh+Jp8FIYcxggHyCqcQ/ko9hKFiljJEAhFsWLeJ 4gewY0TIeLDyc939Tr4l/pbRASCJ6w2QaBFE36iWXjeW1Vq5Z012Mg0vG4QCZm8CHO0J 2jjg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=kkExeGeCRN4bDwUwdejNA1qOLCVpD1iACgxT/YIc0H4=; b=sfpz2yvG24CEKC0D/wFVw1QWrCvrdcqryOnFpleobU9N82jgwP/Ii2OYiCdWwcsIlX RxyJX08x8/HioRYzATHPEqzTcFI6IUOF10F5Wb+PyAws02S/UyhFLoDOO5yhroh3Ha4V YiyMf63muhlBwHIL1gjZotSni7SCcz/Q3dGTTjG0R8kFWXGLm+Q0sEgA7Cp/Qo1j6IDj KdtEPgPlgNHzKHKUAVshTztQ0UZ9PqFl1JKgItfn9bHA6nguQUzLrSOOxRvR1g+WMYLi ZjbRkM9roU9UaTygpusxlt4WV1B0qJ3G5Q1N69cbeILcoARNY7XI35ps6leC2Uq55Bjk zItg== X-Gm-Message-State: AO0yUKUPwxQggD4R6YBhEHuOChFw4MsZJ1WFqbHE2KwBi2PgxMr3tRC/ Ne7pMLAast3DdA1IqvZimDVk+wxSqG2H+zNr5p52pp76 X-Google-Smtp-Source: AK7set9ZTTmns7D0RljrIOVszeKqbNiISSyLqYxL/gvuE5rL7nsd/IJR1q/QF7myt3X0ticm3OkWGQEdElOgf+Fh6tA= X-Received: by 2002:a17:906:5e42:b0:877:747d:4a85 with SMTP id b2-20020a1709065e4200b00877747d4a85mr6920410eju.3.1677015340323; Tue, 21 Feb 2023 13:35:40 -0800 (PST) MIME-Version: 1.0 References: <20230221175529.644311-1-qobilidop@gmail.com> <20230221193710.717280-1-qobilidop@gmail.com> In-Reply-To: <20230221193710.717280-1-qobilidop@gmail.com> From: Bili Dong Date: Tue, 21 Feb 2023 13:35:04 -0800 Message-ID: Subject: Re: [PATCH v6] hash: add XOR32 hash function To: Bruce Richardson , vladimir.medvedkin@intel.com Cc: dev@dpdk.org, cristian.dumitrescu@intel.com, =?UTF-8?Q?Morten_Br=C3=B8rup?= , Stephen Hemminger Content-Type: multipart/alternative; boundary="000000000000a49bc805f53c8fda" X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org --000000000000a49bc805f53c8fda Content-Type: text/plain; charset="UTF-8" The reported performance issue is a mystery to me. Does anyone have an idea what's going on? Thanks, Bili On Tue, Feb 21, 2023 at 11:37 AM Bili Dong wrote: > An XOR32 hash is needed in the Software Switch (SWX) Pipeline for its > use case in P4. We implement it in this patch so it could be easily > registered in the pipeline later. > > Signed-off-by: Bili Dong > --- > .mailmap | 1 + > app/test/test_hash_functions.c | 33 +++++++++++-- > lib/hash/rte_hash_xor.h | 87 ++++++++++++++++++++++++++++++++++ > 3 files changed, 118 insertions(+), 3 deletions(-) > create mode 100644 lib/hash/rte_hash_xor.h > > diff --git a/.mailmap b/.mailmap > index a9f4f28fba..3e9bec29d5 100644 > --- a/.mailmap > +++ b/.mailmap > @@ -159,6 +159,7 @@ Bernard Iremonger > Bert van Leeuwen > Bhagyada Modali > Bharat Mota > +Bili Dong > Bill Hong > Billy McFall > Billy O'Mahony > diff --git a/app/test/test_hash_functions.c > b/app/test/test_hash_functions.c > index 76d51b6e71..53e296fec4 100644 > --- a/app/test/test_hash_functions.c > +++ b/app/test/test_hash_functions.c > @@ -15,6 +15,7 @@ > #include > #include > #include > +#include > > #include "test.h" > > @@ -22,8 +23,8 @@ > * Hash values calculated for key sizes from array "hashtest_key_lens" > * and for initial values from array "hashtest_initvals. > * Each key will be formed by increasing each byte by 1: > - * e.g.: key size = 4, key = 0x03020100 > - * key size = 8, key = 0x0706050403020100 > + * e.g.: key size = 4, key = 0x00010203 > + * key size = 8, key = 0x0001020304050607 > */ > static uint32_t hash_values_jhash[2][12] = {{ > 0x8ba9414b, 0xdf0d39c9, > @@ -51,6 +52,19 @@ static uint32_t hash_values_crc[2][12] = {{ > 0x789c104f, 0x53028d3e > } > }; > +static uint32_t hash_values_xor32[2][12] = {{ > + 0x00000000, 0x00010000, > + 0x00010203, 0x04040404, 0x00000000, 0x00000000, > + 0x00000000, 0x00000000, 0x0c040404, 0x000d0e0f, > + 0x04212223, 0x04040404 > +}, > +{ > + 0xdeadbeef, 0xdeacbeef, > + 0xdeacbcec, 0xdaa9baeb, 0xdeadbeef, 0xdeadbeef, > + 0xdeadbeef, 0xdeadbeef, 0xd2a9baeb, 0xdea0b0e0, > + 0xda8c9ccc, 0xdaa9baeb > +} > +}; > > > /******************************************************************************* > * Hash function performance test configuration section. Each performance > test > @@ -61,7 +75,7 @@ static uint32_t hash_values_crc[2][12] = {{ > */ > #define HASHTEST_ITERATIONS 1000000 > #define MAX_KEYSIZE 64 > -static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc}; > +static rte_hash_function hashtest_funcs[] = {rte_jhash, rte_hash_crc, > rte_hash_xor32}; > static uint32_t hashtest_initvals[] = {0, 0xdeadbeef}; > static uint32_t hashtest_key_lens[] = { > 1, 2, /* Unusual key sizes */ > @@ -85,6 +99,9 @@ get_hash_name(rte_hash_function f) > if (f == rte_hash_crc) > return "rte_hash_crc"; > > + if (f == rte_hash_xor32) > + return "rte_hash_xor32"; > + > return "UnknownHash"; > } > > @@ -173,6 +190,16 @@ verify_precalculated_hash_func_tests(void) > hash_values_crc[j][i], hash); > return -1; > } > + > + hash = rte_hash_xor32(key, hashtest_key_lens[i], > + hashtest_initvals[j]); > + if (hash != hash_values_xor32[j][i]) { > + printf("XOR32 for %u bytes with initial > value 0x%x." > + " Expected 0x%x, but got 0x%x\n", > + hashtest_key_lens[i], > hashtest_initvals[j], > + hash_values_xor32[j][i], hash); > + return -1; > + } > } > } > > diff --git a/lib/hash/rte_hash_xor.h b/lib/hash/rte_hash_xor.h > new file mode 100644 > index 0000000000..366adbe64c > --- /dev/null > +++ b/lib/hash/rte_hash_xor.h > @@ -0,0 +1,87 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2023 Intel Corporation > + */ > + > +#ifndef _RTE_HASH_XOR_H_ > +#define _RTE_HASH_XOR_H_ > + > +/** > + * @file > + * > + * RTE XOR Hash > + */ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +#include > + > +#include > + > +/** > + * Calculate XOR32 hash on user-supplied byte array. > + * > + * @param data > + * Data to perform hash on. > + * @param data_len > + * How many bytes to use to calculate hash value. > + * @param init_val > + * Value to initialise hash generator. > + * @return > + * 32bit calculated hash value. > + */ > +static inline uint32_t > +rte_hash_xor32(const void *data, uint32_t data_len, uint32_t init_val) > +{ > + uint32_t hash32; > + const uint8_t *data8 = data; > + > + /* Minimize byte order conversions depending on data length. */ > + if (data_len >= 8) { > + /* For longer arrays, operate in big endian. */ > + uint64_t hash64 = rte_cpu_to_be_32(init_val); > + > + uint32_t i; > + for (i = 0; i < data_len / 8; i++) { > + hash64 ^= *(const uint64_t *)data8; > + data8 += 8; > + } > + > + if (data_len & 0x4) { > + hash64 ^= *(const uint32_t *)data8; > + data8 += 4; > + } > + > + hash32 = rte_be_to_cpu_32(hash64 ^ (hash64 >> 32)); > + } else { > + /* For shorter arrays, operate in host endian. */ > + hash32 = init_val; > + > + if (data_len & 0x4) { > + hash32 ^= rte_be_to_cpu_32(*(const uint32_t > *)data8); > + data8 += 4; > + } > + } > + > + /* Deal with remaining (< 4) bytes. */ > + > + uint8_t bit_offset = 0; > + > + if (data_len & 0x2) { > + hash32 ^= (uint32_t)rte_be_to_cpu_16(*(const uint16_t > *)data8) << 16; > + data8 += 2; > + bit_offset += 16; > + } > + > + if (data_len & 0x1) > + hash32 ^= (uint32_t)(*(const uint8_t *)data8) << (24 - > bit_offset); > + > + return hash32; > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* _RTE_HASH_XOR_H_ */ > -- > 2.34.1 > > --000000000000a49bc805f53c8fda Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
The reported performance issue is a mystery to m= e. Does anyone have an idea what's going on?

Thanks,=
Bili

On Tue, Feb 21, 2023 at 11:37 AM Bili Dong <qobilidop@gmail.com> wrote:
An XOR32 hash is needed = in the Software Switch (SWX) Pipeline for its
use case in P4. We implement it in this patch so it could be easily
registered in the pipeline later.

Signed-off-by: Bili Dong <qobilidop@gmail.com>
---
=C2=A0.mailmap=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 1 +
=C2=A0app/test/test_hash_functions.c | 33 +++++++++++--
=C2=A0lib/hash/rte_hash_xor.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 87 +++++++++++++= +++++++++++++++++++++
=C2=A03 files changed, 118 insertions(+), 3 deletions(-)
=C2=A0create mode 100644 lib/hash/rte_hash_xor.h

diff --git a/.mailmap b/.mailmap
index a9f4f28fba..3e9bec29d5 100644
--- a/.mailmap
+++ b/.mailmap
@@ -159,6 +159,7 @@ Bernard Iremonger <bernard.iremonger@intel.com>
=C2=A0Bert van Leeuwen <bert.vanleeuwen@netronome.com>
=C2=A0Bhagyada Modali <bhagyada.modali@amd.com>
=C2=A0Bharat Mota <bmota@vmware.com>
+Bili Dong <qob= ilidop@gmail.com>
=C2=A0Bill Hong <= bhong@brocade.com>
=C2=A0Billy McFall <bmcfall@redhat.com>
=C2=A0Billy O'Mahony <billy.o.mahony@intel.com>
diff --git a/app/test/test_hash_functions.c b/app/test/test_hash_functions.= c
index 76d51b6e71..53e296fec4 100644
--- a/app/test/test_hash_functions.c
+++ b/app/test/test_hash_functions.c
@@ -15,6 +15,7 @@
=C2=A0#include <rte_hash.h>
=C2=A0#include <rte_jhash.h>
=C2=A0#include <rte_hash_crc.h>
+#include <rte_hash_xor.h>

=C2=A0#include "test.h"

@@ -22,8 +23,8 @@
=C2=A0 * Hash values calculated for key sizes from array "hashtest_key= _lens"
=C2=A0 * and for initial values from array "hashtest_initvals.
=C2=A0 * Each key will be formed by increasing each byte by 1:
- * e.g.: key size =3D 4, key =3D 0x03020100
- *=C2=A0 =C2=A0 =C2=A0 =C2=A0key size =3D 8, key =3D 0x0706050403020100 + * e.g.: key size =3D 4, key =3D 0x00010203
+ *=C2=A0 =C2=A0 =C2=A0 =C2=A0key size =3D 8, key =3D 0x0001020304050607 =C2=A0 */
=C2=A0static uint32_t hash_values_jhash[2][12] =3D {{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 0x8ba9414b, 0xdf0d39c9,
@@ -51,6 +52,19 @@ static uint32_t hash_values_crc[2][12] =3D {{
=C2=A0 =C2=A0 =C2=A0 =C2=A0 0x789c104f, 0x53028d3e
=C2=A0}
=C2=A0};
+static uint32_t hash_values_xor32[2][12] =3D {{
+=C2=A0 =C2=A0 =C2=A0 =C2=A00x00000000, 0x00010000,
+=C2=A0 =C2=A0 =C2=A0 =C2=A00x00010203, 0x04040404, 0x00000000, 0x00000000,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A00x00000000, 0x00000000, 0x0c040404, 0x000d0e0f,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A00x04212223, 0x04040404
+},
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A00xdeadbeef, 0xdeacbeef,
+=C2=A0 =C2=A0 =C2=A0 =C2=A00xdeacbcec, 0xdaa9baeb, 0xdeadbeef, 0xdeadbeef,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A00xdeadbeef, 0xdeadbeef, 0xd2a9baeb, 0xdea0b0e0,=
+=C2=A0 =C2=A0 =C2=A0 =C2=A00xda8c9ccc, 0xdaa9baeb
+}
+};

=C2=A0/********************************************************************= ***********
=C2=A0 * Hash function performance test configuration section. Each perform= ance test
@@ -61,7 +75,7 @@ static uint32_t hash_values_crc[2][12] =3D {{
=C2=A0 */
=C2=A0#define HASHTEST_ITERATIONS 1000000
=C2=A0#define MAX_KEYSIZE 64
-static rte_hash_function hashtest_funcs[] =3D {rte_jhash, rte_hash_crc}; +static rte_hash_function hashtest_funcs[] =3D {rte_jhash, rte_hash_crc, rt= e_hash_xor32};
=C2=A0static uint32_t hashtest_initvals[] =3D {0, 0xdeadbeef};
=C2=A0static uint32_t hashtest_key_lens[] =3D {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 1, 2,=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0/* Unusual key sizes */
@@ -85,6 +99,9 @@ get_hash_name(rte_hash_function f)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (f =3D=3D rte_hash_crc)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return "rte_ha= sh_crc";

+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (f =3D=3D rte_hash_xor32)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return "rte_ha= sh_xor32";
+
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return "UnknownHash";
=C2=A0}

@@ -173,6 +190,16 @@ verify_precalculated_hash_func_tests(void)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hash_valu= es_crc[j][i], hash);
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 return -1;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 }
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0hash =3D rte_hash_xor32(key, hashtest_key_lens[i],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hashtest_= initvals[j]);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0if (hash !=3D hash_values_xor32[j][i]) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("XOR32 for %u bytes with = initial value 0x%x."
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 " Expected= 0x%x, but got 0x%x\n",
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hashtest_key_le= ns[i], hashtest_initvals[j],
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hash_values_xor= 32[j][i], hash);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -1;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0}
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

diff --git a/lib/hash/rte_hash_xor.h b/lib/hash/rte_hash_xor.h
new file mode 100644
index 0000000000..366adbe64c
--- /dev/null
+++ b/lib/hash/rte_hash_xor.h
@@ -0,0 +1,87 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2023 Intel Corporation
+ */
+
+#ifndef _RTE_HASH_XOR_H_
+#define _RTE_HASH_XOR_H_
+
+/**
+ * @file
+ *
+ * RTE XOR Hash
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include <rte_byteorder.h>
+
+/**
+ * Calculate XOR32 hash on user-supplied byte array.
+ *
+ * @param data
+ *=C2=A0 =C2=A0Data to perform hash on.
+ * @param data_len
+ *=C2=A0 =C2=A0How many bytes to use to calculate hash value.
+ * @param init_val
+ *=C2=A0 =C2=A0Value to initialise hash generator.
+ * @return
+ *=C2=A0 =C2=A032bit calculated hash value.
+ */
+static inline uint32_t
+rte_hash_xor32(const void *data, uint32_t data_len, uint32_t init_val)
+{
+=C2=A0 =C2=A0 =C2=A0 =C2=A0uint32_t hash32;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0const uint8_t *data8 =3D data;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Minimize byte order conversions depending on= data length. */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (data_len >=3D 8) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* For longer array= s, operate in big endian. */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0uint64_t hash64 =3D= rte_cpu_to_be_32(init_val);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0uint32_t i;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i <= ; data_len / 8; i++) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0hash64 ^=3D *(const uint64_t *)data8;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0data8 +=3D 8;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (data_len & = 0x4) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0hash64 ^=3D *(const uint32_t *)data8;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0data8 +=3D 4;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hash32 =3D rte_be_t= o_cpu_32(hash64 ^ (hash64 >> 32));
+=C2=A0 =C2=A0 =C2=A0 =C2=A0} else {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0/* For shorter arra= ys, operate in host endian. */
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hash32 =3D init_val= ;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if (data_len & = 0x4) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0hash32 ^=3D rte_be_to_cpu_32(*(const uint32_t *)data8);
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0data8 +=3D 4;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0/* Deal with remaining (< 4) bytes. */
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0uint8_t bit_offset =3D 0;
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (data_len & 0x2) {
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hash32 ^=3D (uint32= _t)rte_be_to_cpu_16(*(const uint16_t *)data8) << 16;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0data8 +=3D 2;
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bit_offset +=3D 16;=
+=C2=A0 =C2=A0 =C2=A0 =C2=A0}
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0if (data_len & 0x1)
+=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0hash32 ^=3D (uint32= _t)(*(const uint8_t *)data8) << (24 - bit_offset);
+
+=C2=A0 =C2=A0 =C2=A0 =C2=A0return hash32;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_HASH_XOR_H_ */
--
2.34.1

--000000000000a49bc805f53c8fda--