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 A219343B4F; Mon, 19 Feb 2024 22:29:08 +0100 (CET) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7B94040275; Mon, 19 Feb 2024 22:29:08 +0100 (CET) Received: from mail-oa1-f54.google.com (mail-oa1-f54.google.com [209.85.160.54]) by mails.dpdk.org (Postfix) with ESMTP id BEF6540263 for ; Mon, 19 Feb 2024 22:29:07 +0100 (CET) Received: by mail-oa1-f54.google.com with SMTP id 586e51a60fabf-20503dc09adso3134141fac.2 for ; Mon, 19 Feb 2024 13:29:07 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1708378147; x=1708982947; darn=dpdk.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=xN1gumXsrir5pnQ939h6YfPmU2G5nMzIz/EGSIPoESQ=; b=VnrPamcXtRSLSg/zwKkgn1HxG/y7g/gfv9RJUgdt9+tiICz++X4V8/rVJWYdDQ6Wwx ogi7i2LA5cnmo77Old6aUbw6/pIzYKGxFVLcbGE4PZKqOq8+aZLzRdRIR6Jgmd5vMSPb g5YsAvThZKb7QZxIo7rAnJtgFQ7mukWLh46Gb9KnlDxSmtsNV0HRoK7YxXUACcE7Gicm nSb2D4No1Gi4FvPg1dAJAxdPTZaQmpMZ1Ptxpl8ZpUpXEbTqObyd0sIHJhYE2dG/SxK3 d2Ji/qJqLk5lhLAZWnq0ds5caF8wIY49jm+9PUGY/wm345ZFXU1zLjadRXM0LNirg+OV I7ow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1708378147; x=1708982947; 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=xN1gumXsrir5pnQ939h6YfPmU2G5nMzIz/EGSIPoESQ=; b=WGbs26/tL7is7P8M8azLGfWuVwi60OZ6FasMNMY4cYScdM/vPdd/pBmBH9zSc/F6h7 veIt1OKC5n6IlB3A5TyW49hdVENtvRDF/JsEvnQSxVq/7UfnkIIBiipSMOzgvxw/Zvxy BJpwMqwnoT24O+FBatDjpNeVwtSm24k8QR2yHbbMCab4BQ7I5ioT15XSW9W28WYWKrQV gwdNlcs55PTZkekxhEN4HtUAPMVirRzmQJIym3WWC0z1T0jdmo+ewENbbv/oVkH0V2Ru Sol1ePwSiuBzW9c5ZAmZZ6TlfnZkQ2oPyxxnL4YkIYNIGy4jNlYDoxJmtiaB7SLTxE0D peEA== X-Gm-Message-State: AOJu0YxoigrlnLG+LPG0c2b0ZSmpeFu1otupIdwof6cOAYT7epBBgi8t TKAiM0bQb0ZnCcjWSl5CkTUN9kKByfTeCQI6O/TYHfiEuOvId14IdOXTNsW/6qlI2rK/Wv5rDIR vkm9h2NrEeYI1vD+YJzJY36AmXhs= X-Google-Smtp-Source: AGHT+IFUv00U4Np6bxlWVW2HbwZNJ6SCctu9Evra1rcTp/mULW4BE8WaorxX3dUuUMb1o6FoY18KCpJfavFcDwiEYpY= X-Received: by 2002:a05:6870:c110:b0:21e:8cd7:50e2 with SMTP id f16-20020a056870c11000b0021e8cd750e2mr8286917oad.26.1708378146844; Mon, 19 Feb 2024 13:29:06 -0800 (PST) MIME-Version: 1.0 References: <20240207153340.34146-1-aomeryamac@gmail.com> In-Reply-To: From: =?UTF-8?B?QWJkdWxsYWggw5ZtZXIgWWFtYcOn?= Date: Tue, 20 Feb 2024 00:28:55 +0300 Message-ID: Subject: Re: [PATCH] lib/hash,lib/rcu: feature hidden key count in hash To: "Medvedkin, Vladimir" Cc: dev@dpdk.org, Honnappa Nagarahalli , Yipeng Wang , Sameh Gobriel , Bruce Richardson , Thomas Monjalon Content-Type: multipart/alternative; boundary="00000000000095b3d10611c2c894" 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 --00000000000095b3d10611c2c894 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hello, Let me explain a use case; I have a hash table whose key value is IP addresses, and data (let's say the username of the IP) is related to the IP address. The key point is matching these data with flows. Flows are dynamic, and this hash table is dynamic, as well; both can change anytime. For example, when a flow starts, we look up the hash table with the corresponding IP and retrieve the username. We need to hold this username until the flow terminates, although we removed this IP key from the hash table (multithread). That's why we have RCU and defer queue is necessary for high performance. In my application, I need to know the number of IP-username entries. These numbers can be calculated by rte_hash_count - defer queue size. I think if you need a non-blocking and multithreaded hash table, an RCU-enabled hash table is necessary. Also, this API is necessary if you need to get the actual matchable size. On Mon, Feb 19, 2024 at 8:36=E2=80=AFPM Medvedkin, Vladimir < vladimir.medvedkin@intel.com> wrote: > Hi Abdullah, > > Could you please tell more about use cases where this API may be useful? > > >a new API to get the hidden key count in the hash table if the rcu qsbr > is enabled > > Here in commit message and down below in doxygen comments, I think this > statement should be more specific because rcu can be created with > RTE_HASH_QSBR_MODE_SYNC mode i.e. without defer queue. > > Also, new API must be reflected in release notes > > On 07/02/2024 15:33, Abdullah =C3=96mer Yama=C3=A7 wrote: > > This patch introduce a new API to get the hidden key count in the hash > > table if the rcu qsbr is enabled. When using rte_hash_count with rcu > > qsbr enabled, it will return the number of elements that are not in the > > free queue. Unless rte_rcu_qsbr_dq_reclaim is called, the number of > > elements in the defer queue will not be counted and freed. Therefore I > > added a new API to get the number of hidden (defer queue) elements > > in the hash table. Then the user can calculate the total number of > > elements that are available in the hash table. > > > > Signed-off-by: Abdullah =C3=96mer Yama=C3=A7 > > > > --- > > Cc: Honnappa Nagarahalli > > Cc: Yipeng Wang > > Cc: Sameh Gobriel > > Cc: Bruce Richardson > > Cc: Vladimir Medvedkin > > --- > > lib/hash/rte_cuckoo_hash.c | 9 +++++++++ > > lib/hash/rte_hash.h | 13 +++++++++++++ > > lib/hash/version.map | 1 + > > lib/rcu/rte_rcu_qsbr.c | 8 ++++++++ > > lib/rcu/rte_rcu_qsbr.h | 11 +++++++++++ > > lib/rcu/version.map | 1 + > > 6 files changed, 43 insertions(+) > > > > diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c > > index 70456754c4..3553f3efc7 100644 > > --- a/lib/hash/rte_cuckoo_hash.c > > +++ b/lib/hash/rte_cuckoo_hash.c > > @@ -555,6 +555,15 @@ rte_hash_max_key_id(const struct rte_hash *h) > > return h->entries; > > } > > > > +int32_t > > +rte_hash_dq_count(const struct rte_hash *h) > > +{ > > + if (h->dq =3D=3D NULL) > input arguments must be checked since this is a public API, the same is > true for rte_rcu_qsbr_dq_count() > > + return -EINVAL; > why not just return 0? > > + > > + return rte_rcu_qsbr_dq_count(h->dq); > > +} > > + > > int32_t > > rte_hash_count(const struct rte_hash *h) > > { > > diff --git a/lib/hash/rte_hash.h b/lib/hash/rte_hash.h > > index 7ecc021111..8ea97e297d 100644 > > --- a/lib/hash/rte_hash.h > > +++ b/lib/hash/rte_hash.h > > @@ -193,6 +193,19 @@ rte_hash_free(struct rte_hash *h); > > void > > rte_hash_reset(struct rte_hash *h); > > > > + > > +/** > > + * Return the number of records in the defer queue of the hash table > > + * if RCU is enabled. > > + * @param h > > + * Hash table to query from > > + * @return > > + * - -EINVAL if parameters are invalid > > + * - A value indicating how many records were inserted in the table. > did you mean how many records are kept in defer queue? > > + */ > > +int32_t > > +rte_hash_dq_count(const struct rte_hash *h); > > + > > /** > > * Return the number of keys in the hash table > > * @param h > > diff --git a/lib/hash/version.map b/lib/hash/version.map > > index 6b2afebf6b..7f7b158cf1 100644 > > --- a/lib/hash/version.map > > +++ b/lib/hash/version.map > > @@ -9,6 +9,7 @@ DPDK_24 { > > rte_hash_add_key_with_hash; > > rte_hash_add_key_with_hash_data; > > rte_hash_count; > > + rte_hash_dq_count; > new API must introduced as an experimental API. The same is true for > rte_rcu_qsbr_dq_count() > > rte_hash_crc32_alg; > > rte_hash_crc_set_alg; > > rte_hash_create; > > diff --git a/lib/rcu/rte_rcu_qsbr.c b/lib/rcu/rte_rcu_qsbr.c > > index bd0b83be0c..89f8da4c4c 100644 > > --- a/lib/rcu/rte_rcu_qsbr.c > > +++ b/lib/rcu/rte_rcu_qsbr.c > > @@ -450,6 +450,14 @@ rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq= , > unsigned int n, > > return 0; > > } > > > > +/** > > + * Return the number of entries in a defer queue. > > + */ > > +unsigned int rte_rcu_qsbr_dq_count(struct rte_rcu_qsbr_dq *dq) > > +{ > > + return rte_ring_count(dq->r); > > +} > > + > > /* Delete a defer queue. */ > > int > > rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq) > > diff --git a/lib/rcu/rte_rcu_qsbr.h b/lib/rcu/rte_rcu_qsbr.h > > index 23c9f89805..ed5a590edd 100644 > > --- a/lib/rcu/rte_rcu_qsbr.h > > +++ b/lib/rcu/rte_rcu_qsbr.h > > @@ -794,6 +794,17 @@ int > > rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq, unsigned int n, > > unsigned int *freed, unsigned int *pending, unsigned int > *available); > > > > +/** > > + * Return the number of entries in a defer queue. > > + * > > + * @param dq > > + * Defer queue. > > + * @return > > + * The number of entries in the defer queue. > > + */ > > +unsigned int > > +rte_rcu_qsbr_dq_count(struct rte_rcu_qsbr_dq *dq); > > + > > /** > > * Delete a defer queue. > > * > > diff --git a/lib/rcu/version.map b/lib/rcu/version.map > > index 982ffd59d9..f410ab41e7 100644 > > --- a/lib/rcu/version.map > > +++ b/lib/rcu/version.map > > @@ -5,6 +5,7 @@ DPDK_24 { > > rte_rcu_qsbr_dq_create; > > rte_rcu_qsbr_dq_delete; > > rte_rcu_qsbr_dq_enqueue; > > + rte_rcu_qsbr_dq_count; > > rte_rcu_qsbr_dq_reclaim; > > rte_rcu_qsbr_dump; > > rte_rcu_qsbr_get_memsize; > > -- > Regards, > Vladimir > > --00000000000095b3d10611c2c894 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
Hello,

Let me explain a use case;

I have a hash table whose key value is IP addresses, and data (let's = say the username of the IP) is related to the IP address. The key point is = matching these data with flows. Flows are dynamic, and this hash table is d= ynamic, as well; both can change anytime. For=C2=A0example, when a flow sta= rts, we look up the hash table with the=C2=A0corresponding=C2=A0IP and retr= ieve=C2=A0the username. We need to hold this username until the flow termin= ates, although we removed this IP key from the hash table (multithread). Th= at's why we have RCU and defer queue is necessary for high performance.= In my application, I need to know the number of IP-username entries. These= numbers can be calculated by rte_hash_count - defer queue size.

I t= hink if you need a non-blocking and multithreaded hash table, an RCU-enable= d hash table is necessary. Also, this API is necessary if you need to get t= he actual matchable size.





On Mon, Feb 19, 2= 024 at 8:36=E2=80=AFPM Medvedkin, Vladimir <vladimir.medvedkin@intel.com> wrote:
Hi Abdullah,

Could you please tell more about use cases where this API may be useful?
>a new API to get the hidden key count in the hash table if the rcu qsbr= is enabled

Here in commit message and down below in doxygen comments, I think this statement should be more specific because rcu can be created with
RTE_HASH_QSBR_MODE_SYNC mode i.e. without defer queue.

Also, new API must be reflected in release notes

On 07/02/2024 15:33, Abdullah =C3=96mer Yama=C3=A7 wrote:
> This patch introduce a new API to get the hidden key count in the hash=
> table if the rcu qsbr is enabled. When using rte_hash_count with rcu > qsbr enabled, it will return the number of elements that are not in th= e
> free queue. Unless rte_rcu_qsbr_dq_reclaim is called, the number of > elements in the defer queue will not be counted and freed. Therefore I=
> added a new API to get the number of hidden (defer queue) elements
> in the hash table. Then the user can calculate the total number of
> elements that are available in the hash table.
>
> Signed-off-by: Abdullah =C3=96mer Yama=C3=A7 <aomeryamac@gmail.com>
>
> ---
> Cc: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Cc: Yipeng Wang <yipeng1.wang@intel.com>
> Cc: Sameh Gobriel <sameh.gobriel@intel.com>
> Cc: Bruce Richardson <bruce.richardson@intel.com>
> Cc: Vladimir Medvedkin <vladimir.medvedkin@intel.com>
> ---
>=C2=A0 =C2=A0lib/hash/rte_cuckoo_hash.c |=C2=A0 9 +++++++++
>=C2=A0 =C2=A0lib/hash/rte_hash.h=C2=A0 =C2=A0 =C2=A0 =C2=A0 | 13 ++++++= +++++++
>=C2=A0 =C2=A0lib/hash/version.map=C2=A0 =C2=A0 =C2=A0 =C2=A0|=C2=A0 1 +=
>=C2=A0 =C2=A0lib/rcu/rte_rcu_qsbr.c=C2=A0 =C2=A0 =C2=A0|=C2=A0 8 ++++++= ++
>=C2=A0 =C2=A0lib/rcu/rte_rcu_qsbr.h=C2=A0 =C2=A0 =C2=A0| 11 +++++++++++=
>=C2=A0 =C2=A0lib/rcu/version.map=C2=A0 =C2=A0 =C2=A0 =C2=A0 |=C2=A0 1 +=
>=C2=A0 =C2=A06 files changed, 43 insertions(+)
>
> diff --git a/lib/hash/rte_cuckoo_hash.c b/lib/hash/rte_cuckoo_hash.c > index 70456754c4..3553f3efc7 100644
> --- a/lib/hash/rte_cuckoo_hash.c
> +++ b/lib/hash/rte_cuckoo_hash.c
> @@ -555,6 +555,15 @@ rte_hash_max_key_id(const struct rte_hash *h)
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return h->ent= ries;
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> +int32_t
> +rte_hash_dq_count(const struct rte_hash *h)
> +{
> +=C2=A0 =C2=A0 =C2=A0if (h->dq =3D=3D NULL)
input arguments must be checked since this is a public API, the same is true for rte_rcu_qsbr_dq_count()
> +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return -EINVAL;
why not just return 0?
> +
> +=C2=A0 =C2=A0 =C2=A0return rte_rcu_qsbr_dq_count(h->dq);
> +}
> +
>=C2=A0 =C2=A0int32_t
>=C2=A0 =C2=A0rte_hash_count(const struct rte_hash *h)
>=C2=A0 =C2=A0{
> diff --git a/lib/hash/rte_hash.h b/lib/hash/rte_hash.h
> index 7ecc021111..8ea97e297d 100644
> --- a/lib/hash/rte_hash.h
> +++ b/lib/hash/rte_hash.h
> @@ -193,6 +193,19 @@ rte_hash_free(struct rte_hash *h);
>=C2=A0 =C2=A0void
>=C2=A0 =C2=A0rte_hash_reset(struct rte_hash *h);
>=C2=A0 =C2=A0
> +
> +/**
> + * Return the number of records in the defer queue of the hash table<= br> > + * if RCU is enabled.
> + * @param h
> + *=C2=A0 Hash table to query from
> + * @return
> + *=C2=A0 =C2=A0- -EINVAL if parameters are invalid
> + *=C2=A0 =C2=A0- A value indicating how many records were inserted in= the table.
did you mean how many records are kept in defer queue?
> + */
> +int32_t
> +rte_hash_dq_count(const struct rte_hash *h);
> +
>=C2=A0 =C2=A0/**
>=C2=A0 =C2=A0 * Return the number of keys in the hash table
>=C2=A0 =C2=A0 * @param h
> diff --git a/lib/hash/version.map b/lib/hash/version.map
> index 6b2afebf6b..7f7b158cf1 100644
> --- a/lib/hash/version.map
> +++ b/lib/hash/version.map
> @@ -9,6 +9,7 @@ DPDK_24 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_add_key_with_hash;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_add_key_with_hash_data;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_count;
> +=C2=A0 =C2=A0 =C2=A0rte_hash_dq_count;
new API must introduced as an experimental API. The same is true for
rte_rcu_qsbr_dq_count()
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_crc32_alg;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_crc_set_alg;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_hash_create;
> diff --git a/lib/rcu/rte_rcu_qsbr.c b/lib/rcu/rte_rcu_qsbr.c
> index bd0b83be0c..89f8da4c4c 100644
> --- a/lib/rcu/rte_rcu_qsbr.c
> +++ b/lib/rcu/rte_rcu_qsbr.c
> @@ -450,6 +450,14 @@ rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *d= q, unsigned int n,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0return 0;
>=C2=A0 =C2=A0}
>=C2=A0 =C2=A0
> +/**
> + * Return the number of entries in a defer queue.
> + */
> +unsigned int rte_rcu_qsbr_dq_count(struct rte_rcu_qsbr_dq *dq)
> +{
> +=C2=A0 =C2=A0 =C2=A0return rte_ring_count(dq->r);
> +}
> +
>=C2=A0 =C2=A0/* Delete a defer queue. */
>=C2=A0 =C2=A0int
>=C2=A0 =C2=A0rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq)
> diff --git a/lib/rcu/rte_rcu_qsbr.h b/lib/rcu/rte_rcu_qsbr.h
> index 23c9f89805..ed5a590edd 100644
> --- a/lib/rcu/rte_rcu_qsbr.h
> +++ b/lib/rcu/rte_rcu_qsbr.h
> @@ -794,6 +794,17 @@ int
>=C2=A0 =C2=A0rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq, unsign= ed int n,
>=C2=A0 =C2=A0 =C2=A0 =C2=A0unsigned int *freed, unsigned int *pending, = unsigned int *available);
>=C2=A0 =C2=A0
> +/**
> + * Return the number of entries in a defer queue.
> + *
> + * @param dq
> + *=C2=A0 =C2=A0Defer queue.
> + * @return
> + *=C2=A0 =C2=A0The number of entries in the defer queue.
> + */
> +unsigned int
> +rte_rcu_qsbr_dq_count(struct rte_rcu_qsbr_dq *dq);
> +
>=C2=A0 =C2=A0/**
>=C2=A0 =C2=A0 * Delete a defer queue.
>=C2=A0 =C2=A0 *
> diff --git a/lib/rcu/version.map b/lib/rcu/version.map
> index 982ffd59d9..f410ab41e7 100644
> --- a/lib/rcu/version.map
> +++ b/lib/rcu/version.map
> @@ -5,6 +5,7 @@ DPDK_24 {
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dq_create;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dq_delete;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dq_enqueue;
> +=C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dq_count;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dq_reclaim;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_dump;
>=C2=A0 =C2=A0 =C2=A0 =C2=A0rte_rcu_qsbr_get_memsize;

--
Regards,
Vladimir

--00000000000095b3d10611c2c894--