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 466D542CDA; Fri, 16 Jun 2023 19:16:04 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id C86C940E0F; Fri, 16 Jun 2023 19:16:03 +0200 (CEST) Received: from mail-ed1-f49.google.com (mail-ed1-f49.google.com [209.85.208.49]) by mails.dpdk.org (Postfix) with ESMTP id A6B6E40DDB for ; Fri, 16 Jun 2023 19:16:02 +0200 (CEST) Received: by mail-ed1-f49.google.com with SMTP id 4fb4d7f45d1cf-51a1d539ffaso2100492a12.0 for ; Fri, 16 Jun 2023 10:16:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1686935762; x=1689527762; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=OUMKQ0z1/oBnkAAcULyO+Mgvpu7uYLu2npOZ1Xj5vys=; b=U4FBEiaQBG+Eiw7uE5dciqjcHlwP7vjHJj9QBUnhg9/9K+PLSomBg3ppTDiF6OmO2r 7yl7xcd0OOGW8qPlesUfZ9EWe91qQyv17P6pRskzVopJOSGBdNdDTCeVKYs6Z5kRNGnU /qaVo61Vt0oh5Xo0pH/yxSPa/Iaok8hKXrSggxpvdAj7xPFMogK6eTOpEE7gGl/AUEV8 JRSKrsOPsxJjgAjx73DoV3sRNQU1lIhiSJZ061GRoUm2BzTH5qZuOima9qEiZUrl0tf7 0UU3TU6yGo08inUJFlPBqzDKwLyaXQx2lc309JdQt2Sp5LlWnnEhmOnoSbnbmg90Cl+m kkyw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1686935762; x=1689527762; 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=OUMKQ0z1/oBnkAAcULyO+Mgvpu7uYLu2npOZ1Xj5vys=; b=c7Ix+gTg42FuQp9yH3WzFyLonHxglcPSKFr/e9LbbmxNqH0zdzxzev2otwtKrKTON3 QHh9Y2PVjLuz15v5MN1mYVZ38OEm8ZWJEpDBtQHpWBZsF7xW5hx7QhIclP8fJQfbS3au 9xpfyiXPoQK+EC1wkdQvGiBy95Fk98qRfvWVJ/zkWFlA0hcSG7Ia5MXkP7nYaMtBPDzt vDNpcsNuyXwBBhUQB7wUiBkz6FZDzXI5gR/a6sx6KlDlQBko80ckIdWax31cAYNA6/XC OzAygx5d1oDsvY9BnQn83wmKW/chFv3L3oonO5fcOvTVWUWE8XVKdIvDDCvCaaGuTRC9 ZbMA== X-Gm-Message-State: AC+VfDwnMOKyc8PBTwPAR/fWlMsfM0CsTvSmJeXM8jxtsKB/THu9uiYg FXa1qFIHUjpJHOPiMhJ8knVSKeq5xUzf/9wbT28= X-Google-Smtp-Source: ACHHUZ7HawASEM41n5DUYtzVxjwOHuy3c44MK50i2KgUdtkCOhlZRXGJOFIrJkp1FQ9W5alV9HL+x/Mza8KZYu/OZX0= X-Received: by 2002:aa7:d64a:0:b0:50b:c456:a72a with SMTP id v10-20020aa7d64a000000b0050bc456a72amr2490332edr.19.1686935761980; Fri, 16 Jun 2023 10:16:01 -0700 (PDT) MIME-Version: 1.0 References: <20230221175529.644311-1-qobilidop@gmail.com> <20230221193710.717280-1-qobilidop@gmail.com> In-Reply-To: From: Bili Dong Date: Fri, 16 Jun 2023 10:15:25 -0700 Message-ID: Subject: Re: [PATCH v6] hash: add XOR32 hash function To: Vladimir Medvedkin Cc: vladimir.medvedkin@intel.com, dev@dpdk.org, cristian.dumitrescu@intel.com, Bruce Richardson , yipeng1.wang@intel.com, sameh.gobriel@intel.com, Thomas Monjalon Content-Type: multipart/alternative; boundary="000000000000da111e05fe425629" 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 --000000000000da111e05fe425629 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Thanks Vladimir for your suggestion! Indeed your version looks cleaner. I will make the changes (including the new test case you mentioned) and prepare a new version this weekend. Regards, Bili On Thu, Jun 15, 2023 at 10:15=E2=80=AFAM Vladimir Medvedkin wrote: > Hi Bili, > > The rte_hash_xor32() implementation looks a bit messy with respect to byt= e > ordering, i.e. in case when data_len >=3D 8 init_val is byte swapped, but= in > other cases the data is byte swapped. > Maybe it could be implemented like: > > static inline uint32_t > rte_hash_xor32(const void *data, uint32_t data_len, uint32_t init_val) > { > const uint8_t *data8 =3D data; > uint64_t hash64 =3D 0; > uint32_t hash32; > unsigned int i; > > for (i =3D 0; i < data_len / 8; i++) { > hash64 ^=3D *(const uint64_t *)data8; > data8 +=3D 8; > } > > if (data_len & 0x4) { > hash64 ^=3D *(const uint32_t *)data8; > data8 +=3D 4; > } > > int bit_offset =3D 0; > > if (data_len & 0x2) { > hash64 ^=3D *(const uint16_t *)data8; > bit_offset =3D 16; > data8 +=3D 2; > } > > if (data_len & 0x1) > hash64 ^=3D *(const uint8_t *)data8 << bit_offset; > > hash32 =3D (hash64 >> 32) ^ (uint32_t)hash64; > > return rte_be_to_cpu_32(hash32) ^ init_val; > } > > What do you think? > > Also, consider to check in hash_functions_autotest keys with length equal > to 3 (or eq 3 mod 4, for example 7 or 11) > > =D0=B2=D1=82, 21 =D1=84=D0=B5=D0=B2=D1=80. 2023=E2=80=AF=D0=B3. =D0=B2 19= :37, Bili Dong : > >> 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 =3D 4, key =3D 0x03020100 >> - * key size =3D 8, key =3D 0x0706050403020100 >> + * e.g.: key size =3D 4, key =3D 0x00010203 >> + * key size =3D 8, key =3D 0x0001020304050607 >> */ >> static uint32_t hash_values_jhash[2][12] =3D {{ >> 0x8ba9414b, 0xdf0d39c9, >> @@ -51,6 +52,19 @@ static uint32_t hash_values_crc[2][12] =3D {{ >> 0x789c104f, 0x53028d3e >> } >> }; >> +static uint32_t hash_values_xor32[2][12] =3D {{ >> + 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] =3D {{ >> */ >> #define HASHTEST_ITERATIONS 1000000 >> #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, >> rte_hash_xor32}; >> static uint32_t hashtest_initvals[] =3D {0, 0xdeadbeef}; >> static uint32_t hashtest_key_lens[] =3D { >> 1, 2, /* Unusual key sizes */ >> @@ -85,6 +99,9 @@ get_hash_name(rte_hash_function f) >> if (f =3D=3D rte_hash_crc) >> return "rte_hash_crc"; >> >> + if (f =3D=3D 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 =3D rte_hash_xor32(key, hashtest_key_lens[i= ], >> + hashtest_initvals[j]); >> + if (hash !=3D 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 =3D data; >> + >> + /* Minimize byte order conversions depending on data length. */ >> + if (data_len >=3D 8) { >> + /* For longer arrays, operate in big endian. */ >> + uint64_t hash64 =3D rte_cpu_to_be_32(init_val); >> + >> + uint32_t i; >> + for (i =3D 0; i < data_len / 8; i++) { >> + hash64 ^=3D *(const uint64_t *)data8; >> + data8 +=3D 8; >> + } >> + >> + if (data_len & 0x4) { >> + hash64 ^=3D *(const uint32_t *)data8; >> + data8 +=3D 4; >> + } >> + >> + hash32 =3D rte_be_to_cpu_32(hash64 ^ (hash64 >> 32)); >> + } else { >> + /* For shorter arrays, operate in host endian. */ >> + hash32 =3D init_val; >> + >> + if (data_len & 0x4) { >> + hash32 ^=3D rte_be_to_cpu_32(*(const uint32_t >> *)data8); >> + data8 +=3D 4; >> + } >> + } >> + >> + /* Deal with remaining (< 4) bytes. */ >> + >> + uint8_t bit_offset =3D 0; >> + >> + if (data_len & 0x2) { >> + hash32 ^=3D (uint32_t)rte_be_to_cpu_16(*(const uint16_t >> *)data8) << 16; >> + data8 +=3D 2; >> + bit_offset +=3D 16; >> + } >> + >> + if (data_len & 0x1) >> + hash32 ^=3D (uint32_t)(*(const uint8_t *)data8) << (24 - >> bit_offset); >> + >> + return hash32; >> +} >> + >> +#ifdef __cplusplus >> +} >> +#endif >> + >> +#endif /* _RTE_HASH_XOR_H_ */ >> -- >> 2.34.1 >> >> > > -- > Regards, > Vladimir > --000000000000da111e05fe425629 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Thanks Vladimir for your suggestion! Indeed your version l= ooks cleaner.

I will make the changes (including the new= test case you mentioned) and prepare a new version this weekend.

<= /div>
Regards,
Bili

On Thu, Jun 15, 2023 at 10:15= =E2=80=AFAM Vladimir Medvedkin <= medvedkinv@gmail.com> wrote:
Hi Bili,

The rte_hash_xor32() implementation looks a bit messy with respect to byte= ordering, i.e. in case when data_len >=3D 8 init_val is byte swapped, b= ut in other cases the data is byte swapped.
Maybe it could be imp= lemented like:

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=A0 const uint8_t *data8 =3D data;
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 uint64_t hash64 =3D 0;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 uint32_= t hash32;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 unsigned int i;

=C2=A0 =C2= =A0 =C2=A0 =C2=A0 for (i =3D 0; i < data_len / 8; i++) {
=C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hash64 ^=3D *(const uint64_t = *)data8;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data8 += =3D 8;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 = if (data_len & 0x4) {
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 hash64 ^=3D *(const uint32_t *)data8;
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data8 +=3D 4;
=C2=A0 =C2=A0 =C2=A0 = =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 int bit_offset =3D 0;

= =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (data_len & 0x2) {
=C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 hash64 ^=3D *(const uint16_t *)data8= ;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 bit_offset =3D= 16;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 data8 +=3D = 2;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 }

=C2=A0 =C2=A0 =C2=A0 =C2=A0 if (= data_len & 0x1)
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 hash64 ^=3D *(const uint8_t *)data8 << bit_offset;

=C2=A0 = =C2=A0 =C2=A0 =C2=A0 hash32 =3D (hash64 >> 32) ^ (uint32_t)hash64;
=C2=A0 =C2=A0 =C2=A0 =C2=A0 return rte_be_to_cpu_32(hash32) ^ init_val= ;
}

What do you think?

=
Also, consider to check in=C2=A0hash_functions_autotest keys with leng= th equal to 3 (or eq 3 mod 4, for example 7 or 11)

=D0=B2=D1=82, 21 =D1=84= =D0=B5=D0=B2=D1=80. 2023=E2=80=AF=D0=B3. =D0=B2 19:37, Bili Dong <qobilidop@gmail.com&= gt;:
An XOR32 ha= sh 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



--
Regards,
Vladimir
--000000000000da111e05fe425629--