* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-23 10:21 0% ` Olivier Matz
@ 2019-10-23 15:00 0% ` Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-23 15:00 UTC (permalink / raw)
To: Olivier Matz
Cc: Wang, Haiyue, Ananyev, Konstantin, dev, Andrew Rybchenko,
Richardson, Bruce, Jerin Jacob Kollanukkaran, Wiles, Keith,
Morten Brørup, Thomas Monjalon
On Wed, 23 Oct 2019 12:21:43 +0200
Olivier Matz <olivier.matz@6wind.com> wrote:
> On Wed, Oct 23, 2019 at 03:16:13AM +0000, Wang, Haiyue wrote:
> > > -----Original Message-----
> > > From: Ananyev, Konstantin
> > > Sent: Wednesday, October 23, 2019 06:52
> > > To: Olivier Matz <olivier.matz@6wind.com>; dev@dpdk.org
> > > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>; Wang,
> > > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > > <keith.wiles@intel.com>; Morten Brørup <mb@smartsharesystems.com>; Stephen Hemminger
> > > <stephen@networkplumber.org>; Thomas Monjalon <thomas@monjalon.net>
> > > Subject: RE: [PATCH v2] mbuf: support dynamic fields and flags
> > >
> > >
> > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > structure is limited, it is not possible to have a field for each
> > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > or ABI.
> > > >
> > > > This commit addresses these issues, by enabling the dynamic registration
> > > > of fields or flags:
> > > >
> > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > given size (>= 1 byte) and alignment constraint.
> > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > >
> > > > The typical use case is a PMD that registers space for an offload
> > > > feature, when the application requests to enable this feature. As
> > > > the space in mbuf is limited, the space should only be reserved if it
> > > > is going to be used (i.e when the application explicitly asks for it).
> > > >
> > > > The registration can be done at any moment, but it is not possible
> > > > to unregister fields or flags for now.
> > > >
> > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > > ---
> > > >
> > > > v2
> > > >
> > > > * Rebase on top of master: solve conflict with Stephen's patchset
> > > > (packet copy)
> > > > * Add new apis to register a dynamic field/flag at a specific place
> > > > * Add a dump function (sugg by David)
> > > > * Enhance field registration function to select the best offset, keeping
> > > > large aligned zones as much as possible (sugg by Konstantin)
> > > > * Use a size_t and unsigned int instead of int when relevant
> > > > (sugg by Konstantin)
> > > > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > > > (sugg by Konstantin)
> > > > * Remove unused argument in private function (sugg by Konstantin)
> > > > * Fix and simplify locking (sugg by Konstantin)
> > > > * Fix minor typo
> > > >
> > > > rfc -> v1
> > > >
> > > > * Rebase on top of master
> > > > * Change registration API to use a structure instead of
> > > > variables, getting rid of #defines (Stephen's comment)
> > > > * Update flag registration to use a similar API as fields.
> > > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > > * Add a debug log at registration
> > > > * Add some words in release note
> > > > * Did some performance tests (sugg. by Andrew):
> > > > On my platform, reading a dynamic field takes ~3 cycles more
> > > > than a static field, and ~2 cycles more for writing.
> > > >
> > > > app/test/test_mbuf.c | 145 ++++++-
> > > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > > lib/librte_mbuf/Makefile | 2 +
> > > > lib/librte_mbuf/meson.build | 6 +-
> > > > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > > > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > > > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > > > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > > > 8 files changed, 959 insertions(+), 5 deletions(-)
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > > >
> > > > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > > > index b9c2b2500..01cafad59 100644
> > > > --- a/app/test/test_mbuf.c
> > > > +++ b/app/test/test_mbuf.c
> > > > @@ -28,6 +28,7 @@
> > > > #include <rte_random.h>
> > > > #include <rte_cycles.h>
> > > > #include <rte_malloc.h>
> > > > +#include <rte_mbuf_dyn.h>
> > > >
> >
> > [snip]
> > > > +int
> > > > +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> > > > + unsigned int req)
> > > > +{
> > > > + int ret;
> > > > +
> > > > + if (req != UINT_MAX && req >= 64) {
> > >
> > > Might be better to replace 64 with something like sizeof(mbuf->ol_flags) * CHAR_BIT or so.
> >
> > Might introduce a new macro like kernel:
> >
> > /**
> > * FIELD_SIZEOF - get the size of a struct's field
> > * @t: the target struct
> > * @f: the target struct's field
> > * Return: the size of @f in the struct definition without having a
> > * declared instance of @t.
> > */
> > #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
> >
> > Then: FIELD_SIZEOF(rte_mbuf, ol_flags) * CHAR_BIT
>
> Good idea, thanks
>
Kernel is replacing FIELD_SIZEOF with sizeof_member
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-23 12:00 0% ` Shahaf Shuler
@ 2019-10-23 13:33 0% ` Olivier Matz
0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2019-10-23 13:33 UTC (permalink / raw)
To: Shahaf Shuler
Cc: dev, Andrew Rybchenko, Bruce Richardson, Wang, Haiyue,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
Hi Shahaf,
On Wed, Oct 23, 2019 at 12:00:30PM +0000, Shahaf Shuler wrote:
> Hi Olivier,
>
> Thursday, October 17, 2019 5:42 PM, Olivier Matz:
> > Subject: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
> >
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each feature. Also,
> > changing fields in the mbuf structure can break the API or ABI.
> >
> > This commit addresses these issues, by enabling the dynamic registration of
> > fields or flags:
> >
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> > given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> >
> > The typical use case is a PMD that registers space for an offload feature,
> > when the application requests to enable this feature. As the space in mbuf is
> > limited, the space should only be reserved if it is going to be used (i.e when
> > the application explicitly asks for it).
>
> According to description, the dynamic field enables custom application and supported PMDs to use the dynamic part of the mbuf for their specific needs.
> However the mechanism to report and activate the field/flag registration comes from the general OFFLOAD flags.
>
> Maybe it will be better to an option to query and select dynamic fields for PMD outside of the standard ethdev offload flags?
It is not mandatory to use the ethdev layer to register a dynamic field
or flag in the mbuf. It is just the typical use case.
It can also be enabled when using a library that have specific needs,
for instance, you call rte_reorder_init(), and it will register the
sequence number dynamic field.
An application that requires a specific mbuf field can also do the
registration by itself.
In other words, when you initialize a subpart that needs a dynamic field
or flag, you have to do the registration there.
>
> >
> > The registration can be done at any moment, but it is not possible to
> > unregister fields or flags for now.
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Acked-by: Thomas Monjalon <thomas@monjalon.net>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 0/3] net definitions fixes
2019-10-23 13:00 0% ` David Marchand
@ 2019-10-23 13:19 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-23 13:19 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Olivier Matz
On 10/23/2019 2:00 PM, David Marchand wrote:
> On Wed, Oct 23, 2019 at 2:57 PM David Marchand
> <david.marchand@redhat.com> wrote:
>>
>> On Wed, Oct 23, 2019 at 2:12 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>>
>>> On 10/23/2019 9:51 AM, David Marchand wrote:
>>>> Small patchset with fixes after inspecting the librte_net.
>>>> I copied stable@dpdk.org in the 2nd patch for information only.
>>>>
>>>
>>> Overall lgtm. And this release seems the one to make these changes, and we
>>> already break the API for net library on this release BUT should we update the
>>> ABIVER for net library?
>>
>> This patchset breaks API by renaming structures/defines and remove
>> some constant defines.
>> ABI should be the same ?
>
> But I suppose adding some words in the release notes can't be wrong.
>
You are right, there is not point on increasing ABIVER since only API is
changing, +1 to document change in release notes. (also for previous rte_esp change)
Thanks,
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 8/8] log: hide internal log structure
2019-10-22 9:32 3% ` [dpdk-dev] [PATCH 8/8] log: hide internal log structure David Marchand
2019-10-22 16:35 0% ` Stephen Hemminger
@ 2019-10-23 13:02 0% ` David Marchand
1 sibling, 0 replies; 200+ results
From: David Marchand @ 2019-10-23 13:02 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Burakov, Anatoly, Thomas Monjalon
On Tue, Oct 22, 2019 at 11:33 AM David Marchand
<david.marchand@redhat.com> wrote:
>
> No need to expose rte_logs, hide it and remove it from the current ABI.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> lib/librte_eal/common/eal_common_log.c | 23 ++++++++++++++++-------
> lib/librte_eal/common/include/rte_log.h | 20 +++-----------------
> lib/librte_eal/rte_eal_version.map | 1 -
> 3 files changed, 19 insertions(+), 25 deletions(-)
Note to self.
If we go with this patch, an update of the release notes is missing.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 0/3] net definitions fixes
2019-10-23 12:57 3% ` David Marchand
@ 2019-10-23 13:00 0% ` David Marchand
2019-10-23 13:19 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-10-23 13:00 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, Olivier Matz
On Wed, Oct 23, 2019 at 2:57 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> On Wed, Oct 23, 2019 at 2:12 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> >
> > On 10/23/2019 9:51 AM, David Marchand wrote:
> > > Small patchset with fixes after inspecting the librte_net.
> > > I copied stable@dpdk.org in the 2nd patch for information only.
> > >
> >
> > Overall lgtm. And this release seems the one to make these changes, and we
> > already break the API for net library on this release BUT should we update the
> > ABIVER for net library?
>
> This patchset breaks API by renaming structures/defines and remove
> some constant defines.
> ABI should be the same ?
But I suppose adding some words in the release notes can't be wrong.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 0/3] net definitions fixes
@ 2019-10-23 12:57 3% ` David Marchand
2019-10-23 13:00 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-10-23 12:57 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, Olivier Matz
On Wed, Oct 23, 2019 at 2:12 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 10/23/2019 9:51 AM, David Marchand wrote:
> > Small patchset with fixes after inspecting the librte_net.
> > I copied stable@dpdk.org in the 2nd patch for information only.
> >
>
> Overall lgtm. And this release seems the one to make these changes, and we
> already break the API for net library on this release BUT should we update the
> ABIVER for net library?
This patchset breaks API by renaming structures/defines and remove
some constant defines.
ABI should be the same ?
--
David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-17 14:42 3% ` [dpdk-dev] [PATCH v2] " Olivier Matz
2019-10-18 2:47 0% ` Wang, Haiyue
2019-10-22 22:51 0% ` Ananyev, Konstantin
@ 2019-10-23 12:00 0% ` Shahaf Shuler
2019-10-23 13:33 0% ` Olivier Matz
2 siblings, 1 reply; 200+ results
From: Shahaf Shuler @ 2019-10-23 12:00 UTC (permalink / raw)
To: Olivier Matz, dev
Cc: Andrew Rybchenko, Bruce Richardson, Wang, Haiyue,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
Hi Olivier,
Thursday, October 17, 2019 5:42 PM, Olivier Matz:
> Subject: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
>
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each feature. Also,
> changing fields in the mbuf structure can break the API or ABI.
>
> This commit addresses these issues, by enabling the dynamic registration of
> fields or flags:
>
> - a dynamic field is a named area in the rte_mbuf structure, with a
> given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
>
> The typical use case is a PMD that registers space for an offload feature,
> when the application requests to enable this feature. As the space in mbuf is
> limited, the space should only be reserved if it is going to be used (i.e when
> the application explicitly asks for it).
According to description, the dynamic field enables custom application and supported PMDs to use the dynamic part of the mbuf for their specific needs.
However the mechanism to report and activate the field/flag registration comes from the general OFFLOAD flags.
Maybe it will be better to an option to query and select dynamic fields for PMD outside of the standard ethdev offload flags?
>
> The registration can be done at any moment, but it is not possible to
> unregister fields or flags for now.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>
> v2
>
> * Rebase on top of master: solve conflict with Stephen's patchset
> (packet copy)
> * Add new apis to register a dynamic field/flag at a specific place
> * Add a dump function (sugg by David)
> * Enhance field registration function to select the best offset, keeping
> large aligned zones as much as possible (sugg by Konstantin)
> * Use a size_t and unsigned int instead of int when relevant
> (sugg by Konstantin)
> * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> (sugg by Konstantin)
> * Remove unused argument in private function (sugg by Konstantin)
> * Fix and simplify locking (sugg by Konstantin)
> * Fix minor typo
>
> rfc -> v1
>
> * Rebase on top of master
> * Change registration API to use a structure instead of
> variables, getting rid of #defines (Stephen's comment)
> * Update flag registration to use a similar API as fields.
> * Change max name length from 32 to 64 (sugg. by Thomas)
> * Enhance API documentation (Haiyue's and Andrew's comments)
> * Add a debug log at registration
> * Add some words in release note
> * Did some performance tests (sugg. by Andrew):
> On my platform, reading a dynamic field takes ~3 cycles more
> than a static field, and ~2 cycles more for writing.
>
> app/test/test_mbuf.c | 145 ++++++-
> doc/guides/rel_notes/release_19_11.rst | 7 +
> lib/librte_mbuf/Makefile | 2 +
> lib/librte_mbuf/meson.build | 6 +-
> lib/librte_mbuf/rte_mbuf.h | 23 +-
> lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> lib/librte_mbuf/rte_mbuf_version.map | 7 +
> 8 files changed, 959 insertions(+), 5 deletions(-) create mode 100644
> lib/librte_mbuf/rte_mbuf_dyn.c create mode 100644
> lib/librte_mbuf/rte_mbuf_dyn.h
>
> diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c index
> b9c2b2500..01cafad59 100644
> --- a/app/test/test_mbuf.c
> +++ b/app/test/test_mbuf.c
> @@ -28,6 +28,7 @@
> #include <rte_random.h>
> #include <rte_cycles.h>
> #include <rte_malloc.h>
> +#include <rte_mbuf_dyn.h>
>
> #include "test.h"
>
> @@ -657,7 +658,6 @@ test_attach_from_different_pool(struct
> rte_mempool *pktmbuf_pool,
> rte_pktmbuf_free(clone2);
> return -1;
> }
> -#undef GOTO_FAIL
>
> /*
> * test allocation and free of mbufs
> @@ -1276,6 +1276,143 @@ test_tx_offload(void)
> return (v1 == v2) ? 0 : -EINVAL;
> }
>
> +static int
> +test_mbuf_dyn(struct rte_mempool *pktmbuf_pool) {
> + const struct rte_mbuf_dynfield dynfield = {
> + .name = "test-dynfield",
> + .size = sizeof(uint8_t),
> + .align = __alignof__(uint8_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield2 = {
> + .name = "test-dynfield2",
> + .size = sizeof(uint16_t),
> + .align = __alignof__(uint16_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield3 = {
> + .name = "test-dynfield3",
> + .size = sizeof(uint8_t),
> + .align = __alignof__(uint8_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield_fail_big = {
> + .name = "test-dynfield-fail-big",
> + .size = 256,
> + .align = 1,
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield_fail_align = {
> + .name = "test-dynfield-fail-align",
> + .size = 1,
> + .align = 3,
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag = {
> + .name = "test-dynflag",
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag2 = {
> + .name = "test-dynflag2",
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag3 = {
> + .name = "test-dynflag3",
> + .flags = 0,
> + };
> + struct rte_mbuf *m = NULL;
> + int offset, offset2, offset3;
> + int flag, flag2, flag3;
> + int ret;
> +
> + printf("Test mbuf dynamic fields and flags\n");
> + rte_mbuf_dyn_dump(stdout);
> +
> + offset = rte_mbuf_dynfield_register(&dynfield);
> + if (offset == -1)
> + GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
> + offset, strerror(errno));
> +
> + ret = rte_mbuf_dynfield_register(&dynfield);
> + if (ret != offset)
> + GOTO_FAIL("failed to lookup dynamic field, ret=%d: %s",
> + ret, strerror(errno));
> +
> + offset2 = rte_mbuf_dynfield_register(&dynfield2);
> + if (offset2 == -1 || offset2 == offset || (offset2 & 1))
> + GOTO_FAIL("failed to register dynamic field 2, offset2=%d:
> %s",
> + offset2, strerror(errno));
> +
> + offset3 = rte_mbuf_dynfield_register_offset(&dynfield3,
> + offsetof(struct rte_mbuf, dynfield1[1]));
> + if (offset3 != offsetof(struct rte_mbuf, dynfield1[1]))
> + GOTO_FAIL("failed to register dynamic field 3, offset=%d:
> %s",
> + offset3, strerror(errno));
> +
> + printf("dynfield: offset=%d, offset2=%d, offset3=%d\n",
> + offset, offset2, offset3);
> +
> + ret = rte_mbuf_dynfield_register(&dynfield_fail_big);
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (too big)");
> +
> + ret = rte_mbuf_dynfield_register(&dynfield_fail_align);
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (bad
> alignment)");
> +
> + ret = rte_mbuf_dynfield_register_offset(&dynfield_fail_align,
> + offsetof(struct rte_mbuf, ol_flags));
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (not avail)");
> +
> + flag = rte_mbuf_dynflag_register(&dynflag);
> + if (flag == -1)
> + GOTO_FAIL("failed to register dynamic flag, flag=%d: %s",
> + flag, strerror(errno));
> +
> + ret = rte_mbuf_dynflag_register(&dynflag);
> + if (ret != flag)
> + GOTO_FAIL("failed to lookup dynamic flag, ret=%d: %s",
> + ret, strerror(errno));
> +
> + flag2 = rte_mbuf_dynflag_register(&dynflag2);
> + if (flag2 == -1 || flag2 == flag)
> + GOTO_FAIL("failed to register dynamic flag 2, flag2=%d: %s",
> + flag2, strerror(errno));
> +
> + flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3,
> + rte_bsf64(PKT_LAST_FREE));
> + if (flag3 != rte_bsf64(PKT_LAST_FREE))
> + GOTO_FAIL("failed to register dynamic flag 3, flag2=%d: %s",
> + flag3, strerror(errno));
> +
> + printf("dynflag: flag=%d, flag2=%d, flag3=%d\n", flag, flag2, flag3);
> +
> + /* set, get dynamic field */
> + m = rte_pktmbuf_alloc(pktmbuf_pool);
> + if (m == NULL)
> + GOTO_FAIL("Cannot allocate mbuf");
> +
> + *RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
> + if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
> + GOTO_FAIL("failed to read dynamic field");
> + *RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
> + if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
> + GOTO_FAIL("failed to read dynamic field");
> +
> + /* set a dynamic flag */
> + m->ol_flags |= (1ULL << flag);
> +
> + rte_mbuf_dyn_dump(stdout);
> + rte_pktmbuf_free(m);
> + return 0;
> +fail:
> + rte_pktmbuf_free(m);
> + return -1;
> +}
> +#undef GOTO_FAIL
> +
> static int
> test_mbuf(void)
> {
> @@ -1295,6 +1432,12 @@ test_mbuf(void)
> goto err;
> }
>
> + /* test registration of dynamic fields and flags */
> + if (test_mbuf_dyn(pktmbuf_pool) < 0) {
> + printf("mbuf dynflag test failed\n");
> + goto err;
> + }
> +
> /* create a specific pktmbuf pool with a priv_size != 0 and no data
> * room size */
> pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
> diff --git a/doc/guides/rel_notes/release_19_11.rst
> b/doc/guides/rel_notes/release_19_11.rst
> index 85953b962..9e9c94554 100644
> --- a/doc/guides/rel_notes/release_19_11.rst
> +++ b/doc/guides/rel_notes/release_19_11.rst
> @@ -21,6 +21,13 @@ DPDK Release 19.11
>
> xdg-open build/doc/html/guides/rel_notes/release_19_11.html
>
> +* **Add support of support dynamic fields and flags in mbuf.**
> +
> + This new feature adds the ability to dynamically register some room
> + for a field or a flag in the mbuf structure. This is typically used
> + for specific offload features, where adding a static field or flag in
> + the mbuf is not justified.
> +
>
> New Features
> ------------
> diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile index
> c8f6d2689..5a9bcee73 100644
> --- a/lib/librte_mbuf/Makefile
> +++ b/lib/librte_mbuf/Makefile
> @@ -17,8 +17,10 @@ LIBABIVER := 5
>
> # all source are stored in SRCS-y
> SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c
> rte_mbuf_pool_ops.c
> +SRCS-$(CONFIG_RTE_LIBRTE_MBUF) += rte_mbuf_dyn.c
>
> # install includes
> SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h
> rte_mbuf_ptype.h rte_mbuf_pool_ops.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include += rte_mbuf_dyn.h
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build index
> 6cc11ebb4..9137e8f26 100644
> --- a/lib/librte_mbuf/meson.build
> +++ b/lib/librte_mbuf/meson.build
> @@ -2,8 +2,10 @@
> # Copyright(c) 2017 Intel Corporation
>
> version = 5
> -sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c') -
> headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
> +sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c',
> + 'rte_mbuf_dyn.c')
> +headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h',
> + 'rte_mbuf_dyn.h')
> deps += ['mempool']
>
> allow_experimental_apis = true
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h index
> fb0849ac1..5740b1e93 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -198,9 +198,12 @@ extern "C" {
> #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
>
> -/* add new RX flags here */
> +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
>
> -/* add new TX flags here */
> +#define PKT_FIRST_FREE (1ULL << 23)
> +#define PKT_LAST_FREE (1ULL << 39)
> +
> +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
>
> /**
> * Indicate that the metadata field in the mbuf is in use.
> @@ -738,6 +741,7 @@ struct rte_mbuf {
> */
> struct rte_mbuf_ext_shared_info *shinfo;
>
> + uint64_t dynfield1[2]; /**< Reserved for dynamic fields. */
> } __rte_cache_aligned;
>
> /**
> @@ -1684,6 +1688,20 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m,
> void *buf_addr,
> */
> #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
>
> +/**
> + * Copy dynamic fields from m_src to m_dst.
> + *
> + * @param m_dst
> + * The destination mbuf.
> + * @param m_src
> + * The source mbuf.
> + */
> +static inline void
> +rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf
> +*msrc) {
> + memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst-
> >dynfield1)); }
> +
> /* internal */
> static inline void
> __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf
> *msrc) @@ -1695,6 +1713,7 @@ __rte_pktmbuf_copy_hdr(struct rte_mbuf
> *mdst, const struct rte_mbuf *msrc)
> mdst->hash = msrc->hash;
> mdst->packet_type = msrc->packet_type;
> mdst->timestamp = msrc->timestamp;
> + rte_mbuf_dynfield_copy(mdst, msrc);
> }
>
> /**
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c
> b/lib/librte_mbuf/rte_mbuf_dyn.c new file mode 100644 index
> 000000000..9ef235483
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> @@ -0,0 +1,548 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#include <sys/queue.h>
> +#include <stdint.h>
> +#include <limits.h>
> +
> +#include <rte_common.h>
> +#include <rte_eal.h>
> +#include <rte_eal_memconfig.h>
> +#include <rte_tailq.h>
> +#include <rte_errno.h>
> +#include <rte_malloc.h>
> +#include <rte_string_fns.h>
> +#include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> +
> +struct mbuf_dynfield_elt {
> + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> + struct rte_mbuf_dynfield params;
> + size_t offset;
> +};
> +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> + .name = "RTE_MBUF_DYNFIELD",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> +
> +struct mbuf_dynflag_elt {
> + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> + struct rte_mbuf_dynflag params;
> + unsigned int bitnum;
> +};
> +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> + .name = "RTE_MBUF_DYNFLAG",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> +
> +struct mbuf_dyn_shm {
> + /**
> + * For each mbuf byte, free_space[i] != 0 if space is free.
> + * The value is the size of the biggest aligned element that
> + * can fit in the zone.
> + */
> + uint8_t free_space[sizeof(struct rte_mbuf)];
> + /** Bitfield of available flags. */
> + uint64_t free_flags;
> +};
> +static struct mbuf_dyn_shm *shm;
> +
> +/* Set the value of free_space[] according to the size and alignment of
> + * the free areas. This helps to select the best place when reserving a
> + * dynamic field. Assume tailq is locked.
> + */
> +static void
> +process_score(void)
> +{
> + size_t off, align, size, i;
> +
> + /* first, erase previous info */
> + for (i = 0; i < sizeof(struct rte_mbuf); i++) {
> + if (shm->free_space[i])
> + shm->free_space[i] = 1;
> + }
> +
> + for (off = 0; off < sizeof(struct rte_mbuf); off++) {
> + /* get the size of the free zone */
> + for (size = 0; shm->free_space[off + size]; size++)
> + ;
> + if (size == 0)
> + continue;
> +
> + /* get the alignment of biggest object that can fit in
> + * the zone at this offset.
> + */
> + for (align = 1;
> + (off % (align << 1)) == 0 && (align << 1) <= size;
> + align <<= 1)
> + ;
> +
> + /* save it in free_space[] */
> + for (i = off; i < off + size; i++)
> + shm->free_space[i] = RTE_MAX(align, shm-
> >free_space[i]);
> + }
> +}
> +
> +/* Allocate and initialize the shared memory. Assume tailq is locked */
> +static int
> +init_shared_mem(void)
> +{
> + const struct rte_memzone *mz;
> + uint64_t mask;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + mz =
> rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> + sizeof(struct
> mbuf_dyn_shm),
> + SOCKET_ID_ANY, 0,
> + RTE_CACHE_LINE_SIZE);
> + } else {
> + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> + }
> + if (mz == NULL)
> + return -1;
> +
> + shm = mz->addr;
> +
> +#define mark_free(field) \
> + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> + 1, sizeof(((struct rte_mbuf *)0)->field))
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + /* init free_space, keep it sync'd with
> + * rte_mbuf_dynfield_copy().
> + */
> + memset(shm, 0, sizeof(*shm));
> + mark_free(dynfield1);
> +
> + /* init free_flags */
> + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask
> <<= 1)
> + shm->free_flags |= mask;
> +
> + process_score();
> + }
> +#undef mark_free
> +
> + return 0;
> +}
> +
> +/* check if this offset can be used */
> +static int
> +check_offset(size_t offset, size_t size, size_t align) {
> + size_t i;
> +
> + if ((offset & (align - 1)) != 0)
> + return -1;
> + if (offset + size > sizeof(struct rte_mbuf))
> + return -1;
> +
> + for (i = 0; i < size; i++) {
> + if (!shm->free_space[i + offset])
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynfield_elt *
> +__mbuf_dynfield_lookup(const char *name) {
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynfield;
> +}
> +
> +int
> +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield
> +*params) {
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynfield == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynfield->params,
> sizeof(*params));
> +
> + return mbuf_dynfield->offset;
> +}
> +
> +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> + const struct rte_mbuf_dynfield *params2) {
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->size != params2->size)
> + return -1;
> + if (params1->align != params2->align)
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static int
> +__rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield
> *params,
> + size_t req)
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> + struct rte_tailq_entry *te = NULL;
> + unsigned int best_zone = UINT_MAX;
> + size_t i, offset;
> + int ret;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + return -1;
> +
> + mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
> + if (mbuf_dynfield != NULL) {
> + if (req != SIZE_MAX && req != mbuf_dynfield->offset) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) <
> 0) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + return mbuf_dynfield->offset;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + return -1;
> + }
> +
> + if (req == SIZE_MAX) {
> + for (offset = 0;
> + offset < sizeof(struct rte_mbuf);
> + offset++) {
> + if (check_offset(offset, params->size,
> + params->align) == 0 &&
> + shm->free_space[offset] <
> best_zone) {
> + best_zone = shm->free_space[offset];
> + req = offset;
> + }
> + }
> + if (req == SIZE_MAX) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> + } else {
> + if (check_offset(req, params->size, params->align) < 0) {
> + rte_errno = EBUSY;
> + return -1;
> + }
> + }
> +
> + offset = req;
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + return -1;
> +
> + mbuf_dynfield = rte_zmalloc("mbuf_dynfield",
> sizeof(*mbuf_dynfield), 0);
> + if (mbuf_dynfield == NULL) {
> + rte_free(te);
> + return -1;
> + }
> +
> + ret = strlcpy(mbuf_dynfield->params.name, params->name,
> + sizeof(mbuf_dynfield->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
> + rte_errno = ENAMETOOLONG;
> + rte_free(mbuf_dynfield);
> + rte_free(te);
> + return -1;
> + }
> + memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield-
> >params));
> + mbuf_dynfield->offset = offset;
> + te->data = mbuf_dynfield;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> +
> + for (i = offset; i < offset + params->size; i++)
> + shm->free_space[i] = 0;
> + process_score();
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu,
> al=%zu, fl=0x%x) -> %zd\n",
> + params->name, params->size, params->align, params->flags,
> + offset);
> +
> + return offset;
> +}
> +
> +int
> +rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield
> *params,
> + size_t req)
> +{
> + int ret;
> +
> + if (params->size >= sizeof(struct rte_mbuf)) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> + if (!rte_is_power_of_2(params->align)) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> + if (params->flags != 0) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_write_lock();
> + ret = __rte_mbuf_dynfield_register_offset(params, req);
> + rte_mcfg_tailq_write_unlock();
> +
> + return ret;
> +}
> +
> +int
> +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params) {
> + return rte_mbuf_dynfield_register_offset(params, SIZE_MAX); }
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynflag_elt *
> +__mbuf_dynflag_lookup(const char *name) {
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> + mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
> + if (strncmp(name, mbuf_dynflag->params.name,
> + RTE_MBUF_DYN_NAMESIZE) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynflag;
> +}
> +
> +int
> +rte_mbuf_dynflag_lookup(const char *name,
> + struct rte_mbuf_dynflag *params)
> +{
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynflag = __mbuf_dynflag_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynflag == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynflag->params,
> sizeof(*params));
> +
> + return mbuf_dynflag->bitnum;
> +}
> +
> +static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
> + const struct rte_mbuf_dynflag *params2) {
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static int
> +__rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag
> *params,
> + unsigned int req)
> +{
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
> + struct rte_tailq_entry *te = NULL;
> + unsigned int bitnum;
> + int ret;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + return -1;
> +
> + mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
> + if (mbuf_dynflag != NULL) {
> + if (req != UINT_MAX && req != mbuf_dynflag->bitnum) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) <
> 0) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + return mbuf_dynflag->bitnum;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + return -1;
> + }
> +
> + if (req == UINT_MAX) {
> + if (shm->free_flags == 0) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> + bitnum = rte_bsf64(shm->free_flags);
> + } else {
> + if ((shm->free_flags & (1ULL << req)) == 0) {
> + rte_errno = EBUSY;
> + return -1;
> + }
> + bitnum = req;
> + }
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + return -1;
> +
> + mbuf_dynflag = rte_zmalloc("mbuf_dynflag",
> sizeof(*mbuf_dynflag), 0);
> + if (mbuf_dynflag == NULL) {
> + rte_free(te);
> + return -1;
> + }
> +
> + ret = strlcpy(mbuf_dynflag->params.name, params->name,
> + sizeof(mbuf_dynflag->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
> + rte_free(mbuf_dynflag);
> + rte_free(te);
> + rte_errno = ENAMETOOLONG;
> + return -1;
> + }
> + mbuf_dynflag->bitnum = bitnum;
> + te->data = mbuf_dynflag;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> +
> + shm->free_flags &= ~(1ULL << bitnum);
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) ->
> %u\n",
> + params->name, params->flags, bitnum);
> +
> + return bitnum;
> +}
> +
> +int
> +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag
> *params,
> + unsigned int req)
> +{
> + int ret;
> +
> + if (req != UINT_MAX && req >= 64) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_write_lock();
> + ret = __rte_mbuf_dynflag_register_bitnum(params, req);
> + rte_mcfg_tailq_write_unlock();
> +
> + return ret;
> +}
> +
> +int
> +rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params) {
> + return rte_mbuf_dynflag_register_bitnum(params, UINT_MAX); }
> +
> +void rte_mbuf_dyn_dump(FILE *out)
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *dynfield;
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *dynflag;
> + struct rte_tailq_entry *te;
> + size_t i;
> +
> + rte_mcfg_tailq_write_lock();
> + init_shared_mem();
> + fprintf(out, "Reserved fields:\n");
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> + dynfield = (struct mbuf_dynfield_elt *)te->data;
> + fprintf(out, " name=%s offset=%zd size=%zd align=%zd
> flags=%x\n",
> + dynfield->params.name, dynfield->offset,
> + dynfield->params.size, dynfield->params.align,
> + dynfield->params.flags);
> + }
> + fprintf(out, "Reserved flags:\n");
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> + dynflag = (struct mbuf_dynflag_elt *)te->data;
> + fprintf(out, " name=%s bitnum=%u flags=%x\n",
> + dynflag->params.name, dynflag->bitnum,
> + dynflag->params.flags);
> + }
> + fprintf(out, "Free space in mbuf (0 = free, value = zone
> alignment):\n");
> + for (i = 0; i < sizeof(struct rte_mbuf); i++) {
> + if ((i % 8) == 0)
> + fprintf(out, " %4.4zx: ", i);
> + fprintf(out, "%2.2x%s", shm->free_space[i],
> + (i % 8 != 7) ? " " : "\n");
> + }
> + rte_mcfg_tailq_write_unlock();
> +}
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h
> b/lib/librte_mbuf/rte_mbuf_dyn.h new file mode 100644 index
> 000000000..307613c96
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.h
> @@ -0,0 +1,226 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#ifndef _RTE_MBUF_DYN_H_
> +#define _RTE_MBUF_DYN_H_
> +
> +/**
> + * @file
> + * RTE Mbuf dynamic fields and flags
> + *
> + * Many features require to store data inside the mbuf. As the room in
> + * mbuf structure is limited, it is not possible to have a field for
> + * each feature. Also, changing fields in the mbuf structure can break
> + * the API or ABI.
> + *
> + * This module addresses this issue, by enabling the dynamic
> + * registration of fields or flags:
> + *
> + * - a dynamic field is a named area in the rte_mbuf structure, with a
> + * given size (>= 1 byte) and alignment constraint.
> + * - a dynamic flag is a named bit in the rte_mbuf structure, stored
> + * in mbuf->ol_flags.
> + *
> + * The typical use case is when a specific offload feature requires to
> + * register a dedicated offload field in the mbuf structure, and adding
> + * a static field or flag is not justified.
> + *
> + * Example of use:
> + *
> + * - A rte_mbuf_dynfield structure is defined, containing the parameters
> + * of the dynamic field to be registered:
> + * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
> + * - The application initializes the PMD, and asks for this feature
> + * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
> + * rxconf. This will make the PMD to register the field by calling
> + * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
> + * stores the returned offset.
> + * - The application that uses the offload feature also registers
> + * the field to retrieve the same offset.
> + * - When the PMD receives a packet, it can set the field:
> + * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
> + * - In the main loop, the application can retrieve the value with
> + * the same macro.
> + *
> + * To avoid wasting space, the dynamic fields or flags must only be
> + * reserved on demand, when an application asks for the related feature.
> + *
> + * The registration can be done at any moment, but it is not possible
> + * to unregister fields or flags for now.
> + *
> + * A dynamic field can be reserved and used by an application only.
> + * It can for instance be a packet mark.
> + */
> +
> +#include <sys/types.h>
> +/**
> + * Maximum length of the dynamic field or flag string.
> + */
> +#define RTE_MBUF_DYN_NAMESIZE 64
> +
> +/**
> + * Structure describing the parameters of a mbuf dynamic field.
> + */
> +struct rte_mbuf_dynfield {
> + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
> + size_t size; /**< The number of bytes to reserve. */
> + size_t align; /**< The alignment constraint (power of 2). */
> + unsigned int flags; /**< Reserved for future use, must be 0. */ };
> +
> +/**
> + * Structure describing the parameters of a mbuf dynamic flag.
> + */
> +struct rte_mbuf_dynflag {
> + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic
> flag. */
> + unsigned int flags; /**< Reserved for future use, must be 0. */ };
> +
> +/**
> + * Register space for a dynamic field in the mbuf structure.
> + *
> + * If the field is already registered (same name and parameters), its
> + * offset is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters (name, size,
> + * alignment constraint and flags).
> + * @return
> + * The offset in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, or flags).
> + * - EEXIST: this name is already register with different parameters.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: not enough room in mbuf.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name does not ends with \0.
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
> +
> +/**
> + * Register space for a dynamic field in the mbuf structure at offset.
> + *
> + * If the field is already registered (same name, parameters and
> +offset),
> + * the offset is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters (name, size,
> + * alignment constraint and flags).
> + * @param offset
> + * The requested offset. Ignored if SIZE_MAX is passed.
> + * @return
> + * The offset in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, flags, or offset).
> + * - EEXIST: this name is already register with different parameters.
> + * - EBUSY: the requested offset cannot be used.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: not enough room in mbuf.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name does not ends with \0.
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield
> *params,
> + size_t offset);
> +
> +/**
> + * Lookup for a registered dynamic mbuf field.
> + *
> + * @param name
> + * A string identifying the dynamic field.
> + * @param params
> + * If not NULL, and if the lookup is successful, the structure is
> + * filled with the parameters of the dynamic field.
> + * @return
> + * The offset of this field in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - ENOENT: no dynamic field matches this name.
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_lookup(const char *name,
> + struct rte_mbuf_dynfield *params);
> +
> +/**
> + * Register a dynamic flag in the mbuf structure.
> + *
> + * If the flag is already registered (same name and parameters), its
> + * bitnum is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters of the dynamic
> + * flag (name and options).
> + * @return
> + * The number of the reserved bit, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, or flags).
> + * - EEXIST: this name is already register with different parameters.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: no more flag available.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE -
> 1.
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
> +
> +/**
> + * Register a dynamic flag in the mbuf structure specifying bitnum.
> + *
> + * If the flag is already registered (same name, parameters and
> +bitnum),
> + * the bitnum is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters of the dynamic
> + * flag (name and options).
> + * @param bitnum
> + * The requested bitnum. Ignored if UINT_MAX is passed.
> + * @return
> + * The number of the reserved bit, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, or flags).
> + * - EEXIST: this name is already register with different parameters.
> + * - EBUSY: the requested bitnum cannot be used.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: no more flag available.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE -
> 1.
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag
> *params,
> + unsigned int bitnum);
> +
> +/**
> + * Lookup for a registered dynamic mbuf flag.
> + *
> + * @param name
> + * A string identifying the dynamic flag.
> + * @param params
> + * If not NULL, and if the lookup is successful, the structure is
> + * filled with the parameters of the dynamic flag.
> + * @return
> + * The offset of this flag in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - ENOENT: no dynamic flag matches this name.
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_lookup(const char *name,
> + struct rte_mbuf_dynflag *params);
> +
> +/**
> + * Helper macro to access to a dynamic field.
> + */
> +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) +
> +(offset)))
> +
> +/**
> + * Dump the status of dynamic fields and flags.
> + *
> + * @param out
> + * The stream where the status is displayed.
> + */
> +__rte_experimental
> +void rte_mbuf_dyn_dump(FILE *out);
> +
> +/* Placeholder for dynamic fields and flags declarations. */
> +
> +#endif
> diff --git a/lib/librte_mbuf/rte_mbuf_version.map
> b/lib/librte_mbuf/rte_mbuf_version.map
> index 519fead35..9bf5ca37a 100644
> --- a/lib/librte_mbuf/rte_mbuf_version.map
> +++ b/lib/librte_mbuf/rte_mbuf_version.map
> @@ -58,6 +58,13 @@ EXPERIMENTAL {
> global:
>
> rte_mbuf_check;
> + rte_mbuf_dynfield_lookup;
> + rte_mbuf_dynfield_register;
> + rte_mbuf_dynfield_register_offset;
> + rte_mbuf_dynflag_lookup;
> + rte_mbuf_dynflag_register;
> + rte_mbuf_dynflag_register_bitnum;
> + rte_mbuf_dyn_dump;
> rte_pktmbuf_copy;
>
> } DPDK_18.08;
> --
> 2.20.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-23 3:16 0% ` Wang, Haiyue
@ 2019-10-23 10:21 0% ` Olivier Matz
2019-10-23 15:00 0% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-10-23 10:21 UTC (permalink / raw)
To: Wang, Haiyue
Cc: Ananyev, Konstantin, dev, Andrew Rybchenko, Richardson, Bruce,
Jerin Jacob Kollanukkaran, Wiles, Keith, Morten Brørup,
Stephen Hemminger, Thomas Monjalon
On Wed, Oct 23, 2019 at 03:16:13AM +0000, Wang, Haiyue wrote:
> > -----Original Message-----
> > From: Ananyev, Konstantin
> > Sent: Wednesday, October 23, 2019 06:52
> > To: Olivier Matz <olivier.matz@6wind.com>; dev@dpdk.org
> > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>; Wang,
> > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Morten Brørup <mb@smartsharesystems.com>; Stephen Hemminger
> > <stephen@networkplumber.org>; Thomas Monjalon <thomas@monjalon.net>
> > Subject: RE: [PATCH v2] mbuf: support dynamic fields and flags
> >
> >
> > > Many features require to store data inside the mbuf. As the room in mbuf
> > > structure is limited, it is not possible to have a field for each
> > > feature. Also, changing fields in the mbuf structure can break the API
> > > or ABI.
> > >
> > > This commit addresses these issues, by enabling the dynamic registration
> > > of fields or flags:
> > >
> > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > given size (>= 1 byte) and alignment constraint.
> > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > >
> > > The typical use case is a PMD that registers space for an offload
> > > feature, when the application requests to enable this feature. As
> > > the space in mbuf is limited, the space should only be reserved if it
> > > is going to be used (i.e when the application explicitly asks for it).
> > >
> > > The registration can be done at any moment, but it is not possible
> > > to unregister fields or flags for now.
> > >
> > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > ---
> > >
> > > v2
> > >
> > > * Rebase on top of master: solve conflict with Stephen's patchset
> > > (packet copy)
> > > * Add new apis to register a dynamic field/flag at a specific place
> > > * Add a dump function (sugg by David)
> > > * Enhance field registration function to select the best offset, keeping
> > > large aligned zones as much as possible (sugg by Konstantin)
> > > * Use a size_t and unsigned int instead of int when relevant
> > > (sugg by Konstantin)
> > > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > > (sugg by Konstantin)
> > > * Remove unused argument in private function (sugg by Konstantin)
> > > * Fix and simplify locking (sugg by Konstantin)
> > > * Fix minor typo
> > >
> > > rfc -> v1
> > >
> > > * Rebase on top of master
> > > * Change registration API to use a structure instead of
> > > variables, getting rid of #defines (Stephen's comment)
> > > * Update flag registration to use a similar API as fields.
> > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > * Add a debug log at registration
> > > * Add some words in release note
> > > * Did some performance tests (sugg. by Andrew):
> > > On my platform, reading a dynamic field takes ~3 cycles more
> > > than a static field, and ~2 cycles more for writing.
> > >
> > > app/test/test_mbuf.c | 145 ++++++-
> > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > lib/librte_mbuf/Makefile | 2 +
> > > lib/librte_mbuf/meson.build | 6 +-
> > > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > > 8 files changed, 959 insertions(+), 5 deletions(-)
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > >
> > > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > > index b9c2b2500..01cafad59 100644
> > > --- a/app/test/test_mbuf.c
> > > +++ b/app/test/test_mbuf.c
> > > @@ -28,6 +28,7 @@
> > > #include <rte_random.h>
> > > #include <rte_cycles.h>
> > > #include <rte_malloc.h>
> > > +#include <rte_mbuf_dyn.h>
> > >
>
> [snip]
> > > +int
> > > +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> > > + unsigned int req)
> > > +{
> > > + int ret;
> > > +
> > > + if (req != UINT_MAX && req >= 64) {
> >
> > Might be better to replace 64 with something like sizeof(mbuf->ol_flags) * CHAR_BIT or so.
>
> Might introduce a new macro like kernel:
>
> /**
> * FIELD_SIZEOF - get the size of a struct's field
> * @t: the target struct
> * @f: the target struct's field
> * Return: the size of @f in the struct definition without having a
> * declared instance of @t.
> */
> #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
>
> Then: FIELD_SIZEOF(rte_mbuf, ol_flags) * CHAR_BIT
Good idea, thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-22 22:51 0% ` Ananyev, Konstantin
2019-10-23 3:16 0% ` Wang, Haiyue
@ 2019-10-23 10:19 0% ` Olivier Matz
1 sibling, 0 replies; 200+ results
From: Olivier Matz @ 2019-10-23 10:19 UTC (permalink / raw)
To: Ananyev, Konstantin
Cc: dev, Andrew Rybchenko, Richardson, Bruce, Wang, Haiyue,
Jerin Jacob Kollanukkaran, Wiles, Keith, Morten Brørup,
Stephen Hemminger, Thomas Monjalon
On Tue, Oct 22, 2019 at 10:51:51PM +0000, Ananyev, Konstantin wrote:
>
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> >
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> >
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> > given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> >
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature. As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> >
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >
> > v2
> >
> > * Rebase on top of master: solve conflict with Stephen's patchset
> > (packet copy)
> > * Add new apis to register a dynamic field/flag at a specific place
> > * Add a dump function (sugg by David)
> > * Enhance field registration function to select the best offset, keeping
> > large aligned zones as much as possible (sugg by Konstantin)
> > * Use a size_t and unsigned int instead of int when relevant
> > (sugg by Konstantin)
> > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > (sugg by Konstantin)
> > * Remove unused argument in private function (sugg by Konstantin)
> > * Fix and simplify locking (sugg by Konstantin)
> > * Fix minor typo
> >
> > rfc -> v1
> >
> > * Rebase on top of master
> > * Change registration API to use a structure instead of
> > variables, getting rid of #defines (Stephen's comment)
> > * Update flag registration to use a similar API as fields.
> > * Change max name length from 32 to 64 (sugg. by Thomas)
> > * Enhance API documentation (Haiyue's and Andrew's comments)
> > * Add a debug log at registration
> > * Add some words in release note
> > * Did some performance tests (sugg. by Andrew):
> > On my platform, reading a dynamic field takes ~3 cycles more
> > than a static field, and ~2 cycles more for writing.
> >
> > app/test/test_mbuf.c | 145 ++++++-
> > doc/guides/rel_notes/release_19_11.rst | 7 +
> > lib/librte_mbuf/Makefile | 2 +
> > lib/librte_mbuf/meson.build | 6 +-
> > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > 8 files changed, 959 insertions(+), 5 deletions(-)
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> >
> > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > index b9c2b2500..01cafad59 100644
> > --- a/app/test/test_mbuf.c
> > +++ b/app/test/test_mbuf.c
> > @@ -28,6 +28,7 @@
> > #include <rte_random.h>
> > #include <rte_cycles.h>
> > #include <rte_malloc.h>
> > +#include <rte_mbuf_dyn.h>
> >
> > #include "test.h"
> >
> > @@ -657,7 +658,6 @@ test_attach_from_different_pool(struct rte_mempool *pktmbuf_pool,
> > rte_pktmbuf_free(clone2);
> > return -1;
> > }
> > -#undef GOTO_FAIL
> >
> > /*
> > * test allocation and free of mbufs
> > @@ -1276,6 +1276,143 @@ test_tx_offload(void)
> > return (v1 == v2) ? 0 : -EINVAL;
> > }
> >
> > +static int
> > +test_mbuf_dyn(struct rte_mempool *pktmbuf_pool)
> > +{
> > + const struct rte_mbuf_dynfield dynfield = {
> > + .name = "test-dynfield",
> > + .size = sizeof(uint8_t),
> > + .align = __alignof__(uint8_t),
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynfield dynfield2 = {
> > + .name = "test-dynfield2",
> > + .size = sizeof(uint16_t),
> > + .align = __alignof__(uint16_t),
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynfield dynfield3 = {
> > + .name = "test-dynfield3",
> > + .size = sizeof(uint8_t),
> > + .align = __alignof__(uint8_t),
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynfield dynfield_fail_big = {
> > + .name = "test-dynfield-fail-big",
> > + .size = 256,
> > + .align = 1,
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynfield dynfield_fail_align = {
> > + .name = "test-dynfield-fail-align",
> > + .size = 1,
> > + .align = 3,
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynflag dynflag = {
> > + .name = "test-dynflag",
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynflag dynflag2 = {
> > + .name = "test-dynflag2",
> > + .flags = 0,
> > + };
> > + const struct rte_mbuf_dynflag dynflag3 = {
> > + .name = "test-dynflag3",
> > + .flags = 0,
> > + };
> > + struct rte_mbuf *m = NULL;
> > + int offset, offset2, offset3;
> > + int flag, flag2, flag3;
> > + int ret;
> > +
> > + printf("Test mbuf dynamic fields and flags\n");
> > + rte_mbuf_dyn_dump(stdout);
> > +
> > + offset = rte_mbuf_dynfield_register(&dynfield);
> > + if (offset == -1)
> > + GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
> > + offset, strerror(errno));
> > +
> > + ret = rte_mbuf_dynfield_register(&dynfield);
> > + if (ret != offset)
> > + GOTO_FAIL("failed to lookup dynamic field, ret=%d: %s",
> > + ret, strerror(errno));
> > +
> > + offset2 = rte_mbuf_dynfield_register(&dynfield2);
> > + if (offset2 == -1 || offset2 == offset || (offset2 & 1))
> > + GOTO_FAIL("failed to register dynamic field 2, offset2=%d: %s",
> > + offset2, strerror(errno));
> > +
> > + offset3 = rte_mbuf_dynfield_register_offset(&dynfield3,
> > + offsetof(struct rte_mbuf, dynfield1[1]));
> > + if (offset3 != offsetof(struct rte_mbuf, dynfield1[1]))
> > + GOTO_FAIL("failed to register dynamic field 3, offset=%d: %s",
> > + offset3, strerror(errno));
> > +
> > + printf("dynfield: offset=%d, offset2=%d, offset3=%d\n",
> > + offset, offset2, offset3);
> > +
> > + ret = rte_mbuf_dynfield_register(&dynfield_fail_big);
> > + if (ret != -1)
> > + GOTO_FAIL("dynamic field creation should fail (too big)");
> > +
> > + ret = rte_mbuf_dynfield_register(&dynfield_fail_align);
> > + if (ret != -1)
> > + GOTO_FAIL("dynamic field creation should fail (bad alignment)");
> > +
> > + ret = rte_mbuf_dynfield_register_offset(&dynfield_fail_align,
> > + offsetof(struct rte_mbuf, ol_flags));
> > + if (ret != -1)
> > + GOTO_FAIL("dynamic field creation should fail (not avail)");
> > +
> > + flag = rte_mbuf_dynflag_register(&dynflag);
> > + if (flag == -1)
> > + GOTO_FAIL("failed to register dynamic flag, flag=%d: %s",
> > + flag, strerror(errno));
> > +
> > + ret = rte_mbuf_dynflag_register(&dynflag);
> > + if (ret != flag)
> > + GOTO_FAIL("failed to lookup dynamic flag, ret=%d: %s",
> > + ret, strerror(errno));
> > +
> > + flag2 = rte_mbuf_dynflag_register(&dynflag2);
> > + if (flag2 == -1 || flag2 == flag)
> > + GOTO_FAIL("failed to register dynamic flag 2, flag2=%d: %s",
> > + flag2, strerror(errno));
> > +
> > + flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3,
> > + rte_bsf64(PKT_LAST_FREE));
> > + if (flag3 != rte_bsf64(PKT_LAST_FREE))
> > + GOTO_FAIL("failed to register dynamic flag 3, flag2=%d: %s",
> > + flag3, strerror(errno));
> > +
> > + printf("dynflag: flag=%d, flag2=%d, flag3=%d\n", flag, flag2, flag3);
> > +
> > + /* set, get dynamic field */
> > + m = rte_pktmbuf_alloc(pktmbuf_pool);
> > + if (m == NULL)
> > + GOTO_FAIL("Cannot allocate mbuf");
> > +
> > + *RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
> > + if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
> > + GOTO_FAIL("failed to read dynamic field");
> > + *RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
> > + if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
> > + GOTO_FAIL("failed to read dynamic field");
> > +
> > + /* set a dynamic flag */
> > + m->ol_flags |= (1ULL << flag);
> > +
> > + rte_mbuf_dyn_dump(stdout);
> > + rte_pktmbuf_free(m);
> > + return 0;
> > +fail:
> > + rte_pktmbuf_free(m);
> > + return -1;
> > +}
> > +#undef GOTO_FAIL
> > +
> > static int
> > test_mbuf(void)
> > {
> > @@ -1295,6 +1432,12 @@ test_mbuf(void)
> > goto err;
> > }
> >
> > + /* test registration of dynamic fields and flags */
> > + if (test_mbuf_dyn(pktmbuf_pool) < 0) {
> > + printf("mbuf dynflag test failed\n");
> > + goto err;
> > + }
> > +
> > /* create a specific pktmbuf pool with a priv_size != 0 and no data
> > * room size */
> > pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
> > diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
> > index 85953b962..9e9c94554 100644
> > --- a/doc/guides/rel_notes/release_19_11.rst
> > +++ b/doc/guides/rel_notes/release_19_11.rst
> > @@ -21,6 +21,13 @@ DPDK Release 19.11
> >
> > xdg-open build/doc/html/guides/rel_notes/release_19_11.html
> >
> > +* **Add support of support dynamic fields and flags in mbuf.**
> > +
> > + This new feature adds the ability to dynamically register some room
> > + for a field or a flag in the mbuf structure. This is typically used
> > + for specific offload features, where adding a static field or flag
> > + in the mbuf is not justified.
> > +
> >
> > New Features
> > ------------
> > diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
> > index c8f6d2689..5a9bcee73 100644
> > --- a/lib/librte_mbuf/Makefile
> > +++ b/lib/librte_mbuf/Makefile
> > @@ -17,8 +17,10 @@ LIBABIVER := 5
> >
> > # all source are stored in SRCS-y
> > SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
> > +SRCS-$(CONFIG_RTE_LIBRTE_MBUF) += rte_mbuf_dyn.c
> >
> > # install includes
> > SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h rte_mbuf_ptype.h rte_mbuf_pool_ops.h
> > +SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include += rte_mbuf_dyn.h
> >
> > include $(RTE_SDK)/mk/rte.lib.mk
> > diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
> > index 6cc11ebb4..9137e8f26 100644
> > --- a/lib/librte_mbuf/meson.build
> > +++ b/lib/librte_mbuf/meson.build
> > @@ -2,8 +2,10 @@
> > # Copyright(c) 2017 Intel Corporation
> >
> > version = 5
> > -sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
> > -headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
> > +sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c',
> > + 'rte_mbuf_dyn.c')
> > +headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h',
> > + 'rte_mbuf_dyn.h')
> > deps += ['mempool']
> >
> > allow_experimental_apis = true
> > diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> > index fb0849ac1..5740b1e93 100644
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -198,9 +198,12 @@ extern "C" {
> > #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> > #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
> >
> > -/* add new RX flags here */
> > +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
> >
> > -/* add new TX flags here */
> > +#define PKT_FIRST_FREE (1ULL << 23)
> > +#define PKT_LAST_FREE (1ULL << 39)
> > +
> > +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
> >
> > /**
> > * Indicate that the metadata field in the mbuf is in use.
> > @@ -738,6 +741,7 @@ struct rte_mbuf {
> > */
> > struct rte_mbuf_ext_shared_info *shinfo;
> >
> > + uint64_t dynfield1[2]; /**< Reserved for dynamic fields. */
> > } __rte_cache_aligned;
> >
> > /**
> > @@ -1684,6 +1688,20 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> > */
> > #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
> >
> > +/**
> > + * Copy dynamic fields from m_src to m_dst.
> > + *
> > + * @param m_dst
> > + * The destination mbuf.
> > + * @param m_src
> > + * The source mbuf.
> > + */
> > +static inline void
> > +rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> > +{
> > + memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
> > +}
> > +
> > /* internal */
> > static inline void
> > __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> > @@ -1695,6 +1713,7 @@ __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> > mdst->hash = msrc->hash;
> > mdst->packet_type = msrc->packet_type;
> > mdst->timestamp = msrc->timestamp;
> > + rte_mbuf_dynfield_copy(mdst, msrc);
> > }
> >
> > /**
> > diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> > new file mode 100644
> > index 000000000..9ef235483
> > --- /dev/null
> > +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> > @@ -0,0 +1,548 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2019 6WIND S.A.
> > + */
> > +
> > +#include <sys/queue.h>
> > +#include <stdint.h>
> > +#include <limits.h>
> > +
> > +#include <rte_common.h>
> > +#include <rte_eal.h>
> > +#include <rte_eal_memconfig.h>
> > +#include <rte_tailq.h>
> > +#include <rte_errno.h>
> > +#include <rte_malloc.h>
> > +#include <rte_string_fns.h>
> > +#include <rte_mbuf.h>
> > +#include <rte_mbuf_dyn.h>
> > +
> > +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> > +
> > +struct mbuf_dynfield_elt {
> > + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> > + struct rte_mbuf_dynfield params;
> > + size_t offset;
> > +};
> > +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> > +
> > +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> > + .name = "RTE_MBUF_DYNFIELD",
> > +};
> > +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> > +
> > +struct mbuf_dynflag_elt {
> > + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> > + struct rte_mbuf_dynflag params;
> > + unsigned int bitnum;
> > +};
> > +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> > +
> > +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> > + .name = "RTE_MBUF_DYNFLAG",
> > +};
> > +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> > +
> > +struct mbuf_dyn_shm {
> > + /**
> > + * For each mbuf byte, free_space[i] != 0 if space is free.
> > + * The value is the size of the biggest aligned element that
> > + * can fit in the zone.
> > + */
> > + uint8_t free_space[sizeof(struct rte_mbuf)];
> > + /** Bitfield of available flags. */
> > + uint64_t free_flags;
> > +};
> > +static struct mbuf_dyn_shm *shm;
> > +
> > +/* Set the value of free_space[] according to the size and alignment of
> > + * the free areas. This helps to select the best place when reserving a
> > + * dynamic field. Assume tailq is locked.
> > + */
> > +static void
> > +process_score(void)
> > +{
> > + size_t off, align, size, i;
> > +
> > + /* first, erase previous info */
> > + for (i = 0; i < sizeof(struct rte_mbuf); i++) {
> > + if (shm->free_space[i])
> > + shm->free_space[i] = 1;
> > + }
> > +
> > + for (off = 0; off < sizeof(struct rte_mbuf); off++) {
> > + /* get the size of the free zone */
> > + for (size = 0; shm->free_space[off + size]; size++)
> > + ;
> > + if (size == 0)
> > + continue;
> > +
> > + /* get the alignment of biggest object that can fit in
> > + * the zone at this offset.
> > + */
> > + for (align = 1;
> > + (off % (align << 1)) == 0 && (align << 1) <= size;
> > + align <<= 1)
> > + ;
> > +
> > + /* save it in free_space[] */
> > + for (i = off; i < off + size; i++)
> > + shm->free_space[i] = RTE_MAX(align, shm->free_space[i]);
> > + }
> > +}
> > +
> > +/* Allocate and initialize the shared memory. Assume tailq is locked */
> > +static int
> > +init_shared_mem(void)
> > +{
> > + const struct rte_memzone *mz;
> > + uint64_t mask;
> > +
> > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> > + sizeof(struct mbuf_dyn_shm),
> > + SOCKET_ID_ANY, 0,
> > + RTE_CACHE_LINE_SIZE);
> > + } else {
> > + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> > + }
> > + if (mz == NULL)
> > + return -1;
> > +
> > + shm = mz->addr;
> > +
> > +#define mark_free(field) \
> > + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> > + 1, sizeof(((struct rte_mbuf *)0)->field))
>
> Still think it would look nicer without multi-line macro defines/undef in the middle of the function.
I rather think that macro helps to make the code more readable, but it's
probably just a matter of taste. Will someone puts a contract on me if I
keep it like this? If yes I'll do the change ;)
> > +
> > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > + /* init free_space, keep it sync'd with
> > + * rte_mbuf_dynfield_copy().
> > + */
> > + memset(shm, 0, sizeof(*shm));
> > + mark_free(dynfield1);
> > +
> > + /* init free_flags */
> > + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> > + shm->free_flags |= mask;
> > +
> > + process_score();
> > + }
> > +#undef mark_free
> > +
> > + return 0;
> > +}
> > +
> > +/* check if this offset can be used */
> > +static int
> > +check_offset(size_t offset, size_t size, size_t align)
> > +{
> > + size_t i;
> > +
> > + if ((offset & (align - 1)) != 0)
> > + return -1;
> > + if (offset + size > sizeof(struct rte_mbuf))
> > + return -1;
> > +
> > + for (i = 0; i < size; i++) {
> > + if (!shm->free_space[i + offset])
> > + return -1;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/* assume tailq is locked */
> > +static struct mbuf_dynfield_elt *
> > +__mbuf_dynfield_lookup(const char *name)
> > +{
> > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > + struct rte_tailq_entry *te;
> > +
> > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > +
> > + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> > + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> > + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> > + break;
> > + }
> > +
> > + if (te == NULL) {
> > + rte_errno = ENOENT;
> > + return NULL;
> > + }
> > +
> > + return mbuf_dynfield;
> > +}
> > +
> > +int
> > +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> > +{
> > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > +
> > + if (shm == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_read_lock();
> > + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> > + rte_mcfg_tailq_read_unlock();
> > +
> > + if (mbuf_dynfield == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + if (params != NULL)
> > + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> > +
> > + return mbuf_dynfield->offset;
> > +}
> > +
> > +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> > + const struct rte_mbuf_dynfield *params2)
> > +{
> > + if (strcmp(params1->name, params2->name))
> > + return -1;
> > + if (params1->size != params2->size)
> > + return -1;
> > + if (params1->align != params2->align)
> > + return -1;
> > + if (params1->flags != params2->flags)
> > + return -1;
> > + return 0;
> > +}
> > +
> > +/* assume tailq is locked */
> > +static int
> > +__rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
> > + size_t req)
> > +{
> > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> > + struct rte_tailq_entry *te = NULL;
> > + unsigned int best_zone = UINT_MAX;
> > + size_t i, offset;
> > + int ret;
> > +
> > + if (shm == NULL && init_shared_mem() < 0)
> > + return -1;
> > +
> > + mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
> > + if (mbuf_dynfield != NULL) {
> > + if (req != SIZE_MAX && req != mbuf_dynfield->offset) {
> > + rte_errno = EEXIST;
> > + return -1;
> > + }
> > + if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) < 0) {
> > + rte_errno = EEXIST;
> > + return -1;
> > + }
> > + return mbuf_dynfield->offset;
> > + }
> > +
> > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > + rte_errno = EPERM;
> > + return -1;
> > + }
> > +
> > + if (req == SIZE_MAX) {
> > + for (offset = 0;
> > + offset < sizeof(struct rte_mbuf);
> > + offset++) {
> > + if (check_offset(offset, params->size,
> > + params->align) == 0 &&
> > + shm->free_space[offset] < best_zone) {
>
> Probably worth to explain a bit more here about best_zone logic -
> trying to find offset with minimal score (minimal continuous length), etc.
Yes, will do.
> > + best_zone = shm->free_space[offset];
> > + req = offset;
> > + }
> > + }
> > + if (req == SIZE_MAX) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > + } else {
> > + if (check_offset(req, params->size, params->align) < 0) {
> > + rte_errno = EBUSY;
> > + return -1;
> > + }
> > + }
> > +
> > + offset = req;
> > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > +
> > + te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> > + if (te == NULL)
> > + return -1;
> > +
> > + mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
> > + if (mbuf_dynfield == NULL) {
> > + rte_free(te);
> > + return -1;
> > + }
> > +
> > + ret = strlcpy(mbuf_dynfield->params.name, params->name,
> > + sizeof(mbuf_dynfield->params.name));
> > + if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
> > + rte_errno = ENAMETOOLONG;
> > + rte_free(mbuf_dynfield);
> > + rte_free(te);
> > + return -1;
> > + }
> > + memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield->params));
> > + mbuf_dynfield->offset = offset;
> > + te->data = mbuf_dynfield;
> > +
> > + TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> > +
> > + for (i = offset; i < offset + params->size; i++)
> > + shm->free_space[i] = 0;
> > + process_score();
> > +
> > + RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu, al=%zu, fl=0x%x) -> %zd\n",
> > + params->name, params->size, params->align, params->flags,
> > + offset);
> > +
> > + return offset;
> > +}
> > +
> > +int
> > +rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
> > + size_t req)
> > +{
> > + int ret;
> > +
> > + if (params->size >= sizeof(struct rte_mbuf)) {
> > + rte_errno = EINVAL;
> > + return -1;
> > + }
> > + if (!rte_is_power_of_2(params->align)) {
> > + rte_errno = EINVAL;
> > + return -1;
> > + }
> > + if (params->flags != 0) {
> > + rte_errno = EINVAL;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_write_lock();
> > + ret = __rte_mbuf_dynfield_register_offset(params, req);
> > + rte_mcfg_tailq_write_unlock();
> > +
> > + return ret;
> > +}
> > +
> > +int
> > +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
> > +{
> > + return rte_mbuf_dynfield_register_offset(params, SIZE_MAX);
> > +}
> > +
> > +/* assume tailq is locked */
> > +static struct mbuf_dynflag_elt *
> > +__mbuf_dynflag_lookup(const char *name)
> > +{
> > + struct mbuf_dynflag_list *mbuf_dynflag_list;
> > + struct mbuf_dynflag_elt *mbuf_dynflag;
> > + struct rte_tailq_entry *te;
> > +
> > + mbuf_dynflag_list = RTE_TAILQ_CAST(
> > + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> > +
> > + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> > + mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
> > + if (strncmp(name, mbuf_dynflag->params.name,
> > + RTE_MBUF_DYN_NAMESIZE) == 0)
> > + break;
> > + }
> > +
> > + if (te == NULL) {
> > + rte_errno = ENOENT;
> > + return NULL;
> > + }
> > +
> > + return mbuf_dynflag;
> > +}
> > +
> > +int
> > +rte_mbuf_dynflag_lookup(const char *name,
> > + struct rte_mbuf_dynflag *params)
> > +{
> > + struct mbuf_dynflag_elt *mbuf_dynflag;
> > +
> > + if (shm == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_read_lock();
> > + mbuf_dynflag = __mbuf_dynflag_lookup(name);
> > + rte_mcfg_tailq_read_unlock();
> > +
> > + if (mbuf_dynflag == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + if (params != NULL)
> > + memcpy(params, &mbuf_dynflag->params, sizeof(*params));
> > +
> > + return mbuf_dynflag->bitnum;
> > +}
> > +
> > +static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
> > + const struct rte_mbuf_dynflag *params2)
> > +{
> > + if (strcmp(params1->name, params2->name))
> > + return -1;
> > + if (params1->flags != params2->flags)
> > + return -1;
> > + return 0;
> > +}
> > +
> > +/* assume tailq is locked */
> > +static int
> > +__rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> > + unsigned int req)
> > +{
> > + struct mbuf_dynflag_list *mbuf_dynflag_list;
> > + struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
> > + struct rte_tailq_entry *te = NULL;
> > + unsigned int bitnum;
> > + int ret;
> > +
> > + if (shm == NULL && init_shared_mem() < 0)
> > + return -1;
> > +
> > + mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
> > + if (mbuf_dynflag != NULL) {
> > + if (req != UINT_MAX && req != mbuf_dynflag->bitnum) {
> > + rte_errno = EEXIST;
> > + return -1;
> > + }
> > + if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) < 0) {
> > + rte_errno = EEXIST;
> > + return -1;
> > + }
> > + return mbuf_dynflag->bitnum;
> > + }
> > +
> > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > + rte_errno = EPERM;
> > + return -1;
> > + }
> > +
> > + if (req == UINT_MAX) {
> > + if (shm->free_flags == 0) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > + bitnum = rte_bsf64(shm->free_flags);
> > + } else {
> > + if ((shm->free_flags & (1ULL << req)) == 0) {
> > + rte_errno = EBUSY;
> > + return -1;
> > + }
> > + bitnum = req;
> > + }
> > +
> > + mbuf_dynflag_list = RTE_TAILQ_CAST(
> > + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> > +
> > + te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> > + if (te == NULL)
> > + return -1;
> > +
> > + mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
> > + if (mbuf_dynflag == NULL) {
> > + rte_free(te);
> > + return -1;
> > + }
> > +
> > + ret = strlcpy(mbuf_dynflag->params.name, params->name,
> > + sizeof(mbuf_dynflag->params.name));
> > + if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
> > + rte_free(mbuf_dynflag);
> > + rte_free(te);
> > + rte_errno = ENAMETOOLONG;
> > + return -1;
> > + }
> > + mbuf_dynflag->bitnum = bitnum;
> > + te->data = mbuf_dynflag;
> > +
> > + TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> > +
> > + shm->free_flags &= ~(1ULL << bitnum);
> > +
> > + RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) -> %u\n",
> > + params->name, params->flags, bitnum);
> > +
> > + return bitnum;
> > +}
> > +
> > +int
> > +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> > + unsigned int req)
> > +{
> > + int ret;
> > +
> > + if (req != UINT_MAX && req >= 64) {
>
> Might be better to replace 64 with something like sizeof(mbuf->ol_flags) * CHAR_BIT or so.
Will do.
> Apart from that:
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Thanks for the review
Olivier
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-22 17:44 0% ` Ananyev, Konstantin
2019-10-22 22:21 0% ` Ananyev, Konstantin
@ 2019-10-23 10:05 0% ` Akhil Goyal
1 sibling, 0 replies; 200+ results
From: Akhil Goyal @ 2019-10-23 10:05 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', Hemant Agrawal
Hi Konstantin,
>
> Hi Akhil,
>
>
> > > > Added my comments inline with your draft.
> > > > [snip]..
> > > >
> > > > >
> > > > > Ok, then my suggestion:
> > > > > Let's at least write down all points about crypto-dev approach where we
> > > > > disagree and then probably try to resolve them one by one....
> > > > > If we fail to make an agreement/progress in next week or so,
> > > > > (and no more reviews from the community)
> > > > > will have bring that subject to TB meeting to decide.
> > > > > Sounds fair to you?
> > > > Agreed
> > > > >
> > > > > List is below.
> > > > > Please add/correct me, if I missed something.
> > > > >
> > > > > Konstantin
> > > >
> > > > Before going into comparison, we should define the requirement as well.
> > >
> > > Good point.
> > >
> > > > What I understood from the patchset,
> > > > "You need a synchronous API to perform crypto operations on raw data
> using
> > > SW PMDs"
> > > > So,
> > > > - no crypto-ops,
> > > > - no separate enq-deq, only single process API for data path
> > > > - Do not need any value addition to the session parameters.
> > > > (You would need some parameters from the crypto-op which
> > > > Are constant per session and since you wont use crypto-op,
> > > > You need some place to store that)
> > >
> > > Yes, this is correct, I think.
> > >
> > > >
> > > > Now as per your mail, the comparison
> > > > 1. extra input parameters to create/init rte_(cpu)_sym_session.
> > > >
> > > > Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo'
> and
> > > 'key' fields.
> > > > New fields will be optional and would be used by PMD only when cpu-
> crypto
> > > session is requested.
> > > > For lksd-crypto session PMD is free to ignore these fields.
> > > > No ABI breakage is required.
> > > >
> > > > [Akhil] Agreed, no issues.
> > > >
> > > > 2. cpu-crypto create/init.
> > > > a) Our suggestion - introduce new API for that:
> > > > - rte_crypto_cpu_sym_init() that would init completely opaque
> > > rte_crypto_cpu_sym_session.
> > > > - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear);
> > > /*whatever else we'll need *'};
> > > > - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform
> > > *xforms)
> > > > that would return const struct rte_crypto_cpu_sym_session_ops
> *based
> > > on input xforms.
> > > > Advantages:
> > > > 1) totally opaque data structure (no ABI breakages in future), PMD
> > > writer is totally free
> > > > with it format and contents.
> > > >
> > > > [Akhil] It will have breakage at some point till we don't hit the union size.
> > >
> > > Not sure, what union you are talking about?
> >
> > Union of xforms in rte_security_session_conf
>
> Hmm, how does it relates here?
> I thought we discussing pure rte_cryptodev_sym_session, no?
>
> >
> > >
> > > > Rather I don't suspect there will be more parameters added.
> > > > Or do we really care about the ABI breakage when the argument is about
> > > > the correct place to add a piece of code or do we really agree to add code
> > > > anywhere just to avoid that breakage.
> > >
> > > I am talking about maintaining it in future.
> > > if your struct is not seen externally, no chances to introduce ABI breakage.
> > >
> > > >
> > > > 2) each session entity is self-contained, user doesn't need to bring along
> > > dev_id etc.
> > > > dev_id is needed only at init stage, after that user will use session ops
> > > to perform
> > > > all operations on that session (process(), clear(), etc.).
> > > >
> > > > [Akhil] There is nothing called as session ops in current DPDK.
> > >
> > > True, but it doesn't mean we can't/shouldn't have it.
> >
> > We can have it if it is not adding complexity for the user. Creating 2 different
> code
> > Paths for user is not desirable for the stack developers.
> >
> > >
> > > > What you are proposing
> > > > is a new concept which doesn't have any extra benefit, rather it is adding
> > > complexity
> > > > to have two different code paths for session create.
> > > >
> > > >
> > > > 3) User can decide does he wants to store ops[] pointer on a per session
> > > basis,
> > > > or on a per group of same sessions, or...
> > > >
> > > > [Akhil] Will the user really care which process API should be called from the
> > > PMD.
> > > > Rather it should be driver's responsibility to store that in the session private
> > > data
> > > > which would be opaque to the user. As per my suggestion same process
> > > function can
> > > > be added to multiple sessions or a single session can be managed inside the
> > > PMD.
> > >
> > > In that case we either need to have a function per session (stored internally),
> > > or make decision (branches) at run-time.
> > > But as I said in other mail - I am ok to add small shim structure here:
> > > either rte_crypto_cpu_sym_session { void *ses; struct
> > > rte_crypto_cpu_sym_session_ops ops; }
> > > or rte_crypto_cpu_sym_session { void *ses; struct
> > > rte_crypto_cpu_sym_session_ops *ops; }
> > > And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops()
> into
> > > one (init).
> >
> > Again that will be a separate API call from the user perspective which is not
> good.
> >
> > >
> > > >
> > > >
> > > > 4) No mandatory mempools for private sessions. User can allocate
> > > memory for cpu-crypto
> > > > session whenever he likes.
> > > >
> > > > [Akhil] you mean session private data?
> > >
> > > Yes.
> > >
> > > > You would need that memory anyways, user will be
> > > > allocating that already. You do not need to manage that.
> > >
> > > What I am saying - right now user has no choice but to allocate it via
> mempool.
> > > Which is probably not the best options for all cases.
> > >
> > > >
> > > > Disadvantages:
> > > > 5) Extra changes in control path
> > > > 6) User has to store session_ops pointer explicitly.
> > > >
> > > > [Akhil] More disadvantages:
> > > > - All supporting PMDs will need to maintain TWO types of session for the
> > > > same crypto processing. Suppose a fix or a new feature(or algo) is added,
> PMD
> > > owner
> > > > will need to add code in both the session create APIs. Hence more
> > > maintenance and
> > > > error prone.
> > >
> > > I think majority of code for both paths will be common, plus even we'll reuse
> > > current sym_session_init() -
> > > changes in PMD session_init() code will be unavoidable.
> > > But yes, it will be new entry in devops, that PMD will have to support.
> > > Ok to add it as 7) to the list.
> > >
> > > > - Stacks which will be using these new APIs also need to maintain two
> > > > code path for the same processing while doing session initialization
> > > > for sync and async
> > >
> > > That's the same as #5 above, I think.
> > >
> > > >
> > > >
> > > > b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and
> > > existing rte_cryptodev_sym_session
> > > > structure.
> > > > Advantages:
> > > > 1) allows to reuse same struct and init/create/clear() functions.
> > > > Probably less changes in control path.
> > > > Disadvantages:
> > > > 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id,
> > > which means that
> > > > we can't use the same rte_cryptodev_sym_session to hold private
> > > sessions pointers
> > > > for both sync and async mode for the same device.
> > > > So the only option we have - make PMD devops-
> > > >sym_session_configure()
> > > > always create a session that can work in both cpu and lksd modes.
> > > > For some implementations that would probably mean that under the
> > > hood PMD would create
> > > > 2 different session structs (sync/async) and then use one or another
> > > depending on from what API been called.
> > > > Seems doable, but ...:
> > > > - will contradict with statement from 1:
> > > > " New fields will be optional and would be used by PMD only when
> > > cpu-crypto session is requested."
> > > > Now it becomes mandatory for all apps to specify cpu-crypto
> > > related parameters too,
> > > > even if they don't plan to use that mode - i.e. behavior change,
> > > existing app change.
> > > > - might cause extra space overhead.
> > > >
> > > > [Akhil] It will not contradict with #1, you will only have few checks in the
> > > session init PMD
> > > > Which support this mode, find appropriate values and set the appropriate
> > > process() in it.
> > > > User should be able to call, legacy enq-deq as well as the new process()
> > > without any issue.
> > > > User would be at runtime will be able to change the datapath.
> > > > So this is not a disadvantage, it would be additional flexibility for the user.
> > >
> > > Ok, but that's what I am saying - if PMD would *always* have to create a
> > > session that can handle
> > > both modes (sync/async), then user would *always* have to provide
> parameters
> > > for both modes too.
> > > Otherwise if let say user didn't setup sync specific parameters at all, what
> PMD
> > > should do?
> > > - return with error?
> > > - init session that can be used with async path only?
> > > My current assumption is #1.
> > > If #2, then how user will be able to distinguish is that session valid for both
> > > modes, or only for one?
> >
> > I would say a 3rd option, do nothing if sync params are not set.
> > Probably have a debug print in the PMD(which support sync mode) to specify
> that
> > session is not configured properly for sync mode.
>
> So, just print warning and proceed with init session that can be used with async
> path only?
> Then it sounds the same as #2 above.
> Which actually means that sync mode parameters for sym_session_init()
> becomes optional.
> Then we need an API to provide to the user information what modes
> (sync+async/async only) is supported by that session for given dev_id.
> And user would have to query/retain this information at control-path,
> and store it somewhere in user-space together with session pointer and dev_ids
> to use later at data-path (same as we do now for session type).
> That definitely requires changes in control-path to start using it.
> Plus the fact that this value can differ for different dev_ids for the same session -
> doesn't make things easier here.
API wont be required to specify that. Feature flag will be sufficient, not a big change
From the application perspective.
Here is some pseudo code just to elaborate my understanding. This will need some
From application,
If(dev_info->feature_flags & RTE_CRYPTODEV_FF_SYNC) {
/* set additional params in crypto xform */
}
Now in the driver,
pmd_sym_session_configure(dev,xform,sess,mempool) {
...
If(dev_info->feature_flags & RTE_CRYPTODEV_FF_SYNC
&& xform->/*sync params are set*/) {
/*Assign process function pointer in sess->priv_data*/
} /* It may return error if FF_SYNC is set and params are not correct.
It would be upto the driver whether it support both SYNC and ASYNC.*/
}
Now the new sync API
pmd_process(...) {
If(dev_info->feature_flags & RTE_CRYPTODEV_FF_SYNC
&& sess_priv->process != NULL)
sess_priv->process(...);
else
ASSERT("sync mode not configured properly or not supported");
}
In the data path, there is no extra processing happening.
Even in case of your suggestion, you should have these type of error checks,
You cannot blindly trust on the application that the pointers are correct.
>
> > Internally the PMD will not store the process() API in the session priv data
> > And while calling the first packet, devops->process will give an assert that
> session
> > Is not configured for sync mode. The session validation would be done in any
> case
> > your suggestion or mine. So no extra overhead at runtime.
>
> I believe that after session_init() user should get either an error or
> valid session handler that he can use at runtime.
> Pushing session validation to runtime doesn't seem like a good idea.
>
It may get a warning from the PMD, that FF_SYNC is set but params are not
Correct/available. See above.
> >
> > >
> > >
> > > >
> > > >
> > > > 3) not possible to store device (not driver) specific data within the
> > > session, but I think it is not really needed right now.
> > > > So probably minor compared to 2.b.2.
> > > >
> > > > [Akhil] So lets omit this for current discussion. And I hope we can find some
> > > way to deal with it.
> > >
> > > I don't think there is an easy way to fix that with existing API.
> > >
> > > >
> > > >
> > > > Actually #3 follows from #2, but decided to have them separated.
> > > >
> > > > 3. process() parameters/behavior
> > > > a) Our suggestion: user stores ptr to session ops (or to (*process) itself)
> and
> > > just does:
> > > > session_ops->process(sess, ...);
> > > > Advantages:
> > > > 1) fastest possible execution path
> > > > 2) no need to carry on dev_id for data-path
> > > >
> > > > [Akhil] I don't see any overhead of carrying dev id, at least it would be
> inline
> > > with the
> > > > current DPDK methodology.
> > >
> > > If we'll add process() into rte_cryptodev itself (same as we have
> > > enqueue_burst/dequeue_burst),
> > > then it will be an ABI breakage.
> > > Also there are discussions to get rid of that approach completely:
> > >
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmails.dpd
> k.org%2Farchives%2Fdev%2F2019-
> September%2F144674.html&data=02%7C01%7Cakhil.goyal%40nxp.com%7
> C1859dc1d29cd45a51e9908d7571784bb%7C686ea1d3bc2b4c6fa92cd99c5c301
> 635%7C0%7C0%7C637073630835415165&sdata=Bz9jgisyVzRJNt1BijtvSlurh
> JU1vXBbynNwlMDjaco%3D&reserved=0
> > > So I am not sure this is a recommended way these days.
> >
> > We can either have it in rte_cryptodev or in rte_cryptodev_ops whichever
> > is good for you.
> >
> > Whether it is ABI breakage or not, as per your requirements, this is the correct
> > approach. Do you agree with this or not?
>
> I think it is possible approach, but not the best one:
> it looks quite flakey to me (see all these uncertainty with sym_session_init
> above),
> plus introduces extra overhead at data-path.
Uncertainties can be handled appropriately using a feature flag
And As per my understanding there is no extra overhead in data path.
>
> >
> > Now handling the API/ABI breakage is a separate story. In 19.11 release we
> > Are not much concerned about the ABI breakages, this was discussed in
> > community. So adding a new dev_ops wouldn't have been an issue.
> > Now since we are so close to RC1 deadline, we should come up with some
> > other solution for next release. May be having a pmd API in 20.02 and
> > converting it into formal one in 20.11
> >
> >
> > >
> > > > What you are suggesting is a new way to get the things done without much
> > > benefit.
> > >
> > > Would help with ABI stability plus better performance, isn't it enough?
> > >
> > > > Also I don't see any performance difference as crypto workload is heavier
> than
> > > > Code cycles, so that wont matter.
> > >
> > > It depends.
> > > Suppose function call costs you ~30 cycles.
> > > If you have burst of big packets (let say crypto for each will take ~2K cycles)
> that
> > > belong
> > > to the same session, then yes you wouldn't notice these extra 30 cycles at all.
> > > If you have burst of small packets (let say crypto for each will take ~300
> cycles)
> > > each
> > > belongs to different session, then it will cost you ~10% extra.
> >
> > Let us do some profiling on openssl with both the approaches and find out the
> > difference.
> >
> > >
> > > > So IMO, there is no advantage in your suggestion as well.
> > > >
> > > >
> > > > Disadvantages:
> > > > 3) user has to carry on session_ops pointer explicitly
> > > > b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and
> then:
> > > > rte_crypto_cpu_sym_process(uint8_t dev_id,
> rte_cryptodev_sym_session
> > > *sess, /*data parameters*/) {...
> > > > rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> > > > /*and then inside PMD specifc process: */
> > > > pmd_private_session = sess-
> >sess_data[this_pmd_driver_id].data;
> > > > /* and then most likely either */
> > > > pmd_private_session->process(pmd_private_session, ...);
> > > > /* or jump based on session/input data */
> > > > Advantages:
> > > > 1) don't see any...
> > > > Disadvantages:
> > > > 2) User has to carry on dev_id inside data-path
> > > > 3) Extra level of indirection (plus data dependency) - both for data and
> > > instructions.
> > > > Possible slowdown compared to a) (not measured).
> > > >
> > > > Having said all this, if the disagreements cannot be resolved, you can go
> for a
> > > pmd API specific
> > > > to your PMDs,
> > >
> > > I don't think it is good idea.
> > > PMD specific API is sort of deprecated path, also there is no clean way to use
> it
> > > within the libraries.
> >
> > I know that this is a deprecated path, we can use it until we are not allowed
> > to break ABI/API
> >
> > >
> > > > because as per my understanding the solution doesn't look scalable to
> other
> > > PMDs.
> > > > Your approach is aligned only to Intel , will not benefit others like openssl
> > > which is used by all
> > > > vendors.
> > >
> > > I feel quite opposite, from my perspective majority of SW backed PMDs will
> > > benefit from it.
> > > And I don't see anything Intel specific in my proposals above.
> > > About openssl PMD: I am not an expert here, but looking at the code, I think
> it
> > > will fit really well.
> > > Look yourself at its internal functions:
> > > process_openssl_auth_op/process_openssl_crypto_op,
> > > I think they doing exactly the same - they use sync API underneath, and they
> are
> > > session based
> > > (AFAIK you don't need any device/queue data, everything that needed for
> > > crypto/auth is stored inside session).
> > >
> > By vendor specific, I mean,
> > - no PMD would like to have 2 different variants of session Init APIs for doing
> the same stuff.
> > - stacks will become vendor specific while using 2 separate session create APIs.
> No stack would
> > Like to support 2 variants of session create- one for HW PMDs and one for SW
> PMDs.
>
> I think what you refer on has nothing to do with 'vendor specific'.
> I would name it 'extra overhead for PMD and stack writers'.
> Yes, for sure there is extra overhead (as always with new API) -
> for both producer (PMD writer) and consumer (stack writer):
> New function(s) to support, probably more tests to create/run, etc.
> Though this API is optional - if PMD/stack maintainer doesn't see
> value in it, they are free not to support it.
> From other side, re-using rte_cryptodev_sym_session_init()
> wouldn't help anyway - both data-path and control-path would differ
> from async mode anyway.
> BTW, right now to support different HW flavors
> we do have 4 different control and data-paths for both
> ipsec-secgw and librte_ipsec:
> lkds-none/lksd-proto/inline-crypto/inline-proto.
> And that is considered to be ok.
No that is not ok. We cannot add new paths for every other case.
Those 4 are controlled using 2 set of APIs. We should try our best to
Have minimum overhead to the application writer. This pain was also discussed
In the one of DPDK conference as well.
DPDK is not a standalone entity, there are stacks running over it always.
We should not add API for every other use case when we have an alternative
Approach with the existing API set.
Now introducing another one would add to that pain and a lot of work for
Both producer and consumer.
It would be interesting to see how much performance difference will be there in the
Two approaches. As per my understanding it wont be much as compared to the
Extra work that you will be inducing.
-Akhil
> Honestly, I don't understand why SW backed implementations
> can't have their own path that would suite them most.
> Konstantin
>
>
>
>
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [RFC 6/6] build: add drivers abi checks to meson
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
` (3 preceding siblings ...)
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 5/6] build: add lib abi checks to meson Kevin Laatz
@ 2019-10-23 1:07 14% ` Kevin Laatz
4 siblings, 0 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella, Kevin Laatz
This patch adds the ABI compatibility check for the drivers directory to
the meson build. If enabled, the ABI compatibility checks will run for all
.so's in the lib directory (provided a matching dump file exists). The
build will fail if an ABI incompatibility is detected.
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
---
drivers/meson.build | 17 ++++++++++++++++-
1 file changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/meson.build b/drivers/meson.build
index 3202ba00d..0fda5a9e0 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -158,7 +158,9 @@ foreach class:dpdk_driver_classes
version_map, '@INPUT@'],
capture: true,
input: static_lib,
- output: lib_name + '.exp_chk')
+ output: lib_name + '.exp_chk'
+ install: false,
+ build_by_default: get_option('abi_compat_checks'))
endif
shared_lib = shared_library(lib_name,
@@ -183,6 +185,19 @@ foreach class:dpdk_driver_classes
include_directories: includes,
dependencies: static_objs)
+ if is_experimental == 0
+ custom_target('lib' + lib_name + '.abi_chk',
+ command: [abidiff,
+ meson.source_root() + '/drivers/abi/lib'
+ + lib_name + '.dump',
+ '@INPUT@'],
+ input: shared_lib,
+ output: 'lib' + lib_name + '.abi_chk',
+ capture: true,
+ install: false,
+ build_by_default: get_option('abi_compat_checks'))
+ endif
+
dpdk_drivers += static_lib
set_variable('shared_@0@'.format(lib_name), shared_dep)
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [RFC 5/6] build: add lib abi checks to meson
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
` (2 preceding siblings ...)
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 4/6] build: add meson option for abi related checks Kevin Laatz
@ 2019-10-23 1:07 14% ` Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 6/6] build: add drivers " Kevin Laatz
4 siblings, 0 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella, Kevin Laatz
This patch adds the ABI compatibility check for the lib directory to the
meson build. If enabled, the ABI compatibility checks will run for all
.so's in the lib directory (provided a matching dump file exists). The
build will fail if an ABI incompatibility is detected.
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
buildtools/meson.build | 4 ++++
lib/meson.build | 17 ++++++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 1ec2c2f95..a895c791c 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -7,6 +7,10 @@ pmdinfo = find_program('gen-pmdinfo-cfile.sh')
check_experimental_syms = find_program('check-experimental-syms.sh')
+if get_option('abi_compat_checks')
+ abidiff = find_program('abidiff')
+endif
+
# set up map-to-def script using python, either built-in or external
python3 = import('python').find_installation(required: false)
if python3.found()
diff --git a/lib/meson.build b/lib/meson.build
index 7849ac9f7..da180fb37 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -146,7 +146,9 @@ foreach l:libraries
version_map, '@INPUT@'],
capture: true,
input: static_lib,
- output: name + '.exp_chk')
+ output: name + '.exp_chk',
+ install: false,
+ build_by_default: get_option('abi_compat_checks'))
endif
shared_lib = shared_library(libname,
@@ -164,6 +166,19 @@ foreach l:libraries
include_directories: includes,
dependencies: shared_deps)
+ if is_experimental == 0
+ custom_target(dir_name + '.abi_chk',
+ command: [abidiff,
+ meson.source_root() + '/lib/abi/'
+ + dir_name + '.dump',
+ '@INPUT@'],
+ input: shared_lib,
+ output: dir_name + '.abi_chk',
+ capture: true,
+ install: false,
+ build_by_default: get_option('abi_compat_checks'))
+ endif
+
dpdk_libraries = [shared_lib] + dpdk_libraries
dpdk_static_libraries = [static_lib] + dpdk_static_libraries
endif # sources.length() > 0
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [RFC 4/6] build: add meson option for abi related checks
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
2019-10-23 1:07 3% ` [dpdk-dev] [RFC 1/6] build: enable debug info by default in meson builds Kevin Laatz
2019-10-23 1:07 22% ` [dpdk-dev] [RFC 3/6] devtools: add abi dump generation script Kevin Laatz
@ 2019-10-23 1:07 14% ` Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 5/6] build: add lib abi checks to meson Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 6/6] build: add drivers " Kevin Laatz
4 siblings, 0 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella, Kevin Laatz
This patch adds a new meson option for running ABI compatibility checks
during the build. If enabled, the lib and drivers .so files will be
compared against any existing ABI dump files in lib|drivers/abi of the
source directory. If there are any incompatibilities, the build will fail
and display the incompatibility.
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
---
meson_options.txt | 2 ++
1 file changed, 2 insertions(+)
diff --git a/meson_options.txt b/meson_options.txt
index 000e38fd9..aefab391a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,5 +1,7 @@
# Please keep these options sorted alphabetically.
+option('abi_compat_checks', type: 'boolean', value: true,
+ description: 'enable abi compatibility checks to run during the build')
option('allow_invalid_socket_id', type: 'boolean', value: false,
description: 'allow out-of-range NUMA socket id\'s for platforms that don\'t report the value correctly')
option('drivers_install_subdir', type: 'string', value: 'dpdk/pmds-<VERSION>',
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [RFC 3/6] devtools: add abi dump generation script
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
2019-10-23 1:07 3% ` [dpdk-dev] [RFC 1/6] build: enable debug info by default in meson builds Kevin Laatz
@ 2019-10-23 1:07 22% ` Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 4/6] build: add meson option for abi related checks Kevin Laatz
` (2 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella, Kevin Laatz
This patch adds a script to generate ABI dump files. These files will be
required to perform ABI compatibility checks during the build later in the
patchset. This script should be run on a DPDK version with a stable ABI.
Since this is a tool designed for human use, we simplify it to just work
off a whole build directory, taking the parameter of the builddir and
generating the lib|drivers/abi dir. This is hardcoded into the script since
the meson build expects the .dump files in these directories.
Signed-off-by: Kevin Laatz <kevin.laatz@intel.com>
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
devtools/gen-abi-dump.sh | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
create mode 100755 devtools/gen-abi-dump.sh
diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh
new file mode 100755
index 000000000..ffedef10c
--- /dev/null
+++ b/devtools/gen-abi-dump.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+builddir=$1
+
+if [ -z "$builddir" ] ; then
+ echo "Usage: $(basename $0) build_dir"
+ exit 1
+fi
+
+if [ ! -d "$builddir" ] ; then
+ echo "Error: build directory, '$builddir', doesn't exist"
+ exit 1
+fi
+
+for d in lib drivers ; do
+ mkdir -p $d/abi
+
+ for f in $builddir/$d/*.so* ; do
+ test -L "$f" && continue
+
+ libname=$(basename $f)
+ abidw --out-file $d/abi/${libname%.so*}.dump $f || exit 1
+ done
+done
--
2.17.1
^ permalink raw reply [relevance 22%]
* [dpdk-dev] [RFC 1/6] build: enable debug info by default in meson builds
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
@ 2019-10-23 1:07 3% ` Kevin Laatz
2019-10-23 1:07 22% ` [dpdk-dev] [RFC 3/6] devtools: add abi dump generation script Kevin Laatz
` (3 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella
From: Bruce Richardson <bruce.richardson@intel.com>
We can turn on debug info by default in meson builds, since it has no
performance penalty. This is done by changing the default build type from
"release" to "debugoptimized". Since the latter using O2, we can using
extra cflags to override that back to O3, which will make little real
difference for actual debugging.
For real debug builds, the user can still do "meson --buildtype=debug ..."
and to remove the debug info "meson --buildtype=release ..." can be used.
These are all standard meson options.
The advantage of having debug builds by default using meson settings is
that we can then add checks for ABI compatibility into each build, and
disable them if we detect that the user has turned off the debug info.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
meson.build | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index c5a3dda26..b77ccd6ef 100644
--- a/meson.build
+++ b/meson.build
@@ -7,10 +7,16 @@ project('DPDK', 'C',
version: run_command(find_program('cat', 'more'),
files('VERSION')).stdout().strip(),
license: 'BSD',
- default_options: ['buildtype=release', 'default_library=static'],
+ default_options: ['buildtype=debugoptimized',
+ 'default_library=static'],
meson_version: '>= 0.47.1'
)
+# for default "debugoptimized" builds override optimization level 2 with 3
+if get_option('buildtype') == 'debugoptimized'
+ add_project_arguments('-O3', language: 'c')
+endif
+
# set up some global vars for compiler, platform, configuration, etc.
cc = meson.get_compiler('c')
dpdk_conf = configuration_data()
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build
@ 2019-10-23 1:07 9% Kevin Laatz
2019-10-23 1:07 3% ` [dpdk-dev] [RFC 1/6] build: enable debug info by default in meson builds Kevin Laatz
` (4 more replies)
0 siblings, 5 replies; 200+ results
From: Kevin Laatz @ 2019-10-23 1:07 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, thomas, ray.kinsella, Kevin Laatz
With the recent changes made to stabilize ABI versioning in DPDK, it will
become increasingly important to check patches for ABI compatibility. We
propose adding the ABI compatibility checking to be done as part of the
build.
The advantages to adding the ABI compatibility checking to the build are
two-fold. Firstly, developers can easily check their patches to make sure
they don’t break the ABI without adding any extra steps. Secondly, it
makes the integration into existing CI seamless since there are no extra
scripts to make the CI run. The build will run as usual and if an
incompatibility is detected in the ABI, the build will fail and show the
incompatibility. As an added bonus, enabling the ABI compatibility checks
does not impact the build speed.
The proposed solution works as follows:
1. Generate the ABI dump of the baseline. This can be done with the new
script added in this RFC. This step will only need to be done when the
ABI version changes (so once a year) and can be added to master so it
exists by default. This step can be skipped if the dump files for the
baseline already exist.
2. Build with meson. If there is an ABI incompatibility, the build will
fail and print the incompatibility information.
The patches accompanying this RFC add the ABI dump file generating script,
the meson option required to enable/disable the checks, and the required
meson changes to run the compatibility checks during the build.
This patchset depends on:
- The "Implement the new ABI policy and add helper scripts" patchset
(http://patches.dpdk.org/project/dpdk/list/?series=6913).
- The "Add scanning for experimental symbols to meson" patchset
(http://patches.dpdk.org/project/dpdk/list/?series=6744).
- "build: enable extra warnings for meson build" patch
(http://patches.dpdk.org/patch/60622/).
Bruce Richardson (2):
build: enable debug info by default in meson builds
build: use meson warning levels
Kevin Laatz (4):
devtools: add abi dump generation script
build: add meson option for abi related checks
build: add lib abi checks to meson
build: add drivers abi checks to meson
buildtools/meson.build | 4 ++++
config/meson.build | 40 +++++++++++++++++++++-------------------
devtools/gen-abi-dump.sh | 24 ++++++++++++++++++++++++
drivers/meson.build | 17 ++++++++++++++++-
lib/meson.build | 17 ++++++++++++++++-
meson.build | 9 ++++++++-
meson_options.txt | 2 ++
7 files changed, 91 insertions(+), 22 deletions(-)
create mode 100755 devtools/gen-abi-dump.sh
--
2.17.1
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-22 22:51 0% ` Ananyev, Konstantin
@ 2019-10-23 3:16 0% ` Wang, Haiyue
2019-10-23 10:21 0% ` Olivier Matz
2019-10-23 10:19 0% ` Olivier Matz
1 sibling, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-10-23 3:16 UTC (permalink / raw)
To: Ananyev, Konstantin, Olivier Matz, dev
Cc: Andrew Rybchenko, Richardson, Bruce, Jerin Jacob Kollanukkaran,
Wiles, Keith, Morten Brørup, Stephen Hemminger,
Thomas Monjalon
> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Wednesday, October 23, 2019 06:52
> To: Olivier Matz <olivier.matz@6wind.com>; dev@dpdk.org
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>; Wang,
> Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> <keith.wiles@intel.com>; Morten Brørup <mb@smartsharesystems.com>; Stephen Hemminger
> <stephen@networkplumber.org>; Thomas Monjalon <thomas@monjalon.net>
> Subject: RE: [PATCH v2] mbuf: support dynamic fields and flags
>
>
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> >
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> >
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> > given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> >
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature. As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> >
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >
> > v2
> >
> > * Rebase on top of master: solve conflict with Stephen's patchset
> > (packet copy)
> > * Add new apis to register a dynamic field/flag at a specific place
> > * Add a dump function (sugg by David)
> > * Enhance field registration function to select the best offset, keeping
> > large aligned zones as much as possible (sugg by Konstantin)
> > * Use a size_t and unsigned int instead of int when relevant
> > (sugg by Konstantin)
> > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > (sugg by Konstantin)
> > * Remove unused argument in private function (sugg by Konstantin)
> > * Fix and simplify locking (sugg by Konstantin)
> > * Fix minor typo
> >
> > rfc -> v1
> >
> > * Rebase on top of master
> > * Change registration API to use a structure instead of
> > variables, getting rid of #defines (Stephen's comment)
> > * Update flag registration to use a similar API as fields.
> > * Change max name length from 32 to 64 (sugg. by Thomas)
> > * Enhance API documentation (Haiyue's and Andrew's comments)
> > * Add a debug log at registration
> > * Add some words in release note
> > * Did some performance tests (sugg. by Andrew):
> > On my platform, reading a dynamic field takes ~3 cycles more
> > than a static field, and ~2 cycles more for writing.
> >
> > app/test/test_mbuf.c | 145 ++++++-
> > doc/guides/rel_notes/release_19_11.rst | 7 +
> > lib/librte_mbuf/Makefile | 2 +
> > lib/librte_mbuf/meson.build | 6 +-
> > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > 8 files changed, 959 insertions(+), 5 deletions(-)
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> >
> > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > index b9c2b2500..01cafad59 100644
> > --- a/app/test/test_mbuf.c
> > +++ b/app/test/test_mbuf.c
> > @@ -28,6 +28,7 @@
> > #include <rte_random.h>
> > #include <rte_cycles.h>
> > #include <rte_malloc.h>
> > +#include <rte_mbuf_dyn.h>
> >
[snip]
> > +int
> > +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> > + unsigned int req)
> > +{
> > + int ret;
> > +
> > + if (req != UINT_MAX && req >= 64) {
>
> Might be better to replace 64 with something like sizeof(mbuf->ol_flags) * CHAR_BIT or so.
Might introduce a new macro like kernel:
/**
* FIELD_SIZEOF - get the size of a struct's field
* @t: the target struct
* @f: the target struct's field
* Return: the size of @f in the struct definition without having a
* declared instance of @t.
*/
#define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
Then: FIELD_SIZEOF(rte_mbuf, ol_flags) * CHAR_BIT
> Apart from that:
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
>
> > + rte_errno = EINVAL;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_write_lock();
> > + ret = __rte_mbuf_dynflag_register_bitnum(params, req);
> > + rte_mcfg_tailq_write_unlock();
> > +
> > + return ret;
> > +}
> > +
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-17 14:42 3% ` [dpdk-dev] [PATCH v2] " Olivier Matz
2019-10-18 2:47 0% ` Wang, Haiyue
@ 2019-10-22 22:51 0% ` Ananyev, Konstantin
2019-10-23 3:16 0% ` Wang, Haiyue
2019-10-23 10:19 0% ` Olivier Matz
2019-10-23 12:00 0% ` Shahaf Shuler
2 siblings, 2 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-22 22:51 UTC (permalink / raw)
To: Olivier Matz, dev
Cc: Andrew Rybchenko, Richardson, Bruce, Wang, Haiyue,
Jerin Jacob Kollanukkaran, Wiles, Keith, Morten Brørup,
Stephen Hemminger, Thomas Monjalon
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
>
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
>
> - a dynamic field is a named area in the rte_mbuf structure, with a
> given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
>
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature. As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
>
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>
> v2
>
> * Rebase on top of master: solve conflict with Stephen's patchset
> (packet copy)
> * Add new apis to register a dynamic field/flag at a specific place
> * Add a dump function (sugg by David)
> * Enhance field registration function to select the best offset, keeping
> large aligned zones as much as possible (sugg by Konstantin)
> * Use a size_t and unsigned int instead of int when relevant
> (sugg by Konstantin)
> * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> (sugg by Konstantin)
> * Remove unused argument in private function (sugg by Konstantin)
> * Fix and simplify locking (sugg by Konstantin)
> * Fix minor typo
>
> rfc -> v1
>
> * Rebase on top of master
> * Change registration API to use a structure instead of
> variables, getting rid of #defines (Stephen's comment)
> * Update flag registration to use a similar API as fields.
> * Change max name length from 32 to 64 (sugg. by Thomas)
> * Enhance API documentation (Haiyue's and Andrew's comments)
> * Add a debug log at registration
> * Add some words in release note
> * Did some performance tests (sugg. by Andrew):
> On my platform, reading a dynamic field takes ~3 cycles more
> than a static field, and ~2 cycles more for writing.
>
> app/test/test_mbuf.c | 145 ++++++-
> doc/guides/rel_notes/release_19_11.rst | 7 +
> lib/librte_mbuf/Makefile | 2 +
> lib/librte_mbuf/meson.build | 6 +-
> lib/librte_mbuf/rte_mbuf.h | 23 +-
> lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> lib/librte_mbuf/rte_mbuf_version.map | 7 +
> 8 files changed, 959 insertions(+), 5 deletions(-)
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
>
> diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> index b9c2b2500..01cafad59 100644
> --- a/app/test/test_mbuf.c
> +++ b/app/test/test_mbuf.c
> @@ -28,6 +28,7 @@
> #include <rte_random.h>
> #include <rte_cycles.h>
> #include <rte_malloc.h>
> +#include <rte_mbuf_dyn.h>
>
> #include "test.h"
>
> @@ -657,7 +658,6 @@ test_attach_from_different_pool(struct rte_mempool *pktmbuf_pool,
> rte_pktmbuf_free(clone2);
> return -1;
> }
> -#undef GOTO_FAIL
>
> /*
> * test allocation and free of mbufs
> @@ -1276,6 +1276,143 @@ test_tx_offload(void)
> return (v1 == v2) ? 0 : -EINVAL;
> }
>
> +static int
> +test_mbuf_dyn(struct rte_mempool *pktmbuf_pool)
> +{
> + const struct rte_mbuf_dynfield dynfield = {
> + .name = "test-dynfield",
> + .size = sizeof(uint8_t),
> + .align = __alignof__(uint8_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield2 = {
> + .name = "test-dynfield2",
> + .size = sizeof(uint16_t),
> + .align = __alignof__(uint16_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield3 = {
> + .name = "test-dynfield3",
> + .size = sizeof(uint8_t),
> + .align = __alignof__(uint8_t),
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield_fail_big = {
> + .name = "test-dynfield-fail-big",
> + .size = 256,
> + .align = 1,
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynfield dynfield_fail_align = {
> + .name = "test-dynfield-fail-align",
> + .size = 1,
> + .align = 3,
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag = {
> + .name = "test-dynflag",
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag2 = {
> + .name = "test-dynflag2",
> + .flags = 0,
> + };
> + const struct rte_mbuf_dynflag dynflag3 = {
> + .name = "test-dynflag3",
> + .flags = 0,
> + };
> + struct rte_mbuf *m = NULL;
> + int offset, offset2, offset3;
> + int flag, flag2, flag3;
> + int ret;
> +
> + printf("Test mbuf dynamic fields and flags\n");
> + rte_mbuf_dyn_dump(stdout);
> +
> + offset = rte_mbuf_dynfield_register(&dynfield);
> + if (offset == -1)
> + GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
> + offset, strerror(errno));
> +
> + ret = rte_mbuf_dynfield_register(&dynfield);
> + if (ret != offset)
> + GOTO_FAIL("failed to lookup dynamic field, ret=%d: %s",
> + ret, strerror(errno));
> +
> + offset2 = rte_mbuf_dynfield_register(&dynfield2);
> + if (offset2 == -1 || offset2 == offset || (offset2 & 1))
> + GOTO_FAIL("failed to register dynamic field 2, offset2=%d: %s",
> + offset2, strerror(errno));
> +
> + offset3 = rte_mbuf_dynfield_register_offset(&dynfield3,
> + offsetof(struct rte_mbuf, dynfield1[1]));
> + if (offset3 != offsetof(struct rte_mbuf, dynfield1[1]))
> + GOTO_FAIL("failed to register dynamic field 3, offset=%d: %s",
> + offset3, strerror(errno));
> +
> + printf("dynfield: offset=%d, offset2=%d, offset3=%d\n",
> + offset, offset2, offset3);
> +
> + ret = rte_mbuf_dynfield_register(&dynfield_fail_big);
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (too big)");
> +
> + ret = rte_mbuf_dynfield_register(&dynfield_fail_align);
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (bad alignment)");
> +
> + ret = rte_mbuf_dynfield_register_offset(&dynfield_fail_align,
> + offsetof(struct rte_mbuf, ol_flags));
> + if (ret != -1)
> + GOTO_FAIL("dynamic field creation should fail (not avail)");
> +
> + flag = rte_mbuf_dynflag_register(&dynflag);
> + if (flag == -1)
> + GOTO_FAIL("failed to register dynamic flag, flag=%d: %s",
> + flag, strerror(errno));
> +
> + ret = rte_mbuf_dynflag_register(&dynflag);
> + if (ret != flag)
> + GOTO_FAIL("failed to lookup dynamic flag, ret=%d: %s",
> + ret, strerror(errno));
> +
> + flag2 = rte_mbuf_dynflag_register(&dynflag2);
> + if (flag2 == -1 || flag2 == flag)
> + GOTO_FAIL("failed to register dynamic flag 2, flag2=%d: %s",
> + flag2, strerror(errno));
> +
> + flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3,
> + rte_bsf64(PKT_LAST_FREE));
> + if (flag3 != rte_bsf64(PKT_LAST_FREE))
> + GOTO_FAIL("failed to register dynamic flag 3, flag2=%d: %s",
> + flag3, strerror(errno));
> +
> + printf("dynflag: flag=%d, flag2=%d, flag3=%d\n", flag, flag2, flag3);
> +
> + /* set, get dynamic field */
> + m = rte_pktmbuf_alloc(pktmbuf_pool);
> + if (m == NULL)
> + GOTO_FAIL("Cannot allocate mbuf");
> +
> + *RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
> + if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
> + GOTO_FAIL("failed to read dynamic field");
> + *RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
> + if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
> + GOTO_FAIL("failed to read dynamic field");
> +
> + /* set a dynamic flag */
> + m->ol_flags |= (1ULL << flag);
> +
> + rte_mbuf_dyn_dump(stdout);
> + rte_pktmbuf_free(m);
> + return 0;
> +fail:
> + rte_pktmbuf_free(m);
> + return -1;
> +}
> +#undef GOTO_FAIL
> +
> static int
> test_mbuf(void)
> {
> @@ -1295,6 +1432,12 @@ test_mbuf(void)
> goto err;
> }
>
> + /* test registration of dynamic fields and flags */
> + if (test_mbuf_dyn(pktmbuf_pool) < 0) {
> + printf("mbuf dynflag test failed\n");
> + goto err;
> + }
> +
> /* create a specific pktmbuf pool with a priv_size != 0 and no data
> * room size */
> pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
> diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
> index 85953b962..9e9c94554 100644
> --- a/doc/guides/rel_notes/release_19_11.rst
> +++ b/doc/guides/rel_notes/release_19_11.rst
> @@ -21,6 +21,13 @@ DPDK Release 19.11
>
> xdg-open build/doc/html/guides/rel_notes/release_19_11.html
>
> +* **Add support of support dynamic fields and flags in mbuf.**
> +
> + This new feature adds the ability to dynamically register some room
> + for a field or a flag in the mbuf structure. This is typically used
> + for specific offload features, where adding a static field or flag
> + in the mbuf is not justified.
> +
>
> New Features
> ------------
> diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
> index c8f6d2689..5a9bcee73 100644
> --- a/lib/librte_mbuf/Makefile
> +++ b/lib/librte_mbuf/Makefile
> @@ -17,8 +17,10 @@ LIBABIVER := 5
>
> # all source are stored in SRCS-y
> SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
> +SRCS-$(CONFIG_RTE_LIBRTE_MBUF) += rte_mbuf_dyn.c
>
> # install includes
> SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h rte_mbuf_ptype.h rte_mbuf_pool_ops.h
> +SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include += rte_mbuf_dyn.h
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
> index 6cc11ebb4..9137e8f26 100644
> --- a/lib/librte_mbuf/meson.build
> +++ b/lib/librte_mbuf/meson.build
> @@ -2,8 +2,10 @@
> # Copyright(c) 2017 Intel Corporation
>
> version = 5
> -sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
> -headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
> +sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c',
> + 'rte_mbuf_dyn.c')
> +headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h',
> + 'rte_mbuf_dyn.h')
> deps += ['mempool']
>
> allow_experimental_apis = true
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index fb0849ac1..5740b1e93 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -198,9 +198,12 @@ extern "C" {
> #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
>
> -/* add new RX flags here */
> +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
>
> -/* add new TX flags here */
> +#define PKT_FIRST_FREE (1ULL << 23)
> +#define PKT_LAST_FREE (1ULL << 39)
> +
> +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
>
> /**
> * Indicate that the metadata field in the mbuf is in use.
> @@ -738,6 +741,7 @@ struct rte_mbuf {
> */
> struct rte_mbuf_ext_shared_info *shinfo;
>
> + uint64_t dynfield1[2]; /**< Reserved for dynamic fields. */
> } __rte_cache_aligned;
>
> /**
> @@ -1684,6 +1688,20 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> */
> #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
>
> +/**
> + * Copy dynamic fields from m_src to m_dst.
> + *
> + * @param m_dst
> + * The destination mbuf.
> + * @param m_src
> + * The source mbuf.
> + */
> +static inline void
> +rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> +{
> + memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
> +}
> +
> /* internal */
> static inline void
> __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> @@ -1695,6 +1713,7 @@ __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
> mdst->hash = msrc->hash;
> mdst->packet_type = msrc->packet_type;
> mdst->timestamp = msrc->timestamp;
> + rte_mbuf_dynfield_copy(mdst, msrc);
> }
>
> /**
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> new file mode 100644
> index 000000000..9ef235483
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> @@ -0,0 +1,548 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#include <sys/queue.h>
> +#include <stdint.h>
> +#include <limits.h>
> +
> +#include <rte_common.h>
> +#include <rte_eal.h>
> +#include <rte_eal_memconfig.h>
> +#include <rte_tailq.h>
> +#include <rte_errno.h>
> +#include <rte_malloc.h>
> +#include <rte_string_fns.h>
> +#include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> +
> +struct mbuf_dynfield_elt {
> + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> + struct rte_mbuf_dynfield params;
> + size_t offset;
> +};
> +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> + .name = "RTE_MBUF_DYNFIELD",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> +
> +struct mbuf_dynflag_elt {
> + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> + struct rte_mbuf_dynflag params;
> + unsigned int bitnum;
> +};
> +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> + .name = "RTE_MBUF_DYNFLAG",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> +
> +struct mbuf_dyn_shm {
> + /**
> + * For each mbuf byte, free_space[i] != 0 if space is free.
> + * The value is the size of the biggest aligned element that
> + * can fit in the zone.
> + */
> + uint8_t free_space[sizeof(struct rte_mbuf)];
> + /** Bitfield of available flags. */
> + uint64_t free_flags;
> +};
> +static struct mbuf_dyn_shm *shm;
> +
> +/* Set the value of free_space[] according to the size and alignment of
> + * the free areas. This helps to select the best place when reserving a
> + * dynamic field. Assume tailq is locked.
> + */
> +static void
> +process_score(void)
> +{
> + size_t off, align, size, i;
> +
> + /* first, erase previous info */
> + for (i = 0; i < sizeof(struct rte_mbuf); i++) {
> + if (shm->free_space[i])
> + shm->free_space[i] = 1;
> + }
> +
> + for (off = 0; off < sizeof(struct rte_mbuf); off++) {
> + /* get the size of the free zone */
> + for (size = 0; shm->free_space[off + size]; size++)
> + ;
> + if (size == 0)
> + continue;
> +
> + /* get the alignment of biggest object that can fit in
> + * the zone at this offset.
> + */
> + for (align = 1;
> + (off % (align << 1)) == 0 && (align << 1) <= size;
> + align <<= 1)
> + ;
> +
> + /* save it in free_space[] */
> + for (i = off; i < off + size; i++)
> + shm->free_space[i] = RTE_MAX(align, shm->free_space[i]);
> + }
> +}
> +
> +/* Allocate and initialize the shared memory. Assume tailq is locked */
> +static int
> +init_shared_mem(void)
> +{
> + const struct rte_memzone *mz;
> + uint64_t mask;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> + sizeof(struct mbuf_dyn_shm),
> + SOCKET_ID_ANY, 0,
> + RTE_CACHE_LINE_SIZE);
> + } else {
> + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> + }
> + if (mz == NULL)
> + return -1;
> +
> + shm = mz->addr;
> +
> +#define mark_free(field) \
> + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> + 1, sizeof(((struct rte_mbuf *)0)->field))
Still think it would look nicer without multi-line macro defines/undef in the middle of the function.
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + /* init free_space, keep it sync'd with
> + * rte_mbuf_dynfield_copy().
> + */
> + memset(shm, 0, sizeof(*shm));
> + mark_free(dynfield1);
> +
> + /* init free_flags */
> + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> + shm->free_flags |= mask;
> +
> + process_score();
> + }
> +#undef mark_free
> +
> + return 0;
> +}
> +
> +/* check if this offset can be used */
> +static int
> +check_offset(size_t offset, size_t size, size_t align)
> +{
> + size_t i;
> +
> + if ((offset & (align - 1)) != 0)
> + return -1;
> + if (offset + size > sizeof(struct rte_mbuf))
> + return -1;
> +
> + for (i = 0; i < size; i++) {
> + if (!shm->free_space[i + offset])
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynfield_elt *
> +__mbuf_dynfield_lookup(const char *name)
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynfield;
> +}
> +
> +int
> +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> +{
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynfield == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> +
> + return mbuf_dynfield->offset;
> +}
> +
> +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> + const struct rte_mbuf_dynfield *params2)
> +{
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->size != params2->size)
> + return -1;
> + if (params1->align != params2->align)
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static int
> +__rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
> + size_t req)
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> + struct rte_tailq_entry *te = NULL;
> + unsigned int best_zone = UINT_MAX;
> + size_t i, offset;
> + int ret;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + return -1;
> +
> + mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
> + if (mbuf_dynfield != NULL) {
> + if (req != SIZE_MAX && req != mbuf_dynfield->offset) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) < 0) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + return mbuf_dynfield->offset;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + return -1;
> + }
> +
> + if (req == SIZE_MAX) {
> + for (offset = 0;
> + offset < sizeof(struct rte_mbuf);
> + offset++) {
> + if (check_offset(offset, params->size,
> + params->align) == 0 &&
> + shm->free_space[offset] < best_zone) {
Probably worth to explain a bit more here about best_zone logic -
trying to find offset with minimal score (minimal continuous length), etc.
> + best_zone = shm->free_space[offset];
> + req = offset;
> + }
> + }
> + if (req == SIZE_MAX) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> + } else {
> + if (check_offset(req, params->size, params->align) < 0) {
> + rte_errno = EBUSY;
> + return -1;
> + }
> + }
> +
> + offset = req;
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + return -1;
> +
> + mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
> + if (mbuf_dynfield == NULL) {
> + rte_free(te);
> + return -1;
> + }
> +
> + ret = strlcpy(mbuf_dynfield->params.name, params->name,
> + sizeof(mbuf_dynfield->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
> + rte_errno = ENAMETOOLONG;
> + rte_free(mbuf_dynfield);
> + rte_free(te);
> + return -1;
> + }
> + memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield->params));
> + mbuf_dynfield->offset = offset;
> + te->data = mbuf_dynfield;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> +
> + for (i = offset; i < offset + params->size; i++)
> + shm->free_space[i] = 0;
> + process_score();
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu, al=%zu, fl=0x%x) -> %zd\n",
> + params->name, params->size, params->align, params->flags,
> + offset);
> +
> + return offset;
> +}
> +
> +int
> +rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
> + size_t req)
> +{
> + int ret;
> +
> + if (params->size >= sizeof(struct rte_mbuf)) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> + if (!rte_is_power_of_2(params->align)) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> + if (params->flags != 0) {
> + rte_errno = EINVAL;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_write_lock();
> + ret = __rte_mbuf_dynfield_register_offset(params, req);
> + rte_mcfg_tailq_write_unlock();
> +
> + return ret;
> +}
> +
> +int
> +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
> +{
> + return rte_mbuf_dynfield_register_offset(params, SIZE_MAX);
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynflag_elt *
> +__mbuf_dynflag_lookup(const char *name)
> +{
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> + mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
> + if (strncmp(name, mbuf_dynflag->params.name,
> + RTE_MBUF_DYN_NAMESIZE) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynflag;
> +}
> +
> +int
> +rte_mbuf_dynflag_lookup(const char *name,
> + struct rte_mbuf_dynflag *params)
> +{
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynflag = __mbuf_dynflag_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynflag == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynflag->params, sizeof(*params));
> +
> + return mbuf_dynflag->bitnum;
> +}
> +
> +static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
> + const struct rte_mbuf_dynflag *params2)
> +{
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static int
> +__rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> + unsigned int req)
> +{
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
> + struct rte_tailq_entry *te = NULL;
> + unsigned int bitnum;
> + int ret;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + return -1;
> +
> + mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
> + if (mbuf_dynflag != NULL) {
> + if (req != UINT_MAX && req != mbuf_dynflag->bitnum) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) < 0) {
> + rte_errno = EEXIST;
> + return -1;
> + }
> + return mbuf_dynflag->bitnum;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + return -1;
> + }
> +
> + if (req == UINT_MAX) {
> + if (shm->free_flags == 0) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> + bitnum = rte_bsf64(shm->free_flags);
> + } else {
> + if ((shm->free_flags & (1ULL << req)) == 0) {
> + rte_errno = EBUSY;
> + return -1;
> + }
> + bitnum = req;
> + }
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + return -1;
> +
> + mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
> + if (mbuf_dynflag == NULL) {
> + rte_free(te);
> + return -1;
> + }
> +
> + ret = strlcpy(mbuf_dynflag->params.name, params->name,
> + sizeof(mbuf_dynflag->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
> + rte_free(mbuf_dynflag);
> + rte_free(te);
> + rte_errno = ENAMETOOLONG;
> + return -1;
> + }
> + mbuf_dynflag->bitnum = bitnum;
> + te->data = mbuf_dynflag;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> +
> + shm->free_flags &= ~(1ULL << bitnum);
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) -> %u\n",
> + params->name, params->flags, bitnum);
> +
> + return bitnum;
> +}
> +
> +int
> +rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
> + unsigned int req)
> +{
> + int ret;
> +
> + if (req != UINT_MAX && req >= 64) {
Might be better to replace 64 with something like sizeof(mbuf->ol_flags) * CHAR_BIT or so.
Apart from that:
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> + rte_errno = EINVAL;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_write_lock();
> + ret = __rte_mbuf_dynflag_register_bitnum(params, req);
> + rte_mcfg_tailq_write_unlock();
> +
> + return ret;
> +}
> +
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-22 17:44 0% ` Ananyev, Konstantin
@ 2019-10-22 22:21 0% ` Ananyev, Konstantin
2019-10-23 10:05 0% ` Akhil Goyal
1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-22 22:21 UTC (permalink / raw)
To: 'Akhil Goyal', 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', 'Hemant Agrawal'
> > > > Added my comments inline with your draft.
> > > > [snip]..
> > > >
> > > > >
> > > > > Ok, then my suggestion:
> > > > > Let's at least write down all points about crypto-dev approach where we
> > > > > disagree and then probably try to resolve them one by one....
> > > > > If we fail to make an agreement/progress in next week or so,
> > > > > (and no more reviews from the community)
> > > > > will have bring that subject to TB meeting to decide.
> > > > > Sounds fair to you?
> > > > Agreed
> > > > >
> > > > > List is below.
> > > > > Please add/correct me, if I missed something.
> > > > >
> > > > > Konstantin
> > > >
> > > > Before going into comparison, we should define the requirement as well.
> > >
> > > Good point.
> > >
> > > > What I understood from the patchset,
> > > > "You need a synchronous API to perform crypto operations on raw data using
> > > SW PMDs"
> > > > So,
> > > > - no crypto-ops,
> > > > - no separate enq-deq, only single process API for data path
> > > > - Do not need any value addition to the session parameters.
> > > > (You would need some parameters from the crypto-op which
> > > > Are constant per session and since you wont use crypto-op,
> > > > You need some place to store that)
> > >
> > > Yes, this is correct, I think.
> > >
> > > >
> > > > Now as per your mail, the comparison
> > > > 1. extra input parameters to create/init rte_(cpu)_sym_session.
> > > >
> > > > Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and
> > > 'key' fields.
> > > > New fields will be optional and would be used by PMD only when cpu-crypto
> > > session is requested.
> > > > For lksd-crypto session PMD is free to ignore these fields.
> > > > No ABI breakage is required.
> > > >
> > > > [Akhil] Agreed, no issues.
> > > >
> > > > 2. cpu-crypto create/init.
> > > > a) Our suggestion - introduce new API for that:
> > > > - rte_crypto_cpu_sym_init() that would init completely opaque
> > > rte_crypto_cpu_sym_session.
> > > > - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear);
> > > /*whatever else we'll need *'};
> > > > - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform
> > > *xforms)
> > > > that would return const struct rte_crypto_cpu_sym_session_ops *based
> > > on input xforms.
> > > > Advantages:
> > > > 1) totally opaque data structure (no ABI breakages in future), PMD
> > > writer is totally free
> > > > with it format and contents.
> > > >
> > > > [Akhil] It will have breakage at some point till we don't hit the union size.
> > >
> > > Not sure, what union you are talking about?
> >
> > Union of xforms in rte_security_session_conf
>
> Hmm, how does it relates here?
> I thought we discussing pure rte_cryptodev_sym_session, no?
>
> >
> > >
> > > > Rather I don't suspect there will be more parameters added.
> > > > Or do we really care about the ABI breakage when the argument is about
> > > > the correct place to add a piece of code or do we really agree to add code
> > > > anywhere just to avoid that breakage.
> > >
> > > I am talking about maintaining it in future.
> > > if your struct is not seen externally, no chances to introduce ABI breakage.
> > >
> > > >
> > > > 2) each session entity is self-contained, user doesn't need to bring along
> > > dev_id etc.
> > > > dev_id is needed only at init stage, after that user will use session ops
> > > to perform
> > > > all operations on that session (process(), clear(), etc.).
> > > >
> > > > [Akhil] There is nothing called as session ops in current DPDK.
> > >
> > > True, but it doesn't mean we can't/shouldn't have it.
> >
> > We can have it if it is not adding complexity for the user. Creating 2 different code
> > Paths for user is not desirable for the stack developers.
> >
> > >
> > > > What you are proposing
> > > > is a new concept which doesn't have any extra benefit, rather it is adding
> > > complexity
> > > > to have two different code paths for session create.
> > > >
> > > >
> > > > 3) User can decide does he wants to store ops[] pointer on a per session
> > > basis,
> > > > or on a per group of same sessions, or...
> > > >
> > > > [Akhil] Will the user really care which process API should be called from the
> > > PMD.
> > > > Rather it should be driver's responsibility to store that in the session private
> > > data
> > > > which would be opaque to the user. As per my suggestion same process
> > > function can
> > > > be added to multiple sessions or a single session can be managed inside the
> > > PMD.
> > >
> > > In that case we either need to have a function per session (stored internally),
> > > or make decision (branches) at run-time.
> > > But as I said in other mail - I am ok to add small shim structure here:
> > > either rte_crypto_cpu_sym_session { void *ses; struct
> > > rte_crypto_cpu_sym_session_ops ops; }
> > > or rte_crypto_cpu_sym_session { void *ses; struct
> > > rte_crypto_cpu_sym_session_ops *ops; }
> > > And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops() into
> > > one (init).
> >
> > Again that will be a separate API call from the user perspective which is not good.
> >
> > >
> > > >
> > > >
> > > > 4) No mandatory mempools for private sessions. User can allocate
> > > memory for cpu-crypto
> > > > session whenever he likes.
> > > >
> > > > [Akhil] you mean session private data?
> > >
> > > Yes.
> > >
> > > > You would need that memory anyways, user will be
> > > > allocating that already. You do not need to manage that.
> > >
> > > What I am saying - right now user has no choice but to allocate it via mempool.
> > > Which is probably not the best options for all cases.
> > >
> > > >
> > > > Disadvantages:
> > > > 5) Extra changes in control path
> > > > 6) User has to store session_ops pointer explicitly.
> > > >
> > > > [Akhil] More disadvantages:
> > > > - All supporting PMDs will need to maintain TWO types of session for the
> > > > same crypto processing. Suppose a fix or a new feature(or algo) is added, PMD
> > > owner
> > > > will need to add code in both the session create APIs. Hence more
> > > maintenance and
> > > > error prone.
> > >
> > > I think majority of code for both paths will be common, plus even we'll reuse
> > > current sym_session_init() -
> > > changes in PMD session_init() code will be unavoidable.
> > > But yes, it will be new entry in devops, that PMD will have to support.
> > > Ok to add it as 7) to the list.
> > >
> > > > - Stacks which will be using these new APIs also need to maintain two
> > > > code path for the same processing while doing session initialization
> > > > for sync and async
> > >
> > > That's the same as #5 above, I think.
> > >
> > > >
> > > >
> > > > b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and
> > > existing rte_cryptodev_sym_session
> > > > structure.
> > > > Advantages:
> > > > 1) allows to reuse same struct and init/create/clear() functions.
> > > > Probably less changes in control path.
> > > > Disadvantages:
> > > > 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id,
> > > which means that
> > > > we can't use the same rte_cryptodev_sym_session to hold private
> > > sessions pointers
> > > > for both sync and async mode for the same device.
> > > > So the only option we have - make PMD devops-
> > > >sym_session_configure()
> > > > always create a session that can work in both cpu and lksd modes.
> > > > For some implementations that would probably mean that under the
> > > hood PMD would create
> > > > 2 different session structs (sync/async) and then use one or another
> > > depending on from what API been called.
> > > > Seems doable, but ...:
> > > > - will contradict with statement from 1:
> > > > " New fields will be optional and would be used by PMD only when
> > > cpu-crypto session is requested."
> > > > Now it becomes mandatory for all apps to specify cpu-crypto
> > > related parameters too,
> > > > even if they don't plan to use that mode - i.e. behavior change,
> > > existing app change.
> > > > - might cause extra space overhead.
> > > >
> > > > [Akhil] It will not contradict with #1, you will only have few checks in the
> > > session init PMD
> > > > Which support this mode, find appropriate values and set the appropriate
> > > process() in it.
> > > > User should be able to call, legacy enq-deq as well as the new process()
> > > without any issue.
> > > > User would be at runtime will be able to change the datapath.
> > > > So this is not a disadvantage, it would be additional flexibility for the user.
> > >
> > > Ok, but that's what I am saying - if PMD would *always* have to create a
> > > session that can handle
> > > both modes (sync/async), then user would *always* have to provide parameters
> > > for both modes too.
> > > Otherwise if let say user didn't setup sync specific parameters at all, what PMD
> > > should do?
> > > - return with error?
> > > - init session that can be used with async path only?
> > > My current assumption is #1.
> > > If #2, then how user will be able to distinguish is that session valid for both
> > > modes, or only for one?
> >
> > I would say a 3rd option, do nothing if sync params are not set.
> > Probably have a debug print in the PMD(which support sync mode) to specify that
> > session is not configured properly for sync mode.
>
> So, just print warning and proceed with init session that can be used with async path only?
> Then it sounds the same as #2 above.
> Which actually means that sync mode parameters for sym_session_init() becomes optional.
> Then we need an API to provide to the user information what modes
> (sync+async/async only) is supported by that session for given dev_id.
> And user would have to query/retain this information at control-path,
> and store it somewhere in user-space together with session pointer and dev_ids
> to use later at data-path (same as we do now for session type).
> That definitely requires changes in control-path to start using it.
> Plus the fact that this value can differ for different dev_ids for the same session -
> doesn't make things easier here.
>
> > Internally the PMD will not store the process() API in the session priv data
> > And while calling the first packet, devops->process will give an assert that session
> > Is not configured for sync mode. The session validation would be done in any case
> > your suggestion or mine. So no extra overhead at runtime.
>
> I believe that after session_init() user should get either an error or
> valid session handler that he can use at runtime.
> Pushing session validation to runtime doesn't seem like a good idea.
>
> >
> > >
> > >
> > > >
> > > >
> > > > 3) not possible to store device (not driver) specific data within the
> > > session, but I think it is not really needed right now.
> > > > So probably minor compared to 2.b.2.
> > > >
> > > > [Akhil] So lets omit this for current discussion. And I hope we can find some
> > > way to deal with it.
> > >
> > > I don't think there is an easy way to fix that with existing API.
> > >
> > > >
> > > >
> > > > Actually #3 follows from #2, but decided to have them separated.
> > > >
> > > > 3. process() parameters/behavior
> > > > a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and
> > > just does:
> > > > session_ops->process(sess, ...);
> > > > Advantages:
> > > > 1) fastest possible execution path
> > > > 2) no need to carry on dev_id for data-path
> > > >
> > > > [Akhil] I don't see any overhead of carrying dev id, at least it would be inline
> > > with the
> > > > current DPDK methodology.
> > >
> > > If we'll add process() into rte_cryptodev itself (same as we have
> > > enqueue_burst/dequeue_burst),
> > > then it will be an ABI breakage.
> > > Also there are discussions to get rid of that approach completely:
> > > http://mails.dpdk.org/archives/dev/2019-September/144674.html
> > > So I am not sure this is a recommended way these days.
> >
> > We can either have it in rte_cryptodev or in rte_cryptodev_ops whichever
> > is good for you.
> >
> > Whether it is ABI breakage or not, as per your requirements, this is the correct
> > approach. Do you agree with this or not?
>
> I think it is possible approach, but not the best one:
> it looks quite flakey to me (see all these uncertainty with sym_session_init above),
> plus introduces extra overhead at data-path.
>
> >
> > Now handling the API/ABI breakage is a separate story. In 19.11 release we
> > Are not much concerned about the ABI breakages, this was discussed in
> > community. So adding a new dev_ops wouldn't have been an issue.
> > Now since we are so close to RC1 deadline, we should come up with some
> > other solution for next release. May be having a pmd API in 20.02 and
> > converting it into formal one in 20.11
> >
> >
> > >
> > > > What you are suggesting is a new way to get the things done without much
> > > benefit.
> > >
> > > Would help with ABI stability plus better performance, isn't it enough?
> > >
> > > > Also I don't see any performance difference as crypto workload is heavier than
> > > > Code cycles, so that wont matter.
> > >
> > > It depends.
> > > Suppose function call costs you ~30 cycles.
> > > If you have burst of big packets (let say crypto for each will take ~2K cycles) that
> > > belong
> > > to the same session, then yes you wouldn't notice these extra 30 cycles at all.
> > > If you have burst of small packets (let say crypto for each will take ~300 cycles)
> > > each
> > > belongs to different session, then it will cost you ~10% extra.
> >
> > Let us do some profiling on openssl with both the approaches and find out the
> > difference.
> >
> > >
> > > > So IMO, there is no advantage in your suggestion as well.
> > > >
> > > >
> > > > Disadvantages:
> > > > 3) user has to carry on session_ops pointer explicitly
> > > > b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
> > > > rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session
> > > *sess, /*data parameters*/) {...
> > > > rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> > > > /*and then inside PMD specifc process: */
> > > > pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
> > > > /* and then most likely either */
> > > > pmd_private_session->process(pmd_private_session, ...);
> > > > /* or jump based on session/input data */
> > > > Advantages:
> > > > 1) don't see any...
> > > > Disadvantages:
> > > > 2) User has to carry on dev_id inside data-path
> > > > 3) Extra level of indirection (plus data dependency) - both for data and
> > > instructions.
> > > > Possible slowdown compared to a) (not measured).
> > > >
> > > > Having said all this, if the disagreements cannot be resolved, you can go for a
> > > pmd API specific
> > > > to your PMDs,
> > >
> > > I don't think it is good idea.
> > > PMD specific API is sort of deprecated path, also there is no clean way to use it
> > > within the libraries.
> >
> > I know that this is a deprecated path, we can use it until we are not allowed
> > to break ABI/API
> >
> > >
> > > > because as per my understanding the solution doesn't look scalable to other
> > > PMDs.
> > > > Your approach is aligned only to Intel , will not benefit others like openssl
> > > which is used by all
> > > > vendors.
> > >
> > > I feel quite opposite, from my perspective majority of SW backed PMDs will
> > > benefit from it.
> > > And I don't see anything Intel specific in my proposals above.
> > > About openssl PMD: I am not an expert here, but looking at the code, I think it
> > > will fit really well.
> > > Look yourself at its internal functions:
> > > process_openssl_auth_op/process_openssl_crypto_op,
> > > I think they doing exactly the same - they use sync API underneath, and they are
> > > session based
> > > (AFAIK you don't need any device/queue data, everything that needed for
> > > crypto/auth is stored inside session).
Looked at drivers/crypto/armv8 - same story here, I believe.
> > >
> > By vendor specific, I mean,
> > - no PMD would like to have 2 different variants of session Init APIs for doing the same stuff.
> > - stacks will become vendor specific while using 2 separate session create APIs. No stack would
> > Like to support 2 variants of session create- one for HW PMDs and one for SW PMDs.
>
> I think what you refer on has nothing to do with 'vendor specific'.
> I would name it 'extra overhead for PMD and stack writers'.
> Yes, for sure there is extra overhead (as always with new API) -
> for both producer (PMD writer) and consumer (stack writer):
> New function(s) to support, probably more tests to create/run, etc.
> Though this API is optional - if PMD/stack maintainer doesn't see
> value in it, they are free not to support it.
> From other side, re-using rte_cryptodev_sym_session_init()
> wouldn't help anyway - both data-path and control-path would differ
> from async mode anyway.
> BTW, right now to support different HW flavors
> we do have 4 different control and data-paths for both
> ipsec-secgw and librte_ipsec:
> lkds-none/lksd-proto/inline-crypto/inline-proto.
> And that is considered to be ok.
> Honestly, I don't understand why SW backed implementations
> can't have their own path that would suite them most.
> Konstantin
>
>
>
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-22 13:31 4% ` Akhil Goyal
@ 2019-10-22 17:44 0% ` Ananyev, Konstantin
2019-10-22 22:21 0% ` Ananyev, Konstantin
2019-10-23 10:05 0% ` Akhil Goyal
0 siblings, 2 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-22 17:44 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', Hemant Agrawal
Hi Akhil,
> > > Added my comments inline with your draft.
> > > [snip]..
> > >
> > > >
> > > > Ok, then my suggestion:
> > > > Let's at least write down all points about crypto-dev approach where we
> > > > disagree and then probably try to resolve them one by one....
> > > > If we fail to make an agreement/progress in next week or so,
> > > > (and no more reviews from the community)
> > > > will have bring that subject to TB meeting to decide.
> > > > Sounds fair to you?
> > > Agreed
> > > >
> > > > List is below.
> > > > Please add/correct me, if I missed something.
> > > >
> > > > Konstantin
> > >
> > > Before going into comparison, we should define the requirement as well.
> >
> > Good point.
> >
> > > What I understood from the patchset,
> > > "You need a synchronous API to perform crypto operations on raw data using
> > SW PMDs"
> > > So,
> > > - no crypto-ops,
> > > - no separate enq-deq, only single process API for data path
> > > - Do not need any value addition to the session parameters.
> > > (You would need some parameters from the crypto-op which
> > > Are constant per session and since you wont use crypto-op,
> > > You need some place to store that)
> >
> > Yes, this is correct, I think.
> >
> > >
> > > Now as per your mail, the comparison
> > > 1. extra input parameters to create/init rte_(cpu)_sym_session.
> > >
> > > Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and
> > 'key' fields.
> > > New fields will be optional and would be used by PMD only when cpu-crypto
> > session is requested.
> > > For lksd-crypto session PMD is free to ignore these fields.
> > > No ABI breakage is required.
> > >
> > > [Akhil] Agreed, no issues.
> > >
> > > 2. cpu-crypto create/init.
> > > a) Our suggestion - introduce new API for that:
> > > - rte_crypto_cpu_sym_init() that would init completely opaque
> > rte_crypto_cpu_sym_session.
> > > - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear);
> > /*whatever else we'll need *'};
> > > - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform
> > *xforms)
> > > that would return const struct rte_crypto_cpu_sym_session_ops *based
> > on input xforms.
> > > Advantages:
> > > 1) totally opaque data structure (no ABI breakages in future), PMD
> > writer is totally free
> > > with it format and contents.
> > >
> > > [Akhil] It will have breakage at some point till we don't hit the union size.
> >
> > Not sure, what union you are talking about?
>
> Union of xforms in rte_security_session_conf
Hmm, how does it relates here?
I thought we discussing pure rte_cryptodev_sym_session, no?
>
> >
> > > Rather I don't suspect there will be more parameters added.
> > > Or do we really care about the ABI breakage when the argument is about
> > > the correct place to add a piece of code or do we really agree to add code
> > > anywhere just to avoid that breakage.
> >
> > I am talking about maintaining it in future.
> > if your struct is not seen externally, no chances to introduce ABI breakage.
> >
> > >
> > > 2) each session entity is self-contained, user doesn't need to bring along
> > dev_id etc.
> > > dev_id is needed only at init stage, after that user will use session ops
> > to perform
> > > all operations on that session (process(), clear(), etc.).
> > >
> > > [Akhil] There is nothing called as session ops in current DPDK.
> >
> > True, but it doesn't mean we can't/shouldn't have it.
>
> We can have it if it is not adding complexity for the user. Creating 2 different code
> Paths for user is not desirable for the stack developers.
>
> >
> > > What you are proposing
> > > is a new concept which doesn't have any extra benefit, rather it is adding
> > complexity
> > > to have two different code paths for session create.
> > >
> > >
> > > 3) User can decide does he wants to store ops[] pointer on a per session
> > basis,
> > > or on a per group of same sessions, or...
> > >
> > > [Akhil] Will the user really care which process API should be called from the
> > PMD.
> > > Rather it should be driver's responsibility to store that in the session private
> > data
> > > which would be opaque to the user. As per my suggestion same process
> > function can
> > > be added to multiple sessions or a single session can be managed inside the
> > PMD.
> >
> > In that case we either need to have a function per session (stored internally),
> > or make decision (branches) at run-time.
> > But as I said in other mail - I am ok to add small shim structure here:
> > either rte_crypto_cpu_sym_session { void *ses; struct
> > rte_crypto_cpu_sym_session_ops ops; }
> > or rte_crypto_cpu_sym_session { void *ses; struct
> > rte_crypto_cpu_sym_session_ops *ops; }
> > And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops() into
> > one (init).
>
> Again that will be a separate API call from the user perspective which is not good.
>
> >
> > >
> > >
> > > 4) No mandatory mempools for private sessions. User can allocate
> > memory for cpu-crypto
> > > session whenever he likes.
> > >
> > > [Akhil] you mean session private data?
> >
> > Yes.
> >
> > > You would need that memory anyways, user will be
> > > allocating that already. You do not need to manage that.
> >
> > What I am saying - right now user has no choice but to allocate it via mempool.
> > Which is probably not the best options for all cases.
> >
> > >
> > > Disadvantages:
> > > 5) Extra changes in control path
> > > 6) User has to store session_ops pointer explicitly.
> > >
> > > [Akhil] More disadvantages:
> > > - All supporting PMDs will need to maintain TWO types of session for the
> > > same crypto processing. Suppose a fix or a new feature(or algo) is added, PMD
> > owner
> > > will need to add code in both the session create APIs. Hence more
> > maintenance and
> > > error prone.
> >
> > I think majority of code for both paths will be common, plus even we'll reuse
> > current sym_session_init() -
> > changes in PMD session_init() code will be unavoidable.
> > But yes, it will be new entry in devops, that PMD will have to support.
> > Ok to add it as 7) to the list.
> >
> > > - Stacks which will be using these new APIs also need to maintain two
> > > code path for the same processing while doing session initialization
> > > for sync and async
> >
> > That's the same as #5 above, I think.
> >
> > >
> > >
> > > b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and
> > existing rte_cryptodev_sym_session
> > > structure.
> > > Advantages:
> > > 1) allows to reuse same struct and init/create/clear() functions.
> > > Probably less changes in control path.
> > > Disadvantages:
> > > 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id,
> > which means that
> > > we can't use the same rte_cryptodev_sym_session to hold private
> > sessions pointers
> > > for both sync and async mode for the same device.
> > > So the only option we have - make PMD devops-
> > >sym_session_configure()
> > > always create a session that can work in both cpu and lksd modes.
> > > For some implementations that would probably mean that under the
> > hood PMD would create
> > > 2 different session structs (sync/async) and then use one or another
> > depending on from what API been called.
> > > Seems doable, but ...:
> > > - will contradict with statement from 1:
> > > " New fields will be optional and would be used by PMD only when
> > cpu-crypto session is requested."
> > > Now it becomes mandatory for all apps to specify cpu-crypto
> > related parameters too,
> > > even if they don't plan to use that mode - i.e. behavior change,
> > existing app change.
> > > - might cause extra space overhead.
> > >
> > > [Akhil] It will not contradict with #1, you will only have few checks in the
> > session init PMD
> > > Which support this mode, find appropriate values and set the appropriate
> > process() in it.
> > > User should be able to call, legacy enq-deq as well as the new process()
> > without any issue.
> > > User would be at runtime will be able to change the datapath.
> > > So this is not a disadvantage, it would be additional flexibility for the user.
> >
> > Ok, but that's what I am saying - if PMD would *always* have to create a
> > session that can handle
> > both modes (sync/async), then user would *always* have to provide parameters
> > for both modes too.
> > Otherwise if let say user didn't setup sync specific parameters at all, what PMD
> > should do?
> > - return with error?
> > - init session that can be used with async path only?
> > My current assumption is #1.
> > If #2, then how user will be able to distinguish is that session valid for both
> > modes, or only for one?
>
> I would say a 3rd option, do nothing if sync params are not set.
> Probably have a debug print in the PMD(which support sync mode) to specify that
> session is not configured properly for sync mode.
So, just print warning and proceed with init session that can be used with async path only?
Then it sounds the same as #2 above.
Which actually means that sync mode parameters for sym_session_init() becomes optional.
Then we need an API to provide to the user information what modes
(sync+async/async only) is supported by that session for given dev_id.
And user would have to query/retain this information at control-path,
and store it somewhere in user-space together with session pointer and dev_ids
to use later at data-path (same as we do now for session type).
That definitely requires changes in control-path to start using it.
Plus the fact that this value can differ for different dev_ids for the same session -
doesn't make things easier here.
> Internally the PMD will not store the process() API in the session priv data
> And while calling the first packet, devops->process will give an assert that session
> Is not configured for sync mode. The session validation would be done in any case
> your suggestion or mine. So no extra overhead at runtime.
I believe that after session_init() user should get either an error or
valid session handler that he can use at runtime.
Pushing session validation to runtime doesn't seem like a good idea.
>
> >
> >
> > >
> > >
> > > 3) not possible to store device (not driver) specific data within the
> > session, but I think it is not really needed right now.
> > > So probably minor compared to 2.b.2.
> > >
> > > [Akhil] So lets omit this for current discussion. And I hope we can find some
> > way to deal with it.
> >
> > I don't think there is an easy way to fix that with existing API.
> >
> > >
> > >
> > > Actually #3 follows from #2, but decided to have them separated.
> > >
> > > 3. process() parameters/behavior
> > > a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and
> > just does:
> > > session_ops->process(sess, ...);
> > > Advantages:
> > > 1) fastest possible execution path
> > > 2) no need to carry on dev_id for data-path
> > >
> > > [Akhil] I don't see any overhead of carrying dev id, at least it would be inline
> > with the
> > > current DPDK methodology.
> >
> > If we'll add process() into rte_cryptodev itself (same as we have
> > enqueue_burst/dequeue_burst),
> > then it will be an ABI breakage.
> > Also there are discussions to get rid of that approach completely:
> > http://mails.dpdk.org/archives/dev/2019-September/144674.html
> > So I am not sure this is a recommended way these days.
>
> We can either have it in rte_cryptodev or in rte_cryptodev_ops whichever
> is good for you.
>
> Whether it is ABI breakage or not, as per your requirements, this is the correct
> approach. Do you agree with this or not?
I think it is possible approach, but not the best one:
it looks quite flakey to me (see all these uncertainty with sym_session_init above),
plus introduces extra overhead at data-path.
>
> Now handling the API/ABI breakage is a separate story. In 19.11 release we
> Are not much concerned about the ABI breakages, this was discussed in
> community. So adding a new dev_ops wouldn't have been an issue.
> Now since we are so close to RC1 deadline, we should come up with some
> other solution for next release. May be having a pmd API in 20.02 and
> converting it into formal one in 20.11
>
>
> >
> > > What you are suggesting is a new way to get the things done without much
> > benefit.
> >
> > Would help with ABI stability plus better performance, isn't it enough?
> >
> > > Also I don't see any performance difference as crypto workload is heavier than
> > > Code cycles, so that wont matter.
> >
> > It depends.
> > Suppose function call costs you ~30 cycles.
> > If you have burst of big packets (let say crypto for each will take ~2K cycles) that
> > belong
> > to the same session, then yes you wouldn't notice these extra 30 cycles at all.
> > If you have burst of small packets (let say crypto for each will take ~300 cycles)
> > each
> > belongs to different session, then it will cost you ~10% extra.
>
> Let us do some profiling on openssl with both the approaches and find out the
> difference.
>
> >
> > > So IMO, there is no advantage in your suggestion as well.
> > >
> > >
> > > Disadvantages:
> > > 3) user has to carry on session_ops pointer explicitly
> > > b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
> > > rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session
> > *sess, /*data parameters*/) {...
> > > rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> > > /*and then inside PMD specifc process: */
> > > pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
> > > /* and then most likely either */
> > > pmd_private_session->process(pmd_private_session, ...);
> > > /* or jump based on session/input data */
> > > Advantages:
> > > 1) don't see any...
> > > Disadvantages:
> > > 2) User has to carry on dev_id inside data-path
> > > 3) Extra level of indirection (plus data dependency) - both for data and
> > instructions.
> > > Possible slowdown compared to a) (not measured).
> > >
> > > Having said all this, if the disagreements cannot be resolved, you can go for a
> > pmd API specific
> > > to your PMDs,
> >
> > I don't think it is good idea.
> > PMD specific API is sort of deprecated path, also there is no clean way to use it
> > within the libraries.
>
> I know that this is a deprecated path, we can use it until we are not allowed
> to break ABI/API
>
> >
> > > because as per my understanding the solution doesn't look scalable to other
> > PMDs.
> > > Your approach is aligned only to Intel , will not benefit others like openssl
> > which is used by all
> > > vendors.
> >
> > I feel quite opposite, from my perspective majority of SW backed PMDs will
> > benefit from it.
> > And I don't see anything Intel specific in my proposals above.
> > About openssl PMD: I am not an expert here, but looking at the code, I think it
> > will fit really well.
> > Look yourself at its internal functions:
> > process_openssl_auth_op/process_openssl_crypto_op,
> > I think they doing exactly the same - they use sync API underneath, and they are
> > session based
> > (AFAIK you don't need any device/queue data, everything that needed for
> > crypto/auth is stored inside session).
> >
> By vendor specific, I mean,
> - no PMD would like to have 2 different variants of session Init APIs for doing the same stuff.
> - stacks will become vendor specific while using 2 separate session create APIs. No stack would
> Like to support 2 variants of session create- one for HW PMDs and one for SW PMDs.
I think what you refer on has nothing to do with 'vendor specific'.
I would name it 'extra overhead for PMD and stack writers'.
Yes, for sure there is extra overhead (as always with new API) -
for both producer (PMD writer) and consumer (stack writer):
New function(s) to support, probably more tests to create/run, etc.
Though this API is optional - if PMD/stack maintainer doesn't see
value in it, they are free not to support it.
From other side, re-using rte_cryptodev_sym_session_init()
wouldn't help anyway - both data-path and control-path would differ
from async mode anyway.
BTW, right now to support different HW flavors
we do have 4 different control and data-paths for both
ipsec-secgw and librte_ipsec:
lkds-none/lksd-proto/inline-crypto/inline-proto.
And that is considered to be ok.
Honestly, I don't understand why SW backed implementations
can't have their own path that would suite them most.
Konstantin
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8] eal: make lcore_config private
2019-10-22 16:30 0% ` Stephen Hemminger
@ 2019-10-22 16:49 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-22 16:49 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Tue, Oct 22, 2019 at 6:30 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Tue, 22 Oct 2019 11:05:01 +0200
> David Marchand <david.marchand@redhat.com> wrote:
>
> > On Wed, Oct 2, 2019 at 9:40 PM Stephen Hemminger
> > <stephen@networkplumber.org> wrote:
> > > +struct lcore_config {
> > > + pthread_t thread_id; /**< pthread identifier */
> > > + int pipe_master2slave[2]; /**< communication pipe with master */
> > > + int pipe_slave2master[2]; /**< communication pipe with master */
> > > +
> > > + lcore_function_t * volatile f; /**< function to call */
> > > + void * volatile arg; /**< argument of function */
> > > + volatile int ret; /**< return value of function */
> > > +
> > > + uint32_t core_id; /**< core number on socket for this lcore */
> > > + uint32_t core_index; /**< relative index, starting from 0 */
> > > + uint16_t socket_id; /**< physical socket id for this lcore */
> > > + uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
> > > + uint8_t detected; /**< true if lcore was detected */
> > > + volatile enum rte_lcore_state_t state; /**< lcore state */
> > > + rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
> > > +};
> >
> > There are still changes on the core_id, core_index, socket_id that I
> > am not confortable with (at this point).
> >
> > I prepared a series for -rc1 on ABI changes in EAL (that I will send shortly).
> > I took your patch without the changes on core_id, core_index and socket_id.
>
>
> Why, please be more precise.
>
I commented earlier that there were integer conversion with the fields
you changed.
core_id is ok, and a uint32_t would be fine, but this does not change the size.
socket_id needs investigation, but should be safe.
I am nervous about core_index, because it is used as a signed integer.
It looks too dangerous to blindly accept this change with the only
reason of saving space.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 8/8] log: hide internal log structure
2019-10-22 9:32 3% ` [dpdk-dev] [PATCH 8/8] log: hide internal log structure David Marchand
@ 2019-10-22 16:35 0% ` Stephen Hemminger
2019-10-23 13:02 0% ` David Marchand
1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-22 16:35 UTC (permalink / raw)
To: David Marchand; +Cc: dev, anatoly.burakov, thomas
On Tue, 22 Oct 2019 11:32:41 +0200
David Marchand <david.marchand@redhat.com> wrote:
> No need to expose rte_logs, hide it and remove it from the current ABI.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> lib/librte_eal/common/eal_common_log.c | 23 ++++++++++++++++-------
> lib/librte_eal/common/include/rte_log.h | 20 +++-----------------
> lib/librte_eal/rte_eal_version.map | 1 -
> 3 files changed, 19 insertions(+), 25 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
> index cfe9599..3a7ab88 100644
> --- a/lib/librte_eal/common/eal_common_log.c
> +++ b/lib/librte_eal/common/eal_common_log.c
> @@ -17,13 +17,6 @@
>
> #include "eal_private.h"
>
> -/* global log structure */
> -struct rte_logs rte_logs = {
> - .type = ~0,
> - .level = RTE_LOG_DEBUG,
> - .file = NULL,
> -};
> -
> struct rte_eal_opt_loglevel {
> /** Next list entry */
> TAILQ_ENTRY(rte_eal_opt_loglevel) next;
> @@ -58,6 +51,22 @@ struct rte_log_dynamic_type {
> uint32_t loglevel;
> };
>
> +/** The rte_log structure. */
> +struct rte_logs {
> + uint32_t type; /**< Bitfield with enabled logs. */
> + uint32_t level; /**< Log level. */
> + FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */
> + size_t dynamic_types_len;
> + struct rte_log_dynamic_type *dynamic_types;
> +};
> +
> +/* global log structure */
> +static struct rte_logs rte_logs = {
> + .type = ~0,
> + .level = RTE_LOG_DEBUG,
> + .file = NULL,
> +};
> +
> /* per core log */
> static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
>
> diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
> index 1bb0e66..a8d0eb7 100644
> --- a/lib/librte_eal/common/include/rte_log.h
> +++ b/lib/librte_eal/common/include/rte_log.h
> @@ -26,20 +26,6 @@ extern "C" {
> #include <rte_config.h>
> #include <rte_compat.h>
>
> -struct rte_log_dynamic_type;
> -
> -/** The rte_log structure. */
> -struct rte_logs {
> - uint32_t type; /**< Bitfield with enabled logs. */
> - uint32_t level; /**< Log level. */
> - FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */
> - size_t dynamic_types_len;
> - struct rte_log_dynamic_type *dynamic_types;
> -};
> -
> -/** Global log information */
> -extern struct rte_logs rte_logs;
> -
> /* SDK log type */
> #define RTE_LOGTYPE_EAL 0 /**< Log related to eal. */
> #define RTE_LOGTYPE_MALLOC 1 /**< Log related to malloc. */
> @@ -260,7 +246,7 @@ void rte_log_dump(FILE *f);
> * to rte_openlog_stream().
> *
> * The level argument determines if the log should be displayed or
> - * not, depending on the global rte_logs variable.
> + * not, depending on the global log level and the per logtype level.
> *
> * The preferred alternative is the RTE_LOG() because it adds the
> * level and type in the logged string.
> @@ -291,8 +277,8 @@ int rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
> * to rte_openlog_stream().
> *
> * The level argument determines if the log should be displayed or
> - * not, depending on the global rte_logs variable. A trailing
> - * newline may be added if needed.
> + * not, depending on the global log level and the per logtype level.
> + * A trailing newline may be added if needed.
> *
> * The preferred alternative is the RTE_LOG() because it adds the
> * level and type in the logged string.
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index 6d7e0e4..ca9ace0 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -45,7 +45,6 @@ DPDK_2.0 {
> rte_log;
> rte_log_cur_msg_loglevel;
> rte_log_cur_msg_logtype;
> - rte_logs;
> rte_malloc;
> rte_malloc_dump_stats;
> rte_malloc_get_socket_stats;
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8] eal: make lcore_config private
2019-10-22 9:05 3% ` David Marchand
@ 2019-10-22 16:30 0% ` Stephen Hemminger
2019-10-22 16:49 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-10-22 16:30 UTC (permalink / raw)
To: David Marchand; +Cc: dev
On Tue, 22 Oct 2019 11:05:01 +0200
David Marchand <david.marchand@redhat.com> wrote:
> On Wed, Oct 2, 2019 at 9:40 PM Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> > +struct lcore_config {
> > + pthread_t thread_id; /**< pthread identifier */
> > + int pipe_master2slave[2]; /**< communication pipe with master */
> > + int pipe_slave2master[2]; /**< communication pipe with master */
> > +
> > + lcore_function_t * volatile f; /**< function to call */
> > + void * volatile arg; /**< argument of function */
> > + volatile int ret; /**< return value of function */
> > +
> > + uint32_t core_id; /**< core number on socket for this lcore */
> > + uint32_t core_index; /**< relative index, starting from 0 */
> > + uint16_t socket_id; /**< physical socket id for this lcore */
> > + uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
> > + uint8_t detected; /**< true if lcore was detected */
> > + volatile enum rte_lcore_state_t state; /**< lcore state */
> > + rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
> > +};
>
> There are still changes on the core_id, core_index, socket_id that I
> am not confortable with (at this point).
>
> I prepared a series for -rc1 on ABI changes in EAL (that I will send shortly).
> I took your patch without the changes on core_id, core_index and socket_id.
Why, please be more precise.
Do you expect to support more than 32 bit worth of cores?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-21 13:47 4% ` Ananyev, Konstantin
@ 2019-10-22 13:31 4% ` Akhil Goyal
2019-10-22 17:44 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-10-22 13:31 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', Hemant Agrawal
Hi Konstantin,
>
>
> Hi Akhil,
>
>
> > Added my comments inline with your draft.
> > [snip]..
> >
> > >
> > > Ok, then my suggestion:
> > > Let's at least write down all points about crypto-dev approach where we
> > > disagree and then probably try to resolve them one by one....
> > > If we fail to make an agreement/progress in next week or so,
> > > (and no more reviews from the community)
> > > will have bring that subject to TB meeting to decide.
> > > Sounds fair to you?
> > Agreed
> > >
> > > List is below.
> > > Please add/correct me, if I missed something.
> > >
> > > Konstantin
> >
> > Before going into comparison, we should define the requirement as well.
>
> Good point.
>
> > What I understood from the patchset,
> > "You need a synchronous API to perform crypto operations on raw data using
> SW PMDs"
> > So,
> > - no crypto-ops,
> > - no separate enq-deq, only single process API for data path
> > - Do not need any value addition to the session parameters.
> > (You would need some parameters from the crypto-op which
> > Are constant per session and since you wont use crypto-op,
> > You need some place to store that)
>
> Yes, this is correct, I think.
>
> >
> > Now as per your mail, the comparison
> > 1. extra input parameters to create/init rte_(cpu)_sym_session.
> >
> > Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and
> 'key' fields.
> > New fields will be optional and would be used by PMD only when cpu-crypto
> session is requested.
> > For lksd-crypto session PMD is free to ignore these fields.
> > No ABI breakage is required.
> >
> > [Akhil] Agreed, no issues.
> >
> > 2. cpu-crypto create/init.
> > a) Our suggestion - introduce new API for that:
> > - rte_crypto_cpu_sym_init() that would init completely opaque
> rte_crypto_cpu_sym_session.
> > - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear);
> /*whatever else we'll need *'};
> > - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform
> *xforms)
> > that would return const struct rte_crypto_cpu_sym_session_ops *based
> on input xforms.
> > Advantages:
> > 1) totally opaque data structure (no ABI breakages in future), PMD
> writer is totally free
> > with it format and contents.
> >
> > [Akhil] It will have breakage at some point till we don't hit the union size.
>
> Not sure, what union you are talking about?
Union of xforms in rte_security_session_conf
>
> > Rather I don't suspect there will be more parameters added.
> > Or do we really care about the ABI breakage when the argument is about
> > the correct place to add a piece of code or do we really agree to add code
> > anywhere just to avoid that breakage.
>
> I am talking about maintaining it in future.
> if your struct is not seen externally, no chances to introduce ABI breakage.
>
> >
> > 2) each session entity is self-contained, user doesn't need to bring along
> dev_id etc.
> > dev_id is needed only at init stage, after that user will use session ops
> to perform
> > all operations on that session (process(), clear(), etc.).
> >
> > [Akhil] There is nothing called as session ops in current DPDK.
>
> True, but it doesn't mean we can't/shouldn't have it.
We can have it if it is not adding complexity for the user. Creating 2 different code
Paths for user is not desirable for the stack developers.
>
> > What you are proposing
> > is a new concept which doesn't have any extra benefit, rather it is adding
> complexity
> > to have two different code paths for session create.
> >
> >
> > 3) User can decide does he wants to store ops[] pointer on a per session
> basis,
> > or on a per group of same sessions, or...
> >
> > [Akhil] Will the user really care which process API should be called from the
> PMD.
> > Rather it should be driver's responsibility to store that in the session private
> data
> > which would be opaque to the user. As per my suggestion same process
> function can
> > be added to multiple sessions or a single session can be managed inside the
> PMD.
>
> In that case we either need to have a function per session (stored internally),
> or make decision (branches) at run-time.
> But as I said in other mail - I am ok to add small shim structure here:
> either rte_crypto_cpu_sym_session { void *ses; struct
> rte_crypto_cpu_sym_session_ops ops; }
> or rte_crypto_cpu_sym_session { void *ses; struct
> rte_crypto_cpu_sym_session_ops *ops; }
> And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops() into
> one (init).
Again that will be a separate API call from the user perspective which is not good.
>
> >
> >
> > 4) No mandatory mempools for private sessions. User can allocate
> memory for cpu-crypto
> > session whenever he likes.
> >
> > [Akhil] you mean session private data?
>
> Yes.
>
> > You would need that memory anyways, user will be
> > allocating that already. You do not need to manage that.
>
> What I am saying - right now user has no choice but to allocate it via mempool.
> Which is probably not the best options for all cases.
>
> >
> > Disadvantages:
> > 5) Extra changes in control path
> > 6) User has to store session_ops pointer explicitly.
> >
> > [Akhil] More disadvantages:
> > - All supporting PMDs will need to maintain TWO types of session for the
> > same crypto processing. Suppose a fix or a new feature(or algo) is added, PMD
> owner
> > will need to add code in both the session create APIs. Hence more
> maintenance and
> > error prone.
>
> I think majority of code for both paths will be common, plus even we'll reuse
> current sym_session_init() -
> changes in PMD session_init() code will be unavoidable.
> But yes, it will be new entry in devops, that PMD will have to support.
> Ok to add it as 7) to the list.
>
> > - Stacks which will be using these new APIs also need to maintain two
> > code path for the same processing while doing session initialization
> > for sync and async
>
> That's the same as #5 above, I think.
>
> >
> >
> > b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and
> existing rte_cryptodev_sym_session
> > structure.
> > Advantages:
> > 1) allows to reuse same struct and init/create/clear() functions.
> > Probably less changes in control path.
> > Disadvantages:
> > 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id,
> which means that
> > we can't use the same rte_cryptodev_sym_session to hold private
> sessions pointers
> > for both sync and async mode for the same device.
> > So the only option we have - make PMD devops-
> >sym_session_configure()
> > always create a session that can work in both cpu and lksd modes.
> > For some implementations that would probably mean that under the
> hood PMD would create
> > 2 different session structs (sync/async) and then use one or another
> depending on from what API been called.
> > Seems doable, but ...:
> > - will contradict with statement from 1:
> > " New fields will be optional and would be used by PMD only when
> cpu-crypto session is requested."
> > Now it becomes mandatory for all apps to specify cpu-crypto
> related parameters too,
> > even if they don't plan to use that mode - i.e. behavior change,
> existing app change.
> > - might cause extra space overhead.
> >
> > [Akhil] It will not contradict with #1, you will only have few checks in the
> session init PMD
> > Which support this mode, find appropriate values and set the appropriate
> process() in it.
> > User should be able to call, legacy enq-deq as well as the new process()
> without any issue.
> > User would be at runtime will be able to change the datapath.
> > So this is not a disadvantage, it would be additional flexibility for the user.
>
> Ok, but that's what I am saying - if PMD would *always* have to create a
> session that can handle
> both modes (sync/async), then user would *always* have to provide parameters
> for both modes too.
> Otherwise if let say user didn't setup sync specific parameters at all, what PMD
> should do?
> - return with error?
> - init session that can be used with async path only?
> My current assumption is #1.
> If #2, then how user will be able to distinguish is that session valid for both
> modes, or only for one?
I would say a 3rd option, do nothing if sync params are not set.
Probably have a debug print in the PMD(which support sync mode) to specify that
session is not configured properly for sync mode.
Internally the PMD will not store the process() API in the session priv data
And while calling the first packet, devops->process will give an assert that session
Is not configured for sync mode. The session validation would be done in any case
your suggestion or mine. So no extra overhead at runtime.
>
>
> >
> >
> > 3) not possible to store device (not driver) specific data within the
> session, but I think it is not really needed right now.
> > So probably minor compared to 2.b.2.
> >
> > [Akhil] So lets omit this for current discussion. And I hope we can find some
> way to deal with it.
>
> I don't think there is an easy way to fix that with existing API.
>
> >
> >
> > Actually #3 follows from #2, but decided to have them separated.
> >
> > 3. process() parameters/behavior
> > a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and
> just does:
> > session_ops->process(sess, ...);
> > Advantages:
> > 1) fastest possible execution path
> > 2) no need to carry on dev_id for data-path
> >
> > [Akhil] I don't see any overhead of carrying dev id, at least it would be inline
> with the
> > current DPDK methodology.
>
> If we'll add process() into rte_cryptodev itself (same as we have
> enqueue_burst/dequeue_burst),
> then it will be an ABI breakage.
> Also there are discussions to get rid of that approach completely:
> http://mails.dpdk.org/archives/dev/2019-September/144674.html
> So I am not sure this is a recommended way these days.
We can either have it in rte_cryptodev or in rte_cryptodev_ops whichever
is good for you.
Whether it is ABI breakage or not, as per your requirements, this is the correct
approach. Do you agree with this or not?
Now handling the API/ABI breakage is a separate story. In 19.11 release we
Are not much concerned about the ABI breakages, this was discussed in
community. So adding a new dev_ops wouldn't have been an issue.
Now since we are so close to RC1 deadline, we should come up with some
other solution for next release. May be having a pmd API in 20.02 and
converting it into formal one in 20.11
>
> > What you are suggesting is a new way to get the things done without much
> benefit.
>
> Would help with ABI stability plus better performance, isn't it enough?
>
> > Also I don't see any performance difference as crypto workload is heavier than
> > Code cycles, so that wont matter.
>
> It depends.
> Suppose function call costs you ~30 cycles.
> If you have burst of big packets (let say crypto for each will take ~2K cycles) that
> belong
> to the same session, then yes you wouldn't notice these extra 30 cycles at all.
> If you have burst of small packets (let say crypto for each will take ~300 cycles)
> each
> belongs to different session, then it will cost you ~10% extra.
Let us do some profiling on openssl with both the approaches and find out the
difference.
>
> > So IMO, there is no advantage in your suggestion as well.
> >
> >
> > Disadvantages:
> > 3) user has to carry on session_ops pointer explicitly
> > b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
> > rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session
> *sess, /*data parameters*/) {...
> > rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> > /*and then inside PMD specifc process: */
> > pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
> > /* and then most likely either */
> > pmd_private_session->process(pmd_private_session, ...);
> > /* or jump based on session/input data */
> > Advantages:
> > 1) don't see any...
> > Disadvantages:
> > 2) User has to carry on dev_id inside data-path
> > 3) Extra level of indirection (plus data dependency) - both for data and
> instructions.
> > Possible slowdown compared to a) (not measured).
> >
> > Having said all this, if the disagreements cannot be resolved, you can go for a
> pmd API specific
> > to your PMDs,
>
> I don't think it is good idea.
> PMD specific API is sort of deprecated path, also there is no clean way to use it
> within the libraries.
I know that this is a deprecated path, we can use it until we are not allowed
to break ABI/API
>
> > because as per my understanding the solution doesn't look scalable to other
> PMDs.
> > Your approach is aligned only to Intel , will not benefit others like openssl
> which is used by all
> > vendors.
>
> I feel quite opposite, from my perspective majority of SW backed PMDs will
> benefit from it.
> And I don't see anything Intel specific in my proposals above.
> About openssl PMD: I am not an expert here, but looking at the code, I think it
> will fit really well.
> Look yourself at its internal functions:
> process_openssl_auth_op/process_openssl_crypto_op,
> I think they doing exactly the same - they use sync API underneath, and they are
> session based
> (AFAIK you don't need any device/queue data, everything that needed for
> crypto/auth is stored inside session).
>
By vendor specific, I mean,
- no PMD would like to have 2 different variants of session Init APIs for doing the same stuff.
- stacks will become vendor specific while using 2 separate session create APIs. No stack would
Like to support 2 variants of session create- one for HW PMDs and one for SW PMDs.
-Akhil
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC] ethdev: add new fields for max LRO session size
2019-10-18 16:35 0% ` Ferruh Yigit
2019-10-18 18:05 0% ` Ananyev, Konstantin
@ 2019-10-22 12:56 0% ` Andrew Rybchenko
1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2019-10-22 12:56 UTC (permalink / raw)
To: Ferruh Yigit, Thomas Monjalon, Matan Azrad
Cc: dev, Konstantin Ananyev, Olivier Matz
On 10/18/19 7:35 PM, Ferruh Yigit wrote:
> On 10/2/2019 2:58 PM, Thomas Monjalon wrote:
>> 24/09/2019 14:03, Matan Azrad:
>>> From: Ferruh Yigit
>>>> On 9/15/2019 8:48 AM, Matan Azrad wrote:
>>>>> Hi Ferruh
>>>>>
>>>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
>>>>>> On 8/29/2019 8:47 AM, Matan Azrad wrote:
>>>>>>> It may be needed by the user to limit the LRO session packet size.
>>>>>>> In order to allow the above limitation, add new Rx configuration for
>>>>>>> the maximum LRO session size.
>>>>>>>
>>>>>>> In addition, Add a new capability to expose the maximum LRO session
>>>>>>> size supported by the port.
>>>>>>>
>>>>>>> Signed-off-by: Matan Azrad <matan@mellanox.com>
>>>>>> Hi Matan,
>>>>>>
>>>>>> Is there any existing user of this new field?
>>>>> All the LRO users need it due to the next reasons:
>>>>>
>>>>> 1. If scatter is enabled - The dpdk user can limit the LRO session size created
>>>> by the HW by this field, if no field like that - there is no way to limit it.
>>>>> 2. No scatter - the dpdk user may want to limit the LRO packet size in order
>>>> to save enough tail-room in the mbuf for its own usage.
>>>>> 3. The limitation of max_rx_pkt_len is not enough - doesn't make sense to
>>>> limit LRO traffic as single packet.
>>>> So should there be more complement patches to this RFC? To update the
>>>> users of the field with the new field.
>>>
>>> We already exposed it as ABI breakage in the last deprecation notice.
>>> We probably cannot complete it for 19.11 version, hopefully for 20.02 it will be completed.
>> We won't break the ABI in 20.02.
>> What should be done in 19.11?
>>
> The ask was to add code that uses new added fields, this patch only adds new
> field to two public ethdev struct.
>
> @Thomas, @Andrew, if this patch doesn't goes it on this release it will have to
> wait a year. I would like to see the implementation but it is not there, what is
> your comment?
I don't mind to accept it in 19.11 modulo better description of
what is LRO session length/size.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 6/8] pci: remove deprecated functions
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
` (2 preceding siblings ...)
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 3/8] eal: remove deprecated malloc virt2phys function David Marchand
@ 2019-10-22 9:32 4% ` David Marchand
2019-10-22 9:32 3% ` [dpdk-dev] [PATCH 8/8] log: hide internal log structure David Marchand
4 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev
Cc: stephen, anatoly.burakov, thomas, Neil Horman, John McNamara,
Marko Kovacevic, Gaetan Rivet
Those functions have been deprecated since 17.11 and have 1:1
replacement.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
doc/guides/rel_notes/deprecation.rst | 7 -----
doc/guides/rel_notes/release_19_11.rst | 6 +++++
lib/librte_pci/rte_pci.c | 19 --------------
lib/librte_pci/rte_pci.h | 47 ----------------------------------
lib/librte_pci/rte_pci_version.map | 3 ---
5 files changed, 6 insertions(+), 76 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index bbd5863..cf7744e 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -38,13 +38,6 @@ Deprecation Notices
have been replaced with ``rte_dev_dma_map`` and ``rte_dev_dma_unmap``
functions. The due date for the removal targets DPDK 20.02.
-* pci: Several exposed functions are misnamed.
- The following functions are deprecated starting from v17.11 and are replaced:
-
- - ``eal_parse_pci_BDF`` replaced by ``rte_pci_addr_parse``
- - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_addr_parse``
- - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
-
* dpaa2: removal of ``rte_dpaa2_memsegs`` structure which has been replaced
by a pa-va search library. This structure was earlier being used for holding
memory segments used by dpaa2 driver for faster pa->va translation. This
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 0c61c1c..579311d 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -210,6 +210,12 @@ ABI Changes
* eal: removed the ``rte_malloc_virt2phy`` function, replaced by
``rte_malloc_virt2iova`` since v17.11.
+* pci: removed the following deprecated functions since dpdk:
+
+ - ``eal_parse_pci_BDF`` replaced by ``rte_pci_addr_parse``
+ - ``eal_parse_pci_DomBDF`` replaced by ``rte_pci_addr_parse``
+ - ``rte_eal_compare_pci_addr`` replaced by ``rte_pci_addr_cmp``
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_pci/rte_pci.c b/lib/librte_pci/rte_pci.c
index f400178..a753cf3 100644
--- a/lib/librte_pci/rte_pci.c
+++ b/lib/librte_pci/rte_pci.c
@@ -87,18 +87,6 @@ pci_dbdf_parse(const char *input, struct rte_pci_addr *dev_addr)
return 0;
}
-int
-eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr)
-{
- return pci_bdf_parse(input, dev_addr);
-}
-
-int
-eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr)
-{
- return pci_dbdf_parse(input, dev_addr);
-}
-
void
rte_pci_device_name(const struct rte_pci_addr *addr,
char *output, size_t size)
@@ -110,13 +98,6 @@ rte_pci_device_name(const struct rte_pci_addr *addr,
}
int
-rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
- const struct rte_pci_addr *addr2)
-{
- return rte_pci_addr_cmp(addr, addr2);
-}
-
-int
rte_pci_addr_cmp(const struct rte_pci_addr *addr,
const struct rte_pci_addr *addr2)
{
diff --git a/lib/librte_pci/rte_pci.h b/lib/librte_pci/rte_pci.h
index eaa9d07..c878914 100644
--- a/lib/librte_pci/rte_pci.h
+++ b/lib/librte_pci/rte_pci.h
@@ -106,37 +106,6 @@ struct mapped_pci_resource {
TAILQ_HEAD(mapped_pci_res_list, mapped_pci_resource);
/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided without
- * a domain prefix (i.e. domain returned is always 0)
- *
- * @param input
- * The input string to be parsed. Should have the format XX:XX.X
- * @param dev_addr
- * The PCI Bus-Device-Function address to be returned.
- * Domain will always be returned as 0
- * @return
- * 0 on success, negative on error.
- */
-int eal_parse_pci_BDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
- * @deprecated
- * Utility function to produce a PCI Bus-Device-Function value
- * given a string representation. Assumes that the BDF is provided including
- * a domain prefix.
- *
- * @param input
- * The input string to be parsed. Should have the format XXXX:XX:XX.X
- * @param dev_addr
- * The PCI Bus-Device-Function address to be returned
- * @return
- * 0 on success, negative on error.
- */
-int eal_parse_pci_DomBDF(const char *input, struct rte_pci_addr *dev_addr);
-
-/**
* Utility function to write a pci device name, this device name can later be
* used to retrieve the corresponding rte_pci_addr using eal_parse_pci_*
* BDF helpers.
@@ -152,22 +121,6 @@ void rte_pci_device_name(const struct rte_pci_addr *addr,
char *output, size_t size);
/**
- * @deprecated
- * Utility function to compare two PCI device addresses.
- *
- * @param addr
- * The PCI Bus-Device-Function address to compare
- * @param addr2
- * The PCI Bus-Device-Function address to compare
- * @return
- * 0 on equal PCI address.
- * Positive on addr is greater than addr2.
- * Negative on addr is less than addr2, or error.
- */
-int rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
- const struct rte_pci_addr *addr2);
-
-/**
* Utility function to compare two PCI device addresses.
*
* @param addr
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index c028027..03790cb 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,11 +1,8 @@
DPDK_17.11 {
global:
- eal_parse_pci_BDF;
- eal_parse_pci_DomBDF;
pci_map_resource;
pci_unmap_resource;
- rte_eal_compare_pci_addr;
rte_pci_addr_cmp;
rte_pci_addr_parse;
rte_pci_device_name;
--
1.8.3.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH 3/8] eal: remove deprecated malloc virt2phys function
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
2019-10-22 9:32 12% ` [dpdk-dev] [PATCH 1/8] eal: make lcore config private David Marchand
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 2/8] eal: remove deprecated CPU flags check function David Marchand
@ 2019-10-22 9:32 5% ` David Marchand
2019-10-22 9:32 4% ` [dpdk-dev] [PATCH 6/8] pci: remove deprecated functions David Marchand
2019-10-22 9:32 3% ` [dpdk-dev] [PATCH 8/8] log: hide internal log structure David Marchand
4 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev
Cc: stephen, anatoly.burakov, thomas, Neil Horman, John McNamara,
Marko Kovacevic
Remove rte_malloc_virt2phy as announced previously.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
doc/guides/rel_notes/deprecation.rst | 3 ---
doc/guides/rel_notes/release_19_11.rst | 3 +++
lib/librte_eal/common/include/rte_malloc.h | 7 -------
3 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 50ac348..bbd5863 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -34,9 +34,6 @@ Deprecation Notices
+ ``rte_eal_devargs_type_count``
-* eal: The ``rte_malloc_virt2phy`` function has been deprecated and replaced
- by ``rte_malloc_virt2iova`` since v17.11 and will be removed.
-
* vfio: removal of ``rte_vfio_dma_map`` and ``rte_vfio_dma_unmap`` APIs which
have been replaced with ``rte_dev_dma_map`` and ``rte_dev_dma_unmap``
functions. The due date for the removal targets DPDK 20.02.
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 8bf2437..0c61c1c 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -207,6 +207,9 @@ ABI Changes
* eal: removed the ``rte_cpu_check_supported`` function, replaced by
``rte_cpu_is_supported`` since dpdk v17.08.
+* eal: removed the ``rte_malloc_virt2phy`` function, replaced by
+ ``rte_malloc_virt2iova`` since v17.11.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_eal/common/include/rte_malloc.h b/lib/librte_eal/common/include/rte_malloc.h
index 3593fb4..42ca051 100644
--- a/lib/librte_eal/common/include/rte_malloc.h
+++ b/lib/librte_eal/common/include/rte_malloc.h
@@ -553,13 +553,6 @@ rte_malloc_set_limit(const char *type, size_t max);
rte_iova_t
rte_malloc_virt2iova(const void *addr);
-__rte_deprecated
-static inline phys_addr_t
-rte_malloc_virt2phy(const void *addr)
-{
- return rte_malloc_virt2iova(addr);
-}
-
#ifdef __cplusplus
}
#endif
--
1.8.3.1
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH 8/8] log: hide internal log structure
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
` (3 preceding siblings ...)
2019-10-22 9:32 4% ` [dpdk-dev] [PATCH 6/8] pci: remove deprecated functions David Marchand
@ 2019-10-22 9:32 3% ` David Marchand
2019-10-22 16:35 0% ` Stephen Hemminger
2019-10-23 13:02 0% ` David Marchand
4 siblings, 2 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev; +Cc: stephen, anatoly.burakov, thomas
No need to expose rte_logs, hide it and remove it from the current ABI.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
lib/librte_eal/common/eal_common_log.c | 23 ++++++++++++++++-------
lib/librte_eal/common/include/rte_log.h | 20 +++-----------------
lib/librte_eal/rte_eal_version.map | 1 -
3 files changed, 19 insertions(+), 25 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_log.c b/lib/librte_eal/common/eal_common_log.c
index cfe9599..3a7ab88 100644
--- a/lib/librte_eal/common/eal_common_log.c
+++ b/lib/librte_eal/common/eal_common_log.c
@@ -17,13 +17,6 @@
#include "eal_private.h"
-/* global log structure */
-struct rte_logs rte_logs = {
- .type = ~0,
- .level = RTE_LOG_DEBUG,
- .file = NULL,
-};
-
struct rte_eal_opt_loglevel {
/** Next list entry */
TAILQ_ENTRY(rte_eal_opt_loglevel) next;
@@ -58,6 +51,22 @@ struct rte_log_dynamic_type {
uint32_t loglevel;
};
+/** The rte_log structure. */
+struct rte_logs {
+ uint32_t type; /**< Bitfield with enabled logs. */
+ uint32_t level; /**< Log level. */
+ FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */
+ size_t dynamic_types_len;
+ struct rte_log_dynamic_type *dynamic_types;
+};
+
+/* global log structure */
+static struct rte_logs rte_logs = {
+ .type = ~0,
+ .level = RTE_LOG_DEBUG,
+ .file = NULL,
+};
+
/* per core log */
static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
diff --git a/lib/librte_eal/common/include/rte_log.h b/lib/librte_eal/common/include/rte_log.h
index 1bb0e66..a8d0eb7 100644
--- a/lib/librte_eal/common/include/rte_log.h
+++ b/lib/librte_eal/common/include/rte_log.h
@@ -26,20 +26,6 @@ extern "C" {
#include <rte_config.h>
#include <rte_compat.h>
-struct rte_log_dynamic_type;
-
-/** The rte_log structure. */
-struct rte_logs {
- uint32_t type; /**< Bitfield with enabled logs. */
- uint32_t level; /**< Log level. */
- FILE *file; /**< Output file set by rte_openlog_stream, or NULL. */
- size_t dynamic_types_len;
- struct rte_log_dynamic_type *dynamic_types;
-};
-
-/** Global log information */
-extern struct rte_logs rte_logs;
-
/* SDK log type */
#define RTE_LOGTYPE_EAL 0 /**< Log related to eal. */
#define RTE_LOGTYPE_MALLOC 1 /**< Log related to malloc. */
@@ -260,7 +246,7 @@ void rte_log_dump(FILE *f);
* to rte_openlog_stream().
*
* The level argument determines if the log should be displayed or
- * not, depending on the global rte_logs variable.
+ * not, depending on the global log level and the per logtype level.
*
* The preferred alternative is the RTE_LOG() because it adds the
* level and type in the logged string.
@@ -291,8 +277,8 @@ int rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
* to rte_openlog_stream().
*
* The level argument determines if the log should be displayed or
- * not, depending on the global rte_logs variable. A trailing
- * newline may be added if needed.
+ * not, depending on the global log level and the per logtype level.
+ * A trailing newline may be added if needed.
*
* The preferred alternative is the RTE_LOG() because it adds the
* level and type in the logged string.
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 6d7e0e4..ca9ace0 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -45,7 +45,6 @@ DPDK_2.0 {
rte_log;
rte_log_cur_msg_loglevel;
rte_log_cur_msg_logtype;
- rte_logs;
rte_malloc;
rte_malloc_dump_stats;
rte_malloc_get_socket_stats;
--
1.8.3.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH 2/8] eal: remove deprecated CPU flags check function
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
2019-10-22 9:32 12% ` [dpdk-dev] [PATCH 1/8] eal: make lcore config private David Marchand
@ 2019-10-22 9:32 5% ` David Marchand
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 3/8] eal: remove deprecated malloc virt2phys function David Marchand
` (2 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev
Cc: stephen, anatoly.burakov, thomas, Neil Horman, John McNamara,
Marko Kovacevic
Remove rte_cpu_check_supported as announced previously.
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
doc/guides/rel_notes/deprecation.rst | 3 ---
doc/guides/rel_notes/release_19_11.rst | 3 +++
lib/librte_eal/common/eal_common_cpuflags.c | 11 -----------
lib/librte_eal/common/include/generic/rte_cpuflags.h | 9 ---------
lib/librte_eal/rte_eal_version.map | 1 -
5 files changed, 3 insertions(+), 24 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index e4a33e0..50ac348 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -34,9 +34,6 @@ Deprecation Notices
+ ``rte_eal_devargs_type_count``
-* eal: The ``rte_cpu_check_supported`` function has been deprecated since
- v17.08 and will be removed.
-
* eal: The ``rte_malloc_virt2phy`` function has been deprecated and replaced
by ``rte_malloc_virt2iova`` since v17.11 and will be removed.
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index d7e14b4..8bf2437 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -204,6 +204,9 @@ ABI Changes
* eal: made the ``lcore_config`` struct and global symbol private.
+* eal: removed the ``rte_cpu_check_supported`` function, replaced by
+ ``rte_cpu_is_supported`` since dpdk v17.08.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_eal/common/eal_common_cpuflags.c b/lib/librte_eal/common/eal_common_cpuflags.c
index 3a055f7..dc5f75d 100644
--- a/lib/librte_eal/common/eal_common_cpuflags.c
+++ b/lib/librte_eal/common/eal_common_cpuflags.c
@@ -7,17 +7,6 @@
#include <rte_common.h>
#include <rte_cpuflags.h>
-/**
- * Checks if the machine is adequate for running the binary. If it is not, the
- * program exits with status 1.
- */
-void
-rte_cpu_check_supported(void)
-{
- if (!rte_cpu_is_supported())
- exit(1);
-}
-
int
rte_cpu_is_supported(void)
{
diff --git a/lib/librte_eal/common/include/generic/rte_cpuflags.h b/lib/librte_eal/common/include/generic/rte_cpuflags.h
index 156ea00..872f0eb 100644
--- a/lib/librte_eal/common/include/generic/rte_cpuflags.h
+++ b/lib/librte_eal/common/include/generic/rte_cpuflags.h
@@ -49,15 +49,6 @@ rte_cpu_get_flag_enabled(enum rte_cpu_flag_t feature);
/**
* This function checks that the currently used CPU supports the CPU features
* that were specified at compile time. It is called automatically within the
- * EAL, so does not need to be used by applications.
- */
-__rte_deprecated
-void
-rte_cpu_check_supported(void);
-
-/**
- * This function checks that the currently used CPU supports the CPU features
- * that were specified at compile time. It is called automatically within the
* EAL, so does not need to be used by applications. This version returns a
* result so that decisions may be made (for instance, graceful shutdowns).
*/
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index aeedf39..0887549 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -8,7 +8,6 @@ DPDK_2.0 {
per_lcore__rte_errno;
rte_calloc;
rte_calloc_socket;
- rte_cpu_check_supported;
rte_cpu_get_flag_enabled;
rte_cycles_vmware_tsc_map;
rte_delay_us;
--
1.8.3.1
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH 1/8] eal: make lcore config private
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
@ 2019-10-22 9:32 12% ` David Marchand
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 2/8] eal: remove deprecated CPU flags check function David Marchand
` (3 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev
Cc: stephen, anatoly.burakov, thomas, Neil Horman, John McNamara,
Marko Kovacevic, Harry van Haaren, Harini Ramakrishnan,
Omar Cardona, Anand Rawat, Ranjit Menon
From: Stephen Hemminger <stephen@networkplumber.org>
The internal structure of lcore_config does not need to be part of
visible API/ABI. Make it private to EAL.
Rearrange the structure so it takes less memory (and cache footprint).
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Based on Stephen v8: http://patchwork.dpdk.org/patch/60443/
Changes since Stephen v8:
- do not change core_id, socket_id and core_index types,
---
doc/guides/rel_notes/deprecation.rst | 4 ----
doc/guides/rel_notes/release_19_11.rst | 2 ++
lib/librte_eal/common/eal_common_launch.c | 2 ++
lib/librte_eal/common/eal_private.h | 25 +++++++++++++++++++++++++
lib/librte_eal/common/include/rte_lcore.h | 24 ------------------------
lib/librte_eal/common/rte_service.c | 2 ++
lib/librte_eal/rte_eal_version.map | 1 -
lib/librte_eal/windows/eal/eal_thread.c | 1 +
8 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 237813b..e4a33e0 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,10 +23,6 @@ Deprecation Notices
* eal: The function ``rte_eal_remote_launch`` will return new error codes
after read or write error on the pipe, instead of calling ``rte_panic``.
-* eal: The ``lcore_config`` struct and global symbol will be made private to
- remove it from the externally visible ABI and allow it to be updated in the
- future.
-
* eal: both declaring and identifying devices will be streamlined in v18.11.
New functions will appear to query a specific port from buses, classes of
device and device drivers. Device declaration will be made coherent with the
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 40121b9..d7e14b4 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -202,6 +202,8 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* eal: made the ``lcore_config`` struct and global symbol private.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_eal/common/eal_common_launch.c b/lib/librte_eal/common/eal_common_launch.c
index fe0ba3f..cf52d71 100644
--- a/lib/librte_eal/common/eal_common_launch.c
+++ b/lib/librte_eal/common/eal_common_launch.c
@@ -15,6 +15,8 @@
#include <rte_per_lcore.h>
#include <rte_lcore.h>
+#include "eal_private.h"
+
/*
* Wait until a lcore finished its job.
*/
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 798ede5..0e4b033 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -10,6 +10,31 @@
#include <stdio.h>
#include <rte_dev.h>
+#include <rte_lcore.h>
+
+/**
+ * Structure storing internal configuration (per-lcore)
+ */
+struct lcore_config {
+ pthread_t thread_id; /**< pthread identifier */
+ int pipe_master2slave[2]; /**< communication pipe with master */
+ int pipe_slave2master[2]; /**< communication pipe with master */
+
+ lcore_function_t * volatile f; /**< function to call */
+ void * volatile arg; /**< argument of function */
+ volatile int ret; /**< return value of function */
+
+ volatile enum rte_lcore_state_t state; /**< lcore state */
+ unsigned int socket_id; /**< physical socket id for this lcore */
+ unsigned int core_id; /**< core number on socket for this lcore */
+ int core_index; /**< relative index, starting from 0 */
+ uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
+ uint8_t detected; /**< true if lcore was detected */
+
+ rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
+};
+
+extern struct lcore_config lcore_config[RTE_MAX_LCORE];
/**
* Initialize the memzone subsystem (private to eal).
diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index c86f72e..0c68391 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -66,30 +66,6 @@ typedef cpuset_t rte_cpuset_t;
} while (0)
#endif
-/**
- * Structure storing internal configuration (per-lcore)
- */
-struct lcore_config {
- unsigned detected; /**< true if lcore was detected */
- pthread_t thread_id; /**< pthread identifier */
- int pipe_master2slave[2]; /**< communication pipe with master */
- int pipe_slave2master[2]; /**< communication pipe with master */
- lcore_function_t * volatile f; /**< function to call */
- void * volatile arg; /**< argument of function */
- volatile int ret; /**< return value of function */
- volatile enum rte_lcore_state_t state; /**< lcore state */
- unsigned socket_id; /**< physical socket id for this lcore */
- unsigned core_id; /**< core number on socket for this lcore */
- int core_index; /**< relative index, starting from 0 */
- rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
- uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
-};
-
-/**
- * Internal configuration (per-lcore)
- */
-extern struct lcore_config lcore_config[RTE_MAX_LCORE];
-
RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */
RTE_DECLARE_PER_LCORE(rte_cpuset_t, _cpuset); /**< Per thread "cpuset". */
diff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c
index beb9691..79235c0 100644
--- a/lib/librte_eal/common/rte_service.c
+++ b/lib/librte_eal/common/rte_service.c
@@ -21,6 +21,8 @@
#include <rte_memory.h>
#include <rte_malloc.h>
+#include "eal_private.h"
+
#define RTE_SERVICE_NUM_MAX 64
#define SERVICE_F_REGISTERED (1 << 0)
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7cbf82d..aeedf39 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -4,7 +4,6 @@ DPDK_2.0 {
__rte_panic;
eal_parse_sysfs_value;
eal_timer_source;
- lcore_config;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
diff --git a/lib/librte_eal/windows/eal/eal_thread.c b/lib/librte_eal/windows/eal/eal_thread.c
index 906502f..0591d4c 100644
--- a/lib/librte_eal/windows/eal/eal_thread.c
+++ b/lib/librte_eal/windows/eal/eal_thread.c
@@ -12,6 +12,7 @@
#include <rte_common.h>
#include <eal_thread.h>
+#include "eal_private.h"
RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY;
--
1.8.3.1
^ permalink raw reply [relevance 12%]
* [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11
@ 2019-10-22 9:32 8% David Marchand
2019-10-22 9:32 12% ` [dpdk-dev] [PATCH 1/8] eal: make lcore config private David Marchand
` (4 more replies)
0 siblings, 5 replies; 200+ results
From: David Marchand @ 2019-10-22 9:32 UTC (permalink / raw)
To: dev; +Cc: stephen, anatoly.burakov, thomas
Let's prepare for the ABI freeze.
The first patches are about changes that had been announced before (with
a patch from Stephen that I took as it is ready as is from my pov).
The malloc_heap structure from the memory subsystem can be hidden.
The PCI library had some forgotten deprecated APIs that are removed with
this series.
Finally, rte_logs could be hidden, but I am not that confortable about
doing it right away: I added an accessor to rte_logs.file, but I am fine
with dropping the last patch and wait for actually hiding this in the next
ABI break.
Comments?
--
David Marchand
David Marchand (7):
eal: remove deprecated CPU flags check function
eal: remove deprecated malloc virt2phys function
mem: hide internal heap header
net/bonding: use non deprecated PCI API
pci: remove deprecated functions
log: add log stream accessor
log: hide internal log structure
Stephen Hemminger (1):
eal: make lcore config private
app/test-pmd/testpmd.c | 1 -
doc/guides/rel_notes/deprecation.rst | 17 -------
doc/guides/rel_notes/release_19_11.rst | 14 +++++
drivers/common/qat/qat_logs.c | 3 +-
drivers/common/qat/qat_logs.h | 3 +-
drivers/net/bonding/rte_eth_bond_args.c | 5 +-
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_cpuflags.c | 11 ----
lib/librte_eal/common/eal_common_launch.c | 2 +
lib/librte_eal/common/eal_common_log.c | 59 ++++++++++++++--------
lib/librte_eal/common/eal_memcfg.h | 3 +-
lib/librte_eal/common/eal_private.h | 25 +++++++++
.../common/include/generic/rte_cpuflags.h | 9 ----
lib/librte_eal/common/include/rte_lcore.h | 24 ---------
lib/librte_eal/common/include/rte_log.h | 33 ++++++------
lib/librte_eal/common/include/rte_malloc.h | 7 ---
lib/librte_eal/common/include/rte_malloc_heap.h | 35 -------------
lib/librte_eal/common/malloc_heap.h | 25 ++++++++-
lib/librte_eal/common/meson.build | 1 -
lib/librte_eal/common/rte_service.c | 2 +
lib/librte_eal/rte_eal_version.map | 6 +--
lib/librte_eal/windows/eal/eal_thread.c | 1 +
lib/librte_pci/rte_pci.c | 19 -------
lib/librte_pci/rte_pci.h | 47 -----------------
lib/librte_pci/rte_pci_version.map | 3 --
25 files changed, 132 insertions(+), 225 deletions(-)
delete mode 100644 lib/librte_eal/common/include/rte_malloc_heap.h
--
1.8.3.1
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v8] eal: make lcore_config private
2019-10-02 19:40 13% ` [dpdk-dev] [PATCH v8] " Stephen Hemminger
@ 2019-10-22 9:05 3% ` David Marchand
2019-10-22 16:30 0% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-10-22 9:05 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Wed, Oct 2, 2019 at 9:40 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
> +struct lcore_config {
> + pthread_t thread_id; /**< pthread identifier */
> + int pipe_master2slave[2]; /**< communication pipe with master */
> + int pipe_slave2master[2]; /**< communication pipe with master */
> +
> + lcore_function_t * volatile f; /**< function to call */
> + void * volatile arg; /**< argument of function */
> + volatile int ret; /**< return value of function */
> +
> + uint32_t core_id; /**< core number on socket for this lcore */
> + uint32_t core_index; /**< relative index, starting from 0 */
> + uint16_t socket_id; /**< physical socket id for this lcore */
> + uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
> + uint8_t detected; /**< true if lcore was detected */
> + volatile enum rte_lcore_state_t state; /**< lcore state */
> + rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
> +};
There are still changes on the core_id, core_index, socket_id that I
am not confortable with (at this point).
I prepared a series for -rc1 on ABI changes in EAL (that I will send shortly).
I took your patch without the changes on core_id, core_index and socket_id.
We can discuss those changes later, thanks.
--
David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v6 0/4] doc: changes to abi policy introducing major abi versions
2019-10-21 14:38 5% ` Thomas Monjalon
@ 2019-10-22 8:12 5% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-10-22 8:12 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, stephen, bruce.richardson, ferruh.yigit, konstantin.ananyev,
jerinj, olivier.matz, nhorman, maxime.coquelin, john.mcnamara,
marko.kovacevic, hemant.agrawal, ktraynor, aconole
On 21/10/2019 15:38, Thomas Monjalon wrote:
> 21/10/2019 12:10, Ray Kinsella:
>>
>> On 21/10/2019 10:50, Thomas Monjalon wrote:
>>> 27/09/2019 18:54, Ray Kinsella:
>>>> TL;DR abbreviation:
>>>> A major ABI version that all DPDK releases during a one year period
>>>> support. ABI versioning is managed at a project-level, in place of library-level
>>>> management. ABI changes to add new features are permitted, as long as ABI
>>>> compatibility with the major ABI version is maintained.
>>>>
>>>> Detail:
>>>> This patch introduces major ABI versions, supported for one year and released
>>>> aligned with the LTS release. This ABI version is then supported by all
>>>> subsequent releases within that one year period. The intention is that the one
>>>> year support period, will then be reviewed after the initial year with the
>>>> intention of lengthing the support period for the next ABI version.
>>>
>>> For the record, I would prefer a v7 saying it is a fixed period of time,
>>> being one year at first and should be longer next.
>>> Please don't state "supported for one year", which can be understood as a general truth.
>>
>> Well I was very careful to only state an _intention_ to lengthen the fix period,
>> I though it prudent to avoid words like "should", as nothing is known until the year is behind us.
>>
>> Where I used the word "support", I talk about "abi support".
>> I suggest rewording as follows:-
>>
>> This patch introduces major ABI versions, released aligned with the LTS release,
>> maintained for one year through all subsequent releases within that one year period.
>> The intention is that the one year abi support period, will then be reviewed after
>> the initial year with the intention of lengthening the period for the next ABI version.
>
> Yes, looks better.
>
> I am going to review carefully the series.
>
Ok - I will hold fire on any changes then.
Ray K
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v6 0/4] doc: changes to abi policy introducing major abi versions
2019-10-21 10:10 10% ` Ray Kinsella
@ 2019-10-21 14:38 5% ` Thomas Monjalon
2019-10-22 8:12 5% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-10-21 14:38 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, stephen, bruce.richardson, ferruh.yigit, konstantin.ananyev,
jerinj, olivier.matz, nhorman, maxime.coquelin, john.mcnamara,
marko.kovacevic, hemant.agrawal, ktraynor, aconole
21/10/2019 12:10, Ray Kinsella:
>
> On 21/10/2019 10:50, Thomas Monjalon wrote:
> > 27/09/2019 18:54, Ray Kinsella:
> >> TL;DR abbreviation:
> >> A major ABI version that all DPDK releases during a one year period
> >> support. ABI versioning is managed at a project-level, in place of library-level
> >> management. ABI changes to add new features are permitted, as long as ABI
> >> compatibility with the major ABI version is maintained.
> >>
> >> Detail:
> >> This patch introduces major ABI versions, supported for one year and released
> >> aligned with the LTS release. This ABI version is then supported by all
> >> subsequent releases within that one year period. The intention is that the one
> >> year support period, will then be reviewed after the initial year with the
> >> intention of lengthing the support period for the next ABI version.
> >
> > For the record, I would prefer a v7 saying it is a fixed period of time,
> > being one year at first and should be longer next.
> > Please don't state "supported for one year", which can be understood as a general truth.
>
> Well I was very careful to only state an _intention_ to lengthen the fix period,
> I though it prudent to avoid words like "should", as nothing is known until the year is behind us.
>
> Where I used the word "support", I talk about "abi support".
> I suggest rewording as follows:-
>
> This patch introduces major ABI versions, released aligned with the LTS release,
> maintained for one year through all subsequent releases within that one year period.
> The intention is that the one year abi support period, will then be reviewed after
> the initial year with the intention of lengthening the period for the next ABI version.
Yes, looks better.
I am going to review carefully the series.
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v8 00/13] vhost packed ring performance optimization
2019-10-21 15:40 3% ` [dpdk-dev] [PATCH v7 " Marvin Liu
@ 2019-10-21 22:08 3% ` Marvin Liu
0 siblings, 0 replies; 200+ results
From: Marvin Liu @ 2019-10-21 22:08 UTC (permalink / raw)
To: maxime.coquelin, tiwei.bie, zhihong.wang, stephen, gavin.hu
Cc: dev, Marvin Liu
Packed ring has more compact ring format and thus can significantly
reduce the number of cache miss. It can lead to better performance.
This has been approved in virtio user driver, on normal E5 Xeon cpu
single core performance can raise 12%.
http://mails.dpdk.org/archives/dev/2018-April/095470.html
However vhost performance with packed ring performance was decreased.
Through analysis, mostly extra cost was from the calculating of each
descriptor flag which depended on ring wrap counter. Moreover, both
frontend and backend need to write same descriptors which will cause
cache contention. Especially when doing vhost enqueue function, virtio
refill packed ring function may write same cache line when vhost doing
enqueue function. This kind of extra cache cost will reduce the benefit
of reducing cache misses.
For optimizing vhost packed ring performance, vhost enqueue and dequeue
function will be splitted into fast and normal path.
Several methods will be taken in fast path:
Handle descriptors in one cache line by batch.
Split loop function into more pieces and unroll them.
Prerequisite check that whether I/O space can copy directly into mbuf
space and vice versa.
Prerequisite check that whether descriptor mapping is successful.
Distinguish vhost used ring update function by enqueue and dequeue
function.
Buffer dequeue used descriptors as many as possible.
Update enqueue used descriptors by cache line.
After all these methods done, single core vhost PvP performance with 64B
packet on Xeon 8180 can boost 35%.
v8:
- Allocate mbuf by virtio_dev_pktmbuf_alloc
v7:
- Rebase code
- Rename unroll macro and definitions
- Calculate flags when doing single dequeue
v6:
- Fix dequeue zcopy result check
v5:
- Remove disable sw prefetch as performance impact is small
- Change unroll pragma macro format
- Rename shadow counter elements names
- Clean dequeue update check condition
- Add inline functions replace of duplicated code
- Unify code style
v4:
- Support meson build
- Remove memory region cache for no clear performance gain and ABI break
- Not assume ring size is power of two
v3:
- Check available index overflow
- Remove dequeue remained descs number check
- Remove changes in split ring datapath
- Call memory write barriers once when updating used flags
- Rename some functions and macros
- Code style optimization
v2:
- Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
- Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
- Optimize dequeue used ring update when in_order negotiated
Marvin Liu (13):
vhost: add packed ring indexes increasing function
vhost: add packed ring single enqueue
vhost: try to unroll for each loop
vhost: add packed ring batch enqueue
vhost: add packed ring single dequeue
vhost: add packed ring batch dequeue
vhost: flush enqueue updates by cacheline
vhost: flush batched enqueue descs directly
vhost: buffer packed ring dequeue updates
vhost: optimize packed ring enqueue
vhost: add packed ring zcopy batch and single dequeue
vhost: optimize packed ring dequeue
vhost: optimize packed ring dequeue when in-order
lib/librte_vhost/Makefile | 18 +
lib/librte_vhost/meson.build | 7 +
lib/librte_vhost/vhost.h | 57 ++
lib/librte_vhost/virtio_net.c | 948 +++++++++++++++++++++++++++-------
4 files changed, 837 insertions(+), 193 deletions(-)
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-18 13:17 4% ` Akhil Goyal
@ 2019-10-21 13:47 4% ` Ananyev, Konstantin
2019-10-22 13:31 4% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-21 13:47 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', Hemant Agrawal
Hi Akhil,
> Added my comments inline with your draft.
> >
> >
> > Hi Akhil,
> >
> > > > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > > > construct for multiple device_ids:
> > > > __extension__ struct {
> > > > void *data;
> > > > uint16_t refcnt;
> > > > } sess_data[0];
> > > > /**< Driver specific session material, variable size */
> > > >
> > > Yes I also feel the same. I was also not in favor of this when it was introduced.
> > > Please go ahead and remove this. I have no issues with that.
> >
> > If you are not happy with that structure, and admit there are issues with it,
> > why do you push for reusing it for cpu-crypto API?
> > Why not to take step back, take into account current drawbacks
> > and define something that (hopefully) would suite us better?
> > Again new API will be experimental for some time, so we'll
> > have some opportunity to see does it works and if not fix it.
>
> [Akhil] This structure is serving some use case which is agreed upon in the
> Community, we cannot just remove a feature altogether.
I understand that, but we don't suggest to remove anything that already here.
We are talking about extending existing/adding new API.
All our debates around how much we can reuse from existing one and what new
needs to be added.
> Rather it is Intel's Use case only.
>
> >
> > About removing data[] from existing rte_cryptodev_sym_session -
> > Personally would like to do that, but the change seems to be too massive.
> > Definitely not ready for such effort right now.
> >
>
> [snip]..
>
> >
> > Ok, then my suggestion:
> > Let's at least write down all points about crypto-dev approach where we
> > disagree and then probably try to resolve them one by one....
> > If we fail to make an agreement/progress in next week or so,
> > (and no more reviews from the community)
> > will have bring that subject to TB meeting to decide.
> > Sounds fair to you?
> Agreed
> >
> > List is below.
> > Please add/correct me, if I missed something.
> >
> > Konstantin
>
> Before going into comparison, we should define the requirement as well.
Good point.
> What I understood from the patchset,
> "You need a synchronous API to perform crypto operations on raw data using SW PMDs"
> So,
> - no crypto-ops,
> - no separate enq-deq, only single process API for data path
> - Do not need any value addition to the session parameters.
> (You would need some parameters from the crypto-op which
> Are constant per session and since you wont use crypto-op,
> You need some place to store that)
Yes, this is correct, I think.
>
> Now as per your mail, the comparison
> 1. extra input parameters to create/init rte_(cpu)_sym_session.
>
> Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and 'key' fields.
> New fields will be optional and would be used by PMD only when cpu-crypto session is requested.
> For lksd-crypto session PMD is free to ignore these fields.
> No ABI breakage is required.
>
> [Akhil] Agreed, no issues.
>
> 2. cpu-crypto create/init.
> a) Our suggestion - introduce new API for that:
> - rte_crypto_cpu_sym_init() that would init completely opaque rte_crypto_cpu_sym_session.
> - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear); /*whatever else we'll need *'};
> - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform *xforms)
> that would return const struct rte_crypto_cpu_sym_session_ops *based on input xforms.
> Advantages:
> 1) totally opaque data structure (no ABI breakages in future), PMD writer is totally free
> with it format and contents.
>
> [Akhil] It will have breakage at some point till we don't hit the union size.
Not sure, what union you are talking about?
> Rather I don't suspect there will be more parameters added.
> Or do we really care about the ABI breakage when the argument is about
> the correct place to add a piece of code or do we really agree to add code
> anywhere just to avoid that breakage.
I am talking about maintaining it in future.
if your struct is not seen externally, no chances to introduce ABI breakage.
>
> 2) each session entity is self-contained, user doesn't need to bring along dev_id etc.
> dev_id is needed only at init stage, after that user will use session ops to perform
> all operations on that session (process(), clear(), etc.).
>
> [Akhil] There is nothing called as session ops in current DPDK.
True, but it doesn't mean we can't/shouldn't have it.
> What you are proposing
> is a new concept which doesn't have any extra benefit, rather it is adding complexity
> to have two different code paths for session create.
>
>
> 3) User can decide does he wants to store ops[] pointer on a per session basis,
> or on a per group of same sessions, or...
>
> [Akhil] Will the user really care which process API should be called from the PMD.
> Rather it should be driver's responsibility to store that in the session private data
> which would be opaque to the user. As per my suggestion same process function can
> be added to multiple sessions or a single session can be managed inside the PMD.
In that case we either need to have a function per session (stored internally),
or make decision (branches) at run-time.
But as I said in other mail - I am ok to add small shim structure here:
either rte_crypto_cpu_sym_session { void *ses; struct rte_crypto_cpu_sym_session_ops ops; }
or rte_crypto_cpu_sym_session { void *ses; struct rte_crypto_cpu_sym_session_ops *ops; }
And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops() into one (init).
>
>
> 4) No mandatory mempools for private sessions. User can allocate memory for cpu-crypto
> session whenever he likes.
>
> [Akhil] you mean session private data?
Yes.
> You would need that memory anyways, user will be
> allocating that already. You do not need to manage that.
What I am saying - right now user has no choice but to allocate it via mempool.
Which is probably not the best options for all cases.
>
> Disadvantages:
> 5) Extra changes in control path
> 6) User has to store session_ops pointer explicitly.
>
> [Akhil] More disadvantages:
> - All supporting PMDs will need to maintain TWO types of session for the
> same crypto processing. Suppose a fix or a new feature(or algo) is added, PMD owner
> will need to add code in both the session create APIs. Hence more maintenance and
> error prone.
I think majority of code for both paths will be common, plus even we'll reuse current sym_session_init() -
changes in PMD session_init() code will be unavoidable.
But yes, it will be new entry in devops, that PMD will have to support.
Ok to add it as 7) to the list.
> - Stacks which will be using these new APIs also need to maintain two
> code path for the same processing while doing session initialization
> for sync and async
That's the same as #5 above, I think.
>
>
> b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and existing rte_cryptodev_sym_session
> structure.
> Advantages:
> 1) allows to reuse same struct and init/create/clear() functions.
> Probably less changes in control path.
> Disadvantages:
> 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means that
> we can't use the same rte_cryptodev_sym_session to hold private sessions pointers
> for both sync and async mode for the same device.
> So the only option we have - make PMD devops->sym_session_configure()
> always create a session that can work in both cpu and lksd modes.
> For some implementations that would probably mean that under the hood PMD would create
> 2 different session structs (sync/async) and then use one or another depending on from what API been called.
> Seems doable, but ...:
> - will contradict with statement from 1:
> " New fields will be optional and would be used by PMD only when cpu-crypto session is requested."
> Now it becomes mandatory for all apps to specify cpu-crypto related parameters too,
> even if they don't plan to use that mode - i.e. behavior change, existing app change.
> - might cause extra space overhead.
>
> [Akhil] It will not contradict with #1, you will only have few checks in the session init PMD
> Which support this mode, find appropriate values and set the appropriate process() in it.
> User should be able to call, legacy enq-deq as well as the new process() without any issue.
> User would be at runtime will be able to change the datapath.
> So this is not a disadvantage, it would be additional flexibility for the user.
Ok, but that's what I am saying - if PMD would *always* have to create a session that can handle
both modes (sync/async), then user would *always* have to provide parameters for both modes too.
Otherwise if let say user didn't setup sync specific parameters at all, what PMD should do?
- return with error?
- init session that can be used with async path only?
My current assumption is #1.
If #2, then how user will be able to distinguish is that session valid for both modes, or only for one?
>
>
> 3) not possible to store device (not driver) specific data within the session, but I think it is not really needed right now.
> So probably minor compared to 2.b.2.
>
> [Akhil] So lets omit this for current discussion. And I hope we can find some way to deal with it.
I don't think there is an easy way to fix that with existing API.
>
>
> Actually #3 follows from #2, but decided to have them separated.
>
> 3. process() parameters/behavior
> a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and just does:
> session_ops->process(sess, ...);
> Advantages:
> 1) fastest possible execution path
> 2) no need to carry on dev_id for data-path
>
> [Akhil] I don't see any overhead of carrying dev id, at least it would be inline with the
> current DPDK methodology.
If we'll add process() into rte_cryptodev itself (same as we have enqueue_burst/dequeue_burst),
then it will be an ABI breakage.
Also there are discussions to get rid of that approach completely:
http://mails.dpdk.org/archives/dev/2019-September/144674.html
So I am not sure this is a recommended way these days.
> What you are suggesting is a new way to get the things done without much benefit.
Would help with ABI stability plus better performance, isn't it enough?
> Also I don't see any performance difference as crypto workload is heavier than
> Code cycles, so that wont matter.
It depends.
Suppose function call costs you ~30 cycles.
If you have burst of big packets (let say crypto for each will take ~2K cycles) that belong
to the same session, then yes you wouldn't notice these extra 30 cycles at all.
If you have burst of small packets (let say crypto for each will take ~300 cycles) each
belongs to different session, then it will cost you ~10% extra.
> So IMO, there is no advantage in your suggestion as well.
>
>
> Disadvantages:
> 3) user has to carry on session_ops pointer explicitly
> b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
> rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session *sess, /*data parameters*/) {...
> rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> /*and then inside PMD specifc process: */
> pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
> /* and then most likely either */
> pmd_private_session->process(pmd_private_session, ...);
> /* or jump based on session/input data */
> Advantages:
> 1) don't see any...
> Disadvantages:
> 2) User has to carry on dev_id inside data-path
> 3) Extra level of indirection (plus data dependency) - both for data and instructions.
> Possible slowdown compared to a) (not measured).
>
> Having said all this, if the disagreements cannot be resolved, you can go for a pmd API specific
> to your PMDs,
I don't think it is good idea.
PMD specific API is sort of deprecated path, also there is no clean way to use it within the libraries.
> because as per my understanding the solution doesn't look scalable to other PMDs.
> Your approach is aligned only to Intel , will not benefit others like openssl which is used by all
> vendors.
I feel quite opposite, from my perspective majority of SW backed PMDs will benefit from it.
And I don't see anything Intel specific in my proposals above.
About openssl PMD: I am not an expert here, but looking at the code, I think it will fit really well.
Look yourself at its internal functions: process_openssl_auth_op/process_openssl_crypto_op,
I think they doing exactly the same - they use sync API underneath, and they are session based
(AFAIK you don't need any device/queue data, everything that needed for crypto/auth is stored inside session).
Konstantin
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code Anatoly Burakov
2019-10-17 21:04 0% ` Carrillo, Erik G
@ 2019-10-21 13:24 3% ` Kevin Traynor
1 sibling, 0 replies; 200+ results
From: Kevin Traynor @ 2019-10-21 13:24 UTC (permalink / raw)
To: Anatoly Burakov, dev
Cc: Marcin Baran, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, bruce.richardson, thomas, david.marchand
On 17/10/2019 15:31, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> Remove code for old ABI versions ahead of ABI version bump.
>
I think there needs to be some doc updates for this.
Looking at http://doc.dpdk.org/guides/rel_notes/deprecation.html there
is nothing saying these functions are deprecated? (probably same issue
for other 'remove deprecated code' patches)
There should probably be an entry in the API/ABI changes section of the
release notes too.
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> ---
>
> Notes:
> v2:
> - Moved this to before ABI version bump to avoid compile breakage
>
> lib/librte_timer/rte_timer.c | 90 ++----------------------------------
> lib/librte_timer/rte_timer.h | 15 ------
> 2 files changed, 5 insertions(+), 100 deletions(-)
>
> diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
> index bdcf05d06b..de6959b809 100644
> --- a/lib/librte_timer/rte_timer.c
> +++ b/lib/librte_timer/rte_timer.c
> @@ -68,9 +68,6 @@ static struct rte_timer_data *rte_timer_data_arr;
> static const uint32_t default_data_id;
> static uint32_t rte_timer_subsystem_initialized;
>
> -/* For maintaining older interfaces for a period */
> -static struct rte_timer_data default_timer_data;
> -
> /* when debug is enabled, store some statistics */
> #ifdef RTE_LIBRTE_TIMER_DEBUG
> #define __TIMER_STAT_ADD(priv_timer, name, n) do { \
> @@ -131,22 +128,6 @@ rte_timer_data_dealloc(uint32_t id)
> return 0;
> }
>
> -void
> -rte_timer_subsystem_init_v20(void)
> -{
> - unsigned lcore_id;
> - struct priv_timer *priv_timer = default_timer_data.priv_timer;
> -
> - /* since priv_timer is static, it's zeroed by default, so only init some
> - * fields.
> - */
> - for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) {
> - rte_spinlock_init(&priv_timer[lcore_id].list_lock);
> - priv_timer[lcore_id].prev_lcore = lcore_id;
> - }
> -}
> -VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
> -
> /* Init the timer library. Allocate an array of timer data structs in shared
> * memory, and allocate the zeroth entry for use with original timer
> * APIs. Since the intersection of the sets of lcore ids in primary and
> @@ -154,7 +135,7 @@ VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
> * multiple processes.
> */
> int
> -rte_timer_subsystem_init_v1905(void)
> +rte_timer_subsystem_init(void)
> {
> const struct rte_memzone *mz;
> struct rte_timer_data *data;
> @@ -209,9 +190,6 @@ rte_timer_subsystem_init_v1905(void)
>
> return 0;
> }
> -MAP_STATIC_SYMBOL(int rte_timer_subsystem_init(void),
> - rte_timer_subsystem_init_v1905);
> -BIND_DEFAULT_SYMBOL(rte_timer_subsystem_init, _v1905, 19.05);
>
> void
> rte_timer_subsystem_finalize(void)
> @@ -552,42 +530,13 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
>
> /* Reset and start the timer associated with the timer handle tim */
> int
> -rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
> - enum rte_timer_type type, unsigned int tim_lcore,
> - rte_timer_cb_t fct, void *arg)
> -{
> - uint64_t cur_time = rte_get_timer_cycles();
> - uint64_t period;
> -
> - if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
> - !(rte_lcore_is_enabled(tim_lcore) ||
> - rte_lcore_has_role(tim_lcore, ROLE_SERVICE))))
> - return -1;
> -
> - if (type == PERIODICAL)
> - period = ticks;
> - else
> - period = 0;
> -
> - return __rte_timer_reset(tim, cur_time + ticks, period, tim_lcore,
> - fct, arg, 0, &default_timer_data);
> -}
> -VERSION_SYMBOL(rte_timer_reset, _v20, 2.0);
> -
> -int
> -rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
> +rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
> enum rte_timer_type type, unsigned int tim_lcore,
> rte_timer_cb_t fct, void *arg)
> {
> return rte_timer_alt_reset(default_data_id, tim, ticks, type,
> tim_lcore, fct, arg);
> }
> -MAP_STATIC_SYMBOL(int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
> - enum rte_timer_type type,
> - unsigned int tim_lcore,
> - rte_timer_cb_t fct, void *arg),
> - rte_timer_reset_v1905);
> -BIND_DEFAULT_SYMBOL(rte_timer_reset, _v1905, 19.05);
>
> int
> rte_timer_alt_reset(uint32_t timer_data_id, struct rte_timer *tim,
> @@ -658,20 +607,10 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked,
>
> /* Stop the timer associated with the timer handle tim */
> int
> -rte_timer_stop_v20(struct rte_timer *tim)
> -{
> - return __rte_timer_stop(tim, 0, &default_timer_data);
> -}
> -VERSION_SYMBOL(rte_timer_stop, _v20, 2.0);
> -
> -int
> -rte_timer_stop_v1905(struct rte_timer *tim)
> +rte_timer_stop(struct rte_timer *tim)
> {
> return rte_timer_alt_stop(default_data_id, tim);
> }
> -MAP_STATIC_SYMBOL(int rte_timer_stop(struct rte_timer *tim),
> - rte_timer_stop_v1905);
> -BIND_DEFAULT_SYMBOL(rte_timer_stop, _v1905, 19.05);
>
> int
> rte_timer_alt_stop(uint32_t timer_data_id, struct rte_timer *tim)
> @@ -817,15 +756,8 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
> priv_timer[lcore_id].running_tim = NULL;
> }
>
> -void
> -rte_timer_manage_v20(void)
> -{
> - __rte_timer_manage(&default_timer_data);
> -}
> -VERSION_SYMBOL(rte_timer_manage, _v20, 2.0);
> -
> int
> -rte_timer_manage_v1905(void)
> +rte_timer_manage(void)
> {
> struct rte_timer_data *timer_data;
>
> @@ -835,8 +767,6 @@ rte_timer_manage_v1905(void)
>
> return 0;
> }
> -MAP_STATIC_SYMBOL(int rte_timer_manage(void), rte_timer_manage_v1905);
> -BIND_DEFAULT_SYMBOL(rte_timer_manage, _v1905, 19.05);
>
> int
> rte_timer_alt_manage(uint32_t timer_data_id,
> @@ -1074,21 +1004,11 @@ __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f)
> #endif
> }
>
> -void
> -rte_timer_dump_stats_v20(FILE *f)
> -{
> - __rte_timer_dump_stats(&default_timer_data, f);
> -}
> -VERSION_SYMBOL(rte_timer_dump_stats, _v20, 2.0);
> -
> int
> -rte_timer_dump_stats_v1905(FILE *f)
> +rte_timer_dump_stats(FILE *f)
> {
> return rte_timer_alt_dump_stats(default_data_id, f);
> }
> -MAP_STATIC_SYMBOL(int rte_timer_dump_stats(FILE *f),
> - rte_timer_dump_stats_v1905);
> -BIND_DEFAULT_SYMBOL(rte_timer_dump_stats, _v1905, 19.05);
>
> int
> rte_timer_alt_dump_stats(uint32_t timer_data_id __rte_unused, FILE *f)
> diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h
> index 05d287d8f2..9dc5fc3092 100644
> --- a/lib/librte_timer/rte_timer.h
> +++ b/lib/librte_timer/rte_timer.h
> @@ -181,8 +181,6 @@ int rte_timer_data_dealloc(uint32_t id);
> * subsystem
> */
> int rte_timer_subsystem_init(void);
> -int rte_timer_subsystem_init_v1905(void);
> -void rte_timer_subsystem_init_v20(void);
>
> /**
> * @warning
> @@ -250,13 +248,6 @@ void rte_timer_init(struct rte_timer *tim);
> int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
> enum rte_timer_type type, unsigned tim_lcore,
> rte_timer_cb_t fct, void *arg);
> -int rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
> - enum rte_timer_type type, unsigned int tim_lcore,
> - rte_timer_cb_t fct, void *arg);
> -int rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
> - enum rte_timer_type type, unsigned int tim_lcore,
> - rte_timer_cb_t fct, void *arg);
> -
>
> /**
> * Loop until rte_timer_reset() succeeds.
> @@ -313,8 +304,6 @@ rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
> * - (-1): The timer is in the RUNNING or CONFIG state.
> */
> int rte_timer_stop(struct rte_timer *tim);
> -int rte_timer_stop_v1905(struct rte_timer *tim);
> -int rte_timer_stop_v20(struct rte_timer *tim);
>
> /**
> * Loop until rte_timer_stop() succeeds.
> @@ -358,8 +347,6 @@ int rte_timer_pending(struct rte_timer *tim);
> * - -EINVAL: timer subsystem not yet initialized
> */
> int rte_timer_manage(void);
> -int rte_timer_manage_v1905(void);
> -void rte_timer_manage_v20(void);
>
> /**
> * Dump statistics about timers.
> @@ -371,8 +358,6 @@ void rte_timer_manage_v20(void);
> * - -EINVAL: timer subsystem not yet initialized
> */
> int rte_timer_dump_stats(FILE *f);
> -int rte_timer_dump_stats_v1905(FILE *f);
> -void rte_timer_dump_stats_v20(FILE *f);
>
> /**
> * @warning
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v6 0/4] doc: changes to abi policy introducing major abi versions
2019-10-21 9:50 5% ` [dpdk-dev] [PATCH v6 0/4] " Thomas Monjalon
@ 2019-10-21 10:10 10% ` Ray Kinsella
2019-10-21 14:38 5% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2019-10-21 10:10 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, stephen, bruce.richardson, ferruh.yigit, konstantin.ananyev,
jerinj, olivier.matz, nhorman, maxime.coquelin, john.mcnamara,
marko.kovacevic, hemant.agrawal, ktraynor, aconole
On 21/10/2019 10:50, Thomas Monjalon wrote:
> 27/09/2019 18:54, Ray Kinsella:
>> TL;DR abbreviation:
>> A major ABI version that all DPDK releases during a one year period
>> support. ABI versioning is managed at a project-level, in place of library-level
>> management. ABI changes to add new features are permitted, as long as ABI
>> compatibility with the major ABI version is maintained.
>>
>> Detail:
>> This patch introduces major ABI versions, supported for one year and released
>> aligned with the LTS release. This ABI version is then supported by all
>> subsequent releases within that one year period. The intention is that the one
>> year support period, will then be reviewed after the initial year with the
>> intention of lengthing the support period for the next ABI version.
>
> For the record, I would prefer a v7 saying it is a fixed period of time,
> being one year at first and should be longer next.
> Please don't state "supported for one year", which can be understood as a general truth.
Well I was very careful to only state an _intention_ to lengthen the fix period,
I though it prudent to avoid words like "should", as nothing is known until the year is behind us.
Where I used the word "support", I talk about "abi support".
I suggest rewording as follows:-
This patch introduces major ABI versions, released aligned with the LTS release,
maintained for one year through all subsequent releases within that one year period.
The intention is that the one year abi support period, will then be reviewed after
the initial year with the intention of lengthening the period for the next ABI version.
>
>> ABI changes that preserve ABI compatibility with the major ABI version are
>> permitted in subsequent releases. ABI changes, follow similar approval rules as
>> before with the additional gate of now requiring technical board approval. The
>> merging and release of ABI breaking changes would now be pushed to the
>> declaration of the next major ABI version.
>>
>> This change encourages developers to maintain ABI compatibility with the major
>> ABI version, by promoting a permissive culture around those changes that
>> preserve ABI compatibility. This approach begins to align DPDK with those
>> projects that declare major ABI versions (e.g. version 2.x, 3.x) and support
>> those versions for some period, typically two years or more.
>>
>> To provide an example of how this might work in practice:
>>
>> * DPDK v20 is declared as the supported ABI version for one year, aligned with
>> the DPDK v19.11 (LTS) release. All library sonames are updated to reflect the
>> new ABI version, e.g. librte_eal.so.20, librte_acl.so.20...
>> * DPDK v20.02 .. v20.08 releases are ABI compatible with the DPDK v20 ABI. ABI
>> changes are permitted from DPDK v20.02 onwards, with the condition that ABI
>> compatibility with DPDK v20 is preserved.
>> * DPDK v21 is declared as the new supported ABI version for two years, aligned
>> with the DPDK v20.11 (LTS) release. The DPDK v20 ABI is now depreciated,
>> library sonames are updated to v21 and ABI compatibility breaking changes may
>> be introduced.
>
> OK I agree with these explanations.
>
>
^ permalink raw reply [relevance 10%]
* Re: [dpdk-dev] [PATCH v6 1/4] doc: separate versioning.rst into version and policy
2019-10-01 12:50 3% ` Hemant Agrawal
@ 2019-10-21 9:53 0% ` Thomas Monjalon
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2019-10-21 9:53 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, stephen, bruce.richardson, ferruh.yigit, konstantin.ananyev,
jerinj, olivier.matz, nhorman, maxime.coquelin, john.mcnamara,
marko.kovacevic, hemant.agrawal, ktraynor, aconole
27/09/2019 18:54, Ray Kinsella:
> Separate versioning.rst into abi versioning and abi policy guidance, in
> preparation for adding more detail to the abi policy.
>
> Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
> ---
> --- /dev/null
> +++ b/doc/guides/contributing/abi_policy.rst
> @@ -0,0 +1,169 @@
> +.. SPDX-License-Identifier: BSD-3-Clause
> + Copyright 2018 The DPDK contributors
> +
> +.. abi_api_policy:
No need to add an anchor at the beginning of a file.
RsT syntax :doc: allows to refer to a .rst file.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 0/4] doc: changes to abi policy introducing major abi versions
@ 2019-10-21 9:50 5% ` Thomas Monjalon
2019-10-21 10:10 10% ` Ray Kinsella
2 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-10-21 9:50 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, stephen, bruce.richardson, ferruh.yigit, konstantin.ananyev,
jerinj, olivier.matz, nhorman, maxime.coquelin, john.mcnamara,
marko.kovacevic, hemant.agrawal, ktraynor, aconole
27/09/2019 18:54, Ray Kinsella:
> TL;DR abbreviation:
> A major ABI version that all DPDK releases during a one year period
> support. ABI versioning is managed at a project-level, in place of library-level
> management. ABI changes to add new features are permitted, as long as ABI
> compatibility with the major ABI version is maintained.
>
> Detail:
> This patch introduces major ABI versions, supported for one year and released
> aligned with the LTS release. This ABI version is then supported by all
> subsequent releases within that one year period. The intention is that the one
> year support period, will then be reviewed after the initial year with the
> intention of lengthing the support period for the next ABI version.
For the record, I would prefer a v7 saying it is a fixed period of time,
being one year at first and should be longer next.
Please don't state "supported for one year", which can be understood as a general truth.
> ABI changes that preserve ABI compatibility with the major ABI version are
> permitted in subsequent releases. ABI changes, follow similar approval rules as
> before with the additional gate of now requiring technical board approval. The
> merging and release of ABI breaking changes would now be pushed to the
> declaration of the next major ABI version.
>
> This change encourages developers to maintain ABI compatibility with the major
> ABI version, by promoting a permissive culture around those changes that
> preserve ABI compatibility. This approach begins to align DPDK with those
> projects that declare major ABI versions (e.g. version 2.x, 3.x) and support
> those versions for some period, typically two years or more.
>
> To provide an example of how this might work in practice:
>
> * DPDK v20 is declared as the supported ABI version for one year, aligned with
> the DPDK v19.11 (LTS) release. All library sonames are updated to reflect the
> new ABI version, e.g. librte_eal.so.20, librte_acl.so.20...
> * DPDK v20.02 .. v20.08 releases are ABI compatible with the DPDK v20 ABI. ABI
> changes are permitted from DPDK v20.02 onwards, with the condition that ABI
> compatibility with DPDK v20 is preserved.
> * DPDK v21 is declared as the new supported ABI version for two years, aligned
> with the DPDK v20.11 (LTS) release. The DPDK v20 ABI is now depreciated,
> library sonames are updated to v21 and ABI compatibility breaking changes may
> be introduced.
OK I agree with these explanations.
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v6 RESEND] eal: add tsc_hz to rte_mem_config
2019-10-08 8:38 0% ` Bruce Richardson
@ 2019-10-21 8:23 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-21 8:23 UTC (permalink / raw)
To: Jim Harris; +Cc: dev, Bruce Richardson, Burakov, Anatoly
On Tue, Oct 8, 2019 at 10:39 AM Bruce Richardson
<bruce.richardson@intel.com> wrote:
>
> On Mon, Oct 07, 2019 at 08:28:21AM -0700, Jim Harris wrote:
> > This ensures secondary processes never have to
> > calculate the TSC rate themselves, which can be
> > noticeable in VMs that don't have access to
> > arch-specific detection mechanism (such as
> > CPUID leaf 0x15 or MSR 0xCE on x86).
> >
> > Since rte_mem_config is now internal to the rte_eal
> > library, we can add tsc_hz without ABI breakage
> > concerns.
> >
> > Reduces rte_eal_init() execution time in a secondary
> > process from 165ms to 66ms on my test system.
> >
> > Signed-off-by: Jim Harris <james.r.harris@intel.com>
> > ---
> This seems a good idea to me.
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
I wonder if we can get rid of eal_tsc_resolution_hz and just rely on
the shared memory to get/store this info.
Feel free to look at this later and send a followup patch :-).
Applied, thanks.
--
David Marchand
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v7 00/13] vhost packed ring performance optimization
2019-10-15 16:07 3% ` [dpdk-dev] [PATCH v6 " Marvin Liu
2019-10-17 7:31 0% ` Maxime Coquelin
@ 2019-10-21 15:40 3% ` Marvin Liu
2019-10-21 22:08 3% ` [dpdk-dev] [PATCH v8 " Marvin Liu
1 sibling, 1 reply; 200+ results
From: Marvin Liu @ 2019-10-21 15:40 UTC (permalink / raw)
To: maxime.coquelin, tiwei.bie, zhihong.wang, stephen, gavin.hu
Cc: dev, Marvin Liu
Packed ring has more compact ring format and thus can significantly
reduce the number of cache miss. It can lead to better performance.
This has been approved in virtio user driver, on normal E5 Xeon cpu
single core performance can raise 12%.
http://mails.dpdk.org/archives/dev/2018-April/095470.html
However vhost performance with packed ring performance was decreased.
Through analysis, mostly extra cost was from the calculating of each
descriptor flag which depended on ring wrap counter. Moreover, both
frontend and backend need to write same descriptors which will cause
cache contention. Especially when doing vhost enqueue function, virtio
refill packed ring function may write same cache line when vhost doing
enqueue function. This kind of extra cache cost will reduce the benefit
of reducing cache misses.
For optimizing vhost packed ring performance, vhost enqueue and dequeue
function will be splitted into fast and normal path.
Several methods will be taken in fast path:
Handle descriptors in one cache line by batch.
Split loop function into more pieces and unroll them.
Prerequisite check that whether I/O space can copy directly into mbuf
space and vice versa.
Prerequisite check that whether descriptor mapping is successful.
Distinguish vhost used ring update function by enqueue and dequeue
function.
Buffer dequeue used descriptors as many as possible.
Update enqueue used descriptors by cache line.
After all these methods done, single core vhost PvP performance with 64B
packet on Xeon 8180 can boost 35%.
v7:
- Rebase code
- Rename unroll macro and definitions
- Calculate flags when doing single dequeue
v6:
- Fix dequeue zcopy result check
v5:
- Remove disable sw prefetch as performance impact is small
- Change unroll pragma macro format
- Rename shadow counter elements names
- Clean dequeue update check condition
- Add inline functions replace of duplicated code
- Unify code style
v4:
- Support meson build
- Remove memory region cache for no clear performance gain and ABI break
- Not assume ring size is power of two
v3:
- Check available index overflow
- Remove dequeue remained descs number check
- Remove changes in split ring datapath
- Call memory write barriers once when updating used flags
- Rename some functions and macros
- Code style optimization
v2:
- Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
- Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
- Optimize dequeue used ring update when in_order negotiated
Marvin Liu (13):
vhost: add packed ring indexes increasing function
vhost: add packed ring single enqueue
vhost: try to unroll for each loop
vhost: add packed ring batch enqueue
vhost: add packed ring single dequeue
vhost: add packed ring batch dequeue
vhost: flush enqueue updates by cacheline
vhost: flush batched enqueue descs directly
vhost: buffer packed ring dequeue updates
vhost: optimize packed ring enqueue
vhost: add packed ring zcopy batch and single dequeue
vhost: optimize packed ring dequeue
vhost: optimize packed ring dequeue when in-order
lib/librte_vhost/Makefile | 18 +
lib/librte_vhost/meson.build | 7 +
lib/librte_vhost/vhost.h | 57 ++
lib/librte_vhost/virtio_net.c | 945 +++++++++++++++++++++++++++-------
4 files changed, 834 insertions(+), 193 deletions(-)
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC] ethdev: add new fields for max LRO session size
2019-10-18 16:35 0% ` Ferruh Yigit
@ 2019-10-18 18:05 0% ` Ananyev, Konstantin
2019-10-22 12:56 0% ` Andrew Rybchenko
1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-18 18:05 UTC (permalink / raw)
To: Yigit, Ferruh, Thomas Monjalon, Matan Azrad
Cc: dev, Andrew Rybchenko, Olivier Matz
> -----Original Message-----
> From: Yigit, Ferruh
> Sent: Friday, October 18, 2019 5:36 PM
> To: Thomas Monjalon <thomas@monjalon.net>; Matan Azrad <matan@mellanox.com>
> Cc: dev@dpdk.org; Andrew Rybchenko <arybchenko@solarflare.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Olivier Matz
> <olivier.matz@6wind.com>
> Subject: Re: [RFC] ethdev: add new fields for max LRO session size
>
> On 10/2/2019 2:58 PM, Thomas Monjalon wrote:
> > 24/09/2019 14:03, Matan Azrad:
> >> From: Ferruh Yigit
> >>> On 9/15/2019 8:48 AM, Matan Azrad wrote:
> >>>> Hi Ferruh
> >>>>
> >>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
> >>>>> On 8/29/2019 8:47 AM, Matan Azrad wrote:
> >>>>>> It may be needed by the user to limit the LRO session packet size.
> >>>>>> In order to allow the above limitation, add new Rx configuration for
> >>>>>> the maximum LRO session size.
> >>>>>>
> >>>>>> In addition, Add a new capability to expose the maximum LRO session
> >>>>>> size supported by the port.
> >>>>>>
> >>>>>> Signed-off-by: Matan Azrad <matan@mellanox.com>
> >>>>>
> >>>>> Hi Matan,
> >>>>>
> >>>>> Is there any existing user of this new field?
> >>>>
> >>>> All the LRO users need it due to the next reasons:
> >>>>
> >>>> 1. If scatter is enabled - The dpdk user can limit the LRO session size created
> >>> by the HW by this field, if no field like that - there is no way to limit it.
> >>>> 2. No scatter - the dpdk user may want to limit the LRO packet size in order
> >>> to save enough tail-room in the mbuf for its own usage.
> >>>> 3. The limitation of max_rx_pkt_len is not enough - doesn't make sense to
> >>> limit LRO traffic as single packet.
> >>>>
> >>>
> >>> So should there be more complement patches to this RFC? To update the
> >>> users of the field with the new field.
> >>
> >>
> >> We already exposed it as ABI breakage in the last deprecation notice.
> >> We probably cannot complete it for 19.11 version, hopefully for 20.02 it will be completed.
> >
> > We won't break the ABI in 20.02.
> > What should be done in 19.11?
> >
>
> The ask was to add code that uses new added fields, this patch only adds new
> field to two public ethdev struct.
>
> @Thomas, @Andrew, if this patch doesn't goes it on this release it will have to
> wait a year. I would like to see the implementation but it is not there, what is
> your comment?
Just a side note, if I am not mistaken, there is a 6B gap in eth_rxmode:
struct rte_eth_rxmode {
/** The multi-queue packet distribution mode to be used, e.g. RSS. */
enum rte_eth_rx_mq_mode mq_mode;
uint32_t max_rx_pkt_len; /**< Only used if JUMBO_FRAME enabled. */
uint16_t split_hdr_size; /**< hdr buf size (header_split enabled).*/ <---- offset 8
/**
* Per-port Rx offloads to be set using DEV_RX_OFFLOAD_* flags.
* Only offloads set on rx_offload_capa field on rte_eth_dev_info
* structure are allowed to be set.
*/
uint64_t offloads; <--- offset 16
};
So we can reserve these 6B, and then reuse for LRO, or whatever.
Might be it would help somehow.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/3] vhost: call vDPA callback at the end of vring enable handler
@ 2019-10-18 16:54 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-18 16:54 UTC (permalink / raw)
To: Tiwei Bie, Andy Pei
Cc: dev, rosen.xu, xiaolong.ye, xiao.w.wang, maxime.coquelin, zhihong.wang
On 9/23/2019 9:12 AM, Tiwei Bie wrote:
> On Tue, Sep 17, 2019 at 05:09:47PM +0800, Andy Pei wrote:
>> vDPA's set_vring_state callback would need to know the virtqueues'
>> enable status to configure the hardware.
>>
>> Signed-off-by: Xiaolong Ye <xiaolong.ye@intel.com>
>> Signed-off-by: Andy Pei <andy.pei@intel.com>
>> ---
>> v2:
>> add nr_active_vring as a parameter to ops function set_vring_state in
>> case of callback in set_vring_state() and avoid exposing new API.
>>
>> lib/librte_vhost/rte_vdpa.h | 4 ++--
>> lib/librte_vhost/vhost_user.c | 27 +++++++++++++++++++++++++--
>> 2 files changed, 27 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/librte_vhost/rte_vdpa.h b/lib/librte_vhost/rte_vdpa.h
>> index 9a3deb3..6e55d4d 100644
>> --- a/lib/librte_vhost/rte_vdpa.h
>> +++ b/lib/librte_vhost/rte_vdpa.h
>> @@ -54,8 +54,8 @@ struct rte_vdpa_dev_ops {
>> int (*dev_conf)(int vid);
>> int (*dev_close)(int vid);
>>
>> - /** Enable/disable this vring */
>> - int (*set_vring_state)(int vid, int vring, int state);
>> + /** Enable/disable vring queue pairs */
>> + int (*set_vring_state)(int vid, int nr_active_vring);
>
> We should avoid changing the API/ABI unless we have a very good
> justification.
>
> With the existing API, it should be easy to get the number of
> active rings by maintaining a bitmap or something similar in
> ifc driver.
>
> Besides, please keep other maintainers got from get-maintainer.sh
> in the Cc list as well.
>
updating patchset [1] as "Change Requested" based on above comment.
[1]
https://patches.dpdk.org/user/todo/dpdk/?series=6424&delegate=319&state=*
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC] ethdev: add new fields for max LRO session size
2019-10-02 13:58 3% ` Thomas Monjalon
@ 2019-10-18 16:35 0% ` Ferruh Yigit
2019-10-18 18:05 0% ` Ananyev, Konstantin
2019-10-22 12:56 0% ` Andrew Rybchenko
0 siblings, 2 replies; 200+ results
From: Ferruh Yigit @ 2019-10-18 16:35 UTC (permalink / raw)
To: Thomas Monjalon, Matan Azrad
Cc: dev, Andrew Rybchenko, Konstantin Ananyev, Olivier Matz
On 10/2/2019 2:58 PM, Thomas Monjalon wrote:
> 24/09/2019 14:03, Matan Azrad:
>> From: Ferruh Yigit
>>> On 9/15/2019 8:48 AM, Matan Azrad wrote:
>>>> Hi Ferruh
>>>>
>>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
>>>>> On 8/29/2019 8:47 AM, Matan Azrad wrote:
>>>>>> It may be needed by the user to limit the LRO session packet size.
>>>>>> In order to allow the above limitation, add new Rx configuration for
>>>>>> the maximum LRO session size.
>>>>>>
>>>>>> In addition, Add a new capability to expose the maximum LRO session
>>>>>> size supported by the port.
>>>>>>
>>>>>> Signed-off-by: Matan Azrad <matan@mellanox.com>
>>>>>
>>>>> Hi Matan,
>>>>>
>>>>> Is there any existing user of this new field?
>>>>
>>>> All the LRO users need it due to the next reasons:
>>>>
>>>> 1. If scatter is enabled - The dpdk user can limit the LRO session size created
>>> by the HW by this field, if no field like that - there is no way to limit it.
>>>> 2. No scatter - the dpdk user may want to limit the LRO packet size in order
>>> to save enough tail-room in the mbuf for its own usage.
>>>> 3. The limitation of max_rx_pkt_len is not enough - doesn't make sense to
>>> limit LRO traffic as single packet.
>>>>
>>>
>>> So should there be more complement patches to this RFC? To update the
>>> users of the field with the new field.
>>
>>
>> We already exposed it as ABI breakage in the last deprecation notice.
>> We probably cannot complete it for 19.11 version, hopefully for 20.02 it will be completed.
>
> We won't break the ABI in 20.02.
> What should be done in 19.11?
>
The ask was to add code that uses new added fields, this patch only adds new
field to two public ethdev struct.
@Thomas, @Andrew, if this patch doesn't goes it on this release it will have to
wait a year. I would like to see the implementation but it is not there, what is
your comment?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-16 22:07 3% ` Ananyev, Konstantin
2019-10-17 12:49 0% ` Ananyev, Konstantin
@ 2019-10-18 13:17 4% ` Akhil Goyal
2019-10-21 13:47 4% ` Ananyev, Konstantin
1 sibling, 1 reply; 200+ results
From: Akhil Goyal @ 2019-10-18 13:17 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph', Hemant Agrawal
Hi Konstantin,
Added my comments inline with your draft.
>
>
> Hi Akhil,
>
> > > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > > construct for multiple device_ids:
> > > __extension__ struct {
> > > void *data;
> > > uint16_t refcnt;
> > > } sess_data[0];
> > > /**< Driver specific session material, variable size */
> > >
> > Yes I also feel the same. I was also not in favor of this when it was introduced.
> > Please go ahead and remove this. I have no issues with that.
>
> If you are not happy with that structure, and admit there are issues with it,
> why do you push for reusing it for cpu-crypto API?
> Why not to take step back, take into account current drawbacks
> and define something that (hopefully) would suite us better?
> Again new API will be experimental for some time, so we'll
> have some opportunity to see does it works and if not fix it.
[Akhil] This structure is serving some use case which is agreed upon in the
Community, we cannot just remove a feature altogether. Rather it is Intel's
Use case only.
>
> About removing data[] from existing rte_cryptodev_sym_session -
> Personally would like to do that, but the change seems to be too massive.
> Definitely not ready for such effort right now.
>
[snip]..
>
> Ok, then my suggestion:
> Let's at least write down all points about crypto-dev approach where we
> disagree and then probably try to resolve them one by one....
> If we fail to make an agreement/progress in next week or so,
> (and no more reviews from the community)
> will have bring that subject to TB meeting to decide.
> Sounds fair to you?
Agreed
>
> List is below.
> Please add/correct me, if I missed something.
>
> Konstantin
Before going into comparison, we should define the requirement as well.
What I understood from the patchset,
"You need a synchronous API to perform crypto operations on raw data using SW PMDs"
So,
- no crypto-ops,
- no separate enq-deq, only single process API for data path
- Do not need any value addition to the session parameters.
(You would need some parameters from the crypto-op which
Are constant per session and since you wont use crypto-op,
You need some place to store that)
Now as per your mail, the comparison
1. extra input parameters to create/init rte_(cpu)_sym_session.
Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and 'key' fields.
New fields will be optional and would be used by PMD only when cpu-crypto session is requested.
For lksd-crypto session PMD is free to ignore these fields.
No ABI breakage is required.
[Akhil] Agreed, no issues.
2. cpu-crypto create/init.
a) Our suggestion - introduce new API for that:
- rte_crypto_cpu_sym_init() that would init completely opaque rte_crypto_cpu_sym_session.
- struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear); /*whatever else we'll need *'};
- rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform *xforms)
that would return const struct rte_crypto_cpu_sym_session_ops *based on input xforms.
Advantages:
1) totally opaque data structure (no ABI breakages in future), PMD writer is totally free
with it format and contents.
[Akhil] It will have breakage at some point till we don't hit the union size.
Rather I don't suspect there will be more parameters added.
Or do we really care about the ABI breakage when the argument is about
the correct place to add a piece of code or do we really agree to add code
anywhere just to avoid that breakage.
2) each session entity is self-contained, user doesn't need to bring along dev_id etc.
dev_id is needed only at init stage, after that user will use session ops to perform
all operations on that session (process(), clear(), etc.).
[Akhil] There is nothing called as session ops in current DPDK. What you are proposing
is a new concept which doesn't have any extra benefit, rather it is adding complexity
to have two different code paths for session create.
3) User can decide does he wants to store ops[] pointer on a per session basis,
or on a per group of same sessions, or...
[Akhil] Will the user really care which process API should be called from the PMD.
Rather it should be driver's responsibility to store that in the session private data
which would be opaque to the user. As per my suggestion same process function can
be added to multiple sessions or a single session can be managed inside the PMD.
4) No mandatory mempools for private sessions. User can allocate memory for cpu-crypto
session whenever he likes.
[Akhil] you mean session private data? You would need that memory anyways, user will be
allocating that already. You do not need to manage that.
Disadvantages:
5) Extra changes in control path
6) User has to store session_ops pointer explicitly.
[Akhil] More disadvantages:
- All supporting PMDs will need to maintain TWO types of session for the
same crypto processing. Suppose a fix or a new feature(or algo) is added, PMD owner
will need to add code in both the session create APIs. Hence more maintenance and
error prone.
- Stacks which will be using these new APIs also need to maintain two
code path for the same processing while doing session initialization
for sync and async
b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and existing rte_cryptodev_sym_session
structure.
Advantages:
1) allows to reuse same struct and init/create/clear() functions.
Probably less changes in control path.
Disadvantages:
2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means that
we can't use the same rte_cryptodev_sym_session to hold private sessions pointers
for both sync and async mode for the same device.
So the only option we have - make PMD devops->sym_session_configure()
always create a session that can work in both cpu and lksd modes.
For some implementations that would probably mean that under the hood PMD would create
2 different session structs (sync/async) and then use one or another depending on from what API been called.
Seems doable, but ...:
- will contradict with statement from 1:
" New fields will be optional and would be used by PMD only when cpu-crypto session is requested."
Now it becomes mandatory for all apps to specify cpu-crypto related parameters too,
even if they don't plan to use that mode - i.e. behavior change, existing app change.
- might cause extra space overhead.
[Akhil] It will not contradict with #1, you will only have few checks in the session init PMD
Which support this mode, find appropriate values and set the appropriate process() in it.
User should be able to call, legacy enq-deq as well as the new process() without any issue.
User would be at runtime will be able to change the datapath.
So this is not a disadvantage, it would be additional flexibility for the user.
3) not possible to store device (not driver) specific data within the session, but I think it is not really needed right now.
So probably minor compared to 2.b.2.
[Akhil] So lets omit this for current discussion. And I hope we can find some way to deal with it.
Actually #3 follows from #2, but decided to have them separated.
3. process() parameters/behavior
a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and just does:
session_ops->process(sess, ...);
Advantages:
1) fastest possible execution path
2) no need to carry on dev_id for data-path
[Akhil] I don't see any overhead of carrying dev id, at least it would be inline with the
current DPDK methodology.
What you are suggesting is a new way to get the things done without much benefit.
Also I don't see any performance difference as crypto workload is heavier than
Code cycles, so that wont matter.
So IMO, there is no advantage in your suggestion as well.
Disadvantages:
3) user has to carry on session_ops pointer explicitly
b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session *sess, /*data parameters*/) {...
rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
/*and then inside PMD specifc process: */
pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
/* and then most likely either */
pmd_private_session->process(pmd_private_session, ...);
/* or jump based on session/input data */
Advantages:
1) don't see any...
Disadvantages:
2) User has to carry on dev_id inside data-path
3) Extra level of indirection (plus data dependency) - both for data and instructions.
Possible slowdown compared to a) (not measured).
Having said all this, if the disagreements cannot be resolved, you can go for a pmd API specific
to your PMDs, because as per my understanding the solution doesn't look scalable to other PMDs.
Your approach is aligned only to Intel, will not benefit others like openssl which is used by all
vendors.
Regards,
Akhil
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-18 9:47 0% ` Olivier Matz
@ 2019-10-18 11:24 0% ` Wang, Haiyue
0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2019-10-18 11:24 UTC (permalink / raw)
To: Olivier Matz
Cc: dev, Andrew Rybchenko, Richardson, Bruce,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Friday, October 18, 2019 17:48
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org; Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: Re: [PATCH v2] mbuf: support dynamic fields and flags
>
> On Fri, Oct 18, 2019 at 08:28:02AM +0000, Wang, Haiyue wrote:
> > Hi Olivier,
> >
> > > -----Original Message-----
> > > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > > Sent: Friday, October 18, 2019 15:54
> > > To: Wang, Haiyue <haiyue.wang@intel.com>
> > > Cc: dev@dpdk.org; Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > > <thomas@monjalon.net>
> > > Subject: Re: [PATCH v2] mbuf: support dynamic fields and flags
> > >
> > > Hi Haiyue,
> > >
> > > On Fri, Oct 18, 2019 at 02:47:50AM +0000, Wang, Haiyue wrote:
> > > > Hi Olivier
> > > >
> > > > > -----Original Message-----
> > > > > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > > > > Sent: Thursday, October 17, 2019 22:42
> > > > > To: dev@dpdk.org
> > > > > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce
> <bruce.richardson@intel.com>;
> > > Wang,
> > > > > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > > > > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > > > > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > > > > <thomas@monjalon.net>
> > > > > Subject: [PATCH v2] mbuf: support dynamic fields and flags
> > > > >
> > > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > > structure is limited, it is not possible to have a field for each
> > > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > > or ABI.
> > > > >
> > > > > This commit addresses these issues, by enabling the dynamic registration
> > > > > of fields or flags:
> > > > >
> > > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > > given size (>= 1 byte) and alignment constraint.
> > > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > > >
> > > > > The typical use case is a PMD that registers space for an offload
> > > > > feature, when the application requests to enable this feature. As
> > > > > the space in mbuf is limited, the space should only be reserved if it
> > > > > is going to be used (i.e when the application explicitly asks for it).
> > > > >
> > > > > The registration can be done at any moment, but it is not possible
> > > > > to unregister fields or flags for now.
> > > > >
> > > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > > > ---
> > > > >
> > > > > v2
> > > > >
> > > > > * Rebase on top of master: solve conflict with Stephen's patchset
> > > > > (packet copy)
> > > > > * Add new apis to register a dynamic field/flag at a specific place
> > > > > * Add a dump function (sugg by David)
> > > > > * Enhance field registration function to select the best offset, keeping
> > > > > large aligned zones as much as possible (sugg by Konstantin)
> > > > > * Use a size_t and unsigned int instead of int when relevant
> > > > > (sugg by Konstantin)
> > > > > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > > > > (sugg by Konstantin)
> > > > > * Remove unused argument in private function (sugg by Konstantin)
> > > > > * Fix and simplify locking (sugg by Konstantin)
> > > > > * Fix minor typo
> > > > >
> > > > > rfc -> v1
> > > > >
> > > > > * Rebase on top of master
> > > > > * Change registration API to use a structure instead of
> > > > > variables, getting rid of #defines (Stephen's comment)
> > > > > * Update flag registration to use a similar API as fields.
> > > > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > > > * Add a debug log at registration
> > > > > * Add some words in release note
> > > > > * Did some performance tests (sugg. by Andrew):
> > > > > On my platform, reading a dynamic field takes ~3 cycles more
> > > > > than a static field, and ~2 cycles more for writing.
> > > > >
> > > > > app/test/test_mbuf.c | 145 ++++++-
> > > > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > > > lib/librte_mbuf/Makefile | 2 +
> > > > > lib/librte_mbuf/meson.build | 6 +-
> > > > > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > > > > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > > > > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > > > > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > > > > 8 files changed, 959 insertions(+), 5 deletions(-)
> > > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > > > >
> > > > > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > > > > index b9c2b2500..01cafad59 100644
> > > > > --- a/app/test/test_mbuf.c
> > > > > +++ b/app/test/test_mbuf.c
> > > > > @@ -28,6 +28,7 @@
> > > > > #include <rte_random.h>
> > > >
> > > > [snip]
> > > >
> > > > > +/**
> > > > > + * Helper macro to access to a dynamic field.
> > > > > + */
> > > > > +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> > > > > +
> > > >
> > > > The suggested macro is missed ? ;-)
> > > > /**
> > > > * Helper macro to access to a dynamic flag.
> > > > */
> > > > #define RTE_MBUF_DYNFLAG(offset) (1ULL << (offset))
> > >
> > > Yes, sorry.
> > >
> > > Thinking a bit more about it, I wonder if the macros below aren't
> > > more consistent with the dynamic field (because they take the mbuf
> > > as parameter)?
> > >
> > > #define RTE_MBUF_SET_DYNFLAG(m, bitnum, val) ...
> > > #define RTE_MBUF_GET_DYNFLAG(m, bitnum) ...
> > >
> > > They could even be static inline functions.
> > >
> > > On the other hand, these helpers would be generic to ol_flags, not only
> > > for dynamic flags. Today, we use (1ULL << bit) for ol_flags, which makes
> > > me wonder... is the macro really needed after all? :)
> > >
> >
> > I used as this:
> > 1). in PMD:
> > mb->ol_flags |= RTE_MBUF_DYNFLAG(ol_offset);
> >
> >
> > 2). In testpmd
> > if (mb->ol_flags & RTE_MBUF_DYNFLAG(ol_offset))
> > ...
> >
> > The above two macros look better in real use.
>
> I just looked at http://patchwork.dpdk.org/patch/60908/
> In the patch, a mask is used instead of a bit number, which is indeed
> better in terms of performance. This makes the macro not that useful,
> given there is a specific helper.
>
'a mask is used instead of a bit number' good practice, yes, then no need
this macro, thanks for sharing. ;-)
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v11 1/3] eal/arm64: add 128-bit atomic compare exchange
2019-10-15 11:38 2% ` [dpdk-dev] [PATCH v10 " Phil Yang
@ 2019-10-18 11:21 4% ` Phil Yang
0 siblings, 0 replies; 200+ results
From: Phil Yang @ 2019-10-18 11:21 UTC (permalink / raw)
To: david.marchand, jerinj, gage.eads, dev
Cc: thomas, hemant.agrawal, Honnappa.Nagarahalli, gavin.hu, nd
This patch adds the implementation of the 128-bit atomic compare
exchange API on AArch64. Using 64-bit 'ldxp/stxp' instructions
can perform this operation. Moreover, on the LSE atomic extension
accelerated platforms, it implemented by 'casp' instructions for
better performance.
Since the '__ARM_FEATURE_ATOMICS' flag only supports GCC-9, so this
patch adds a new config flag 'RTE_ARM_FEATURE_ATOMICS' to enable the
'cas' version on elder version compilers.
Since direct x0 register used in the code and cas_op_name() and
rte_atomic128_cmp_exchange() is inline function, based on parent
function load, it may corrupt x0 register aka Break arm64 ABI.
Define CAS operations as rte_noinline functions to avoid the ABI
break[1].
[1]5b40ec6b9662 ("mempool/octeontx2: fix possible arm64 ABI break").
Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---
v11:
1. Renamed cas_op_name by adding the data width tag 128.
2. Replaced __ldx/__stx inline functions with macros.
3. Illustrate the reason of define cas operations as non-inline
functions in commitlog.
v10:
1.Removed all the rte tag for internal functions.
2.Removed __MO_LOAD and _MO_STORE macros and keep define __HAS_ACQ
and __HAS_REL under non LSE conditional branch.
3.Undef the macro once it is unused.
4.Reword the 1/3 and 2/3 patches' commitlog more specific.
v9:
Updated 19.11 release note.
v8:
Fixed "WARNING:LONG_LINE: line over 80 characters" warnings with latest kernel
checkpatch.pl
v7:
1. Adjust code comment.
v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.
v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git
commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)
v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions.
(Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin
Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage
Eads/Jerin Jocob)
v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)
v2:
Initial version.
config/arm/meson.build | 2 +
config/common_base | 3 +
config/defconfig_arm64-octeontx2-linuxapp-gcc | 1 +
config/defconfig_arm64-thunderx2-linuxapp-gcc | 1 +
.../common/include/arch/arm/rte_atomic_64.h | 151 +++++++++++++++++++++
.../common/include/arch/x86/rte_atomic_64.h | 12 --
lib/librte_eal/common/include/generic/rte_atomic.h | 17 ++-
7 files changed, 174 insertions(+), 13 deletions(-)
diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..9f28271 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
['RTE_CACHE_LINE_SIZE', 64],
['RTE_MAX_NUMA_NODES', 2],
['RTE_MAX_LCORE', 256],
+ ['RTE_ARM_FEATURE_ATOMICS', true],
['RTE_USE_C11_MEM_MODEL', true]]
flags_octeontx2_extra = [
['RTE_MACHINE', '"octeontx2"'],
['RTE_MAX_NUMA_NODES', 1],
['RTE_MAX_LCORE', 24],
+ ['RTE_ARM_FEATURE_ATOMICS', true],
['RTE_EAL_IGB_UIO', false],
['RTE_USE_C11_MEM_MODEL', true]]
diff --git a/config/common_base b/config/common_base
index e843a21..a96beb9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
CONFIG_RTE_MAX_NUMA_NODES=8
CONFIG_RTE_MAX_HEAPS=32
CONFIG_RTE_MAX_MEMSEG_LISTS=64
+
+# Use ARM LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
# each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
# or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..7687dbe 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
CONFIG_RTE_CACHE_LINE_SIZE=128
CONFIG_RTE_MAX_NUMA_NODES=1
CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
# Doesn't support NUMA
CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..af4a89c 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
CONFIG_RTE_CACHE_LINE_SIZE=64
CONFIG_RTE_MAX_NUMA_NODES=2
CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..d9ebccc 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
*/
#ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
#endif
#include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
#define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,153 @@ extern "C" {
#define rte_cio_rmb() dmb(oshld)
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string) \
+static __rte_noinline rte_int128_t \
+cas_op_name(rte_int128_t *dst, rte_int128_t old, \
+ rte_int128_t updated) \
+{ \
+ /* caspX instructions register pair must start from even-numbered
+ * register at operand 1.
+ * So, specify registers for local variables here.
+ */ \
+ register uint64_t x0 __asm("x0") = (uint64_t)old.val[0]; \
+ register uint64_t x1 __asm("x1") = (uint64_t)old.val[1]; \
+ register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0]; \
+ register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1]; \
+ asm volatile( \
+ op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]" \
+ : [old0] "+r" (x0), \
+ [old1] "+r" (x1) \
+ : [upd0] "r" (x2), \
+ [upd1] "r" (x3), \
+ [dst] "r" (dst) \
+ : "memory"); \
+ old.val[0] = x0; \
+ old.val[1] = x1; \
+ return old; \
+}
+
+__ATOMIC128_CAS_OP(__cas_128_relaxed, "casp")
+__ATOMIC128_CAS_OP(__cas_128_acquire, "caspa")
+__ATOMIC128_CAS_OP(__cas_128_release, "caspl")
+__ATOMIC128_CAS_OP(__cas_128_acq_rel, "caspal")
+
+#undef __ATOMIC128_CAS_OP
+
+#endif
+
+__rte_experimental
+static inline int
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+ rte_int128_t *exp,
+ const rte_int128_t *src,
+ unsigned int weak,
+ int success,
+ int failure)
+{
+ /* Always do strong CAS */
+ RTE_SET_USED(weak);
+ /* Ignore memory ordering for failure, memory order for
+ * success must be stronger or equal
+ */
+ RTE_SET_USED(failure);
+ /* Find invalid memory order */
+ RTE_ASSERT(success == __ATOMIC_RELAXED
+ || success == __ATOMIC_ACQUIRE
+ || success == __ATOMIC_RELEASE
+ || success == __ATOMIC_ACQ_REL
+ || success == __ATOMIC_SEQ_CST);
+
+ rte_int128_t expected = *exp;
+ rte_int128_t desired = *src;
+ rte_int128_t old;
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+ if (success == __ATOMIC_RELAXED)
+ old = __cas_128_relaxed(dst, expected, desired);
+ else if (success == __ATOMIC_ACQUIRE)
+ old = __cas_128_acquire(dst, expected, desired);
+ else if (success == __ATOMIC_RELEASE)
+ old = __cas_128_release(dst, expected, desired);
+ else
+ old = __cas_128_acq_rel(dst, expected, desired);
+#else
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+ (mo) == __ATOMIC_SEQ_CST)
+
+ int ldx_mo = __HAS_ACQ(success) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED;
+ int stx_mo = __HAS_RLS(success) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED;
+
+#undef __HAS_ACQ
+#undef __HAS_RLS
+
+ uint32_t ret = 1;
+
+ /* ldx128 can not guarantee atomic,
+ * Must write back src or old to verify atomicity of ldx128;
+ */
+ do {
+
+#define __LOAD_128(op_string, src, dst) {\
+ asm volatile( \
+ op_string " %0, %1, %2" \
+ : "=&r" (dst.val[0]), \
+ "=&r" (dst.val[1]) \
+ : "Q" (src->val[0]) \
+ : "memory"); }
+
+ if (ldx_mo == __ATOMIC_RELAXED)
+ __LOAD_128("ldxp", dst, old)
+ else
+ __LOAD_128("ldaxp", dst, old)
+
+#undef __LOAD_128
+
+#define __STORE_128(op_string, dst, src, ret) {\
+ asm volatile( \
+ op_string " %w0, %1, %2, %3" \
+ : "=&r" (ret) \
+ : "r" (src.val[0]), \
+ "r" (src.val[1]), \
+ "Q" (dst->val[0]) \
+ : "memory"); }
+
+ if (likely(old.int128 == expected.int128)) {
+ if (stx_mo == __ATOMIC_RELAXED)
+ __STORE_128("stxp", dst, desired, ret)
+ else
+ __STORE_128("stlxp", dst, desired, ret)
+ } else {
+ /* In the failure case (since 'weak' is ignored and only
+ * weak == 0 is implemented), expected should contain
+ * the atomically read value of dst. This means, 'old'
+ * needs to be stored back to ensure it was read
+ * atomically.
+ */
+ if (stx_mo == __ATOMIC_RELAXED)
+ __STORE_128("stxp", dst, old, ret)
+ else
+ __STORE_128("stlxp", dst, old, ret)
+ }
+#undef __STORE_128
+
+ } while (unlikely(ret));
+#endif
+
+ /* Unconditionally updating expected removes
+ * an 'if' statement.
+ * expected should already be in register if
+ * not in the cache.
+ */
+ *exp = old;
+
+ return (old.int128 == expected.int128);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index 1335d92..cfe7067 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -183,18 +183,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
/*------------------------ 128 bit atomic operations -------------------------*/
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
- RTE_STD_C11
- union {
- uint64_t val[2];
- __extension__ __int128 int128;
- };
-} __rte_aligned(16) rte_int128_t;
-
__rte_experimental
static inline int
rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
/*------------------------ 128 bit atomic operations -------------------------*/
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+ RTE_STD_C11
+ union {
+ uint64_t val[2];
+#ifdef RTE_ARCH_64
+ __extension__ __int128 int128;
+#endif
+ };
+} __rte_aligned(16) rte_int128_t;
+
#ifdef __DOXYGEN__
/**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
* *exp = *dst
* @endcode
*
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
*
* @note The success and failure arguments must be one of the __ATOMIC_* values
* defined in the C++11 standard. For details on their behavior, refer to the
--
2.7.4
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-17 14:09 8% ` Luca Boccassi
2019-10-17 14:12 4% ` Bruce Richardson
@ 2019-10-18 10:07 7% ` Kevin Traynor
1 sibling, 0 replies; 200+ results
From: Kevin Traynor @ 2019-10-18 10:07 UTC (permalink / raw)
To: Luca Boccassi, Bruce Richardson, Anatoly Burakov,
Christian Ehrhardt, Timothy Redaelli
Cc: dev, Marcin Baran, Thomas Monjalon, john.mcnamara,
david.marchand, Pawel Modrak
On 17/10/2019 15:09, Luca Boccassi wrote:
> On Thu, 2019-10-17 at 09:44 +0100, Bruce Richardson wrote:
>> On Wed, Oct 16, 2019 at 06:03:36PM +0100, Anatoly Burakov wrote:
>>> From: Marcin Baran <
>>> marcinx.baran@intel.com
>>>>
>>>
>>> As per new ABI policy, all of the libraries are now versioned using
>>> one global ABI version. Changes in this patch implement the
>>> necessary steps to enable that.
>>>
>>> Signed-off-by: Marcin Baran <
>>> marcinx.baran@intel.com
>>>>
>>> Signed-off-by: Pawel Modrak <
>>> pawelx.modrak@intel.com
>>>>
>>> Signed-off-by: Anatoly Burakov <
>>> anatoly.burakov@intel.com
>>>>
>>> ---
>>>
>>> Notes:
>>> v3:
>>> - Removed Windows support from Makefile changes
>>> - Removed unneeded path conversions from meson files
>>>
>>> buildtools/meson.build | 2 ++
>>> config/ABI_VERSION | 1 +
>>> config/meson.build | 5 +++--
>>> drivers/meson.build | 20 ++++++++++++--------
>>> lib/meson.build | 18 +++++++++++-------
>>> meson_options.txt | 2 --
>>> mk/rte.lib.mk | 13 ++++---------
>>> 7 files changed, 33 insertions(+), 28 deletions(-)
>>> create mode 100644 config/ABI_VERSION
>>>
>>> diff --git a/buildtools/meson.build b/buildtools/meson.build
>>> index 32c79c1308..78ce69977d 100644
>>> --- a/buildtools/meson.build
>>> +++ b/buildtools/meson.build
>>> @@ -12,3 +12,5 @@ if python3.found()
>>> else
>>> map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
>>> endif
>>> +
>>> +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
>>> diff --git a/config/ABI_VERSION b/config/ABI_VERSION
>>> new file mode 100644
>>> index 0000000000..9a7c1e503f
>>> --- /dev/null
>>> +++ b/config/ABI_VERSION
>>> @@ -0,0 +1 @@
>>> +20.0
>>> diff --git a/config/meson.build b/config/meson.build
>>> index a27f731f85..3cfc02406c 100644
>>> --- a/config/meson.build
>>> +++ b/config/meson.build
>>> @@ -17,7 +17,8 @@ endforeach
>>> # set the major version, which might be used by drivers and
>>> libraries
>>> # depending on the configuration options
>>> pver = meson.project_version().split('.')
>>> -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
>>> +abi_version = run_command(find_program('cat', 'more'),
>>> + files('ABI_VERSION')).stdout().strip()
>>>
>>> # extract all version information into the build configuration
>>> dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
>>> @@ -37,7 +38,7 @@ endif
>>>
>>> pmd_subdir_opt = get_option('drivers_install_subdir')
>>> if pmd_subdir_opt.contains('<VERSION>')
>>> - pmd_subdir_opt =
>>> major_version.join(pmd_subdir_opt.split('<VERSION>'))
>>> + pmd_subdir_opt =
>>> abi_version.join(pmd_subdir_opt.split('<VERSION>'))
>>> endif
>>
>> This is an interesting change, and I'm not sure about it. I think for
>> user-visible changes, version should still refer to DPDK version
>> rather
>> than ABI version. Even with a stable ABI, it makes more sense to me
>> to find
>> the drivers in a 19.11 directory than a 20.0 one. Then again, the
>> drivers
>> should be re-usable across the one ABI version, so perhaps this is
>> the best
>> approach.
>>
>> Thoughts from others? Luca or Kevin, any thoughts from a packagers
>> perspective?
>>
>> /Bruce
>
> Hi,
>
> We are currently assembing this path using the ABI version in
> Debian/Ubuntu, as we want same-ABI libraries not to be co-installed,
> but instead fo use the exact same name/path. So from our POV this
> change seems right.
>
Seems ok to me as it's consistent with having the libs from different
releases using one ABI version. Would like to check with Timothy too..
+ Timothy
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-18 8:28 0% ` Wang, Haiyue
@ 2019-10-18 9:47 0% ` Olivier Matz
2019-10-18 11:24 0% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-10-18 9:47 UTC (permalink / raw)
To: Wang, Haiyue
Cc: dev, Andrew Rybchenko, Richardson, Bruce,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
On Fri, Oct 18, 2019 at 08:28:02AM +0000, Wang, Haiyue wrote:
> Hi Olivier,
>
> > -----Original Message-----
> > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > Sent: Friday, October 18, 2019 15:54
> > To: Wang, Haiyue <haiyue.wang@intel.com>
> > Cc: dev@dpdk.org; Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce
> > <bruce.richardson@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > <thomas@monjalon.net>
> > Subject: Re: [PATCH v2] mbuf: support dynamic fields and flags
> >
> > Hi Haiyue,
> >
> > On Fri, Oct 18, 2019 at 02:47:50AM +0000, Wang, Haiyue wrote:
> > > Hi Olivier
> > >
> > > > -----Original Message-----
> > > > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > > > Sent: Thursday, October 17, 2019 22:42
> > > > To: dev@dpdk.org
> > > > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> > Wang,
> > > > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > > > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > > > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > > > <thomas@monjalon.net>
> > > > Subject: [PATCH v2] mbuf: support dynamic fields and flags
> > > >
> > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > structure is limited, it is not possible to have a field for each
> > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > or ABI.
> > > >
> > > > This commit addresses these issues, by enabling the dynamic registration
> > > > of fields or flags:
> > > >
> > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > given size (>= 1 byte) and alignment constraint.
> > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > >
> > > > The typical use case is a PMD that registers space for an offload
> > > > feature, when the application requests to enable this feature. As
> > > > the space in mbuf is limited, the space should only be reserved if it
> > > > is going to be used (i.e when the application explicitly asks for it).
> > > >
> > > > The registration can be done at any moment, but it is not possible
> > > > to unregister fields or flags for now.
> > > >
> > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > > ---
> > > >
> > > > v2
> > > >
> > > > * Rebase on top of master: solve conflict with Stephen's patchset
> > > > (packet copy)
> > > > * Add new apis to register a dynamic field/flag at a specific place
> > > > * Add a dump function (sugg by David)
> > > > * Enhance field registration function to select the best offset, keeping
> > > > large aligned zones as much as possible (sugg by Konstantin)
> > > > * Use a size_t and unsigned int instead of int when relevant
> > > > (sugg by Konstantin)
> > > > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > > > (sugg by Konstantin)
> > > > * Remove unused argument in private function (sugg by Konstantin)
> > > > * Fix and simplify locking (sugg by Konstantin)
> > > > * Fix minor typo
> > > >
> > > > rfc -> v1
> > > >
> > > > * Rebase on top of master
> > > > * Change registration API to use a structure instead of
> > > > variables, getting rid of #defines (Stephen's comment)
> > > > * Update flag registration to use a similar API as fields.
> > > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > > * Add a debug log at registration
> > > > * Add some words in release note
> > > > * Did some performance tests (sugg. by Andrew):
> > > > On my platform, reading a dynamic field takes ~3 cycles more
> > > > than a static field, and ~2 cycles more for writing.
> > > >
> > > > app/test/test_mbuf.c | 145 ++++++-
> > > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > > lib/librte_mbuf/Makefile | 2 +
> > > > lib/librte_mbuf/meson.build | 6 +-
> > > > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > > > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > > > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > > > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > > > 8 files changed, 959 insertions(+), 5 deletions(-)
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > > >
> > > > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > > > index b9c2b2500..01cafad59 100644
> > > > --- a/app/test/test_mbuf.c
> > > > +++ b/app/test/test_mbuf.c
> > > > @@ -28,6 +28,7 @@
> > > > #include <rte_random.h>
> > >
> > > [snip]
> > >
> > > > +/**
> > > > + * Helper macro to access to a dynamic field.
> > > > + */
> > > > +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> > > > +
> > >
> > > The suggested macro is missed ? ;-)
> > > /**
> > > * Helper macro to access to a dynamic flag.
> > > */
> > > #define RTE_MBUF_DYNFLAG(offset) (1ULL << (offset))
> >
> > Yes, sorry.
> >
> > Thinking a bit more about it, I wonder if the macros below aren't
> > more consistent with the dynamic field (because they take the mbuf
> > as parameter)?
> >
> > #define RTE_MBUF_SET_DYNFLAG(m, bitnum, val) ...
> > #define RTE_MBUF_GET_DYNFLAG(m, bitnum) ...
> >
> > They could even be static inline functions.
> >
> > On the other hand, these helpers would be generic to ol_flags, not only
> > for dynamic flags. Today, we use (1ULL << bit) for ol_flags, which makes
> > me wonder... is the macro really needed after all? :)
> >
>
> I used as this:
> 1). in PMD:
> mb->ol_flags |= RTE_MBUF_DYNFLAG(ol_offset);
>
>
> 2). In testpmd
> if (mb->ol_flags & RTE_MBUF_DYNFLAG(ol_offset))
> ...
>
> The above two macros look better in real use.
I just looked at http://patchwork.dpdk.org/patch/60908/
In the patch, a mask is used instead of a bit number, which is indeed
better in terms of performance. This makes the macro not that useful,
given there is a specific helper.
> > > BTW, should we have a place to put the registered dynamic fields and flags
> > > names together (a name overview -- detail Link to --> PMD's help page) ?
> >
> > The centralized place will be in rte_mbuf_dyn.h for fields/flags that can
> > are shared between several dpdk areas. Some libraries/pmd could have private
> > dynamic fields/flags. In any case, I think the same namespace than functions
> > should be used. Probably something like this:
> > - "rte_mbuf_dynfield_<name>" in mbuf lib
> > - "rte_<libname>_dynfield_<name>" in other libs
> > - "rte_net_<pmd>_dynfield_<name>" in pmds
> > - "<name>" in apps
> >
> > > Since rte_mbuf_dynfield:name & rte_mbuf_dynflag:name work as a API style,
> > > users can check how many 'names' registered, developers can check whether
> > > the names they want to use are registered or not ? They don't need to have
> > > to check the rte_errno ... Just a suggestion for user experience.
> >
> > I did not get you point. Does my response above answers to your question?
> >
>
> Yes, the name conversation you mentioned above is a good practice, then no doc
> needed any more, thanks!
>
> > Regards,
> > Olivier
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-18 7:53 0% ` Olivier Matz
@ 2019-10-18 8:28 0% ` Wang, Haiyue
2019-10-18 9:47 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-10-18 8:28 UTC (permalink / raw)
To: Olivier Matz
Cc: dev, Andrew Rybchenko, Richardson, Bruce,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
Hi Olivier,
> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Friday, October 18, 2019 15:54
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org; Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: Re: [PATCH v2] mbuf: support dynamic fields and flags
>
> Hi Haiyue,
>
> On Fri, Oct 18, 2019 at 02:47:50AM +0000, Wang, Haiyue wrote:
> > Hi Olivier
> >
> > > -----Original Message-----
> > > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > > Sent: Thursday, October 17, 2019 22:42
> > > To: dev@dpdk.org
> > > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Wang,
> > > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > > <thomas@monjalon.net>
> > > Subject: [PATCH v2] mbuf: support dynamic fields and flags
> > >
> > > Many features require to store data inside the mbuf. As the room in mbuf
> > > structure is limited, it is not possible to have a field for each
> > > feature. Also, changing fields in the mbuf structure can break the API
> > > or ABI.
> > >
> > > This commit addresses these issues, by enabling the dynamic registration
> > > of fields or flags:
> > >
> > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > given size (>= 1 byte) and alignment constraint.
> > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > >
> > > The typical use case is a PMD that registers space for an offload
> > > feature, when the application requests to enable this feature. As
> > > the space in mbuf is limited, the space should only be reserved if it
> > > is going to be used (i.e when the application explicitly asks for it).
> > >
> > > The registration can be done at any moment, but it is not possible
> > > to unregister fields or flags for now.
> > >
> > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > ---
> > >
> > > v2
> > >
> > > * Rebase on top of master: solve conflict with Stephen's patchset
> > > (packet copy)
> > > * Add new apis to register a dynamic field/flag at a specific place
> > > * Add a dump function (sugg by David)
> > > * Enhance field registration function to select the best offset, keeping
> > > large aligned zones as much as possible (sugg by Konstantin)
> > > * Use a size_t and unsigned int instead of int when relevant
> > > (sugg by Konstantin)
> > > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > > (sugg by Konstantin)
> > > * Remove unused argument in private function (sugg by Konstantin)
> > > * Fix and simplify locking (sugg by Konstantin)
> > > * Fix minor typo
> > >
> > > rfc -> v1
> > >
> > > * Rebase on top of master
> > > * Change registration API to use a structure instead of
> > > variables, getting rid of #defines (Stephen's comment)
> > > * Update flag registration to use a similar API as fields.
> > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > * Add a debug log at registration
> > > * Add some words in release note
> > > * Did some performance tests (sugg. by Andrew):
> > > On my platform, reading a dynamic field takes ~3 cycles more
> > > than a static field, and ~2 cycles more for writing.
> > >
> > > app/test/test_mbuf.c | 145 ++++++-
> > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > lib/librte_mbuf/Makefile | 2 +
> > > lib/librte_mbuf/meson.build | 6 +-
> > > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > > 8 files changed, 959 insertions(+), 5 deletions(-)
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > >
> > > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > > index b9c2b2500..01cafad59 100644
> > > --- a/app/test/test_mbuf.c
> > > +++ b/app/test/test_mbuf.c
> > > @@ -28,6 +28,7 @@
> > > #include <rte_random.h>
> >
> > [snip]
> >
> > > +/**
> > > + * Helper macro to access to a dynamic field.
> > > + */
> > > +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> > > +
> >
> > The suggested macro is missed ? ;-)
> > /**
> > * Helper macro to access to a dynamic flag.
> > */
> > #define RTE_MBUF_DYNFLAG(offset) (1ULL << (offset))
>
> Yes, sorry.
>
> Thinking a bit more about it, I wonder if the macros below aren't
> more consistent with the dynamic field (because they take the mbuf
> as parameter)?
>
> #define RTE_MBUF_SET_DYNFLAG(m, bitnum, val) ...
> #define RTE_MBUF_GET_DYNFLAG(m, bitnum) ...
>
> They could even be static inline functions.
>
> On the other hand, these helpers would be generic to ol_flags, not only
> for dynamic flags. Today, we use (1ULL << bit) for ol_flags, which makes
> me wonder... is the macro really needed after all? :)
>
I used as this:
1). in PMD:
mb->ol_flags |= RTE_MBUF_DYNFLAG(ol_offset);
2). In testpmd
if (mb->ol_flags & RTE_MBUF_DYNFLAG(ol_offset))
...
The above two macros look better in real use.
> > BTW, should we have a place to put the registered dynamic fields and flags
> > names together (a name overview -- detail Link to --> PMD's help page) ?
>
> The centralized place will be in rte_mbuf_dyn.h for fields/flags that can
> are shared between several dpdk areas. Some libraries/pmd could have private
> dynamic fields/flags. In any case, I think the same namespace than functions
> should be used. Probably something like this:
> - "rte_mbuf_dynfield_<name>" in mbuf lib
> - "rte_<libname>_dynfield_<name>" in other libs
> - "rte_net_<pmd>_dynfield_<name>" in pmds
> - "<name>" in apps
>
> > Since rte_mbuf_dynfield:name & rte_mbuf_dynflag:name work as a API style,
> > users can check how many 'names' registered, developers can check whether
> > the names they want to use are registered or not ? They don't need to have
> > to check the rte_errno ... Just a suggestion for user experience.
>
> I did not get you point. Does my response above answers to your question?
>
Yes, the name conversation you mentioned above is a good practice, then no doc
needed any more, thanks!
> Regards,
> Olivier
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-18 2:47 0% ` Wang, Haiyue
@ 2019-10-18 7:53 0% ` Olivier Matz
2019-10-18 8:28 0% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-10-18 7:53 UTC (permalink / raw)
To: Wang, Haiyue
Cc: dev, Andrew Rybchenko, Richardson, Bruce,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
Hi Haiyue,
On Fri, Oct 18, 2019 at 02:47:50AM +0000, Wang, Haiyue wrote:
> Hi Olivier
>
> > -----Original Message-----
> > From: Olivier Matz [mailto:olivier.matz@6wind.com]
> > Sent: Thursday, October 17, 2019 22:42
> > To: dev@dpdk.org
> > Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>; Wang,
> > Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> > <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> > <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> > <thomas@monjalon.net>
> > Subject: [PATCH v2] mbuf: support dynamic fields and flags
> >
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> >
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> >
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> > given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> >
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature. As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> >
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >
> > v2
> >
> > * Rebase on top of master: solve conflict with Stephen's patchset
> > (packet copy)
> > * Add new apis to register a dynamic field/flag at a specific place
> > * Add a dump function (sugg by David)
> > * Enhance field registration function to select the best offset, keeping
> > large aligned zones as much as possible (sugg by Konstantin)
> > * Use a size_t and unsigned int instead of int when relevant
> > (sugg by Konstantin)
> > * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> > (sugg by Konstantin)
> > * Remove unused argument in private function (sugg by Konstantin)
> > * Fix and simplify locking (sugg by Konstantin)
> > * Fix minor typo
> >
> > rfc -> v1
> >
> > * Rebase on top of master
> > * Change registration API to use a structure instead of
> > variables, getting rid of #defines (Stephen's comment)
> > * Update flag registration to use a similar API as fields.
> > * Change max name length from 32 to 64 (sugg. by Thomas)
> > * Enhance API documentation (Haiyue's and Andrew's comments)
> > * Add a debug log at registration
> > * Add some words in release note
> > * Did some performance tests (sugg. by Andrew):
> > On my platform, reading a dynamic field takes ~3 cycles more
> > than a static field, and ~2 cycles more for writing.
> >
> > app/test/test_mbuf.c | 145 ++++++-
> > doc/guides/rel_notes/release_19_11.rst | 7 +
> > lib/librte_mbuf/Makefile | 2 +
> > lib/librte_mbuf/meson.build | 6 +-
> > lib/librte_mbuf/rte_mbuf.h | 23 +-
> > lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> > lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> > lib/librte_mbuf/rte_mbuf_version.map | 7 +
> > 8 files changed, 959 insertions(+), 5 deletions(-)
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> >
> > diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> > index b9c2b2500..01cafad59 100644
> > --- a/app/test/test_mbuf.c
> > +++ b/app/test/test_mbuf.c
> > @@ -28,6 +28,7 @@
> > #include <rte_random.h>
>
> [snip]
>
> > +/**
> > + * Helper macro to access to a dynamic field.
> > + */
> > +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> > +
>
> The suggested macro is missed ? ;-)
> /**
> * Helper macro to access to a dynamic flag.
> */
> #define RTE_MBUF_DYNFLAG(offset) (1ULL << (offset))
Yes, sorry.
Thinking a bit more about it, I wonder if the macros below aren't
more consistent with the dynamic field (because they take the mbuf
as parameter)?
#define RTE_MBUF_SET_DYNFLAG(m, bitnum, val) ...
#define RTE_MBUF_GET_DYNFLAG(m, bitnum) ...
They could even be static inline functions.
On the other hand, these helpers would be generic to ol_flags, not only
for dynamic flags. Today, we use (1ULL << bit) for ol_flags, which makes
me wonder... is the macro really needed after all? :)
> BTW, should we have a place to put the registered dynamic fields and flags
> names together (a name overview -- detail Link to --> PMD's help page) ?
The centralized place will be in rte_mbuf_dyn.h for fields/flags that can
are shared between several dpdk areas. Some libraries/pmd could have private
dynamic fields/flags. In any case, I think the same namespace than functions
should be used. Probably something like this:
- "rte_mbuf_dynfield_<name>" in mbuf lib
- "rte_<libname>_dynfield_<name>" in other libs
- "rte_net_<pmd>_dynfield_<name>" in pmds
- "<name>" in apps
> Since rte_mbuf_dynfield:name & rte_mbuf_dynflag:name work as a API style,
> users can check how many 'names' registered, developers can check whether
> the names they want to use are registered or not ? They don't need to have
> to check the rte_errno ... Just a suggestion for user experience.
I did not get you point. Does my response above answers to your question?
Regards,
Olivier
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/3] lib/lpm: integrate RCU QSBR
2019-10-15 11:15 0% ` Ananyev, Konstantin
@ 2019-10-18 3:32 0% ` Honnappa Nagarahalli
0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2019-10-18 3:32 UTC (permalink / raw)
To: Ananyev, Konstantin, Richardson, Bruce, Medvedkin, Vladimir,
olivier.matz
Cc: dev, stephen, paulmck, Gavin Hu (Arm Technology China),
Dharmik Thakkar, Ruifeng Wang (Arm Technology China),
Honnappa Nagarahalli, nd, nd
<snip>
> >
> > > Hi guys,
> > I have tried to consolidate design related questions here. If I have missed
> anything, please add.
> >
> > >
> > > >
> > > > From: Ruifeng Wang <ruifeng.wang@arm.com>
> > > >
> > > > Currently, the tbl8 group is freed even though the readers might
> > > > be using the tbl8 group entries. The freed tbl8 group can be
> > > > reallocated quickly. This results in incorrect lookup results.
> > > >
> > > > RCU QSBR process is integrated for safe tbl8 group reclaim.
> > > > Refer to RCU documentation to understand various aspects of
> > > > integrating RCU library into other libraries.
> > > >
> > > > Signed-off-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > ---
> > > > lib/librte_lpm/Makefile | 3 +-
> > > > lib/librte_lpm/meson.build | 2 +
> > > > lib/librte_lpm/rte_lpm.c | 102 +++++++++++++++++++++++++----
> > > > lib/librte_lpm/rte_lpm.h | 21 ++++++
> > > > lib/librte_lpm/rte_lpm_version.map | 6 ++
> > > > 5 files changed, 122 insertions(+), 12 deletions(-)
> > > >
> > > > diff --git a/lib/librte_lpm/Makefile b/lib/librte_lpm/Makefile
> > > > index
> > > > a7946a1c5..ca9e16312 100644
> > > > --- a/lib/librte_lpm/Makefile
> > > > +++ b/lib/librte_lpm/Makefile
> > > > @@ -6,9 +6,10 @@ include $(RTE_SDK)/mk/rte.vars.mk # library name
> > > > LIB = librte_lpm.a
> > > >
> > > > +CFLAGS += -DALLOW_EXPERIMENTAL_API
> > > > CFLAGS += -O3
> > > > CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -LDLIBS += -lrte_eal
> > > > -lrte_hash
> > > > +LDLIBS += -lrte_eal -lrte_hash -lrte_rcu
> > > >
> > > > EXPORT_MAP := rte_lpm_version.map
> > > >
> > > > diff --git a/lib/librte_lpm/meson.build
> > > > b/lib/librte_lpm/meson.build index a5176d8ae..19a35107f 100644
> > > > --- a/lib/librte_lpm/meson.build
> > > > +++ b/lib/librte_lpm/meson.build
> > > > @@ -2,9 +2,11 @@
> > > > # Copyright(c) 2017 Intel Corporation
> > > >
> > > > version = 2
> > > > +allow_experimental_apis = true
> > > > sources = files('rte_lpm.c', 'rte_lpm6.c') headers =
> > > > files('rte_lpm.h', 'rte_lpm6.h') # since header files have
> > > > different names, we can install all vector headers # without
> > > > worrying about which architecture we actually need headers +=
> > > > files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h')
> > > > deps += ['hash']
> > > > +deps += ['rcu']
> > > > diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
> > > > index
> > > > 3a929a1b1..ca58d4b35 100644
> > > > --- a/lib/librte_lpm/rte_lpm.c
> > > > +++ b/lib/librte_lpm/rte_lpm.c
> > > > @@ -1,5 +1,6 @@
> > > > /* SPDX-License-Identifier: BSD-3-Clause
> > > > * Copyright(c) 2010-2014 Intel Corporation
> > > > + * Copyright(c) 2019 Arm Limited
> > > > */
> > > >
> > > > #include <string.h>
> > > > @@ -381,6 +382,8 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
> > > >
> > > > rte_mcfg_tailq_write_unlock();
> > > >
> > > > + if (lpm->dq)
> > > > + rte_rcu_qsbr_dq_delete(lpm->dq);
> > > > rte_free(lpm->tbl8);
> > > > rte_free(lpm->rules_tbl);
> > > > rte_free(lpm);
> > > > @@ -390,6 +393,59 @@ BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604,
> > > 16.04);
> > > > MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
> > > > rte_lpm_free_v1604);
> > > >
> > > > +struct __rte_lpm_rcu_dq_entry {
> > > > + uint32_t tbl8_group_index;
> > > > + uint32_t pad;
> > > > +};
> > > > +
> > > > +static void
> > > > +__lpm_rcu_qsbr_free_resource(void *p, void *data) {
> > > > + struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > > > + struct __rte_lpm_rcu_dq_entry *e =
> > > > + (struct __rte_lpm_rcu_dq_entry *)data;
> > > > + struct rte_lpm_tbl_entry *tbl8 = (struct rte_lpm_tbl_entry *)p;
> > > > +
> > > > + /* Set tbl8 group invalid */
> > > > + __atomic_store(&tbl8[e->tbl8_group_index], &zero_tbl8_entry,
> > > > + __ATOMIC_RELAXED);
> > > > +}
> > > > +
> > > > +/* Associate QSBR variable with an LPM object.
> > > > + */
> > > > +int
> > > > +rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr *v) {
> > > > + char rcu_dq_name[RTE_RCU_QSBR_DQ_NAMESIZE];
> > > > + struct rte_rcu_qsbr_dq_parameters params;
> > > > +
> > > > + if ((lpm == NULL) || (v == NULL)) {
> > > > + rte_errno = EINVAL;
> > > > + return 1;
> > > > + }
> > > > +
> > > > + if (lpm->dq) {
> > > > + rte_errno = EEXIST;
> > > > + return 1;
> > > > + }
> > > > +
> > > > + /* Init QSBR defer queue. */
> > > > + snprintf(rcu_dq_name, sizeof(rcu_dq_name), "LPM_RCU_%s", lpm-
> > > >name);
> > > > + params.name = rcu_dq_name;
> > > > + params.size = lpm->number_tbl8s;
> > > > + params.esize = sizeof(struct __rte_lpm_rcu_dq_entry);
> > > > + params.f = __lpm_rcu_qsbr_free_resource;
> > > > + params.p = lpm->tbl8;
> > > > + params.v = v;
> > > > + lpm->dq = rte_rcu_qsbr_dq_create(¶ms);
> > > > + if (lpm->dq == NULL) {
> > > > + RTE_LOG(ERR, LPM, "LPM QS defer queue creation failed\n");
> > > > + return 1;
> > > > + }
> > >
> > > Few thoughts about that function:
> > Few things to keep in mind, the goal of the design is to make it easy
> > for the applications to adopt lock-free algorithms. The reclamation
> > process in the writer is a major portion of code one has to write for using
> lock-free algorithms. The current design is such that the writer does not have
> to change any code or write additional code other than calling
> 'rte_lpm_rcu_qsbr_add'.
> >
> > > It names rcu_qsbr_add() but in fact it allocates defer queue for give rcu var.
> > > So first thought - is it always necessary?
> > This is part of the design. If the application does not want to use
> > this integrated logic then, it does not have to call this API. It can
> > use the RCU defer APIs to implement its own logic. But, if I ask the question,
> does this integrated logic address most of the use cases of the LPM library, I
> think the answer is yes.
> >
> > > For some use-cases I suppose user might be ok to wait for quiescent
> > > state change inside tbl8_free()?
> > Yes, that is a possibility (for ex: no frequent route changes). But, I
> > think that is very trivial for the application to implement. Though, the LPM
> library has to separate the 'delete' and 'free' operations.
>
> Exactly.
> That's why it is not trivial with current LPM library.
> In fact to do that himself right now, user would have to implement and support
> his own version of LPM code.
😊, well we definitely don't want them to write their own library (if DPDK LPM is enough)
IMO, we need to be consistent with other libraries in terms of APIs. That's another topic.
I do not see any problem to implement this or provide facility to implement this in the future in the APIs now. We can add 'flags' field which will allow for other methods of reclamation.
>
> Honestly, I don't understand why you consider it as a drawback.
> From my perspective only few things need to be changed:
>
> 1. Add 2 parameters to 'rte_lpm_rcu_qsbr_add():
> number of elems in defer_queue
> reclaim() threshold value.
> If the user doesn't want to provide any values, that's fine we can use default
> ones here (as you do it right now).
I think we have agreed on this, I see the value in doing this.
> 2. Make rte_lpm_rcu_qsbr_add() to return pointer to the defer_queue.
> Again if user doesn't want to call reclaim() himself, he can just ignore return
> value.
Given the goal of reducing the burden on the user, this is not in that direction. But if you see a use case for it, I don't have any issues. Vladimir asked for it as well in the other thread.
>
> These 2 changes will provide us with necessary flexibility that would help to
> cover more use-cases:
> - user can decide how big should be the defer queue
> - user can decide when/how he wants to do reclaim()
>
> Konstantin
>
> >Similar operations are provided in rte_hash library. IMO, we should
> >follow consistent approach.
> >
> > > Another thing you do allocate defer queue, but it is internal, so
> > > user can't call
> > > reclaim() manually, which looks strange.
> > > Why not to return defer_queue pointer to the user, so he can call
> > > reclaim() himself at appropriate time?
> > The intention of the design is to take the complexity away from the
> > user of LPM library. IMO, the current design will address most uses cases of
> LPM library. If we expose the 2 parameters (when to trigger reclamation and
> how much to reclaim) in the 'rte_lpm_rcu_qsbr_add'
> > API, it should provide enough flexibility to the application.
> >
> > > Third thing - you always allocate defer queue with size equal to
> > > number of tbl8.
> > > Though I understand it could be up to 16M tbl8 groups inside the LPM.
> > > Do we really need defer queue that long?
> > No, we do not need it to be this long. It is this long today to avoid returning
> no-space on the defer queue error.
> >
> > > Especially considering that current rcu_defer_queue will start
> > > reclamation when 1/8 of defer_quueue becomes full and wouldn't
> > > reclaim more then
> > > 1/16 of it.
> > > Probably better to let user to decide himself how long defer_queue
> > > he needs for that LPM?
> > It makes sense to expose it to the user if the writer-writer
> > concurrency is lock-free (no memory allocation allowed to expand the
> > defer queue size when the queue is full). However, LPM is not lock-free on
> the writer side. If we think the writer could be lock-free in the future, it has to
> be exposed to the user.
> >
> > >
> > > Konstantin
> > Pulling questions/comments from other threads:
> > Can we leave reclamation to some other house-keeping thread to do (sort of
> garbage collector). Or such mode is not supported/planned?
> >
> > [Honnappa] If the reclamation cost is small, the current method
> > provides advantages over having a separate thread to do reclamation. I
> > did not plan to provide such an option. But may be it makes sense to keep the
> options open (especially from ABI perspective). May be we should add a flags
> field which will allow us to implement different methods in the future?
> >
> > >
> > >
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > /*
> > > > * Adds a rule to the rule table.
> > > > *
> > > > @@ -679,14 +735,15 @@ tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20
> > > > *tbl8) }
> > > >
> > > > static int32_t
> > > > -tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > > > number_tbl8s)
> > > > +__tbl8_alloc_v1604(struct rte_lpm *lpm)
> > > > {
> > > > uint32_t group_idx; /* tbl8 group index. */
> > > > struct rte_lpm_tbl_entry *tbl8_entry;
> > > >
> > > > /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
> > > > - for (group_idx = 0; group_idx < number_tbl8s; group_idx++) {
> > > > - tbl8_entry = &tbl8[group_idx *
> > > RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > > > + for (group_idx = 0; group_idx < lpm->number_tbl8s; group_idx++) {
> > > > + tbl8_entry = &lpm->tbl8[group_idx *
> > > > +
> > > RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > > > /* If a free tbl8 group is found clean it and set as VALID. */
> > > > if (!tbl8_entry->valid_group) {
> > > > struct rte_lpm_tbl_entry new_tbl8_entry = { @@ -
> > > 712,6 +769,21 @@
> > > > tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
> > > > return -ENOSPC;
> > > > }
> > > >
> > > > +static int32_t
> > > > +tbl8_alloc_v1604(struct rte_lpm *lpm) {
> > > > + int32_t group_idx; /* tbl8 group index. */
> > > > +
> > > > + group_idx = __tbl8_alloc_v1604(lpm);
> > > > + if ((group_idx < 0) && (lpm->dq != NULL)) {
> > > > + /* If there are no tbl8 groups try to reclaim some. */
> > > > + if (rte_rcu_qsbr_dq_reclaim(lpm->dq) == 0)
> > > > + group_idx = __tbl8_alloc_v1604(lpm);
> > > > + }
> > > > +
> > > > + return group_idx;
> > > > +}
> > > > +
> > > > static void
> > > > tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t
> > > > tbl8_group_start) { @@ -728,13 +800,21 @@ tbl8_free_v20(struct
> > > > rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start) }
> > > >
> > > > static void
> > > > -tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > > > tbl8_group_start)
> > > > +tbl8_free_v1604(struct rte_lpm *lpm, uint32_t tbl8_group_start)
> > > > {
> > > > - /* Set tbl8 group invalid*/
> > > > struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > > > + struct __rte_lpm_rcu_dq_entry e;
> > > >
> > > > - __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
> > > > - __ATOMIC_RELAXED);
> > > > + if (lpm->dq != NULL) {
> > > > + e.tbl8_group_index = tbl8_group_start;
> > > > + e.pad = 0;
> > > > + /* Push into QSBR defer queue. */
> > > > + rte_rcu_qsbr_dq_enqueue(lpm->dq, (void *)&e);
> > > > + } else {
> > > > + /* Set tbl8 group invalid*/
> > > > + __atomic_store(&lpm->tbl8[tbl8_group_start],
> > > &zero_tbl8_entry,
> > > > + __ATOMIC_RELAXED);
> > > > + }
> > > > }
> > > >
> > > > static __rte_noinline int32_t
> > > > @@ -1037,7 +1117,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> > > > uint32_t ip_masked, uint8_t depth,
> > > >
> > > > if (!lpm->tbl24[tbl24_index].valid) {
> > > > /* Search for a free tbl8 group. */
> > > > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> > > >number_tbl8s);
> > > > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> > > >
> > > > /* Check tbl8 allocation was successful. */
> > > > if (tbl8_group_index < 0) {
> > > > @@ -1083,7 +1163,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> > > uint32_t ip_masked, uint8_t depth,
> > > > } /* If valid entry but not extended calculate the index into Table8. */
> > > > else if (lpm->tbl24[tbl24_index].valid_group == 0) {
> > > > /* Search for free tbl8 group. */
> > > > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> > > >number_tbl8s);
> > > > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> > > >
> > > > if (tbl8_group_index < 0) {
> > > > return tbl8_group_index;
> > > > @@ -1818,7 +1898,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm,
> > > uint32_t ip_masked,
> > > > */
> > > > lpm->tbl24[tbl24_index].valid = 0;
> > > > __atomic_thread_fence(__ATOMIC_RELEASE);
> > > > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > > > + tbl8_free_v1604(lpm, tbl8_group_start);
> > > > } else if (tbl8_recycle_index > -1) {
> > > > /* Update tbl24 entry. */
> > > > struct rte_lpm_tbl_entry new_tbl24_entry = { @@ -1834,7
> > > +1914,7 @@
> > > > delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
> > > > __atomic_store(&lpm->tbl24[tbl24_index],
> > > &new_tbl24_entry,
> > > > __ATOMIC_RELAXED);
> > > > __atomic_thread_fence(__ATOMIC_RELEASE);
> > > > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > > > + tbl8_free_v1604(lpm, tbl8_group_start);
> > > > }
> > > > #undef group_idx
> > > > return 0;
> > > > diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
> > > > index 906ec4483..49c12a68d 100644
> > > > --- a/lib/librte_lpm/rte_lpm.h
> > > > +++ b/lib/librte_lpm/rte_lpm.h
> > > > @@ -1,5 +1,6 @@
> > > > /* SPDX-License-Identifier: BSD-3-Clause
> > > > * Copyright(c) 2010-2014 Intel Corporation
> > > > + * Copyright(c) 2019 Arm Limited
> > > > */
> > > >
> > > > #ifndef _RTE_LPM_H_
> > > > @@ -21,6 +22,7 @@
> > > > #include <rte_common.h>
> > > > #include <rte_vect.h>
> > > > #include <rte_compat.h>
> > > > +#include <rte_rcu_qsbr.h>
> > > >
> > > > #ifdef __cplusplus
> > > > extern "C" {
> > > > @@ -186,6 +188,7 @@ struct rte_lpm {
> > > > __rte_cache_aligned; /**< LPM tbl24 table. */
> > > > struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
> > > > struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
> > > > + struct rte_rcu_qsbr_dq *dq; /**< RCU QSBR defer queue.*/
> > > > };
> > > >
> > > > /**
> > > > @@ -248,6 +251,24 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
> > > void
> > > > rte_lpm_free_v1604(struct rte_lpm *lpm);
> > > >
> > > > +/**
> > > > + * Associate RCU QSBR variable with an LPM object.
> > > > + *
> > > > + * @param lpm
> > > > + * the lpm object to add RCU QSBR
> > > > + * @param v
> > > > + * RCU QSBR variable
> > > > + * @return
> > > > + * On success - 0
> > > > + * On error - 1 with error code set in rte_errno.
> > > > + * Possible rte_errno codes are:
> > > > + * - EINVAL - invalid pointer
> > > > + * - EEXIST - already added QSBR
> > > > + * - ENOMEM - memory allocation failure
> > > > + */
> > > > +__rte_experimental
> > > > +int rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr
> > > > +*v);
> > > > +
> > > > /**
> > > > * Add a rule to the LPM table.
> > > > *
> > > > diff --git a/lib/librte_lpm/rte_lpm_version.map
> > > > b/lib/librte_lpm/rte_lpm_version.map
> > > > index 90beac853..b353aabd2 100644
> > > > --- a/lib/librte_lpm/rte_lpm_version.map
> > > > +++ b/lib/librte_lpm/rte_lpm_version.map
> > > > @@ -44,3 +44,9 @@ DPDK_17.05 {
> > > > rte_lpm6_lookup_bulk_func;
> > > >
> > > > } DPDK_16.04;
> > > > +
> > > > +EXPERIMENTAL {
> > > > + global:
> > > > +
> > > > + rte_lpm_rcu_qsbr_add;
> > > > +};
> > > > --
> > > > 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
2019-10-17 14:42 3% ` [dpdk-dev] [PATCH v2] " Olivier Matz
@ 2019-10-18 2:47 0% ` Wang, Haiyue
2019-10-18 7:53 0% ` Olivier Matz
2019-10-22 22:51 0% ` Ananyev, Konstantin
2019-10-23 12:00 0% ` Shahaf Shuler
2 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2019-10-18 2:47 UTC (permalink / raw)
To: Olivier Matz, dev
Cc: Andrew Rybchenko, Richardson, Bruce, Jerin Jacob Kollanukkaran,
Wiles, Keith, Ananyev, Konstantin, Morten Brørup,
Stephen Hemminger, Thomas Monjalon
Hi Olivier
> -----Original Message-----
> From: Olivier Matz [mailto:olivier.matz@6wind.com]
> Sent: Thursday, October 17, 2019 22:42
> To: dev@dpdk.org
> Cc: Andrew Rybchenko <arybchenko@solarflare.com>; Richardson, Bruce <bruce.richardson@intel.com>; Wang,
> Haiyue <haiyue.wang@intel.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Wiles, Keith
> <keith.wiles@intel.com>; Ananyev, Konstantin <konstantin.ananyev@intel.com>; Morten Brørup
> <mb@smartsharesystems.com>; Stephen Hemminger <stephen@networkplumber.org>; Thomas Monjalon
> <thomas@monjalon.net>
> Subject: [PATCH v2] mbuf: support dynamic fields and flags
>
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
>
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
>
> - a dynamic field is a named area in the rte_mbuf structure, with a
> given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
>
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature. As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
>
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>
> v2
>
> * Rebase on top of master: solve conflict with Stephen's patchset
> (packet copy)
> * Add new apis to register a dynamic field/flag at a specific place
> * Add a dump function (sugg by David)
> * Enhance field registration function to select the best offset, keeping
> large aligned zones as much as possible (sugg by Konstantin)
> * Use a size_t and unsigned int instead of int when relevant
> (sugg by Konstantin)
> * Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
> (sugg by Konstantin)
> * Remove unused argument in private function (sugg by Konstantin)
> * Fix and simplify locking (sugg by Konstantin)
> * Fix minor typo
>
> rfc -> v1
>
> * Rebase on top of master
> * Change registration API to use a structure instead of
> variables, getting rid of #defines (Stephen's comment)
> * Update flag registration to use a similar API as fields.
> * Change max name length from 32 to 64 (sugg. by Thomas)
> * Enhance API documentation (Haiyue's and Andrew's comments)
> * Add a debug log at registration
> * Add some words in release note
> * Did some performance tests (sugg. by Andrew):
> On my platform, reading a dynamic field takes ~3 cycles more
> than a static field, and ~2 cycles more for writing.
>
> app/test/test_mbuf.c | 145 ++++++-
> doc/guides/rel_notes/release_19_11.rst | 7 +
> lib/librte_mbuf/Makefile | 2 +
> lib/librte_mbuf/meson.build | 6 +-
> lib/librte_mbuf/rte_mbuf.h | 23 +-
> lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
> lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
> lib/librte_mbuf/rte_mbuf_version.map | 7 +
> 8 files changed, 959 insertions(+), 5 deletions(-)
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
>
> diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
> index b9c2b2500..01cafad59 100644
> --- a/app/test/test_mbuf.c
> +++ b/app/test/test_mbuf.c
> @@ -28,6 +28,7 @@
> #include <rte_random.h>
[snip]
> +/**
> + * Helper macro to access to a dynamic field.
> + */
> +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> +
The suggested macro is missed ? ;-)
/**
* Helper macro to access to a dynamic flag.
*/
#define RTE_MBUF_DYNFLAG(offset) (1ULL << (offset))
BTW, should we have a place to put the registered dynamic fields and flags
names together (a name overview -- detail Link to --> PMD's help page) ?
Since rte_mbuf_dynfield:name & rte_mbuf_dynflag:name work as a API style,
users can check how many 'names' registered, developers can check whether
the names they want to use are registered or not ? They don't need to have
to check the rte_errno ... Just a suggestion for user experience.
>
> } DPDK_18.08;
> --
> 2.20.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code Anatoly Burakov
@ 2019-10-17 21:04 0% ` Carrillo, Erik G
2019-10-21 13:24 3% ` Kevin Traynor
1 sibling, 0 replies; 200+ results
From: Carrillo, Erik G @ 2019-10-17 21:04 UTC (permalink / raw)
To: Burakov, Anatoly, dev
Cc: Baran, MarcinX, Robert Sanford, Mcnamara, John, Richardson,
Bruce, thomas, david.marchand
> -----Original Message-----
> From: Burakov, Anatoly <anatoly.burakov@intel.com>
> Sent: Thursday, October 17, 2019 9:32 AM
> To: dev@dpdk.org
> Cc: Baran, MarcinX <marcinx.baran@intel.com>; Robert Sanford
> <rsanford@akamai.com>; Carrillo, Erik G <erik.g.carrillo@intel.com>;
> Mcnamara, John <john.mcnamara@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; thomas@monjalon.net;
> david.marchand@redhat.com
> Subject: [PATCH v4 04/10] timer: remove deprecated code
>
> From: Marcin Baran <marcinx.baran@intel.com>
>
> Remove code for old ABI versions ahead of ABI version bump.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
Looks good to me too:
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 09/10] build: change ABI version to 20.0
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (9 preceding siblings ...)
2019-10-17 14:31 3% ` [dpdk-dev] [PATCH v4 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
@ 2019-10-17 14:31 2% ` Anatoly Burakov
2019-10-17 14:32 23% ` [dpdk-dev] [PATCH v4 10/10] buildtools: add ABI versioning check script Anatoly Burakov
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Pawel Modrak, Nicolas Chautru, Hemant Agrawal, Sachin Saxena,
Rosen Xu, Stephen Hemminger, Anoob Joseph, Tomasz Duszynski,
Liron Himi, Jerin Jacob, Nithin Dabilpuram, Vamsi Attunuru,
Lee Daly, Fiona Trahe, Ashish Gupta, Sunila Sahu, Declan Doherty,
Pablo de Lara, Gagandeep Singh, Ravi Kumar, Akhil Goyal,
Michael Shamis, Nagadheeraj Rottela, Srikanth Jampala, Fan Zhang,
Jay Zhou, Nipun Gupta, Mattias Rönnblom, Pavan Nikhilesh,
Liang Ma, Peter Mccarthy, Harry van Haaren, Artem V. Andreev,
Andrew Rybchenko, Olivier Matz, Gage Eads, John W. Linville,
Xiaolong Ye, Qi Zhang, Shepard Siegel, Ed Czeck, John Miller,
Igor Russkikh, Pavel Belous, Allain Legacy, Matt Peters,
Rasesh Mody, Shahed Shaikh, Ajit Khaparde, Somnath Kotur,
Chas Williams, Rahul Lakkireddy, Wenzhuo Lu, Marcin Wojtas,
Michal Krawczyk, Guy Tzalik, Evgeny Schemeilin, Igor Chauskin,
John Daley, Hyong Youb Kim, Gaetan Rivet, Xiao Wang, Ziyang Xuan,
Xiaoyun Wang, Guoyang Zhou, Wei Hu (Xavier), Min Hu (Connor),
Yisen Zhuang, Beilei Xing, Jingjing Wu, Qiming Yang,
Konstantin Ananyev, Ferruh Yigit, Shijith Thotton,
Srisivasubramanian Srinivasan, Jakub Grajciar, Matan Azrad,
Shahaf Shuler, Viacheslav Ovsiienko, Zyta Szpak,
K. Y. Srinivasan, Haiyang Zhang, Rastislav Cernay, Jan Remes,
Alejandro Lucero, Tetsuya Mukawa, Kiran Kumar K,
Bruce Richardson, Jasvinder Singh, Cristian Dumitrescu,
Keith Wiles, Maciej Czekaj, Maxime Coquelin, Tiwei Bie,
Zhihong Wang, Yong Wang, Tianfei zhang, Xiaoyun Li, Satha Rao,
Shreyansh Jain, David Hunt, Byron Marohn, Yipeng Wang,
Thomas Monjalon, Bernard Iremonger, Jiayu Hu, Sameh Gobriel,
Reshma Pattan, Vladimir Medvedkin, Honnappa Nagarahalli,
Kevin Laatz, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Merge all vesions in linker version script files to DPDK_20.0.
This commit was generated by running the following command:
:~/DPDK$ buildtools/update-abi.sh 20.0
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +++----
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++++-----
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 6 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +--
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 ++--
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 ++--
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 ++----
.../rte_distributor_version.map | 4 +-
lib/librte_eal/rte_eal_version.map | 310 +++++++-----------
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +++------
lib/librte_eventdev/rte_eventdev_version.map | 130 +++-----
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +--
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm_version.map | 39 +--
lib/librte_mbuf/rte_mbuf_version.map | 49 +--
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +--
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +---
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +--
154 files changed, 724 insertions(+), 1406 deletions(-)
diff --git a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
index f64b0f9c27..6bcea2cc7f 100644
--- a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
+++ b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
@@ -1,10 +1,10 @@
-DPDK_19.08 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
EXPERIMENTAL {
- global:
+ global:
- fpga_lte_fec_configure;
+ fpga_lte_fec_configure;
};
diff --git a/drivers/baseband/null/rte_pmd_bbdev_null_version.map b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/null/rte_pmd_bbdev_null_version.map
+++ b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
+++ b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map
index a221522c23..9ab8c76eef 100644
--- a/drivers/bus/dpaa/rte_bus_dpaa_version.map
+++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
bman_acquire;
@@ -8,127 +8,94 @@ DPDK_17.11 {
bman_new_pool;
bman_query_free_buffers;
bman_release;
+ bman_thread_irq;
+ dpaa_logtype_eventdev;
dpaa_logtype_mempool;
dpaa_logtype_pmd;
dpaa_netcfg;
+ dpaa_svr_family;
fman_ccsr_map_fd;
fman_dealloc_bufs_mask_hi;
fman_dealloc_bufs_mask_lo;
fman_if_add_mac_addr;
fman_if_clear_mac_addr;
fman_if_disable_rx;
- fman_if_enable_rx;
fman_if_discard_rx_errors;
- fman_if_get_fc_threshold;
+ fman_if_enable_rx;
fman_if_get_fc_quanta;
+ fman_if_get_fc_threshold;
fman_if_get_fdoff;
+ fman_if_get_sg_enable;
fman_if_loopback_disable;
fman_if_loopback_enable;
fman_if_promiscuous_disable;
fman_if_promiscuous_enable;
fman_if_reset_mcast_filter_table;
fman_if_set_bp;
- fman_if_set_fc_threshold;
fman_if_set_fc_quanta;
+ fman_if_set_fc_threshold;
fman_if_set_fdoff;
fman_if_set_ic_params;
fman_if_set_maxfrm;
fman_if_set_mcast_filter_table;
+ fman_if_set_sg;
fman_if_stats_get;
fman_if_stats_get_all;
fman_if_stats_reset;
fman_ip_rev;
+ fsl_qman_fq_portal_create;
netcfg_acquire;
netcfg_release;
of_find_compatible_node;
+ of_get_mac_address;
of_get_property;
+ per_lcore_dpaa_io;
+ per_lcore_held_bufs;
qm_channel_caam;
+ qm_channel_pool1;
+ qman_alloc_cgrid_range;
+ qman_alloc_pool_range;
+ qman_clear_irq;
+ qman_create_cgr;
qman_create_fq;
+ qman_dca_index;
+ qman_delete_cgr;
qman_dequeue;
qman_dqrr_consume;
qman_enqueue;
qman_enqueue_multi;
+ qman_enqueue_multi_fq;
qman_fq_fqid;
+ qman_fq_portal_irqsource_add;
+ qman_fq_portal_irqsource_remove;
+ qman_fq_portal_thread_irq;
qman_fq_state;
qman_global_init;
qman_init_fq;
- qman_poll_dqrr;
- qman_query_fq_np;
- qman_set_vdq;
- qman_reserve_fqid_range;
- qman_volatile_dequeue;
- rte_dpaa_driver_register;
- rte_dpaa_driver_unregister;
- rte_dpaa_mem_ptov;
- rte_dpaa_portal_init;
-
- local: *;
-};
-
-DPDK_18.02 {
- global:
-
- dpaa_logtype_eventdev;
- dpaa_svr_family;
- per_lcore_dpaa_io;
- per_lcore_held_bufs;
- qm_channel_pool1;
- qman_alloc_cgrid_range;
- qman_alloc_pool_range;
- qman_create_cgr;
- qman_dca_index;
- qman_delete_cgr;
- qman_enqueue_multi_fq;
+ qman_irqsource_add;
+ qman_irqsource_remove;
qman_modify_cgr;
qman_oos_fq;
+ qman_poll_dqrr;
qman_portal_dequeue;
qman_portal_poll_rx;
qman_query_fq_frm_cnt;
+ qman_query_fq_np;
qman_release_cgrid_range;
+ qman_reserve_fqid_range;
qman_retire_fq;
+ qman_set_fq_lookup_table;
+ qman_set_vdq;
qman_static_dequeue_add;
- rte_dpaa_portal_fq_close;
- rte_dpaa_portal_fq_init;
-
-} DPDK_17.11;
-
-DPDK_18.08 {
- global:
-
- fman_if_get_sg_enable;
- fman_if_set_sg;
- of_get_mac_address;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
-
- bman_thread_irq;
- fman_if_get_sg_enable;
- fman_if_set_sg;
- qman_clear_irq;
-
- qman_irqsource_add;
- qman_irqsource_remove;
qman_thread_fd;
qman_thread_irq;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- qman_set_fq_lookup_table;
-
-} DPDK_18.11;
-
-DPDK_19.11 {
- global:
-
- fsl_qman_fq_portal_create;
- qman_fq_portal_irqsource_add;
- qman_fq_portal_irqsource_remove;
- qman_fq_portal_thread_irq;
-
-} DPDK_19.05;
+ qman_volatile_dequeue;
+ rte_dpaa_driver_register;
+ rte_dpaa_driver_unregister;
+ rte_dpaa_mem_ptov;
+ rte_dpaa_portal_fq_close;
+ rte_dpaa_portal_fq_init;
+ rte_dpaa_portal_init;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4da787236b..fe45575046 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,32 +1,67 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
+ dpaa2_affine_qbman_ethrx_swp;
dpaa2_affine_qbman_swp;
dpaa2_alloc_dpbp_dev;
dpaa2_alloc_dq_storage;
+ dpaa2_dpbp_supported;
+ dpaa2_dqrr_size;
+ dpaa2_eqcr_size;
dpaa2_free_dpbp_dev;
dpaa2_free_dq_storage;
+ dpaa2_free_eq_descriptors;
+ dpaa2_get_qbman_swp;
+ dpaa2_io_portal;
+ dpaa2_svr_family;
+ dpaa2_virt_mode;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
dpbp_get_num_free_bufs;
dpbp_open;
dpbp_reset;
+ dpci_get_opr;
+ dpci_set_opr;
+ dpci_set_rx_queue;
+ dpcon_get_attributes;
+ dpcon_open;
+ dpdmai_close;
+ dpdmai_disable;
+ dpdmai_enable;
+ dpdmai_get_attributes;
+ dpdmai_get_rx_queue;
+ dpdmai_get_tx_queue;
+ dpdmai_open;
+ dpdmai_set_rx_queue;
+ dpio_add_static_dequeue_channel;
dpio_close;
dpio_disable;
dpio_enable;
dpio_get_attributes;
dpio_open;
+ dpio_remove_static_dequeue_channel;
dpio_reset;
dpio_set_stashing_destination;
+ mc_get_soc_version;
+ mc_get_version;
mc_send_command;
per_lcore__dpaa2_io;
+ per_lcore_dpaa2_held_bufs;
qbman_check_command_complete;
+ qbman_check_new_result;
qbman_eq_desc_clear;
+ qbman_eq_desc_set_dca;
qbman_eq_desc_set_fq;
qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_orp;
qbman_eq_desc_set_qd;
qbman_eq_desc_set_response;
+ qbman_eq_desc_set_token;
+ qbman_fq_query_state;
+ qbman_fq_state_frame_count;
+ qbman_get_dqrr_from_idx;
+ qbman_get_dqrr_idx;
qbman_pull_desc_clear;
qbman_pull_desc_set_fq;
qbman_pull_desc_set_numframes;
@@ -35,112 +70,43 @@ DPDK_17.05 {
qbman_release_desc_set_bpid;
qbman_result_DQ_fd;
qbman_result_DQ_flags;
- qbman_result_has_new_result;
- qbman_swp_acquire;
- qbman_swp_pull;
- qbman_swp_release;
- rte_fslmc_driver_register;
- rte_fslmc_driver_unregister;
- rte_fslmc_vfio_dmamap;
- rte_mcp_ptr_list;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- dpaa2_io_portal;
- dpaa2_get_qbman_swp;
- dpci_set_rx_queue;
- dpcon_open;
- dpcon_get_attributes;
- dpio_add_static_dequeue_channel;
- dpio_remove_static_dequeue_channel;
- mc_get_soc_version;
- mc_get_version;
- qbman_check_new_result;
- qbman_eq_desc_set_dca;
- qbman_get_dqrr_from_idx;
- qbman_get_dqrr_idx;
qbman_result_DQ_fqd_ctx;
+ qbman_result_DQ_odpid;
+ qbman_result_DQ_seqnum;
qbman_result_SCN_state;
+ qbman_result_eqresp_fd;
+ qbman_result_eqresp_rc;
+ qbman_result_eqresp_rspid;
+ qbman_result_eqresp_set_rspid;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
qbman_swp_dqrr_consume;
+ qbman_swp_dqrr_idx_consume;
qbman_swp_dqrr_next;
qbman_swp_enqueue_multiple;
qbman_swp_enqueue_multiple_desc;
+ qbman_swp_enqueue_multiple_fd;
qbman_swp_interrupt_clear_status;
+ qbman_swp_prefetch_dqrr_next;
+ qbman_swp_pull;
qbman_swp_push_set;
+ qbman_swp_release;
rte_dpaa2_alloc_dpci_dev;
- rte_fslmc_object_register;
- rte_global_active_dqs_list;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- dpaa2_dpbp_supported;
rte_dpaa2_dev_type;
+ rte_dpaa2_free_dpci_dev;
rte_dpaa2_intr_disable;
rte_dpaa2_intr_enable;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- dpaa2_svr_family;
- dpaa2_virt_mode;
- per_lcore_dpaa2_held_bufs;
- qbman_fq_query_state;
- qbman_fq_state_frame_count;
- qbman_swp_dqrr_idx_consume;
- qbman_swp_prefetch_dqrr_next;
- rte_fslmc_get_device_count;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- dpaa2_affine_qbman_ethrx_swp;
- dpdmai_close;
- dpdmai_disable;
- dpdmai_enable;
- dpdmai_get_attributes;
- dpdmai_get_rx_queue;
- dpdmai_get_tx_queue;
- dpdmai_open;
- dpdmai_set_rx_queue;
- rte_dpaa2_free_dpci_dev;
rte_dpaa2_memsegs;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
- dpaa2_dqrr_size;
- dpaa2_eqcr_size;
- dpci_get_opr;
- dpci_set_opr;
-
-} DPDK_18.05;
-
-DPDK_19.05 {
- global:
- dpaa2_free_eq_descriptors;
-
- qbman_eq_desc_set_orp;
- qbman_eq_desc_set_token;
- qbman_result_DQ_odpid;
- qbman_result_DQ_seqnum;
- qbman_result_eqresp_fd;
- qbman_result_eqresp_rc;
- qbman_result_eqresp_rspid;
- qbman_result_eqresp_set_rspid;
- qbman_swp_enqueue_multiple_fd;
-} DPDK_18.11;
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+ rte_fslmc_get_device_count;
+ rte_fslmc_object_register;
+ rte_fslmc_vfio_dmamap;
+ rte_global_active_dqs_list;
+ rte_mcp_ptr_list;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map
index 964c9a9c45..05b4a28c1b 100644
--- a/drivers/bus/ifpga/rte_bus_ifpga_version.map
+++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map
@@ -1,17 +1,11 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
- rte_ifpga_get_integer32_arg;
- rte_ifpga_get_string_arg;
rte_ifpga_driver_register;
rte_ifpga_driver_unregister;
+ rte_ifpga_find_afu_by_name;
+ rte_ifpga_get_integer32_arg;
+ rte_ifpga_get_string_arg;
local: *;
};
-
-DPDK_19.05 {
- global:
-
- rte_ifpga_find_afu_by_name;
-
-} DPDK_18.05;
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
index 27e9c4f101..012d817e14 100644
--- a/drivers/bus/pci/rte_bus_pci_version.map
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pci_dump;
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
index 590cf9b437..5abb10ecb0 100644
--- a/drivers/bus/vdev/rte_bus_vdev_version.map
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -1,18 +1,12 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
+ rte_vdev_add_custom_scan;
rte_vdev_init;
rte_vdev_register;
+ rte_vdev_remove_custom_scan;
rte_vdev_uninit;
rte_vdev_unregister;
local: *;
};
-
-DPDK_18.02 {
- global:
-
- rte_vdev_add_custom_scan;
- rte_vdev_remove_custom_scan;
-
-} DPDK_17.11;
diff --git a/drivers/bus/vmbus/rte_bus_vmbus_version.map b/drivers/bus/vmbus/rte_bus_vmbus_version.map
index ae231ad329..cbaaebc06c 100644
--- a/drivers/bus/vmbus/rte_bus_vmbus_version.map
+++ b/drivers/bus/vmbus/rte_bus_vmbus_version.map
@@ -1,6 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_vmbus_chan_close;
@@ -20,6 +18,7 @@ DPDK_18.08 {
rte_vmbus_probe;
rte_vmbus_register;
rte_vmbus_scan;
+ rte_vmbus_set_latency;
rte_vmbus_sub_channel_index;
rte_vmbus_subchan_open;
rte_vmbus_unmap_device;
@@ -27,10 +26,3 @@ DPDK_18.08 {
local: *;
};
-
-DPDK_18.11 {
- global:
-
- rte_vmbus_set_latency;
-
-} DPDK_18.08;
diff --git a/drivers/common/cpt/rte_common_cpt_version.map b/drivers/common/cpt/rte_common_cpt_version.map
index dec614f0de..79fa5751bc 100644
--- a/drivers/common/cpt/rte_common_cpt_version.map
+++ b/drivers/common/cpt/rte_common_cpt_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
cpt_pmd_ops_helper_get_mlen_direct_mode;
cpt_pmd_ops_helper_get_mlen_sg_mode;
+
+ local: *;
};
diff --git a/drivers/common/dpaax/rte_common_dpaax_version.map b/drivers/common/dpaax/rte_common_dpaax_version.map
index 8131c9e305..45d62aea9d 100644
--- a/drivers/common/dpaax/rte_common_dpaax_version.map
+++ b/drivers/common/dpaax/rte_common_dpaax_version.map
@@ -1,11 +1,11 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- dpaax_iova_table_update;
dpaax_iova_table_depopulate;
dpaax_iova_table_dump;
dpaax_iova_table_p;
dpaax_iova_table_populate;
+ dpaax_iova_table_update;
local: *;
};
diff --git a/drivers/common/mvep/rte_common_mvep_version.map b/drivers/common/mvep/rte_common_mvep_version.map
index c71722d79f..030928439d 100644
--- a/drivers/common/mvep/rte_common_mvep_version.map
+++ b/drivers/common/mvep/rte_common_mvep_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- rte_mvep_init;
rte_mvep_deinit;
+ rte_mvep_init;
+
+ local: *;
};
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index a9b3cff9bc..c15fb89112 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,8 +1,10 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
octeontx_logtype_mbox;
+ octeontx_mbox_send;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
- octeontx_mbox_send;
+
+ local: *;
};
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 4400120da0..adad21a2d6 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -1,39 +1,35 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
otx2_dev_active_vfs;
otx2_dev_fini;
otx2_dev_priv_init;
-
+ otx2_disable_irqs;
+ otx2_intra_dev_get_cfg;
otx2_logtype_base;
otx2_logtype_dpi;
otx2_logtype_mbox;
+ otx2_logtype_nix;
otx2_logtype_npa;
otx2_logtype_npc;
- otx2_logtype_nix;
otx2_logtype_sso;
- otx2_logtype_tm;
otx2_logtype_tim;
-
+ otx2_logtype_tm;
otx2_mbox_alloc_msg_rsp;
otx2_mbox_get_rsp;
otx2_mbox_get_rsp_tmo;
otx2_mbox_id2name;
otx2_mbox_msg_send;
otx2_mbox_wait_for_rsp;
-
- otx2_intra_dev_get_cfg;
otx2_npa_lf_active;
otx2_npa_lf_obj_get;
otx2_npa_lf_obj_ref;
otx2_npa_pf_func_get;
otx2_npa_set_defaults;
+ otx2_register_irq;
otx2_sso_pf_func_get;
otx2_sso_pf_func_set;
-
- otx2_disable_irqs;
otx2_unregister_irq;
- otx2_register_irq;
local: *;
};
diff --git a/drivers/compress/isal/rte_pmd_isal_version.map b/drivers/compress/isal/rte_pmd_isal_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/compress/isal/rte_pmd_isal_version.map
+++ b/drivers/compress/isal/rte_pmd_isal_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
+++ b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/qat/rte_pmd_qat_version.map b/drivers/compress/qat/rte_pmd_qat_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/qat/rte_pmd_qat_version.map
+++ b/drivers/compress/qat/rte_pmd_qat_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/zlib/rte_pmd_zlib_version.map b/drivers/compress/zlib/rte_pmd_zlib_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/zlib/rte_pmd_zlib_version.map
+++ b/drivers/compress/zlib/rte_pmd_zlib_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
+++ b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
+++ b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/armv8/rte_pmd_armv8_version.map b/drivers/crypto/armv8/rte_pmd_armv8_version.map
index 1f84b68a83..f9f17e4f6e 100644
--- a/drivers/crypto/armv8/rte_pmd_armv8_version.map
+++ b/drivers/crypto/armv8/rte_pmd_armv8_version.map
@@ -1,3 +1,3 @@
-DPDK_17.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
+++ b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/ccp/rte_pmd_ccp_version.map b/drivers/crypto/ccp/rte_pmd_ccp_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/crypto/ccp/rte_pmd_ccp_version.map
+++ b/drivers/crypto/ccp/rte_pmd_ccp_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
index 0bfb986d0b..5952d645fd 100644
--- a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
+++ b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_18.11 {
+DPDK_20.0 {
global:
dpaa2_sec_eventq_attach;
dpaa2_sec_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
index cc7f2162e0..8580fa13db 100644
--- a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
+++ b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_19.11 {
+DPDK_20.0 {
global:
dpaa_sec_eventq_attach;
dpaa_sec_eventq_detach;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
index 8ffeca934e..f9f17e4f6e 100644
--- a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
+++ b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
@@ -1,3 +1,3 @@
-DPDK_16.07 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
+++ b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
index 406964d1fc..f9f17e4f6e 100644
--- a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
+++ b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/null/rte_pmd_null_crypto_version.map b/drivers/crypto/null/rte_pmd_null_crypto_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/null/rte_pmd_null_crypto_version.map
+++ b/drivers/crypto/null/rte_pmd_null_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
+++ b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/openssl/rte_pmd_openssl_version.map b/drivers/crypto/openssl/rte_pmd_openssl_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/openssl/rte_pmd_openssl_version.map
+++ b/drivers/crypto/openssl/rte_pmd_openssl_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
index 5c43127cf2..077afedce7 100644
--- a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
+++ b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
@@ -1,21 +1,16 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_cryptodev_scheduler_load_user_scheduler;
- rte_cryptodev_scheduler_slave_attach;
- rte_cryptodev_scheduler_slave_detach;
- rte_cryptodev_scheduler_ordering_set;
- rte_cryptodev_scheduler_ordering_get;
-
-};
-
-DPDK_17.05 {
- global:
-
rte_cryptodev_scheduler_mode_get;
rte_cryptodev_scheduler_mode_set;
rte_cryptodev_scheduler_option_get;
rte_cryptodev_scheduler_option_set;
+ rte_cryptodev_scheduler_ordering_get;
+ rte_cryptodev_scheduler_ordering_set;
+ rte_cryptodev_scheduler_slave_attach;
+ rte_cryptodev_scheduler_slave_detach;
rte_cryptodev_scheduler_slaves_get;
-} DPDK_17.02;
+ local: *;
+};
diff --git a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
+++ b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
+++ b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/zuc/rte_pmd_zuc_version.map b/drivers/crypto/zuc/rte_pmd_zuc_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/zuc/rte_pmd_zuc_version.map
+++ b/drivers/crypto/zuc/rte_pmd_zuc_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
+++ b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
index 1c0b7559dc..f9f17e4f6e 100644
--- a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
+++ b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dsw/rte_pmd_dsw_event_version.map b/drivers/event/dsw/rte_pmd_dsw_event_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/event/dsw/rte_pmd_dsw_event_version.map
+++ b/drivers/event/dsw/rte_pmd_dsw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
+++ b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
index 41c65c8c9c..f9f17e4f6e 100644
--- a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
+++ b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
+DPDK_20.0 {
local: *;
};
-
diff --git a/drivers/event/opdl/rte_pmd_opdl_event_version.map b/drivers/event/opdl/rte_pmd_opdl_event_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/event/opdl/rte_pmd_opdl_event_version.map
+++ b/drivers/event/opdl/rte_pmd_opdl_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
+++ b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/sw/rte_pmd_sw_event_version.map b/drivers/event/sw/rte_pmd_sw_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/sw/rte_pmd_sw_event_version.map
+++ b/drivers/event/sw/rte_pmd_sw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/bucket/rte_mempool_bucket_version.map b/drivers/mempool/bucket/rte_mempool_bucket_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/mempool/bucket/rte_mempool_bucket_version.map
+++ b/drivers/mempool/bucket/rte_mempool_bucket_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
index 60bf50b2d1..9eebaf7ffd 100644
--- a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
+++ b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_dpaa_bpid_info;
diff --git a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
index b45e7a9ac1..cd4bc88273 100644
--- a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
+++ b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
@@ -1,16 +1,10 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_dpaa2_bpid_info;
rte_dpaa2_mbuf_alloc_bulk;
-
- local: *;
-};
-
-DPDK_18.05 {
- global:
-
rte_dpaa2_mbuf_from_buf_addr;
rte_dpaa2_mbuf_pool_bpid;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
+++ b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
index d703368c31..d4f81aed8e 100644
--- a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
+++ b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
@@ -1,8 +1,8 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
- otx2_npa_lf_init;
otx2_npa_lf_fini;
+ otx2_npa_lf_init;
local: *;
};
diff --git a/drivers/mempool/ring/rte_mempool_ring_version.map b/drivers/mempool/ring/rte_mempool_ring_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/ring/rte_mempool_ring_version.map
+++ b/drivers/mempool/ring/rte_mempool_ring_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/stack/rte_mempool_stack_version.map b/drivers/mempool/stack/rte_mempool_stack_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/stack/rte_mempool_stack_version.map
+++ b/drivers/mempool/stack/rte_mempool_stack_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map b/drivers/net/af_packet/rte_pmd_af_packet_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
+++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
index c6db030fe6..f9f17e4f6e 100644
--- a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
+++ b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
@@ -1,3 +1,3 @@
-DPDK_19.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ark/rte_pmd_ark_version.map b/drivers/net/ark/rte_pmd_ark_version.map
index 1062e0429f..f9f17e4f6e 100644
--- a/drivers/net/ark/rte_pmd_ark_version.map
+++ b/drivers/net/ark/rte_pmd_ark_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
- local: *;
-
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/atlantic/rte_pmd_atlantic_version.map b/drivers/net/atlantic/rte_pmd_atlantic_version.map
index b16faa999f..9b04838d84 100644
--- a/drivers/net/atlantic/rte_pmd_atlantic_version.map
+++ b/drivers/net/atlantic/rte_pmd_atlantic_version.map
@@ -1,5 +1,4 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
@@ -13,4 +12,3 @@ EXPERIMENTAL {
rte_pmd_atl_macsec_select_txsa;
rte_pmd_atl_macsec_select_rxsa;
};
-
diff --git a/drivers/net/avp/rte_pmd_avp_version.map b/drivers/net/avp/rte_pmd_avp_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/net/avp/rte_pmd_avp_version.map
+++ b/drivers/net/avp/rte_pmd_avp_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/axgbe/rte_pmd_axgbe_version.map b/drivers/net/axgbe/rte_pmd_axgbe_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/net/axgbe/rte_pmd_axgbe_version.map
+++ b/drivers/net/axgbe/rte_pmd_axgbe_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
+++ b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 4750d40ad6..bb52562347 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_pmd_bnxt_get_vf_rx_status;
@@ -10,13 +10,13 @@ DPDK_17.08 {
rte_pmd_bnxt_set_tx_loopback;
rte_pmd_bnxt_set_vf_mac_addr;
rte_pmd_bnxt_set_vf_mac_anti_spoof;
+ rte_pmd_bnxt_set_vf_persist_stats;
rte_pmd_bnxt_set_vf_rate_limit;
rte_pmd_bnxt_set_vf_rxmode;
rte_pmd_bnxt_set_vf_vlan_anti_spoof;
rte_pmd_bnxt_set_vf_vlan_filter;
rte_pmd_bnxt_set_vf_vlan_insert;
rte_pmd_bnxt_set_vf_vlan_stripq;
- rte_pmd_bnxt_set_vf_persist_stats;
local: *;
};
diff --git a/drivers/net/bonding/rte_pmd_bond_version.map b/drivers/net/bonding/rte_pmd_bond_version.map
index 00d955c481..270c7d5d55 100644
--- a/drivers/net/bonding/rte_pmd_bond_version.map
+++ b/drivers/net/bonding/rte_pmd_bond_version.map
@@ -1,9 +1,21 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_bond_8023ad_agg_selection_get;
+ rte_eth_bond_8023ad_agg_selection_set;
+ rte_eth_bond_8023ad_conf_get;
+ rte_eth_bond_8023ad_dedicated_queues_disable;
+ rte_eth_bond_8023ad_dedicated_queues_enable;
+ rte_eth_bond_8023ad_ext_collect;
+ rte_eth_bond_8023ad_ext_collect_get;
+ rte_eth_bond_8023ad_ext_distrib;
+ rte_eth_bond_8023ad_ext_distrib_get;
+ rte_eth_bond_8023ad_ext_slowtx;
+ rte_eth_bond_8023ad_setup;
rte_eth_bond_8023ad_slave_info;
rte_eth_bond_active_slaves_get;
rte_eth_bond_create;
+ rte_eth_bond_free;
rte_eth_bond_link_monitoring_set;
rte_eth_bond_mac_address_reset;
rte_eth_bond_mac_address_set;
@@ -19,36 +31,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- rte_eth_bond_free;
-
-} DPDK_2.0;
-
-DPDK_16.04 {
-};
-
-DPDK_16.07 {
- global:
-
- rte_eth_bond_8023ad_ext_collect;
- rte_eth_bond_8023ad_ext_collect_get;
- rte_eth_bond_8023ad_ext_distrib;
- rte_eth_bond_8023ad_ext_distrib_get;
- rte_eth_bond_8023ad_ext_slowtx;
-
-} DPDK_16.04;
-
-DPDK_17.08 {
- global:
-
- rte_eth_bond_8023ad_dedicated_queues_enable;
- rte_eth_bond_8023ad_dedicated_queues_disable;
- rte_eth_bond_8023ad_agg_selection_get;
- rte_eth_bond_8023ad_agg_selection_set;
- rte_eth_bond_8023ad_conf_get;
- rte_eth_bond_8023ad_setup;
-
-} DPDK_16.07;
diff --git a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
+++ b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/dpaa/rte_pmd_dpaa_version.map b/drivers/net/dpaa/rte_pmd_dpaa_version.map
index 8cb4500b51..f403a1526d 100644
--- a/drivers/net/dpaa/rte_pmd_dpaa_version.map
+++ b/drivers/net/dpaa/rte_pmd_dpaa_version.map
@@ -1,12 +1,9 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
dpaa_eth_eventq_attach;
dpaa_eth_eventq_detach;
rte_pmd_dpaa_set_tx_loopback;
-} DPDK_17.11;
+
+ local: *;
+};
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
index d1b4cdb232..f2bb793319 100644
--- a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -1,15 +1,11 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_17.11 {
+DPDK_20.0 {
global:
dpaa2_eth_eventq_attach;
dpaa2_eth_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
@@ -17,4 +13,4 @@ EXPERIMENTAL {
rte_pmd_dpaa2_mux_flow_create;
rte_pmd_dpaa2_set_custom_hash;
rte_pmd_dpaa2_set_timestamp;
-} DPDK_17.11;
+};
diff --git a/drivers/net/e1000/rte_pmd_e1000_version.map b/drivers/net/e1000/rte_pmd_e1000_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/e1000/rte_pmd_e1000_version.map
+++ b/drivers/net/e1000/rte_pmd_e1000_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ena/rte_pmd_ena_version.map b/drivers/net/ena/rte_pmd_ena_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/ena/rte_pmd_ena_version.map
+++ b/drivers/net/ena/rte_pmd_ena_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/net/enetc/rte_pmd_enetc_version.map
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enic/rte_pmd_enic_version.map b/drivers/net/enic/rte_pmd_enic_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/enic/rte_pmd_enic_version.map
+++ b/drivers/net/enic/rte_pmd_enic_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/failsafe/rte_pmd_failsafe_version.map b/drivers/net/failsafe/rte_pmd_failsafe_version.map
index b6d2840be4..f9f17e4f6e 100644
--- a/drivers/net/failsafe/rte_pmd_failsafe_version.map
+++ b/drivers/net/failsafe/rte_pmd_failsafe_version.map
@@ -1,4 +1,3 @@
-DPDK_17.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/fm10k/rte_pmd_fm10k_version.map b/drivers/net/fm10k/rte_pmd_fm10k_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/fm10k/rte_pmd_fm10k_version.map
+++ b/drivers/net/fm10k/rte_pmd_fm10k_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hinic/rte_pmd_hinic_version.map b/drivers/net/hinic/rte_pmd_hinic_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/hinic/rte_pmd_hinic_version.map
+++ b/drivers/net/hinic/rte_pmd_hinic_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hns3/rte_pmd_hns3_version.map b/drivers/net/hns3/rte_pmd_hns3_version.map
index 35e5f2debb..f9f17e4f6e 100644
--- a/drivers/net/hns3/rte_pmd_hns3_version.map
+++ b/drivers/net/hns3/rte_pmd_hns3_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index cccd5768c2..a80e69b93e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -1,23 +1,34 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_i40e_add_vf_mac_addr;
+ rte_pmd_i40e_flow_add_del_packet_template;
+ rte_pmd_i40e_flow_type_mapping_get;
+ rte_pmd_i40e_flow_type_mapping_reset;
+ rte_pmd_i40e_flow_type_mapping_update;
+ rte_pmd_i40e_get_ddp_info;
+ rte_pmd_i40e_get_ddp_list;
rte_pmd_i40e_get_vf_stats;
+ rte_pmd_i40e_inset_get;
+ rte_pmd_i40e_inset_set;
rte_pmd_i40e_ping_vfs;
+ rte_pmd_i40e_process_ddp_package;
rte_pmd_i40e_ptype_mapping_get;
rte_pmd_i40e_ptype_mapping_replace;
rte_pmd_i40e_ptype_mapping_reset;
rte_pmd_i40e_ptype_mapping_update;
+ rte_pmd_i40e_query_vfid_by_mac;
rte_pmd_i40e_reset_vf_stats;
+ rte_pmd_i40e_rss_queue_region_conf;
+ rte_pmd_i40e_set_tc_strict_prio;
rte_pmd_i40e_set_tx_loopback;
rte_pmd_i40e_set_vf_broadcast;
rte_pmd_i40e_set_vf_mac_addr;
rte_pmd_i40e_set_vf_mac_anti_spoof;
+ rte_pmd_i40e_set_vf_max_bw;
rte_pmd_i40e_set_vf_multicast_promisc;
+ rte_pmd_i40e_set_vf_tc_bw_alloc;
+ rte_pmd_i40e_set_vf_tc_max_bw;
rte_pmd_i40e_set_vf_unicast_promisc;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_vf_vlan_filter;
@@ -25,43 +36,5 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_vlan_stripq;
rte_pmd_i40e_set_vf_vlan_tag;
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_pmd_i40e_set_tc_strict_prio;
- rte_pmd_i40e_set_vf_max_bw;
- rte_pmd_i40e_set_vf_tc_bw_alloc;
- rte_pmd_i40e_set_vf_tc_max_bw;
- rte_pmd_i40e_process_ddp_package;
- rte_pmd_i40e_get_ddp_list;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_i40e_get_ddp_info;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_pmd_i40e_add_vf_mac_addr;
- rte_pmd_i40e_flow_add_del_packet_template;
- rte_pmd_i40e_flow_type_mapping_update;
- rte_pmd_i40e_flow_type_mapping_get;
- rte_pmd_i40e_flow_type_mapping_reset;
- rte_pmd_i40e_query_vfid_by_mac;
- rte_pmd_i40e_rss_queue_region_conf;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_pmd_i40e_inset_get;
- rte_pmd_i40e_inset_set;
-} DPDK_17.11;
\ No newline at end of file
+ local: *;
+};
diff --git a/drivers/net/iavf/rte_pmd_iavf_version.map b/drivers/net/iavf/rte_pmd_iavf_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/iavf/rte_pmd_iavf_version.map
+++ b/drivers/net/iavf/rte_pmd_iavf_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ice/rte_pmd_ice_version.map b/drivers/net/ice/rte_pmd_ice_version.map
index 7b23b609da..f9f17e4f6e 100644
--- a/drivers/net/ice/rte_pmd_ice_version.map
+++ b/drivers/net/ice/rte_pmd_ice_version.map
@@ -1,4 +1,3 @@
-DPDK_19.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ifc/rte_pmd_ifc_version.map b/drivers/net/ifc/rte_pmd_ifc_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/net/ifc/rte_pmd_ifc_version.map
+++ b/drivers/net/ifc/rte_pmd_ifc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
+++ b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index c814f96d72..21534dbc3d 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
- rte_pmd_ixgbe_set_all_queues_drop_en;
- rte_pmd_ixgbe_set_tx_loopback;
- rte_pmd_ixgbe_set_vf_mac_addr;
- rte_pmd_ixgbe_set_vf_mac_anti_spoof;
- rte_pmd_ixgbe_set_vf_split_drop_en;
- rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
- rte_pmd_ixgbe_set_vf_vlan_insert;
- rte_pmd_ixgbe_set_vf_vlan_stripq;
-} DPDK_2.0;
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_ixgbe_bypass_event_show;
+ rte_pmd_ixgbe_bypass_event_store;
+ rte_pmd_ixgbe_bypass_init;
+ rte_pmd_ixgbe_bypass_state_set;
+ rte_pmd_ixgbe_bypass_state_show;
+ rte_pmd_ixgbe_bypass_ver_show;
+ rte_pmd_ixgbe_bypass_wd_reset;
+ rte_pmd_ixgbe_bypass_wd_timeout_show;
+ rte_pmd_ixgbe_bypass_wd_timeout_store;
rte_pmd_ixgbe_macsec_config_rxsc;
rte_pmd_ixgbe_macsec_config_txsc;
rte_pmd_ixgbe_macsec_disable;
rte_pmd_ixgbe_macsec_enable;
rte_pmd_ixgbe_macsec_select_rxsa;
rte_pmd_ixgbe_macsec_select_txsa;
+ rte_pmd_ixgbe_ping_vf;
+ rte_pmd_ixgbe_set_all_queues_drop_en;
+ rte_pmd_ixgbe_set_tc_bw_alloc;
+ rte_pmd_ixgbe_set_tx_loopback;
+ rte_pmd_ixgbe_set_vf_mac_addr;
+ rte_pmd_ixgbe_set_vf_mac_anti_spoof;
rte_pmd_ixgbe_set_vf_rate_limit;
rte_pmd_ixgbe_set_vf_rx;
rte_pmd_ixgbe_set_vf_rxmode;
+ rte_pmd_ixgbe_set_vf_split_drop_en;
rte_pmd_ixgbe_set_vf_tx;
+ rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
rte_pmd_ixgbe_set_vf_vlan_filter;
-} DPDK_16.11;
+ rte_pmd_ixgbe_set_vf_vlan_insert;
+ rte_pmd_ixgbe_set_vf_vlan_stripq;
-DPDK_17.05 {
- global:
-
- rte_pmd_ixgbe_ping_vf;
- rte_pmd_ixgbe_set_tc_bw_alloc;
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_ixgbe_bypass_event_show;
- rte_pmd_ixgbe_bypass_event_store;
- rte_pmd_ixgbe_bypass_init;
- rte_pmd_ixgbe_bypass_state_set;
- rte_pmd_ixgbe_bypass_state_show;
- rte_pmd_ixgbe_bypass_ver_show;
- rte_pmd_ixgbe_bypass_wd_reset;
- rte_pmd_ixgbe_bypass_wd_timeout_show;
- rte_pmd_ixgbe_bypass_wd_timeout_store;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/net/kni/rte_pmd_kni_version.map b/drivers/net/kni/rte_pmd_kni_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/kni/rte_pmd_kni_version.map
+++ b/drivers/net/kni/rte_pmd_kni_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/liquidio/rte_pmd_liquidio_version.map b/drivers/net/liquidio/rte_pmd_liquidio_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/liquidio/rte_pmd_liquidio_version.map
+++ b/drivers/net/liquidio/rte_pmd_liquidio_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/memif/rte_pmd_memif_version.map b/drivers/net/memif/rte_pmd_memif_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/net/memif/rte_pmd_memif_version.map
+++ b/drivers/net/memif/rte_pmd_memif_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/mlx4/rte_pmd_mlx4_version.map b/drivers/net/mlx4/rte_pmd_mlx4_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/mlx4/rte_pmd_mlx4_version.map
+++ b/drivers/net/mlx4/rte_pmd_mlx4_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mlx5/rte_pmd_mlx5_version.map b/drivers/net/mlx5/rte_pmd_mlx5_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/mlx5/rte_pmd_mlx5_version.map
+++ b/drivers/net/mlx5/rte_pmd_mlx5_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvneta/rte_pmd_mvneta_version.map b/drivers/net/mvneta/rte_pmd_mvneta_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/net/mvneta/rte_pmd_mvneta_version.map
+++ b/drivers/net/mvneta/rte_pmd_mvneta_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
+++ b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/netvsc/rte_pmd_netvsc_version.map b/drivers/net/netvsc/rte_pmd_netvsc_version.map
index d534019a6b..f9f17e4f6e 100644
--- a/drivers/net/netvsc/rte_pmd_netvsc_version.map
+++ b/drivers/net/netvsc/rte_pmd_netvsc_version.map
@@ -1,5 +1,3 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfb/rte_pmd_nfb_version.map b/drivers/net/nfb/rte_pmd_nfb_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/nfb/rte_pmd_nfb_version.map
+++ b/drivers/net/nfb/rte_pmd_nfb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfp/rte_pmd_nfp_version.map b/drivers/net/nfp/rte_pmd_nfp_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/nfp/rte_pmd_nfp_version.map
+++ b/drivers/net/nfp/rte_pmd_nfp_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/null/rte_pmd_null_version.map b/drivers/net/null/rte_pmd_null_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/null/rte_pmd_null_version.map
+++ b/drivers/net/null/rte_pmd_null_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/octeontx/rte_pmd_octeontx_version.map b/drivers/net/octeontx/rte_pmd_octeontx_version.map
index a3161b14d0..f7cae02fac 100644
--- a/drivers/net/octeontx/rte_pmd_octeontx_version.map
+++ b/drivers/net/octeontx/rte_pmd_octeontx_version.map
@@ -1,11 +1,7 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.02 {
+DPDK_20.0 {
global:
rte_octeontx_pchan_map;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
+++ b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/pcap/rte_pmd_pcap_version.map b/drivers/net/pcap/rte_pmd_pcap_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/pcap/rte_pmd_pcap_version.map
+++ b/drivers/net/pcap/rte_pmd_pcap_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/qede/rte_pmd_qede_version.map b/drivers/net/qede/rte_pmd_qede_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/qede/rte_pmd_qede_version.map
+++ b/drivers/net/qede/rte_pmd_qede_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ring/rte_pmd_ring_version.map b/drivers/net/ring/rte_pmd_ring_version.map
index 1f785d9409..ebb6be2733 100644
--- a/drivers/net/ring/rte_pmd_ring_version.map
+++ b/drivers/net/ring/rte_pmd_ring_version.map
@@ -1,14 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_from_ring;
rte_eth_from_rings;
local: *;
};
-
-DPDK_2.2 {
- global:
-
- rte_eth_from_ring;
-
-} DPDK_2.0;
diff --git a/drivers/net/sfc/rte_pmd_sfc_version.map b/drivers/net/sfc/rte_pmd_sfc_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/sfc/rte_pmd_sfc_version.map
+++ b/drivers/net/sfc/rte_pmd_sfc_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/softnic/rte_pmd_softnic_version.map b/drivers/net/softnic/rte_pmd_softnic_version.map
index bc44b06f98..50f113d5a2 100644
--- a/drivers/net/softnic/rte_pmd_softnic_version.map
+++ b/drivers/net/softnic/rte_pmd_softnic_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pmd_softnic_run;
diff --git a/drivers/net/szedata2/rte_pmd_szedata2_version.map b/drivers/net/szedata2/rte_pmd_szedata2_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/szedata2/rte_pmd_szedata2_version.map
+++ b/drivers/net/szedata2/rte_pmd_szedata2_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/tap/rte_pmd_tap_version.map
+++ b/drivers/net/tap/rte_pmd_tap_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/thunderx/rte_pmd_thunderx_version.map b/drivers/net/thunderx/rte_pmd_thunderx_version.map
index 1901bcb3b3..f9f17e4f6e 100644
--- a/drivers/net/thunderx/rte_pmd_thunderx_version.map
+++ b/drivers/net/thunderx/rte_pmd_thunderx_version.map
@@ -1,4 +1,3 @@
-DPDK_16.07 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
+++ b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vhost/rte_pmd_vhost_version.map b/drivers/net/vhost/rte_pmd_vhost_version.map
index 695db85749..16b591ccc4 100644
--- a/drivers/net/vhost/rte_pmd_vhost_version.map
+++ b/drivers/net/vhost/rte_pmd_vhost_version.map
@@ -1,13 +1,8 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
rte_eth_vhost_get_queue_event;
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
rte_eth_vhost_get_vid_from_port_id;
+
+ local: *;
};
diff --git a/drivers/net/virtio/rte_pmd_virtio_version.map b/drivers/net/virtio/rte_pmd_virtio_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/virtio/rte_pmd_virtio_version.map
+++ b/drivers/net/virtio/rte_pmd_virtio_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
+++ b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
+++ b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
index d16a136fc8..ca6a0d7626 100644
--- a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
@@ -1,4 +1,4 @@
-DPDK_19.05 {
+DPDK_20.0 {
global:
rte_qdma_attr_get;
@@ -9,9 +9,9 @@ DPDK_19.05 {
rte_qdma_start;
rte_qdma_stop;
rte_qdma_vq_create;
- rte_qdma_vq_destroy;
rte_qdma_vq_dequeue;
rte_qdma_vq_dequeue_multi;
+ rte_qdma_vq_destroy;
rte_qdma_vq_enqueue;
rte_qdma_vq_enqueue_multi;
rte_qdma_vq_stats;
diff --git a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
+++ b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ioat/rte_rawdev_ioat_version.map b/drivers/raw/ioat/rte_rawdev_ioat_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/ioat/rte_rawdev_ioat_version.map
+++ b/drivers/raw/ioat/rte_rawdev_ioat_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ntb/rte_rawdev_ntb_version.map b/drivers/raw/ntb/rte_rawdev_ntb_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/raw/ntb/rte_rawdev_ntb_version.map
+++ b/drivers/raw/ntb/rte_rawdev_ntb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
+++ b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
+++ b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/lib/librte_acl/rte_acl_version.map b/lib/librte_acl/rte_acl_version.map
index b09370a104..c3daca8115 100644
--- a/lib/librte_acl/rte_acl_version.map
+++ b/lib/librte_acl/rte_acl_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_acl_add_rules;
diff --git a/lib/librte_bbdev/rte_bbdev_version.map b/lib/librte_bbdev/rte_bbdev_version.map
index 3624eb1cb4..45b560dbe7 100644
--- a/lib/librte_bbdev/rte_bbdev_version.map
+++ b/lib/librte_bbdev/rte_bbdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_bitratestats/rte_bitratestats_version.map b/lib/librte_bitratestats/rte_bitratestats_version.map
index fe7454452d..88fc2912db 100644
--- a/lib/librte_bitratestats/rte_bitratestats_version.map
+++ b/lib/librte_bitratestats/rte_bitratestats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_stats_bitrate_calc;
diff --git a/lib/librte_bpf/rte_bpf_version.map b/lib/librte_bpf/rte_bpf_version.map
index a203e088ea..e1ec43faa0 100644
--- a/lib/librte_bpf/rte_bpf_version.map
+++ b/lib/librte_bpf/rte_bpf_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cfgfile/rte_cfgfile_version.map b/lib/librte_cfgfile/rte_cfgfile_version.map
index a0a11cea8d..906eee96bf 100644
--- a/lib/librte_cfgfile/rte_cfgfile_version.map
+++ b/lib/librte_cfgfile/rte_cfgfile_version.map
@@ -1,40 +1,22 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_cfgfile_add_entry;
+ rte_cfgfile_add_section;
rte_cfgfile_close;
+ rte_cfgfile_create;
rte_cfgfile_get_entry;
rte_cfgfile_has_entry;
rte_cfgfile_has_section;
rte_cfgfile_load;
+ rte_cfgfile_load_with_params;
rte_cfgfile_num_sections;
+ rte_cfgfile_save;
rte_cfgfile_section_entries;
+ rte_cfgfile_section_entries_by_index;
rte_cfgfile_section_num_entries;
rte_cfgfile_sections;
+ rte_cfgfile_set_entry;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_cfgfile_section_entries_by_index;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_cfgfile_load_with_params;
-
-} DPDK_16.04;
-
-DPDK_17.11 {
- global:
-
- rte_cfgfile_add_entry;
- rte_cfgfile_add_section;
- rte_cfgfile_create;
- rte_cfgfile_save;
- rte_cfgfile_set_entry;
-
-} DPDK_17.05;
diff --git a/lib/librte_cmdline/rte_cmdline_version.map b/lib/librte_cmdline/rte_cmdline_version.map
index 04bcb387f2..95fce812ff 100644
--- a/lib/librte_cmdline/rte_cmdline_version.map
+++ b/lib/librte_cmdline/rte_cmdline_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
cirbuf_add_buf_head;
@@ -40,6 +40,7 @@ DPDK_2.0 {
cmdline_parse_num;
cmdline_parse_portlist;
cmdline_parse_string;
+ cmdline_poll;
cmdline_printf;
cmdline_quit;
cmdline_set_prompt;
@@ -68,10 +69,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- cmdline_poll;
-
-} DPDK_2.0;
diff --git a/lib/librte_compressdev/rte_compressdev_version.map b/lib/librte_compressdev/rte_compressdev_version.map
index e2a108b650..cfcd50ac1c 100644
--- a/lib/librte_compressdev/rte_compressdev_version.map
+++ b/lib/librte_compressdev/rte_compressdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 3deb265ac2..1dd1e259a0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -1,92 +1,62 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
- rte_cryptodevs;
+ rte_crypto_aead_algorithm_strings;
+ rte_crypto_aead_operation_strings;
+ rte_crypto_auth_algorithm_strings;
+ rte_crypto_auth_operation_strings;
+ rte_crypto_cipher_algorithm_strings;
+ rte_crypto_cipher_operation_strings;
+ rte_crypto_op_pool_create;
+ rte_cryptodev_allocate_driver;
rte_cryptodev_callback_register;
rte_cryptodev_callback_unregister;
rte_cryptodev_close;
- rte_cryptodev_count;
rte_cryptodev_configure;
+ rte_cryptodev_count;
+ rte_cryptodev_device_count_by_driver;
+ rte_cryptodev_devices_get;
+ rte_cryptodev_driver_id_get;
+ rte_cryptodev_driver_name_get;
+ rte_cryptodev_get_aead_algo_enum;
+ rte_cryptodev_get_auth_algo_enum;
+ rte_cryptodev_get_cipher_algo_enum;
rte_cryptodev_get_dev_id;
rte_cryptodev_get_feature_name;
+ rte_cryptodev_get_sec_ctx;
rte_cryptodev_info_get;
+ rte_cryptodev_name_get;
rte_cryptodev_pmd_allocate;
rte_cryptodev_pmd_callback_process;
+ rte_cryptodev_pmd_create;
+ rte_cryptodev_pmd_create_dev_name;
+ rte_cryptodev_pmd_destroy;
+ rte_cryptodev_pmd_get_dev;
+ rte_cryptodev_pmd_get_named_dev;
+ rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_pmd_parse_input_args;
rte_cryptodev_pmd_release_device;
- rte_cryptodev_sym_session_create;
- rte_cryptodev_sym_session_free;
+ rte_cryptodev_queue_pair_count;
+ rte_cryptodev_queue_pair_setup;
rte_cryptodev_socket_id;
rte_cryptodev_start;
rte_cryptodev_stats_get;
rte_cryptodev_stats_reset;
rte_cryptodev_stop;
- rte_cryptodev_queue_pair_count;
- rte_cryptodev_queue_pair_setup;
- rte_crypto_op_pool_create;
-
- local: *;
-};
-
-DPDK_17.02 {
- global:
-
- rte_cryptodev_devices_get;
- rte_cryptodev_pmd_create_dev_name;
- rte_cryptodev_pmd_get_dev;
- rte_cryptodev_pmd_get_named_dev;
- rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_sym_capability_check_aead;
rte_cryptodev_sym_capability_check_auth;
rte_cryptodev_sym_capability_check_cipher;
rte_cryptodev_sym_capability_get;
- rte_crypto_auth_algorithm_strings;
- rte_crypto_auth_operation_strings;
- rte_crypto_cipher_algorithm_strings;
- rte_crypto_cipher_operation_strings;
-
-} DPDK_16.04;
-
-DPDK_17.05 {
- global:
-
- rte_cryptodev_get_auth_algo_enum;
- rte_cryptodev_get_cipher_algo_enum;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_cryptodev_allocate_driver;
- rte_cryptodev_device_count_by_driver;
- rte_cryptodev_driver_id_get;
- rte_cryptodev_driver_name_get;
- rte_cryptodev_get_aead_algo_enum;
- rte_cryptodev_sym_capability_check_aead;
- rte_cryptodev_sym_session_init;
- rte_cryptodev_sym_session_clear;
- rte_crypto_aead_algorithm_strings;
- rte_crypto_aead_operation_strings;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_cryptodev_get_sec_ctx;
- rte_cryptodev_name_get;
- rte_cryptodev_pmd_create;
- rte_cryptodev_pmd_destroy;
- rte_cryptodev_pmd_parse_input_args;
-
-} DPDK_17.08;
-
-DPDK_18.05 {
- global:
-
rte_cryptodev_sym_get_header_session_size;
rte_cryptodev_sym_get_private_session_size;
+ rte_cryptodev_sym_session_clear;
+ rte_cryptodev_sym_session_create;
+ rte_cryptodev_sym_session_free;
+ rte_cryptodev_sym_session_init;
+ rte_cryptodevs;
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_distributor/rte_distributor_version.map b/lib/librte_distributor/rte_distributor_version.map
index 00e26b4804..1b7c643005 100644
--- a/lib/librte_distributor/rte_distributor_version.map
+++ b/lib/librte_distributor/rte_distributor_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_distributor_clear_returns;
@@ -10,4 +10,6 @@ DPDK_17.05 {
rte_distributor_request_pkt;
rte_distributor_return_pkt;
rte_distributor_returned_pkts;
+
+ local: *;
};
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7cbf82d37b..8c41999317 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
__rte_panic;
@@ -7,46 +7,111 @@ DPDK_2.0 {
lcore_config;
per_lcore__lcore_id;
per_lcore__rte_errno;
+ rte_bus_dump;
+ rte_bus_find;
+ rte_bus_find_by_device;
+ rte_bus_find_by_name;
+ rte_bus_get_iommu_class;
+ rte_bus_probe;
+ rte_bus_register;
+ rte_bus_scan;
+ rte_bus_unregister;
rte_calloc;
rte_calloc_socket;
rte_cpu_check_supported;
rte_cpu_get_flag_enabled;
+ rte_cpu_get_flag_name;
+ rte_cpu_is_supported;
+ rte_ctrl_thread_create;
rte_cycles_vmware_tsc_map;
rte_delay_us;
+ rte_delay_us_block;
+ rte_delay_us_callback_register;
+ rte_dev_is_probed;
+ rte_dev_probe;
+ rte_dev_remove;
+ rte_devargs_add;
+ rte_devargs_dump;
+ rte_devargs_insert;
+ rte_devargs_next;
+ rte_devargs_parse;
+ rte_devargs_parsef;
+ rte_devargs_remove;
+ rte_devargs_type_count;
rte_dump_physmem_layout;
rte_dump_registers;
rte_dump_stack;
rte_dump_tailq;
rte_eal_alarm_cancel;
rte_eal_alarm_set;
+ rte_eal_cleanup;
+ rte_eal_create_uio_dev;
rte_eal_get_configuration;
rte_eal_get_lcore_state;
rte_eal_get_physmem_size;
+ rte_eal_get_runtime_dir;
rte_eal_has_hugepages;
+ rte_eal_has_pci;
+ rte_eal_hotplug_add;
+ rte_eal_hotplug_remove;
rte_eal_hpet_init;
rte_eal_init;
rte_eal_iopl_init;
+ rte_eal_iova_mode;
rte_eal_lcore_role;
+ rte_eal_mbuf_user_pool_ops;
rte_eal_mp_remote_launch;
rte_eal_mp_wait_lcore;
+ rte_eal_primary_proc_alive;
rte_eal_process_type;
rte_eal_remote_launch;
rte_eal_tailq_lookup;
rte_eal_tailq_register;
+ rte_eal_using_phys_addrs;
+ rte_eal_vfio_intr_mode;
rte_eal_wait_lcore;
+ rte_epoll_ctl;
+ rte_epoll_wait;
rte_exit;
rte_free;
rte_get_hpet_cycles;
rte_get_hpet_hz;
rte_get_tsc_hz;
rte_hexdump;
+ rte_hypervisor_get;
+ rte_hypervisor_get_name;
+ rte_intr_allow_others;
rte_intr_callback_register;
rte_intr_callback_unregister;
+ rte_intr_cap_multiple;
rte_intr_disable;
+ rte_intr_dp_is_en;
+ rte_intr_efd_disable;
+ rte_intr_efd_enable;
rte_intr_enable;
+ rte_intr_free_epoll_fd;
+ rte_intr_rx_ctl;
+ rte_intr_tls_epfd;
+ rte_keepalive_create;
+ rte_keepalive_dispatch_pings;
+ rte_keepalive_mark_alive;
+ rte_keepalive_mark_sleep;
+ rte_keepalive_register_core;
+ rte_keepalive_register_relay_callback;
+ rte_lcore_has_role;
+ rte_lcore_index;
+ rte_lcore_to_socket_id;
rte_log;
rte_log_cur_msg_loglevel;
rte_log_cur_msg_logtype;
+ rte_log_dump;
+ rte_log_get_global_level;
+ rte_log_get_level;
+ rte_log_register;
+ rte_log_set_global_level;
+ rte_log_set_level;
+ rte_log_set_level_pattern;
+ rte_log_set_level_regexp;
rte_logs;
rte_malloc;
rte_malloc_dump_stats;
@@ -54,155 +119,38 @@ DPDK_2.0 {
rte_malloc_set_limit;
rte_malloc_socket;
rte_malloc_validate;
+ rte_malloc_virt2iova;
+ rte_mcfg_mem_read_lock;
+ rte_mcfg_mem_read_unlock;
+ rte_mcfg_mem_write_lock;
+ rte_mcfg_mem_write_unlock;
+ rte_mcfg_mempool_read_lock;
+ rte_mcfg_mempool_read_unlock;
+ rte_mcfg_mempool_write_lock;
+ rte_mcfg_mempool_write_unlock;
+ rte_mcfg_tailq_read_lock;
+ rte_mcfg_tailq_read_unlock;
+ rte_mcfg_tailq_write_lock;
+ rte_mcfg_tailq_write_unlock;
rte_mem_lock_page;
+ rte_mem_virt2iova;
rte_mem_virt2phy;
rte_memdump;
rte_memory_get_nchannel;
rte_memory_get_nrank;
rte_memzone_dump;
+ rte_memzone_free;
rte_memzone_lookup;
rte_memzone_reserve;
rte_memzone_reserve_aligned;
rte_memzone_reserve_bounded;
rte_memzone_walk;
rte_openlog_stream;
+ rte_rand;
rte_realloc;
- rte_set_application_usage_hook;
- rte_socket_id;
- rte_strerror;
- rte_strsplit;
- rte_sys_gettid;
- rte_thread_get_affinity;
- rte_thread_set_affinity;
- rte_vlog;
- rte_zmalloc;
- rte_zmalloc_socket;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_epoll_ctl;
- rte_epoll_wait;
- rte_intr_allow_others;
- rte_intr_dp_is_en;
- rte_intr_efd_disable;
- rte_intr_efd_enable;
- rte_intr_rx_ctl;
- rte_intr_tls_epfd;
- rte_memzone_free;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_intr_cap_multiple;
- rte_keepalive_create;
- rte_keepalive_dispatch_pings;
- rte_keepalive_mark_alive;
- rte_keepalive_register_core;
-
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_cpu_get_flag_name;
- rte_eal_primary_proc_alive;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_keepalive_mark_sleep;
- rte_keepalive_register_relay_callback;
- rte_rtm_supported;
- rte_thread_setname;
-
-} DPDK_16.04;
-
-DPDK_16.11 {
- global:
-
- rte_delay_us_block;
- rte_delay_us_callback_register;
-
-} DPDK_16.07;
-
-DPDK_17.02 {
- global:
-
- rte_bus_dump;
- rte_bus_probe;
- rte_bus_register;
- rte_bus_scan;
- rte_bus_unregister;
-
-} DPDK_16.11;
-
-DPDK_17.05 {
- global:
-
- rte_cpu_is_supported;
- rte_intr_free_epoll_fd;
- rte_log_dump;
- rte_log_get_global_level;
- rte_log_register;
- rte_log_set_global_level;
- rte_log_set_level;
- rte_log_set_level_regexp;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_bus_find;
- rte_bus_find_by_device;
- rte_bus_find_by_name;
- rte_log_get_level;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eal_create_uio_dev;
- rte_bus_get_iommu_class;
- rte_eal_has_pci;
- rte_eal_iova_mode;
- rte_eal_using_phys_addrs;
- rte_eal_vfio_intr_mode;
- rte_lcore_has_role;
- rte_malloc_virt2iova;
- rte_mem_virt2iova;
- rte_vfio_enable;
- rte_vfio_is_enabled;
- rte_vfio_noiommu_is_enabled;
- rte_vfio_release_device;
- rte_vfio_setup_device;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_hypervisor_get;
- rte_hypervisor_get_name;
- rte_vfio_clear_group;
rte_reciprocal_value;
rte_reciprocal_value_u64;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_log_set_level_pattern;
+ rte_rtm_supported;
rte_service_attr_get;
rte_service_attr_reset_all;
rte_service_component_register;
@@ -215,6 +163,8 @@ DPDK_18.05 {
rte_service_get_count;
rte_service_get_name;
rte_service_lcore_add;
+ rte_service_lcore_attr_get;
+ rte_service_lcore_attr_reset_all;
rte_service_lcore_count;
rte_service_lcore_count_services;
rte_service_lcore_del;
@@ -224,6 +174,7 @@ DPDK_18.05 {
rte_service_lcore_stop;
rte_service_map_lcore_get;
rte_service_map_lcore_set;
+ rte_service_may_be_active;
rte_service_probe_capability;
rte_service_run_iter_on_app_lcore;
rte_service_runstate_get;
@@ -231,17 +182,23 @@ DPDK_18.05 {
rte_service_set_runstate_mapped_check;
rte_service_set_stats_enable;
rte_service_start_with_defaults;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eal_mbuf_user_pool_ops;
+ rte_set_application_usage_hook;
+ rte_socket_count;
+ rte_socket_id;
+ rte_socket_id_by_idx;
+ rte_srand;
+ rte_strerror;
+ rte_strscpy;
+ rte_strsplit;
+ rte_sys_gettid;
+ rte_thread_get_affinity;
+ rte_thread_set_affinity;
+ rte_thread_setname;
rte_uuid_compare;
rte_uuid_is_null;
rte_uuid_parse;
rte_uuid_unparse;
+ rte_vfio_clear_group;
rte_vfio_container_create;
rte_vfio_container_destroy;
rte_vfio_container_dma_map;
@@ -250,67 +207,20 @@ DPDK_18.08 {
rte_vfio_container_group_unbind;
rte_vfio_dma_map;
rte_vfio_dma_unmap;
+ rte_vfio_enable;
rte_vfio_get_container_fd;
rte_vfio_get_group_fd;
rte_vfio_get_group_num;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_dev_probe;
- rte_dev_remove;
- rte_eal_get_runtime_dir;
- rte_eal_hotplug_add;
- rte_eal_hotplug_remove;
- rte_strscpy;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_ctrl_thread_create;
- rte_dev_is_probed;
- rte_devargs_add;
- rte_devargs_dump;
- rte_devargs_insert;
- rte_devargs_next;
- rte_devargs_parse;
- rte_devargs_parsef;
- rte_devargs_remove;
- rte_devargs_type_count;
- rte_eal_cleanup;
- rte_socket_count;
- rte_socket_id_by_idx;
-
-} DPDK_18.11;
-
-DPDK_19.08 {
- global:
-
- rte_lcore_index;
- rte_lcore_to_socket_id;
- rte_mcfg_mem_read_lock;
- rte_mcfg_mem_read_unlock;
- rte_mcfg_mem_write_lock;
- rte_mcfg_mem_write_unlock;
- rte_mcfg_mempool_read_lock;
- rte_mcfg_mempool_read_unlock;
- rte_mcfg_mempool_write_lock;
- rte_mcfg_mempool_write_unlock;
- rte_mcfg_tailq_read_lock;
- rte_mcfg_tailq_read_unlock;
- rte_mcfg_tailq_write_lock;
- rte_mcfg_tailq_write_unlock;
- rte_rand;
- rte_service_lcore_attr_get;
- rte_service_lcore_attr_reset_all;
- rte_service_may_be_active;
- rte_srand;
-
-} DPDK_19.05;
+ rte_vfio_is_enabled;
+ rte_vfio_noiommu_is_enabled;
+ rte_vfio_release_device;
+ rte_vfio_setup_device;
+ rte_vlog;
+ rte_zmalloc;
+ rte_zmalloc_socket;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_efd/rte_efd_version.map b/lib/librte_efd/rte_efd_version.map
index ae60a64178..e010eecfe4 100644
--- a/lib/librte_efd/rte_efd_version.map
+++ b/lib/librte_efd/rte_efd_version.map
@@ -1,4 +1,4 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_efd_create;
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b8..9e1dbdebb4 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -1,35 +1,53 @@
-DPDK_2.2 {
+DPDK_20.0 {
global:
+ _rte_eth_dev_callback_process;
+ _rte_eth_dev_reset;
+ rte_eth_add_first_rx_callback;
rte_eth_add_rx_callback;
rte_eth_add_tx_callback;
rte_eth_allmulticast_disable;
rte_eth_allmulticast_enable;
rte_eth_allmulticast_get;
+ rte_eth_dev_adjust_nb_rx_tx_desc;
rte_eth_dev_allocate;
rte_eth_dev_allocated;
+ rte_eth_dev_attach_secondary;
rte_eth_dev_callback_register;
rte_eth_dev_callback_unregister;
rte_eth_dev_close;
rte_eth_dev_configure;
rte_eth_dev_count;
+ rte_eth_dev_count_avail;
+ rte_eth_dev_count_total;
rte_eth_dev_default_mac_addr_set;
+ rte_eth_dev_filter_ctrl;
rte_eth_dev_filter_supported;
rte_eth_dev_flow_ctrl_get;
rte_eth_dev_flow_ctrl_set;
+ rte_eth_dev_fw_version_get;
rte_eth_dev_get_dcb_info;
rte_eth_dev_get_eeprom;
rte_eth_dev_get_eeprom_length;
rte_eth_dev_get_mtu;
+ rte_eth_dev_get_name_by_port;
+ rte_eth_dev_get_port_by_name;
rte_eth_dev_get_reg_info;
+ rte_eth_dev_get_sec_ctx;
+ rte_eth_dev_get_supported_ptypes;
rte_eth_dev_get_vlan_offload;
- rte_eth_devices;
rte_eth_dev_info_get;
rte_eth_dev_is_valid_port;
+ rte_eth_dev_l2_tunnel_eth_type_conf;
+ rte_eth_dev_l2_tunnel_offload_set;
+ rte_eth_dev_logtype;
rte_eth_dev_mac_addr_add;
rte_eth_dev_mac_addr_remove;
+ rte_eth_dev_pool_ops_supported;
rte_eth_dev_priority_flow_ctrl_set;
+ rte_eth_dev_probing_finish;
rte_eth_dev_release_port;
+ rte_eth_dev_reset;
rte_eth_dev_rss_hash_conf_get;
rte_eth_dev_rss_hash_update;
rte_eth_dev_rss_reta_query;
@@ -38,6 +56,7 @@ DPDK_2.2 {
rte_eth_dev_rx_intr_ctl_q;
rte_eth_dev_rx_intr_disable;
rte_eth_dev_rx_intr_enable;
+ rte_eth_dev_rx_offload_name;
rte_eth_dev_rx_queue_start;
rte_eth_dev_rx_queue_stop;
rte_eth_dev_set_eeprom;
@@ -47,18 +66,28 @@ DPDK_2.2 {
rte_eth_dev_set_mtu;
rte_eth_dev_set_rx_queue_stats_mapping;
rte_eth_dev_set_tx_queue_stats_mapping;
+ rte_eth_dev_set_vlan_ether_type;
rte_eth_dev_set_vlan_offload;
rte_eth_dev_set_vlan_pvid;
rte_eth_dev_set_vlan_strip_on_queue;
rte_eth_dev_socket_id;
rte_eth_dev_start;
rte_eth_dev_stop;
+ rte_eth_dev_tx_offload_name;
rte_eth_dev_tx_queue_start;
rte_eth_dev_tx_queue_stop;
rte_eth_dev_uc_all_hash_table_set;
rte_eth_dev_uc_hash_table_set;
+ rte_eth_dev_udp_tunnel_port_add;
+ rte_eth_dev_udp_tunnel_port_delete;
rte_eth_dev_vlan_filter;
+ rte_eth_devices;
rte_eth_dma_zone_reserve;
+ rte_eth_find_next;
+ rte_eth_find_next_owned_by;
+ rte_eth_iterator_cleanup;
+ rte_eth_iterator_init;
+ rte_eth_iterator_next;
rte_eth_led_off;
rte_eth_led_on;
rte_eth_link;
@@ -75,6 +104,7 @@ DPDK_2.2 {
rte_eth_rx_queue_info_get;
rte_eth_rx_queue_setup;
rte_eth_set_queue_rate_limit;
+ rte_eth_speed_bitflag;
rte_eth_stats;
rte_eth_stats_get;
rte_eth_stats_reset;
@@ -85,66 +115,27 @@ DPDK_2.2 {
rte_eth_timesync_read_time;
rte_eth_timesync_read_tx_timestamp;
rte_eth_timesync_write_time;
- rte_eth_tx_queue_info_get;
- rte_eth_tx_queue_setup;
- rte_eth_xstats_get;
- rte_eth_xstats_reset;
-
- local: *;
-};
-
-DPDK_16.04 {
- global:
-
- rte_eth_dev_get_supported_ptypes;
- rte_eth_dev_l2_tunnel_eth_type_conf;
- rte_eth_dev_l2_tunnel_offload_set;
- rte_eth_dev_set_vlan_ether_type;
- rte_eth_dev_udp_tunnel_port_add;
- rte_eth_dev_udp_tunnel_port_delete;
- rte_eth_speed_bitflag;
rte_eth_tx_buffer_count_callback;
rte_eth_tx_buffer_drop_callback;
rte_eth_tx_buffer_init;
rte_eth_tx_buffer_set_err_callback;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_eth_add_first_rx_callback;
- rte_eth_dev_get_name_by_port;
- rte_eth_dev_get_port_by_name;
- rte_eth_xstats_get_names;
-
-} DPDK_16.04;
-
-DPDK_17.02 {
- global:
-
- _rte_eth_dev_reset;
- rte_eth_dev_fw_version_get;
-
-} DPDK_16.07;
-
-DPDK_17.05 {
- global:
-
- rte_eth_dev_attach_secondary;
- rte_eth_find_next;
rte_eth_tx_done_cleanup;
+ rte_eth_tx_queue_info_get;
+ rte_eth_tx_queue_setup;
+ rte_eth_xstats_get;
rte_eth_xstats_get_by_id;
rte_eth_xstats_get_id_by_name;
+ rte_eth_xstats_get_names;
rte_eth_xstats_get_names_by_id;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- _rte_eth_dev_callback_process;
- rte_eth_dev_adjust_nb_rx_tx_desc;
+ rte_eth_xstats_reset;
+ rte_flow_copy;
+ rte_flow_create;
+ rte_flow_destroy;
+ rte_flow_error_set;
+ rte_flow_flush;
+ rte_flow_isolate;
+ rte_flow_query;
+ rte_flow_validate;
rte_tm_capabilities_get;
rte_tm_get_number_of_leaf_nodes;
rte_tm_hierarchy_commit;
@@ -176,65 +167,8 @@ DPDK_17.08 {
rte_tm_wred_profile_add;
rte_tm_wred_profile_delete;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eth_dev_get_sec_ctx;
- rte_eth_dev_pool_ops_supported;
- rte_eth_dev_reset;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_eth_dev_filter_ctrl;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_eth_dev_count_avail;
- rte_eth_dev_probing_finish;
- rte_eth_find_next_owned_by;
- rte_flow_copy;
- rte_flow_create;
- rte_flow_destroy;
- rte_flow_error_set;
- rte_flow_flush;
- rte_flow_isolate;
- rte_flow_query;
- rte_flow_validate;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eth_dev_logtype;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_eth_dev_rx_offload_name;
- rte_eth_dev_tx_offload_name;
- rte_eth_iterator_cleanup;
- rte_eth_iterator_init;
- rte_eth_iterator_next;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_eth_dev_count_total;
-
-} DPDK_18.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index 76b3021d3a..edfc15282d 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -1,61 +1,38 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
- rte_eventdevs;
-
+ rte_event_crypto_adapter_caps_get;
+ rte_event_crypto_adapter_create;
+ rte_event_crypto_adapter_create_ext;
+ rte_event_crypto_adapter_event_port_get;
+ rte_event_crypto_adapter_free;
+ rte_event_crypto_adapter_queue_pair_add;
+ rte_event_crypto_adapter_queue_pair_del;
+ rte_event_crypto_adapter_service_id_get;
+ rte_event_crypto_adapter_start;
+ rte_event_crypto_adapter_stats_get;
+ rte_event_crypto_adapter_stats_reset;
+ rte_event_crypto_adapter_stop;
+ rte_event_dequeue_timeout_ticks;
+ rte_event_dev_attr_get;
+ rte_event_dev_close;
+ rte_event_dev_configure;
rte_event_dev_count;
+ rte_event_dev_dump;
rte_event_dev_get_dev_id;
- rte_event_dev_socket_id;
rte_event_dev_info_get;
- rte_event_dev_configure;
+ rte_event_dev_selftest;
+ rte_event_dev_service_id_get;
+ rte_event_dev_socket_id;
rte_event_dev_start;
rte_event_dev_stop;
- rte_event_dev_close;
- rte_event_dev_dump;
+ rte_event_dev_stop_flush_callback_register;
rte_event_dev_xstats_by_name_get;
rte_event_dev_xstats_get;
rte_event_dev_xstats_names_get;
rte_event_dev_xstats_reset;
-
- rte_event_port_default_conf_get;
- rte_event_port_setup;
- rte_event_port_link;
- rte_event_port_unlink;
- rte_event_port_links_get;
-
- rte_event_queue_default_conf_get;
- rte_event_queue_setup;
-
- rte_event_dequeue_timeout_ticks;
-
- rte_event_pmd_allocate;
- rte_event_pmd_release;
- rte_event_pmd_vdev_init;
- rte_event_pmd_vdev_uninit;
- rte_event_pmd_pci_probe;
- rte_event_pmd_pci_remove;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- rte_event_ring_create;
- rte_event_ring_free;
- rte_event_ring_init;
- rte_event_ring_lookup;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_event_dev_attr_get;
- rte_event_dev_service_id_get;
- rte_event_port_attr_get;
- rte_event_queue_attr_get;
-
rte_event_eth_rx_adapter_caps_get;
+ rte_event_eth_rx_adapter_cb_register;
rte_event_eth_rx_adapter_create;
rte_event_eth_rx_adapter_create_ext;
rte_event_eth_rx_adapter_free;
@@ -63,38 +40,9 @@ DPDK_17.11 {
rte_event_eth_rx_adapter_queue_del;
rte_event_eth_rx_adapter_service_id_get;
rte_event_eth_rx_adapter_start;
+ rte_event_eth_rx_adapter_stats_get;
rte_event_eth_rx_adapter_stats_reset;
rte_event_eth_rx_adapter_stop;
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_event_dev_selftest;
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_event_dev_stop_flush_callback_register;
-} DPDK_18.02;
-
-DPDK_19.05 {
- global:
-
- rte_event_crypto_adapter_caps_get;
- rte_event_crypto_adapter_create;
- rte_event_crypto_adapter_create_ext;
- rte_event_crypto_adapter_event_port_get;
- rte_event_crypto_adapter_free;
- rte_event_crypto_adapter_queue_pair_add;
- rte_event_crypto_adapter_queue_pair_del;
- rte_event_crypto_adapter_service_id_get;
- rte_event_crypto_adapter_start;
- rte_event_crypto_adapter_stats_get;
- rte_event_crypto_adapter_stats_reset;
- rte_event_crypto_adapter_stop;
- rte_event_port_unlinks_in_progress;
rte_event_eth_tx_adapter_caps_get;
rte_event_eth_tx_adapter_create;
rte_event_eth_tx_adapter_create_ext;
@@ -107,6 +55,26 @@ DPDK_19.05 {
rte_event_eth_tx_adapter_stats_get;
rte_event_eth_tx_adapter_stats_reset;
rte_event_eth_tx_adapter_stop;
+ rte_event_pmd_allocate;
+ rte_event_pmd_pci_probe;
+ rte_event_pmd_pci_remove;
+ rte_event_pmd_release;
+ rte_event_pmd_vdev_init;
+ rte_event_pmd_vdev_uninit;
+ rte_event_port_attr_get;
+ rte_event_port_default_conf_get;
+ rte_event_port_link;
+ rte_event_port_links_get;
+ rte_event_port_setup;
+ rte_event_port_unlink;
+ rte_event_port_unlinks_in_progress;
+ rte_event_queue_attr_get;
+ rte_event_queue_default_conf_get;
+ rte_event_queue_setup;
+ rte_event_ring_create;
+ rte_event_ring_free;
+ rte_event_ring_init;
+ rte_event_ring_lookup;
rte_event_timer_adapter_caps_get;
rte_event_timer_adapter_create;
rte_event_timer_adapter_create_ext;
@@ -121,11 +89,7 @@ DPDK_19.05 {
rte_event_timer_arm_burst;
rte_event_timer_arm_tmo_tick_burst;
rte_event_timer_cancel_burst;
-} DPDK_18.05;
+ rte_eventdevs;
-DPDK_19.08 {
- global:
-
- rte_event_eth_rx_adapter_cb_register;
- rte_event_eth_rx_adapter_stats_get;
-} DPDK_19.05;
+ local: *;
+};
diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map b/lib/librte_flow_classify/rte_flow_classify_version.map
index 49bc25c6a0..001ff660e3 100644
--- a/lib/librte_flow_classify/rte_flow_classify_version.map
+++ b/lib/librte_flow_classify/rte_flow_classify_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_gro/rte_gro_version.map b/lib/librte_gro/rte_gro_version.map
index 1606b6dc72..9f6fe79e57 100644
--- a/lib/librte_gro/rte_gro_version.map
+++ b/lib/librte_gro/rte_gro_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_gro_ctx_create;
diff --git a/lib/librte_gso/rte_gso_version.map b/lib/librte_gso/rte_gso_version.map
index e1fd453edb..8505a59c27 100644
--- a/lib/librte_gso/rte_gso_version.map
+++ b/lib/librte_gso/rte_gso_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_gso_segment;
diff --git a/lib/librte_hash/rte_hash_version.map b/lib/librte_hash/rte_hash_version.map
index 734ae28b04..138c130c1b 100644
--- a/lib/librte_hash/rte_hash_version.map
+++ b/lib/librte_hash/rte_hash_version.map
@@ -1,58 +1,33 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_fbk_hash_create;
rte_fbk_hash_find_existing;
rte_fbk_hash_free;
rte_hash_add_key;
+ rte_hash_add_key_data;
rte_hash_add_key_with_hash;
+ rte_hash_add_key_with_hash_data;
+ rte_hash_count;
rte_hash_create;
rte_hash_del_key;
rte_hash_del_key_with_hash;
rte_hash_find_existing;
rte_hash_free;
+ rte_hash_get_key_with_position;
rte_hash_hash;
+ rte_hash_iterate;
rte_hash_lookup;
rte_hash_lookup_bulk;
- rte_hash_lookup_with_hash;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_hash_add_key_data;
- rte_hash_add_key_with_hash_data;
- rte_hash_iterate;
rte_hash_lookup_bulk_data;
rte_hash_lookup_data;
+ rte_hash_lookup_with_hash;
rte_hash_lookup_with_hash_data;
rte_hash_reset;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_hash_set_cmp_func;
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_hash_get_key_with_position;
-
-} DPDK_2.2;
-
-
-DPDK_18.08 {
- global:
-
- rte_hash_count;
-
-} DPDK_16.07;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
index a193007c61..5dd34f828c 100644
--- a/lib/librte_ip_frag/rte_ip_frag_version.map
+++ b/lib/librte_ip_frag/rte_ip_frag_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ip_frag_free_death_row;
rte_ip_frag_table_create;
+ rte_ip_frag_table_destroy;
rte_ip_frag_table_statistics_dump;
rte_ipv4_frag_reassemble_packet;
rte_ipv4_fragment_packet;
@@ -12,13 +13,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_17.08 {
- global:
-
- rte_ip_frag_table_destroy;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_ipsec/rte_ipsec_version.map b/lib/librte_ipsec/rte_ipsec_version.map
index ee9f1961b0..3723b812fc 100644
--- a/lib/librte_ipsec/rte_ipsec_version.map
+++ b/lib/librte_ipsec/rte_ipsec_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_jobstats/rte_jobstats_version.map b/lib/librte_jobstats/rte_jobstats_version.map
index f89441438e..dbd2664ae2 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -1,6 +1,7 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_jobstats_abort;
rte_jobstats_context_finish;
rte_jobstats_context_init;
rte_jobstats_context_reset;
@@ -17,10 +18,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_jobstats_abort;
-
-} DPDK_2.0;
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6aaa..9cd3cedc54 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kni_alloc;
diff --git a/lib/librte_kvargs/rte_kvargs_version.map b/lib/librte_kvargs/rte_kvargs_version.map
index 8f4b4e3f8f..3ba0f4b59c 100644
--- a/lib/librte_kvargs/rte_kvargs_version.map
+++ b/lib/librte_kvargs/rte_kvargs_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kvargs_count;
@@ -15,4 +15,4 @@ EXPERIMENTAL {
rte_kvargs_parse_delim;
rte_kvargs_strcmp;
-} DPDK_2.0;
+};
diff --git a/lib/librte_latencystats/rte_latencystats_version.map b/lib/librte_latencystats/rte_latencystats_version.map
index ac8403e821..e04e63463f 100644
--- a/lib/librte_latencystats/rte_latencystats_version.map
+++ b/lib/librte_latencystats/rte_latencystats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_latencystats_get;
diff --git a/lib/librte_lpm/rte_lpm_version.map b/lib/librte_lpm/rte_lpm_version.map
index 90beac853d..500f58b806 100644
--- a/lib/librte_lpm/rte_lpm_version.map
+++ b/lib/librte_lpm/rte_lpm_version.map
@@ -1,13 +1,6 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
- rte_lpm_add;
- rte_lpm_create;
- rte_lpm_delete;
- rte_lpm_delete_all;
- rte_lpm_find_existing;
- rte_lpm_free;
- rte_lpm_is_rule_present;
rte_lpm6_add;
rte_lpm6_create;
rte_lpm6_delete;
@@ -18,29 +11,13 @@ DPDK_2.0 {
rte_lpm6_is_rule_present;
rte_lpm6_lookup;
rte_lpm6_lookup_bulk_func;
+ rte_lpm_add;
+ rte_lpm_create;
+ rte_lpm_delete;
+ rte_lpm_delete_all;
+ rte_lpm_find_existing;
+ rte_lpm_free;
+ rte_lpm_is_rule_present;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_lpm_add;
- rte_lpm_find_existing;
- rte_lpm_create;
- rte_lpm_free;
- rte_lpm_is_rule_present;
- rte_lpm_delete;
- rte_lpm_delete_all;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_lpm6_add;
- rte_lpm6_is_rule_present;
- rte_lpm6_lookup;
- rte_lpm6_lookup_bulk_func;
-
-} DPDK_16.04;
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index 519fead35a..b2dc5e50f4 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -1,26 +1,7 @@
-DPDK_2.0 {
- global:
-
- rte_get_rx_ol_flag_name;
- rte_get_tx_ol_flag_name;
- rte_mbuf_sanity_check;
- rte_pktmbuf_dump;
- rte_pktmbuf_init;
- rte_pktmbuf_pool_init;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pktmbuf_pool_create;
-
-} DPDK_2.0;
-
-DPDK_16.11 {
+DPDK_20.0 {
global:
+ __rte_pktmbuf_linearize;
__rte_pktmbuf_read;
rte_get_ptype_inner_l2_name;
rte_get_ptype_inner_l3_name;
@@ -31,28 +12,24 @@ DPDK_16.11 {
rte_get_ptype_name;
rte_get_ptype_tunnel_name;
rte_get_rx_ol_flag_list;
+ rte_get_rx_ol_flag_name;
rte_get_tx_ol_flag_list;
-
-} DPDK_2.1;
-
-DPDK_18.08 {
- global:
-
+ rte_get_tx_ol_flag_name;
rte_mbuf_best_mempool_ops;
rte_mbuf_platform_mempool_ops;
+ rte_mbuf_sanity_check;
rte_mbuf_set_platform_mempool_ops;
rte_mbuf_set_user_mempool_ops;
rte_mbuf_user_mempool_ops;
- rte_pktmbuf_pool_create_by_ops;
-} DPDK_16.11;
-
-DPDK_19.11 {
- global:
-
- __rte_pktmbuf_linearize;
rte_pktmbuf_clone;
+ rte_pktmbuf_dump;
+ rte_pktmbuf_init;
+ rte_pktmbuf_pool_create;
+ rte_pktmbuf_pool_create_by_ops;
+ rte_pktmbuf_pool_init;
-} DPDK_18.08;
+ local: *;
+};
EXPERIMENTAL {
global:
@@ -60,4 +37,4 @@ EXPERIMENTAL {
rte_mbuf_check;
rte_pktmbuf_copy;
-} DPDK_18.08;
+};
diff --git a/lib/librte_member/rte_member_version.map b/lib/librte_member/rte_member_version.map
index 019e4cd962..87780ae611 100644
--- a/lib/librte_member/rte_member_version.map
+++ b/lib/librte_member/rte_member_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_member_add;
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 17cbca4607..6a425d203a 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_mempool_audit;
- rte_mempool_calc_obj_size;
- rte_mempool_create;
- rte_mempool_dump;
- rte_mempool_list_dump;
- rte_mempool_lookup;
- rte_mempool_walk;
-
- local: *;
-};
-
-DPDK_16.07 {
- global:
-
rte_mempool_avail_count;
rte_mempool_cache_create;
rte_mempool_cache_flush;
rte_mempool_cache_free;
+ rte_mempool_calc_obj_size;
rte_mempool_check_cookies;
+ rte_mempool_contig_blocks_check_cookies;
+ rte_mempool_create;
rte_mempool_create_empty;
rte_mempool_default_cache;
+ rte_mempool_dump;
rte_mempool_free;
rte_mempool_generic_get;
rte_mempool_generic_put;
rte_mempool_in_use_count;
+ rte_mempool_list_dump;
+ rte_mempool_lookup;
rte_mempool_mem_iter;
rte_mempool_obj_iter;
+ rte_mempool_op_calc_mem_size_default;
+ rte_mempool_op_populate_default;
rte_mempool_ops_table;
rte_mempool_populate_anon;
rte_mempool_populate_default;
+ rte_mempool_populate_iova;
rte_mempool_populate_virt;
rte_mempool_register_ops;
rte_mempool_set_ops_byname;
+ rte_mempool_walk;
-} DPDK_2.0;
-
-DPDK_17.11 {
- global:
-
- rte_mempool_populate_iova;
-
-} DPDK_16.07;
-
-DPDK_18.05 {
- global:
-
- rte_mempool_contig_blocks_check_cookies;
- rte_mempool_op_calc_mem_size_default;
- rte_mempool_op_populate_default;
-
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 4b460d5803..46410b0369 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -1,21 +1,16 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_meter_srtcm_color_aware_check;
rte_meter_srtcm_color_blind_check;
rte_meter_srtcm_config;
+ rte_meter_srtcm_profile_config;
rte_meter_trtcm_color_aware_check;
rte_meter_trtcm_color_blind_check;
rte_meter_trtcm_config;
-
- local: *;
-};
-
-DPDK_18.08 {
- global:
-
- rte_meter_srtcm_profile_config;
rte_meter_trtcm_profile_config;
+
+ local: *;
};
EXPERIMENTAL {
diff --git a/lib/librte_metrics/rte_metrics_version.map b/lib/librte_metrics/rte_metrics_version.map
index 6ac99a44a1..85663f356e 100644
--- a/lib/librte_metrics/rte_metrics_version.map
+++ b/lib/librte_metrics/rte_metrics_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_metrics_get_names;
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index fffc4a3723..8a4e75a3a0 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -1,25 +1,14 @@
-DPDK_16.11 {
- global:
- rte_net_get_ptype;
-
- local: *;
-};
-
-DPDK_17.05 {
- global:
-
- rte_net_crc_calc;
- rte_net_crc_set_alg;
-
-} DPDK_16.11;
-
-DPDK_19.08 {
+DPDK_20.0 {
global:
rte_eth_random_addr;
rte_ether_format_addr;
+ rte_net_crc_calc;
+ rte_net_crc_set_alg;
+ rte_net_get_ptype;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index c0280277bb..539785f5f4 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
eal_parse_pci_BDF;
diff --git a/lib/librte_pdump/rte_pdump_version.map b/lib/librte_pdump/rte_pdump_version.map
index 3e744f3012..6d02ccce6d 100644
--- a/lib/librte_pdump/rte_pdump_version.map
+++ b/lib/librte_pdump/rte_pdump_version.map
@@ -1,4 +1,4 @@
-DPDK_16.07 {
+DPDK_20.0 {
global:
rte_pdump_disable;
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 420f065d6e..64d38afecd 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -1,6 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_pipeline_ah_packet_drop;
+ rte_pipeline_ah_packet_hijack;
rte_pipeline_check;
rte_pipeline_create;
rte_pipeline_flush;
@@ -9,42 +11,22 @@ DPDK_2.0 {
rte_pipeline_port_in_create;
rte_pipeline_port_in_disable;
rte_pipeline_port_in_enable;
+ rte_pipeline_port_in_stats_read;
rte_pipeline_port_out_create;
rte_pipeline_port_out_packet_insert;
+ rte_pipeline_port_out_stats_read;
rte_pipeline_run;
rte_pipeline_table_create;
rte_pipeline_table_default_entry_add;
rte_pipeline_table_default_entry_delete;
rte_pipeline_table_entry_add;
- rte_pipeline_table_entry_delete;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pipeline_port_in_stats_read;
- rte_pipeline_port_out_stats_read;
- rte_pipeline_table_stats_read;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_pipeline_table_entry_add_bulk;
+ rte_pipeline_table_entry_delete;
rte_pipeline_table_entry_delete_bulk;
+ rte_pipeline_table_stats_read;
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_pipeline_ah_packet_hijack;
- rte_pipeline_ah_packet_drop;
-
-} DPDK_2.2;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map
index 609bcec3ff..db1b8681d9 100644
--- a/lib/librte_port/rte_port_version.map
+++ b/lib/librte_port/rte_port_version.map
@@ -1,62 +1,32 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_port_ethdev_reader_ops;
+ rte_port_ethdev_writer_nodrop_ops;
rte_port_ethdev_writer_ops;
+ rte_port_fd_reader_ops;
+ rte_port_fd_writer_nodrop_ops;
+ rte_port_fd_writer_ops;
+ rte_port_kni_reader_ops;
+ rte_port_kni_writer_nodrop_ops;
+ rte_port_kni_writer_ops;
+ rte_port_ring_multi_reader_ops;
+ rte_port_ring_multi_writer_nodrop_ops;
+ rte_port_ring_multi_writer_ops;
rte_port_ring_reader_ipv4_frag_ops;
+ rte_port_ring_reader_ipv6_frag_ops;
rte_port_ring_reader_ops;
rte_port_ring_writer_ipv4_ras_ops;
+ rte_port_ring_writer_ipv6_ras_ops;
+ rte_port_ring_writer_nodrop_ops;
rte_port_ring_writer_ops;
rte_port_sched_reader_ops;
rte_port_sched_writer_ops;
rte_port_sink_ops;
rte_port_source_ops;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_port_ethdev_writer_nodrop_ops;
- rte_port_ring_reader_ipv6_frag_ops;
- rte_port_ring_writer_ipv6_ras_ops;
- rte_port_ring_writer_nodrop_ops;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_port_ring_multi_reader_ops;
- rte_port_ring_multi_writer_ops;
- rte_port_ring_multi_writer_nodrop_ops;
-
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_port_kni_reader_ops;
- rte_port_kni_writer_ops;
- rte_port_kni_writer_nodrop_ops;
-
-} DPDK_2.2;
-
-DPDK_16.11 {
- global:
-
- rte_port_fd_reader_ops;
- rte_port_fd_writer_ops;
- rte_port_fd_writer_nodrop_ops;
-
-} DPDK_16.07;
-
-DPDK_18.11 {
- global:
-
rte_port_sym_crypto_reader_ops;
- rte_port_sym_crypto_writer_ops;
rte_port_sym_crypto_writer_nodrop_ops;
+ rte_port_sym_crypto_writer_ops;
-} DPDK_16.11;
+ local: *;
+};
diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map
index 042917360e..a94ab30c3d 100644
--- a/lib/librte_power/rte_power_version.map
+++ b/lib/librte_power/rte_power_version.map
@@ -1,39 +1,27 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_power_exit;
+ rte_power_freq_disable_turbo;
rte_power_freq_down;
+ rte_power_freq_enable_turbo;
rte_power_freq_max;
rte_power_freq_min;
rte_power_freq_up;
rte_power_freqs;
+ rte_power_get_capabilities;
rte_power_get_env;
rte_power_get_freq;
+ rte_power_guest_channel_send_msg;
rte_power_init;
rte_power_set_env;
rte_power_set_freq;
+ rte_power_turbo_status;
rte_power_unset_env;
local: *;
};
-DPDK_17.11 {
- global:
-
- rte_power_guest_channel_send_msg;
- rte_power_freq_disable_turbo;
- rte_power_freq_enable_turbo;
- rte_power_turbo_status;
-
-} DPDK_2.0;
-
-DPDK_18.08 {
- global:
-
- rte_power_get_capabilities;
-
-} DPDK_17.11;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index b61dbff11c..d847c9e0d3 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -1,4 +1,4 @@
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_rawdev_close;
@@ -17,8 +17,8 @@ DPDK_18.08 {
rte_rawdev_pmd_release;
rte_rawdev_queue_conf_get;
rte_rawdev_queue_count;
- rte_rawdev_queue_setup;
rte_rawdev_queue_release;
+ rte_rawdev_queue_setup;
rte_rawdev_reset;
rte_rawdev_selftest;
rte_rawdev_set_attr;
diff --git a/lib/librte_rcu/rte_rcu_version.map b/lib/librte_rcu/rte_rcu_version.map
index f8b9ef2abb..787e51ef27 100644
--- a/lib/librte_rcu/rte_rcu_version.map
+++ b/lib/librte_rcu/rte_rcu_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_reorder/rte_reorder_version.map b/lib/librte_reorder/rte_reorder_version.map
index 0a8a54de83..cf444062df 100644
--- a/lib/librte_reorder/rte_reorder_version.map
+++ b/lib/librte_reorder/rte_reorder_version.map
@@ -1,13 +1,13 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_reorder_create;
- rte_reorder_init;
+ rte_reorder_drain;
rte_reorder_find_existing;
- rte_reorder_reset;
rte_reorder_free;
+ rte_reorder_init;
rte_reorder_insert;
- rte_reorder_drain;
+ rte_reorder_reset;
local: *;
};
diff --git a/lib/librte_ring/rte_ring_version.map b/lib/librte_ring/rte_ring_version.map
index 510c1386e0..89d84bcf48 100644
--- a/lib/librte_ring/rte_ring_version.map
+++ b/lib/librte_ring/rte_ring_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ring_create;
rte_ring_dump;
+ rte_ring_free;
rte_ring_get_memsize;
rte_ring_init;
rte_ring_list_dump;
@@ -11,13 +12,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.2 {
- global:
-
- rte_ring_free;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_sched/rte_sched_version.map b/lib/librte_sched/rte_sched_version.map
index 729588794e..1b48bfbf36 100644
--- a/lib/librte_sched/rte_sched_version.map
+++ b/lib/librte_sched/rte_sched_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_approx;
@@ -14,6 +14,9 @@ DPDK_2.0 {
rte_sched_port_enqueue;
rte_sched_port_free;
rte_sched_port_get_memory_footprint;
+ rte_sched_port_pkt_read_color;
+ rte_sched_port_pkt_read_tree_path;
+ rte_sched_port_pkt_write;
rte_sched_queue_read_stats;
rte_sched_subport_config;
rte_sched_subport_read_stats;
@@ -21,15 +24,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.1 {
- global:
-
- rte_sched_port_pkt_write;
- rte_sched_port_pkt_read_tree_path;
- rte_sched_port_pkt_read_color;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_security/rte_security_version.map b/lib/librte_security/rte_security_version.map
index 53267bf3cc..b07314bbf4 100644
--- a/lib/librte_security/rte_security_version.map
+++ b/lib/librte_security/rte_security_version.map
@@ -1,4 +1,4 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
rte_security_attach_session;
diff --git a/lib/librte_stack/rte_stack_version.map b/lib/librte_stack/rte_stack_version.map
index 6662679c36..adbb7be9d9 100644
--- a/lib/librte_stack/rte_stack_version.map
+++ b/lib/librte_stack/rte_stack_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_table/rte_table_version.map b/lib/librte_table/rte_table_version.map
index 6237252bec..40f72b1fe8 100644
--- a/lib/librte_table/rte_table_version.map
+++ b/lib/librte_table/rte_table_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_table_acl_ops;
diff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map
index fa62d7718c..c1f4613af5 100644
--- a/lib/librte_telemetry/rte_telemetry_version.map
+++ b/lib/librte_telemetry/rte_telemetry_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_timer/rte_timer_version.map b/lib/librte_timer/rte_timer_version.map
index 72f75c8181..2a59d3f081 100644
--- a/lib/librte_timer/rte_timer_version.map
+++ b/lib/librte_timer/rte_timer_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_timer_dump_stats;
@@ -14,16 +14,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_19.05 {
- global:
-
- rte_timer_dump_stats;
- rte_timer_manage;
- rte_timer_reset;
- rte_timer_stop;
- rte_timer_subsystem_init;
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 5f1d4a75c2..8e9ffac2c2 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -1,64 +1,34 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_vhost_avail_entries;
rte_vhost_dequeue_burst;
rte_vhost_driver_callback_register;
- rte_vhost_driver_register;
- rte_vhost_enable_guest_notification;
- rte_vhost_enqueue_burst;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_vhost_driver_unregister;
-
-} DPDK_2.0;
-
-DPDK_16.07 {
- global:
-
- rte_vhost_avail_entries;
- rte_vhost_get_ifname;
- rte_vhost_get_numa_node;
- rte_vhost_get_queue_num;
-
-} DPDK_2.1;
-
-DPDK_17.05 {
- global:
-
rte_vhost_driver_disable_features;
rte_vhost_driver_enable_features;
rte_vhost_driver_get_features;
+ rte_vhost_driver_register;
rte_vhost_driver_set_features;
rte_vhost_driver_start;
+ rte_vhost_driver_unregister;
+ rte_vhost_enable_guest_notification;
+ rte_vhost_enqueue_burst;
+ rte_vhost_get_ifname;
rte_vhost_get_mem_table;
rte_vhost_get_mtu;
rte_vhost_get_negotiated_features;
+ rte_vhost_get_numa_node;
+ rte_vhost_get_queue_num;
rte_vhost_get_vhost_vring;
rte_vhost_get_vring_num;
rte_vhost_gpa_to_vva;
rte_vhost_log_used_vring;
rte_vhost_log_write;
-
-} DPDK_16.07;
-
-DPDK_17.08 {
- global:
-
rte_vhost_rx_queue_count;
-
-} DPDK_17.05;
-
-DPDK_18.02 {
- global:
-
rte_vhost_vring_call;
-} DPDK_17.08;
+ local: *;
+};
EXPERIMENTAL {
global:
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix
2019-10-17 14:31 6% ` [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix Anatoly Burakov
@ 2019-10-17 16:00 4% ` Hunt, David
0 siblings, 0 replies; 200+ results
From: Hunt, David @ 2019-10-17 16:00 UTC (permalink / raw)
To: Anatoly Burakov, dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas, david.marchand
On 17/10/2019 15:31, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> The original ABI versioning was slightly misleading in that the
> DPDK 2.0 ABI was really a single mode for the distributor, and is
> used as such throughout the distributor code.
>
> Fix this by renaming all _v20 API's to _single API's, and remove
> symbol versioning.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v4:
> - Changed it back to how it was with v2
> - Removed remaining v2.0 symbols
>
> v3:
> - Removed single mode from distributor as per Dave's comments
>
> v2:
> - Moved this to before ABI version bump to avoid compile breakage
>
Hi Anatoly,
tested with Distributor sample app, Unit tests, looks good.
Acked-by: David Hunt <david.hunt@intel.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4 06/10] distributor: remove deprecated code
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 06/10] distributor: " Anatoly Burakov
@ 2019-10-17 15:59 0% ` Hunt, David
0 siblings, 0 replies; 200+ results
From: Hunt, David @ 2019-10-17 15:59 UTC (permalink / raw)
To: Anatoly Burakov, dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas, david.marchand
On 17/10/2019 15:31, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> Remove code for old ABI versions ahead of ABI version bump.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v2:
> - Moved this to before ABI version bump to avoid compile breakage
>
Hi Anatoly,
tested with Distributor sample app, Unit tests, looks good.
Acked-by: David Hunt <david.hunt@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2] mbuf: support dynamic fields and flags
@ 2019-10-17 14:42 3% ` Olivier Matz
2019-10-18 2:47 0% ` Wang, Haiyue
` (2 more replies)
1 sibling, 3 replies; 200+ results
From: Olivier Matz @ 2019-10-17 14:42 UTC (permalink / raw)
To: dev
Cc: Andrew Rybchenko, Bruce Richardson, Wang, Haiyue,
Jerin Jacob Kollanukkaran, Wiles, Keith, Ananyev, Konstantin,
Morten Brørup, Stephen Hemminger, Thomas Monjalon
Many features require to store data inside the mbuf. As the room in mbuf
structure is limited, it is not possible to have a field for each
feature. Also, changing fields in the mbuf structure can break the API
or ABI.
This commit addresses these issues, by enabling the dynamic registration
of fields or flags:
- a dynamic field is a named area in the rte_mbuf structure, with a
given size (>= 1 byte) and alignment constraint.
- a dynamic flag is a named bit in the rte_mbuf structure.
The typical use case is a PMD that registers space for an offload
feature, when the application requests to enable this feature. As
the space in mbuf is limited, the space should only be reserved if it
is going to be used (i.e when the application explicitly asks for it).
The registration can be done at any moment, but it is not possible
to unregister fields or flags for now.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Thomas Monjalon <thomas@monjalon.net>
---
v2
* Rebase on top of master: solve conflict with Stephen's patchset
(packet copy)
* Add new apis to register a dynamic field/flag at a specific place
* Add a dump function (sugg by David)
* Enhance field registration function to select the best offset, keeping
large aligned zones as much as possible (sugg by Konstantin)
* Use a size_t and unsigned int instead of int when relevant
(sugg by Konstantin)
* Use "uint64_t dynfield1[2]" in mbuf instead of 2 uint64_t fields
(sugg by Konstantin)
* Remove unused argument in private function (sugg by Konstantin)
* Fix and simplify locking (sugg by Konstantin)
* Fix minor typo
rfc -> v1
* Rebase on top of master
* Change registration API to use a structure instead of
variables, getting rid of #defines (Stephen's comment)
* Update flag registration to use a similar API as fields.
* Change max name length from 32 to 64 (sugg. by Thomas)
* Enhance API documentation (Haiyue's and Andrew's comments)
* Add a debug log at registration
* Add some words in release note
* Did some performance tests (sugg. by Andrew):
On my platform, reading a dynamic field takes ~3 cycles more
than a static field, and ~2 cycles more for writing.
app/test/test_mbuf.c | 145 ++++++-
doc/guides/rel_notes/release_19_11.rst | 7 +
lib/librte_mbuf/Makefile | 2 +
lib/librte_mbuf/meson.build | 6 +-
lib/librte_mbuf/rte_mbuf.h | 23 +-
lib/librte_mbuf/rte_mbuf_dyn.c | 548 +++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf_dyn.h | 226 ++++++++++
lib/librte_mbuf/rte_mbuf_version.map | 7 +
8 files changed, 959 insertions(+), 5 deletions(-)
create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
diff --git a/app/test/test_mbuf.c b/app/test/test_mbuf.c
index b9c2b2500..01cafad59 100644
--- a/app/test/test_mbuf.c
+++ b/app/test/test_mbuf.c
@@ -28,6 +28,7 @@
#include <rte_random.h>
#include <rte_cycles.h>
#include <rte_malloc.h>
+#include <rte_mbuf_dyn.h>
#include "test.h"
@@ -657,7 +658,6 @@ test_attach_from_different_pool(struct rte_mempool *pktmbuf_pool,
rte_pktmbuf_free(clone2);
return -1;
}
-#undef GOTO_FAIL
/*
* test allocation and free of mbufs
@@ -1276,6 +1276,143 @@ test_tx_offload(void)
return (v1 == v2) ? 0 : -EINVAL;
}
+static int
+test_mbuf_dyn(struct rte_mempool *pktmbuf_pool)
+{
+ const struct rte_mbuf_dynfield dynfield = {
+ .name = "test-dynfield",
+ .size = sizeof(uint8_t),
+ .align = __alignof__(uint8_t),
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynfield dynfield2 = {
+ .name = "test-dynfield2",
+ .size = sizeof(uint16_t),
+ .align = __alignof__(uint16_t),
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynfield dynfield3 = {
+ .name = "test-dynfield3",
+ .size = sizeof(uint8_t),
+ .align = __alignof__(uint8_t),
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynfield dynfield_fail_big = {
+ .name = "test-dynfield-fail-big",
+ .size = 256,
+ .align = 1,
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynfield dynfield_fail_align = {
+ .name = "test-dynfield-fail-align",
+ .size = 1,
+ .align = 3,
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynflag dynflag = {
+ .name = "test-dynflag",
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynflag dynflag2 = {
+ .name = "test-dynflag2",
+ .flags = 0,
+ };
+ const struct rte_mbuf_dynflag dynflag3 = {
+ .name = "test-dynflag3",
+ .flags = 0,
+ };
+ struct rte_mbuf *m = NULL;
+ int offset, offset2, offset3;
+ int flag, flag2, flag3;
+ int ret;
+
+ printf("Test mbuf dynamic fields and flags\n");
+ rte_mbuf_dyn_dump(stdout);
+
+ offset = rte_mbuf_dynfield_register(&dynfield);
+ if (offset == -1)
+ GOTO_FAIL("failed to register dynamic field, offset=%d: %s",
+ offset, strerror(errno));
+
+ ret = rte_mbuf_dynfield_register(&dynfield);
+ if (ret != offset)
+ GOTO_FAIL("failed to lookup dynamic field, ret=%d: %s",
+ ret, strerror(errno));
+
+ offset2 = rte_mbuf_dynfield_register(&dynfield2);
+ if (offset2 == -1 || offset2 == offset || (offset2 & 1))
+ GOTO_FAIL("failed to register dynamic field 2, offset2=%d: %s",
+ offset2, strerror(errno));
+
+ offset3 = rte_mbuf_dynfield_register_offset(&dynfield3,
+ offsetof(struct rte_mbuf, dynfield1[1]));
+ if (offset3 != offsetof(struct rte_mbuf, dynfield1[1]))
+ GOTO_FAIL("failed to register dynamic field 3, offset=%d: %s",
+ offset3, strerror(errno));
+
+ printf("dynfield: offset=%d, offset2=%d, offset3=%d\n",
+ offset, offset2, offset3);
+
+ ret = rte_mbuf_dynfield_register(&dynfield_fail_big);
+ if (ret != -1)
+ GOTO_FAIL("dynamic field creation should fail (too big)");
+
+ ret = rte_mbuf_dynfield_register(&dynfield_fail_align);
+ if (ret != -1)
+ GOTO_FAIL("dynamic field creation should fail (bad alignment)");
+
+ ret = rte_mbuf_dynfield_register_offset(&dynfield_fail_align,
+ offsetof(struct rte_mbuf, ol_flags));
+ if (ret != -1)
+ GOTO_FAIL("dynamic field creation should fail (not avail)");
+
+ flag = rte_mbuf_dynflag_register(&dynflag);
+ if (flag == -1)
+ GOTO_FAIL("failed to register dynamic flag, flag=%d: %s",
+ flag, strerror(errno));
+
+ ret = rte_mbuf_dynflag_register(&dynflag);
+ if (ret != flag)
+ GOTO_FAIL("failed to lookup dynamic flag, ret=%d: %s",
+ ret, strerror(errno));
+
+ flag2 = rte_mbuf_dynflag_register(&dynflag2);
+ if (flag2 == -1 || flag2 == flag)
+ GOTO_FAIL("failed to register dynamic flag 2, flag2=%d: %s",
+ flag2, strerror(errno));
+
+ flag3 = rte_mbuf_dynflag_register_bitnum(&dynflag3,
+ rte_bsf64(PKT_LAST_FREE));
+ if (flag3 != rte_bsf64(PKT_LAST_FREE))
+ GOTO_FAIL("failed to register dynamic flag 3, flag2=%d: %s",
+ flag3, strerror(errno));
+
+ printf("dynflag: flag=%d, flag2=%d, flag3=%d\n", flag, flag2, flag3);
+
+ /* set, get dynamic field */
+ m = rte_pktmbuf_alloc(pktmbuf_pool);
+ if (m == NULL)
+ GOTO_FAIL("Cannot allocate mbuf");
+
+ *RTE_MBUF_DYNFIELD(m, offset, uint8_t *) = 1;
+ if (*RTE_MBUF_DYNFIELD(m, offset, uint8_t *) != 1)
+ GOTO_FAIL("failed to read dynamic field");
+ *RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) = 1000;
+ if (*RTE_MBUF_DYNFIELD(m, offset2, uint16_t *) != 1000)
+ GOTO_FAIL("failed to read dynamic field");
+
+ /* set a dynamic flag */
+ m->ol_flags |= (1ULL << flag);
+
+ rte_mbuf_dyn_dump(stdout);
+ rte_pktmbuf_free(m);
+ return 0;
+fail:
+ rte_pktmbuf_free(m);
+ return -1;
+}
+#undef GOTO_FAIL
+
static int
test_mbuf(void)
{
@@ -1295,6 +1432,12 @@ test_mbuf(void)
goto err;
}
+ /* test registration of dynamic fields and flags */
+ if (test_mbuf_dyn(pktmbuf_pool) < 0) {
+ printf("mbuf dynflag test failed\n");
+ goto err;
+ }
+
/* create a specific pktmbuf pool with a priv_size != 0 and no data
* room size */
pktmbuf_pool2 = rte_pktmbuf_pool_create("test_pktmbuf_pool2",
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 85953b962..9e9c94554 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -21,6 +21,13 @@ DPDK Release 19.11
xdg-open build/doc/html/guides/rel_notes/release_19_11.html
+* **Add support of support dynamic fields and flags in mbuf.**
+
+ This new feature adds the ability to dynamically register some room
+ for a field or a flag in the mbuf structure. This is typically used
+ for specific offload features, where adding a static field or flag
+ in the mbuf is not justified.
+
New Features
------------
diff --git a/lib/librte_mbuf/Makefile b/lib/librte_mbuf/Makefile
index c8f6d2689..5a9bcee73 100644
--- a/lib/librte_mbuf/Makefile
+++ b/lib/librte_mbuf/Makefile
@@ -17,8 +17,10 @@ LIBABIVER := 5
# all source are stored in SRCS-y
SRCS-$(CONFIG_RTE_LIBRTE_MBUF) := rte_mbuf.c rte_mbuf_ptype.c rte_mbuf_pool_ops.c
+SRCS-$(CONFIG_RTE_LIBRTE_MBUF) += rte_mbuf_dyn.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include := rte_mbuf.h rte_mbuf_ptype.h rte_mbuf_pool_ops.h
+SYMLINK-$(CONFIG_RTE_LIBRTE_MBUF)-include += rte_mbuf_dyn.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_mbuf/meson.build b/lib/librte_mbuf/meson.build
index 6cc11ebb4..9137e8f26 100644
--- a/lib/librte_mbuf/meson.build
+++ b/lib/librte_mbuf/meson.build
@@ -2,8 +2,10 @@
# Copyright(c) 2017 Intel Corporation
version = 5
-sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c')
-headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h')
+sources = files('rte_mbuf.c', 'rte_mbuf_ptype.c', 'rte_mbuf_pool_ops.c',
+ 'rte_mbuf_dyn.c')
+headers = files('rte_mbuf.h', 'rte_mbuf_ptype.h', 'rte_mbuf_pool_ops.h',
+ 'rte_mbuf_dyn.h')
deps += ['mempool']
allow_experimental_apis = true
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index fb0849ac1..5740b1e93 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -198,9 +198,12 @@ extern "C" {
#define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
#define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
-/* add new RX flags here */
+/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
-/* add new TX flags here */
+#define PKT_FIRST_FREE (1ULL << 23)
+#define PKT_LAST_FREE (1ULL << 39)
+
+/* add new TX flags here, don't forget to update PKT_LAST_FREE */
/**
* Indicate that the metadata field in the mbuf is in use.
@@ -738,6 +741,7 @@ struct rte_mbuf {
*/
struct rte_mbuf_ext_shared_info *shinfo;
+ uint64_t dynfield1[2]; /**< Reserved for dynamic fields. */
} __rte_cache_aligned;
/**
@@ -1684,6 +1688,20 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
*/
#define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
+/**
+ * Copy dynamic fields from m_src to m_dst.
+ *
+ * @param m_dst
+ * The destination mbuf.
+ * @param m_src
+ * The source mbuf.
+ */
+static inline void
+rte_mbuf_dynfield_copy(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
+{
+ memcpy(&mdst->dynfield1, msrc->dynfield1, sizeof(mdst->dynfield1));
+}
+
/* internal */
static inline void
__rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
@@ -1695,6 +1713,7 @@ __rte_pktmbuf_copy_hdr(struct rte_mbuf *mdst, const struct rte_mbuf *msrc)
mdst->hash = msrc->hash;
mdst->packet_type = msrc->packet_type;
mdst->timestamp = msrc->timestamp;
+ rte_mbuf_dynfield_copy(mdst, msrc);
}
/**
diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
new file mode 100644
index 000000000..9ef235483
--- /dev/null
+++ b/lib/librte_mbuf/rte_mbuf_dyn.c
@@ -0,0 +1,548 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2019 6WIND S.A.
+ */
+
+#include <sys/queue.h>
+#include <stdint.h>
+#include <limits.h>
+
+#include <rte_common.h>
+#include <rte_eal.h>
+#include <rte_eal_memconfig.h>
+#include <rte_tailq.h>
+#include <rte_errno.h>
+#include <rte_malloc.h>
+#include <rte_string_fns.h>
+#include <rte_mbuf.h>
+#include <rte_mbuf_dyn.h>
+
+#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
+
+struct mbuf_dynfield_elt {
+ TAILQ_ENTRY(mbuf_dynfield_elt) next;
+ struct rte_mbuf_dynfield params;
+ size_t offset;
+};
+TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
+
+static struct rte_tailq_elem mbuf_dynfield_tailq = {
+ .name = "RTE_MBUF_DYNFIELD",
+};
+EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
+
+struct mbuf_dynflag_elt {
+ TAILQ_ENTRY(mbuf_dynflag_elt) next;
+ struct rte_mbuf_dynflag params;
+ unsigned int bitnum;
+};
+TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
+
+static struct rte_tailq_elem mbuf_dynflag_tailq = {
+ .name = "RTE_MBUF_DYNFLAG",
+};
+EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
+
+struct mbuf_dyn_shm {
+ /**
+ * For each mbuf byte, free_space[i] != 0 if space is free.
+ * The value is the size of the biggest aligned element that
+ * can fit in the zone.
+ */
+ uint8_t free_space[sizeof(struct rte_mbuf)];
+ /** Bitfield of available flags. */
+ uint64_t free_flags;
+};
+static struct mbuf_dyn_shm *shm;
+
+/* Set the value of free_space[] according to the size and alignment of
+ * the free areas. This helps to select the best place when reserving a
+ * dynamic field. Assume tailq is locked.
+ */
+static void
+process_score(void)
+{
+ size_t off, align, size, i;
+
+ /* first, erase previous info */
+ for (i = 0; i < sizeof(struct rte_mbuf); i++) {
+ if (shm->free_space[i])
+ shm->free_space[i] = 1;
+ }
+
+ for (off = 0; off < sizeof(struct rte_mbuf); off++) {
+ /* get the size of the free zone */
+ for (size = 0; shm->free_space[off + size]; size++)
+ ;
+ if (size == 0)
+ continue;
+
+ /* get the alignment of biggest object that can fit in
+ * the zone at this offset.
+ */
+ for (align = 1;
+ (off % (align << 1)) == 0 && (align << 1) <= size;
+ align <<= 1)
+ ;
+
+ /* save it in free_space[] */
+ for (i = off; i < off + size; i++)
+ shm->free_space[i] = RTE_MAX(align, shm->free_space[i]);
+ }
+}
+
+/* Allocate and initialize the shared memory. Assume tailq is locked */
+static int
+init_shared_mem(void)
+{
+ const struct rte_memzone *mz;
+ uint64_t mask;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
+ sizeof(struct mbuf_dyn_shm),
+ SOCKET_ID_ANY, 0,
+ RTE_CACHE_LINE_SIZE);
+ } else {
+ mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
+ }
+ if (mz == NULL)
+ return -1;
+
+ shm = mz->addr;
+
+#define mark_free(field) \
+ memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
+ 1, sizeof(((struct rte_mbuf *)0)->field))
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* init free_space, keep it sync'd with
+ * rte_mbuf_dynfield_copy().
+ */
+ memset(shm, 0, sizeof(*shm));
+ mark_free(dynfield1);
+
+ /* init free_flags */
+ for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
+ shm->free_flags |= mask;
+
+ process_score();
+ }
+#undef mark_free
+
+ return 0;
+}
+
+/* check if this offset can be used */
+static int
+check_offset(size_t offset, size_t size, size_t align)
+{
+ size_t i;
+
+ if ((offset & (align - 1)) != 0)
+ return -1;
+ if (offset + size > sizeof(struct rte_mbuf))
+ return -1;
+
+ for (i = 0; i < size; i++) {
+ if (!shm->free_space[i + offset])
+ return -1;
+ }
+
+ return 0;
+}
+
+/* assume tailq is locked */
+static struct mbuf_dynfield_elt *
+__mbuf_dynfield_lookup(const char *name)
+{
+ struct mbuf_dynfield_list *mbuf_dynfield_list;
+ struct mbuf_dynfield_elt *mbuf_dynfield;
+ struct rte_tailq_entry *te;
+
+ mbuf_dynfield_list = RTE_TAILQ_CAST(
+ mbuf_dynfield_tailq.head, mbuf_dynfield_list);
+
+ TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
+ mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
+ if (strcmp(name, mbuf_dynfield->params.name) == 0)
+ break;
+ }
+
+ if (te == NULL) {
+ rte_errno = ENOENT;
+ return NULL;
+ }
+
+ return mbuf_dynfield;
+}
+
+int
+rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
+{
+ struct mbuf_dynfield_elt *mbuf_dynfield;
+
+ if (shm == NULL) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+
+ rte_mcfg_tailq_read_lock();
+ mbuf_dynfield = __mbuf_dynfield_lookup(name);
+ rte_mcfg_tailq_read_unlock();
+
+ if (mbuf_dynfield == NULL) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+
+ if (params != NULL)
+ memcpy(params, &mbuf_dynfield->params, sizeof(*params));
+
+ return mbuf_dynfield->offset;
+}
+
+static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
+ const struct rte_mbuf_dynfield *params2)
+{
+ if (strcmp(params1->name, params2->name))
+ return -1;
+ if (params1->size != params2->size)
+ return -1;
+ if (params1->align != params2->align)
+ return -1;
+ if (params1->flags != params2->flags)
+ return -1;
+ return 0;
+}
+
+/* assume tailq is locked */
+static int
+__rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
+ size_t req)
+{
+ struct mbuf_dynfield_list *mbuf_dynfield_list;
+ struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
+ struct rte_tailq_entry *te = NULL;
+ unsigned int best_zone = UINT_MAX;
+ size_t i, offset;
+ int ret;
+
+ if (shm == NULL && init_shared_mem() < 0)
+ return -1;
+
+ mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
+ if (mbuf_dynfield != NULL) {
+ if (req != SIZE_MAX && req != mbuf_dynfield->offset) {
+ rte_errno = EEXIST;
+ return -1;
+ }
+ if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) < 0) {
+ rte_errno = EEXIST;
+ return -1;
+ }
+ return mbuf_dynfield->offset;
+ }
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ rte_errno = EPERM;
+ return -1;
+ }
+
+ if (req == SIZE_MAX) {
+ for (offset = 0;
+ offset < sizeof(struct rte_mbuf);
+ offset++) {
+ if (check_offset(offset, params->size,
+ params->align) == 0 &&
+ shm->free_space[offset] < best_zone) {
+ best_zone = shm->free_space[offset];
+ req = offset;
+ }
+ }
+ if (req == SIZE_MAX) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+ } else {
+ if (check_offset(req, params->size, params->align) < 0) {
+ rte_errno = EBUSY;
+ return -1;
+ }
+ }
+
+ offset = req;
+ mbuf_dynfield_list = RTE_TAILQ_CAST(
+ mbuf_dynfield_tailq.head, mbuf_dynfield_list);
+
+ te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
+ if (te == NULL)
+ return -1;
+
+ mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
+ if (mbuf_dynfield == NULL) {
+ rte_free(te);
+ return -1;
+ }
+
+ ret = strlcpy(mbuf_dynfield->params.name, params->name,
+ sizeof(mbuf_dynfield->params.name));
+ if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
+ rte_errno = ENAMETOOLONG;
+ rte_free(mbuf_dynfield);
+ rte_free(te);
+ return -1;
+ }
+ memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield->params));
+ mbuf_dynfield->offset = offset;
+ te->data = mbuf_dynfield;
+
+ TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
+
+ for (i = offset; i < offset + params->size; i++)
+ shm->free_space[i] = 0;
+ process_score();
+
+ RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu, al=%zu, fl=0x%x) -> %zd\n",
+ params->name, params->size, params->align, params->flags,
+ offset);
+
+ return offset;
+}
+
+int
+rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
+ size_t req)
+{
+ int ret;
+
+ if (params->size >= sizeof(struct rte_mbuf)) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+ if (!rte_is_power_of_2(params->align)) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+ if (params->flags != 0) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ rte_mcfg_tailq_write_lock();
+ ret = __rte_mbuf_dynfield_register_offset(params, req);
+ rte_mcfg_tailq_write_unlock();
+
+ return ret;
+}
+
+int
+rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
+{
+ return rte_mbuf_dynfield_register_offset(params, SIZE_MAX);
+}
+
+/* assume tailq is locked */
+static struct mbuf_dynflag_elt *
+__mbuf_dynflag_lookup(const char *name)
+{
+ struct mbuf_dynflag_list *mbuf_dynflag_list;
+ struct mbuf_dynflag_elt *mbuf_dynflag;
+ struct rte_tailq_entry *te;
+
+ mbuf_dynflag_list = RTE_TAILQ_CAST(
+ mbuf_dynflag_tailq.head, mbuf_dynflag_list);
+
+ TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
+ mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
+ if (strncmp(name, mbuf_dynflag->params.name,
+ RTE_MBUF_DYN_NAMESIZE) == 0)
+ break;
+ }
+
+ if (te == NULL) {
+ rte_errno = ENOENT;
+ return NULL;
+ }
+
+ return mbuf_dynflag;
+}
+
+int
+rte_mbuf_dynflag_lookup(const char *name,
+ struct rte_mbuf_dynflag *params)
+{
+ struct mbuf_dynflag_elt *mbuf_dynflag;
+
+ if (shm == NULL) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+
+ rte_mcfg_tailq_read_lock();
+ mbuf_dynflag = __mbuf_dynflag_lookup(name);
+ rte_mcfg_tailq_read_unlock();
+
+ if (mbuf_dynflag == NULL) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+
+ if (params != NULL)
+ memcpy(params, &mbuf_dynflag->params, sizeof(*params));
+
+ return mbuf_dynflag->bitnum;
+}
+
+static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
+ const struct rte_mbuf_dynflag *params2)
+{
+ if (strcmp(params1->name, params2->name))
+ return -1;
+ if (params1->flags != params2->flags)
+ return -1;
+ return 0;
+}
+
+/* assume tailq is locked */
+static int
+__rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
+ unsigned int req)
+{
+ struct mbuf_dynflag_list *mbuf_dynflag_list;
+ struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
+ struct rte_tailq_entry *te = NULL;
+ unsigned int bitnum;
+ int ret;
+
+ if (shm == NULL && init_shared_mem() < 0)
+ return -1;
+
+ mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
+ if (mbuf_dynflag != NULL) {
+ if (req != UINT_MAX && req != mbuf_dynflag->bitnum) {
+ rte_errno = EEXIST;
+ return -1;
+ }
+ if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) < 0) {
+ rte_errno = EEXIST;
+ return -1;
+ }
+ return mbuf_dynflag->bitnum;
+ }
+
+ if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
+ rte_errno = EPERM;
+ return -1;
+ }
+
+ if (req == UINT_MAX) {
+ if (shm->free_flags == 0) {
+ rte_errno = ENOENT;
+ return -1;
+ }
+ bitnum = rte_bsf64(shm->free_flags);
+ } else {
+ if ((shm->free_flags & (1ULL << req)) == 0) {
+ rte_errno = EBUSY;
+ return -1;
+ }
+ bitnum = req;
+ }
+
+ mbuf_dynflag_list = RTE_TAILQ_CAST(
+ mbuf_dynflag_tailq.head, mbuf_dynflag_list);
+
+ te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
+ if (te == NULL)
+ return -1;
+
+ mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
+ if (mbuf_dynflag == NULL) {
+ rte_free(te);
+ return -1;
+ }
+
+ ret = strlcpy(mbuf_dynflag->params.name, params->name,
+ sizeof(mbuf_dynflag->params.name));
+ if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
+ rte_free(mbuf_dynflag);
+ rte_free(te);
+ rte_errno = ENAMETOOLONG;
+ return -1;
+ }
+ mbuf_dynflag->bitnum = bitnum;
+ te->data = mbuf_dynflag;
+
+ TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
+
+ shm->free_flags &= ~(1ULL << bitnum);
+
+ RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) -> %u\n",
+ params->name, params->flags, bitnum);
+
+ return bitnum;
+}
+
+int
+rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
+ unsigned int req)
+{
+ int ret;
+
+ if (req != UINT_MAX && req >= 64) {
+ rte_errno = EINVAL;
+ return -1;
+ }
+
+ rte_mcfg_tailq_write_lock();
+ ret = __rte_mbuf_dynflag_register_bitnum(params, req);
+ rte_mcfg_tailq_write_unlock();
+
+ return ret;
+}
+
+int
+rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params)
+{
+ return rte_mbuf_dynflag_register_bitnum(params, UINT_MAX);
+}
+
+void rte_mbuf_dyn_dump(FILE *out)
+{
+ struct mbuf_dynfield_list *mbuf_dynfield_list;
+ struct mbuf_dynfield_elt *dynfield;
+ struct mbuf_dynflag_list *mbuf_dynflag_list;
+ struct mbuf_dynflag_elt *dynflag;
+ struct rte_tailq_entry *te;
+ size_t i;
+
+ rte_mcfg_tailq_write_lock();
+ init_shared_mem();
+ fprintf(out, "Reserved fields:\n");
+ mbuf_dynfield_list = RTE_TAILQ_CAST(
+ mbuf_dynfield_tailq.head, mbuf_dynfield_list);
+ TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
+ dynfield = (struct mbuf_dynfield_elt *)te->data;
+ fprintf(out, " name=%s offset=%zd size=%zd align=%zd flags=%x\n",
+ dynfield->params.name, dynfield->offset,
+ dynfield->params.size, dynfield->params.align,
+ dynfield->params.flags);
+ }
+ fprintf(out, "Reserved flags:\n");
+ mbuf_dynflag_list = RTE_TAILQ_CAST(
+ mbuf_dynflag_tailq.head, mbuf_dynflag_list);
+ TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
+ dynflag = (struct mbuf_dynflag_elt *)te->data;
+ fprintf(out, " name=%s bitnum=%u flags=%x\n",
+ dynflag->params.name, dynflag->bitnum,
+ dynflag->params.flags);
+ }
+ fprintf(out, "Free space in mbuf (0 = free, value = zone alignment):\n");
+ for (i = 0; i < sizeof(struct rte_mbuf); i++) {
+ if ((i % 8) == 0)
+ fprintf(out, " %4.4zx: ", i);
+ fprintf(out, "%2.2x%s", shm->free_space[i],
+ (i % 8 != 7) ? " " : "\n");
+ }
+ rte_mcfg_tailq_write_unlock();
+}
diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h b/lib/librte_mbuf/rte_mbuf_dyn.h
new file mode 100644
index 000000000..307613c96
--- /dev/null
+++ b/lib/librte_mbuf/rte_mbuf_dyn.h
@@ -0,0 +1,226 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright 2019 6WIND S.A.
+ */
+
+#ifndef _RTE_MBUF_DYN_H_
+#define _RTE_MBUF_DYN_H_
+
+/**
+ * @file
+ * RTE Mbuf dynamic fields and flags
+ *
+ * Many features require to store data inside the mbuf. As the room in
+ * mbuf structure is limited, it is not possible to have a field for
+ * each feature. Also, changing fields in the mbuf structure can break
+ * the API or ABI.
+ *
+ * This module addresses this issue, by enabling the dynamic
+ * registration of fields or flags:
+ *
+ * - a dynamic field is a named area in the rte_mbuf structure, with a
+ * given size (>= 1 byte) and alignment constraint.
+ * - a dynamic flag is a named bit in the rte_mbuf structure, stored
+ * in mbuf->ol_flags.
+ *
+ * The typical use case is when a specific offload feature requires to
+ * register a dedicated offload field in the mbuf structure, and adding
+ * a static field or flag is not justified.
+ *
+ * Example of use:
+ *
+ * - A rte_mbuf_dynfield structure is defined, containing the parameters
+ * of the dynamic field to be registered:
+ * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
+ * - The application initializes the PMD, and asks for this feature
+ * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
+ * rxconf. This will make the PMD to register the field by calling
+ * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
+ * stores the returned offset.
+ * - The application that uses the offload feature also registers
+ * the field to retrieve the same offset.
+ * - When the PMD receives a packet, it can set the field:
+ * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
+ * - In the main loop, the application can retrieve the value with
+ * the same macro.
+ *
+ * To avoid wasting space, the dynamic fields or flags must only be
+ * reserved on demand, when an application asks for the related feature.
+ *
+ * The registration can be done at any moment, but it is not possible
+ * to unregister fields or flags for now.
+ *
+ * A dynamic field can be reserved and used by an application only.
+ * It can for instance be a packet mark.
+ */
+
+#include <sys/types.h>
+/**
+ * Maximum length of the dynamic field or flag string.
+ */
+#define RTE_MBUF_DYN_NAMESIZE 64
+
+/**
+ * Structure describing the parameters of a mbuf dynamic field.
+ */
+struct rte_mbuf_dynfield {
+ char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
+ size_t size; /**< The number of bytes to reserve. */
+ size_t align; /**< The alignment constraint (power of 2). */
+ unsigned int flags; /**< Reserved for future use, must be 0. */
+};
+
+/**
+ * Structure describing the parameters of a mbuf dynamic flag.
+ */
+struct rte_mbuf_dynflag {
+ char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */
+ unsigned int flags; /**< Reserved for future use, must be 0. */
+};
+
+/**
+ * Register space for a dynamic field in the mbuf structure.
+ *
+ * If the field is already registered (same name and parameters), its
+ * offset is returned.
+ *
+ * @param params
+ * A structure containing the requested parameters (name, size,
+ * alignment constraint and flags).
+ * @return
+ * The offset in the mbuf structure, or -1 on error.
+ * Possible values for rte_errno:
+ * - EINVAL: invalid parameters (size, align, or flags).
+ * - EEXIST: this name is already register with different parameters.
+ * - EPERM: called from a secondary process.
+ * - ENOENT: not enough room in mbuf.
+ * - ENOMEM: allocation failure.
+ * - ENAMETOOLONG: name does not ends with \0.
+ */
+__rte_experimental
+int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
+
+/**
+ * Register space for a dynamic field in the mbuf structure at offset.
+ *
+ * If the field is already registered (same name, parameters and offset),
+ * the offset is returned.
+ *
+ * @param params
+ * A structure containing the requested parameters (name, size,
+ * alignment constraint and flags).
+ * @param offset
+ * The requested offset. Ignored if SIZE_MAX is passed.
+ * @return
+ * The offset in the mbuf structure, or -1 on error.
+ * Possible values for rte_errno:
+ * - EINVAL: invalid parameters (size, align, flags, or offset).
+ * - EEXIST: this name is already register with different parameters.
+ * - EBUSY: the requested offset cannot be used.
+ * - EPERM: called from a secondary process.
+ * - ENOENT: not enough room in mbuf.
+ * - ENOMEM: allocation failure.
+ * - ENAMETOOLONG: name does not ends with \0.
+ */
+__rte_experimental
+int rte_mbuf_dynfield_register_offset(const struct rte_mbuf_dynfield *params,
+ size_t offset);
+
+/**
+ * Lookup for a registered dynamic mbuf field.
+ *
+ * @param name
+ * A string identifying the dynamic field.
+ * @param params
+ * If not NULL, and if the lookup is successful, the structure is
+ * filled with the parameters of the dynamic field.
+ * @return
+ * The offset of this field in the mbuf structure, or -1 on error.
+ * Possible values for rte_errno:
+ * - ENOENT: no dynamic field matches this name.
+ */
+__rte_experimental
+int rte_mbuf_dynfield_lookup(const char *name,
+ struct rte_mbuf_dynfield *params);
+
+/**
+ * Register a dynamic flag in the mbuf structure.
+ *
+ * If the flag is already registered (same name and parameters), its
+ * bitnum is returned.
+ *
+ * @param params
+ * A structure containing the requested parameters of the dynamic
+ * flag (name and options).
+ * @return
+ * The number of the reserved bit, or -1 on error.
+ * Possible values for rte_errno:
+ * - EINVAL: invalid parameters (size, align, or flags).
+ * - EEXIST: this name is already register with different parameters.
+ * - EPERM: called from a secondary process.
+ * - ENOENT: no more flag available.
+ * - ENOMEM: allocation failure.
+ * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
+ */
+__rte_experimental
+int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
+
+/**
+ * Register a dynamic flag in the mbuf structure specifying bitnum.
+ *
+ * If the flag is already registered (same name, parameters and bitnum),
+ * the bitnum is returned.
+ *
+ * @param params
+ * A structure containing the requested parameters of the dynamic
+ * flag (name and options).
+ * @param bitnum
+ * The requested bitnum. Ignored if UINT_MAX is passed.
+ * @return
+ * The number of the reserved bit, or -1 on error.
+ * Possible values for rte_errno:
+ * - EINVAL: invalid parameters (size, align, or flags).
+ * - EEXIST: this name is already register with different parameters.
+ * - EBUSY: the requested bitnum cannot be used.
+ * - EPERM: called from a secondary process.
+ * - ENOENT: no more flag available.
+ * - ENOMEM: allocation failure.
+ * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
+ */
+__rte_experimental
+int rte_mbuf_dynflag_register_bitnum(const struct rte_mbuf_dynflag *params,
+ unsigned int bitnum);
+
+/**
+ * Lookup for a registered dynamic mbuf flag.
+ *
+ * @param name
+ * A string identifying the dynamic flag.
+ * @param params
+ * If not NULL, and if the lookup is successful, the structure is
+ * filled with the parameters of the dynamic flag.
+ * @return
+ * The offset of this flag in the mbuf structure, or -1 on error.
+ * Possible values for rte_errno:
+ * - ENOENT: no dynamic flag matches this name.
+ */
+__rte_experimental
+int rte_mbuf_dynflag_lookup(const char *name,
+ struct rte_mbuf_dynflag *params);
+
+/**
+ * Helper macro to access to a dynamic field.
+ */
+#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
+
+/**
+ * Dump the status of dynamic fields and flags.
+ *
+ * @param out
+ * The stream where the status is displayed.
+ */
+__rte_experimental
+void rte_mbuf_dyn_dump(FILE *out);
+
+/* Placeholder for dynamic fields and flags declarations. */
+
+#endif
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index 519fead35..9bf5ca37a 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -58,6 +58,13 @@ EXPERIMENTAL {
global:
rte_mbuf_check;
+ rte_mbuf_dynfield_lookup;
+ rte_mbuf_dynfield_register;
+ rte_mbuf_dynfield_register_offset;
+ rte_mbuf_dynflag_lookup;
+ rte_mbuf_dynflag_register;
+ rte_mbuf_dynflag_register_bitnum;
+ rte_mbuf_dyn_dump;
rte_pktmbuf_copy;
} DPDK_18.08;
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 10/10] buildtools: add ABI versioning check script
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (10 preceding siblings ...)
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 09/10] build: change ABI version to 20.0 Anatoly Burakov
@ 2019-10-17 14:32 23% ` Anatoly Burakov
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:32 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
Add a shell script that checks whether built libraries are
versioned with expected ABI (current ABI, current ABI + 1,
or EXPERIMENTAL).
The following command was used to verify current source tree
(assuming build directory is in ./build):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v2:
- Moved this to the end of the patchset
- Fixed bug when ABI symbols were not found because the .so
did not declare any public symbols
buildtools/check-abi-version.sh | 54 +++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100755 buildtools/check-abi-version.sh
diff --git a/buildtools/check-abi-version.sh b/buildtools/check-abi-version.sh
new file mode 100755
index 0000000000..29aea97735
--- /dev/null
+++ b/buildtools/check-abi-version.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# Check whether library symbols have correct
+# version (provided ABI number or provided ABI
+# number + 1 or EXPERIMENTAL).
+# Args:
+# $1: path of the library .so file
+# $2: ABI major version number to check
+# (defaults to ABI_VERSION file value)
+
+if [ -z "$1" ]; then
+ echo "Script checks whether library symbols have"
+ echo "correct version (ABI_VER/ABI_VER+1/EXPERIMENTAL)"
+ echo "Usage:"
+ echo " $0 SO_FILE_PATH [ABI_VER]"
+ exit 1
+fi
+
+LIB="$1"
+DEFAULT_ABI=$(cat "$(dirname \
+ $(readlink -f $0))/../config/ABI_VERSION" | \
+ cut -d'.' -f 1)
+ABIVER="DPDK_${2-$DEFAULT_ABI}"
+NEXT_ABIVER="DPDK_$((${2-$DEFAULT_ABI}+1))"
+
+ret=0
+
+# get output of objdump
+OBJ_DUMP_OUTPUT=`objdump -TC --section=.text ${LIB} 2>&1 | grep ".text"`
+
+# there may not be any .text sections in the .so file, in which case exit early
+echo "${OBJ_DUMP_OUTPUT}" | grep "not found in any input file" -q
+if [ "$?" -eq 0 ]; then
+ exit 0
+fi
+
+# we have symbols, so let's see if the versions are correct
+for SYM in `echo "${OBJ_DUMP_OUTPUT}" | awk '{print $(NF-1) "-" $NF}'`
+do
+ version=$(echo $SYM | cut -d'-' -f 1)
+ symbol=$(echo $SYM | cut -d'-' -f 2)
+ case $version in (*"$ABIVER"*|*"$NEXT_ABIVER"*|"EXPERIMENTAL")
+ ;;
+ (*)
+ echo "Warning: symbol $symbol ($version) should be annotated " \
+ "as ABI version $ABIVER / $NEXT_ABIVER, or EXPERIMENTAL."
+ ret=1
+ ;;
+ esac
+done
+
+exit $ret
--
2.17.1
^ permalink raw reply [relevance 23%]
* [dpdk-dev] [PATCH v4 08/10] drivers/octeontx: add missing public symbol
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (8 preceding siblings ...)
2019-10-17 14:31 6% ` [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix Anatoly Burakov
@ 2019-10-17 14:31 3% ` Anatoly Burakov
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 09/10] build: change ABI version to 20.0 Anatoly Burakov
2019-10-17 14:32 23% ` [dpdk-dev] [PATCH v4 10/10] buildtools: add ABI versioning check script Anatoly Burakov
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Jerin Jacob, john.mcnamara, bruce.richardson, thomas,
david.marchand, pbhagavatula, stable
The logtype symbol was missing from the .map file. Add it.
Fixes: d8dd31652cf4 ("common/octeontx: move mbox to common folder")
Cc: pbhagavatula@caviumnetworks.com
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v2:
- add this patch to avoid compile breakage when bumping ABI
drivers/common/octeontx/rte_common_octeontx_version.map | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index f04b3b7f8a..a9b3cff9bc 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,6 +1,7 @@
DPDK_18.05 {
global:
+ octeontx_logtype_mbox;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
octeontx_mbox_send;
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (7 preceding siblings ...)
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 06/10] distributor: " Anatoly Burakov
@ 2019-10-17 14:31 6% ` Anatoly Burakov
2019-10-17 16:00 4% ` Hunt, David
2019-10-17 14:31 3% ` [dpdk-dev] [PATCH v4 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
` (2 subsequent siblings)
11 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, David Hunt, john.mcnamara, bruce.richardson,
thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
The original ABI versioning was slightly misleading in that the
DPDK 2.0 ABI was really a single mode for the distributor, and is
used as such throughout the distributor code.
Fix this by renaming all _v20 API's to _single API's, and remove
symbol versioning.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v4:
- Changed it back to how it was with v2
- Removed remaining v2.0 symbols
v3:
- Removed single mode from distributor as per Dave's comments
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_distributor/Makefile | 2 +-
lib/librte_distributor/meson.build | 2 +-
lib/librte_distributor/rte_distributor.c | 24 ++++----
.../rte_distributor_private.h | 10 ++--
...ributor_v20.c => rte_distributor_single.c} | 57 ++++++++-----------
...ributor_v20.h => rte_distributor_single.h} | 26 ++++-----
.../rte_distributor_version.map | 18 +-----
7 files changed, 58 insertions(+), 81 deletions(-)
rename lib/librte_distributor/{rte_distributor_v20.c => rte_distributor_single.c} (84%)
rename lib/librte_distributor/{rte_distributor_v20.h => rte_distributor_single.h} (89%)
diff --git a/lib/librte_distributor/Makefile b/lib/librte_distributor/Makefile
index 0ef80dcff4..d9d0089166 100644
--- a/lib/librte_distributor/Makefile
+++ b/lib/librte_distributor/Makefile
@@ -15,7 +15,7 @@ EXPORT_MAP := rte_distributor_version.map
LIBABIVER := 1
# all source are stored in SRCS-y
-SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) := rte_distributor_v20.c
+SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) := rte_distributor_single.c
SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += rte_distributor.c
ifeq ($(CONFIG_RTE_ARCH_X86),y)
SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += rte_distributor_match_sse.c
diff --git a/lib/librte_distributor/meson.build b/lib/librte_distributor/meson.build
index dba7e3b2aa..bd12ddb2f1 100644
--- a/lib/librte_distributor/meson.build
+++ b/lib/librte_distributor/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-sources = files('rte_distributor.c', 'rte_distributor_v20.c')
+sources = files('rte_distributor.c', 'rte_distributor_single.c')
if arch_subdir == 'x86'
sources += files('rte_distributor_match_sse.c')
else
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index ca3f21b833..b4fc0bfead 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -18,7 +18,7 @@
#include "rte_distributor_private.h"
#include "rte_distributor.h"
-#include "rte_distributor_v20.h"
+#include "rte_distributor_single.h"
TAILQ_HEAD(rte_dist_burst_list, rte_distributor);
@@ -42,7 +42,7 @@ rte_distributor_request_pkt(struct rte_distributor *d,
volatile int64_t *retptr64;
if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- rte_distributor_request_pkt_v20(d->d_v20,
+ rte_distributor_request_pkt_single(d->d_single,
worker_id, oldpkt[0]);
return;
}
@@ -88,7 +88,8 @@ rte_distributor_poll_pkt(struct rte_distributor *d,
unsigned int i;
if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- pkts[0] = rte_distributor_poll_pkt_v20(d->d_v20, worker_id);
+ pkts[0] = rte_distributor_poll_pkt_single(d->d_single,
+ worker_id);
return (pkts[0]) ? 1 : 0;
}
@@ -123,7 +124,7 @@ rte_distributor_get_pkt(struct rte_distributor *d,
if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
if (return_count <= 1) {
- pkts[0] = rte_distributor_get_pkt_v20(d->d_v20,
+ pkts[0] = rte_distributor_get_pkt_single(d->d_single,
worker_id, oldpkt[0]);
return (pkts[0]) ? 1 : 0;
} else
@@ -153,7 +154,7 @@ rte_distributor_return_pkt(struct rte_distributor *d,
if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
if (num == 1)
- return rte_distributor_return_pkt_v20(d->d_v20,
+ return rte_distributor_return_pkt_single(d->d_single,
worker_id, oldpkt[0]);
else
return -EINVAL;
@@ -330,7 +331,8 @@ rte_distributor_process(struct rte_distributor *d,
if (d->alg_type == RTE_DIST_ALG_SINGLE) {
/* Call the old API */
- return rte_distributor_process_v20(d->d_v20, mbufs, num_mbufs);
+ return rte_distributor_process_single(d->d_single,
+ mbufs, num_mbufs);
}
if (unlikely(num_mbufs == 0)) {
@@ -464,7 +466,7 @@ rte_distributor_returned_pkts(struct rte_distributor *d,
if (d->alg_type == RTE_DIST_ALG_SINGLE) {
/* Call the old API */
- return rte_distributor_returned_pkts_v20(d->d_v20,
+ return rte_distributor_returned_pkts_single(d->d_single,
mbufs, max_mbufs);
}
@@ -507,7 +509,7 @@ rte_distributor_flush(struct rte_distributor *d)
if (d->alg_type == RTE_DIST_ALG_SINGLE) {
/* Call the old API */
- return rte_distributor_flush_v20(d->d_v20);
+ return rte_distributor_flush_single(d->d_single);
}
flushed = total_outstanding(d);
@@ -538,7 +540,7 @@ rte_distributor_clear_returns(struct rte_distributor *d)
if (d->alg_type == RTE_DIST_ALG_SINGLE) {
/* Call the old API */
- rte_distributor_clear_returns_v20(d->d_v20);
+ rte_distributor_clear_returns_single(d->d_single);
return;
}
@@ -578,9 +580,9 @@ rte_distributor_create(const char *name,
rte_errno = ENOMEM;
return NULL;
}
- d->d_v20 = rte_distributor_create_v20(name,
+ d->d_single = rte_distributor_create_single(name,
socket_id, num_workers);
- if (d->d_v20 == NULL) {
+ if (d->d_single == NULL) {
free(d);
/* rte_errno will have been set */
return NULL;
diff --git a/lib/librte_distributor/rte_distributor_private.h b/lib/librte_distributor/rte_distributor_private.h
index 33cd89410c..bdb62b6e92 100644
--- a/lib/librte_distributor/rte_distributor_private.h
+++ b/lib/librte_distributor/rte_distributor_private.h
@@ -55,7 +55,7 @@ extern "C" {
* the next cache line to worker 0, we pad this out to three cache lines.
* Only 64-bits of the memory is actually used though.
*/
-union rte_distributor_buffer_v20 {
+union rte_distributor_buffer_single {
volatile int64_t bufptr64;
char pad[RTE_CACHE_LINE_SIZE*3];
} __rte_cache_aligned;
@@ -80,8 +80,8 @@ struct rte_distributor_returned_pkts {
struct rte_mbuf *mbufs[RTE_DISTRIB_MAX_RETURNS];
};
-struct rte_distributor_v20 {
- TAILQ_ENTRY(rte_distributor_v20) next; /**< Next in list. */
+struct rte_distributor_single {
+ TAILQ_ENTRY(rte_distributor_single) next; /**< Next in list. */
char name[RTE_DISTRIBUTOR_NAMESIZE]; /**< Name of the ring. */
unsigned int num_workers; /**< Number of workers polling */
@@ -96,7 +96,7 @@ struct rte_distributor_v20 {
struct rte_distributor_backlog backlog[RTE_DISTRIB_MAX_WORKERS];
- union rte_distributor_buffer_v20 bufs[RTE_DISTRIB_MAX_WORKERS];
+ union rte_distributor_buffer_single bufs[RTE_DISTRIB_MAX_WORKERS];
struct rte_distributor_returned_pkts returns;
};
@@ -154,7 +154,7 @@ struct rte_distributor {
enum rte_distributor_match_function dist_match_fn;
- struct rte_distributor_v20 *d_v20;
+ struct rte_distributor_single *d_single;
};
void
diff --git a/lib/librte_distributor/rte_distributor_v20.c b/lib/librte_distributor/rte_distributor_single.c
similarity index 84%
rename from lib/librte_distributor/rte_distributor_v20.c
rename to lib/librte_distributor/rte_distributor_single.c
index cdc0969a89..9a6ef826c9 100644
--- a/lib/librte_distributor/rte_distributor_v20.c
+++ b/lib/librte_distributor/rte_distributor_single.c
@@ -15,10 +15,10 @@
#include <rte_pause.h>
#include <rte_tailq.h>
-#include "rte_distributor_v20.h"
+#include "rte_distributor_single.h"
#include "rte_distributor_private.h"
-TAILQ_HEAD(rte_distributor_list, rte_distributor_v20);
+TAILQ_HEAD(rte_distributor_list, rte_distributor_single);
static struct rte_tailq_elem rte_distributor_tailq = {
.name = "RTE_DISTRIBUTOR",
@@ -28,23 +28,22 @@ EAL_REGISTER_TAILQ(rte_distributor_tailq)
/**** APIs called by workers ****/
void
-rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_request_pkt_single(struct rte_distributor_single *d,
unsigned worker_id, struct rte_mbuf *oldpkt)
{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
+ union rte_distributor_buffer_single *buf = &d->bufs[worker_id];
int64_t req = (((int64_t)(uintptr_t)oldpkt) << RTE_DISTRIB_FLAG_BITS)
| RTE_DISTRIB_GET_BUF;
while (unlikely(buf->bufptr64 & RTE_DISTRIB_FLAGS_MASK))
rte_pause();
buf->bufptr64 = req;
}
-VERSION_SYMBOL(rte_distributor_request_pkt, _v20, 2.0);
struct rte_mbuf *
-rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_poll_pkt_single(struct rte_distributor_single *d,
unsigned worker_id)
{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
+ union rte_distributor_buffer_single *buf = &d->bufs[worker_id];
if (buf->bufptr64 & RTE_DISTRIB_GET_BUF)
return NULL;
@@ -52,31 +51,28 @@ rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d,
int64_t ret = buf->bufptr64 >> RTE_DISTRIB_FLAG_BITS;
return (struct rte_mbuf *)((uintptr_t)ret);
}
-VERSION_SYMBOL(rte_distributor_poll_pkt, _v20, 2.0);
struct rte_mbuf *
-rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_get_pkt_single(struct rte_distributor_single *d,
unsigned worker_id, struct rte_mbuf *oldpkt)
{
struct rte_mbuf *ret;
- rte_distributor_request_pkt_v20(d, worker_id, oldpkt);
- while ((ret = rte_distributor_poll_pkt_v20(d, worker_id)) == NULL)
+ rte_distributor_request_pkt_single(d, worker_id, oldpkt);
+ while ((ret = rte_distributor_poll_pkt_single(d, worker_id)) == NULL)
rte_pause();
return ret;
}
-VERSION_SYMBOL(rte_distributor_get_pkt, _v20, 2.0);
int
-rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_return_pkt_single(struct rte_distributor_single *d,
unsigned worker_id, struct rte_mbuf *oldpkt)
{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
+ union rte_distributor_buffer_single *buf = &d->bufs[worker_id];
uint64_t req = (((int64_t)(uintptr_t)oldpkt) << RTE_DISTRIB_FLAG_BITS)
| RTE_DISTRIB_RETURN_BUF;
buf->bufptr64 = req;
return 0;
}
-VERSION_SYMBOL(rte_distributor_return_pkt, _v20, 2.0);
/**** APIs called on distributor core ***/
@@ -102,7 +98,7 @@ backlog_pop(struct rte_distributor_backlog *bl)
/* stores a packet returned from a worker inside the returns array */
static inline void
-store_return(uintptr_t oldbuf, struct rte_distributor_v20 *d,
+store_return(uintptr_t oldbuf, struct rte_distributor_single *d,
unsigned *ret_start, unsigned *ret_count)
{
/* store returns in a circular buffer - code is branch-free */
@@ -113,7 +109,7 @@ store_return(uintptr_t oldbuf, struct rte_distributor_v20 *d,
}
static inline void
-handle_worker_shutdown(struct rte_distributor_v20 *d, unsigned int wkr)
+handle_worker_shutdown(struct rte_distributor_single *d, unsigned int wkr)
{
d->in_flight_tags[wkr] = 0;
d->in_flight_bitmask &= ~(1UL << wkr);
@@ -143,7 +139,7 @@ handle_worker_shutdown(struct rte_distributor_v20 *d, unsigned int wkr)
* Note that the tags were set before first level call
* to rte_distributor_process.
*/
- rte_distributor_process_v20(d, pkts, i);
+ rte_distributor_process_single(d, pkts, i);
bl->count = bl->start = 0;
}
}
@@ -153,7 +149,7 @@ handle_worker_shutdown(struct rte_distributor_v20 *d, unsigned int wkr)
* to do a partial flush.
*/
static int
-process_returns(struct rte_distributor_v20 *d)
+process_returns(struct rte_distributor_single *d)
{
unsigned wkr;
unsigned flushed = 0;
@@ -192,7 +188,7 @@ process_returns(struct rte_distributor_v20 *d)
/* process a set of packets to distribute them to workers */
int
-rte_distributor_process_v20(struct rte_distributor_v20 *d,
+rte_distributor_process_single(struct rte_distributor_single *d,
struct rte_mbuf **mbufs, unsigned num_mbufs)
{
unsigned next_idx = 0;
@@ -293,11 +289,10 @@ rte_distributor_process_v20(struct rte_distributor_v20 *d,
d->returns.count = ret_count;
return num_mbufs;
}
-VERSION_SYMBOL(rte_distributor_process, _v20, 2.0);
/* return to the caller, packets returned from workers */
int
-rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
+rte_distributor_returned_pkts_single(struct rte_distributor_single *d,
struct rte_mbuf **mbufs, unsigned max_mbufs)
{
struct rte_distributor_returned_pkts *returns = &d->returns;
@@ -314,13 +309,12 @@ rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
return retval;
}
-VERSION_SYMBOL(rte_distributor_returned_pkts, _v20, 2.0);
/* return the number of packets in-flight in a distributor, i.e. packets
* being worked on or queued up in a backlog.
*/
static inline unsigned
-total_outstanding(const struct rte_distributor_v20 *d)
+total_outstanding(const struct rte_distributor_single *d)
{
unsigned wkr, total_outstanding;
@@ -335,35 +329,33 @@ total_outstanding(const struct rte_distributor_v20 *d)
/* flush the distributor, so that there are no outstanding packets in flight or
* queued up. */
int
-rte_distributor_flush_v20(struct rte_distributor_v20 *d)
+rte_distributor_flush_single(struct rte_distributor_single *d)
{
const unsigned flushed = total_outstanding(d);
while (total_outstanding(d) > 0)
- rte_distributor_process_v20(d, NULL, 0);
+ rte_distributor_process_single(d, NULL, 0);
return flushed;
}
-VERSION_SYMBOL(rte_distributor_flush, _v20, 2.0);
/* clears the internal returns array in the distributor */
void
-rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d)
+rte_distributor_clear_returns_single(struct rte_distributor_single *d)
{
d->returns.start = d->returns.count = 0;
#ifndef __OPTIMIZE__
memset(d->returns.mbufs, 0, sizeof(d->returns.mbufs));
#endif
}
-VERSION_SYMBOL(rte_distributor_clear_returns, _v20, 2.0);
/* creates a distributor instance */
-struct rte_distributor_v20 *
-rte_distributor_create_v20(const char *name,
+struct rte_distributor_single *
+rte_distributor_create_single(const char *name,
unsigned socket_id,
unsigned num_workers)
{
- struct rte_distributor_v20 *d;
+ struct rte_distributor_single *d;
struct rte_distributor_list *distributor_list;
char mz_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
@@ -399,4 +391,3 @@ rte_distributor_create_v20(const char *name,
return d;
}
-VERSION_SYMBOL(rte_distributor_create, _v20, 2.0);
diff --git a/lib/librte_distributor/rte_distributor_v20.h b/lib/librte_distributor/rte_distributor_single.h
similarity index 89%
rename from lib/librte_distributor/rte_distributor_v20.h
rename to lib/librte_distributor/rte_distributor_single.h
index 12865658ba..2f80aa43d1 100644
--- a/lib/librte_distributor/rte_distributor_v20.h
+++ b/lib/librte_distributor/rte_distributor_single.h
@@ -2,8 +2,8 @@
* Copyright(c) 2010-2014 Intel Corporation
*/
-#ifndef _RTE_DISTRIB_V20_H_
-#define _RTE_DISTRIB_V20_H_
+#ifndef _RTE_DISTRIB_SINGLE_H_
+#define _RTE_DISTRIB_SINGLE_H_
/**
* @file
@@ -19,7 +19,7 @@ extern "C" {
#define RTE_DISTRIBUTOR_NAMESIZE 32 /**< Length of name for instance */
-struct rte_distributor_v20;
+struct rte_distributor_single;
struct rte_mbuf;
/**
@@ -38,8 +38,8 @@ struct rte_mbuf;
* @return
* The newly created distributor instance
*/
-struct rte_distributor_v20 *
-rte_distributor_create_v20(const char *name, unsigned int socket_id,
+struct rte_distributor_single *
+rte_distributor_create_single(const char *name, unsigned int socket_id,
unsigned int num_workers);
/* *** APIS to be called on the distributor lcore *** */
@@ -74,7 +74,7 @@ rte_distributor_create_v20(const char *name, unsigned int socket_id,
* The number of mbufs processed.
*/
int
-rte_distributor_process_v20(struct rte_distributor_v20 *d,
+rte_distributor_process_single(struct rte_distributor_single *d,
struct rte_mbuf **mbufs, unsigned int num_mbufs);
/**
@@ -92,7 +92,7 @@ rte_distributor_process_v20(struct rte_distributor_v20 *d,
* The number of mbufs returned in the mbufs array.
*/
int
-rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
+rte_distributor_returned_pkts_single(struct rte_distributor_single *d,
struct rte_mbuf **mbufs, unsigned int max_mbufs);
/**
@@ -107,7 +107,7 @@ rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
* The number of queued/in-flight packets that were completed by this call.
*/
int
-rte_distributor_flush_v20(struct rte_distributor_v20 *d);
+rte_distributor_flush_single(struct rte_distributor_single *d);
/**
* Clears the array of returned packets used as the source for the
@@ -119,7 +119,7 @@ rte_distributor_flush_v20(struct rte_distributor_v20 *d);
* The distributor instance to be used
*/
void
-rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d);
+rte_distributor_clear_returns_single(struct rte_distributor_single *d);
/* *** APIS to be called on the worker lcores *** */
/*
@@ -148,7 +148,7 @@ rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d);
* A new packet to be processed by the worker thread.
*/
struct rte_mbuf *
-rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_get_pkt_single(struct rte_distributor_single *d,
unsigned int worker_id, struct rte_mbuf *oldpkt);
/**
@@ -164,7 +164,7 @@ rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d,
* The previous packet being processed by the worker
*/
int
-rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_return_pkt_single(struct rte_distributor_single *d,
unsigned int worker_id, struct rte_mbuf *mbuf);
/**
@@ -188,7 +188,7 @@ rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d,
* The previous packet, if any, being processed by the worker
*/
void
-rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_request_pkt_single(struct rte_distributor_single *d,
unsigned int worker_id, struct rte_mbuf *oldpkt);
/**
@@ -208,7 +208,7 @@ rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d,
* packet is yet available.
*/
struct rte_mbuf *
-rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d,
+rte_distributor_poll_pkt_single(struct rte_distributor_single *d,
unsigned int worker_id);
#ifdef __cplusplus
diff --git a/lib/librte_distributor/rte_distributor_version.map b/lib/librte_distributor/rte_distributor_version.map
index 3a285b394e..00e26b4804 100644
--- a/lib/librte_distributor/rte_distributor_version.map
+++ b/lib/librte_distributor/rte_distributor_version.map
@@ -1,19 +1,3 @@
-DPDK_2.0 {
- global:
-
- rte_distributor_clear_returns;
- rte_distributor_create;
- rte_distributor_flush;
- rte_distributor_get_pkt;
- rte_distributor_poll_pkt;
- rte_distributor_process;
- rte_distributor_request_pkt;
- rte_distributor_return_pkt;
- rte_distributor_returned_pkts;
-
- local: *;
-};
-
DPDK_17.05 {
global:
@@ -26,4 +10,4 @@ DPDK_17.05 {
rte_distributor_request_pkt;
rte_distributor_return_pkt;
rte_distributor_returned_pkts;
-} DPDK_2.0;
+};
--
2.17.1
^ permalink raw reply [relevance 6%]
* [dpdk-dev] [PATCH v4 06/10] distributor: remove deprecated code
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (6 preceding siblings ...)
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 05/10] lpm: " Anatoly Burakov
@ 2019-10-17 14:31 4% ` Anatoly Burakov
2019-10-17 15:59 0% ` Hunt, David
2019-10-17 14:31 6% ` [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix Anatoly Burakov
` (3 subsequent siblings)
11 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, David Hunt, john.mcnamara, bruce.richardson,
thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_distributor/rte_distributor.c | 56 +++--------------
.../rte_distributor_v1705.h | 61 -------------------
2 files changed, 9 insertions(+), 108 deletions(-)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index 21eb1fb0a1..ca3f21b833 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -19,7 +19,6 @@
#include "rte_distributor_private.h"
#include "rte_distributor.h"
#include "rte_distributor_v20.h"
-#include "rte_distributor_v1705.h"
TAILQ_HEAD(rte_dist_burst_list, rte_distributor);
@@ -33,7 +32,7 @@ EAL_REGISTER_TAILQ(rte_dist_burst_tailq)
/**** Burst Packet APIs called by workers ****/
void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
+rte_distributor_request_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt,
unsigned int count)
{
@@ -78,14 +77,9 @@ rte_distributor_request_pkt_v1705(struct rte_distributor *d,
*/
*retptr64 |= RTE_DISTRIB_GET_BUF;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_request_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_request_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count),
- rte_distributor_request_pkt_v1705);
int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
+rte_distributor_poll_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -119,13 +113,9 @@ rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_poll_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_poll_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts),
- rte_distributor_poll_pkt_v1705);
int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
+rte_distributor_get_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts,
struct rte_mbuf **oldpkt, unsigned int return_count)
{
@@ -153,14 +143,9 @@ rte_distributor_get_pkt_v1705(struct rte_distributor *d,
}
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_get_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_get_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int return_count),
- rte_distributor_get_pkt_v1705);
int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
+rte_distributor_return_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt, int num)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -187,10 +172,6 @@ rte_distributor_return_pkt_v1705(struct rte_distributor *d,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_return_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_return_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num),
- rte_distributor_return_pkt_v1705);
/**** APIs called on distributor core ***/
@@ -336,7 +317,7 @@ release(struct rte_distributor *d, unsigned int wkr)
/* process a set of packets to distribute them to workers */
int
-rte_distributor_process_v1705(struct rte_distributor *d,
+rte_distributor_process(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int num_mbufs)
{
unsigned int next_idx = 0;
@@ -470,14 +451,10 @@ rte_distributor_process_v1705(struct rte_distributor *d,
return num_mbufs;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_process, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_process(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs),
- rte_distributor_process_v1705);
/* return to the caller, packets returned from workers */
int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
+rte_distributor_returned_pkts(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int max_mbufs)
{
struct rte_distributor_returned_pkts *returns = &d->returns;
@@ -502,10 +479,6 @@ rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
return retval;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_returned_pkts, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_returned_pkts(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs),
- rte_distributor_returned_pkts_v1705);
/*
* Return the number of packets in-flight in a distributor, i.e. packets
@@ -527,7 +500,7 @@ total_outstanding(const struct rte_distributor *d)
* queued up.
*/
int
-rte_distributor_flush_v1705(struct rte_distributor *d)
+rte_distributor_flush(struct rte_distributor *d)
{
unsigned int flushed;
unsigned int wkr;
@@ -556,13 +529,10 @@ rte_distributor_flush_v1705(struct rte_distributor *d)
return flushed;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_flush, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_flush(struct rte_distributor *d),
- rte_distributor_flush_v1705);
/* clears the internal returns array in the distributor */
void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d)
+rte_distributor_clear_returns(struct rte_distributor *d)
{
unsigned int wkr;
@@ -576,13 +546,10 @@ rte_distributor_clear_returns_v1705(struct rte_distributor *d)
for (wkr = 0; wkr < d->num_workers; wkr++)
d->bufs[wkr].retptr64[0] = 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_clear_returns, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_clear_returns(struct rte_distributor *d),
- rte_distributor_clear_returns_v1705);
/* creates a distributor instance */
struct rte_distributor *
-rte_distributor_create_v1705(const char *name,
+rte_distributor_create(const char *name,
unsigned int socket_id,
unsigned int num_workers,
unsigned int alg_type)
@@ -656,8 +623,3 @@ rte_distributor_create_v1705(const char *name,
return d;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_create, _v1705, 17.05);
-MAP_STATIC_SYMBOL(struct rte_distributor *rte_distributor_create(
- const char *name, unsigned int socket_id,
- unsigned int num_workers, unsigned int alg_type),
- rte_distributor_create_v1705);
diff --git a/lib/librte_distributor/rte_distributor_v1705.h b/lib/librte_distributor/rte_distributor_v1705.h
deleted file mode 100644
index df4d9e8150..0000000000
--- a/lib/librte_distributor/rte_distributor_v1705.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017 Intel Corporation
- */
-
-#ifndef _RTE_DISTRIB_V1705_H_
-#define _RTE_DISTRIB_V1705_H_
-
-/**
- * @file
- * RTE distributor
- *
- * The distributor is a component which is designed to pass packets
- * one-at-a-time to workers, with dynamic load balancing.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_distributor *
-rte_distributor_create_v1705(const char *name, unsigned int socket_id,
- unsigned int num_workers,
- unsigned int alg_type);
-
-int
-rte_distributor_process_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs);
-
-int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs);
-
-int
-rte_distributor_flush_v1705(struct rte_distributor *d);
-
-void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d);
-
-int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int retcount);
-
-int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
-
-void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count);
-
-int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **mbufs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 05/10] lpm: remove deprecated code
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (5 preceding siblings ...)
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code Anatoly Burakov
@ 2019-10-17 14:31 2% ` Anatoly Burakov
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 06/10] distributor: " Anatoly Burakov
` (4 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Bruce Richardson, Vladimir Medvedkin,
john.mcnamara, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_lpm/rte_lpm.c | 996 ++------------------------------------
lib/librte_lpm/rte_lpm.h | 88 ----
lib/librte_lpm/rte_lpm6.c | 132 +----
lib/librte_lpm/rte_lpm6.h | 25 -
4 files changed, 48 insertions(+), 1193 deletions(-)
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 3a929a1b16..2687564194 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -89,34 +89,8 @@ depth_to_range(uint8_t depth)
/*
* Find an existing lpm table and return a pointer to it.
*/
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name)
-{
- struct rte_lpm_v20 *l = NULL;
- struct rte_tailq_entry *te;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_read_lock();
- TAILQ_FOREACH(te, lpm_list, next) {
- l = te->data;
- if (strncmp(name, l->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
- rte_mcfg_tailq_read_unlock();
-
- if (te == NULL) {
- rte_errno = ENOENT;
- return NULL;
- }
-
- return l;
-}
-VERSION_SYMBOL(rte_lpm_find_existing, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name)
+rte_lpm_find_existing(const char *name)
{
struct rte_lpm *l = NULL;
struct rte_tailq_entry *te;
@@ -139,88 +113,12 @@ rte_lpm_find_existing_v1604(const char *name)
return l;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_find_existing, _v1604, 16.04);
-MAP_STATIC_SYMBOL(struct rte_lpm *rte_lpm_find_existing(const char *name),
- rte_lpm_find_existing_v1604);
/*
* Allocates memory for LPM object
*/
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
-{
- char mem_name[RTE_LPM_NAMESIZE];
- struct rte_lpm_v20 *lpm = NULL;
- struct rte_tailq_entry *te;
- uint32_t mem_size;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry_v20) != 2);
-
- /* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
-
- /* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
-
- rte_mcfg_tailq_write_lock();
-
- /* guarantee there's no existing */
- TAILQ_FOREACH(te, lpm_list, next) {
- lpm = te->data;
- if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
-
- if (te != NULL) {
- lpm = NULL;
- rte_errno = EEXIST;
- goto exit;
- }
-
- /* allocate tailq entry */
- te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0);
- if (te == NULL) {
- RTE_LOG(ERR, LPM, "Failed to allocate tailq entry\n");
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Allocate memory to store the LPM data structures. */
- lpm = rte_zmalloc_socket(mem_name, mem_size,
- RTE_CACHE_LINE_SIZE, socket_id);
- if (lpm == NULL) {
- RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
- rte_free(te);
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Save user arguments. */
- lpm->max_rules = max_rules;
- strlcpy(lpm->name, name, sizeof(lpm->name));
-
- te->data = lpm;
-
- TAILQ_INSERT_TAIL(lpm_list, te, next);
-
-exit:
- rte_mcfg_tailq_write_unlock();
-
- return lpm;
-}
-VERSION_SYMBOL(rte_lpm_create, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
+rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
@@ -320,45 +218,12 @@ rte_lpm_create_v1604(const char *name, int socket_id,
return lpm;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 16.04);
-MAP_STATIC_SYMBOL(
- struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
*/
void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm)
-{
- struct rte_lpm_list *lpm_list;
- struct rte_tailq_entry *te;
-
- /* Check user arguments. */
- if (lpm == NULL)
- return;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_write_lock();
-
- /* find our tailq entry */
- TAILQ_FOREACH(te, lpm_list, next) {
- if (te->data == (void *) lpm)
- break;
- }
- if (te != NULL)
- TAILQ_REMOVE(lpm_list, te, next);
-
- rte_mcfg_tailq_write_unlock();
-
- rte_free(lpm);
- rte_free(te);
-}
-VERSION_SYMBOL(rte_lpm_free, _v20, 2.0);
-
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm)
+rte_lpm_free(struct rte_lpm *lpm)
{
struct rte_lpm_list *lpm_list;
struct rte_tailq_entry *te;
@@ -386,9 +251,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
rte_free(lpm);
rte_free(te);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
- rte_lpm_free_v1604);
/*
* Adds a rule to the rule table.
@@ -401,79 +263,7 @@ MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t rule_gindex, rule_index, last_rule;
- int i;
-
- VERIFY_DEPTH(depth);
-
- /* Scan through rule group to see if rule already exists. */
- if (lpm->rule_info[depth - 1].used_rules > 0) {
-
- /* rule_gindex stands for rule group index. */
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- /* Initialise rule_index to point to start of rule group. */
- rule_index = rule_gindex;
- /* Last rule = Last used rule in this rule group. */
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- for (; rule_index < last_rule; rule_index++) {
-
- /* If rule already exists update its next_hop and return. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked) {
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- return rule_index;
- }
- }
-
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
- } else {
- /* Calculate the position in which the rule will be stored. */
- rule_index = 0;
-
- for (i = depth - 1; i > 0; i--) {
- if (lpm->rule_info[i - 1].used_rules > 0) {
- rule_index = lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules;
- break;
- }
- }
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
-
- lpm->rule_info[depth - 1].first_rule = rule_index;
- }
-
- /* Make room for the new rule in the array. */
- for (i = RTE_LPM_MAX_DEPTH; i > depth; i--) {
- if (lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules == lpm->max_rules)
- return -ENOSPC;
-
- if (lpm->rule_info[i - 1].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules]
- = lpm->rules_tbl[lpm->rule_info[i - 1].first_rule];
- lpm->rule_info[i - 1].first_rule++;
- }
- }
-
- /* Add the new rule. */
- lpm->rules_tbl[rule_index].ip = ip_masked;
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- /* Increment the used rules counter for this rule group. */
- lpm->rule_info[depth - 1].used_rules++;
-
- return rule_index;
-}
-
-static int32_t
-rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+rule_add(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
uint32_t rule_gindex, rule_index, last_rule;
@@ -549,30 +339,7 @@ rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static void
-rule_delete_v20(struct rte_lpm_v20 *lpm, int32_t rule_index, uint8_t depth)
-{
- int i;
-
- VERIFY_DEPTH(depth);
-
- lpm->rules_tbl[rule_index] =
- lpm->rules_tbl[lpm->rule_info[depth - 1].first_rule
- + lpm->rule_info[depth - 1].used_rules - 1];
-
- for (i = depth; i < RTE_LPM_MAX_DEPTH; i++) {
- if (lpm->rule_info[i].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i].first_rule - 1] =
- lpm->rules_tbl[lpm->rule_info[i].first_rule
- + lpm->rule_info[i].used_rules - 1];
- lpm->rule_info[i].first_rule--;
- }
- }
-
- lpm->rule_info[depth - 1].used_rules--;
-}
-
-static void
-rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
+rule_delete(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
{
int i;
@@ -599,28 +366,7 @@ rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_find_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth)
-{
- uint32_t rule_gindex, last_rule, rule_index;
-
- VERIFY_DEPTH(depth);
-
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- /* Scan used rules at given depth to find rule. */
- for (rule_index = rule_gindex; rule_index < last_rule; rule_index++) {
- /* If rule is found return the rule index. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked)
- return rule_index;
- }
-
- /* If rule is not found return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
+rule_find(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
{
uint32_t rule_gindex, last_rule, rule_index;
@@ -644,42 +390,7 @@ rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
* Find, clean and allocate a tbl8.
*/
static int32_t
-tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
-{
- uint32_t group_idx; /* tbl8 group index. */
- struct rte_lpm_tbl_entry_v20 *tbl8_entry;
-
- /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
- tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
- /* If a free tbl8 group is found clean it and set as VALID. */
- if (!tbl8_entry->valid_group) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = VALID,
- };
- new_tbl8_entry.next_hop = 0;
-
- memset(&tbl8_entry[0], 0,
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES *
- sizeof(tbl8_entry[0]));
-
- __atomic_store(tbl8_entry, &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- /* Return group index for allocated tbl8 group. */
- return group_idx;
- }
- }
-
- /* If there are no tbl8 groups free then return error. */
- return -ENOSPC;
-}
-
-static int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
+tbl8_alloc(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
@@ -713,22 +424,7 @@ tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
}
static void
-tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start)
-{
- /* Set tbl8 group invalid*/
- struct rte_lpm_tbl_entry_v20 zero_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = INVALID,
- };
- zero_tbl8_entry.next_hop = 0;
-
- __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
- __ATOMIC_RELAXED);
-}
-
-static void
-tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
+tbl8_free(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
{
/* Set tbl8 group invalid*/
struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
@@ -738,78 +434,7 @@ tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
}
static __rte_noinline int32_t
-add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index, tbl24_range, tbl8_index, tbl8_group_end, i, j;
-
- /* Calculate the index into Table24. */
- tbl24_index = ip >> 8;
- tbl24_range = depth_to_range(depth);
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
- /*
- * For invalid OR valid and non-extended tbl 24 entries set
- * entry.
- */
- if (!lpm->tbl24[i].valid || (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth)) {
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .valid = VALID,
- .valid_group = 0,
- .depth = depth,
- };
- new_tbl24_entry.next_hop = next_hop;
-
- /* Setting tbl24 entry in one go to avoid race
- * conditions
- */
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- continue;
- }
-
- if (lpm->tbl24[i].valid_group == 1) {
- /* If tbl24 entry is valid and extended calculate the
- * index into tbl8.
- */
- tbl8_index = lpm->tbl24[i].group_idx *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < tbl8_group_end; j++) {
- if (!lpm->tbl8[j].valid ||
- lpm->tbl8[j].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = depth,
- };
- new_tbl8_entry.next_hop = next_hop;
-
- /*
- * Setting tbl8 entry in one go to avoid
- * race conditions
- */
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+add_depth_small(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -881,150 +506,7 @@ add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
static __rte_noinline int32_t
-add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index;
- int32_t tbl8_group_index, tbl8_group_start, tbl8_group_end, tbl8_index,
- tbl8_range, i;
-
- tbl24_index = (ip_masked >> 8);
- tbl8_range = depth_to_range(depth);
-
- if (!lpm->tbl24[tbl24_index].valid) {
- /* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- /* Check tbl8 allocation was successful. */
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- /* Find index into tbl8 and range. */
- tbl8_index = (tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES) +
- (ip_masked & 0xFF);
-
- /* Set tbl8 entry. */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } /* If valid entry but not extended calculate the index into Table8. */
- else if (lpm->tbl24[tbl24_index].valid_group == 0) {
- /* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_group_start +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /* Populate new tbl8 with tbl24 value. */
- for (i = tbl8_group_start; i < tbl8_group_end; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = lpm->tbl24[tbl24_index].depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop =
- lpm->tbl24[tbl24_index].next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- /* Insert new rule into the tbl8 entry. */
- for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } else { /*
- * If it is valid, extended entry calculate the index into tbl8.
- */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
-
- if (!lpm->tbl8[i].valid ||
- lpm->tbl8[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- /*
- * Setting tbl8 entry in one go to avoid race
- * condition
- */
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+add_depth_big(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -1037,7 +519,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1083,7 +565,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1177,48 +659,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* Add a route
*/
int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- int32_t rule_index, status = 0;
- uint32_t ip_masked;
-
- /* Check user arguments. */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- ip_masked = ip & depth_to_mask(depth);
-
- /* Add the rule to the rule table. */
- rule_index = rule_add_v20(lpm, ip_masked, depth, next_hop);
-
- /* If the is no space available for new rule return error. */
- if (rule_index < 0) {
- return rule_index;
- }
-
- if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v20(lpm, ip_masked, depth, next_hop);
- } else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v20(lpm, ip_masked, depth, next_hop);
-
- /*
- * If add fails due to exhaustion of tbl8 extensions delete
- * rule that was added to rule table.
- */
- if (status < 0) {
- rule_delete_v20(lpm, rule_index, depth);
-
- return status;
- }
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_add, _v20, 2.0);
-
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
int32_t rule_index, status = 0;
@@ -1231,7 +672,7 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
ip_masked = ip & depth_to_mask(depth);
/* Add the rule to the rule table. */
- rule_index = rule_add_v1604(lpm, ip_masked, depth, next_hop);
+ rule_index = rule_add(lpm, ip_masked, depth, next_hop);
/* If the is no space available for new rule return error. */
if (rule_index < 0) {
@@ -1239,16 +680,16 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_small(lpm, ip_masked, depth, next_hop);
} else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_big(lpm, ip_masked, depth, next_hop);
/*
* If add fails due to exhaustion of tbl8 extensions delete
* rule that was added to rule table.
*/
if (status < 0) {
- rule_delete_v1604(lpm, rule_index, depth);
+ rule_delete(lpm, rule_index, depth);
return status;
}
@@ -1256,42 +697,12 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_add, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_add(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t next_hop), rte_lpm_add_v1604);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop)
-{
- uint32_t ip_masked;
- int32_t rule_index;
-
- /* Check user arguments. */
- if ((lpm == NULL) ||
- (next_hop == NULL) ||
- (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- /* Look for the rule using rule_find. */
- ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v20(lpm, ip_masked, depth);
-
- if (rule_index >= 0) {
- *next_hop = lpm->rules_tbl[rule_index].next_hop;
- return 1;
- }
-
- /* If rule is not found return 0. */
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop)
{
uint32_t ip_masked;
@@ -1305,7 +716,7 @@ uint32_t *next_hop)
/* Look for the rule using rule_find. */
ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v1604(lpm, ip_masked, depth);
+ rule_index = rule_find(lpm, ip_masked, depth);
if (rule_index >= 0) {
*next_hop = lpm->rules_tbl[rule_index].next_hop;
@@ -1315,12 +726,9 @@ uint32_t *next_hop)
/* If rule is not found return 0. */
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_is_rule_present, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t *next_hop), rte_lpm_is_rule_present_v1604);
static int32_t
-find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
+find_previous_rule(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint8_t *sub_rule_depth)
{
int32_t rule_index;
@@ -1330,7 +738,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
ip_masked = ip & depth_to_mask(prev_depth);
- rule_index = rule_find_v20(lpm, ip_masked, prev_depth);
+ rule_index = rule_find(lpm, ip_masked, prev_depth);
if (rule_index >= 0) {
*sub_rule_depth = prev_depth;
@@ -1342,133 +750,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
}
static int32_t
-find_previous_rule_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint8_t *sub_rule_depth)
-{
- int32_t rule_index;
- uint32_t ip_masked;
- uint8_t prev_depth;
-
- for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
- ip_masked = ip & depth_to_mask(prev_depth);
-
- rule_index = rule_find_v1604(lpm, ip_masked, prev_depth);
-
- if (rule_index >= 0) {
- *sub_rule_depth = prev_depth;
- return rule_index;
- }
- }
-
- return -1;
-}
-
-static int32_t
-delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_range, tbl24_index, tbl8_group_index, tbl8_index, i, j;
-
- /* Calculate the range and index into Table24. */
- tbl24_range = depth_to_range(depth);
- tbl24_index = (ip_masked >> 8);
-
- /*
- * Firstly check the sub_rule_index. A -1 indicates no replacement rule
- * and a positive number indicates a sub_rule_index.
- */
- if (sub_rule_index < 0) {
- /*
- * If no replacement rule exists then invalidate entries
- * associated with this rule.
- */
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- zero_tbl24_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = 0,
- };
- zero_tbl24_entry.next_hop = 0;
- __atomic_store(&lpm->tbl24[i],
- &zero_tbl24_entry, __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- lpm->tbl8[j].valid = INVALID;
- }
- }
- }
- } else {
- /*
- * If a replacement rule exists then modify entries
- * associated with this rule.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->rules_tbl[sub_rule_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = sub_rule_depth,
- };
-
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = sub_rule_depth,
- };
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1575,7 +857,7 @@ delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* thus can be recycled
*/
static int32_t
-tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
+tbl8_recycle_check(struct rte_lpm_tbl_entry *tbl8,
uint32_t tbl8_group_start)
{
uint32_t tbl8_group_end, i;
@@ -1622,140 +904,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
}
static int32_t
-tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
- uint32_t tbl8_group_start)
-{
- uint32_t tbl8_group_end, i;
- tbl8_group_end = tbl8_group_start + RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /*
- * Check the first entry of the given tbl8. If it is invalid we know
- * this tbl8 does not contain any rule with a depth < RTE_LPM_MAX_DEPTH
- * (As they would affect all entries in a tbl8) and thus this table
- * can not be recycled.
- */
- if (tbl8[tbl8_group_start].valid) {
- /*
- * If first entry is valid check if the depth is less than 24
- * and if so check the rest of the entries to verify that they
- * are all of this depth.
- */
- if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
- for (i = (tbl8_group_start + 1); i < tbl8_group_end;
- i++) {
-
- if (tbl8[i].depth !=
- tbl8[tbl8_group_start].depth) {
-
- return -EEXIST;
- }
- }
- /* If all entries are the same return the tb8 index */
- return tbl8_group_start;
- }
-
- return -EEXIST;
- }
- /*
- * If the first entry is invalid check if the rest of the entries in
- * the tbl8 are invalid.
- */
- for (i = (tbl8_group_start + 1); i < tbl8_group_end; i++) {
- if (tbl8[i].valid)
- return -EEXIST;
- }
- /* If no valid entries are found then return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_index, tbl8_group_index, tbl8_group_start, tbl8_index,
- tbl8_range, i;
- int32_t tbl8_recycle_index;
-
- /*
- * Calculate the index into tbl24 and range. Note: All depths larger
- * than MAX_DEPTH_TBL24 are associated with only one tbl24 entry.
- */
- tbl24_index = ip_masked >> 8;
-
- /* Calculate the index into tbl8 and range. */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
- tbl8_range = depth_to_range(depth);
-
- if (sub_rule_index < 0) {
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be removed or modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- lpm->tbl8[i].valid = INVALID;
- }
- } else {
- /* Set new tbl8 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = sub_rule_depth,
- .valid_group = lpm->tbl8[tbl8_group_start].valid_group,
- };
-
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
-
- /*
- * Check if there are any valid entries in this tbl8 group. If all
- * tbl8 entries are invalid we can free the tbl8 and invalidate the
- * associated tbl24 entry.
- */
-
- tbl8_recycle_index = tbl8_recycle_check_v20(lpm->tbl8, tbl8_group_start);
-
- if (tbl8_recycle_index == -EINVAL) {
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- lpm->tbl24[tbl24_index].valid = 0;
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- } else if (tbl8_recycle_index > -1) {
- /* Update tbl24 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = lpm->tbl8[tbl8_recycle_index].depth,
- };
-
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELAXED);
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_big(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1810,7 +959,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* associated tbl24 entry.
*/
- tbl8_recycle_index = tbl8_recycle_check_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_recycle_index = tbl8_recycle_check(lpm->tbl8, tbl8_group_start);
if (tbl8_recycle_index == -EINVAL) {
/* Set tbl24 before freeing tbl8 to avoid race condition.
@@ -1818,7 +967,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
*/
lpm->tbl24[tbl24_index].valid = 0;
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
} else if (tbl8_recycle_index > -1) {
/* Update tbl24 entry. */
struct rte_lpm_tbl_entry new_tbl24_entry = {
@@ -1834,7 +983,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
__atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
__ATOMIC_RELAXED);
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
}
#undef group_idx
return 0;
@@ -1844,7 +993,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* Deletes a rule
*/
int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
+rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
{
int32_t rule_to_delete_index, sub_rule_index;
uint32_t ip_masked;
@@ -1863,7 +1012,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* Find the index of the input rule, that needs to be deleted, in the
* rule table.
*/
- rule_to_delete_index = rule_find_v20(lpm, ip_masked, depth);
+ rule_to_delete_index = rule_find(lpm, ip_masked, depth);
/*
* Check if rule_to_delete_index was found. If no rule was found the
@@ -1873,7 +1022,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
return -EINVAL;
/* Delete the rule from the rule table. */
- rule_delete_v20(lpm, rule_to_delete_index, depth);
+ rule_delete(lpm, rule_to_delete_index, depth);
/*
* Find rule to replace the rule_to_delete. If there is no rule to
@@ -1881,100 +1030,26 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* entries associated with this rule.
*/
sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v20(lpm, ip, depth, &sub_rule_depth);
+ sub_rule_index = find_previous_rule(lpm, ip, depth, &sub_rule_depth);
/*
* If the input depth value is less than 25 use function
* delete_depth_small otherwise use delete_depth_big.
*/
if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v20(lpm, ip_masked, depth,
+ return delete_depth_small(lpm, ip_masked, depth,
sub_rule_index, sub_rule_depth);
} else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v20(lpm, ip_masked, depth, sub_rule_index,
+ return delete_depth_big(lpm, ip_masked, depth, sub_rule_index,
sub_rule_depth);
}
}
-VERSION_SYMBOL(rte_lpm_delete, _v20, 2.0);
-
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
-{
- int32_t rule_to_delete_index, sub_rule_index;
- uint32_t ip_masked;
- uint8_t sub_rule_depth;
- /*
- * Check input arguments. Note: IP must be a positive integer of 32
- * bits in length therefore it need not be checked.
- */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH)) {
- return -EINVAL;
- }
-
- ip_masked = ip & depth_to_mask(depth);
-
- /*
- * Find the index of the input rule, that needs to be deleted, in the
- * rule table.
- */
- rule_to_delete_index = rule_find_v1604(lpm, ip_masked, depth);
-
- /*
- * Check if rule_to_delete_index was found. If no rule was found the
- * function rule_find returns -EINVAL.
- */
- if (rule_to_delete_index < 0)
- return -EINVAL;
-
- /* Delete the rule from the rule table. */
- rule_delete_v1604(lpm, rule_to_delete_index, depth);
-
- /*
- * Find rule to replace the rule_to_delete. If there is no rule to
- * replace the rule_to_delete we return -1 and invalidate the table
- * entries associated with this rule.
- */
- sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v1604(lpm, ip, depth, &sub_rule_depth);
-
- /*
- * If the input depth value is less than 25 use function
- * delete_depth_small otherwise use delete_depth_big.
- */
- if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v1604(lpm, ip_masked, depth,
- sub_rule_index, sub_rule_depth);
- } else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v1604(lpm, ip_masked, depth, sub_rule_index,
- sub_rule_depth);
- }
-}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth), rte_lpm_delete_v1604);
/*
* Delete all rules from the LPM table.
*/
void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm)
-{
- /* Zero rule information. */
- memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
-
- /* Zero tbl24. */
- memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
-
- /* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
-
- /* Delete all rules form the rules table. */
- memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
-}
-VERSION_SYMBOL(rte_lpm_delete_all, _v20, 2.0);
-
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
+rte_lpm_delete_all(struct rte_lpm *lpm)
{
/* Zero rule information. */
memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
@@ -1989,6 +1064,3 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete_all, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_delete_all(struct rte_lpm *lpm),
- rte_lpm_delete_all_v1604);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index 906ec44830..ca9627a141 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -65,31 +65,6 @@ extern "C" {
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- /**
- * Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
- * a group index pointing to a tbl8 structure (tbl24 only, when
- * valid_group is set)
- */
- RTE_STD_C11
- union {
- uint8_t next_hop;
- uint8_t group_idx;
- };
- /* Using single uint8_t to store 3 values. */
- uint8_t valid :1; /**< Validation flag. */
- /**
- * For tbl24:
- * - valid_group == 0: entry stores a next hop
- * - valid_group == 1: entry stores a group_index pointing to a tbl8
- * For tbl8:
- * - valid_group indicates whether the current tbl8 is in use or not
- */
- uint8_t valid_group :1;
- uint8_t depth :6; /**< Rule depth. */
-} __rte_aligned(sizeof(uint16_t));
-
__extension__
struct rte_lpm_tbl_entry {
/**
@@ -112,16 +87,6 @@ struct rte_lpm_tbl_entry {
};
#else
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- uint8_t depth :6;
- uint8_t valid_group :1;
- uint8_t valid :1;
- union {
- uint8_t group_idx;
- uint8_t next_hop;
- };
-} __rte_aligned(sizeof(uint16_t));
__extension__
struct rte_lpm_tbl_entry {
@@ -142,11 +107,6 @@ struct rte_lpm_config {
};
/** @internal Rule structure. */
-struct rte_lpm_rule_v20 {
- uint32_t ip; /**< Rule IP address. */
- uint8_t next_hop; /**< Rule next hop. */
-};
-
struct rte_lpm_rule {
uint32_t ip; /**< Rule IP address. */
uint32_t next_hop; /**< Rule next hop. */
@@ -159,21 +119,6 @@ struct rte_lpm_rule_info {
};
/** @internal LPM structure. */
-struct rte_lpm_v20 {
- /* LPM metadata. */
- char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
- uint32_t max_rules; /**< Max. balanced rules per lpm. */
- struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
-
- /* LPM Tables. */
- struct rte_lpm_tbl_entry_v20 tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry_v20 tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule_v20 rules_tbl[]
- __rte_cache_aligned; /**< LPM rules. */
-};
-
struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
@@ -210,11 +155,6 @@ struct rte_lpm {
struct rte_lpm *
rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config);
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
-struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
- const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
@@ -228,10 +168,6 @@ rte_lpm_create_v1604(const char *name, int socket_id,
*/
struct rte_lpm *
rte_lpm_find_existing(const char *name);
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name);
-struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name);
/**
* Free an LPM object.
@@ -243,10 +179,6 @@ rte_lpm_find_existing_v1604(const char *name);
*/
void
rte_lpm_free(struct rte_lpm *lpm);
-void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm);
/**
* Add a rule to the LPM table.
@@ -264,12 +196,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm);
*/
int
rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop);
-int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -289,12 +215,6 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
int
rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop);
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
-uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -310,10 +230,6 @@ uint32_t *next_hop);
*/
int
rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
/**
* Delete all rules from the LPM table.
@@ -323,10 +239,6 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
*/
void
rte_lpm_delete_all(struct rte_lpm *lpm);
-void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm);
/**
* Lookup an IP into the LPM table.
diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c
index 9b8aeb9721..b981e40714 100644
--- a/lib/librte_lpm/rte_lpm6.c
+++ b/lib/librte_lpm/rte_lpm6.c
@@ -808,18 +808,6 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
return 1;
}
-/*
- * Add a route
- */
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop)
-{
- return rte_lpm6_add_v1705(lpm, ip, depth, next_hop);
-}
-VERSION_SYMBOL(rte_lpm6_add, _v20, 2.0);
-
-
/*
* Simulate adding a route to LPM
*
@@ -841,7 +829,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
/* Inspect the first three bytes through tbl24 on the first step. */
ret = simulate_add_step(lpm, lpm->tbl24, &tbl_next, masked_ip,
- ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
+ ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
total_need_tbl_nb = need_tbl_nb;
/*
* Inspect one by one the rest of the bytes until
@@ -850,7 +838,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && ret == 1; i++) {
tbl = tbl_next;
ret = simulate_add_step(lpm, tbl, &tbl_next, masked_ip, 1,
- (uint8_t)(i+1), depth, &need_tbl_nb);
+ (uint8_t)(i + 1), depth, &need_tbl_nb);
total_need_tbl_nb += need_tbl_nb;
}
@@ -861,9 +849,12 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
return 0;
}
+/*
+ * Add a route
+ */
int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop)
+rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+ uint32_t next_hop)
{
struct rte_lpm6_tbl_entry *tbl;
struct rte_lpm6_tbl_entry *tbl_next = NULL;
@@ -895,8 +886,8 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
/* Inspect the first three bytes through tbl24 on the first step. */
tbl = lpm->tbl24;
status = add_step(lpm, tbl, TBL24_IND, &tbl_next, &tbl_next_num,
- masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
- is_new_rule);
+ masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
+ is_new_rule);
assert(status >= 0);
/*
@@ -906,17 +897,13 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && status == 1; i++) {
tbl = tbl_next;
status = add_step(lpm, tbl, tbl_next_num, &tbl_next,
- &tbl_next_num, masked_ip, 1, (uint8_t)(i+1),
- depth, next_hop, is_new_rule);
+ &tbl_next_num, masked_ip, 1, (uint8_t)(i + 1),
+ depth, next_hop, is_new_rule);
assert(status >= 0);
}
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_add, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip,
- uint8_t depth, uint32_t next_hop),
- rte_lpm6_add_v1705);
/*
* Takes a pointer to a table entry and inspect one level.
@@ -955,25 +942,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl,
* Looks up an IP
*/
int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_lookup_v1705(lpm, ip, &next_hop32);
- if (status == 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-}
-VERSION_SYMBOL(rte_lpm6_lookup, _v20, 2.0);
-
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
+rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
uint32_t *next_hop)
{
const struct rte_lpm6_tbl_entry *tbl;
@@ -1000,56 +969,12 @@ rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop), rte_lpm6_lookup_v1705);
/*
* Looks up a group of IP addresses
*/
int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t * next_hops, unsigned n)
-{
- unsigned i;
- const struct rte_lpm6_tbl_entry *tbl;
- const struct rte_lpm6_tbl_entry *tbl_next = NULL;
- uint32_t tbl24_index, next_hop;
- uint8_t first_byte;
- int status;
-
- /* DEBUG: Check user input arguments. */
- if ((lpm == NULL) || (ips == NULL) || (next_hops == NULL))
- return -EINVAL;
-
- for (i = 0; i < n; i++) {
- first_byte = LOOKUP_FIRST_BYTE;
- tbl24_index = (ips[i][0] << BYTES2_SIZE) |
- (ips[i][1] << BYTE_SIZE) | ips[i][2];
-
- /* Calculate pointer to the first entry to be inspected */
- tbl = &lpm->tbl24[tbl24_index];
-
- do {
- /* Continue inspecting following levels until success or failure */
- status = lookup_step(lpm, tbl, &tbl_next, ips[i], first_byte++,
- &next_hop);
- tbl = tbl_next;
- } while (status == 1);
-
- if (status < 0)
- next_hops[i] = -1;
- else
- next_hops[i] = (int16_t)next_hop;
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm6_lookup_bulk_func, _v20, 2.0);
-
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
+rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n)
{
@@ -1089,37 +1014,12 @@ rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup_bulk_func, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n),
- rte_lpm6_lookup_bulk_func_v1705);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_is_rule_present_v1705(lpm, ip, depth, &next_hop32);
- if (status > 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-
-}
-VERSION_SYMBOL(rte_lpm6_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop)
{
uint8_t masked_ip[RTE_LPM6_IPV6_ADDR_SIZE];
@@ -1135,10 +1035,6 @@ rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
return rule_find(lpm, masked_ip, depth, next_hop);
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_is_rule_present, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm,
- uint8_t *ip, uint8_t depth, uint32_t *next_hop),
- rte_lpm6_is_rule_present_v1705);
/*
* Delete a rule from the rule table.
diff --git a/lib/librte_lpm/rte_lpm6.h b/lib/librte_lpm/rte_lpm6.h
index 5d59ccb1fe..37dfb20249 100644
--- a/lib/librte_lpm/rte_lpm6.h
+++ b/lib/librte_lpm/rte_lpm6.h
@@ -96,12 +96,6 @@ rte_lpm6_free(struct rte_lpm6 *lpm);
int
rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t next_hop);
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -121,12 +115,6 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
int
rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop);
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -184,11 +172,6 @@ rte_lpm6_delete_all(struct rte_lpm6 *lpm);
*/
int
rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint32_t *next_hop);
-int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop);
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop);
/**
* Lookup multiple IP addresses in an LPM table.
@@ -210,14 +193,6 @@ int
rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n);
#ifdef __cplusplus
}
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (4 preceding siblings ...)
2019-10-17 14:31 23% ` [dpdk-dev] [PATCH v4 03/10] buildtools: add ABI update shell script Anatoly Burakov
@ 2019-10-17 14:31 4% ` Anatoly Burakov
2019-10-17 21:04 0% ` Carrillo, Erik G
2019-10-21 13:24 3% ` Kevin Traynor
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 05/10] lpm: " Anatoly Burakov
` (5 subsequent siblings)
11 siblings, 2 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, bruce.richardson, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_timer/rte_timer.c | 90 ++----------------------------------
lib/librte_timer/rte_timer.h | 15 ------
2 files changed, 5 insertions(+), 100 deletions(-)
diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
index bdcf05d06b..de6959b809 100644
--- a/lib/librte_timer/rte_timer.c
+++ b/lib/librte_timer/rte_timer.c
@@ -68,9 +68,6 @@ static struct rte_timer_data *rte_timer_data_arr;
static const uint32_t default_data_id;
static uint32_t rte_timer_subsystem_initialized;
-/* For maintaining older interfaces for a period */
-static struct rte_timer_data default_timer_data;
-
/* when debug is enabled, store some statistics */
#ifdef RTE_LIBRTE_TIMER_DEBUG
#define __TIMER_STAT_ADD(priv_timer, name, n) do { \
@@ -131,22 +128,6 @@ rte_timer_data_dealloc(uint32_t id)
return 0;
}
-void
-rte_timer_subsystem_init_v20(void)
-{
- unsigned lcore_id;
- struct priv_timer *priv_timer = default_timer_data.priv_timer;
-
- /* since priv_timer is static, it's zeroed by default, so only init some
- * fields.
- */
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) {
- rte_spinlock_init(&priv_timer[lcore_id].list_lock);
- priv_timer[lcore_id].prev_lcore = lcore_id;
- }
-}
-VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
-
/* Init the timer library. Allocate an array of timer data structs in shared
* memory, and allocate the zeroth entry for use with original timer
* APIs. Since the intersection of the sets of lcore ids in primary and
@@ -154,7 +135,7 @@ VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
* multiple processes.
*/
int
-rte_timer_subsystem_init_v1905(void)
+rte_timer_subsystem_init(void)
{
const struct rte_memzone *mz;
struct rte_timer_data *data;
@@ -209,9 +190,6 @@ rte_timer_subsystem_init_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_subsystem_init(void),
- rte_timer_subsystem_init_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_subsystem_init, _v1905, 19.05);
void
rte_timer_subsystem_finalize(void)
@@ -552,42 +530,13 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
/* Reset and start the timer associated with the timer handle tim */
int
-rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg)
-{
- uint64_t cur_time = rte_get_timer_cycles();
- uint64_t period;
-
- if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
- !(rte_lcore_is_enabled(tim_lcore) ||
- rte_lcore_has_role(tim_lcore, ROLE_SERVICE))))
- return -1;
-
- if (type == PERIODICAL)
- period = ticks;
- else
- period = 0;
-
- return __rte_timer_reset(tim, cur_time + ticks, period, tim_lcore,
- fct, arg, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_reset, _v20, 2.0);
-
-int
-rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
+rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned int tim_lcore,
rte_timer_cb_t fct, void *arg)
{
return rte_timer_alt_reset(default_data_id, tim, ticks, type,
tim_lcore, fct, arg);
}
-MAP_STATIC_SYMBOL(int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type,
- unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg),
- rte_timer_reset_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_reset, _v1905, 19.05);
int
rte_timer_alt_reset(uint32_t timer_data_id, struct rte_timer *tim,
@@ -658,20 +607,10 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked,
/* Stop the timer associated with the timer handle tim */
int
-rte_timer_stop_v20(struct rte_timer *tim)
-{
- return __rte_timer_stop(tim, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_stop, _v20, 2.0);
-
-int
-rte_timer_stop_v1905(struct rte_timer *tim)
+rte_timer_stop(struct rte_timer *tim)
{
return rte_timer_alt_stop(default_data_id, tim);
}
-MAP_STATIC_SYMBOL(int rte_timer_stop(struct rte_timer *tim),
- rte_timer_stop_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_stop, _v1905, 19.05);
int
rte_timer_alt_stop(uint32_t timer_data_id, struct rte_timer *tim)
@@ -817,15 +756,8 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
priv_timer[lcore_id].running_tim = NULL;
}
-void
-rte_timer_manage_v20(void)
-{
- __rte_timer_manage(&default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_manage, _v20, 2.0);
-
int
-rte_timer_manage_v1905(void)
+rte_timer_manage(void)
{
struct rte_timer_data *timer_data;
@@ -835,8 +767,6 @@ rte_timer_manage_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_manage(void), rte_timer_manage_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_manage, _v1905, 19.05);
int
rte_timer_alt_manage(uint32_t timer_data_id,
@@ -1074,21 +1004,11 @@ __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f)
#endif
}
-void
-rte_timer_dump_stats_v20(FILE *f)
-{
- __rte_timer_dump_stats(&default_timer_data, f);
-}
-VERSION_SYMBOL(rte_timer_dump_stats, _v20, 2.0);
-
int
-rte_timer_dump_stats_v1905(FILE *f)
+rte_timer_dump_stats(FILE *f)
{
return rte_timer_alt_dump_stats(default_data_id, f);
}
-MAP_STATIC_SYMBOL(int rte_timer_dump_stats(FILE *f),
- rte_timer_dump_stats_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_dump_stats, _v1905, 19.05);
int
rte_timer_alt_dump_stats(uint32_t timer_data_id __rte_unused, FILE *f)
diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h
index 05d287d8f2..9dc5fc3092 100644
--- a/lib/librte_timer/rte_timer.h
+++ b/lib/librte_timer/rte_timer.h
@@ -181,8 +181,6 @@ int rte_timer_data_dealloc(uint32_t id);
* subsystem
*/
int rte_timer_subsystem_init(void);
-int rte_timer_subsystem_init_v1905(void);
-void rte_timer_subsystem_init_v20(void);
/**
* @warning
@@ -250,13 +248,6 @@ void rte_timer_init(struct rte_timer *tim);
int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned tim_lcore,
rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-
/**
* Loop until rte_timer_reset() succeeds.
@@ -313,8 +304,6 @@ rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
* - (-1): The timer is in the RUNNING or CONFIG state.
*/
int rte_timer_stop(struct rte_timer *tim);
-int rte_timer_stop_v1905(struct rte_timer *tim);
-int rte_timer_stop_v20(struct rte_timer *tim);
/**
* Loop until rte_timer_stop() succeeds.
@@ -358,8 +347,6 @@ int rte_timer_pending(struct rte_timer *tim);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_manage(void);
-int rte_timer_manage_v1905(void);
-void rte_timer_manage_v20(void);
/**
* Dump statistics about timers.
@@ -371,8 +358,6 @@ void rte_timer_manage_v20(void);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_dump_stats(FILE *f);
-int rte_timer_dump_stats_v1905(FILE *f);
-void rte_timer_dump_stats_v20(FILE *f);
/**
* @warning
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 03/10] buildtools: add ABI update shell script
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (3 preceding siblings ...)
2019-10-17 14:31 14% ` [dpdk-dev] [PATCH v4 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
@ 2019-10-17 14:31 23% ` Anatoly Burakov
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code Anatoly Burakov
` (6 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
In order to facilitate mass updating of version files, add a shell
script that recurses into lib/ and drivers/ directories and calls
the ABI version update script.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v3:
- Switch to sh rather than bash, and remove bash-isms
- Address review comments
v2:
- Add this patch to split the shell script from previous commit
- Fixup miscellaneous bugs
buildtools/update-abi.sh | 42 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100755 buildtools/update-abi.sh
diff --git a/buildtools/update-abi.sh b/buildtools/update-abi.sh
new file mode 100755
index 0000000000..89ba5804a6
--- /dev/null
+++ b/buildtools/update-abi.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+abi_version=$1
+abi_version_file="./config/ABI_VERSION"
+update_path="lib drivers"
+
+if [ -z "$1" ]; then
+ # output to stderr
+ >&2 echo "Please provide ABI version"
+ exit 1
+fi
+
+# check version string format
+echo $abi_version | grep -q -e "^[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}$"
+if [ "$?" -ne 0 ]; then
+ # output to stderr
+ >&2 echo "ABI version must be formatted as MAJOR.MINOR version"
+ exit 1
+fi
+
+if [ -n "$2" ]; then
+ abi_version_file=$2
+fi
+
+if [ -n "$3" ]; then
+ # drop $1 and $2
+ shift 2
+ # assign all other arguments as update paths
+ update_path=$@
+fi
+
+echo "New ABI version:" $abi_version
+echo "ABI_VERSION path:" $abi_version_file
+echo "Path to update:" $update_path
+
+echo $abi_version > $abi_version_file
+
+find $update_path -name \*version.map -exec \
+ ./buildtools/update_version_map_abi.py {} \
+ $abi_version \; -print
--
2.17.1
^ permalink raw reply [relevance 23%]
* [dpdk-dev] [PATCH v4 02/10] buildtools: add script for updating symbols abi version
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (2 preceding siblings ...)
2019-10-17 14:31 7% ` [dpdk-dev] [PATCH v4 01/10] config: change ABI versioning to global Anatoly Burakov
@ 2019-10-17 14:31 14% ` Anatoly Burakov
2019-10-17 14:31 23% ` [dpdk-dev] [PATCH v4 03/10] buildtools: add ABI update shell script Anatoly Burakov
` (7 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev; +Cc: Pawel Modrak, john.mcnamara, bruce.richardson, thomas, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Add a script that automatically merges all stable ABI's under one
ABI section with the new version, while leaving experimental
section exactly as it is.
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v3:
- Add comments to regex patterns
v2:
- Reworked script to be pep8-compliant and more reliable
buildtools/update_version_map_abi.py | 170 +++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
create mode 100755 buildtools/update_version_map_abi.py
diff --git a/buildtools/update_version_map_abi.py b/buildtools/update_version_map_abi.py
new file mode 100755
index 0000000000..50283e6a3d
--- /dev/null
+++ b/buildtools/update_version_map_abi.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+"""
+A Python program to update the ABI version and function names in a DPDK
+lib_*_version.map file. Called from the buildtools/update_abi.sh utility.
+"""
+
+from __future__ import print_function
+import argparse
+import sys
+import re
+
+
+def __parse_map_file(f_in):
+ # match function name, followed by semicolon, followed by EOL, optionally
+ # with whitespace inbetween each item
+ func_line_regex = re.compile(r"\s*"
+ r"(?P<func>[a-zA-Z_0-9]+)"
+ r"\s*"
+ r";"
+ r"\s*"
+ r"$")
+ # match section name, followed by opening bracked, followed by EOL,
+ # optionally with whitespace inbetween each item
+ section_begin_regex = re.compile(r"\s*"
+ r"(?P<version>[a-zA-Z0-9_\.]+)"
+ r"\s*"
+ r"{"
+ r"\s*"
+ r"$")
+ # match closing bracket, optionally followed by section name (for when we
+ # inherit from another ABI version), followed by semicolon, followed by
+ # EOL, optionally with whitespace inbetween each item
+ section_end_regex = re.compile(r"\s*"
+ r"}"
+ r"\s*"
+ r"(?P<parent>[a-zA-Z0-9_\.]+)?"
+ r"\s*"
+ r";"
+ r"\s*"
+ r"$")
+
+ # for stable ABI, we don't care about which version introduced which
+ # function, we just flatten the list. there are dupes in certain files, so
+ # use a set instead of a list
+ stable_lines = set()
+ # copy experimental section as is
+ experimental_lines = []
+ is_experimental = False
+
+ # gather all functions
+ for line in f_in:
+ # clean up the line
+ line = line.strip('\n').strip()
+
+ # is this an end of section?
+ match = section_end_regex.match(line)
+ if match:
+ # whatever section this was, it's not active any more
+ is_experimental = False
+ continue
+
+ # if we're in the middle of experimental section, we need to copy
+ # the section verbatim, so just add the line
+ if is_experimental:
+ experimental_lines += [line]
+ continue
+
+ # skip empty lines
+ if not line:
+ continue
+
+ # is this a beginning of a new section?
+ match = section_begin_regex.match(line)
+ if match:
+ cur_section = match.group("version")
+ # is it experimental?
+ is_experimental = cur_section == "EXPERIMENTAL"
+ continue
+
+ # is this a function?
+ match = func_line_regex.match(line)
+ if match:
+ stable_lines.add(match.group("func"))
+
+ return stable_lines, experimental_lines
+
+
+def __regenerate_map_file(f_out, abi_version, stable_lines,
+ experimental_lines):
+ # print ABI version header
+ print("DPDK_{} {{".format(abi_version), file=f_out)
+
+ if stable_lines:
+ # print global section
+ print("\tglobal:", file=f_out)
+ # blank line
+ print(file=f_out)
+
+ # print all stable lines, alphabetically sorted
+ for line in sorted(stable_lines):
+ print("\t{};".format(line), file=f_out)
+
+ # another blank line
+ print(file=f_out)
+
+ # print local section
+ print("\tlocal: *;", file=f_out)
+
+ # end stable version
+ print("};", file=f_out)
+
+ # do we have experimental lines?
+ if not experimental_lines:
+ return
+
+ # another blank line
+ print(file=f_out)
+
+ # start experimental section
+ print("EXPERIMENTAL {", file=f_out)
+
+ # print all experimental lines as they were
+ for line in experimental_lines:
+ # don't print empty whitespace
+ if not line:
+ print("", file=f_out)
+ else:
+ print("\t{}".format(line), file=f_out)
+
+ # end section
+ print("};", file=f_out)
+
+
+def __main():
+ arg_parser = argparse.ArgumentParser(
+ description='Merge versions in linker version script.')
+
+ arg_parser.add_argument("map_file", type=str,
+ help='path to linker version script file '
+ '(pattern: *version.map)')
+ arg_parser.add_argument("abi_version", type=str,
+ help='target ABI version (pattern: MAJOR.MINOR)')
+
+ parsed = arg_parser.parse_args()
+
+ if not parsed.map_file.endswith('version.map'):
+ print("Invalid input file: {}".format(parsed.map_file),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ if not re.match(r"\d{1,2}\.\d{1,2}", parsed.abi_version):
+ print("Invalid ABI version: {}".format(parsed.abi_version),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ with open(parsed.map_file) as f_in:
+ stable_lines, experimental_lines = __parse_map_file(f_in)
+
+ with open(parsed.map_file, 'w') as f_out:
+ __regenerate_map_file(f_out, parsed.abi_version, stable_lines,
+ experimental_lines)
+
+
+if __name__ == "__main__":
+ __main()
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v4 01/10] config: change ABI versioning to global
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
2019-10-17 8:50 4% ` Bruce Richardson
2019-10-17 14:31 8% ` [dpdk-dev] [PATCH v4 00/10] " Anatoly Burakov
@ 2019-10-17 14:31 7% ` Anatoly Burakov
2019-10-17 14:31 14% ` [dpdk-dev] [PATCH v4 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
` (8 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Thomas Monjalon, Bruce Richardson, john.mcnamara,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
As per new ABI policy, all of the libraries are now versioned using
one global ABI version. Changes in this patch implement the
necessary steps to enable that.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
---
Notes:
v3:
- Removed Windows support from Makefile changes
- Removed unneeded path conversions from meson files
buildtools/meson.build | 2 ++
config/ABI_VERSION | 1 +
config/meson.build | 4 +++-
drivers/meson.build | 20 ++++++++++++--------
lib/meson.build | 18 +++++++++++-------
meson_options.txt | 2 --
mk/rte.lib.mk | 13 ++++---------
7 files changed, 33 insertions(+), 27 deletions(-)
create mode 100644 config/ABI_VERSION
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 32c79c1308..78ce69977d 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -12,3 +12,5 @@ if python3.found()
else
map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
endif
+
+is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
diff --git a/config/ABI_VERSION b/config/ABI_VERSION
new file mode 100644
index 0000000000..9a7c1e503f
--- /dev/null
+++ b/config/ABI_VERSION
@@ -0,0 +1 @@
+20.0
diff --git a/config/meson.build b/config/meson.build
index a27f731f85..374735590c 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -18,6 +18,8 @@ endforeach
# depending on the configuration options
pver = meson.project_version().split('.')
major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
+abi_version = run_command(find_program('cat', 'more'),
+ files('ABI_VERSION')).stdout().strip()
# extract all version information into the build configuration
dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
@@ -37,7 +39,7 @@ endif
pmd_subdir_opt = get_option('drivers_install_subdir')
if pmd_subdir_opt.contains('<VERSION>')
- pmd_subdir_opt = major_version.join(pmd_subdir_opt.split('<VERSION>'))
+ pmd_subdir_opt = abi_version.join(pmd_subdir_opt.split('<VERSION>'))
endif
driver_install_path = join_paths(get_option('libdir'), pmd_subdir_opt)
eal_pmd_path = join_paths(get_option('prefix'), driver_install_path)
diff --git a/drivers/meson.build b/drivers/meson.build
index 2ed2e95411..fd628d9587 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -110,12 +110,19 @@ foreach class:dpdk_driver_classes
output: out_filename,
depends: [pmdinfogen, tmp_lib])
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/@2@_version.map'.format(
+ meson.current_source_dir(),
+ drv_path, lib_name)
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
- lib_version = major_version
- so_version = major_version
+ lib_version = abi_version
+ so_version = abi_version
endif
# now build the static driver
@@ -128,9 +135,6 @@ foreach class:dpdk_driver_classes
install: true)
# now build the shared driver
- version_map = '@0@/@1@/@2@_version.map'.format(
- meson.current_source_dir(),
- drv_path, lib_name)
shared_lib = shared_library(lib_name,
sources,
objects: objs,
diff --git a/lib/meson.build b/lib/meson.build
index e5ff838934..e626da778c 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -97,12 +97,18 @@ foreach l:libraries
cflags += '-DALLOW_EXPERIMENTAL_API'
endif
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/rte_@2@_version.map'.format(
+ meson.current_source_dir(), dir_name, name)
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
- lib_version = major_version
- so_version = major_version
+ lib_version = abi_version
+ so_version = abi_version
endif
# first build static lib
@@ -120,8 +126,6 @@ foreach l:libraries
# then use pre-build objects to build shared lib
sources = []
objs += static_lib.extract_all_objects(recursive: false)
- version_map = '@0@/@1@/rte_@2@_version.map'.format(
- meson.current_source_dir(), dir_name, name)
implib = dir_name + '.dll.a'
def_file = custom_target(name + '_def',
diff --git a/meson_options.txt b/meson_options.txt
index 448f3e63dc..000e38fd98 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -28,8 +28,6 @@ option('max_lcores', type: 'integer', value: 128,
description: 'maximum number of cores/threads supported by EAL')
option('max_numa_nodes', type: 'integer', value: 4,
description: 'maximum number of NUMA nodes supported by EAL')
-option('per_library_versions', type: 'boolean', value: true,
- description: 'true: each lib gets its own version number, false: DPDK version used for each lib')
option('tests', type: 'boolean', value: true,
description: 'build unit tests')
option('use_hpet', type: 'boolean', value: false,
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 4df8849a08..e1ea292b6e 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -11,20 +11,15 @@ EXTLIB_BUILD ?= n
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifneq ($(CONFIG_RTE_MAJOR_ABI),)
-ifneq ($(LIBABIVER),)
-LIBABIVER := $(CONFIG_RTE_MAJOR_ABI)
-endif
+ifneq ($(shell grep "^DPDK_" $(SRCDIR)/$(EXPORT_MAP)),)
+LIBABIVER := $(shell cat $(RTE_SRCDIR)/config/ABI_VERSION)
+else
+LIBABIVER := 0
endif
ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
ifeq ($(EXTLIB_BUILD),n)
-ifeq ($(CONFIG_RTE_MAJOR_ABI),)
-ifeq ($(CONFIG_RTE_NEXT_ABI),y)
-LIB := $(LIB).1
-endif
-endif
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
endif
endif
--
2.17.1
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v4 00/10] Implement the new ABI policy and add helper scripts
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
2019-10-17 8:50 4% ` Bruce Richardson
@ 2019-10-17 14:31 8% ` Anatoly Burakov
2019-10-17 14:31 7% ` [dpdk-dev] [PATCH v4 01/10] config: change ABI versioning to global Anatoly Burakov
` (9 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-17 14:31 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
This patchset prepares the codebase for the new ABI policy and
adds a few helper scripts.
There are two new scripts for managing ABI versions added. The
first one is a Python script that will read in a .map file,
flatten it and update the ABI version to the ABI version
specified on the command-line.
The second one is a shell script that will run the above mentioned
Python script recursively over the source tree and set the ABI
version to either that which is defined in config/ABI_VERSION, or
a user-specified one.
Example of its usage: buildtools/update-abi.sh 20.0
This will recurse into lib/ and drivers/ directory and update
whatever .map files it can find.
The other shell script that's added is one that can take in a .so
file and ensure that its declared public ABI matches either
current ABI, next ABI, or EXPERIMENTAL. This was moved to the
last commit because it made no sense to have it beforehand.
The source tree was verified to follow the new ABI policy using
the following command (assuming built binaries are in build/):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
This returns 0.
Changes since v3:
- Put distributor code back and cleaned it up
- Rebased on latest master and regenerated commit 9
Changes since v2:
- Addressed Bruce's review comments
- Removed single distributor mode as per Dave's suggestion
Changes since v1:
- Reordered patchset to have removal of old ABI's before introducing
the new one to avoid compile breakages between patches
- Added a new patch fixing missing symbol in octeontx common
- Split script commits into multiple commits and reordered them
- Re-generated the ABI bump commit
- Verified all scripts to work
Anatoly Burakov (2):
buildtools: add ABI update shell script
drivers/octeontx: add missing public symbol
Marcin Baran (6):
config: change ABI versioning to global
timer: remove deprecated code
lpm: remove deprecated code
distributor: remove deprecated code
distributor: rename v2.0 ABI to _single suffix
buildtools: add ABI versioning check script
Pawel Modrak (2):
buildtools: add script for updating symbols abi version
build: change ABI version to 20.0
buildtools/check-abi-version.sh | 54 +
buildtools/meson.build | 2 +
buildtools/update-abi.sh | 42 +
buildtools/update_version_map_abi.py | 170 +++
config/ABI_VERSION | 1 +
config/meson.build | 4 +-
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +-
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++-
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 7 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
drivers/meson.build | 20 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +-
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 +-
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 +-
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 +-
lib/librte_distributor/Makefile | 2 +-
lib/librte_distributor/meson.build | 2 +-
lib/librte_distributor/rte_distributor.c | 80 +-
.../rte_distributor_private.h | 10 +-
...ributor_v20.c => rte_distributor_single.c} | 57 +-
...ributor_v20.h => rte_distributor_single.h} | 26 +-
.../rte_distributor_v1705.h | 61 --
.../rte_distributor_version.map | 16 +-
lib/librte_eal/rte_eal_version.map | 310 ++----
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +--
lib/librte_eventdev/rte_eventdev_version.map | 130 +--
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +-
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm.c | 996 +-----------------
lib/librte_lpm/rte_lpm.h | 88 --
lib/librte_lpm/rte_lpm6.c | 132 +--
lib/librte_lpm/rte_lpm6.h | 25 -
lib/librte_lpm/rte_lpm_version.map | 39 +-
lib/librte_mbuf/rte_mbuf_version.map | 49 +-
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +-
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +-
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer.c | 90 +-
lib/librte_timer/rte_timer.h | 15 -
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +-
lib/meson.build | 18 +-
meson_options.txt | 2 -
mk/rte.lib.mk | 13 +-
177 files changed, 1141 insertions(+), 2912 deletions(-)
create mode 100755 buildtools/check-abi-version.sh
create mode 100755 buildtools/update-abi.sh
create mode 100755 buildtools/update_version_map_abi.py
create mode 100644 config/ABI_VERSION
rename lib/librte_distributor/{rte_distributor_v20.c => rte_distributor_single.c} (84%)
rename lib/librte_distributor/{rte_distributor_v20.h => rte_distributor_single.h} (89%)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
--
2.17.1
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-17 14:09 8% ` Luca Boccassi
@ 2019-10-17 14:12 4% ` Bruce Richardson
2019-10-18 10:07 7% ` Kevin Traynor
1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-17 14:12 UTC (permalink / raw)
To: Luca Boccassi
Cc: Anatoly Burakov, Christian Ehrhardt, dev, Marcin Baran,
Thomas Monjalon, john.mcnamara, david.marchand, Pawel Modrak,
ktraynor
On Thu, Oct 17, 2019 at 03:09:00PM +0100, Luca Boccassi wrote:
> On Thu, 2019-10-17 at 09:44 +0100, Bruce Richardson wrote:
> > On Wed, Oct 16, 2019 at 06:03:36PM +0100, Anatoly Burakov wrote:
> > > From: Marcin Baran <
> > > marcinx.baran@intel.com
> > > >
> > >
> > > As per new ABI policy, all of the libraries are now versioned using
> > > one global ABI version. Changes in this patch implement the
> > > necessary steps to enable that.
> > >
> > > Signed-off-by: Marcin Baran <
> > > marcinx.baran@intel.com
> > > >
> > > Signed-off-by: Pawel Modrak <
> > > pawelx.modrak@intel.com
> > > >
> > > Signed-off-by: Anatoly Burakov <
> > > anatoly.burakov@intel.com
> > > >
> > > ---
> > >
> > > Notes:
> > > v3:
> > > - Removed Windows support from Makefile changes
> > > - Removed unneeded path conversions from meson files
> > >
> > > buildtools/meson.build | 2 ++
> > > config/ABI_VERSION | 1 +
> > > config/meson.build | 5 +++--
> > > drivers/meson.build | 20 ++++++++++++--------
> > > lib/meson.build | 18 +++++++++++-------
> > > meson_options.txt | 2 --
> > > mk/rte.lib.mk | 13 ++++---------
> > > 7 files changed, 33 insertions(+), 28 deletions(-)
> > > create mode 100644 config/ABI_VERSION
> > >
> > > diff --git a/buildtools/meson.build b/buildtools/meson.build
> > > index 32c79c1308..78ce69977d 100644
> > > --- a/buildtools/meson.build
> > > +++ b/buildtools/meson.build
> > > @@ -12,3 +12,5 @@ if python3.found()
> > > else
> > > map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
> > > endif
> > > +
> > > +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
> > > diff --git a/config/ABI_VERSION b/config/ABI_VERSION
> > > new file mode 100644
> > > index 0000000000..9a7c1e503f
> > > --- /dev/null
> > > +++ b/config/ABI_VERSION
> > > @@ -0,0 +1 @@
> > > +20.0
> > > diff --git a/config/meson.build b/config/meson.build
> > > index a27f731f85..3cfc02406c 100644
> > > --- a/config/meson.build
> > > +++ b/config/meson.build
> > > @@ -17,7 +17,8 @@ endforeach
> > > # set the major version, which might be used by drivers and
> > > libraries
> > > # depending on the configuration options
> > > pver = meson.project_version().split('.')
> > > -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
> > > +abi_version = run_command(find_program('cat', 'more'),
> > > + files('ABI_VERSION')).stdout().strip()
> > >
> > > # extract all version information into the build configuration
> > > dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
> > > @@ -37,7 +38,7 @@ endif
> > >
> > > pmd_subdir_opt = get_option('drivers_install_subdir')
> > > if pmd_subdir_opt.contains('<VERSION>')
> > > - pmd_subdir_opt =
> > > major_version.join(pmd_subdir_opt.split('<VERSION>'))
> > > + pmd_subdir_opt =
> > > abi_version.join(pmd_subdir_opt.split('<VERSION>'))
> > > endif
> >
> > This is an interesting change, and I'm not sure about it. I think for
> > user-visible changes, version should still refer to DPDK version
> > rather
> > than ABI version. Even with a stable ABI, it makes more sense to me
> > to find
> > the drivers in a 19.11 directory than a 20.0 one. Then again, the
> > drivers
> > should be re-usable across the one ABI version, so perhaps this is
> > the best
> > approach.
> >
> > Thoughts from others? Luca or Kevin, any thoughts from a packagers
> > perspective?
> >
> > /Bruce
>
> Hi,
>
> We are currently assembing this path using the ABI version in
> Debian/Ubuntu, as we want same-ABI libraries not to be co-installed,
> but instead fo use the exact same name/path. So from our POV this
> change seems right.
>
Thanks for confirming, Luca.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-17 8:44 9% ` Bruce Richardson
2019-10-17 10:25 4% ` Burakov, Anatoly
@ 2019-10-17 14:09 8% ` Luca Boccassi
2019-10-17 14:12 4% ` Bruce Richardson
2019-10-18 10:07 7% ` Kevin Traynor
1 sibling, 2 replies; 200+ results
From: Luca Boccassi @ 2019-10-17 14:09 UTC (permalink / raw)
To: Bruce Richardson, Anatoly Burakov, Christian Ehrhardt
Cc: dev, Marcin Baran, Thomas Monjalon, john.mcnamara,
david.marchand, Pawel Modrak, ktraynor
On Thu, 2019-10-17 at 09:44 +0100, Bruce Richardson wrote:
> On Wed, Oct 16, 2019 at 06:03:36PM +0100, Anatoly Burakov wrote:
> > From: Marcin Baran <
> > marcinx.baran@intel.com
> > >
> >
> > As per new ABI policy, all of the libraries are now versioned using
> > one global ABI version. Changes in this patch implement the
> > necessary steps to enable that.
> >
> > Signed-off-by: Marcin Baran <
> > marcinx.baran@intel.com
> > >
> > Signed-off-by: Pawel Modrak <
> > pawelx.modrak@intel.com
> > >
> > Signed-off-by: Anatoly Burakov <
> > anatoly.burakov@intel.com
> > >
> > ---
> >
> > Notes:
> > v3:
> > - Removed Windows support from Makefile changes
> > - Removed unneeded path conversions from meson files
> >
> > buildtools/meson.build | 2 ++
> > config/ABI_VERSION | 1 +
> > config/meson.build | 5 +++--
> > drivers/meson.build | 20 ++++++++++++--------
> > lib/meson.build | 18 +++++++++++-------
> > meson_options.txt | 2 --
> > mk/rte.lib.mk | 13 ++++---------
> > 7 files changed, 33 insertions(+), 28 deletions(-)
> > create mode 100644 config/ABI_VERSION
> >
> > diff --git a/buildtools/meson.build b/buildtools/meson.build
> > index 32c79c1308..78ce69977d 100644
> > --- a/buildtools/meson.build
> > +++ b/buildtools/meson.build
> > @@ -12,3 +12,5 @@ if python3.found()
> > else
> > map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
> > endif
> > +
> > +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
> > diff --git a/config/ABI_VERSION b/config/ABI_VERSION
> > new file mode 100644
> > index 0000000000..9a7c1e503f
> > --- /dev/null
> > +++ b/config/ABI_VERSION
> > @@ -0,0 +1 @@
> > +20.0
> > diff --git a/config/meson.build b/config/meson.build
> > index a27f731f85..3cfc02406c 100644
> > --- a/config/meson.build
> > +++ b/config/meson.build
> > @@ -17,7 +17,8 @@ endforeach
> > # set the major version, which might be used by drivers and
> > libraries
> > # depending on the configuration options
> > pver = meson.project_version().split('.')
> > -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
> > +abi_version = run_command(find_program('cat', 'more'),
> > + files('ABI_VERSION')).stdout().strip()
> >
> > # extract all version information into the build configuration
> > dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
> > @@ -37,7 +38,7 @@ endif
> >
> > pmd_subdir_opt = get_option('drivers_install_subdir')
> > if pmd_subdir_opt.contains('<VERSION>')
> > - pmd_subdir_opt =
> > major_version.join(pmd_subdir_opt.split('<VERSION>'))
> > + pmd_subdir_opt =
> > abi_version.join(pmd_subdir_opt.split('<VERSION>'))
> > endif
>
> This is an interesting change, and I'm not sure about it. I think for
> user-visible changes, version should still refer to DPDK version
> rather
> than ABI version. Even with a stable ABI, it makes more sense to me
> to find
> the drivers in a 19.11 directory than a 20.0 one. Then again, the
> drivers
> should be re-usable across the one ABI version, so perhaps this is
> the best
> approach.
>
> Thoughts from others? Luca or Kevin, any thoughts from a packagers
> perspective?
>
> /Bruce
Hi,
We are currently assembing this path using the ABI version in
Debian/Ubuntu, as we want same-ABI libraries not to be co-installed,
but instead fo use the exact same name/path. So from our POV this
change seems right.
--
Kind regards,
Luca Boccassi
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH] mbuf: support dynamic fields and flags
2019-10-17 11:58 0% ` Ananyev, Konstantin
@ 2019-10-17 12:58 0% ` Olivier Matz
0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2019-10-17 12:58 UTC (permalink / raw)
To: Ananyev, Konstantin
Cc: dev, Thomas Monjalon, Wang, Haiyue, Stephen Hemminger,
Andrew Rybchenko, Wiles, Keith, Jerin Jacob Kollanukkaran
Hi Konstantin,
On Thu, Oct 17, 2019 at 11:58:52AM +0000, Ananyev, Konstantin wrote:
>
> Hi Olivier,
>
> > > > Many features require to store data inside the mbuf. As the room in mbuf
> > > > structure is limited, it is not possible to have a field for each
> > > > feature. Also, changing fields in the mbuf structure can break the API
> > > > or ABI.
> > > >
> > > > This commit addresses these issues, by enabling the dynamic registration
> > > > of fields or flags:
> > > >
> > > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > > given size (>= 1 byte) and alignment constraint.
> > > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > > >
> > > > The typical use case is a PMD that registers space for an offload
> > > > feature, when the application requests to enable this feature. As
> > > > the space in mbuf is limited, the space should only be reserved if it
> > > > is going to be used (i.e when the application explicitly asks for it).
> > > >
> > > > The registration can be done at any moment, but it is not possible
> > > > to unregister fields or flags for now.
> > >
> > > Looks ok to me in general.
> > > Some comments/suggestions inline.
> > > Konstantin
> > >
> > > >
> > > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > > ---
> > > >
> > > > rfc -> v1
> > > >
> > > > * Rebase on top of master
> > > > * Change registration API to use a structure instead of
> > > > variables, getting rid of #defines (Stephen's comment)
> > > > * Update flag registration to use a similar API as fields.
> > > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > > * Add a debug log at registration
> > > > * Add some words in release note
> > > > * Did some performance tests (sugg. by Andrew):
> > > > On my platform, reading a dynamic field takes ~3 cycles more
> > > > than a static field, and ~2 cycles more for writing.
> > > >
> > > > app/test/test_mbuf.c | 114 ++++++-
> > > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > > lib/librte_mbuf/Makefile | 2 +
> > > > lib/librte_mbuf/meson.build | 6 +-
> > > > lib/librte_mbuf/rte_mbuf.h | 25 +-
> > > > lib/librte_mbuf/rte_mbuf_dyn.c | 408 +++++++++++++++++++++++++
> > > > lib/librte_mbuf/rte_mbuf_dyn.h | 163 ++++++++++
> > > > lib/librte_mbuf/rte_mbuf_version.map | 4 +
> > > > 8 files changed, 724 insertions(+), 5 deletions(-)
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > > >
> > > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > > @@ -198,9 +198,12 @@ extern "C" {
> > > > #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> > > > #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
> > > >
> > > > -/* add new RX flags here */
> > > > +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
> > > >
> > > > -/* add new TX flags here */
> > > > +#define PKT_FIRST_FREE (1ULL << 23)
> > > > +#define PKT_LAST_FREE (1ULL << 39)
> > > > +
> > > > +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
> > > >
> > > > /**
> > > > * Indicate that the metadata field in the mbuf is in use.
> > > > @@ -738,6 +741,8 @@ struct rte_mbuf {
> > > > */
> > > > struct rte_mbuf_ext_shared_info *shinfo;
> > > >
> > > > + uint64_t dynfield1; /**< Reserved for dynamic fields. */
> > > > + uint64_t dynfield2; /**< Reserved for dynamic fields. */
> > >
> > > Wonder why just not one field:
> > > union {
> > > uint8_t u8[16];
> > > ...
> > > uint64_t u64[2];
> > > } dyn_field1;
> > > ?
> > > Probably would be a bit handy, to refer, register, etc. no?
> >
> > I didn't find any place where we need an access through u8, so I
> > just changed it into uint64_t dynfield1[2].
>
> My thought was - if you'll have all dynamic stuff as one field (uint64_t dyn_field[2]),
> then you woulnd't need any cycles at register() at all.
> But up to you.
I changed it.
> >
> > >
> > > > } __rte_cache_aligned;
> > > >
> > > > /**
> > > > @@ -1684,6 +1689,21 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> > > > */
> > > > #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
> > > >
> > > > +/**
> > > > + * Copy dynamic fields from m_src to m_dst.
> > > > + *
> > > > + * @param m_dst
> > > > + * The destination mbuf.
> > > > + * @param m_src
> > > > + * The source mbuf.
> > > > + */
> > > > +static inline void
> > > > +rte_mbuf_dynfield_copy(struct rte_mbuf *m_dst, const struct rte_mbuf *m_src)
> > > > +{
> > > > + m_dst->dynfield1 = m_src->dynfield1;
> > > > + m_dst->dynfield2 = m_src->dynfield2;
> > > > +}
> > > > +
> > > > /**
> > > > * Attach packet mbuf to another packet mbuf.
> > > > *
> > > > @@ -1732,6 +1752,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
> > > > mi->vlan_tci_outer = m->vlan_tci_outer;
> > > > mi->tx_offload = m->tx_offload;
> > > > mi->hash = m->hash;
> > > > + rte_mbuf_dynfield_copy(mi, m);
> > > >
> > > > mi->next = NULL;
> > > > mi->pkt_len = mi->data_len;
> > > > diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> > > > new file mode 100644
> > > > index 000000000..13b8742d0
> > > > --- /dev/null
> > > > +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> > > > @@ -0,0 +1,408 @@
> > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > + * Copyright 2019 6WIND S.A.
> > > > + */
> > > > +
> > > > +#include <sys/queue.h>
> > > > +
> > > > +#include <rte_common.h>
> > > > +#include <rte_eal.h>
> > > > +#include <rte_eal_memconfig.h>
> > > > +#include <rte_tailq.h>
> > > > +#include <rte_errno.h>
> > > > +#include <rte_malloc.h>
> > > > +#include <rte_string_fns.h>
> > > > +#include <rte_mbuf.h>
> > > > +#include <rte_mbuf_dyn.h>
> > > > +
> > > > +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> > > > +
> > > > +struct mbuf_dynfield_elt {
> > > > + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> > > > + struct rte_mbuf_dynfield params;
> > > > + int offset;
> > >
> > > Why not 'size_t offset', to avoid any explicit conversions, etc?
> >
> > Fixed
> >
> >
> > > > +};
> > > > +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> > > > +
> > > > +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> > > > + .name = "RTE_MBUF_DYNFIELD",
> > > > +};
> > > > +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> > > > +
> > > > +struct mbuf_dynflag_elt {
> > > > + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> > > > + struct rte_mbuf_dynflag params;
> > > > + int bitnum;
> > > > +};
> > > > +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> > > > +
> > > > +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> > > > + .name = "RTE_MBUF_DYNFLAG",
> > > > +};
> > > > +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> > > > +
> > > > +struct mbuf_dyn_shm {
> > > > + /** For each mbuf byte, free_space[i] == 1 if space is free. */
> > > > + uint8_t free_space[sizeof(struct rte_mbuf)];
> > > > + /** Bitfield of available flags. */
> > > > + uint64_t free_flags;
> > > > +};
> > > > +static struct mbuf_dyn_shm *shm;
> > > > +
> > > > +/* allocate and initialize the shared memory */
> > > > +static int
> > > > +init_shared_mem(void)
> > > > +{
> > > > + const struct rte_memzone *mz;
> > > > + uint64_t mask;
> > > > +
> > > > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > > > + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> > > > + sizeof(struct mbuf_dyn_shm),
> > > > + SOCKET_ID_ANY, 0,
> > > > + RTE_CACHE_LINE_SIZE);
> > > > + } else {
> > > > + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> > > > + }
> > > > + if (mz == NULL)
> > > > + return -1;
> > > > +
> > > > + shm = mz->addr;
> > > > +
> > > > +#define mark_free(field) \
> > > > + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> > > > + 0xff, sizeof(((struct rte_mbuf *)0)->field))
> > >
> > > I think you can avoid defining/unedifying macros here by something like that:
> > >
> > > static const struct {
> > > size_t offset;
> > > size_t size;
> > > } dyn_syms[] = {
> > > [0] = {.offset = offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
> > > [1] = {.offset = offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
> > > };
> > > ...
> > >
> > > for (i = 0; i != RTE_DIM(dyn_syms); i++)
> > > memset(shm->free_space + dym_syms[i].offset, UINT8_MAX, dym_syms[i].size);
> > >
> >
> > I tried it, but the following lines are too long
> > [0] = {offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
> > [1] = {offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
> > To make them shorter, we can use a macro... but... wait :)
>
> Guess what, you can put offset ans size on different lines :)
> [0] = {
> .offset = offsetof(struct rte_mbuf, dynfield1),
> .size= sizeof((struct rte_mbuf *)0)->dynfield1),
> },
Yes, but honnestly, I'm not sure that it will be more readable than
the macro, knowing that we could add fields in the future.
> ....
>
> >
> > > > +
> > > > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > > > + /* init free_space, keep it sync'd with
> > > > + * rte_mbuf_dynfield_copy().
> > > > + */
> > > > + memset(shm, 0, sizeof(*shm));
> > > > + mark_free(dynfield1);
> > > > + mark_free(dynfield2);
> > > > +
> > > > + /* init free_flags */
> > > > + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> > > > + shm->free_flags |= mask;
> > > > + }
> > > > +#undef mark_free
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* check if this offset can be used */
> > > > +static int
> > > > +check_offset(size_t offset, size_t size, size_t align, unsigned int flags)
> > > > +{
> > > > + size_t i;
> > > > +
> > > > + (void)flags;
> > >
> > >
> > > We have RTE_SET_USED() for such cases...
> > > Though as it is an internal function probably better not to introduce
> > > unused parameters at all.
> >
> > I removed the flag parameter as you suggested.
> >
> >
> > > > +
> > > > + if ((offset & (align - 1)) != 0)
> > > > + return -1;
> > > > + if (offset + size > sizeof(struct rte_mbuf))
> > > > + return -1;
> > > > +
> > > > + for (i = 0; i < size; i++) {
> > > > + if (!shm->free_space[i + offset])
> > > > + return -1;
> > > > + }
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* assume tailq is locked */
> > > > +static struct mbuf_dynfield_elt *
> > > > +__mbuf_dynfield_lookup(const char *name)
> > > > +{
> > > > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > > > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > > > + struct rte_tailq_entry *te;
> > > > +
> > > > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > > > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > > > +
> > > > + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> > > > + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> > > > + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> > > > + break;
> > > > + }
> > > > +
> > > > + if (te == NULL) {
> > > > + rte_errno = ENOENT;
> > > > + return NULL;
> > > > + }
> > > > +
> > > > + return mbuf_dynfield;
> > > > +}
> > > > +
> > > > +int
> > > > +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> > > > +{
> > > > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > > > +
> > > > + if (shm == NULL) {
> > > > + rte_errno = ENOENT;
> > > > + return -1;
> > > > + }
> > > > +
> > > > + rte_mcfg_tailq_read_lock();
> > > > + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> > > > + rte_mcfg_tailq_read_unlock();
> > > > +
> > > > + if (mbuf_dynfield == NULL) {
> > > > + rte_errno = ENOENT;
> > > > + return -1;
> > > > + }
> > > > +
> > > > + if (params != NULL)
> > > > + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> > > > +
> > > > + return mbuf_dynfield->offset;
> > > > +}
> > > > +
> > > > +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> > > > + const struct rte_mbuf_dynfield *params2)
> > > > +{
> > > > + if (strcmp(params1->name, params2->name))
> > > > + return -1;
> > > > + if (params1->size != params2->size)
> > > > + return -1;
> > > > + if (params1->align != params2->align)
> > > > + return -1;
> > > > + if (params1->flags != params2->flags)
> > > > + return -1;
> > > > + return 0;
> > > > +}
> > > > +
> > > > +int
> > > > +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
> > >
> > > What I meant at user-space - if we can also have another function that would allow
> > > user to specify required offset for dynfield explicitly, then user can define it as constant
> > > value and let compiler do optimization work and hopefully generate faster code to access
> > > this field.
> > > Something like that:
> > >
> > > int rte_mbuf_dynfiled_register_offset(const struct rte_mbuf_dynfield *params, size_t offset);
> > >
> > > #define RTE_MBUF_DYNFIELD_OFFSET(fld, off) (offsetof(struct rte_mbuf, fld) + (off))
> > >
> > > And then somewhere in user code:
> > >
> > > /* to let say reserve first 4B in dynfield1*/
> > > #define MBUF_DYNFIELD_A RTE_MBUF_DYNFIELD_OFFSET(dynfiled1, 0)
> > > ...
> > > params.name = RTE_STR(MBUF_DYNFIELD_A);
> > > params.size = sizeof(uint32_t);
> > > params.align = sizeof(uint32_t);
> > > ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_A);
> > > if (ret != MBUF_DYNFIELD_A) {
> > > /* handle it somehow, probably just terminate gracefully... */
> > > }
> > > ...
> > >
> > > /* to let say reserve last 2B in dynfield2*/
> > > #define MBUF_DYNFIELD_B RTE_MBUF_DYNFIELD_OFFSET(dynfiled2, 6)
> > > ...
> > > params.name = RTE_STR(MBUF_DYNFIELD_B);
> > > params.size = sizeof(uint16_t);
> > > params.align = sizeof(uint16_t);
> > > ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_B);
> > >
> > > After that user can use constant offsets MBUF_DYNFIELD_A/ MBUF_DYNFIELD_B
> > > to access these fields.
> > > Same thoughts for DYNFLAG.
> >
> > I added the feature in v2.
> >
> >
> > > > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > > > + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> > > > + struct rte_tailq_entry *te = NULL;
> > > > + int offset, ret;
> > >
> > > size_t offset
> > > to avoid explicit conversions, etc.?
> > >
> >
> > Fixed.
> >
> >
> > > > + size_t i;
> > > > +
> > > > + if (shm == NULL && init_shared_mem() < 0)
> > > > + goto fail;
> > >
> > > As I understand, here you allocate/initialize your shm without any lock protection,
> > > though later you protect it via rte_mcfg_tailq_write_lock().
> > > That seems a bit flakey to me.
> > > Why not to store information about free dynfield bytes inside mbuf_dynfield_tailq?
> > > Let say at init() create and add an entry into that list with some reserved name.
> > > Then at register - grab mcfg_tailq_write_lock and do lookup
> > > for such entry and then read/update it as needed.
> > > It would help to avoid racing problem, plus you wouldn't need to
> > > allocate/lookup for memzone.
> >
> > I don't quite like the idea of having a special entry with a different type
> > in an element list. Despite it is simpler for a locking perspective, it is
> > less obvious for the developper.
> >
> > Also, I changed the way a zone is reserved to return the one that have the
> > less impact on next reservation, and I feel it is easier to implement with
> > the shared memory.
> >
> > So, I just moved the init_shared_mem() inside the rte_mcfg_tailq_write_lock(),
> > it should do the job.
>
> Yep, that should work too, I think.
>
> >
> >
> > > > + if (params->size >= sizeof(struct rte_mbuf)) {
> > > > + rte_errno = EINVAL;
> > > > + goto fail;
> > > > + }
> > > > + if (!rte_is_power_of_2(params->align)) {
> > > > + rte_errno = EINVAL;
> > > > + goto fail;
> > > > + }
> > > > + if (params->flags != 0) {
> > > > + rte_errno = EINVAL;
> > > > + goto fail;
> > > > + }
> > > > +
> > > > + rte_mcfg_tailq_write_lock();
> > > > +
> > >
> > > I think it probably would be cleaner and easier to read/maintain, if you'll put actual
> > > code under lock protection into a separate function - as you did for __mbuf_dynfield_lookup().
> >
> > Yes, I did that, it should be clearer now.
> >
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-16 22:07 3% ` Ananyev, Konstantin
@ 2019-10-17 12:49 0% ` Ananyev, Konstantin
2019-10-18 13:17 4% ` Akhil Goyal
1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-17 12:49 UTC (permalink / raw)
To: Ananyev, Konstantin, Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph'
>
> > > > User can use the same session, that is what I am also insisting, but it may have
> > > separate
> > > > Session private data. Cryptodev session create API provide that functionality
> > > and we can
> > > > Leverage that.
> > >
> > > rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means
> > > we can't use
> > > the same rte_cryptodev_sym_session to hold sessions for both sync and async
> > > mode
> > > for the same device. Off course we can add a hard requirement that any driver
> > > that wants to
> > > support process() has to create sessions that can handle both process and
> > > enqueue/dequeue,
> > > but then again what for to create such overhead?
> > >
> > > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > > construct for multiple device_ids:
> > > __extension__ struct {
> > > void *data;
> > > uint16_t refcnt;
> > > } sess_data[0];
> > > /**< Driver specific session material, variable size */
> > >
> > Yes I also feel the same. I was also not in favor of this when it was introduced.
> > Please go ahead and remove this. I have no issues with that.
>
> If you are not happy with that structure, and admit there are issues with it,
> why do you push for reusing it for cpu-crypto API?
> Why not to take step back, take into account current drawbacks
> and define something that (hopefully) would suite us better?
> Again new API will be experimental for some time, so we'll
> have some opportunity to see does it works and if not fix it.
>
> About removing data[] from existing rte_cryptodev_sym_session -
> Personally would like to do that, but the change seems to be too massive.
> Definitely not ready for such effort right now.
>
> >
> > > as an advantage.
> > > It looks too error prone for me:
> > > 1. Simultaneous session initialization/de-initialization for devices with the same
> > > driver_id is not possible.
> > > 2. It assumes that all device driver will be loaded before we start to create
> > > session pools.
> > >
> > > Right now it seems ok, as no-one requires such functionality, but I don't know
> > > how it will be in future.
> > > For me rte_security session model, where for each security context user have to
> > > create new session
> > > looks much more robust.
> > Agreed
> >
> > >
> > > >
> > > > BTW, I can see a v2 to this RFC which is still based on security library.
> > >
> > > Yes, v2 was concentrated on fixing found issues, some code restructuring,
> > > i.e. - changes that would be needed anyway whatever API aproach we'll choose.
> > >
> > > > When do you plan
> > > > To submit the patches for crypto based APIs. We have RC1 merge deadline for
> > > this
> > > > patchset on 21st Oct.
> > >
> > > We'd like to start working on it ASAP, but it seems we still have a major
> > > disagreement
> > > about how this crypto-dev API should look like.
> > > Which makes me think - should we return to our original proposal via
> > > rte_security?
> > > It still looks to me like clean and straightforward way to enable this new API,
> > > and probably wouldn't cause that much controversy.
> > > What do you think?
> >
> > I cannot spend more time discussing on this until RC1 date. I have some other stuff pending.
> > You can send the patches early next week with the approach that I mentioned or else we
> > can discuss this post RC1(which would mean deferring to 20.02).
> >
> > But moving back to security is not acceptable to me. The code should be put where it is
> > intended and not where it is easy to put. You are not doing any rte_security stuff.
> >
>
> Ok, then my suggestion:
> Let's at least write down all points about crypto-dev approach where we
> disagree and then probably try to resolve them one by one....
> If we fail to make an agreement/progress in next week or so,
> (and no more reviews from the community)
> will have bring that subject to TB meeting to decide.
> Sounds fair to you?
>
> List is below.
> Please add/correct me, if I missed something.
>
> Konstantin
>
> 1. extra input parameters to create/init rte_(cpu)_sym_session.
>
> Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and 'key' fields.
> New fields will be optional and would be used by PMD only when cpu-crypto session is requested.
> For lksd-crypto session PMD is free to ignore these fields.
> No ABI breakage is required.
>
> Hopefully no controversy here with #1.
>
> 2. cpu-crypto create/init.
> a) Our suggestion - introduce new API for that:
> - rte_crypto_cpu_sym_init() that would init completely opaque rte_crypto_cpu_sym_session.
> - struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear); /*whatever else we'll need *'};
> - rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform *xforms)
> that would return const struct rte_crypto_cpu_sym_session_ops *based on input xforms.
> Advantages:
> 1) totally opaque data structure (no ABI breakages in future), PMD writer is totally free
> with it format and contents.
> 2) each session entity is self-contained, user doesn't need to bring along dev_id etc.
> dev_id is needed only at init stage, after that user will use session ops to perform
> all operations on that session (process(), clear(), etc.).
> 3) User can decide does he wants to store ops[] pointer on a per session basis,
> or on a per group of same sessions, or...
> 4) No mandatory mempools for private sessions. User can allocate memory for cpu-crypto
> session whenever he likes.
> Disadvantages:
> 5) Extra changes in control path
> 6) User has to store session_ops pointer explicitly.
After another thought if 2.a.6 is really that big deal we can have small shim layer on top:
rte_crypto_cpu_sym_session { void *ses; struct rte_crypto_cpu_sym_session_ops * const ops; }
OR even
rte_crypto_cpu_sym_session { void *ses; struct rte_crypto_cpu_sym_session_ops ops; }
And merge rte_crypto_cpu_sym_init() and rte_crypto_cpu_sym_get_ops() into one (init).
Then process() can become a wrapper:
rte_crypto_cpu_sym_process(ses, ...) {return ses->ops->process(ses->ses, ...);}
OR
rte_crypto_cpu_sym_process(ses, ...) {return ses->ops.process(ses->ses, ...);}
if that would help to reach consensus - works for me.
> b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and existing rte_cryptodev_sym_session
> structure.
> Advantages:
> 1) allows to reuse same struct and init/create/clear() functions.
> Probably less changes in control path.
> Disadvantages:
> 2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means that
> we can't use the same rte_cryptodev_sym_session to hold private sessions pointers
> for both sync and async mode for the same device.
> So wthe only option we have - make PMD devops->sym_session_configure()
> always create a session that can work in both cpu and lksd modes.
> For some implementations that would probably mean that under the hood PMD would create
> 2 different session structs (sync/async) and then use one or another depending on from what API been called.
> Seems doable, but ...:
> - will contradict with statement from 1:
> " New fields will be optional and would be used by PMD only when cpu-crypto session is requested."
> Now it becomes mandatory for all apps to specify cpu-crypto related parameters too,
> even if they don't plan to use that mode - i.e. behavior change, existing app change.
> - might cause extra space overhead.
> 3) not possible to store device (not driver) specific data within the session, but I think it is not really needed right now.
> So probably minor compared to 2.b.2.
>
> Actually #3 follows from #2, but decided to have them separated.
>
> 3. process() parameters/behavior
> a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and just does:
> session_ops->process(sess, ...);
> Advantages:
> 1) fastest possible execution path
> 2) no need to carry on dev_id for data-path
> Disadvantages:
> 3) user has to carry on session_ops pointer explicitly
> b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
> rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session *sess, /*data parameters*/) {...
> rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
> /*and then inside PMD specifc process: */
> pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
> /* and then most likely either */
> pmd_private_session->process(pmd_private_session, ...);
> /* or jump based on session/input data */
> Advantages:
> 1) don't see any...
> Disadvantages:
> 2) User has to carry on dev_id inside data-path
> 3) Extra level of indirection (plus data dependency) - both for data and instructions.
> Possible slowdown compared to a) (not measured).
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic compare exchange
2019-10-16 9:04 4% ` Phil Yang (Arm Technology China)
@ 2019-10-17 12:45 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-17 12:45 UTC (permalink / raw)
To: Phil Yang (Arm Technology China)
Cc: thomas, jerinj, Gage Eads, dev, hemant.agrawal,
Honnappa Nagarahalli, Gavin Hu (Arm Technology China),
nd
On Wed, Oct 16, 2019 at 11:04 AM Phil Yang (Arm Technology China)
<Phil.Yang@arm.com> wrote:
>
> > -----Original Message-----
> > From: David Marchand <david.marchand@redhat.com>
> > Sent: Tuesday, October 15, 2019 8:16 PM
> > To: Phil Yang (Arm Technology China) <Phil.Yang@arm.com>
> > Cc: thomas@monjalon.net; jerinj@marvell.com; Gage Eads
> > <gage.eads@intel.com>; dev <dev@dpdk.org>; hemant.agrawal@nxp.com;
> > Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu (Arm
> > Technology China) <Gavin.Hu@arm.com>; nd <nd@arm.com>
> > Subject: Re: [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic
> > compare exchange
> >
> > On Tue, Oct 15, 2019 at 1:32 PM Phil Yang (Arm Technology China)
> > <Phil.Yang@arm.com> wrote:
> > > > -----Original Message-----
> > > > From: David Marchand <david.marchand@redhat.com>
> > > > If LSE is available, we expose __rte_cas_XX (explicitely) *non*
> > > > inlined functions, while without LSE, we expose inlined __rte_ldr_XX
> > > > and __rte_stx_XX functions.
> > > > So we have a first disparity with non-inlined vs inlined functions
> > > > depending on a #ifdef.
> >
> > You did not comment on the inline / no inline part and I still see
> > this in the v10.
> > Is this __rte_noinline on the CAS function intentional?
>
> Apologize for missing this item. Yes, it is to avoid ABI break.
> Please check
> 5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix possible arm64 ABI break")
Looked at the kernel parts on LSE CAS (thanks for the pointer) but I
see inlines are used:
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/arm64/include/asm/atomic_lse.h#n365?h=v5.4-rc3
What is special in the kernel or in dpdk that makes this different?
>
> >
> >
> > > > Then, we have a second disparity with two sets of "apis" depending on
> > > > this #ifdef.
> > > >
> > > > And we expose those sets with a rte_ prefix, meaning people will try
> > > > to use them, but those are not part of a public api.
> > > >
> > > > Can't we do without them ? (see below [2] for a proposal with ldr/stx,
> > > > cas should be the same)
> > >
> > > No, it doesn't work.
> > > Because we need to verify the return value at the end of the loop for these
> > macros.
> >
> > Do you mean the return value for the stores?
>
> It is my bad. I missed the ret option in the macro. This approach works.
Ok, thanks for confirming.
>
> However, I suggest to keep them as static inline functions rather than a piece of macro in the rte_atomic128_cmp_exchange API.
> One reason is APIs name can indicate the memory ordering of these operations.
API?
Those inlines are not part of a public API and we agree this patch is
not about adding 128 bits load/store apis.
My proposal gives us small code that looks like:
if (ldx_mo == __ATOMIC_RELAXED)
__READ_128("ldxp", dst, old);
else
__READ_128("ldaxp", dst, old);
I am not a memory order guru, but with this, I can figure the asm
instruction depends on it.
And, since we are looking at internals of an implementation, this is
mainly for people looking at/maintaining these low level details.
> Moreover, it uses the register type to pass the value in the inline function, so it should not have too much cost comparing with the macro.
This is not a problem of cost, this is about hiding architecture
details from the final user.
If you expose something, you can expect someone will start using it
and will complain later if you break it.
> I also think these 128bit load and store functions can be used in other places, once it has been proved valuable in rte_atomic128_cmp_exchange API. But let's keep them private for the current stage.
Yes I agree this could be introduced in the future.
> BTW, Linux kernel implemented in the same way. https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/atomic_lse.h#L19
Ok kernel exposes its internals, but I think kernel developpers are
more vigilant than dpdk developpers on what is part of the public API
and what is internal.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] mbuf: support dynamic fields and flags
2019-10-17 7:54 0% ` Olivier Matz
@ 2019-10-17 11:58 0% ` Ananyev, Konstantin
2019-10-17 12:58 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-17 11:58 UTC (permalink / raw)
To: Olivier Matz
Cc: dev, Thomas Monjalon, Wang, Haiyue, Stephen Hemminger,
Andrew Rybchenko, Wiles, Keith, Jerin Jacob Kollanukkaran
Hi Olivier,
> > > Many features require to store data inside the mbuf. As the room in mbuf
> > > structure is limited, it is not possible to have a field for each
> > > feature. Also, changing fields in the mbuf structure can break the API
> > > or ABI.
> > >
> > > This commit addresses these issues, by enabling the dynamic registration
> > > of fields or flags:
> > >
> > > - a dynamic field is a named area in the rte_mbuf structure, with a
> > > given size (>= 1 byte) and alignment constraint.
> > > - a dynamic flag is a named bit in the rte_mbuf structure.
> > >
> > > The typical use case is a PMD that registers space for an offload
> > > feature, when the application requests to enable this feature. As
> > > the space in mbuf is limited, the space should only be reserved if it
> > > is going to be used (i.e when the application explicitly asks for it).
> > >
> > > The registration can be done at any moment, but it is not possible
> > > to unregister fields or flags for now.
> >
> > Looks ok to me in general.
> > Some comments/suggestions inline.
> > Konstantin
> >
> > >
> > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > > ---
> > >
> > > rfc -> v1
> > >
> > > * Rebase on top of master
> > > * Change registration API to use a structure instead of
> > > variables, getting rid of #defines (Stephen's comment)
> > > * Update flag registration to use a similar API as fields.
> > > * Change max name length from 32 to 64 (sugg. by Thomas)
> > > * Enhance API documentation (Haiyue's and Andrew's comments)
> > > * Add a debug log at registration
> > > * Add some words in release note
> > > * Did some performance tests (sugg. by Andrew):
> > > On my platform, reading a dynamic field takes ~3 cycles more
> > > than a static field, and ~2 cycles more for writing.
> > >
> > > app/test/test_mbuf.c | 114 ++++++-
> > > doc/guides/rel_notes/release_19_11.rst | 7 +
> > > lib/librte_mbuf/Makefile | 2 +
> > > lib/librte_mbuf/meson.build | 6 +-
> > > lib/librte_mbuf/rte_mbuf.h | 25 +-
> > > lib/librte_mbuf/rte_mbuf_dyn.c | 408 +++++++++++++++++++++++++
> > > lib/librte_mbuf/rte_mbuf_dyn.h | 163 ++++++++++
> > > lib/librte_mbuf/rte_mbuf_version.map | 4 +
> > > 8 files changed, 724 insertions(+), 5 deletions(-)
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> > >
> > > --- a/lib/librte_mbuf/rte_mbuf.h
> > > +++ b/lib/librte_mbuf/rte_mbuf.h
> > > @@ -198,9 +198,12 @@ extern "C" {
> > > #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> > > #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
> > >
> > > -/* add new RX flags here */
> > > +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
> > >
> > > -/* add new TX flags here */
> > > +#define PKT_FIRST_FREE (1ULL << 23)
> > > +#define PKT_LAST_FREE (1ULL << 39)
> > > +
> > > +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
> > >
> > > /**
> > > * Indicate that the metadata field in the mbuf is in use.
> > > @@ -738,6 +741,8 @@ struct rte_mbuf {
> > > */
> > > struct rte_mbuf_ext_shared_info *shinfo;
> > >
> > > + uint64_t dynfield1; /**< Reserved for dynamic fields. */
> > > + uint64_t dynfield2; /**< Reserved for dynamic fields. */
> >
> > Wonder why just not one field:
> > union {
> > uint8_t u8[16];
> > ...
> > uint64_t u64[2];
> > } dyn_field1;
> > ?
> > Probably would be a bit handy, to refer, register, etc. no?
>
> I didn't find any place where we need an access through u8, so I
> just changed it into uint64_t dynfield1[2].
My thought was - if you'll have all dynamic stuff as one field (uint64_t dyn_field[2]),
then you woulnd't need any cycles at register() at all.
But up to you.
>
>
> >
> > > } __rte_cache_aligned;
> > >
> > > /**
> > > @@ -1684,6 +1689,21 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> > > */
> > > #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
> > >
> > > +/**
> > > + * Copy dynamic fields from m_src to m_dst.
> > > + *
> > > + * @param m_dst
> > > + * The destination mbuf.
> > > + * @param m_src
> > > + * The source mbuf.
> > > + */
> > > +static inline void
> > > +rte_mbuf_dynfield_copy(struct rte_mbuf *m_dst, const struct rte_mbuf *m_src)
> > > +{
> > > + m_dst->dynfield1 = m_src->dynfield1;
> > > + m_dst->dynfield2 = m_src->dynfield2;
> > > +}
> > > +
> > > /**
> > > * Attach packet mbuf to another packet mbuf.
> > > *
> > > @@ -1732,6 +1752,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
> > > mi->vlan_tci_outer = m->vlan_tci_outer;
> > > mi->tx_offload = m->tx_offload;
> > > mi->hash = m->hash;
> > > + rte_mbuf_dynfield_copy(mi, m);
> > >
> > > mi->next = NULL;
> > > mi->pkt_len = mi->data_len;
> > > diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> > > new file mode 100644
> > > index 000000000..13b8742d0
> > > --- /dev/null
> > > +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> > > @@ -0,0 +1,408 @@
> > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > + * Copyright 2019 6WIND S.A.
> > > + */
> > > +
> > > +#include <sys/queue.h>
> > > +
> > > +#include <rte_common.h>
> > > +#include <rte_eal.h>
> > > +#include <rte_eal_memconfig.h>
> > > +#include <rte_tailq.h>
> > > +#include <rte_errno.h>
> > > +#include <rte_malloc.h>
> > > +#include <rte_string_fns.h>
> > > +#include <rte_mbuf.h>
> > > +#include <rte_mbuf_dyn.h>
> > > +
> > > +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> > > +
> > > +struct mbuf_dynfield_elt {
> > > + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> > > + struct rte_mbuf_dynfield params;
> > > + int offset;
> >
> > Why not 'size_t offset', to avoid any explicit conversions, etc?
>
> Fixed
>
>
> > > +};
> > > +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> > > +
> > > +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> > > + .name = "RTE_MBUF_DYNFIELD",
> > > +};
> > > +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> > > +
> > > +struct mbuf_dynflag_elt {
> > > + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> > > + struct rte_mbuf_dynflag params;
> > > + int bitnum;
> > > +};
> > > +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> > > +
> > > +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> > > + .name = "RTE_MBUF_DYNFLAG",
> > > +};
> > > +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> > > +
> > > +struct mbuf_dyn_shm {
> > > + /** For each mbuf byte, free_space[i] == 1 if space is free. */
> > > + uint8_t free_space[sizeof(struct rte_mbuf)];
> > > + /** Bitfield of available flags. */
> > > + uint64_t free_flags;
> > > +};
> > > +static struct mbuf_dyn_shm *shm;
> > > +
> > > +/* allocate and initialize the shared memory */
> > > +static int
> > > +init_shared_mem(void)
> > > +{
> > > + const struct rte_memzone *mz;
> > > + uint64_t mask;
> > > +
> > > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > > + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> > > + sizeof(struct mbuf_dyn_shm),
> > > + SOCKET_ID_ANY, 0,
> > > + RTE_CACHE_LINE_SIZE);
> > > + } else {
> > > + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> > > + }
> > > + if (mz == NULL)
> > > + return -1;
> > > +
> > > + shm = mz->addr;
> > > +
> > > +#define mark_free(field) \
> > > + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> > > + 0xff, sizeof(((struct rte_mbuf *)0)->field))
> >
> > I think you can avoid defining/unedifying macros here by something like that:
> >
> > static const struct {
> > size_t offset;
> > size_t size;
> > } dyn_syms[] = {
> > [0] = {.offset = offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
> > [1] = {.offset = offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
> > };
> > ...
> >
> > for (i = 0; i != RTE_DIM(dyn_syms); i++)
> > memset(shm->free_space + dym_syms[i].offset, UINT8_MAX, dym_syms[i].size);
> >
>
> I tried it, but the following lines are too long
> [0] = {offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
> [1] = {offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
> To make them shorter, we can use a macro... but... wait :)
Guess what, you can put offset ans size on different lines :)
[0] = {
.offset = offsetof(struct rte_mbuf, dynfield1),
.size= sizeof((struct rte_mbuf *)0)->dynfield1),
},
....
>
> > > +
> > > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > > + /* init free_space, keep it sync'd with
> > > + * rte_mbuf_dynfield_copy().
> > > + */
> > > + memset(shm, 0, sizeof(*shm));
> > > + mark_free(dynfield1);
> > > + mark_free(dynfield2);
> > > +
> > > + /* init free_flags */
> > > + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> > > + shm->free_flags |= mask;
> > > + }
> > > +#undef mark_free
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +/* check if this offset can be used */
> > > +static int
> > > +check_offset(size_t offset, size_t size, size_t align, unsigned int flags)
> > > +{
> > > + size_t i;
> > > +
> > > + (void)flags;
> >
> >
> > We have RTE_SET_USED() for such cases...
> > Though as it is an internal function probably better not to introduce
> > unused parameters at all.
>
> I removed the flag parameter as you suggested.
>
>
> > > +
> > > + if ((offset & (align - 1)) != 0)
> > > + return -1;
> > > + if (offset + size > sizeof(struct rte_mbuf))
> > > + return -1;
> > > +
> > > + for (i = 0; i < size; i++) {
> > > + if (!shm->free_space[i + offset])
> > > + return -1;
> > > + }
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +/* assume tailq is locked */
> > > +static struct mbuf_dynfield_elt *
> > > +__mbuf_dynfield_lookup(const char *name)
> > > +{
> > > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > > + struct rte_tailq_entry *te;
> > > +
> > > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > > +
> > > + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> > > + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> > > + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> > > + break;
> > > + }
> > > +
> > > + if (te == NULL) {
> > > + rte_errno = ENOENT;
> > > + return NULL;
> > > + }
> > > +
> > > + return mbuf_dynfield;
> > > +}
> > > +
> > > +int
> > > +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> > > +{
> > > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > > +
> > > + if (shm == NULL) {
> > > + rte_errno = ENOENT;
> > > + return -1;
> > > + }
> > > +
> > > + rte_mcfg_tailq_read_lock();
> > > + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> > > + rte_mcfg_tailq_read_unlock();
> > > +
> > > + if (mbuf_dynfield == NULL) {
> > > + rte_errno = ENOENT;
> > > + return -1;
> > > + }
> > > +
> > > + if (params != NULL)
> > > + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> > > +
> > > + return mbuf_dynfield->offset;
> > > +}
> > > +
> > > +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> > > + const struct rte_mbuf_dynfield *params2)
> > > +{
> > > + if (strcmp(params1->name, params2->name))
> > > + return -1;
> > > + if (params1->size != params2->size)
> > > + return -1;
> > > + if (params1->align != params2->align)
> > > + return -1;
> > > + if (params1->flags != params2->flags)
> > > + return -1;
> > > + return 0;
> > > +}
> > > +
> > > +int
> > > +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
> >
> > What I meant at user-space - if we can also have another function that would allow
> > user to specify required offset for dynfield explicitly, then user can define it as constant
> > value and let compiler do optimization work and hopefully generate faster code to access
> > this field.
> > Something like that:
> >
> > int rte_mbuf_dynfiled_register_offset(const struct rte_mbuf_dynfield *params, size_t offset);
> >
> > #define RTE_MBUF_DYNFIELD_OFFSET(fld, off) (offsetof(struct rte_mbuf, fld) + (off))
> >
> > And then somewhere in user code:
> >
> > /* to let say reserve first 4B in dynfield1*/
> > #define MBUF_DYNFIELD_A RTE_MBUF_DYNFIELD_OFFSET(dynfiled1, 0)
> > ...
> > params.name = RTE_STR(MBUF_DYNFIELD_A);
> > params.size = sizeof(uint32_t);
> > params.align = sizeof(uint32_t);
> > ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_A);
> > if (ret != MBUF_DYNFIELD_A) {
> > /* handle it somehow, probably just terminate gracefully... */
> > }
> > ...
> >
> > /* to let say reserve last 2B in dynfield2*/
> > #define MBUF_DYNFIELD_B RTE_MBUF_DYNFIELD_OFFSET(dynfiled2, 6)
> > ...
> > params.name = RTE_STR(MBUF_DYNFIELD_B);
> > params.size = sizeof(uint16_t);
> > params.align = sizeof(uint16_t);
> > ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_B);
> >
> > After that user can use constant offsets MBUF_DYNFIELD_A/ MBUF_DYNFIELD_B
> > to access these fields.
> > Same thoughts for DYNFLAG.
>
> I added the feature in v2.
>
>
> > > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > > + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> > > + struct rte_tailq_entry *te = NULL;
> > > + int offset, ret;
> >
> > size_t offset
> > to avoid explicit conversions, etc.?
> >
>
> Fixed.
>
>
> > > + size_t i;
> > > +
> > > + if (shm == NULL && init_shared_mem() < 0)
> > > + goto fail;
> >
> > As I understand, here you allocate/initialize your shm without any lock protection,
> > though later you protect it via rte_mcfg_tailq_write_lock().
> > That seems a bit flakey to me.
> > Why not to store information about free dynfield bytes inside mbuf_dynfield_tailq?
> > Let say at init() create and add an entry into that list with some reserved name.
> > Then at register - grab mcfg_tailq_write_lock and do lookup
> > for such entry and then read/update it as needed.
> > It would help to avoid racing problem, plus you wouldn't need to
> > allocate/lookup for memzone.
>
> I don't quite like the idea of having a special entry with a different type
> in an element list. Despite it is simpler for a locking perspective, it is
> less obvious for the developper.
>
> Also, I changed the way a zone is reserved to return the one that have the
> less impact on next reservation, and I feel it is easier to implement with
> the shared memory.
>
> So, I just moved the init_shared_mem() inside the rte_mcfg_tailq_write_lock(),
> it should do the job.
Yep, that should work too, I think.
>
>
> > > + if (params->size >= sizeof(struct rte_mbuf)) {
> > > + rte_errno = EINVAL;
> > > + goto fail;
> > > + }
> > > + if (!rte_is_power_of_2(params->align)) {
> > > + rte_errno = EINVAL;
> > > + goto fail;
> > > + }
> > > + if (params->flags != 0) {
> > > + rte_errno = EINVAL;
> > > + goto fail;
> > > + }
> > > +
> > > + rte_mcfg_tailq_write_lock();
> > > +
> >
> > I think it probably would be cleaner and easier to read/maintain, if you'll put actual
> > code under lock protection into a separate function - as you did for __mbuf_dynfield_lookup().
>
> Yes, I did that, it should be clearer now.
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 6/9] distributor: remove deprecated code
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 6/9] distributor: " Anatoly Burakov
@ 2019-10-17 10:53 0% ` Hunt, David
0 siblings, 0 replies; 200+ results
From: Hunt, David @ 2019-10-17 10:53 UTC (permalink / raw)
To: Anatoly Burakov, dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas, david.marchand
On 16/10/2019 18:03, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> Remove code for old ABI versions ahead of ABI version bump.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v3:
> - Removed single mode from distributor as per Dave's comments
Hi Anatoly,
Having looked at this code closer, I see that this now breaks the API
for when a distributor instance is created with the RTE_DIST_ALG_SINGLE.
I think now that the better solution would be to just re-name the _v20
to _single for structs, functions, etc, as you did in the previous patch
version. That means that the unit and perf tests should still work
unchanged, and maintain the API.
Rgds,
Dave.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-17 8:44 9% ` Bruce Richardson
@ 2019-10-17 10:25 4% ` Burakov, Anatoly
2019-10-17 14:09 8% ` Luca Boccassi
1 sibling, 0 replies; 200+ results
From: Burakov, Anatoly @ 2019-10-17 10:25 UTC (permalink / raw)
To: Bruce Richardson
Cc: dev, Marcin Baran, Thomas Monjalon, john.mcnamara,
david.marchand, Pawel Modrak, bluca, ktraynor
On 17-Oct-19 9:44 AM, Bruce Richardson wrote:
> On Wed, Oct 16, 2019 at 06:03:36PM +0100, Anatoly Burakov wrote:
>> From: Marcin Baran <marcinx.baran@intel.com>
>>
>> As per new ABI policy, all of the libraries are now versioned using
>> one global ABI version. Changes in this patch implement the
>> necessary steps to enable that.
>>
>> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
>> Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>> ---
>>
>> Notes:
>> v3:
>> - Removed Windows support from Makefile changes
>> - Removed unneeded path conversions from meson files
>>
>> buildtools/meson.build | 2 ++
>> config/ABI_VERSION | 1 +
>> config/meson.build | 5 +++--
>> drivers/meson.build | 20 ++++++++++++--------
>> lib/meson.build | 18 +++++++++++-------
>> meson_options.txt | 2 --
>> mk/rte.lib.mk | 13 ++++---------
>> 7 files changed, 33 insertions(+), 28 deletions(-)
>> create mode 100644 config/ABI_VERSION
>>
>> diff --git a/buildtools/meson.build b/buildtools/meson.build
>> index 32c79c1308..78ce69977d 100644
>> --- a/buildtools/meson.build
>> +++ b/buildtools/meson.build
>> @@ -12,3 +12,5 @@ if python3.found()
>> else
>> map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
>> endif
>> +
>> +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
>> diff --git a/config/ABI_VERSION b/config/ABI_VERSION
>> new file mode 100644
>> index 0000000000..9a7c1e503f
>> --- /dev/null
>> +++ b/config/ABI_VERSION
>> @@ -0,0 +1 @@
>> +20.0
>> diff --git a/config/meson.build b/config/meson.build
>> index a27f731f85..3cfc02406c 100644
>> --- a/config/meson.build
>> +++ b/config/meson.build
>> @@ -17,7 +17,8 @@ endforeach
>> # set the major version, which might be used by drivers and libraries
>> # depending on the configuration options
>> pver = meson.project_version().split('.')
>> -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
>> +abi_version = run_command(find_program('cat', 'more'),
>> + files('ABI_VERSION')).stdout().strip()
>>
>> # extract all version information into the build configuration
>> dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
>> @@ -37,7 +38,7 @@ endif
>>
>> pmd_subdir_opt = get_option('drivers_install_subdir')
>> if pmd_subdir_opt.contains('<VERSION>')
>> - pmd_subdir_opt = major_version.join(pmd_subdir_opt.split('<VERSION>'))
>> + pmd_subdir_opt = abi_version.join(pmd_subdir_opt.split('<VERSION>'))
>> endif
>
> This is an interesting change, and I'm not sure about it. I think for
> user-visible changes, version should still refer to DPDK version rather
> than ABI version. Even with a stable ABI, it makes more sense to me to find
> the drivers in a 19.11 directory than a 20.0 one. Then again, the drivers
> should be re-usable across the one ABI version, so perhaps this is the best
> approach.
>
> Thoughts from others? Luca or Kevin, any thoughts from a packagers
> perspective?
>
> /Bruce
I can certainly change it back. This wasn't intentional - i just did a
search-and-replace without thinking too much about it :)
--
Thanks,
Anatoly
^ permalink raw reply [relevance 4%]
* [dpdk-dev] DPDK Release Status Meeting 17/10/2019
@ 2019-10-17 9:59 3% Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-17 9:59 UTC (permalink / raw)
To: dpdk-dev; +Cc: Thomas Monjalon
Minutes 17 October 2019
-----------------------
Agenda:
* Release Dates
* Subtrees
* OvS
* Conferences
* Opens
Participants:
* Arm
* Debian/Microsoft
* Intel
* Marvell
* NXP
* Red Hat
Release Dates
-------------
* v19.11 dates:
* Integration/Merge/RC1 Wednesday 23 October
* For sub-trees Monday 21 October
* Release Friday 22 November
* Proposed dates for 20.02 release on the mail list, please comment
https://mails.dpdk.org/archives/dev/2019-September/143311.html
These dates may affected from the 19.11 delays, please review again.
Subtrees
--------
* main
* David merged some patches and working on KNI/eal patches
* Planning review ABI process patches for rc1
* next-net
* ~80 patches in backlog, trying to make rc1 dates
* Planning to get ethdev API and rte_flow patches (7-8 patchset) for rc1,
testpmd and driver patches may pushed to rc2
* Two new PMDs already merged
* next-net-crypto
* Planning to get 'octeontx2' PMD
* More review required on three patchset
* ipsec-secgw, add fallback session
https://patches.dpdk.org/project/dpdk/list/?series=6833
* ipsec-secgw, set default to IPsec library mode
https://patches.dpdk.org/patch/60349/, 60350, 60351
* security library, CPU Crypto (asked for tech board review)
https://patches.dpdk.org/project/dpdk/list/?series=6727&state=*
* ipsec, inbound SAD series waiting for an update
https://patches.dpdk.org/project/dpdk/list/?series=6790&state=*
* next-net-eventdev
* Some more patches are in the tree waiting for pull
* l2fwd-event app can be pushed to rc2
(update the existing l3fwd for eventdev pushed to next release)
* next-net-virtio (update from David)
* Reviewing Marvin's vhost packed ring performance optimization patch
* Maxim's (own) Virtio vDPA set is at risk, may pushed to next release
* next-net-intel
* Some patches already in the tree waiting for pull
* ice PMD patches for RSS and FDIR patches under review
* ipn3ke PMD patches has some issues, it has risk for rc1,
can be considered for rc2
* LTS
* v18.11.3-rc2 under test
* More test from more companies is welcome
* Target release date is next week
OvS
---
* For TSO support, DPDK patch has been merged
Conferences
-----------
* DPDK Summit North America, Mountain View CA, November 12-13
* CPF results announced
https://www.dpdk.org/event/dpdk-summit-na-mountain-view/
Opens
-----
* Coverity run last week, there are outstanding issues:
https://scan.coverity.com/projects/dpdk-data-plane-development-kit?tab=overview
* Reminder of other static analysis tool for dpdk, lgtm:
https://lgtm.com/projects/g/DPDK/dpdk/?mode=list
DPDK Release Status Meetings
============================
The DPDK Release Status Meeting is intended for DPDK Committers to discuss
the status of the master tree and sub-trees, and for project managers to
track progress or milestone dates.
The meeting occurs on Thursdays at 8:30 UTC. If you wish to attend just
send an email to "John McNamara <john.mcnamara@intel.com>" for the invite.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 0/9] Implement the new ABI policy and add helper scripts
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
@ 2019-10-17 8:50 4% ` Bruce Richardson
2019-10-17 14:31 8% ` [dpdk-dev] [PATCH v4 00/10] " Anatoly Burakov
` (10 subsequent siblings)
11 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-17 8:50 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev, john.mcnamara, thomas, david.marchand
On Wed, Oct 16, 2019 at 06:03:35PM +0100, Anatoly Burakov wrote:
> This patchset prepares the codebase for the new ABI policy and
> adds a few helper scripts.
>
> There are two new scripts for managing ABI versions added. The
> first one is a Python script that will read in a .map file,
> flatten it and update the ABI version to the ABI version
> specified on the command-line.
>
> The second one is a shell script that will run the above mentioned
> Python script recursively over the source tree and set the ABI
> version to either that which is defined in config/ABI_VERSION, or
> a user-specified one.
>
> Example of its usage: buildtools/update-abi.sh 20.0
>
> This will recurse into lib/ and drivers/ directory and update
> whatever .map files it can find.
>
> The other shell script that's added is one that can take in a .so
> file and ensure that its declared public ABI matches either
> current ABI, next ABI, or EXPERIMENTAL. This was moved to the
> last commit because it made no sense to have it beforehand.
>
> The source tree was verified to follow the new ABI policy using
> the following command (assuming built binaries are in build/):
>
> find ./build/lib ./build/drivers -name \*.so \
> -exec ./buildtools/check-abi-version.sh {} \; -print
>
> This returns 0.
>
> Changes since v2:
> - Addressed Bruce's review comments
> - Removed single distributor mode as per Dave's suggestion
>
> Changes since v1:
> - Reordered patchset to have removal of old ABI's before introducing
> the new one to avoid compile breakages between patches
> - Added a new patch fixing missing symbol in octeontx common
> - Split script commits into multiple commits and reordered them
> - Re-generated the ABI bump commit
> - Verified all scripts to work
>
> Anatoly Burakov (2):
> buildtools: add ABI update shell script
> drivers/octeontx: add missing public symbol
>
> Marcin Baran (5):
> config: change ABI versioning to global
> timer: remove deprecated code
> lpm: remove deprecated code
> distributor: remove deprecated code
> buildtools: add ABI versioning check script
>
> Pawel Modrak (2):
> buildtools: add script for updating symbols abi version
> build: change ABI version to 20.0
>
For me, bar the one small open question on driver paths, this looks pretty
good.
Series-acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-16 17:03 7% ` [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global Anatoly Burakov
@ 2019-10-17 8:44 9% ` Bruce Richardson
2019-10-17 10:25 4% ` Burakov, Anatoly
2019-10-17 14:09 8% ` Luca Boccassi
0 siblings, 2 replies; 200+ results
From: Bruce Richardson @ 2019-10-17 8:44 UTC (permalink / raw)
To: Anatoly Burakov
Cc: dev, Marcin Baran, Thomas Monjalon, john.mcnamara,
david.marchand, Pawel Modrak, bluca, ktraynor
On Wed, Oct 16, 2019 at 06:03:36PM +0100, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> As per new ABI policy, all of the libraries are now versioned using
> one global ABI version. Changes in this patch implement the
> necessary steps to enable that.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v3:
> - Removed Windows support from Makefile changes
> - Removed unneeded path conversions from meson files
>
> buildtools/meson.build | 2 ++
> config/ABI_VERSION | 1 +
> config/meson.build | 5 +++--
> drivers/meson.build | 20 ++++++++++++--------
> lib/meson.build | 18 +++++++++++-------
> meson_options.txt | 2 --
> mk/rte.lib.mk | 13 ++++---------
> 7 files changed, 33 insertions(+), 28 deletions(-)
> create mode 100644 config/ABI_VERSION
>
> diff --git a/buildtools/meson.build b/buildtools/meson.build
> index 32c79c1308..78ce69977d 100644
> --- a/buildtools/meson.build
> +++ b/buildtools/meson.build
> @@ -12,3 +12,5 @@ if python3.found()
> else
> map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
> endif
> +
> +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
> diff --git a/config/ABI_VERSION b/config/ABI_VERSION
> new file mode 100644
> index 0000000000..9a7c1e503f
> --- /dev/null
> +++ b/config/ABI_VERSION
> @@ -0,0 +1 @@
> +20.0
> diff --git a/config/meson.build b/config/meson.build
> index a27f731f85..3cfc02406c 100644
> --- a/config/meson.build
> +++ b/config/meson.build
> @@ -17,7 +17,8 @@ endforeach
> # set the major version, which might be used by drivers and libraries
> # depending on the configuration options
> pver = meson.project_version().split('.')
> -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
> +abi_version = run_command(find_program('cat', 'more'),
> + files('ABI_VERSION')).stdout().strip()
>
> # extract all version information into the build configuration
> dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
> @@ -37,7 +38,7 @@ endif
>
> pmd_subdir_opt = get_option('drivers_install_subdir')
> if pmd_subdir_opt.contains('<VERSION>')
> - pmd_subdir_opt = major_version.join(pmd_subdir_opt.split('<VERSION>'))
> + pmd_subdir_opt = abi_version.join(pmd_subdir_opt.split('<VERSION>'))
> endif
This is an interesting change, and I'm not sure about it. I think for
user-visible changes, version should still refer to DPDK version rather
than ABI version. Even with a stable ABI, it makes more sense to me to find
the drivers in a 19.11 directory than a 20.0 one. Then again, the drivers
should be re-usable across the one ABI version, so perhaps this is the best
approach.
Thoughts from others? Luca or Kevin, any thoughts from a packagers
perspective?
/Bruce
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] mbuf: support dynamic fields and flags
2019-10-01 10:49 0% ` Ananyev, Konstantin
@ 2019-10-17 7:54 0% ` Olivier Matz
2019-10-17 11:58 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2019-10-17 7:54 UTC (permalink / raw)
To: Ananyev, Konstantin
Cc: dev, Thomas Monjalon, Wang, Haiyue, Stephen Hemminger,
Andrew Rybchenko, Wiles, Keith, Jerin Jacob Kollanukkaran
Hi Konstantin,
Thanks for the feedback. Please see my answers below.
On Tue, Oct 01, 2019 at 10:49:39AM +0000, Ananyev, Konstantin wrote:
> Hi Olivier,
>
> > Many features require to store data inside the mbuf. As the room in mbuf
> > structure is limited, it is not possible to have a field for each
> > feature. Also, changing fields in the mbuf structure can break the API
> > or ABI.
> >
> > This commit addresses these issues, by enabling the dynamic registration
> > of fields or flags:
> >
> > - a dynamic field is a named area in the rte_mbuf structure, with a
> > given size (>= 1 byte) and alignment constraint.
> > - a dynamic flag is a named bit in the rte_mbuf structure.
> >
> > The typical use case is a PMD that registers space for an offload
> > feature, when the application requests to enable this feature. As
> > the space in mbuf is limited, the space should only be reserved if it
> > is going to be used (i.e when the application explicitly asks for it).
> >
> > The registration can be done at any moment, but it is not possible
> > to unregister fields or flags for now.
>
> Looks ok to me in general.
> Some comments/suggestions inline.
> Konstantin
>
> >
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > Acked-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >
> > rfc -> v1
> >
> > * Rebase on top of master
> > * Change registration API to use a structure instead of
> > variables, getting rid of #defines (Stephen's comment)
> > * Update flag registration to use a similar API as fields.
> > * Change max name length from 32 to 64 (sugg. by Thomas)
> > * Enhance API documentation (Haiyue's and Andrew's comments)
> > * Add a debug log at registration
> > * Add some words in release note
> > * Did some performance tests (sugg. by Andrew):
> > On my platform, reading a dynamic field takes ~3 cycles more
> > than a static field, and ~2 cycles more for writing.
> >
> > app/test/test_mbuf.c | 114 ++++++-
> > doc/guides/rel_notes/release_19_11.rst | 7 +
> > lib/librte_mbuf/Makefile | 2 +
> > lib/librte_mbuf/meson.build | 6 +-
> > lib/librte_mbuf/rte_mbuf.h | 25 +-
> > lib/librte_mbuf/rte_mbuf_dyn.c | 408 +++++++++++++++++++++++++
> > lib/librte_mbuf/rte_mbuf_dyn.h | 163 ++++++++++
> > lib/librte_mbuf/rte_mbuf_version.map | 4 +
> > 8 files changed, 724 insertions(+), 5 deletions(-)
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> > create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
> >
> > --- a/lib/librte_mbuf/rte_mbuf.h
> > +++ b/lib/librte_mbuf/rte_mbuf.h
> > @@ -198,9 +198,12 @@ extern "C" {
> > #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> > #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
> >
> > -/* add new RX flags here */
> > +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
> >
> > -/* add new TX flags here */
> > +#define PKT_FIRST_FREE (1ULL << 23)
> > +#define PKT_LAST_FREE (1ULL << 39)
> > +
> > +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
> >
> > /**
> > * Indicate that the metadata field in the mbuf is in use.
> > @@ -738,6 +741,8 @@ struct rte_mbuf {
> > */
> > struct rte_mbuf_ext_shared_info *shinfo;
> >
> > + uint64_t dynfield1; /**< Reserved for dynamic fields. */
> > + uint64_t dynfield2; /**< Reserved for dynamic fields. */
>
> Wonder why just not one field:
> union {
> uint8_t u8[16];
> ...
> uint64_t u64[2];
> } dyn_field1;
> ?
> Probably would be a bit handy, to refer, register, etc. no?
I didn't find any place where we need an access through u8, so I
just changed it into uint64_t dynfield1[2].
>
> > } __rte_cache_aligned;
> >
> > /**
> > @@ -1684,6 +1689,21 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> > */
> > #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
> >
> > +/**
> > + * Copy dynamic fields from m_src to m_dst.
> > + *
> > + * @param m_dst
> > + * The destination mbuf.
> > + * @param m_src
> > + * The source mbuf.
> > + */
> > +static inline void
> > +rte_mbuf_dynfield_copy(struct rte_mbuf *m_dst, const struct rte_mbuf *m_src)
> > +{
> > + m_dst->dynfield1 = m_src->dynfield1;
> > + m_dst->dynfield2 = m_src->dynfield2;
> > +}
> > +
> > /**
> > * Attach packet mbuf to another packet mbuf.
> > *
> > @@ -1732,6 +1752,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
> > mi->vlan_tci_outer = m->vlan_tci_outer;
> > mi->tx_offload = m->tx_offload;
> > mi->hash = m->hash;
> > + rte_mbuf_dynfield_copy(mi, m);
> >
> > mi->next = NULL;
> > mi->pkt_len = mi->data_len;
> > diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> > new file mode 100644
> > index 000000000..13b8742d0
> > --- /dev/null
> > +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> > @@ -0,0 +1,408 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2019 6WIND S.A.
> > + */
> > +
> > +#include <sys/queue.h>
> > +
> > +#include <rte_common.h>
> > +#include <rte_eal.h>
> > +#include <rte_eal_memconfig.h>
> > +#include <rte_tailq.h>
> > +#include <rte_errno.h>
> > +#include <rte_malloc.h>
> > +#include <rte_string_fns.h>
> > +#include <rte_mbuf.h>
> > +#include <rte_mbuf_dyn.h>
> > +
> > +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> > +
> > +struct mbuf_dynfield_elt {
> > + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> > + struct rte_mbuf_dynfield params;
> > + int offset;
>
> Why not 'size_t offset', to avoid any explicit conversions, etc?
Fixed
> > +};
> > +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> > +
> > +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> > + .name = "RTE_MBUF_DYNFIELD",
> > +};
> > +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> > +
> > +struct mbuf_dynflag_elt {
> > + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> > + struct rte_mbuf_dynflag params;
> > + int bitnum;
> > +};
> > +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> > +
> > +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> > + .name = "RTE_MBUF_DYNFLAG",
> > +};
> > +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> > +
> > +struct mbuf_dyn_shm {
> > + /** For each mbuf byte, free_space[i] == 1 if space is free. */
> > + uint8_t free_space[sizeof(struct rte_mbuf)];
> > + /** Bitfield of available flags. */
> > + uint64_t free_flags;
> > +};
> > +static struct mbuf_dyn_shm *shm;
> > +
> > +/* allocate and initialize the shared memory */
> > +static int
> > +init_shared_mem(void)
> > +{
> > + const struct rte_memzone *mz;
> > + uint64_t mask;
> > +
> > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> > + sizeof(struct mbuf_dyn_shm),
> > + SOCKET_ID_ANY, 0,
> > + RTE_CACHE_LINE_SIZE);
> > + } else {
> > + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> > + }
> > + if (mz == NULL)
> > + return -1;
> > +
> > + shm = mz->addr;
> > +
> > +#define mark_free(field) \
> > + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> > + 0xff, sizeof(((struct rte_mbuf *)0)->field))
>
> I think you can avoid defining/unedifying macros here by something like that:
>
> static const struct {
> size_t offset;
> size_t size;
> } dyn_syms[] = {
> [0] = {.offset = offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
> [1] = {.offset = offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
> };
> ...
>
> for (i = 0; i != RTE_DIM(dyn_syms); i++)
> memset(shm->free_space + dym_syms[i].offset, UINT8_MAX, dym_syms[i].size);
>
I tried it, but the following lines are too long
[0] = {offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
[1] = {offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
To make them shorter, we can use a macro... but... wait :)
> > +
> > + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> > + /* init free_space, keep it sync'd with
> > + * rte_mbuf_dynfield_copy().
> > + */
> > + memset(shm, 0, sizeof(*shm));
> > + mark_free(dynfield1);
> > + mark_free(dynfield2);
> > +
> > + /* init free_flags */
> > + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> > + shm->free_flags |= mask;
> > + }
> > +#undef mark_free
> > +
> > + return 0;
> > +}
> > +
> > +/* check if this offset can be used */
> > +static int
> > +check_offset(size_t offset, size_t size, size_t align, unsigned int flags)
> > +{
> > + size_t i;
> > +
> > + (void)flags;
>
>
> We have RTE_SET_USED() for such cases...
> Though as it is an internal function probably better not to introduce
> unused parameters at all.
I removed the flag parameter as you suggested.
> > +
> > + if ((offset & (align - 1)) != 0)
> > + return -1;
> > + if (offset + size > sizeof(struct rte_mbuf))
> > + return -1;
> > +
> > + for (i = 0; i < size; i++) {
> > + if (!shm->free_space[i + offset])
> > + return -1;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +/* assume tailq is locked */
> > +static struct mbuf_dynfield_elt *
> > +__mbuf_dynfield_lookup(const char *name)
> > +{
> > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > + struct rte_tailq_entry *te;
> > +
> > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > +
> > + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> > + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> > + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> > + break;
> > + }
> > +
> > + if (te == NULL) {
> > + rte_errno = ENOENT;
> > + return NULL;
> > + }
> > +
> > + return mbuf_dynfield;
> > +}
> > +
> > +int
> > +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> > +{
> > + struct mbuf_dynfield_elt *mbuf_dynfield;
> > +
> > + if (shm == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_read_lock();
> > + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> > + rte_mcfg_tailq_read_unlock();
> > +
> > + if (mbuf_dynfield == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + if (params != NULL)
> > + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> > +
> > + return mbuf_dynfield->offset;
> > +}
> > +
> > +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> > + const struct rte_mbuf_dynfield *params2)
> > +{
> > + if (strcmp(params1->name, params2->name))
> > + return -1;
> > + if (params1->size != params2->size)
> > + return -1;
> > + if (params1->align != params2->align)
> > + return -1;
> > + if (params1->flags != params2->flags)
> > + return -1;
> > + return 0;
> > +}
> > +
> > +int
> > +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
>
> What I meant at user-space - if we can also have another function that would allow
> user to specify required offset for dynfield explicitly, then user can define it as constant
> value and let compiler do optimization work and hopefully generate faster code to access
> this field.
> Something like that:
>
> int rte_mbuf_dynfiled_register_offset(const struct rte_mbuf_dynfield *params, size_t offset);
>
> #define RTE_MBUF_DYNFIELD_OFFSET(fld, off) (offsetof(struct rte_mbuf, fld) + (off))
>
> And then somewhere in user code:
>
> /* to let say reserve first 4B in dynfield1*/
> #define MBUF_DYNFIELD_A RTE_MBUF_DYNFIELD_OFFSET(dynfiled1, 0)
> ...
> params.name = RTE_STR(MBUF_DYNFIELD_A);
> params.size = sizeof(uint32_t);
> params.align = sizeof(uint32_t);
> ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_A);
> if (ret != MBUF_DYNFIELD_A) {
> /* handle it somehow, probably just terminate gracefully... */
> }
> ...
>
> /* to let say reserve last 2B in dynfield2*/
> #define MBUF_DYNFIELD_B RTE_MBUF_DYNFIELD_OFFSET(dynfiled2, 6)
> ...
> params.name = RTE_STR(MBUF_DYNFIELD_B);
> params.size = sizeof(uint16_t);
> params.align = sizeof(uint16_t);
> ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_B);
>
> After that user can use constant offsets MBUF_DYNFIELD_A/ MBUF_DYNFIELD_B
> to access these fields.
> Same thoughts for DYNFLAG.
I added the feature in v2.
> > + struct mbuf_dynfield_list *mbuf_dynfield_list;
> > + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> > + struct rte_tailq_entry *te = NULL;
> > + int offset, ret;
>
> size_t offset
> to avoid explicit conversions, etc.?
>
Fixed.
> > + size_t i;
> > +
> > + if (shm == NULL && init_shared_mem() < 0)
> > + goto fail;
>
> As I understand, here you allocate/initialize your shm without any lock protection,
> though later you protect it via rte_mcfg_tailq_write_lock().
> That seems a bit flakey to me.
> Why not to store information about free dynfield bytes inside mbuf_dynfield_tailq?
> Let say at init() create and add an entry into that list with some reserved name.
> Then at register - grab mcfg_tailq_write_lock and do lookup
> for such entry and then read/update it as needed.
> It would help to avoid racing problem, plus you wouldn't need to
> allocate/lookup for memzone.
I don't quite like the idea of having a special entry with a different type
in an element list. Despite it is simpler for a locking perspective, it is
less obvious for the developper.
Also, I changed the way a zone is reserved to return the one that have the
less impact on next reservation, and I feel it is easier to implement with
the shared memory.
So, I just moved the init_shared_mem() inside the rte_mcfg_tailq_write_lock(),
it should do the job.
> > + if (params->size >= sizeof(struct rte_mbuf)) {
> > + rte_errno = EINVAL;
> > + goto fail;
> > + }
> > + if (!rte_is_power_of_2(params->align)) {
> > + rte_errno = EINVAL;
> > + goto fail;
> > + }
> > + if (params->flags != 0) {
> > + rte_errno = EINVAL;
> > + goto fail;
> > + }
> > +
> > + rte_mcfg_tailq_write_lock();
> > +
>
> I think it probably would be cleaner and easier to read/maintain, if you'll put actual
> code under lock protection into a separate function - as you did for __mbuf_dynfield_lookup().
Yes, I did that, it should be clearer now.
> > + mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
> > + if (mbuf_dynfield != NULL) {
> > + if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) < 0) {
> > + rte_errno = EEXIST;
> > + goto fail_unlock;
> > + }
> > + offset = mbuf_dynfield->offset;
> > + goto out_unlock;
> > + }
> > +
> > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > + rte_errno = EPERM;
> > + goto fail_unlock;
> > + }
> > +
> > + for (offset = 0;
> > + offset < (int)sizeof(struct rte_mbuf);
> > + offset++) {
> > + if (check_offset(offset, params->size, params->align,
> > + params->flags) == 0)
> > + break;
> > + }
> > +
> > + if (offset == sizeof(struct rte_mbuf)) {
> > + rte_errno = ENOENT;
> > + goto fail_unlock;
> > + }
> > +
> > + mbuf_dynfield_list = RTE_TAILQ_CAST(
> > + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> > +
> > + te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> > + if (te == NULL)
> > + goto fail_unlock;
> > +
> > + mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
> > + if (mbuf_dynfield == NULL)
> > + goto fail_unlock;
> > +
> > + ret = strlcpy(mbuf_dynfield->params.name, params->name,
> > + sizeof(mbuf_dynfield->params.name));
> > + if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
> > + rte_errno = ENAMETOOLONG;
> > + goto fail_unlock;
> > + }
> > + memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield->params));
> > + mbuf_dynfield->offset = offset;
> > + te->data = mbuf_dynfield;
> > +
> > + TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> > +
> > + for (i = offset; i < offset + params->size; i++)
> > + shm->free_space[i] = 0;
> > +
> > + RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu, al=%zu, fl=0x%x) -> %d\n",
> > + params->name, params->size, params->align, params->flags,
> > + offset);
> > +
> > +out_unlock:
> > + rte_mcfg_tailq_write_unlock();
> > +
> > + return offset;
> > +
> > +fail_unlock:
> > + rte_mcfg_tailq_write_unlock();
> > +fail:
> > + rte_free(mbuf_dynfield);
> > + rte_free(te);
> > + return -1;
> > +}
> > +
> > +/* assume tailq is locked */
> > +static struct mbuf_dynflag_elt *
> > +__mbuf_dynflag_lookup(const char *name)
> > +{
> > + struct mbuf_dynflag_list *mbuf_dynflag_list;
> > + struct mbuf_dynflag_elt *mbuf_dynflag;
> > + struct rte_tailq_entry *te;
> > +
> > + mbuf_dynflag_list = RTE_TAILQ_CAST(
> > + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> > +
> > + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> > + mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
> > + if (strncmp(name, mbuf_dynflag->params.name,
> > + RTE_MBUF_DYN_NAMESIZE) == 0)
> > + break;
> > + }
> > +
> > + if (te == NULL) {
> > + rte_errno = ENOENT;
> > + return NULL;
> > + }
> > +
> > + return mbuf_dynflag;
> > +}
> > +
> > +int
> > +rte_mbuf_dynflag_lookup(const char *name,
> > + struct rte_mbuf_dynflag *params)
> > +{
> > + struct mbuf_dynflag_elt *mbuf_dynflag;
> > +
> > + if (shm == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + rte_mcfg_tailq_read_lock();
> > + mbuf_dynflag = __mbuf_dynflag_lookup(name);
> > + rte_mcfg_tailq_read_unlock();
> > +
> > + if (mbuf_dynflag == NULL) {
> > + rte_errno = ENOENT;
> > + return -1;
> > + }
> > +
> > + if (params != NULL)
> > + memcpy(params, &mbuf_dynflag->params, sizeof(*params));
> > +
> > + return mbuf_dynflag->bitnum;
> > +}
> > +
> > +static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
> > + const struct rte_mbuf_dynflag *params2)
> > +{
> > + if (strcmp(params1->name, params2->name))
> > + return -1;
> > + if (params1->flags != params2->flags)
> > + return -1;
> > + return 0;
> > +}
> > +
> > +int
> > +rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params)
> > +{
> > + struct mbuf_dynflag_list *mbuf_dynflag_list;
> > + struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
> > + struct rte_tailq_entry *te = NULL;
> > + int bitnum, ret;
> > +
> > + if (shm == NULL && init_shared_mem() < 0)
> > + goto fail;
> > +
> > + rte_mcfg_tailq_write_lock();
> > +
> > + mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
> > + if (mbuf_dynflag != NULL) {
> > + if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) < 0) {
> > + rte_errno = EEXIST;
> > + goto fail_unlock;
> > + }
> > + bitnum = mbuf_dynflag->bitnum;
> > + goto out_unlock;
> > + }
> > +
> > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > + rte_errno = EPERM;
> > + goto fail_unlock;
> > + }
> > +
> > + if (shm->free_flags == 0) {
> > + rte_errno = ENOENT;
> > + goto fail_unlock;
> > + }
> > + bitnum = rte_bsf64(shm->free_flags);
> > +
> > + mbuf_dynflag_list = RTE_TAILQ_CAST(
> > + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> > +
> > + te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> > + if (te == NULL)
> > + goto fail_unlock;
> > +
> > + mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
> > + if (mbuf_dynflag == NULL)
> > + goto fail_unlock;
> > +
> > + ret = strlcpy(mbuf_dynflag->params.name, params->name,
> > + sizeof(mbuf_dynflag->params.name));
> > + if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
> > + rte_errno = ENAMETOOLONG;
> > + goto fail_unlock;
> > + }
> > + mbuf_dynflag->bitnum = bitnum;
> > + te->data = mbuf_dynflag;
> > +
> > + TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> > +
> > + shm->free_flags &= ~(1ULL << bitnum);
> > +
> > + RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) -> %u\n",
> > + params->name, params->flags, bitnum);
> > +
> > +out_unlock:
> > + rte_mcfg_tailq_write_unlock();
> > +
> > + return bitnum;
> > +
> > +fail_unlock:
> > + rte_mcfg_tailq_write_unlock();
> > +fail:
> > + rte_free(mbuf_dynflag);
> > + rte_free(te);
> > + return -1;
> > +}
> > diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h b/lib/librte_mbuf/rte_mbuf_dyn.h
> > new file mode 100644
> > index 000000000..6e2c81654
> > --- /dev/null
> > +++ b/lib/librte_mbuf/rte_mbuf_dyn.h
> > @@ -0,0 +1,163 @@
> > +/* SPDX-License-Identifier: BSD-3-Clause
> > + * Copyright 2019 6WIND S.A.
> > + */
> > +
> > +#ifndef _RTE_MBUF_DYN_H_
> > +#define _RTE_MBUF_DYN_H_
> > +
> > +/**
> > + * @file
> > + * RTE Mbuf dynamic fields and flags
> > + *
> > + * Many features require to store data inside the mbuf. As the room in
> > + * mbuf structure is limited, it is not possible to have a field for
> > + * each feature. Also, changing fields in the mbuf structure can break
> > + * the API or ABI.
> > + *
> > + * This module addresses this issue, by enabling the dynamic
> > + * registration of fields or flags:
> > + *
> > + * - a dynamic field is a named area in the rte_mbuf structure, with a
> > + * given size (>= 1 byte) and alignment constraint.
> > + * - a dynamic flag is a named bit in the rte_mbuf structure, stored
> > + * in mbuf->ol_flags.
> > + *
> > + * The typical use case is when a specific offload feature requires to
> > + * register a dedicated offload field in the mbuf structure, and adding
> > + * a static field or flag is not justified.
> > + *
> > + * Example of use:
> > + *
> > + * - A rte_mbuf_dynfield structure is defined, containing the parameters
> > + * of the dynamic field to be registered:
> > + * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
> > + * - The application initializes the PMD, and asks for this feature
> > + * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
> > + * rxconf. This will make the PMD to register the field by calling
> > + * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
> > + * stores the returned offset.
> > + * - The application that uses the offload feature also registers
> > + * the field to retrieve the same offset.
> > + * - When the PMD receives a packet, it can set the field:
> > + * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
> > + * - In the main loop, the application can retrieve the value with
> > + * the same macro.
> > + *
> > + * To avoid wasting space, the dynamic fields or flags must only be
> > + * reserved on demand, when an application asks for the related feature.
> > + *
> > + * The registration can be done at any moment, but it is not possible
> > + * to unregister fields or flags for now.
> > + *
> > + * A dynamic field can be reserved and used by an application only.
> > + * It can for instance be a packet mark.
> > + */
> > +
> > +#include <sys/types.h>
> > +/**
> > + * Maximum length of the dynamic field or flag string.
> > + */
> > +#define RTE_MBUF_DYN_NAMESIZE 64
> > +
> > +/**
> > + * Structure describing the parameters of a mbuf dynamic field.
> > + */
> > +struct rte_mbuf_dynfield {
> > + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
> > + size_t size; /**< The number of bytes to reserve. */
> > + size_t align; /**< The alignment constraint (power of 2). */
> > + unsigned int flags; /**< Reserved for future use, must be 0. */
> > +};
> > +
> > +/**
> > + * Structure describing the parameters of a mbuf dynamic flag.
> > + */
> > +struct rte_mbuf_dynflag {
> > + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */
> > + unsigned int flags; /**< Reserved for future use, must be 0. */
> > +};
> > +
> > +/**
> > + * Register space for a dynamic field in the mbuf structure.
> > + *
> > + * If the field is already registered (same name and parameters), its
> > + * offset is returned.
> > + *
> > + * @param params
> > + * A structure containing the requested parameters (name, size,
> > + * alignment constraint and flags).
> > + * @return
> > + * The offset in the mbuf structure, or -1 on error.
> > + * Possible values for rte_errno:
> > + * - EINVAL: invalid parameters (size, align, or flags).
> > + * - EEXIST: this name is already register with different parameters.
> > + * - EPERM: called from a secondary process.
> > + * - ENOENT: not enough room in mbuf.
> > + * - ENOMEM: allocation failure.
> > + * - ENAMETOOLONG: name does not ends with \0.
> > + */
> > +__rte_experimental
> > +int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
> > +
> > +/**
> > + * Lookup for a registered dynamic mbuf field.
> > + *
> > + * @param name
> > + * A string identifying the dynamic field.
> > + * @param params
> > + * If not NULL, and if the lookup is successful, the structure is
> > + * filled with the parameters of the dynamic field.
> > + * @return
> > + * The offset of this field in the mbuf structure, or -1 on error.
> > + * Possible values for rte_errno:
> > + * - ENOENT: no dynamic field matches this name.
> > + */
> > +__rte_experimental
> > +int rte_mbuf_dynfield_lookup(const char *name,
> > + struct rte_mbuf_dynfield *params);
> > +
> > +/**
> > + * Register a dynamic flag in the mbuf structure.
> > + *
> > + * If the flag is already registered (same name and parameters), its
> > + * offset is returned.
> > + *
> > + * @param params
> > + * A structure containing the requested parameters of the dynamic
> > + * flag (name and options).
> > + * @return
> > + * The number of the reserved bit, or -1 on error.
> > + * Possible values for rte_errno:
> > + * - EINVAL: invalid parameters (size, align, or flags).
> > + * - EEXIST: this name is already register with different parameters.
> > + * - EPERM: called from a secondary process.
> > + * - ENOENT: no more flag available.
> > + * - ENOMEM: allocation failure.
> > + * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
> > + */
> > +__rte_experimental
> > +int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
> > +
> > +/**
> > + * Lookup for a registered dynamic mbuf flag.
> > + *
> > + * @param name
> > + * A string identifying the dynamic flag.
> > + * @param params
> > + * If not NULL, and if the lookup is successful, the structure is
> > + * filled with the parameters of the dynamic flag.
> > + * @return
> > + * The offset of this flag in the mbuf structure, or -1 on error.
> > + * Possible values for rte_errno:
> > + * - ENOENT: no dynamic flag matches this name.
> > + */
> > +__rte_experimental
> > +int rte_mbuf_dynflag_lookup(const char *name,
> > + struct rte_mbuf_dynflag *params);
> > +
> > +/**
> > + * Helper macro to access to a dynamic field.
> > + */
> > +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> > +
> > +#endif
> > diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
> > index 2662a37bf..a98310570 100644
> > --- a/lib/librte_mbuf/rte_mbuf_version.map
> > +++ b/lib/librte_mbuf/rte_mbuf_version.map
> > @@ -50,4 +50,8 @@ EXPERIMENTAL {
> > global:
> >
> > rte_mbuf_check;
> > + rte_mbuf_dynfield_lookup;
> > + rte_mbuf_dynfield_register;
> > + rte_mbuf_dynflag_lookup;
> > + rte_mbuf_dynflag_register;
> > } DPDK_18.08;
> > --
> > 2.20.1
>
I will send a v2 shortly, thanks
Olivier
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 00/13] vhost packed ring performance optimization
2019-10-17 7:31 0% ` Maxime Coquelin
@ 2019-10-17 7:32 0% ` Liu, Yong
0 siblings, 0 replies; 200+ results
From: Liu, Yong @ 2019-10-17 7:32 UTC (permalink / raw)
To: Maxime Coquelin, Bie, Tiwei, Wang, Zhihong, stephen, gavin.hu; +Cc: dev
> -----Original Message-----
> From: Maxime Coquelin [mailto:maxime.coquelin@redhat.com]
> Sent: Thursday, October 17, 2019 3:31 PM
> To: Liu, Yong <yong.liu@intel.com>; Bie, Tiwei <tiwei.bie@intel.com>; Wang,
> Zhihong <zhihong.wang@intel.com>; stephen@networkplumber.org;
> gavin.hu@arm.com
> Cc: dev@dpdk.org
> Subject: Re: [PATCH v6 00/13] vhost packed ring performance optimization
>
> Hi Marvin,
>
> This is almost good, just fix the small comments I made.
>
> Also, please rebase on top of next-virtio branch, because I applied
> below patch from Flavio that you need to take into account:
>
> http://patches.dpdk.org/patch/61284/
Thanks, Maxime. I will start rebasing work.
>
> Regards,
> Maxime
>
> On 10/15/19 6:07 PM, Marvin Liu wrote:
> > Packed ring has more compact ring format and thus can significantly
> > reduce the number of cache miss. It can lead to better performance.
> > This has been approved in virtio user driver, on normal E5 Xeon cpu
> > single core performance can raise 12%.
> >
> > http://mails.dpdk.org/archives/dev/2018-April/095470.html
> >
> > However vhost performance with packed ring performance was decreased.
> > Through analysis, mostly extra cost was from the calculating of each
> > descriptor flag which depended on ring wrap counter. Moreover, both
> > frontend and backend need to write same descriptors which will cause
> > cache contention. Especially when doing vhost enqueue function, virtio
> > refill packed ring function may write same cache line when vhost doing
> > enqueue function. This kind of extra cache cost will reduce the benefit
> > of reducing cache misses.
> >
> > For optimizing vhost packed ring performance, vhost enqueue and dequeue
> > function will be splitted into fast and normal path.
> >
> > Several methods will be taken in fast path:
> > Handle descriptors in one cache line by batch.
> > Split loop function into more pieces and unroll them.
> > Prerequisite check that whether I/O space can copy directly into mbuf
> > space and vice versa.
> > Prerequisite check that whether descriptor mapping is successful.
> > Distinguish vhost used ring update function by enqueue and dequeue
> > function.
> > Buffer dequeue used descriptors as many as possible.
> > Update enqueue used descriptors by cache line.
> >
> > After all these methods done, single core vhost PvP performance with 64B
> > packet on Xeon 8180 can boost 35%.
> >
> > v6:
> > - Fix dequeue zcopy result check
> >
> > v5:
> > - Remove disable sw prefetch as performance impact is small
> > - Change unroll pragma macro format
> > - Rename shadow counter elements names
> > - Clean dequeue update check condition
> > - Add inline functions replace of duplicated code
> > - Unify code style
> >
> > v4:
> > - Support meson build
> > - Remove memory region cache for no clear performance gain and ABI break
> > - Not assume ring size is power of two
> >
> > v3:
> > - Check available index overflow
> > - Remove dequeue remained descs number check
> > - Remove changes in split ring datapath
> > - Call memory write barriers once when updating used flags
> > - Rename some functions and macros
> > - Code style optimization
> >
> > v2:
> > - Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
> > - Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
> > - Optimize dequeue used ring update when in_order negotiated
> >
> >
> > Marvin Liu (13):
> > vhost: add packed ring indexes increasing function
> > vhost: add packed ring single enqueue
> > vhost: try to unroll for each loop
> > vhost: add packed ring batch enqueue
> > vhost: add packed ring single dequeue
> > vhost: add packed ring batch dequeue
> > vhost: flush enqueue updates by batch
> > vhost: flush batched enqueue descs directly
> > vhost: buffer packed ring dequeue updates
> > vhost: optimize packed ring enqueue
> > vhost: add packed ring zcopy batch and single dequeue
> > vhost: optimize packed ring dequeue
> > vhost: optimize packed ring dequeue when in-order
> >
> > lib/librte_vhost/Makefile | 18 +
> > lib/librte_vhost/meson.build | 7 +
> > lib/librte_vhost/vhost.h | 57 +++
> > lib/librte_vhost/virtio_net.c | 924 +++++++++++++++++++++++++++-------
> > 4 files changed, 812 insertions(+), 194 deletions(-)
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 00/13] vhost packed ring performance optimization
2019-10-15 16:07 3% ` [dpdk-dev] [PATCH v6 " Marvin Liu
@ 2019-10-17 7:31 0% ` Maxime Coquelin
2019-10-17 7:32 0% ` Liu, Yong
2019-10-21 15:40 3% ` [dpdk-dev] [PATCH v7 " Marvin Liu
1 sibling, 1 reply; 200+ results
From: Maxime Coquelin @ 2019-10-17 7:31 UTC (permalink / raw)
To: Marvin Liu, tiwei.bie, zhihong.wang, stephen, gavin.hu; +Cc: dev
Hi Marvin,
This is almost good, just fix the small comments I made.
Also, please rebase on top of next-virtio branch, because I applied
below patch from Flavio that you need to take into account:
http://patches.dpdk.org/patch/61284/
Regards,
Maxime
On 10/15/19 6:07 PM, Marvin Liu wrote:
> Packed ring has more compact ring format and thus can significantly
> reduce the number of cache miss. It can lead to better performance.
> This has been approved in virtio user driver, on normal E5 Xeon cpu
> single core performance can raise 12%.
>
> http://mails.dpdk.org/archives/dev/2018-April/095470.html
>
> However vhost performance with packed ring performance was decreased.
> Through analysis, mostly extra cost was from the calculating of each
> descriptor flag which depended on ring wrap counter. Moreover, both
> frontend and backend need to write same descriptors which will cause
> cache contention. Especially when doing vhost enqueue function, virtio
> refill packed ring function may write same cache line when vhost doing
> enqueue function. This kind of extra cache cost will reduce the benefit
> of reducing cache misses.
>
> For optimizing vhost packed ring performance, vhost enqueue and dequeue
> function will be splitted into fast and normal path.
>
> Several methods will be taken in fast path:
> Handle descriptors in one cache line by batch.
> Split loop function into more pieces and unroll them.
> Prerequisite check that whether I/O space can copy directly into mbuf
> space and vice versa.
> Prerequisite check that whether descriptor mapping is successful.
> Distinguish vhost used ring update function by enqueue and dequeue
> function.
> Buffer dequeue used descriptors as many as possible.
> Update enqueue used descriptors by cache line.
>
> After all these methods done, single core vhost PvP performance with 64B
> packet on Xeon 8180 can boost 35%.
>
> v6:
> - Fix dequeue zcopy result check
>
> v5:
> - Remove disable sw prefetch as performance impact is small
> - Change unroll pragma macro format
> - Rename shadow counter elements names
> - Clean dequeue update check condition
> - Add inline functions replace of duplicated code
> - Unify code style
>
> v4:
> - Support meson build
> - Remove memory region cache for no clear performance gain and ABI break
> - Not assume ring size is power of two
>
> v3:
> - Check available index overflow
> - Remove dequeue remained descs number check
> - Remove changes in split ring datapath
> - Call memory write barriers once when updating used flags
> - Rename some functions and macros
> - Code style optimization
>
> v2:
> - Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
> - Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
> - Optimize dequeue used ring update when in_order negotiated
>
>
> Marvin Liu (13):
> vhost: add packed ring indexes increasing function
> vhost: add packed ring single enqueue
> vhost: try to unroll for each loop
> vhost: add packed ring batch enqueue
> vhost: add packed ring single dequeue
> vhost: add packed ring batch dequeue
> vhost: flush enqueue updates by batch
> vhost: flush batched enqueue descs directly
> vhost: buffer packed ring dequeue updates
> vhost: optimize packed ring enqueue
> vhost: add packed ring zcopy batch and single dequeue
> vhost: optimize packed ring dequeue
> vhost: optimize packed ring dequeue when in-order
>
> lib/librte_vhost/Makefile | 18 +
> lib/librte_vhost/meson.build | 7 +
> lib/librte_vhost/vhost.h | 57 +++
> lib/librte_vhost/virtio_net.c | 924 +++++++++++++++++++++++++++-------
> 4 files changed, 812 insertions(+), 194 deletions(-)
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-11 13:23 0% ` Akhil Goyal
2019-10-13 23:07 0% ` Zhang, Roy Fan
@ 2019-10-16 22:07 3% ` Ananyev, Konstantin
2019-10-17 12:49 0% ` Ananyev, Konstantin
2019-10-18 13:17 4% ` Akhil Goyal
1 sibling, 2 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-16 22:07 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph'
Hi Akhil,
> > > User can use the same session, that is what I am also insisting, but it may have
> > separate
> > > Session private data. Cryptodev session create API provide that functionality
> > and we can
> > > Leverage that.
> >
> > rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means
> > we can't use
> > the same rte_cryptodev_sym_session to hold sessions for both sync and async
> > mode
> > for the same device. Off course we can add a hard requirement that any driver
> > that wants to
> > support process() has to create sessions that can handle both process and
> > enqueue/dequeue,
> > but then again what for to create such overhead?
> >
> > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > construct for multiple device_ids:
> > __extension__ struct {
> > void *data;
> > uint16_t refcnt;
> > } sess_data[0];
> > /**< Driver specific session material, variable size */
> >
> Yes I also feel the same. I was also not in favor of this when it was introduced.
> Please go ahead and remove this. I have no issues with that.
If you are not happy with that structure, and admit there are issues with it,
why do you push for reusing it for cpu-crypto API?
Why not to take step back, take into account current drawbacks
and define something that (hopefully) would suite us better?
Again new API will be experimental for some time, so we'll
have some opportunity to see does it works and if not fix it.
About removing data[] from existing rte_cryptodev_sym_session -
Personally would like to do that, but the change seems to be too massive.
Definitely not ready for such effort right now.
>
> > as an advantage.
> > It looks too error prone for me:
> > 1. Simultaneous session initialization/de-initialization for devices with the same
> > driver_id is not possible.
> > 2. It assumes that all device driver will be loaded before we start to create
> > session pools.
> >
> > Right now it seems ok, as no-one requires such functionality, but I don't know
> > how it will be in future.
> > For me rte_security session model, where for each security context user have to
> > create new session
> > looks much more robust.
> Agreed
>
> >
> > >
> > > BTW, I can see a v2 to this RFC which is still based on security library.
> >
> > Yes, v2 was concentrated on fixing found issues, some code restructuring,
> > i.e. - changes that would be needed anyway whatever API aproach we'll choose.
> >
> > > When do you plan
> > > To submit the patches for crypto based APIs. We have RC1 merge deadline for
> > this
> > > patchset on 21st Oct.
> >
> > We'd like to start working on it ASAP, but it seems we still have a major
> > disagreement
> > about how this crypto-dev API should look like.
> > Which makes me think - should we return to our original proposal via
> > rte_security?
> > It still looks to me like clean and straightforward way to enable this new API,
> > and probably wouldn't cause that much controversy.
> > What do you think?
>
> I cannot spend more time discussing on this until RC1 date. I have some other stuff pending.
> You can send the patches early next week with the approach that I mentioned or else we
> can discuss this post RC1(which would mean deferring to 20.02).
>
> But moving back to security is not acceptable to me. The code should be put where it is
> intended and not where it is easy to put. You are not doing any rte_security stuff.
>
Ok, then my suggestion:
Let's at least write down all points about crypto-dev approach where we
disagree and then probably try to resolve them one by one....
If we fail to make an agreement/progress in next week or so,
(and no more reviews from the community)
will have bring that subject to TB meeting to decide.
Sounds fair to you?
List is below.
Please add/correct me, if I missed something.
Konstantin
1. extra input parameters to create/init rte_(cpu)_sym_session.
Will leverage existing 6B gap inside rte_crypto_*_xform between 'algo' and 'key' fields.
New fields will be optional and would be used by PMD only when cpu-crypto session is requested.
For lksd-crypto session PMD is free to ignore these fields.
No ABI breakage is required.
Hopefully no controversy here with #1.
2. cpu-crypto create/init.
a) Our suggestion - introduce new API for that:
- rte_crypto_cpu_sym_init() that would init completely opaque rte_crypto_cpu_sym_session.
- struct rte_crypto_cpu_sym_session_ops {(*process)(...); (*clear); /*whatever else we'll need *'};
- rte_crypto_cpu_sym_get_ops(const struct rte_crypto_sym_xform *xforms)
that would return const struct rte_crypto_cpu_sym_session_ops *based on input xforms.
Advantages:
1) totally opaque data structure (no ABI breakages in future), PMD writer is totally free
with it format and contents.
2) each session entity is self-contained, user doesn't need to bring along dev_id etc.
dev_id is needed only at init stage, after that user will use session ops to perform
all operations on that session (process(), clear(), etc.).
3) User can decide does he wants to store ops[] pointer on a per session basis,
or on a per group of same sessions, or...
4) No mandatory mempools for private sessions. User can allocate memory for cpu-crypto
session whenever he likes.
Disadvantages:
5) Extra changes in control path
6) User has to store session_ops pointer explicitly.
b) Your suggestion - reuse existing rte_cryptodev_sym_session_init() and existing rte_cryptodev_sym_session
structure.
Advantages:
1) allows to reuse same struct and init/create/clear() functions.
Probably less changes in control path.
Disadvantages:
2) rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means that
we can't use the same rte_cryptodev_sym_session to hold private sessions pointers
for both sync and async mode for the same device.
So wthe only option we have - make PMD devops->sym_session_configure()
always create a session that can work in both cpu and lksd modes.
For some implementations that would probably mean that under the hood PMD would create
2 different session structs (sync/async) and then use one or another depending on from what API been called.
Seems doable, but ...:
- will contradict with statement from 1:
" New fields will be optional and would be used by PMD only when cpu-crypto session is requested."
Now it becomes mandatory for all apps to specify cpu-crypto related parameters too,
even if they don't plan to use that mode - i.e. behavior change, existing app change.
- might cause extra space overhead.
3) not possible to store device (not driver) specific data within the session, but I think it is not really needed right now.
So probably minor compared to 2.b.2.
Actually #3 follows from #2, but decided to have them separated.
3. process() parameters/behavior
a) Our suggestion: user stores ptr to session ops (or to (*process) itself) and just does:
session_ops->process(sess, ...);
Advantages:
1) fastest possible execution path
2) no need to carry on dev_id for data-path
Disadvantages:
3) user has to carry on session_ops pointer explicitly
b) Your suggestion: add (*cpu_process) inside rte_cryptodev_ops and then:
rte_crypto_cpu_sym_process(uint8_t dev_id, rte_cryptodev_sym_session *sess, /*data parameters*/) {...
rte_cryptodevs[dev_id].dev_ops->cpu_process(ses, ...);
/*and then inside PMD specifc process: */
pmd_private_session = sess->sess_data[this_pmd_driver_id].data;
/* and then most likely either */
pmd_private_session->process(pmd_private_session, ...);
/* or jump based on session/input data */
Advantages:
1) don't see any...
Disadvantages:
2) User has to carry on dev_id inside data-path
3) Extra level of indirection (plus data dependency) - both for data and instructions.
Possible slowdown compared to a) (not measured).
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3 8/9] build: change ABI version to 20.0
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (7 preceding siblings ...)
2019-10-16 17:03 3% ` [dpdk-dev] [PATCH v3 7/9] drivers/octeontx: add missing public symbol Anatoly Burakov
@ 2019-10-16 17:03 2% ` Anatoly Burakov
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 9/9] buildtools: add ABI versioning check script Anatoly Burakov
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Pawel Modrak, Nicolas Chautru, Hemant Agrawal, Sachin Saxena,
Rosen Xu, Stephen Hemminger, Anoob Joseph, Tomasz Duszynski,
Liron Himi, Jerin Jacob, Nithin Dabilpuram, Vamsi Attunuru,
Lee Daly, Fiona Trahe, Ashish Gupta, Sunila Sahu, Declan Doherty,
Pablo de Lara, Gagandeep Singh, Ravi Kumar, Akhil Goyal,
Michael Shamis, Nagadheeraj Rottela, Srikanth Jampala, Fan Zhang,
Jay Zhou, Nipun Gupta, Mattias Rönnblom, Pavan Nikhilesh,
Liang Ma, Peter Mccarthy, Harry van Haaren, Artem V. Andreev,
Andrew Rybchenko, Olivier Matz, Gage Eads, John W. Linville,
Xiaolong Ye, Qi Zhang, Shepard Siegel, Ed Czeck, John Miller,
Igor Russkikh, Pavel Belous, Allain Legacy, Matt Peters,
Rasesh Mody, Shahed Shaikh, Ajit Khaparde, Somnath Kotur,
Chas Williams, Rahul Lakkireddy, Wenzhuo Lu, Marcin Wojtas,
Michal Krawczyk, Guy Tzalik, Evgeny Schemeilin, Igor Chauskin,
John Daley, Hyong Youb Kim, Gaetan Rivet, Xiao Wang, Ziyang Xuan,
Xiaoyun Wang, Guoyang Zhou, Wei Hu (Xavier), Min Hu (Connor),
Yisen Zhuang, Beilei Xing, Jingjing Wu, Qiming Yang,
Konstantin Ananyev, Ferruh Yigit, Shijith Thotton,
Srisivasubramanian Srinivasan, Jakub Grajciar, Matan Azrad,
Shahaf Shuler, Viacheslav Ovsiienko, Zyta Szpak,
K. Y. Srinivasan, Haiyang Zhang, Rastislav Cernay, Jan Remes,
Alejandro Lucero, Tetsuya Mukawa, Kiran Kumar K,
Bruce Richardson, Jasvinder Singh, Cristian Dumitrescu,
Keith Wiles, Maciej Czekaj, Maxime Coquelin, Tiwei Bie,
Zhihong Wang, Yong Wang, Tianfei zhang, Xiaoyun Li, Satha Rao,
Shreyansh Jain, David Hunt, Byron Marohn, Yipeng Wang,
Thomas Monjalon, Bernard Iremonger, Jiayu Hu, Sameh Gobriel,
Reshma Pattan, Vladimir Medvedkin, Honnappa Nagarahalli,
Kevin Laatz, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Merge all vesions in linker version script files to DPDK_20.0.
This commit was generated by running the following command:
:~/DPDK$ buildtools/update-abi.sh 20.0
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Regenerate the commit using the new script
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +++----
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++++-----
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 6 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +--
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 ++--
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 ++--
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 ++----
.../rte_distributor_version.map | 2 +-
lib/librte_eal/rte_eal_version.map | 310 +++++++-----------
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +++------
lib/librte_eventdev/rte_eventdev_version.map | 130 +++-----
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +--
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm_version.map | 39 +--
lib/librte_mbuf/rte_mbuf_version.map | 41 +--
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +--
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +---
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +--
154 files changed, 721 insertions(+), 1399 deletions(-)
diff --git a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
index f64b0f9c27..6bcea2cc7f 100644
--- a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
+++ b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
@@ -1,10 +1,10 @@
-DPDK_19.08 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
EXPERIMENTAL {
- global:
+ global:
- fpga_lte_fec_configure;
+ fpga_lte_fec_configure;
};
diff --git a/drivers/baseband/null/rte_pmd_bbdev_null_version.map b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/null/rte_pmd_bbdev_null_version.map
+++ b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
+++ b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map
index a221522c23..9ab8c76eef 100644
--- a/drivers/bus/dpaa/rte_bus_dpaa_version.map
+++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
bman_acquire;
@@ -8,127 +8,94 @@ DPDK_17.11 {
bman_new_pool;
bman_query_free_buffers;
bman_release;
+ bman_thread_irq;
+ dpaa_logtype_eventdev;
dpaa_logtype_mempool;
dpaa_logtype_pmd;
dpaa_netcfg;
+ dpaa_svr_family;
fman_ccsr_map_fd;
fman_dealloc_bufs_mask_hi;
fman_dealloc_bufs_mask_lo;
fman_if_add_mac_addr;
fman_if_clear_mac_addr;
fman_if_disable_rx;
- fman_if_enable_rx;
fman_if_discard_rx_errors;
- fman_if_get_fc_threshold;
+ fman_if_enable_rx;
fman_if_get_fc_quanta;
+ fman_if_get_fc_threshold;
fman_if_get_fdoff;
+ fman_if_get_sg_enable;
fman_if_loopback_disable;
fman_if_loopback_enable;
fman_if_promiscuous_disable;
fman_if_promiscuous_enable;
fman_if_reset_mcast_filter_table;
fman_if_set_bp;
- fman_if_set_fc_threshold;
fman_if_set_fc_quanta;
+ fman_if_set_fc_threshold;
fman_if_set_fdoff;
fman_if_set_ic_params;
fman_if_set_maxfrm;
fman_if_set_mcast_filter_table;
+ fman_if_set_sg;
fman_if_stats_get;
fman_if_stats_get_all;
fman_if_stats_reset;
fman_ip_rev;
+ fsl_qman_fq_portal_create;
netcfg_acquire;
netcfg_release;
of_find_compatible_node;
+ of_get_mac_address;
of_get_property;
+ per_lcore_dpaa_io;
+ per_lcore_held_bufs;
qm_channel_caam;
+ qm_channel_pool1;
+ qman_alloc_cgrid_range;
+ qman_alloc_pool_range;
+ qman_clear_irq;
+ qman_create_cgr;
qman_create_fq;
+ qman_dca_index;
+ qman_delete_cgr;
qman_dequeue;
qman_dqrr_consume;
qman_enqueue;
qman_enqueue_multi;
+ qman_enqueue_multi_fq;
qman_fq_fqid;
+ qman_fq_portal_irqsource_add;
+ qman_fq_portal_irqsource_remove;
+ qman_fq_portal_thread_irq;
qman_fq_state;
qman_global_init;
qman_init_fq;
- qman_poll_dqrr;
- qman_query_fq_np;
- qman_set_vdq;
- qman_reserve_fqid_range;
- qman_volatile_dequeue;
- rte_dpaa_driver_register;
- rte_dpaa_driver_unregister;
- rte_dpaa_mem_ptov;
- rte_dpaa_portal_init;
-
- local: *;
-};
-
-DPDK_18.02 {
- global:
-
- dpaa_logtype_eventdev;
- dpaa_svr_family;
- per_lcore_dpaa_io;
- per_lcore_held_bufs;
- qm_channel_pool1;
- qman_alloc_cgrid_range;
- qman_alloc_pool_range;
- qman_create_cgr;
- qman_dca_index;
- qman_delete_cgr;
- qman_enqueue_multi_fq;
+ qman_irqsource_add;
+ qman_irqsource_remove;
qman_modify_cgr;
qman_oos_fq;
+ qman_poll_dqrr;
qman_portal_dequeue;
qman_portal_poll_rx;
qman_query_fq_frm_cnt;
+ qman_query_fq_np;
qman_release_cgrid_range;
+ qman_reserve_fqid_range;
qman_retire_fq;
+ qman_set_fq_lookup_table;
+ qman_set_vdq;
qman_static_dequeue_add;
- rte_dpaa_portal_fq_close;
- rte_dpaa_portal_fq_init;
-
-} DPDK_17.11;
-
-DPDK_18.08 {
- global:
-
- fman_if_get_sg_enable;
- fman_if_set_sg;
- of_get_mac_address;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
-
- bman_thread_irq;
- fman_if_get_sg_enable;
- fman_if_set_sg;
- qman_clear_irq;
-
- qman_irqsource_add;
- qman_irqsource_remove;
qman_thread_fd;
qman_thread_irq;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- qman_set_fq_lookup_table;
-
-} DPDK_18.11;
-
-DPDK_19.11 {
- global:
-
- fsl_qman_fq_portal_create;
- qman_fq_portal_irqsource_add;
- qman_fq_portal_irqsource_remove;
- qman_fq_portal_thread_irq;
-
-} DPDK_19.05;
+ qman_volatile_dequeue;
+ rte_dpaa_driver_register;
+ rte_dpaa_driver_unregister;
+ rte_dpaa_mem_ptov;
+ rte_dpaa_portal_fq_close;
+ rte_dpaa_portal_fq_init;
+ rte_dpaa_portal_init;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4da787236b..fe45575046 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,32 +1,67 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
+ dpaa2_affine_qbman_ethrx_swp;
dpaa2_affine_qbman_swp;
dpaa2_alloc_dpbp_dev;
dpaa2_alloc_dq_storage;
+ dpaa2_dpbp_supported;
+ dpaa2_dqrr_size;
+ dpaa2_eqcr_size;
dpaa2_free_dpbp_dev;
dpaa2_free_dq_storage;
+ dpaa2_free_eq_descriptors;
+ dpaa2_get_qbman_swp;
+ dpaa2_io_portal;
+ dpaa2_svr_family;
+ dpaa2_virt_mode;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
dpbp_get_num_free_bufs;
dpbp_open;
dpbp_reset;
+ dpci_get_opr;
+ dpci_set_opr;
+ dpci_set_rx_queue;
+ dpcon_get_attributes;
+ dpcon_open;
+ dpdmai_close;
+ dpdmai_disable;
+ dpdmai_enable;
+ dpdmai_get_attributes;
+ dpdmai_get_rx_queue;
+ dpdmai_get_tx_queue;
+ dpdmai_open;
+ dpdmai_set_rx_queue;
+ dpio_add_static_dequeue_channel;
dpio_close;
dpio_disable;
dpio_enable;
dpio_get_attributes;
dpio_open;
+ dpio_remove_static_dequeue_channel;
dpio_reset;
dpio_set_stashing_destination;
+ mc_get_soc_version;
+ mc_get_version;
mc_send_command;
per_lcore__dpaa2_io;
+ per_lcore_dpaa2_held_bufs;
qbman_check_command_complete;
+ qbman_check_new_result;
qbman_eq_desc_clear;
+ qbman_eq_desc_set_dca;
qbman_eq_desc_set_fq;
qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_orp;
qbman_eq_desc_set_qd;
qbman_eq_desc_set_response;
+ qbman_eq_desc_set_token;
+ qbman_fq_query_state;
+ qbman_fq_state_frame_count;
+ qbman_get_dqrr_from_idx;
+ qbman_get_dqrr_idx;
qbman_pull_desc_clear;
qbman_pull_desc_set_fq;
qbman_pull_desc_set_numframes;
@@ -35,112 +70,43 @@ DPDK_17.05 {
qbman_release_desc_set_bpid;
qbman_result_DQ_fd;
qbman_result_DQ_flags;
- qbman_result_has_new_result;
- qbman_swp_acquire;
- qbman_swp_pull;
- qbman_swp_release;
- rte_fslmc_driver_register;
- rte_fslmc_driver_unregister;
- rte_fslmc_vfio_dmamap;
- rte_mcp_ptr_list;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- dpaa2_io_portal;
- dpaa2_get_qbman_swp;
- dpci_set_rx_queue;
- dpcon_open;
- dpcon_get_attributes;
- dpio_add_static_dequeue_channel;
- dpio_remove_static_dequeue_channel;
- mc_get_soc_version;
- mc_get_version;
- qbman_check_new_result;
- qbman_eq_desc_set_dca;
- qbman_get_dqrr_from_idx;
- qbman_get_dqrr_idx;
qbman_result_DQ_fqd_ctx;
+ qbman_result_DQ_odpid;
+ qbman_result_DQ_seqnum;
qbman_result_SCN_state;
+ qbman_result_eqresp_fd;
+ qbman_result_eqresp_rc;
+ qbman_result_eqresp_rspid;
+ qbman_result_eqresp_set_rspid;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
qbman_swp_dqrr_consume;
+ qbman_swp_dqrr_idx_consume;
qbman_swp_dqrr_next;
qbman_swp_enqueue_multiple;
qbman_swp_enqueue_multiple_desc;
+ qbman_swp_enqueue_multiple_fd;
qbman_swp_interrupt_clear_status;
+ qbman_swp_prefetch_dqrr_next;
+ qbman_swp_pull;
qbman_swp_push_set;
+ qbman_swp_release;
rte_dpaa2_alloc_dpci_dev;
- rte_fslmc_object_register;
- rte_global_active_dqs_list;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- dpaa2_dpbp_supported;
rte_dpaa2_dev_type;
+ rte_dpaa2_free_dpci_dev;
rte_dpaa2_intr_disable;
rte_dpaa2_intr_enable;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- dpaa2_svr_family;
- dpaa2_virt_mode;
- per_lcore_dpaa2_held_bufs;
- qbman_fq_query_state;
- qbman_fq_state_frame_count;
- qbman_swp_dqrr_idx_consume;
- qbman_swp_prefetch_dqrr_next;
- rte_fslmc_get_device_count;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- dpaa2_affine_qbman_ethrx_swp;
- dpdmai_close;
- dpdmai_disable;
- dpdmai_enable;
- dpdmai_get_attributes;
- dpdmai_get_rx_queue;
- dpdmai_get_tx_queue;
- dpdmai_open;
- dpdmai_set_rx_queue;
- rte_dpaa2_free_dpci_dev;
rte_dpaa2_memsegs;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
- dpaa2_dqrr_size;
- dpaa2_eqcr_size;
- dpci_get_opr;
- dpci_set_opr;
-
-} DPDK_18.05;
-
-DPDK_19.05 {
- global:
- dpaa2_free_eq_descriptors;
-
- qbman_eq_desc_set_orp;
- qbman_eq_desc_set_token;
- qbman_result_DQ_odpid;
- qbman_result_DQ_seqnum;
- qbman_result_eqresp_fd;
- qbman_result_eqresp_rc;
- qbman_result_eqresp_rspid;
- qbman_result_eqresp_set_rspid;
- qbman_swp_enqueue_multiple_fd;
-} DPDK_18.11;
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+ rte_fslmc_get_device_count;
+ rte_fslmc_object_register;
+ rte_fslmc_vfio_dmamap;
+ rte_global_active_dqs_list;
+ rte_mcp_ptr_list;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map
index 964c9a9c45..05b4a28c1b 100644
--- a/drivers/bus/ifpga/rte_bus_ifpga_version.map
+++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map
@@ -1,17 +1,11 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
- rte_ifpga_get_integer32_arg;
- rte_ifpga_get_string_arg;
rte_ifpga_driver_register;
rte_ifpga_driver_unregister;
+ rte_ifpga_find_afu_by_name;
+ rte_ifpga_get_integer32_arg;
+ rte_ifpga_get_string_arg;
local: *;
};
-
-DPDK_19.05 {
- global:
-
- rte_ifpga_find_afu_by_name;
-
-} DPDK_18.05;
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
index 27e9c4f101..012d817e14 100644
--- a/drivers/bus/pci/rte_bus_pci_version.map
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pci_dump;
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
index 590cf9b437..5abb10ecb0 100644
--- a/drivers/bus/vdev/rte_bus_vdev_version.map
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -1,18 +1,12 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
+ rte_vdev_add_custom_scan;
rte_vdev_init;
rte_vdev_register;
+ rte_vdev_remove_custom_scan;
rte_vdev_uninit;
rte_vdev_unregister;
local: *;
};
-
-DPDK_18.02 {
- global:
-
- rte_vdev_add_custom_scan;
- rte_vdev_remove_custom_scan;
-
-} DPDK_17.11;
diff --git a/drivers/bus/vmbus/rte_bus_vmbus_version.map b/drivers/bus/vmbus/rte_bus_vmbus_version.map
index ae231ad329..cbaaebc06c 100644
--- a/drivers/bus/vmbus/rte_bus_vmbus_version.map
+++ b/drivers/bus/vmbus/rte_bus_vmbus_version.map
@@ -1,6 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_vmbus_chan_close;
@@ -20,6 +18,7 @@ DPDK_18.08 {
rte_vmbus_probe;
rte_vmbus_register;
rte_vmbus_scan;
+ rte_vmbus_set_latency;
rte_vmbus_sub_channel_index;
rte_vmbus_subchan_open;
rte_vmbus_unmap_device;
@@ -27,10 +26,3 @@ DPDK_18.08 {
local: *;
};
-
-DPDK_18.11 {
- global:
-
- rte_vmbus_set_latency;
-
-} DPDK_18.08;
diff --git a/drivers/common/cpt/rte_common_cpt_version.map b/drivers/common/cpt/rte_common_cpt_version.map
index dec614f0de..79fa5751bc 100644
--- a/drivers/common/cpt/rte_common_cpt_version.map
+++ b/drivers/common/cpt/rte_common_cpt_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
cpt_pmd_ops_helper_get_mlen_direct_mode;
cpt_pmd_ops_helper_get_mlen_sg_mode;
+
+ local: *;
};
diff --git a/drivers/common/dpaax/rte_common_dpaax_version.map b/drivers/common/dpaax/rte_common_dpaax_version.map
index 8131c9e305..45d62aea9d 100644
--- a/drivers/common/dpaax/rte_common_dpaax_version.map
+++ b/drivers/common/dpaax/rte_common_dpaax_version.map
@@ -1,11 +1,11 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- dpaax_iova_table_update;
dpaax_iova_table_depopulate;
dpaax_iova_table_dump;
dpaax_iova_table_p;
dpaax_iova_table_populate;
+ dpaax_iova_table_update;
local: *;
};
diff --git a/drivers/common/mvep/rte_common_mvep_version.map b/drivers/common/mvep/rte_common_mvep_version.map
index c71722d79f..030928439d 100644
--- a/drivers/common/mvep/rte_common_mvep_version.map
+++ b/drivers/common/mvep/rte_common_mvep_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- rte_mvep_init;
rte_mvep_deinit;
+ rte_mvep_init;
+
+ local: *;
};
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index a9b3cff9bc..c15fb89112 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,8 +1,10 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
octeontx_logtype_mbox;
+ octeontx_mbox_send;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
- octeontx_mbox_send;
+
+ local: *;
};
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 4400120da0..adad21a2d6 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -1,39 +1,35 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
otx2_dev_active_vfs;
otx2_dev_fini;
otx2_dev_priv_init;
-
+ otx2_disable_irqs;
+ otx2_intra_dev_get_cfg;
otx2_logtype_base;
otx2_logtype_dpi;
otx2_logtype_mbox;
+ otx2_logtype_nix;
otx2_logtype_npa;
otx2_logtype_npc;
- otx2_logtype_nix;
otx2_logtype_sso;
- otx2_logtype_tm;
otx2_logtype_tim;
-
+ otx2_logtype_tm;
otx2_mbox_alloc_msg_rsp;
otx2_mbox_get_rsp;
otx2_mbox_get_rsp_tmo;
otx2_mbox_id2name;
otx2_mbox_msg_send;
otx2_mbox_wait_for_rsp;
-
- otx2_intra_dev_get_cfg;
otx2_npa_lf_active;
otx2_npa_lf_obj_get;
otx2_npa_lf_obj_ref;
otx2_npa_pf_func_get;
otx2_npa_set_defaults;
+ otx2_register_irq;
otx2_sso_pf_func_get;
otx2_sso_pf_func_set;
-
- otx2_disable_irqs;
otx2_unregister_irq;
- otx2_register_irq;
local: *;
};
diff --git a/drivers/compress/isal/rte_pmd_isal_version.map b/drivers/compress/isal/rte_pmd_isal_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/compress/isal/rte_pmd_isal_version.map
+++ b/drivers/compress/isal/rte_pmd_isal_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
+++ b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/qat/rte_pmd_qat_version.map b/drivers/compress/qat/rte_pmd_qat_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/qat/rte_pmd_qat_version.map
+++ b/drivers/compress/qat/rte_pmd_qat_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/zlib/rte_pmd_zlib_version.map b/drivers/compress/zlib/rte_pmd_zlib_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/zlib/rte_pmd_zlib_version.map
+++ b/drivers/compress/zlib/rte_pmd_zlib_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
+++ b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
+++ b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/armv8/rte_pmd_armv8_version.map b/drivers/crypto/armv8/rte_pmd_armv8_version.map
index 1f84b68a83..f9f17e4f6e 100644
--- a/drivers/crypto/armv8/rte_pmd_armv8_version.map
+++ b/drivers/crypto/armv8/rte_pmd_armv8_version.map
@@ -1,3 +1,3 @@
-DPDK_17.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
+++ b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/ccp/rte_pmd_ccp_version.map b/drivers/crypto/ccp/rte_pmd_ccp_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/crypto/ccp/rte_pmd_ccp_version.map
+++ b/drivers/crypto/ccp/rte_pmd_ccp_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
index 0bfb986d0b..5952d645fd 100644
--- a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
+++ b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_18.11 {
+DPDK_20.0 {
global:
dpaa2_sec_eventq_attach;
dpaa2_sec_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
index cc7f2162e0..8580fa13db 100644
--- a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
+++ b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_19.11 {
+DPDK_20.0 {
global:
dpaa_sec_eventq_attach;
dpaa_sec_eventq_detach;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
index 8ffeca934e..f9f17e4f6e 100644
--- a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
+++ b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
@@ -1,3 +1,3 @@
-DPDK_16.07 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
+++ b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
index 406964d1fc..f9f17e4f6e 100644
--- a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
+++ b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/null/rte_pmd_null_crypto_version.map b/drivers/crypto/null/rte_pmd_null_crypto_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/null/rte_pmd_null_crypto_version.map
+++ b/drivers/crypto/null/rte_pmd_null_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
+++ b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/openssl/rte_pmd_openssl_version.map b/drivers/crypto/openssl/rte_pmd_openssl_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/openssl/rte_pmd_openssl_version.map
+++ b/drivers/crypto/openssl/rte_pmd_openssl_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
index 5c43127cf2..077afedce7 100644
--- a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
+++ b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
@@ -1,21 +1,16 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_cryptodev_scheduler_load_user_scheduler;
- rte_cryptodev_scheduler_slave_attach;
- rte_cryptodev_scheduler_slave_detach;
- rte_cryptodev_scheduler_ordering_set;
- rte_cryptodev_scheduler_ordering_get;
-
-};
-
-DPDK_17.05 {
- global:
-
rte_cryptodev_scheduler_mode_get;
rte_cryptodev_scheduler_mode_set;
rte_cryptodev_scheduler_option_get;
rte_cryptodev_scheduler_option_set;
+ rte_cryptodev_scheduler_ordering_get;
+ rte_cryptodev_scheduler_ordering_set;
+ rte_cryptodev_scheduler_slave_attach;
+ rte_cryptodev_scheduler_slave_detach;
rte_cryptodev_scheduler_slaves_get;
-} DPDK_17.02;
+ local: *;
+};
diff --git a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
+++ b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
+++ b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/zuc/rte_pmd_zuc_version.map b/drivers/crypto/zuc/rte_pmd_zuc_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/zuc/rte_pmd_zuc_version.map
+++ b/drivers/crypto/zuc/rte_pmd_zuc_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
+++ b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
index 1c0b7559dc..f9f17e4f6e 100644
--- a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
+++ b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dsw/rte_pmd_dsw_event_version.map b/drivers/event/dsw/rte_pmd_dsw_event_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/event/dsw/rte_pmd_dsw_event_version.map
+++ b/drivers/event/dsw/rte_pmd_dsw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
+++ b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
index 41c65c8c9c..f9f17e4f6e 100644
--- a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
+++ b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
+DPDK_20.0 {
local: *;
};
-
diff --git a/drivers/event/opdl/rte_pmd_opdl_event_version.map b/drivers/event/opdl/rte_pmd_opdl_event_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/event/opdl/rte_pmd_opdl_event_version.map
+++ b/drivers/event/opdl/rte_pmd_opdl_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
+++ b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/sw/rte_pmd_sw_event_version.map b/drivers/event/sw/rte_pmd_sw_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/sw/rte_pmd_sw_event_version.map
+++ b/drivers/event/sw/rte_pmd_sw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/bucket/rte_mempool_bucket_version.map b/drivers/mempool/bucket/rte_mempool_bucket_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/mempool/bucket/rte_mempool_bucket_version.map
+++ b/drivers/mempool/bucket/rte_mempool_bucket_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
index 60bf50b2d1..9eebaf7ffd 100644
--- a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
+++ b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_dpaa_bpid_info;
diff --git a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
index b45e7a9ac1..cd4bc88273 100644
--- a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
+++ b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
@@ -1,16 +1,10 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_dpaa2_bpid_info;
rte_dpaa2_mbuf_alloc_bulk;
-
- local: *;
-};
-
-DPDK_18.05 {
- global:
-
rte_dpaa2_mbuf_from_buf_addr;
rte_dpaa2_mbuf_pool_bpid;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
+++ b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
index d703368c31..d4f81aed8e 100644
--- a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
+++ b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
@@ -1,8 +1,8 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
- otx2_npa_lf_init;
otx2_npa_lf_fini;
+ otx2_npa_lf_init;
local: *;
};
diff --git a/drivers/mempool/ring/rte_mempool_ring_version.map b/drivers/mempool/ring/rte_mempool_ring_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/ring/rte_mempool_ring_version.map
+++ b/drivers/mempool/ring/rte_mempool_ring_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/stack/rte_mempool_stack_version.map b/drivers/mempool/stack/rte_mempool_stack_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/stack/rte_mempool_stack_version.map
+++ b/drivers/mempool/stack/rte_mempool_stack_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map b/drivers/net/af_packet/rte_pmd_af_packet_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
+++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
index c6db030fe6..f9f17e4f6e 100644
--- a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
+++ b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
@@ -1,3 +1,3 @@
-DPDK_19.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ark/rte_pmd_ark_version.map b/drivers/net/ark/rte_pmd_ark_version.map
index 1062e0429f..f9f17e4f6e 100644
--- a/drivers/net/ark/rte_pmd_ark_version.map
+++ b/drivers/net/ark/rte_pmd_ark_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
- local: *;
-
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/atlantic/rte_pmd_atlantic_version.map b/drivers/net/atlantic/rte_pmd_atlantic_version.map
index b16faa999f..9b04838d84 100644
--- a/drivers/net/atlantic/rte_pmd_atlantic_version.map
+++ b/drivers/net/atlantic/rte_pmd_atlantic_version.map
@@ -1,5 +1,4 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
@@ -13,4 +12,3 @@ EXPERIMENTAL {
rte_pmd_atl_macsec_select_txsa;
rte_pmd_atl_macsec_select_rxsa;
};
-
diff --git a/drivers/net/avp/rte_pmd_avp_version.map b/drivers/net/avp/rte_pmd_avp_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/net/avp/rte_pmd_avp_version.map
+++ b/drivers/net/avp/rte_pmd_avp_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/axgbe/rte_pmd_axgbe_version.map b/drivers/net/axgbe/rte_pmd_axgbe_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/net/axgbe/rte_pmd_axgbe_version.map
+++ b/drivers/net/axgbe/rte_pmd_axgbe_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
+++ b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 4750d40ad6..bb52562347 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_pmd_bnxt_get_vf_rx_status;
@@ -10,13 +10,13 @@ DPDK_17.08 {
rte_pmd_bnxt_set_tx_loopback;
rte_pmd_bnxt_set_vf_mac_addr;
rte_pmd_bnxt_set_vf_mac_anti_spoof;
+ rte_pmd_bnxt_set_vf_persist_stats;
rte_pmd_bnxt_set_vf_rate_limit;
rte_pmd_bnxt_set_vf_rxmode;
rte_pmd_bnxt_set_vf_vlan_anti_spoof;
rte_pmd_bnxt_set_vf_vlan_filter;
rte_pmd_bnxt_set_vf_vlan_insert;
rte_pmd_bnxt_set_vf_vlan_stripq;
- rte_pmd_bnxt_set_vf_persist_stats;
local: *;
};
diff --git a/drivers/net/bonding/rte_pmd_bond_version.map b/drivers/net/bonding/rte_pmd_bond_version.map
index 00d955c481..270c7d5d55 100644
--- a/drivers/net/bonding/rte_pmd_bond_version.map
+++ b/drivers/net/bonding/rte_pmd_bond_version.map
@@ -1,9 +1,21 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_bond_8023ad_agg_selection_get;
+ rte_eth_bond_8023ad_agg_selection_set;
+ rte_eth_bond_8023ad_conf_get;
+ rte_eth_bond_8023ad_dedicated_queues_disable;
+ rte_eth_bond_8023ad_dedicated_queues_enable;
+ rte_eth_bond_8023ad_ext_collect;
+ rte_eth_bond_8023ad_ext_collect_get;
+ rte_eth_bond_8023ad_ext_distrib;
+ rte_eth_bond_8023ad_ext_distrib_get;
+ rte_eth_bond_8023ad_ext_slowtx;
+ rte_eth_bond_8023ad_setup;
rte_eth_bond_8023ad_slave_info;
rte_eth_bond_active_slaves_get;
rte_eth_bond_create;
+ rte_eth_bond_free;
rte_eth_bond_link_monitoring_set;
rte_eth_bond_mac_address_reset;
rte_eth_bond_mac_address_set;
@@ -19,36 +31,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- rte_eth_bond_free;
-
-} DPDK_2.0;
-
-DPDK_16.04 {
-};
-
-DPDK_16.07 {
- global:
-
- rte_eth_bond_8023ad_ext_collect;
- rte_eth_bond_8023ad_ext_collect_get;
- rte_eth_bond_8023ad_ext_distrib;
- rte_eth_bond_8023ad_ext_distrib_get;
- rte_eth_bond_8023ad_ext_slowtx;
-
-} DPDK_16.04;
-
-DPDK_17.08 {
- global:
-
- rte_eth_bond_8023ad_dedicated_queues_enable;
- rte_eth_bond_8023ad_dedicated_queues_disable;
- rte_eth_bond_8023ad_agg_selection_get;
- rte_eth_bond_8023ad_agg_selection_set;
- rte_eth_bond_8023ad_conf_get;
- rte_eth_bond_8023ad_setup;
-
-} DPDK_16.07;
diff --git a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
+++ b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/dpaa/rte_pmd_dpaa_version.map b/drivers/net/dpaa/rte_pmd_dpaa_version.map
index 8cb4500b51..f403a1526d 100644
--- a/drivers/net/dpaa/rte_pmd_dpaa_version.map
+++ b/drivers/net/dpaa/rte_pmd_dpaa_version.map
@@ -1,12 +1,9 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
dpaa_eth_eventq_attach;
dpaa_eth_eventq_detach;
rte_pmd_dpaa_set_tx_loopback;
-} DPDK_17.11;
+
+ local: *;
+};
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
index d1b4cdb232..f2bb793319 100644
--- a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -1,15 +1,11 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_17.11 {
+DPDK_20.0 {
global:
dpaa2_eth_eventq_attach;
dpaa2_eth_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
@@ -17,4 +13,4 @@ EXPERIMENTAL {
rte_pmd_dpaa2_mux_flow_create;
rte_pmd_dpaa2_set_custom_hash;
rte_pmd_dpaa2_set_timestamp;
-} DPDK_17.11;
+};
diff --git a/drivers/net/e1000/rte_pmd_e1000_version.map b/drivers/net/e1000/rte_pmd_e1000_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/e1000/rte_pmd_e1000_version.map
+++ b/drivers/net/e1000/rte_pmd_e1000_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ena/rte_pmd_ena_version.map b/drivers/net/ena/rte_pmd_ena_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/ena/rte_pmd_ena_version.map
+++ b/drivers/net/ena/rte_pmd_ena_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/net/enetc/rte_pmd_enetc_version.map
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enic/rte_pmd_enic_version.map b/drivers/net/enic/rte_pmd_enic_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/enic/rte_pmd_enic_version.map
+++ b/drivers/net/enic/rte_pmd_enic_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/failsafe/rte_pmd_failsafe_version.map b/drivers/net/failsafe/rte_pmd_failsafe_version.map
index b6d2840be4..f9f17e4f6e 100644
--- a/drivers/net/failsafe/rte_pmd_failsafe_version.map
+++ b/drivers/net/failsafe/rte_pmd_failsafe_version.map
@@ -1,4 +1,3 @@
-DPDK_17.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/fm10k/rte_pmd_fm10k_version.map b/drivers/net/fm10k/rte_pmd_fm10k_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/fm10k/rte_pmd_fm10k_version.map
+++ b/drivers/net/fm10k/rte_pmd_fm10k_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hinic/rte_pmd_hinic_version.map b/drivers/net/hinic/rte_pmd_hinic_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/hinic/rte_pmd_hinic_version.map
+++ b/drivers/net/hinic/rte_pmd_hinic_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hns3/rte_pmd_hns3_version.map b/drivers/net/hns3/rte_pmd_hns3_version.map
index 35e5f2debb..f9f17e4f6e 100644
--- a/drivers/net/hns3/rte_pmd_hns3_version.map
+++ b/drivers/net/hns3/rte_pmd_hns3_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index cccd5768c2..a80e69b93e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -1,23 +1,34 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_i40e_add_vf_mac_addr;
+ rte_pmd_i40e_flow_add_del_packet_template;
+ rte_pmd_i40e_flow_type_mapping_get;
+ rte_pmd_i40e_flow_type_mapping_reset;
+ rte_pmd_i40e_flow_type_mapping_update;
+ rte_pmd_i40e_get_ddp_info;
+ rte_pmd_i40e_get_ddp_list;
rte_pmd_i40e_get_vf_stats;
+ rte_pmd_i40e_inset_get;
+ rte_pmd_i40e_inset_set;
rte_pmd_i40e_ping_vfs;
+ rte_pmd_i40e_process_ddp_package;
rte_pmd_i40e_ptype_mapping_get;
rte_pmd_i40e_ptype_mapping_replace;
rte_pmd_i40e_ptype_mapping_reset;
rte_pmd_i40e_ptype_mapping_update;
+ rte_pmd_i40e_query_vfid_by_mac;
rte_pmd_i40e_reset_vf_stats;
+ rte_pmd_i40e_rss_queue_region_conf;
+ rte_pmd_i40e_set_tc_strict_prio;
rte_pmd_i40e_set_tx_loopback;
rte_pmd_i40e_set_vf_broadcast;
rte_pmd_i40e_set_vf_mac_addr;
rte_pmd_i40e_set_vf_mac_anti_spoof;
+ rte_pmd_i40e_set_vf_max_bw;
rte_pmd_i40e_set_vf_multicast_promisc;
+ rte_pmd_i40e_set_vf_tc_bw_alloc;
+ rte_pmd_i40e_set_vf_tc_max_bw;
rte_pmd_i40e_set_vf_unicast_promisc;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_vf_vlan_filter;
@@ -25,43 +36,5 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_vlan_stripq;
rte_pmd_i40e_set_vf_vlan_tag;
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_pmd_i40e_set_tc_strict_prio;
- rte_pmd_i40e_set_vf_max_bw;
- rte_pmd_i40e_set_vf_tc_bw_alloc;
- rte_pmd_i40e_set_vf_tc_max_bw;
- rte_pmd_i40e_process_ddp_package;
- rte_pmd_i40e_get_ddp_list;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_i40e_get_ddp_info;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_pmd_i40e_add_vf_mac_addr;
- rte_pmd_i40e_flow_add_del_packet_template;
- rte_pmd_i40e_flow_type_mapping_update;
- rte_pmd_i40e_flow_type_mapping_get;
- rte_pmd_i40e_flow_type_mapping_reset;
- rte_pmd_i40e_query_vfid_by_mac;
- rte_pmd_i40e_rss_queue_region_conf;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_pmd_i40e_inset_get;
- rte_pmd_i40e_inset_set;
-} DPDK_17.11;
\ No newline at end of file
+ local: *;
+};
diff --git a/drivers/net/iavf/rte_pmd_iavf_version.map b/drivers/net/iavf/rte_pmd_iavf_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/iavf/rte_pmd_iavf_version.map
+++ b/drivers/net/iavf/rte_pmd_iavf_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ice/rte_pmd_ice_version.map b/drivers/net/ice/rte_pmd_ice_version.map
index 7b23b609da..f9f17e4f6e 100644
--- a/drivers/net/ice/rte_pmd_ice_version.map
+++ b/drivers/net/ice/rte_pmd_ice_version.map
@@ -1,4 +1,3 @@
-DPDK_19.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ifc/rte_pmd_ifc_version.map b/drivers/net/ifc/rte_pmd_ifc_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/net/ifc/rte_pmd_ifc_version.map
+++ b/drivers/net/ifc/rte_pmd_ifc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
+++ b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index c814f96d72..21534dbc3d 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
- rte_pmd_ixgbe_set_all_queues_drop_en;
- rte_pmd_ixgbe_set_tx_loopback;
- rte_pmd_ixgbe_set_vf_mac_addr;
- rte_pmd_ixgbe_set_vf_mac_anti_spoof;
- rte_pmd_ixgbe_set_vf_split_drop_en;
- rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
- rte_pmd_ixgbe_set_vf_vlan_insert;
- rte_pmd_ixgbe_set_vf_vlan_stripq;
-} DPDK_2.0;
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_ixgbe_bypass_event_show;
+ rte_pmd_ixgbe_bypass_event_store;
+ rte_pmd_ixgbe_bypass_init;
+ rte_pmd_ixgbe_bypass_state_set;
+ rte_pmd_ixgbe_bypass_state_show;
+ rte_pmd_ixgbe_bypass_ver_show;
+ rte_pmd_ixgbe_bypass_wd_reset;
+ rte_pmd_ixgbe_bypass_wd_timeout_show;
+ rte_pmd_ixgbe_bypass_wd_timeout_store;
rte_pmd_ixgbe_macsec_config_rxsc;
rte_pmd_ixgbe_macsec_config_txsc;
rte_pmd_ixgbe_macsec_disable;
rte_pmd_ixgbe_macsec_enable;
rte_pmd_ixgbe_macsec_select_rxsa;
rte_pmd_ixgbe_macsec_select_txsa;
+ rte_pmd_ixgbe_ping_vf;
+ rte_pmd_ixgbe_set_all_queues_drop_en;
+ rte_pmd_ixgbe_set_tc_bw_alloc;
+ rte_pmd_ixgbe_set_tx_loopback;
+ rte_pmd_ixgbe_set_vf_mac_addr;
+ rte_pmd_ixgbe_set_vf_mac_anti_spoof;
rte_pmd_ixgbe_set_vf_rate_limit;
rte_pmd_ixgbe_set_vf_rx;
rte_pmd_ixgbe_set_vf_rxmode;
+ rte_pmd_ixgbe_set_vf_split_drop_en;
rte_pmd_ixgbe_set_vf_tx;
+ rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
rte_pmd_ixgbe_set_vf_vlan_filter;
-} DPDK_16.11;
+ rte_pmd_ixgbe_set_vf_vlan_insert;
+ rte_pmd_ixgbe_set_vf_vlan_stripq;
-DPDK_17.05 {
- global:
-
- rte_pmd_ixgbe_ping_vf;
- rte_pmd_ixgbe_set_tc_bw_alloc;
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_ixgbe_bypass_event_show;
- rte_pmd_ixgbe_bypass_event_store;
- rte_pmd_ixgbe_bypass_init;
- rte_pmd_ixgbe_bypass_state_set;
- rte_pmd_ixgbe_bypass_state_show;
- rte_pmd_ixgbe_bypass_ver_show;
- rte_pmd_ixgbe_bypass_wd_reset;
- rte_pmd_ixgbe_bypass_wd_timeout_show;
- rte_pmd_ixgbe_bypass_wd_timeout_store;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/net/kni/rte_pmd_kni_version.map b/drivers/net/kni/rte_pmd_kni_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/kni/rte_pmd_kni_version.map
+++ b/drivers/net/kni/rte_pmd_kni_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/liquidio/rte_pmd_liquidio_version.map b/drivers/net/liquidio/rte_pmd_liquidio_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/liquidio/rte_pmd_liquidio_version.map
+++ b/drivers/net/liquidio/rte_pmd_liquidio_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/memif/rte_pmd_memif_version.map b/drivers/net/memif/rte_pmd_memif_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/net/memif/rte_pmd_memif_version.map
+++ b/drivers/net/memif/rte_pmd_memif_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/mlx4/rte_pmd_mlx4_version.map b/drivers/net/mlx4/rte_pmd_mlx4_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/mlx4/rte_pmd_mlx4_version.map
+++ b/drivers/net/mlx4/rte_pmd_mlx4_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mlx5/rte_pmd_mlx5_version.map b/drivers/net/mlx5/rte_pmd_mlx5_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/mlx5/rte_pmd_mlx5_version.map
+++ b/drivers/net/mlx5/rte_pmd_mlx5_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvneta/rte_pmd_mvneta_version.map b/drivers/net/mvneta/rte_pmd_mvneta_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/net/mvneta/rte_pmd_mvneta_version.map
+++ b/drivers/net/mvneta/rte_pmd_mvneta_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
+++ b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/netvsc/rte_pmd_netvsc_version.map b/drivers/net/netvsc/rte_pmd_netvsc_version.map
index d534019a6b..f9f17e4f6e 100644
--- a/drivers/net/netvsc/rte_pmd_netvsc_version.map
+++ b/drivers/net/netvsc/rte_pmd_netvsc_version.map
@@ -1,5 +1,3 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfb/rte_pmd_nfb_version.map b/drivers/net/nfb/rte_pmd_nfb_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/nfb/rte_pmd_nfb_version.map
+++ b/drivers/net/nfb/rte_pmd_nfb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfp/rte_pmd_nfp_version.map b/drivers/net/nfp/rte_pmd_nfp_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/nfp/rte_pmd_nfp_version.map
+++ b/drivers/net/nfp/rte_pmd_nfp_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/null/rte_pmd_null_version.map b/drivers/net/null/rte_pmd_null_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/null/rte_pmd_null_version.map
+++ b/drivers/net/null/rte_pmd_null_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/octeontx/rte_pmd_octeontx_version.map b/drivers/net/octeontx/rte_pmd_octeontx_version.map
index a3161b14d0..f7cae02fac 100644
--- a/drivers/net/octeontx/rte_pmd_octeontx_version.map
+++ b/drivers/net/octeontx/rte_pmd_octeontx_version.map
@@ -1,11 +1,7 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.02 {
+DPDK_20.0 {
global:
rte_octeontx_pchan_map;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
+++ b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/pcap/rte_pmd_pcap_version.map b/drivers/net/pcap/rte_pmd_pcap_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/pcap/rte_pmd_pcap_version.map
+++ b/drivers/net/pcap/rte_pmd_pcap_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/qede/rte_pmd_qede_version.map b/drivers/net/qede/rte_pmd_qede_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/qede/rte_pmd_qede_version.map
+++ b/drivers/net/qede/rte_pmd_qede_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ring/rte_pmd_ring_version.map b/drivers/net/ring/rte_pmd_ring_version.map
index 1f785d9409..ebb6be2733 100644
--- a/drivers/net/ring/rte_pmd_ring_version.map
+++ b/drivers/net/ring/rte_pmd_ring_version.map
@@ -1,14 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_from_ring;
rte_eth_from_rings;
local: *;
};
-
-DPDK_2.2 {
- global:
-
- rte_eth_from_ring;
-
-} DPDK_2.0;
diff --git a/drivers/net/sfc/rte_pmd_sfc_version.map b/drivers/net/sfc/rte_pmd_sfc_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/sfc/rte_pmd_sfc_version.map
+++ b/drivers/net/sfc/rte_pmd_sfc_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/softnic/rte_pmd_softnic_version.map b/drivers/net/softnic/rte_pmd_softnic_version.map
index bc44b06f98..50f113d5a2 100644
--- a/drivers/net/softnic/rte_pmd_softnic_version.map
+++ b/drivers/net/softnic/rte_pmd_softnic_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pmd_softnic_run;
diff --git a/drivers/net/szedata2/rte_pmd_szedata2_version.map b/drivers/net/szedata2/rte_pmd_szedata2_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/szedata2/rte_pmd_szedata2_version.map
+++ b/drivers/net/szedata2/rte_pmd_szedata2_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/tap/rte_pmd_tap_version.map
+++ b/drivers/net/tap/rte_pmd_tap_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/thunderx/rte_pmd_thunderx_version.map b/drivers/net/thunderx/rte_pmd_thunderx_version.map
index 1901bcb3b3..f9f17e4f6e 100644
--- a/drivers/net/thunderx/rte_pmd_thunderx_version.map
+++ b/drivers/net/thunderx/rte_pmd_thunderx_version.map
@@ -1,4 +1,3 @@
-DPDK_16.07 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
+++ b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vhost/rte_pmd_vhost_version.map b/drivers/net/vhost/rte_pmd_vhost_version.map
index 695db85749..16b591ccc4 100644
--- a/drivers/net/vhost/rte_pmd_vhost_version.map
+++ b/drivers/net/vhost/rte_pmd_vhost_version.map
@@ -1,13 +1,8 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
rte_eth_vhost_get_queue_event;
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
rte_eth_vhost_get_vid_from_port_id;
+
+ local: *;
};
diff --git a/drivers/net/virtio/rte_pmd_virtio_version.map b/drivers/net/virtio/rte_pmd_virtio_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/virtio/rte_pmd_virtio_version.map
+++ b/drivers/net/virtio/rte_pmd_virtio_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
+++ b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
+++ b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
index d16a136fc8..ca6a0d7626 100644
--- a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
@@ -1,4 +1,4 @@
-DPDK_19.05 {
+DPDK_20.0 {
global:
rte_qdma_attr_get;
@@ -9,9 +9,9 @@ DPDK_19.05 {
rte_qdma_start;
rte_qdma_stop;
rte_qdma_vq_create;
- rte_qdma_vq_destroy;
rte_qdma_vq_dequeue;
rte_qdma_vq_dequeue_multi;
+ rte_qdma_vq_destroy;
rte_qdma_vq_enqueue;
rte_qdma_vq_enqueue_multi;
rte_qdma_vq_stats;
diff --git a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
+++ b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ioat/rte_rawdev_ioat_version.map b/drivers/raw/ioat/rte_rawdev_ioat_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/ioat/rte_rawdev_ioat_version.map
+++ b/drivers/raw/ioat/rte_rawdev_ioat_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ntb/rte_rawdev_ntb_version.map b/drivers/raw/ntb/rte_rawdev_ntb_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/raw/ntb/rte_rawdev_ntb_version.map
+++ b/drivers/raw/ntb/rte_rawdev_ntb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
+++ b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
+++ b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/lib/librte_acl/rte_acl_version.map b/lib/librte_acl/rte_acl_version.map
index b09370a104..c3daca8115 100644
--- a/lib/librte_acl/rte_acl_version.map
+++ b/lib/librte_acl/rte_acl_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_acl_add_rules;
diff --git a/lib/librte_bbdev/rte_bbdev_version.map b/lib/librte_bbdev/rte_bbdev_version.map
index 3624eb1cb4..45b560dbe7 100644
--- a/lib/librte_bbdev/rte_bbdev_version.map
+++ b/lib/librte_bbdev/rte_bbdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_bitratestats/rte_bitratestats_version.map b/lib/librte_bitratestats/rte_bitratestats_version.map
index fe7454452d..88fc2912db 100644
--- a/lib/librte_bitratestats/rte_bitratestats_version.map
+++ b/lib/librte_bitratestats/rte_bitratestats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_stats_bitrate_calc;
diff --git a/lib/librte_bpf/rte_bpf_version.map b/lib/librte_bpf/rte_bpf_version.map
index a203e088ea..e1ec43faa0 100644
--- a/lib/librte_bpf/rte_bpf_version.map
+++ b/lib/librte_bpf/rte_bpf_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cfgfile/rte_cfgfile_version.map b/lib/librte_cfgfile/rte_cfgfile_version.map
index a0a11cea8d..906eee96bf 100644
--- a/lib/librte_cfgfile/rte_cfgfile_version.map
+++ b/lib/librte_cfgfile/rte_cfgfile_version.map
@@ -1,40 +1,22 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_cfgfile_add_entry;
+ rte_cfgfile_add_section;
rte_cfgfile_close;
+ rte_cfgfile_create;
rte_cfgfile_get_entry;
rte_cfgfile_has_entry;
rte_cfgfile_has_section;
rte_cfgfile_load;
+ rte_cfgfile_load_with_params;
rte_cfgfile_num_sections;
+ rte_cfgfile_save;
rte_cfgfile_section_entries;
+ rte_cfgfile_section_entries_by_index;
rte_cfgfile_section_num_entries;
rte_cfgfile_sections;
+ rte_cfgfile_set_entry;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_cfgfile_section_entries_by_index;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_cfgfile_load_with_params;
-
-} DPDK_16.04;
-
-DPDK_17.11 {
- global:
-
- rte_cfgfile_add_entry;
- rte_cfgfile_add_section;
- rte_cfgfile_create;
- rte_cfgfile_save;
- rte_cfgfile_set_entry;
-
-} DPDK_17.05;
diff --git a/lib/librte_cmdline/rte_cmdline_version.map b/lib/librte_cmdline/rte_cmdline_version.map
index 04bcb387f2..95fce812ff 100644
--- a/lib/librte_cmdline/rte_cmdline_version.map
+++ b/lib/librte_cmdline/rte_cmdline_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
cirbuf_add_buf_head;
@@ -40,6 +40,7 @@ DPDK_2.0 {
cmdline_parse_num;
cmdline_parse_portlist;
cmdline_parse_string;
+ cmdline_poll;
cmdline_printf;
cmdline_quit;
cmdline_set_prompt;
@@ -68,10 +69,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- cmdline_poll;
-
-} DPDK_2.0;
diff --git a/lib/librte_compressdev/rte_compressdev_version.map b/lib/librte_compressdev/rte_compressdev_version.map
index e2a108b650..cfcd50ac1c 100644
--- a/lib/librte_compressdev/rte_compressdev_version.map
+++ b/lib/librte_compressdev/rte_compressdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 3deb265ac2..1dd1e259a0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -1,92 +1,62 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
- rte_cryptodevs;
+ rte_crypto_aead_algorithm_strings;
+ rte_crypto_aead_operation_strings;
+ rte_crypto_auth_algorithm_strings;
+ rte_crypto_auth_operation_strings;
+ rte_crypto_cipher_algorithm_strings;
+ rte_crypto_cipher_operation_strings;
+ rte_crypto_op_pool_create;
+ rte_cryptodev_allocate_driver;
rte_cryptodev_callback_register;
rte_cryptodev_callback_unregister;
rte_cryptodev_close;
- rte_cryptodev_count;
rte_cryptodev_configure;
+ rte_cryptodev_count;
+ rte_cryptodev_device_count_by_driver;
+ rte_cryptodev_devices_get;
+ rte_cryptodev_driver_id_get;
+ rte_cryptodev_driver_name_get;
+ rte_cryptodev_get_aead_algo_enum;
+ rte_cryptodev_get_auth_algo_enum;
+ rte_cryptodev_get_cipher_algo_enum;
rte_cryptodev_get_dev_id;
rte_cryptodev_get_feature_name;
+ rte_cryptodev_get_sec_ctx;
rte_cryptodev_info_get;
+ rte_cryptodev_name_get;
rte_cryptodev_pmd_allocate;
rte_cryptodev_pmd_callback_process;
+ rte_cryptodev_pmd_create;
+ rte_cryptodev_pmd_create_dev_name;
+ rte_cryptodev_pmd_destroy;
+ rte_cryptodev_pmd_get_dev;
+ rte_cryptodev_pmd_get_named_dev;
+ rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_pmd_parse_input_args;
rte_cryptodev_pmd_release_device;
- rte_cryptodev_sym_session_create;
- rte_cryptodev_sym_session_free;
+ rte_cryptodev_queue_pair_count;
+ rte_cryptodev_queue_pair_setup;
rte_cryptodev_socket_id;
rte_cryptodev_start;
rte_cryptodev_stats_get;
rte_cryptodev_stats_reset;
rte_cryptodev_stop;
- rte_cryptodev_queue_pair_count;
- rte_cryptodev_queue_pair_setup;
- rte_crypto_op_pool_create;
-
- local: *;
-};
-
-DPDK_17.02 {
- global:
-
- rte_cryptodev_devices_get;
- rte_cryptodev_pmd_create_dev_name;
- rte_cryptodev_pmd_get_dev;
- rte_cryptodev_pmd_get_named_dev;
- rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_sym_capability_check_aead;
rte_cryptodev_sym_capability_check_auth;
rte_cryptodev_sym_capability_check_cipher;
rte_cryptodev_sym_capability_get;
- rte_crypto_auth_algorithm_strings;
- rte_crypto_auth_operation_strings;
- rte_crypto_cipher_algorithm_strings;
- rte_crypto_cipher_operation_strings;
-
-} DPDK_16.04;
-
-DPDK_17.05 {
- global:
-
- rte_cryptodev_get_auth_algo_enum;
- rte_cryptodev_get_cipher_algo_enum;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_cryptodev_allocate_driver;
- rte_cryptodev_device_count_by_driver;
- rte_cryptodev_driver_id_get;
- rte_cryptodev_driver_name_get;
- rte_cryptodev_get_aead_algo_enum;
- rte_cryptodev_sym_capability_check_aead;
- rte_cryptodev_sym_session_init;
- rte_cryptodev_sym_session_clear;
- rte_crypto_aead_algorithm_strings;
- rte_crypto_aead_operation_strings;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_cryptodev_get_sec_ctx;
- rte_cryptodev_name_get;
- rte_cryptodev_pmd_create;
- rte_cryptodev_pmd_destroy;
- rte_cryptodev_pmd_parse_input_args;
-
-} DPDK_17.08;
-
-DPDK_18.05 {
- global:
-
rte_cryptodev_sym_get_header_session_size;
rte_cryptodev_sym_get_private_session_size;
+ rte_cryptodev_sym_session_clear;
+ rte_cryptodev_sym_session_create;
+ rte_cryptodev_sym_session_free;
+ rte_cryptodev_sym_session_init;
+ rte_cryptodevs;
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_distributor/rte_distributor_version.map b/lib/librte_distributor/rte_distributor_version.map
index 5643ab85fb..1b7c643005 100644
--- a/lib/librte_distributor/rte_distributor_version.map
+++ b/lib/librte_distributor/rte_distributor_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_distributor_clear_returns;
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7cbf82d37b..8c41999317 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
__rte_panic;
@@ -7,46 +7,111 @@ DPDK_2.0 {
lcore_config;
per_lcore__lcore_id;
per_lcore__rte_errno;
+ rte_bus_dump;
+ rte_bus_find;
+ rte_bus_find_by_device;
+ rte_bus_find_by_name;
+ rte_bus_get_iommu_class;
+ rte_bus_probe;
+ rte_bus_register;
+ rte_bus_scan;
+ rte_bus_unregister;
rte_calloc;
rte_calloc_socket;
rte_cpu_check_supported;
rte_cpu_get_flag_enabled;
+ rte_cpu_get_flag_name;
+ rte_cpu_is_supported;
+ rte_ctrl_thread_create;
rte_cycles_vmware_tsc_map;
rte_delay_us;
+ rte_delay_us_block;
+ rte_delay_us_callback_register;
+ rte_dev_is_probed;
+ rte_dev_probe;
+ rte_dev_remove;
+ rte_devargs_add;
+ rte_devargs_dump;
+ rte_devargs_insert;
+ rte_devargs_next;
+ rte_devargs_parse;
+ rte_devargs_parsef;
+ rte_devargs_remove;
+ rte_devargs_type_count;
rte_dump_physmem_layout;
rte_dump_registers;
rte_dump_stack;
rte_dump_tailq;
rte_eal_alarm_cancel;
rte_eal_alarm_set;
+ rte_eal_cleanup;
+ rte_eal_create_uio_dev;
rte_eal_get_configuration;
rte_eal_get_lcore_state;
rte_eal_get_physmem_size;
+ rte_eal_get_runtime_dir;
rte_eal_has_hugepages;
+ rte_eal_has_pci;
+ rte_eal_hotplug_add;
+ rte_eal_hotplug_remove;
rte_eal_hpet_init;
rte_eal_init;
rte_eal_iopl_init;
+ rte_eal_iova_mode;
rte_eal_lcore_role;
+ rte_eal_mbuf_user_pool_ops;
rte_eal_mp_remote_launch;
rte_eal_mp_wait_lcore;
+ rte_eal_primary_proc_alive;
rte_eal_process_type;
rte_eal_remote_launch;
rte_eal_tailq_lookup;
rte_eal_tailq_register;
+ rte_eal_using_phys_addrs;
+ rte_eal_vfio_intr_mode;
rte_eal_wait_lcore;
+ rte_epoll_ctl;
+ rte_epoll_wait;
rte_exit;
rte_free;
rte_get_hpet_cycles;
rte_get_hpet_hz;
rte_get_tsc_hz;
rte_hexdump;
+ rte_hypervisor_get;
+ rte_hypervisor_get_name;
+ rte_intr_allow_others;
rte_intr_callback_register;
rte_intr_callback_unregister;
+ rte_intr_cap_multiple;
rte_intr_disable;
+ rte_intr_dp_is_en;
+ rte_intr_efd_disable;
+ rte_intr_efd_enable;
rte_intr_enable;
+ rte_intr_free_epoll_fd;
+ rte_intr_rx_ctl;
+ rte_intr_tls_epfd;
+ rte_keepalive_create;
+ rte_keepalive_dispatch_pings;
+ rte_keepalive_mark_alive;
+ rte_keepalive_mark_sleep;
+ rte_keepalive_register_core;
+ rte_keepalive_register_relay_callback;
+ rte_lcore_has_role;
+ rte_lcore_index;
+ rte_lcore_to_socket_id;
rte_log;
rte_log_cur_msg_loglevel;
rte_log_cur_msg_logtype;
+ rte_log_dump;
+ rte_log_get_global_level;
+ rte_log_get_level;
+ rte_log_register;
+ rte_log_set_global_level;
+ rte_log_set_level;
+ rte_log_set_level_pattern;
+ rte_log_set_level_regexp;
rte_logs;
rte_malloc;
rte_malloc_dump_stats;
@@ -54,155 +119,38 @@ DPDK_2.0 {
rte_malloc_set_limit;
rte_malloc_socket;
rte_malloc_validate;
+ rte_malloc_virt2iova;
+ rte_mcfg_mem_read_lock;
+ rte_mcfg_mem_read_unlock;
+ rte_mcfg_mem_write_lock;
+ rte_mcfg_mem_write_unlock;
+ rte_mcfg_mempool_read_lock;
+ rte_mcfg_mempool_read_unlock;
+ rte_mcfg_mempool_write_lock;
+ rte_mcfg_mempool_write_unlock;
+ rte_mcfg_tailq_read_lock;
+ rte_mcfg_tailq_read_unlock;
+ rte_mcfg_tailq_write_lock;
+ rte_mcfg_tailq_write_unlock;
rte_mem_lock_page;
+ rte_mem_virt2iova;
rte_mem_virt2phy;
rte_memdump;
rte_memory_get_nchannel;
rte_memory_get_nrank;
rte_memzone_dump;
+ rte_memzone_free;
rte_memzone_lookup;
rte_memzone_reserve;
rte_memzone_reserve_aligned;
rte_memzone_reserve_bounded;
rte_memzone_walk;
rte_openlog_stream;
+ rte_rand;
rte_realloc;
- rte_set_application_usage_hook;
- rte_socket_id;
- rte_strerror;
- rte_strsplit;
- rte_sys_gettid;
- rte_thread_get_affinity;
- rte_thread_set_affinity;
- rte_vlog;
- rte_zmalloc;
- rte_zmalloc_socket;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_epoll_ctl;
- rte_epoll_wait;
- rte_intr_allow_others;
- rte_intr_dp_is_en;
- rte_intr_efd_disable;
- rte_intr_efd_enable;
- rte_intr_rx_ctl;
- rte_intr_tls_epfd;
- rte_memzone_free;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_intr_cap_multiple;
- rte_keepalive_create;
- rte_keepalive_dispatch_pings;
- rte_keepalive_mark_alive;
- rte_keepalive_register_core;
-
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_cpu_get_flag_name;
- rte_eal_primary_proc_alive;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_keepalive_mark_sleep;
- rte_keepalive_register_relay_callback;
- rte_rtm_supported;
- rte_thread_setname;
-
-} DPDK_16.04;
-
-DPDK_16.11 {
- global:
-
- rte_delay_us_block;
- rte_delay_us_callback_register;
-
-} DPDK_16.07;
-
-DPDK_17.02 {
- global:
-
- rte_bus_dump;
- rte_bus_probe;
- rte_bus_register;
- rte_bus_scan;
- rte_bus_unregister;
-
-} DPDK_16.11;
-
-DPDK_17.05 {
- global:
-
- rte_cpu_is_supported;
- rte_intr_free_epoll_fd;
- rte_log_dump;
- rte_log_get_global_level;
- rte_log_register;
- rte_log_set_global_level;
- rte_log_set_level;
- rte_log_set_level_regexp;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_bus_find;
- rte_bus_find_by_device;
- rte_bus_find_by_name;
- rte_log_get_level;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eal_create_uio_dev;
- rte_bus_get_iommu_class;
- rte_eal_has_pci;
- rte_eal_iova_mode;
- rte_eal_using_phys_addrs;
- rte_eal_vfio_intr_mode;
- rte_lcore_has_role;
- rte_malloc_virt2iova;
- rte_mem_virt2iova;
- rte_vfio_enable;
- rte_vfio_is_enabled;
- rte_vfio_noiommu_is_enabled;
- rte_vfio_release_device;
- rte_vfio_setup_device;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_hypervisor_get;
- rte_hypervisor_get_name;
- rte_vfio_clear_group;
rte_reciprocal_value;
rte_reciprocal_value_u64;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_log_set_level_pattern;
+ rte_rtm_supported;
rte_service_attr_get;
rte_service_attr_reset_all;
rte_service_component_register;
@@ -215,6 +163,8 @@ DPDK_18.05 {
rte_service_get_count;
rte_service_get_name;
rte_service_lcore_add;
+ rte_service_lcore_attr_get;
+ rte_service_lcore_attr_reset_all;
rte_service_lcore_count;
rte_service_lcore_count_services;
rte_service_lcore_del;
@@ -224,6 +174,7 @@ DPDK_18.05 {
rte_service_lcore_stop;
rte_service_map_lcore_get;
rte_service_map_lcore_set;
+ rte_service_may_be_active;
rte_service_probe_capability;
rte_service_run_iter_on_app_lcore;
rte_service_runstate_get;
@@ -231,17 +182,23 @@ DPDK_18.05 {
rte_service_set_runstate_mapped_check;
rte_service_set_stats_enable;
rte_service_start_with_defaults;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eal_mbuf_user_pool_ops;
+ rte_set_application_usage_hook;
+ rte_socket_count;
+ rte_socket_id;
+ rte_socket_id_by_idx;
+ rte_srand;
+ rte_strerror;
+ rte_strscpy;
+ rte_strsplit;
+ rte_sys_gettid;
+ rte_thread_get_affinity;
+ rte_thread_set_affinity;
+ rte_thread_setname;
rte_uuid_compare;
rte_uuid_is_null;
rte_uuid_parse;
rte_uuid_unparse;
+ rte_vfio_clear_group;
rte_vfio_container_create;
rte_vfio_container_destroy;
rte_vfio_container_dma_map;
@@ -250,67 +207,20 @@ DPDK_18.08 {
rte_vfio_container_group_unbind;
rte_vfio_dma_map;
rte_vfio_dma_unmap;
+ rte_vfio_enable;
rte_vfio_get_container_fd;
rte_vfio_get_group_fd;
rte_vfio_get_group_num;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_dev_probe;
- rte_dev_remove;
- rte_eal_get_runtime_dir;
- rte_eal_hotplug_add;
- rte_eal_hotplug_remove;
- rte_strscpy;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_ctrl_thread_create;
- rte_dev_is_probed;
- rte_devargs_add;
- rte_devargs_dump;
- rte_devargs_insert;
- rte_devargs_next;
- rte_devargs_parse;
- rte_devargs_parsef;
- rte_devargs_remove;
- rte_devargs_type_count;
- rte_eal_cleanup;
- rte_socket_count;
- rte_socket_id_by_idx;
-
-} DPDK_18.11;
-
-DPDK_19.08 {
- global:
-
- rte_lcore_index;
- rte_lcore_to_socket_id;
- rte_mcfg_mem_read_lock;
- rte_mcfg_mem_read_unlock;
- rte_mcfg_mem_write_lock;
- rte_mcfg_mem_write_unlock;
- rte_mcfg_mempool_read_lock;
- rte_mcfg_mempool_read_unlock;
- rte_mcfg_mempool_write_lock;
- rte_mcfg_mempool_write_unlock;
- rte_mcfg_tailq_read_lock;
- rte_mcfg_tailq_read_unlock;
- rte_mcfg_tailq_write_lock;
- rte_mcfg_tailq_write_unlock;
- rte_rand;
- rte_service_lcore_attr_get;
- rte_service_lcore_attr_reset_all;
- rte_service_may_be_active;
- rte_srand;
-
-} DPDK_19.05;
+ rte_vfio_is_enabled;
+ rte_vfio_noiommu_is_enabled;
+ rte_vfio_release_device;
+ rte_vfio_setup_device;
+ rte_vlog;
+ rte_zmalloc;
+ rte_zmalloc_socket;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_efd/rte_efd_version.map b/lib/librte_efd/rte_efd_version.map
index ae60a64178..e010eecfe4 100644
--- a/lib/librte_efd/rte_efd_version.map
+++ b/lib/librte_efd/rte_efd_version.map
@@ -1,4 +1,4 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_efd_create;
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b8..9e1dbdebb4 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -1,35 +1,53 @@
-DPDK_2.2 {
+DPDK_20.0 {
global:
+ _rte_eth_dev_callback_process;
+ _rte_eth_dev_reset;
+ rte_eth_add_first_rx_callback;
rte_eth_add_rx_callback;
rte_eth_add_tx_callback;
rte_eth_allmulticast_disable;
rte_eth_allmulticast_enable;
rte_eth_allmulticast_get;
+ rte_eth_dev_adjust_nb_rx_tx_desc;
rte_eth_dev_allocate;
rte_eth_dev_allocated;
+ rte_eth_dev_attach_secondary;
rte_eth_dev_callback_register;
rte_eth_dev_callback_unregister;
rte_eth_dev_close;
rte_eth_dev_configure;
rte_eth_dev_count;
+ rte_eth_dev_count_avail;
+ rte_eth_dev_count_total;
rte_eth_dev_default_mac_addr_set;
+ rte_eth_dev_filter_ctrl;
rte_eth_dev_filter_supported;
rte_eth_dev_flow_ctrl_get;
rte_eth_dev_flow_ctrl_set;
+ rte_eth_dev_fw_version_get;
rte_eth_dev_get_dcb_info;
rte_eth_dev_get_eeprom;
rte_eth_dev_get_eeprom_length;
rte_eth_dev_get_mtu;
+ rte_eth_dev_get_name_by_port;
+ rte_eth_dev_get_port_by_name;
rte_eth_dev_get_reg_info;
+ rte_eth_dev_get_sec_ctx;
+ rte_eth_dev_get_supported_ptypes;
rte_eth_dev_get_vlan_offload;
- rte_eth_devices;
rte_eth_dev_info_get;
rte_eth_dev_is_valid_port;
+ rte_eth_dev_l2_tunnel_eth_type_conf;
+ rte_eth_dev_l2_tunnel_offload_set;
+ rte_eth_dev_logtype;
rte_eth_dev_mac_addr_add;
rte_eth_dev_mac_addr_remove;
+ rte_eth_dev_pool_ops_supported;
rte_eth_dev_priority_flow_ctrl_set;
+ rte_eth_dev_probing_finish;
rte_eth_dev_release_port;
+ rte_eth_dev_reset;
rte_eth_dev_rss_hash_conf_get;
rte_eth_dev_rss_hash_update;
rte_eth_dev_rss_reta_query;
@@ -38,6 +56,7 @@ DPDK_2.2 {
rte_eth_dev_rx_intr_ctl_q;
rte_eth_dev_rx_intr_disable;
rte_eth_dev_rx_intr_enable;
+ rte_eth_dev_rx_offload_name;
rte_eth_dev_rx_queue_start;
rte_eth_dev_rx_queue_stop;
rte_eth_dev_set_eeprom;
@@ -47,18 +66,28 @@ DPDK_2.2 {
rte_eth_dev_set_mtu;
rte_eth_dev_set_rx_queue_stats_mapping;
rte_eth_dev_set_tx_queue_stats_mapping;
+ rte_eth_dev_set_vlan_ether_type;
rte_eth_dev_set_vlan_offload;
rte_eth_dev_set_vlan_pvid;
rte_eth_dev_set_vlan_strip_on_queue;
rte_eth_dev_socket_id;
rte_eth_dev_start;
rte_eth_dev_stop;
+ rte_eth_dev_tx_offload_name;
rte_eth_dev_tx_queue_start;
rte_eth_dev_tx_queue_stop;
rte_eth_dev_uc_all_hash_table_set;
rte_eth_dev_uc_hash_table_set;
+ rte_eth_dev_udp_tunnel_port_add;
+ rte_eth_dev_udp_tunnel_port_delete;
rte_eth_dev_vlan_filter;
+ rte_eth_devices;
rte_eth_dma_zone_reserve;
+ rte_eth_find_next;
+ rte_eth_find_next_owned_by;
+ rte_eth_iterator_cleanup;
+ rte_eth_iterator_init;
+ rte_eth_iterator_next;
rte_eth_led_off;
rte_eth_led_on;
rte_eth_link;
@@ -75,6 +104,7 @@ DPDK_2.2 {
rte_eth_rx_queue_info_get;
rte_eth_rx_queue_setup;
rte_eth_set_queue_rate_limit;
+ rte_eth_speed_bitflag;
rte_eth_stats;
rte_eth_stats_get;
rte_eth_stats_reset;
@@ -85,66 +115,27 @@ DPDK_2.2 {
rte_eth_timesync_read_time;
rte_eth_timesync_read_tx_timestamp;
rte_eth_timesync_write_time;
- rte_eth_tx_queue_info_get;
- rte_eth_tx_queue_setup;
- rte_eth_xstats_get;
- rte_eth_xstats_reset;
-
- local: *;
-};
-
-DPDK_16.04 {
- global:
-
- rte_eth_dev_get_supported_ptypes;
- rte_eth_dev_l2_tunnel_eth_type_conf;
- rte_eth_dev_l2_tunnel_offload_set;
- rte_eth_dev_set_vlan_ether_type;
- rte_eth_dev_udp_tunnel_port_add;
- rte_eth_dev_udp_tunnel_port_delete;
- rte_eth_speed_bitflag;
rte_eth_tx_buffer_count_callback;
rte_eth_tx_buffer_drop_callback;
rte_eth_tx_buffer_init;
rte_eth_tx_buffer_set_err_callback;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_eth_add_first_rx_callback;
- rte_eth_dev_get_name_by_port;
- rte_eth_dev_get_port_by_name;
- rte_eth_xstats_get_names;
-
-} DPDK_16.04;
-
-DPDK_17.02 {
- global:
-
- _rte_eth_dev_reset;
- rte_eth_dev_fw_version_get;
-
-} DPDK_16.07;
-
-DPDK_17.05 {
- global:
-
- rte_eth_dev_attach_secondary;
- rte_eth_find_next;
rte_eth_tx_done_cleanup;
+ rte_eth_tx_queue_info_get;
+ rte_eth_tx_queue_setup;
+ rte_eth_xstats_get;
rte_eth_xstats_get_by_id;
rte_eth_xstats_get_id_by_name;
+ rte_eth_xstats_get_names;
rte_eth_xstats_get_names_by_id;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- _rte_eth_dev_callback_process;
- rte_eth_dev_adjust_nb_rx_tx_desc;
+ rte_eth_xstats_reset;
+ rte_flow_copy;
+ rte_flow_create;
+ rte_flow_destroy;
+ rte_flow_error_set;
+ rte_flow_flush;
+ rte_flow_isolate;
+ rte_flow_query;
+ rte_flow_validate;
rte_tm_capabilities_get;
rte_tm_get_number_of_leaf_nodes;
rte_tm_hierarchy_commit;
@@ -176,65 +167,8 @@ DPDK_17.08 {
rte_tm_wred_profile_add;
rte_tm_wred_profile_delete;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eth_dev_get_sec_ctx;
- rte_eth_dev_pool_ops_supported;
- rte_eth_dev_reset;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_eth_dev_filter_ctrl;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_eth_dev_count_avail;
- rte_eth_dev_probing_finish;
- rte_eth_find_next_owned_by;
- rte_flow_copy;
- rte_flow_create;
- rte_flow_destroy;
- rte_flow_error_set;
- rte_flow_flush;
- rte_flow_isolate;
- rte_flow_query;
- rte_flow_validate;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eth_dev_logtype;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_eth_dev_rx_offload_name;
- rte_eth_dev_tx_offload_name;
- rte_eth_iterator_cleanup;
- rte_eth_iterator_init;
- rte_eth_iterator_next;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_eth_dev_count_total;
-
-} DPDK_18.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index 76b3021d3a..edfc15282d 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -1,61 +1,38 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
- rte_eventdevs;
-
+ rte_event_crypto_adapter_caps_get;
+ rte_event_crypto_adapter_create;
+ rte_event_crypto_adapter_create_ext;
+ rte_event_crypto_adapter_event_port_get;
+ rte_event_crypto_adapter_free;
+ rte_event_crypto_adapter_queue_pair_add;
+ rte_event_crypto_adapter_queue_pair_del;
+ rte_event_crypto_adapter_service_id_get;
+ rte_event_crypto_adapter_start;
+ rte_event_crypto_adapter_stats_get;
+ rte_event_crypto_adapter_stats_reset;
+ rte_event_crypto_adapter_stop;
+ rte_event_dequeue_timeout_ticks;
+ rte_event_dev_attr_get;
+ rte_event_dev_close;
+ rte_event_dev_configure;
rte_event_dev_count;
+ rte_event_dev_dump;
rte_event_dev_get_dev_id;
- rte_event_dev_socket_id;
rte_event_dev_info_get;
- rte_event_dev_configure;
+ rte_event_dev_selftest;
+ rte_event_dev_service_id_get;
+ rte_event_dev_socket_id;
rte_event_dev_start;
rte_event_dev_stop;
- rte_event_dev_close;
- rte_event_dev_dump;
+ rte_event_dev_stop_flush_callback_register;
rte_event_dev_xstats_by_name_get;
rte_event_dev_xstats_get;
rte_event_dev_xstats_names_get;
rte_event_dev_xstats_reset;
-
- rte_event_port_default_conf_get;
- rte_event_port_setup;
- rte_event_port_link;
- rte_event_port_unlink;
- rte_event_port_links_get;
-
- rte_event_queue_default_conf_get;
- rte_event_queue_setup;
-
- rte_event_dequeue_timeout_ticks;
-
- rte_event_pmd_allocate;
- rte_event_pmd_release;
- rte_event_pmd_vdev_init;
- rte_event_pmd_vdev_uninit;
- rte_event_pmd_pci_probe;
- rte_event_pmd_pci_remove;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- rte_event_ring_create;
- rte_event_ring_free;
- rte_event_ring_init;
- rte_event_ring_lookup;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_event_dev_attr_get;
- rte_event_dev_service_id_get;
- rte_event_port_attr_get;
- rte_event_queue_attr_get;
-
rte_event_eth_rx_adapter_caps_get;
+ rte_event_eth_rx_adapter_cb_register;
rte_event_eth_rx_adapter_create;
rte_event_eth_rx_adapter_create_ext;
rte_event_eth_rx_adapter_free;
@@ -63,38 +40,9 @@ DPDK_17.11 {
rte_event_eth_rx_adapter_queue_del;
rte_event_eth_rx_adapter_service_id_get;
rte_event_eth_rx_adapter_start;
+ rte_event_eth_rx_adapter_stats_get;
rte_event_eth_rx_adapter_stats_reset;
rte_event_eth_rx_adapter_stop;
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_event_dev_selftest;
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_event_dev_stop_flush_callback_register;
-} DPDK_18.02;
-
-DPDK_19.05 {
- global:
-
- rte_event_crypto_adapter_caps_get;
- rte_event_crypto_adapter_create;
- rte_event_crypto_adapter_create_ext;
- rte_event_crypto_adapter_event_port_get;
- rte_event_crypto_adapter_free;
- rte_event_crypto_adapter_queue_pair_add;
- rte_event_crypto_adapter_queue_pair_del;
- rte_event_crypto_adapter_service_id_get;
- rte_event_crypto_adapter_start;
- rte_event_crypto_adapter_stats_get;
- rte_event_crypto_adapter_stats_reset;
- rte_event_crypto_adapter_stop;
- rte_event_port_unlinks_in_progress;
rte_event_eth_tx_adapter_caps_get;
rte_event_eth_tx_adapter_create;
rte_event_eth_tx_adapter_create_ext;
@@ -107,6 +55,26 @@ DPDK_19.05 {
rte_event_eth_tx_adapter_stats_get;
rte_event_eth_tx_adapter_stats_reset;
rte_event_eth_tx_adapter_stop;
+ rte_event_pmd_allocate;
+ rte_event_pmd_pci_probe;
+ rte_event_pmd_pci_remove;
+ rte_event_pmd_release;
+ rte_event_pmd_vdev_init;
+ rte_event_pmd_vdev_uninit;
+ rte_event_port_attr_get;
+ rte_event_port_default_conf_get;
+ rte_event_port_link;
+ rte_event_port_links_get;
+ rte_event_port_setup;
+ rte_event_port_unlink;
+ rte_event_port_unlinks_in_progress;
+ rte_event_queue_attr_get;
+ rte_event_queue_default_conf_get;
+ rte_event_queue_setup;
+ rte_event_ring_create;
+ rte_event_ring_free;
+ rte_event_ring_init;
+ rte_event_ring_lookup;
rte_event_timer_adapter_caps_get;
rte_event_timer_adapter_create;
rte_event_timer_adapter_create_ext;
@@ -121,11 +89,7 @@ DPDK_19.05 {
rte_event_timer_arm_burst;
rte_event_timer_arm_tmo_tick_burst;
rte_event_timer_cancel_burst;
-} DPDK_18.05;
+ rte_eventdevs;
-DPDK_19.08 {
- global:
-
- rte_event_eth_rx_adapter_cb_register;
- rte_event_eth_rx_adapter_stats_get;
-} DPDK_19.05;
+ local: *;
+};
diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map b/lib/librte_flow_classify/rte_flow_classify_version.map
index 49bc25c6a0..001ff660e3 100644
--- a/lib/librte_flow_classify/rte_flow_classify_version.map
+++ b/lib/librte_flow_classify/rte_flow_classify_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_gro/rte_gro_version.map b/lib/librte_gro/rte_gro_version.map
index 1606b6dc72..9f6fe79e57 100644
--- a/lib/librte_gro/rte_gro_version.map
+++ b/lib/librte_gro/rte_gro_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_gro_ctx_create;
diff --git a/lib/librte_gso/rte_gso_version.map b/lib/librte_gso/rte_gso_version.map
index e1fd453edb..8505a59c27 100644
--- a/lib/librte_gso/rte_gso_version.map
+++ b/lib/librte_gso/rte_gso_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_gso_segment;
diff --git a/lib/librte_hash/rte_hash_version.map b/lib/librte_hash/rte_hash_version.map
index 734ae28b04..138c130c1b 100644
--- a/lib/librte_hash/rte_hash_version.map
+++ b/lib/librte_hash/rte_hash_version.map
@@ -1,58 +1,33 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_fbk_hash_create;
rte_fbk_hash_find_existing;
rte_fbk_hash_free;
rte_hash_add_key;
+ rte_hash_add_key_data;
rte_hash_add_key_with_hash;
+ rte_hash_add_key_with_hash_data;
+ rte_hash_count;
rte_hash_create;
rte_hash_del_key;
rte_hash_del_key_with_hash;
rte_hash_find_existing;
rte_hash_free;
+ rte_hash_get_key_with_position;
rte_hash_hash;
+ rte_hash_iterate;
rte_hash_lookup;
rte_hash_lookup_bulk;
- rte_hash_lookup_with_hash;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_hash_add_key_data;
- rte_hash_add_key_with_hash_data;
- rte_hash_iterate;
rte_hash_lookup_bulk_data;
rte_hash_lookup_data;
+ rte_hash_lookup_with_hash;
rte_hash_lookup_with_hash_data;
rte_hash_reset;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_hash_set_cmp_func;
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_hash_get_key_with_position;
-
-} DPDK_2.2;
-
-
-DPDK_18.08 {
- global:
-
- rte_hash_count;
-
-} DPDK_16.07;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
index a193007c61..5dd34f828c 100644
--- a/lib/librte_ip_frag/rte_ip_frag_version.map
+++ b/lib/librte_ip_frag/rte_ip_frag_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ip_frag_free_death_row;
rte_ip_frag_table_create;
+ rte_ip_frag_table_destroy;
rte_ip_frag_table_statistics_dump;
rte_ipv4_frag_reassemble_packet;
rte_ipv4_fragment_packet;
@@ -12,13 +13,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_17.08 {
- global:
-
- rte_ip_frag_table_destroy;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_ipsec/rte_ipsec_version.map b/lib/librte_ipsec/rte_ipsec_version.map
index ee9f1961b0..3723b812fc 100644
--- a/lib/librte_ipsec/rte_ipsec_version.map
+++ b/lib/librte_ipsec/rte_ipsec_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_jobstats/rte_jobstats_version.map b/lib/librte_jobstats/rte_jobstats_version.map
index f89441438e..dbd2664ae2 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -1,6 +1,7 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_jobstats_abort;
rte_jobstats_context_finish;
rte_jobstats_context_init;
rte_jobstats_context_reset;
@@ -17,10 +18,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_jobstats_abort;
-
-} DPDK_2.0;
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6aaa..9cd3cedc54 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kni_alloc;
diff --git a/lib/librte_kvargs/rte_kvargs_version.map b/lib/librte_kvargs/rte_kvargs_version.map
index 8f4b4e3f8f..3ba0f4b59c 100644
--- a/lib/librte_kvargs/rte_kvargs_version.map
+++ b/lib/librte_kvargs/rte_kvargs_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kvargs_count;
@@ -15,4 +15,4 @@ EXPERIMENTAL {
rte_kvargs_parse_delim;
rte_kvargs_strcmp;
-} DPDK_2.0;
+};
diff --git a/lib/librte_latencystats/rte_latencystats_version.map b/lib/librte_latencystats/rte_latencystats_version.map
index ac8403e821..e04e63463f 100644
--- a/lib/librte_latencystats/rte_latencystats_version.map
+++ b/lib/librte_latencystats/rte_latencystats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_latencystats_get;
diff --git a/lib/librte_lpm/rte_lpm_version.map b/lib/librte_lpm/rte_lpm_version.map
index 90beac853d..500f58b806 100644
--- a/lib/librte_lpm/rte_lpm_version.map
+++ b/lib/librte_lpm/rte_lpm_version.map
@@ -1,13 +1,6 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
- rte_lpm_add;
- rte_lpm_create;
- rte_lpm_delete;
- rte_lpm_delete_all;
- rte_lpm_find_existing;
- rte_lpm_free;
- rte_lpm_is_rule_present;
rte_lpm6_add;
rte_lpm6_create;
rte_lpm6_delete;
@@ -18,29 +11,13 @@ DPDK_2.0 {
rte_lpm6_is_rule_present;
rte_lpm6_lookup;
rte_lpm6_lookup_bulk_func;
+ rte_lpm_add;
+ rte_lpm_create;
+ rte_lpm_delete;
+ rte_lpm_delete_all;
+ rte_lpm_find_existing;
+ rte_lpm_free;
+ rte_lpm_is_rule_present;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_lpm_add;
- rte_lpm_find_existing;
- rte_lpm_create;
- rte_lpm_free;
- rte_lpm_is_rule_present;
- rte_lpm_delete;
- rte_lpm_delete_all;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_lpm6_add;
- rte_lpm6_is_rule_present;
- rte_lpm6_lookup;
- rte_lpm6_lookup_bulk_func;
-
-} DPDK_16.04;
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index 2662a37bf6..d20aa31857 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -1,24 +1,4 @@
-DPDK_2.0 {
- global:
-
- rte_get_rx_ol_flag_name;
- rte_get_tx_ol_flag_name;
- rte_mbuf_sanity_check;
- rte_pktmbuf_dump;
- rte_pktmbuf_init;
- rte_pktmbuf_pool_init;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pktmbuf_pool_create;
-
-} DPDK_2.0;
-
-DPDK_16.11 {
+DPDK_20.0 {
global:
__rte_pktmbuf_read;
@@ -31,23 +11,26 @@ DPDK_16.11 {
rte_get_ptype_name;
rte_get_ptype_tunnel_name;
rte_get_rx_ol_flag_list;
+ rte_get_rx_ol_flag_name;
rte_get_tx_ol_flag_list;
-
-} DPDK_2.1;
-
-DPDK_18.08 {
- global:
-
+ rte_get_tx_ol_flag_name;
rte_mbuf_best_mempool_ops;
rte_mbuf_platform_mempool_ops;
+ rte_mbuf_sanity_check;
rte_mbuf_set_platform_mempool_ops;
rte_mbuf_set_user_mempool_ops;
rte_mbuf_user_mempool_ops;
+ rte_pktmbuf_dump;
+ rte_pktmbuf_init;
+ rte_pktmbuf_pool_create;
rte_pktmbuf_pool_create_by_ops;
-} DPDK_16.11;
+ rte_pktmbuf_pool_init;
+
+ local: *;
+};
EXPERIMENTAL {
global:
rte_mbuf_check;
-} DPDK_18.08;
+};
diff --git a/lib/librte_member/rte_member_version.map b/lib/librte_member/rte_member_version.map
index 019e4cd962..87780ae611 100644
--- a/lib/librte_member/rte_member_version.map
+++ b/lib/librte_member/rte_member_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_member_add;
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 17cbca4607..6a425d203a 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_mempool_audit;
- rte_mempool_calc_obj_size;
- rte_mempool_create;
- rte_mempool_dump;
- rte_mempool_list_dump;
- rte_mempool_lookup;
- rte_mempool_walk;
-
- local: *;
-};
-
-DPDK_16.07 {
- global:
-
rte_mempool_avail_count;
rte_mempool_cache_create;
rte_mempool_cache_flush;
rte_mempool_cache_free;
+ rte_mempool_calc_obj_size;
rte_mempool_check_cookies;
+ rte_mempool_contig_blocks_check_cookies;
+ rte_mempool_create;
rte_mempool_create_empty;
rte_mempool_default_cache;
+ rte_mempool_dump;
rte_mempool_free;
rte_mempool_generic_get;
rte_mempool_generic_put;
rte_mempool_in_use_count;
+ rte_mempool_list_dump;
+ rte_mempool_lookup;
rte_mempool_mem_iter;
rte_mempool_obj_iter;
+ rte_mempool_op_calc_mem_size_default;
+ rte_mempool_op_populate_default;
rte_mempool_ops_table;
rte_mempool_populate_anon;
rte_mempool_populate_default;
+ rte_mempool_populate_iova;
rte_mempool_populate_virt;
rte_mempool_register_ops;
rte_mempool_set_ops_byname;
+ rte_mempool_walk;
-} DPDK_2.0;
-
-DPDK_17.11 {
- global:
-
- rte_mempool_populate_iova;
-
-} DPDK_16.07;
-
-DPDK_18.05 {
- global:
-
- rte_mempool_contig_blocks_check_cookies;
- rte_mempool_op_calc_mem_size_default;
- rte_mempool_op_populate_default;
-
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 4b460d5803..46410b0369 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -1,21 +1,16 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_meter_srtcm_color_aware_check;
rte_meter_srtcm_color_blind_check;
rte_meter_srtcm_config;
+ rte_meter_srtcm_profile_config;
rte_meter_trtcm_color_aware_check;
rte_meter_trtcm_color_blind_check;
rte_meter_trtcm_config;
-
- local: *;
-};
-
-DPDK_18.08 {
- global:
-
- rte_meter_srtcm_profile_config;
rte_meter_trtcm_profile_config;
+
+ local: *;
};
EXPERIMENTAL {
diff --git a/lib/librte_metrics/rte_metrics_version.map b/lib/librte_metrics/rte_metrics_version.map
index 6ac99a44a1..85663f356e 100644
--- a/lib/librte_metrics/rte_metrics_version.map
+++ b/lib/librte_metrics/rte_metrics_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_metrics_get_names;
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index fffc4a3723..8a4e75a3a0 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -1,25 +1,14 @@
-DPDK_16.11 {
- global:
- rte_net_get_ptype;
-
- local: *;
-};
-
-DPDK_17.05 {
- global:
-
- rte_net_crc_calc;
- rte_net_crc_set_alg;
-
-} DPDK_16.11;
-
-DPDK_19.08 {
+DPDK_20.0 {
global:
rte_eth_random_addr;
rte_ether_format_addr;
+ rte_net_crc_calc;
+ rte_net_crc_set_alg;
+ rte_net_get_ptype;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index c0280277bb..539785f5f4 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
eal_parse_pci_BDF;
diff --git a/lib/librte_pdump/rte_pdump_version.map b/lib/librte_pdump/rte_pdump_version.map
index 3e744f3012..6d02ccce6d 100644
--- a/lib/librte_pdump/rte_pdump_version.map
+++ b/lib/librte_pdump/rte_pdump_version.map
@@ -1,4 +1,4 @@
-DPDK_16.07 {
+DPDK_20.0 {
global:
rte_pdump_disable;
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 420f065d6e..64d38afecd 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -1,6 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_pipeline_ah_packet_drop;
+ rte_pipeline_ah_packet_hijack;
rte_pipeline_check;
rte_pipeline_create;
rte_pipeline_flush;
@@ -9,42 +11,22 @@ DPDK_2.0 {
rte_pipeline_port_in_create;
rte_pipeline_port_in_disable;
rte_pipeline_port_in_enable;
+ rte_pipeline_port_in_stats_read;
rte_pipeline_port_out_create;
rte_pipeline_port_out_packet_insert;
+ rte_pipeline_port_out_stats_read;
rte_pipeline_run;
rte_pipeline_table_create;
rte_pipeline_table_default_entry_add;
rte_pipeline_table_default_entry_delete;
rte_pipeline_table_entry_add;
- rte_pipeline_table_entry_delete;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pipeline_port_in_stats_read;
- rte_pipeline_port_out_stats_read;
- rte_pipeline_table_stats_read;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_pipeline_table_entry_add_bulk;
+ rte_pipeline_table_entry_delete;
rte_pipeline_table_entry_delete_bulk;
+ rte_pipeline_table_stats_read;
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_pipeline_ah_packet_hijack;
- rte_pipeline_ah_packet_drop;
-
-} DPDK_2.2;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map
index 609bcec3ff..db1b8681d9 100644
--- a/lib/librte_port/rte_port_version.map
+++ b/lib/librte_port/rte_port_version.map
@@ -1,62 +1,32 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_port_ethdev_reader_ops;
+ rte_port_ethdev_writer_nodrop_ops;
rte_port_ethdev_writer_ops;
+ rte_port_fd_reader_ops;
+ rte_port_fd_writer_nodrop_ops;
+ rte_port_fd_writer_ops;
+ rte_port_kni_reader_ops;
+ rte_port_kni_writer_nodrop_ops;
+ rte_port_kni_writer_ops;
+ rte_port_ring_multi_reader_ops;
+ rte_port_ring_multi_writer_nodrop_ops;
+ rte_port_ring_multi_writer_ops;
rte_port_ring_reader_ipv4_frag_ops;
+ rte_port_ring_reader_ipv6_frag_ops;
rte_port_ring_reader_ops;
rte_port_ring_writer_ipv4_ras_ops;
+ rte_port_ring_writer_ipv6_ras_ops;
+ rte_port_ring_writer_nodrop_ops;
rte_port_ring_writer_ops;
rte_port_sched_reader_ops;
rte_port_sched_writer_ops;
rte_port_sink_ops;
rte_port_source_ops;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_port_ethdev_writer_nodrop_ops;
- rte_port_ring_reader_ipv6_frag_ops;
- rte_port_ring_writer_ipv6_ras_ops;
- rte_port_ring_writer_nodrop_ops;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_port_ring_multi_reader_ops;
- rte_port_ring_multi_writer_ops;
- rte_port_ring_multi_writer_nodrop_ops;
-
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_port_kni_reader_ops;
- rte_port_kni_writer_ops;
- rte_port_kni_writer_nodrop_ops;
-
-} DPDK_2.2;
-
-DPDK_16.11 {
- global:
-
- rte_port_fd_reader_ops;
- rte_port_fd_writer_ops;
- rte_port_fd_writer_nodrop_ops;
-
-} DPDK_16.07;
-
-DPDK_18.11 {
- global:
-
rte_port_sym_crypto_reader_ops;
- rte_port_sym_crypto_writer_ops;
rte_port_sym_crypto_writer_nodrop_ops;
+ rte_port_sym_crypto_writer_ops;
-} DPDK_16.11;
+ local: *;
+};
diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map
index 042917360e..a94ab30c3d 100644
--- a/lib/librte_power/rte_power_version.map
+++ b/lib/librte_power/rte_power_version.map
@@ -1,39 +1,27 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_power_exit;
+ rte_power_freq_disable_turbo;
rte_power_freq_down;
+ rte_power_freq_enable_turbo;
rte_power_freq_max;
rte_power_freq_min;
rte_power_freq_up;
rte_power_freqs;
+ rte_power_get_capabilities;
rte_power_get_env;
rte_power_get_freq;
+ rte_power_guest_channel_send_msg;
rte_power_init;
rte_power_set_env;
rte_power_set_freq;
+ rte_power_turbo_status;
rte_power_unset_env;
local: *;
};
-DPDK_17.11 {
- global:
-
- rte_power_guest_channel_send_msg;
- rte_power_freq_disable_turbo;
- rte_power_freq_enable_turbo;
- rte_power_turbo_status;
-
-} DPDK_2.0;
-
-DPDK_18.08 {
- global:
-
- rte_power_get_capabilities;
-
-} DPDK_17.11;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index b61dbff11c..d847c9e0d3 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -1,4 +1,4 @@
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_rawdev_close;
@@ -17,8 +17,8 @@ DPDK_18.08 {
rte_rawdev_pmd_release;
rte_rawdev_queue_conf_get;
rte_rawdev_queue_count;
- rte_rawdev_queue_setup;
rte_rawdev_queue_release;
+ rte_rawdev_queue_setup;
rte_rawdev_reset;
rte_rawdev_selftest;
rte_rawdev_set_attr;
diff --git a/lib/librte_rcu/rte_rcu_version.map b/lib/librte_rcu/rte_rcu_version.map
index f8b9ef2abb..787e51ef27 100644
--- a/lib/librte_rcu/rte_rcu_version.map
+++ b/lib/librte_rcu/rte_rcu_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_reorder/rte_reorder_version.map b/lib/librte_reorder/rte_reorder_version.map
index 0a8a54de83..cf444062df 100644
--- a/lib/librte_reorder/rte_reorder_version.map
+++ b/lib/librte_reorder/rte_reorder_version.map
@@ -1,13 +1,13 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_reorder_create;
- rte_reorder_init;
+ rte_reorder_drain;
rte_reorder_find_existing;
- rte_reorder_reset;
rte_reorder_free;
+ rte_reorder_init;
rte_reorder_insert;
- rte_reorder_drain;
+ rte_reorder_reset;
local: *;
};
diff --git a/lib/librte_ring/rte_ring_version.map b/lib/librte_ring/rte_ring_version.map
index 510c1386e0..89d84bcf48 100644
--- a/lib/librte_ring/rte_ring_version.map
+++ b/lib/librte_ring/rte_ring_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ring_create;
rte_ring_dump;
+ rte_ring_free;
rte_ring_get_memsize;
rte_ring_init;
rte_ring_list_dump;
@@ -11,13 +12,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.2 {
- global:
-
- rte_ring_free;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_sched/rte_sched_version.map b/lib/librte_sched/rte_sched_version.map
index 729588794e..1b48bfbf36 100644
--- a/lib/librte_sched/rte_sched_version.map
+++ b/lib/librte_sched/rte_sched_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_approx;
@@ -14,6 +14,9 @@ DPDK_2.0 {
rte_sched_port_enqueue;
rte_sched_port_free;
rte_sched_port_get_memory_footprint;
+ rte_sched_port_pkt_read_color;
+ rte_sched_port_pkt_read_tree_path;
+ rte_sched_port_pkt_write;
rte_sched_queue_read_stats;
rte_sched_subport_config;
rte_sched_subport_read_stats;
@@ -21,15 +24,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.1 {
- global:
-
- rte_sched_port_pkt_write;
- rte_sched_port_pkt_read_tree_path;
- rte_sched_port_pkt_read_color;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_security/rte_security_version.map b/lib/librte_security/rte_security_version.map
index 53267bf3cc..b07314bbf4 100644
--- a/lib/librte_security/rte_security_version.map
+++ b/lib/librte_security/rte_security_version.map
@@ -1,4 +1,4 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
rte_security_attach_session;
diff --git a/lib/librte_stack/rte_stack_version.map b/lib/librte_stack/rte_stack_version.map
index 6662679c36..adbb7be9d9 100644
--- a/lib/librte_stack/rte_stack_version.map
+++ b/lib/librte_stack/rte_stack_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_table/rte_table_version.map b/lib/librte_table/rte_table_version.map
index 6237252bec..40f72b1fe8 100644
--- a/lib/librte_table/rte_table_version.map
+++ b/lib/librte_table/rte_table_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_table_acl_ops;
diff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map
index fa62d7718c..c1f4613af5 100644
--- a/lib/librte_telemetry/rte_telemetry_version.map
+++ b/lib/librte_telemetry/rte_telemetry_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_timer/rte_timer_version.map b/lib/librte_timer/rte_timer_version.map
index 72f75c8181..2a59d3f081 100644
--- a/lib/librte_timer/rte_timer_version.map
+++ b/lib/librte_timer/rte_timer_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_timer_dump_stats;
@@ -14,16 +14,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_19.05 {
- global:
-
- rte_timer_dump_stats;
- rte_timer_manage;
- rte_timer_reset;
- rte_timer_stop;
- rte_timer_subsystem_init;
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 5f1d4a75c2..8e9ffac2c2 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -1,64 +1,34 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_vhost_avail_entries;
rte_vhost_dequeue_burst;
rte_vhost_driver_callback_register;
- rte_vhost_driver_register;
- rte_vhost_enable_guest_notification;
- rte_vhost_enqueue_burst;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_vhost_driver_unregister;
-
-} DPDK_2.0;
-
-DPDK_16.07 {
- global:
-
- rte_vhost_avail_entries;
- rte_vhost_get_ifname;
- rte_vhost_get_numa_node;
- rte_vhost_get_queue_num;
-
-} DPDK_2.1;
-
-DPDK_17.05 {
- global:
-
rte_vhost_driver_disable_features;
rte_vhost_driver_enable_features;
rte_vhost_driver_get_features;
+ rte_vhost_driver_register;
rte_vhost_driver_set_features;
rte_vhost_driver_start;
+ rte_vhost_driver_unregister;
+ rte_vhost_enable_guest_notification;
+ rte_vhost_enqueue_burst;
+ rte_vhost_get_ifname;
rte_vhost_get_mem_table;
rte_vhost_get_mtu;
rte_vhost_get_negotiated_features;
+ rte_vhost_get_numa_node;
+ rte_vhost_get_queue_num;
rte_vhost_get_vhost_vring;
rte_vhost_get_vring_num;
rte_vhost_gpa_to_vva;
rte_vhost_log_used_vring;
rte_vhost_log_write;
-
-} DPDK_16.07;
-
-DPDK_17.08 {
- global:
-
rte_vhost_rx_queue_count;
-
-} DPDK_17.05;
-
-DPDK_18.02 {
- global:
-
rte_vhost_vring_call;
-} DPDK_17.08;
+ local: *;
+};
EXPERIMENTAL {
global:
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2 09/10] build: change ABI version to 20.0
` (10 preceding siblings ...)
2019-10-16 12:43 3% ` [dpdk-dev] [PATCH v2 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
@ 2019-10-16 12:43 2% ` Anatoly Burakov
2019-10-16 12:43 23% ` [dpdk-dev] [PATCH v2 10/10] buildtools: add ABI versioning check script Anatoly Burakov
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Pawel Modrak, Nicolas Chautru, Hemant Agrawal, Sachin Saxena,
Rosen Xu, Stephen Hemminger, Anoob Joseph, Tomasz Duszynski,
Liron Himi, Jerin Jacob, Nithin Dabilpuram, Vamsi Attunuru,
Lee Daly, Fiona Trahe, Ashish Gupta, Sunila Sahu, Declan Doherty,
Pablo de Lara, Gagandeep Singh, Ravi Kumar, Akhil Goyal,
Michael Shamis, Nagadheeraj Rottela, Srikanth Jampala, Fan Zhang,
Jay Zhou, Nipun Gupta, Mattias Rönnblom, Pavan Nikhilesh,
Liang Ma, Peter Mccarthy, Harry van Haaren, Artem V. Andreev,
Andrew Rybchenko, Olivier Matz, Gage Eads, John W. Linville,
Xiaolong Ye, Qi Zhang, Shepard Siegel, Ed Czeck, John Miller,
Igor Russkikh, Pavel Belous, Allain Legacy, Matt Peters,
Rasesh Mody, Shahed Shaikh, Ajit Khaparde, Somnath Kotur,
Chas Williams, Rahul Lakkireddy, Wenzhuo Lu, Marcin Wojtas,
Michal Krawczyk, Guy Tzalik, Evgeny Schemeilin, Igor Chauskin,
John Daley, Hyong Youb Kim, Gaetan Rivet, Xiao Wang, Ziyang Xuan,
Xiaoyun Wang, Guoyang Zhou, Wei Hu (Xavier), Min Hu (Connor),
Yisen Zhuang, Beilei Xing, Jingjing Wu, Qiming Yang,
Konstantin Ananyev, Ferruh Yigit, Shijith Thotton,
Srisivasubramanian Srinivasan, Jakub Grajciar, Matan Azrad,
Shahaf Shuler, Viacheslav Ovsiienko, Zyta Szpak,
K. Y. Srinivasan, Haiyang Zhang, Rastislav Cernay, Jan Remes,
Alejandro Lucero, Tetsuya Mukawa, Kiran Kumar K,
Bruce Richardson, Jasvinder Singh, Cristian Dumitrescu,
Keith Wiles, Maciej Czekaj, Maxime Coquelin, Tiwei Bie,
Zhihong Wang, Yong Wang, Tianfei zhang, Xiaoyun Li, Satha Rao,
Shreyansh Jain, David Hunt, Byron Marohn, Yipeng Wang,
Thomas Monjalon, Bernard Iremonger, Jiayu Hu, Sameh Gobriel,
Reshma Pattan, Vladimir Medvedkin, Honnappa Nagarahalli,
Kevin Laatz, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Merge all vesions in linker version script files to DPDK_20.0.
This commit was generated by running the following command:
:~/DPDK$ buildtools/update-abi.sh 20.0
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Regenerated this patch using the new script
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +++----
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++++-----
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 6 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +--
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 ++--
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 ++--
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 ++----
.../rte_distributor_version.map | 16 +-
lib/librte_eal/rte_eal_version.map | 310 +++++++-----------
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +++------
lib/librte_eventdev/rte_eventdev_version.map | 130 +++-----
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +--
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm_version.map | 39 +--
lib/librte_mbuf/rte_mbuf_version.map | 41 +--
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +--
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +---
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +--
154 files changed, 721 insertions(+), 1413 deletions(-)
diff --git a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
index f64b0f9c27..6bcea2cc7f 100644
--- a/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
+++ b/drivers/baseband/fpga_lte_fec/rte_pmd_bbdev_fpga_lte_fec_version.map
@@ -1,10 +1,10 @@
-DPDK_19.08 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
EXPERIMENTAL {
- global:
+ global:
- fpga_lte_fec_configure;
+ fpga_lte_fec_configure;
};
diff --git a/drivers/baseband/null/rte_pmd_bbdev_null_version.map b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/null/rte_pmd_bbdev_null_version.map
+++ b/drivers/baseband/null/rte_pmd_bbdev_null_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
+++ b/drivers/baseband/turbo_sw/rte_pmd_bbdev_turbo_sw_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/bus/dpaa/rte_bus_dpaa_version.map b/drivers/bus/dpaa/rte_bus_dpaa_version.map
index a221522c23..9ab8c76eef 100644
--- a/drivers/bus/dpaa/rte_bus_dpaa_version.map
+++ b/drivers/bus/dpaa/rte_bus_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
bman_acquire;
@@ -8,127 +8,94 @@ DPDK_17.11 {
bman_new_pool;
bman_query_free_buffers;
bman_release;
+ bman_thread_irq;
+ dpaa_logtype_eventdev;
dpaa_logtype_mempool;
dpaa_logtype_pmd;
dpaa_netcfg;
+ dpaa_svr_family;
fman_ccsr_map_fd;
fman_dealloc_bufs_mask_hi;
fman_dealloc_bufs_mask_lo;
fman_if_add_mac_addr;
fman_if_clear_mac_addr;
fman_if_disable_rx;
- fman_if_enable_rx;
fman_if_discard_rx_errors;
- fman_if_get_fc_threshold;
+ fman_if_enable_rx;
fman_if_get_fc_quanta;
+ fman_if_get_fc_threshold;
fman_if_get_fdoff;
+ fman_if_get_sg_enable;
fman_if_loopback_disable;
fman_if_loopback_enable;
fman_if_promiscuous_disable;
fman_if_promiscuous_enable;
fman_if_reset_mcast_filter_table;
fman_if_set_bp;
- fman_if_set_fc_threshold;
fman_if_set_fc_quanta;
+ fman_if_set_fc_threshold;
fman_if_set_fdoff;
fman_if_set_ic_params;
fman_if_set_maxfrm;
fman_if_set_mcast_filter_table;
+ fman_if_set_sg;
fman_if_stats_get;
fman_if_stats_get_all;
fman_if_stats_reset;
fman_ip_rev;
+ fsl_qman_fq_portal_create;
netcfg_acquire;
netcfg_release;
of_find_compatible_node;
+ of_get_mac_address;
of_get_property;
+ per_lcore_dpaa_io;
+ per_lcore_held_bufs;
qm_channel_caam;
+ qm_channel_pool1;
+ qman_alloc_cgrid_range;
+ qman_alloc_pool_range;
+ qman_clear_irq;
+ qman_create_cgr;
qman_create_fq;
+ qman_dca_index;
+ qman_delete_cgr;
qman_dequeue;
qman_dqrr_consume;
qman_enqueue;
qman_enqueue_multi;
+ qman_enqueue_multi_fq;
qman_fq_fqid;
+ qman_fq_portal_irqsource_add;
+ qman_fq_portal_irqsource_remove;
+ qman_fq_portal_thread_irq;
qman_fq_state;
qman_global_init;
qman_init_fq;
- qman_poll_dqrr;
- qman_query_fq_np;
- qman_set_vdq;
- qman_reserve_fqid_range;
- qman_volatile_dequeue;
- rte_dpaa_driver_register;
- rte_dpaa_driver_unregister;
- rte_dpaa_mem_ptov;
- rte_dpaa_portal_init;
-
- local: *;
-};
-
-DPDK_18.02 {
- global:
-
- dpaa_logtype_eventdev;
- dpaa_svr_family;
- per_lcore_dpaa_io;
- per_lcore_held_bufs;
- qm_channel_pool1;
- qman_alloc_cgrid_range;
- qman_alloc_pool_range;
- qman_create_cgr;
- qman_dca_index;
- qman_delete_cgr;
- qman_enqueue_multi_fq;
+ qman_irqsource_add;
+ qman_irqsource_remove;
qman_modify_cgr;
qman_oos_fq;
+ qman_poll_dqrr;
qman_portal_dequeue;
qman_portal_poll_rx;
qman_query_fq_frm_cnt;
+ qman_query_fq_np;
qman_release_cgrid_range;
+ qman_reserve_fqid_range;
qman_retire_fq;
+ qman_set_fq_lookup_table;
+ qman_set_vdq;
qman_static_dequeue_add;
- rte_dpaa_portal_fq_close;
- rte_dpaa_portal_fq_init;
-
-} DPDK_17.11;
-
-DPDK_18.08 {
- global:
-
- fman_if_get_sg_enable;
- fman_if_set_sg;
- of_get_mac_address;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
-
- bman_thread_irq;
- fman_if_get_sg_enable;
- fman_if_set_sg;
- qman_clear_irq;
-
- qman_irqsource_add;
- qman_irqsource_remove;
qman_thread_fd;
qman_thread_irq;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- qman_set_fq_lookup_table;
-
-} DPDK_18.11;
-
-DPDK_19.11 {
- global:
-
- fsl_qman_fq_portal_create;
- qman_fq_portal_irqsource_add;
- qman_fq_portal_irqsource_remove;
- qman_fq_portal_thread_irq;
-
-} DPDK_19.05;
+ qman_volatile_dequeue;
+ rte_dpaa_driver_register;
+ rte_dpaa_driver_unregister;
+ rte_dpaa_mem_ptov;
+ rte_dpaa_portal_fq_close;
+ rte_dpaa_portal_fq_init;
+ rte_dpaa_portal_init;
+
+ local: *;
+};
diff --git a/drivers/bus/fslmc/rte_bus_fslmc_version.map b/drivers/bus/fslmc/rte_bus_fslmc_version.map
index 4da787236b..fe45575046 100644
--- a/drivers/bus/fslmc/rte_bus_fslmc_version.map
+++ b/drivers/bus/fslmc/rte_bus_fslmc_version.map
@@ -1,32 +1,67 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
+ dpaa2_affine_qbman_ethrx_swp;
dpaa2_affine_qbman_swp;
dpaa2_alloc_dpbp_dev;
dpaa2_alloc_dq_storage;
+ dpaa2_dpbp_supported;
+ dpaa2_dqrr_size;
+ dpaa2_eqcr_size;
dpaa2_free_dpbp_dev;
dpaa2_free_dq_storage;
+ dpaa2_free_eq_descriptors;
+ dpaa2_get_qbman_swp;
+ dpaa2_io_portal;
+ dpaa2_svr_family;
+ dpaa2_virt_mode;
dpbp_disable;
dpbp_enable;
dpbp_get_attributes;
dpbp_get_num_free_bufs;
dpbp_open;
dpbp_reset;
+ dpci_get_opr;
+ dpci_set_opr;
+ dpci_set_rx_queue;
+ dpcon_get_attributes;
+ dpcon_open;
+ dpdmai_close;
+ dpdmai_disable;
+ dpdmai_enable;
+ dpdmai_get_attributes;
+ dpdmai_get_rx_queue;
+ dpdmai_get_tx_queue;
+ dpdmai_open;
+ dpdmai_set_rx_queue;
+ dpio_add_static_dequeue_channel;
dpio_close;
dpio_disable;
dpio_enable;
dpio_get_attributes;
dpio_open;
+ dpio_remove_static_dequeue_channel;
dpio_reset;
dpio_set_stashing_destination;
+ mc_get_soc_version;
+ mc_get_version;
mc_send_command;
per_lcore__dpaa2_io;
+ per_lcore_dpaa2_held_bufs;
qbman_check_command_complete;
+ qbman_check_new_result;
qbman_eq_desc_clear;
+ qbman_eq_desc_set_dca;
qbman_eq_desc_set_fq;
qbman_eq_desc_set_no_orp;
+ qbman_eq_desc_set_orp;
qbman_eq_desc_set_qd;
qbman_eq_desc_set_response;
+ qbman_eq_desc_set_token;
+ qbman_fq_query_state;
+ qbman_fq_state_frame_count;
+ qbman_get_dqrr_from_idx;
+ qbman_get_dqrr_idx;
qbman_pull_desc_clear;
qbman_pull_desc_set_fq;
qbman_pull_desc_set_numframes;
@@ -35,112 +70,43 @@ DPDK_17.05 {
qbman_release_desc_set_bpid;
qbman_result_DQ_fd;
qbman_result_DQ_flags;
- qbman_result_has_new_result;
- qbman_swp_acquire;
- qbman_swp_pull;
- qbman_swp_release;
- rte_fslmc_driver_register;
- rte_fslmc_driver_unregister;
- rte_fslmc_vfio_dmamap;
- rte_mcp_ptr_list;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- dpaa2_io_portal;
- dpaa2_get_qbman_swp;
- dpci_set_rx_queue;
- dpcon_open;
- dpcon_get_attributes;
- dpio_add_static_dequeue_channel;
- dpio_remove_static_dequeue_channel;
- mc_get_soc_version;
- mc_get_version;
- qbman_check_new_result;
- qbman_eq_desc_set_dca;
- qbman_get_dqrr_from_idx;
- qbman_get_dqrr_idx;
qbman_result_DQ_fqd_ctx;
+ qbman_result_DQ_odpid;
+ qbman_result_DQ_seqnum;
qbman_result_SCN_state;
+ qbman_result_eqresp_fd;
+ qbman_result_eqresp_rc;
+ qbman_result_eqresp_rspid;
+ qbman_result_eqresp_set_rspid;
+ qbman_result_has_new_result;
+ qbman_swp_acquire;
qbman_swp_dqrr_consume;
+ qbman_swp_dqrr_idx_consume;
qbman_swp_dqrr_next;
qbman_swp_enqueue_multiple;
qbman_swp_enqueue_multiple_desc;
+ qbman_swp_enqueue_multiple_fd;
qbman_swp_interrupt_clear_status;
+ qbman_swp_prefetch_dqrr_next;
+ qbman_swp_pull;
qbman_swp_push_set;
+ qbman_swp_release;
rte_dpaa2_alloc_dpci_dev;
- rte_fslmc_object_register;
- rte_global_active_dqs_list;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- dpaa2_dpbp_supported;
rte_dpaa2_dev_type;
+ rte_dpaa2_free_dpci_dev;
rte_dpaa2_intr_disable;
rte_dpaa2_intr_enable;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- dpaa2_svr_family;
- dpaa2_virt_mode;
- per_lcore_dpaa2_held_bufs;
- qbman_fq_query_state;
- qbman_fq_state_frame_count;
- qbman_swp_dqrr_idx_consume;
- qbman_swp_prefetch_dqrr_next;
- rte_fslmc_get_device_count;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- dpaa2_affine_qbman_ethrx_swp;
- dpdmai_close;
- dpdmai_disable;
- dpdmai_enable;
- dpdmai_get_attributes;
- dpdmai_get_rx_queue;
- dpdmai_get_tx_queue;
- dpdmai_open;
- dpdmai_set_rx_queue;
- rte_dpaa2_free_dpci_dev;
rte_dpaa2_memsegs;
-
-} DPDK_18.02;
-
-DPDK_18.11 {
- global:
- dpaa2_dqrr_size;
- dpaa2_eqcr_size;
- dpci_get_opr;
- dpci_set_opr;
-
-} DPDK_18.05;
-
-DPDK_19.05 {
- global:
- dpaa2_free_eq_descriptors;
-
- qbman_eq_desc_set_orp;
- qbman_eq_desc_set_token;
- qbman_result_DQ_odpid;
- qbman_result_DQ_seqnum;
- qbman_result_eqresp_fd;
- qbman_result_eqresp_rc;
- qbman_result_eqresp_rspid;
- qbman_result_eqresp_set_rspid;
- qbman_swp_enqueue_multiple_fd;
-} DPDK_18.11;
+ rte_fslmc_driver_register;
+ rte_fslmc_driver_unregister;
+ rte_fslmc_get_device_count;
+ rte_fslmc_object_register;
+ rte_fslmc_vfio_dmamap;
+ rte_global_active_dqs_list;
+ rte_mcp_ptr_list;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/bus/ifpga/rte_bus_ifpga_version.map b/drivers/bus/ifpga/rte_bus_ifpga_version.map
index 964c9a9c45..05b4a28c1b 100644
--- a/drivers/bus/ifpga/rte_bus_ifpga_version.map
+++ b/drivers/bus/ifpga/rte_bus_ifpga_version.map
@@ -1,17 +1,11 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
- rte_ifpga_get_integer32_arg;
- rte_ifpga_get_string_arg;
rte_ifpga_driver_register;
rte_ifpga_driver_unregister;
+ rte_ifpga_find_afu_by_name;
+ rte_ifpga_get_integer32_arg;
+ rte_ifpga_get_string_arg;
local: *;
};
-
-DPDK_19.05 {
- global:
-
- rte_ifpga_find_afu_by_name;
-
-} DPDK_18.05;
diff --git a/drivers/bus/pci/rte_bus_pci_version.map b/drivers/bus/pci/rte_bus_pci_version.map
index 27e9c4f101..012d817e14 100644
--- a/drivers/bus/pci/rte_bus_pci_version.map
+++ b/drivers/bus/pci/rte_bus_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pci_dump;
diff --git a/drivers/bus/vdev/rte_bus_vdev_version.map b/drivers/bus/vdev/rte_bus_vdev_version.map
index 590cf9b437..5abb10ecb0 100644
--- a/drivers/bus/vdev/rte_bus_vdev_version.map
+++ b/drivers/bus/vdev/rte_bus_vdev_version.map
@@ -1,18 +1,12 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
+ rte_vdev_add_custom_scan;
rte_vdev_init;
rte_vdev_register;
+ rte_vdev_remove_custom_scan;
rte_vdev_uninit;
rte_vdev_unregister;
local: *;
};
-
-DPDK_18.02 {
- global:
-
- rte_vdev_add_custom_scan;
- rte_vdev_remove_custom_scan;
-
-} DPDK_17.11;
diff --git a/drivers/bus/vmbus/rte_bus_vmbus_version.map b/drivers/bus/vmbus/rte_bus_vmbus_version.map
index ae231ad329..cbaaebc06c 100644
--- a/drivers/bus/vmbus/rte_bus_vmbus_version.map
+++ b/drivers/bus/vmbus/rte_bus_vmbus_version.map
@@ -1,6 +1,4 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_vmbus_chan_close;
@@ -20,6 +18,7 @@ DPDK_18.08 {
rte_vmbus_probe;
rte_vmbus_register;
rte_vmbus_scan;
+ rte_vmbus_set_latency;
rte_vmbus_sub_channel_index;
rte_vmbus_subchan_open;
rte_vmbus_unmap_device;
@@ -27,10 +26,3 @@ DPDK_18.08 {
local: *;
};
-
-DPDK_18.11 {
- global:
-
- rte_vmbus_set_latency;
-
-} DPDK_18.08;
diff --git a/drivers/common/cpt/rte_common_cpt_version.map b/drivers/common/cpt/rte_common_cpt_version.map
index dec614f0de..79fa5751bc 100644
--- a/drivers/common/cpt/rte_common_cpt_version.map
+++ b/drivers/common/cpt/rte_common_cpt_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
cpt_pmd_ops_helper_get_mlen_direct_mode;
cpt_pmd_ops_helper_get_mlen_sg_mode;
+
+ local: *;
};
diff --git a/drivers/common/dpaax/rte_common_dpaax_version.map b/drivers/common/dpaax/rte_common_dpaax_version.map
index 8131c9e305..45d62aea9d 100644
--- a/drivers/common/dpaax/rte_common_dpaax_version.map
+++ b/drivers/common/dpaax/rte_common_dpaax_version.map
@@ -1,11 +1,11 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- dpaax_iova_table_update;
dpaax_iova_table_depopulate;
dpaax_iova_table_dump;
dpaax_iova_table_p;
dpaax_iova_table_populate;
+ dpaax_iova_table_update;
local: *;
};
diff --git a/drivers/common/mvep/rte_common_mvep_version.map b/drivers/common/mvep/rte_common_mvep_version.map
index c71722d79f..030928439d 100644
--- a/drivers/common/mvep/rte_common_mvep_version.map
+++ b/drivers/common/mvep/rte_common_mvep_version.map
@@ -1,6 +1,8 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
- rte_mvep_init;
rte_mvep_deinit;
+ rte_mvep_init;
+
+ local: *;
};
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index a9b3cff9bc..c15fb89112 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,8 +1,10 @@
-DPDK_18.05 {
+DPDK_20.0 {
global:
octeontx_logtype_mbox;
+ octeontx_mbox_send;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
- octeontx_mbox_send;
+
+ local: *;
};
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 4400120da0..adad21a2d6 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -1,39 +1,35 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
otx2_dev_active_vfs;
otx2_dev_fini;
otx2_dev_priv_init;
-
+ otx2_disable_irqs;
+ otx2_intra_dev_get_cfg;
otx2_logtype_base;
otx2_logtype_dpi;
otx2_logtype_mbox;
+ otx2_logtype_nix;
otx2_logtype_npa;
otx2_logtype_npc;
- otx2_logtype_nix;
otx2_logtype_sso;
- otx2_logtype_tm;
otx2_logtype_tim;
-
+ otx2_logtype_tm;
otx2_mbox_alloc_msg_rsp;
otx2_mbox_get_rsp;
otx2_mbox_get_rsp_tmo;
otx2_mbox_id2name;
otx2_mbox_msg_send;
otx2_mbox_wait_for_rsp;
-
- otx2_intra_dev_get_cfg;
otx2_npa_lf_active;
otx2_npa_lf_obj_get;
otx2_npa_lf_obj_ref;
otx2_npa_pf_func_get;
otx2_npa_set_defaults;
+ otx2_register_irq;
otx2_sso_pf_func_get;
otx2_sso_pf_func_set;
-
- otx2_disable_irqs;
otx2_unregister_irq;
- otx2_register_irq;
local: *;
};
diff --git a/drivers/compress/isal/rte_pmd_isal_version.map b/drivers/compress/isal/rte_pmd_isal_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/compress/isal/rte_pmd_isal_version.map
+++ b/drivers/compress/isal/rte_pmd_isal_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
+++ b/drivers/compress/octeontx/rte_pmd_octeontx_compress_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/qat/rte_pmd_qat_version.map b/drivers/compress/qat/rte_pmd_qat_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/qat/rte_pmd_qat_version.map
+++ b/drivers/compress/qat/rte_pmd_qat_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/compress/zlib/rte_pmd_zlib_version.map b/drivers/compress/zlib/rte_pmd_zlib_version.map
index ad6e191e49..f9f17e4f6e 100644
--- a/drivers/compress/zlib/rte_pmd_zlib_version.map
+++ b/drivers/compress/zlib/rte_pmd_zlib_version.map
@@ -1,3 +1,3 @@
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
+++ b/drivers/crypto/aesni_gcm/rte_pmd_aesni_gcm_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
+++ b/drivers/crypto/aesni_mb/rte_pmd_aesni_mb_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/armv8/rte_pmd_armv8_version.map b/drivers/crypto/armv8/rte_pmd_armv8_version.map
index 1f84b68a83..f9f17e4f6e 100644
--- a/drivers/crypto/armv8/rte_pmd_armv8_version.map
+++ b/drivers/crypto/armv8/rte_pmd_armv8_version.map
@@ -1,3 +1,3 @@
-DPDK_17.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
+++ b/drivers/crypto/caam_jr/rte_pmd_caam_jr_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/ccp/rte_pmd_ccp_version.map b/drivers/crypto/ccp/rte_pmd_ccp_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/crypto/ccp/rte_pmd_ccp_version.map
+++ b/drivers/crypto/ccp/rte_pmd_ccp_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
index 0bfb986d0b..5952d645fd 100644
--- a/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
+++ b/drivers/crypto/dpaa2_sec/rte_pmd_dpaa2_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_18.11 {
+DPDK_20.0 {
global:
dpaa2_sec_eventq_attach;
dpaa2_sec_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
index cc7f2162e0..8580fa13db 100644
--- a/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
+++ b/drivers/crypto/dpaa_sec/rte_pmd_dpaa_sec_version.map
@@ -1,12 +1,8 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_19.11 {
+DPDK_20.0 {
global:
dpaa_sec_eventq_attach;
dpaa_sec_eventq_detach;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
index 8ffeca934e..f9f17e4f6e 100644
--- a/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
+++ b/drivers/crypto/kasumi/rte_pmd_kasumi_version.map
@@ -1,3 +1,3 @@
-DPDK_16.07 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
+++ b/drivers/crypto/mvsam/rte_pmd_mvsam_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
index 406964d1fc..f9f17e4f6e 100644
--- a/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
+++ b/drivers/crypto/nitrox/rte_pmd_nitrox_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/null/rte_pmd_null_crypto_version.map b/drivers/crypto/null/rte_pmd_null_crypto_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/null/rte_pmd_null_crypto_version.map
+++ b/drivers/crypto/null/rte_pmd_null_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
+++ b/drivers/crypto/octeontx/rte_pmd_octeontx_crypto_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/openssl/rte_pmd_openssl_version.map b/drivers/crypto/openssl/rte_pmd_openssl_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/openssl/rte_pmd_openssl_version.map
+++ b/drivers/crypto/openssl/rte_pmd_openssl_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
index 5c43127cf2..077afedce7 100644
--- a/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
+++ b/drivers/crypto/scheduler/rte_pmd_crypto_scheduler_version.map
@@ -1,21 +1,16 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_cryptodev_scheduler_load_user_scheduler;
- rte_cryptodev_scheduler_slave_attach;
- rte_cryptodev_scheduler_slave_detach;
- rte_cryptodev_scheduler_ordering_set;
- rte_cryptodev_scheduler_ordering_get;
-
-};
-
-DPDK_17.05 {
- global:
-
rte_cryptodev_scheduler_mode_get;
rte_cryptodev_scheduler_mode_set;
rte_cryptodev_scheduler_option_get;
rte_cryptodev_scheduler_option_set;
+ rte_cryptodev_scheduler_ordering_get;
+ rte_cryptodev_scheduler_ordering_set;
+ rte_cryptodev_scheduler_slave_attach;
+ rte_cryptodev_scheduler_slave_detach;
rte_cryptodev_scheduler_slaves_get;
-} DPDK_17.02;
+ local: *;
+};
diff --git a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
index dc4d417b7b..f9f17e4f6e 100644
--- a/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
+++ b/drivers/crypto/snow3g/rte_pmd_snow3g_version.map
@@ -1,3 +1,3 @@
-DPDK_16.04 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
+++ b/drivers/crypto/virtio/rte_pmd_virtio_crypto_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/crypto/zuc/rte_pmd_zuc_version.map b/drivers/crypto/zuc/rte_pmd_zuc_version.map
index cc5829e30b..f9f17e4f6e 100644
--- a/drivers/crypto/zuc/rte_pmd_zuc_version.map
+++ b/drivers/crypto/zuc/rte_pmd_zuc_version.map
@@ -1,3 +1,3 @@
-DPDK_16.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
+++ b/drivers/event/dpaa/rte_pmd_dpaa_event_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
index 1c0b7559dc..f9f17e4f6e 100644
--- a/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
+++ b/drivers/event/dpaa2/rte_pmd_dpaa2_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/dsw/rte_pmd_dsw_event_version.map b/drivers/event/dsw/rte_pmd_dsw_event_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/event/dsw/rte_pmd_dsw_event_version.map
+++ b/drivers/event/dsw/rte_pmd_dsw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
+++ b/drivers/event/octeontx/rte_pmd_octeontx_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
index 41c65c8c9c..f9f17e4f6e 100644
--- a/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
+++ b/drivers/event/octeontx2/rte_pmd_octeontx2_event_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
+DPDK_20.0 {
local: *;
};
-
diff --git a/drivers/event/opdl/rte_pmd_opdl_event_version.map b/drivers/event/opdl/rte_pmd_opdl_event_version.map
index 58b94270d4..f9f17e4f6e 100644
--- a/drivers/event/opdl/rte_pmd_opdl_event_version.map
+++ b/drivers/event/opdl/rte_pmd_opdl_event_version.map
@@ -1,3 +1,3 @@
-DPDK_18.02 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
+++ b/drivers/event/skeleton/rte_pmd_skeleton_event_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/event/sw/rte_pmd_sw_event_version.map b/drivers/event/sw/rte_pmd_sw_event_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/event/sw/rte_pmd_sw_event_version.map
+++ b/drivers/event/sw/rte_pmd_sw_event_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/bucket/rte_mempool_bucket_version.map b/drivers/mempool/bucket/rte_mempool_bucket_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/mempool/bucket/rte_mempool_bucket_version.map
+++ b/drivers/mempool/bucket/rte_mempool_bucket_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
index 60bf50b2d1..9eebaf7ffd 100644
--- a/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
+++ b/drivers/mempool/dpaa/rte_mempool_dpaa_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_dpaa_bpid_info;
diff --git a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
index b45e7a9ac1..cd4bc88273 100644
--- a/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
+++ b/drivers/mempool/dpaa2/rte_mempool_dpaa2_version.map
@@ -1,16 +1,10 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_dpaa2_bpid_info;
rte_dpaa2_mbuf_alloc_bulk;
-
- local: *;
-};
-
-DPDK_18.05 {
- global:
-
rte_dpaa2_mbuf_from_buf_addr;
rte_dpaa2_mbuf_pool_bpid;
-} DPDK_17.05;
+ local: *;
+};
diff --git a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
+++ b/drivers/mempool/octeontx/rte_mempool_octeontx_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
index d703368c31..d4f81aed8e 100644
--- a/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
+++ b/drivers/mempool/octeontx2/rte_mempool_octeontx2_version.map
@@ -1,8 +1,8 @@
-DPDK_19.08 {
+DPDK_20.0 {
global:
- otx2_npa_lf_init;
otx2_npa_lf_fini;
+ otx2_npa_lf_init;
local: *;
};
diff --git a/drivers/mempool/ring/rte_mempool_ring_version.map b/drivers/mempool/ring/rte_mempool_ring_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/ring/rte_mempool_ring_version.map
+++ b/drivers/mempool/ring/rte_mempool_ring_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/mempool/stack/rte_mempool_stack_version.map b/drivers/mempool/stack/rte_mempool_stack_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/mempool/stack/rte_mempool_stack_version.map
+++ b/drivers/mempool/stack/rte_mempool_stack_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_packet/rte_pmd_af_packet_version.map b/drivers/net/af_packet/rte_pmd_af_packet_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/af_packet/rte_pmd_af_packet_version.map
+++ b/drivers/net/af_packet/rte_pmd_af_packet_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
index c6db030fe6..f9f17e4f6e 100644
--- a/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
+++ b/drivers/net/af_xdp/rte_pmd_af_xdp_version.map
@@ -1,3 +1,3 @@
-DPDK_19.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ark/rte_pmd_ark_version.map b/drivers/net/ark/rte_pmd_ark_version.map
index 1062e0429f..f9f17e4f6e 100644
--- a/drivers/net/ark/rte_pmd_ark_version.map
+++ b/drivers/net/ark/rte_pmd_ark_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
- local: *;
-
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/atlantic/rte_pmd_atlantic_version.map b/drivers/net/atlantic/rte_pmd_atlantic_version.map
index b16faa999f..9b04838d84 100644
--- a/drivers/net/atlantic/rte_pmd_atlantic_version.map
+++ b/drivers/net/atlantic/rte_pmd_atlantic_version.map
@@ -1,5 +1,4 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
@@ -13,4 +12,3 @@ EXPERIMENTAL {
rte_pmd_atl_macsec_select_txsa;
rte_pmd_atl_macsec_select_rxsa;
};
-
diff --git a/drivers/net/avp/rte_pmd_avp_version.map b/drivers/net/avp/rte_pmd_avp_version.map
index 5352e7e3bd..f9f17e4f6e 100644
--- a/drivers/net/avp/rte_pmd_avp_version.map
+++ b/drivers/net/avp/rte_pmd_avp_version.map
@@ -1,3 +1,3 @@
-DPDK_17.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/axgbe/rte_pmd_axgbe_version.map b/drivers/net/axgbe/rte_pmd_axgbe_version.map
index de8e412ff1..f9f17e4f6e 100644
--- a/drivers/net/axgbe/rte_pmd_axgbe_version.map
+++ b/drivers/net/axgbe/rte_pmd_axgbe_version.map
@@ -1,3 +1,3 @@
-DPDK_18.05 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
+++ b/drivers/net/bnx2x/rte_pmd_bnx2x_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 4750d40ad6..bb52562347 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_pmd_bnxt_get_vf_rx_status;
@@ -10,13 +10,13 @@ DPDK_17.08 {
rte_pmd_bnxt_set_tx_loopback;
rte_pmd_bnxt_set_vf_mac_addr;
rte_pmd_bnxt_set_vf_mac_anti_spoof;
+ rte_pmd_bnxt_set_vf_persist_stats;
rte_pmd_bnxt_set_vf_rate_limit;
rte_pmd_bnxt_set_vf_rxmode;
rte_pmd_bnxt_set_vf_vlan_anti_spoof;
rte_pmd_bnxt_set_vf_vlan_filter;
rte_pmd_bnxt_set_vf_vlan_insert;
rte_pmd_bnxt_set_vf_vlan_stripq;
- rte_pmd_bnxt_set_vf_persist_stats;
local: *;
};
diff --git a/drivers/net/bonding/rte_pmd_bond_version.map b/drivers/net/bonding/rte_pmd_bond_version.map
index 00d955c481..270c7d5d55 100644
--- a/drivers/net/bonding/rte_pmd_bond_version.map
+++ b/drivers/net/bonding/rte_pmd_bond_version.map
@@ -1,9 +1,21 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_bond_8023ad_agg_selection_get;
+ rte_eth_bond_8023ad_agg_selection_set;
+ rte_eth_bond_8023ad_conf_get;
+ rte_eth_bond_8023ad_dedicated_queues_disable;
+ rte_eth_bond_8023ad_dedicated_queues_enable;
+ rte_eth_bond_8023ad_ext_collect;
+ rte_eth_bond_8023ad_ext_collect_get;
+ rte_eth_bond_8023ad_ext_distrib;
+ rte_eth_bond_8023ad_ext_distrib_get;
+ rte_eth_bond_8023ad_ext_slowtx;
+ rte_eth_bond_8023ad_setup;
rte_eth_bond_8023ad_slave_info;
rte_eth_bond_active_slaves_get;
rte_eth_bond_create;
+ rte_eth_bond_free;
rte_eth_bond_link_monitoring_set;
rte_eth_bond_mac_address_reset;
rte_eth_bond_mac_address_set;
@@ -19,36 +31,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- rte_eth_bond_free;
-
-} DPDK_2.0;
-
-DPDK_16.04 {
-};
-
-DPDK_16.07 {
- global:
-
- rte_eth_bond_8023ad_ext_collect;
- rte_eth_bond_8023ad_ext_collect_get;
- rte_eth_bond_8023ad_ext_distrib;
- rte_eth_bond_8023ad_ext_distrib_get;
- rte_eth_bond_8023ad_ext_slowtx;
-
-} DPDK_16.04;
-
-DPDK_17.08 {
- global:
-
- rte_eth_bond_8023ad_dedicated_queues_enable;
- rte_eth_bond_8023ad_dedicated_queues_disable;
- rte_eth_bond_8023ad_agg_selection_get;
- rte_eth_bond_8023ad_agg_selection_set;
- rte_eth_bond_8023ad_conf_get;
- rte_eth_bond_8023ad_setup;
-
-} DPDK_16.07;
diff --git a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
index bd8138a034..f9f17e4f6e 100644
--- a/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
+++ b/drivers/net/cxgbe/rte_pmd_cxgbe_version.map
@@ -1,4 +1,3 @@
-DPDK_2.1 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/dpaa/rte_pmd_dpaa_version.map b/drivers/net/dpaa/rte_pmd_dpaa_version.map
index 8cb4500b51..f403a1526d 100644
--- a/drivers/net/dpaa/rte_pmd_dpaa_version.map
+++ b/drivers/net/dpaa/rte_pmd_dpaa_version.map
@@ -1,12 +1,9 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.08 {
+DPDK_20.0 {
global:
dpaa_eth_eventq_attach;
dpaa_eth_eventq_detach;
rte_pmd_dpaa_set_tx_loopback;
-} DPDK_17.11;
+
+ local: *;
+};
diff --git a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
index d1b4cdb232..f2bb793319 100644
--- a/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
+++ b/drivers/net/dpaa2/rte_pmd_dpaa2_version.map
@@ -1,15 +1,11 @@
-DPDK_17.05 {
-
- local: *;
-};
-
-DPDK_17.11 {
+DPDK_20.0 {
global:
dpaa2_eth_eventq_attach;
dpaa2_eth_eventq_detach;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
@@ -17,4 +13,4 @@ EXPERIMENTAL {
rte_pmd_dpaa2_mux_flow_create;
rte_pmd_dpaa2_set_custom_hash;
rte_pmd_dpaa2_set_timestamp;
-} DPDK_17.11;
+};
diff --git a/drivers/net/e1000/rte_pmd_e1000_version.map b/drivers/net/e1000/rte_pmd_e1000_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/e1000/rte_pmd_e1000_version.map
+++ b/drivers/net/e1000/rte_pmd_e1000_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ena/rte_pmd_ena_version.map b/drivers/net/ena/rte_pmd_ena_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/ena/rte_pmd_ena_version.map
+++ b/drivers/net/ena/rte_pmd_ena_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enetc/rte_pmd_enetc_version.map b/drivers/net/enetc/rte_pmd_enetc_version.map
index 521e51f411..f9f17e4f6e 100644
--- a/drivers/net/enetc/rte_pmd_enetc_version.map
+++ b/drivers/net/enetc/rte_pmd_enetc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.11 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/enic/rte_pmd_enic_version.map b/drivers/net/enic/rte_pmd_enic_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/enic/rte_pmd_enic_version.map
+++ b/drivers/net/enic/rte_pmd_enic_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/failsafe/rte_pmd_failsafe_version.map b/drivers/net/failsafe/rte_pmd_failsafe_version.map
index b6d2840be4..f9f17e4f6e 100644
--- a/drivers/net/failsafe/rte_pmd_failsafe_version.map
+++ b/drivers/net/failsafe/rte_pmd_failsafe_version.map
@@ -1,4 +1,3 @@
-DPDK_17.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/fm10k/rte_pmd_fm10k_version.map b/drivers/net/fm10k/rte_pmd_fm10k_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/fm10k/rte_pmd_fm10k_version.map
+++ b/drivers/net/fm10k/rte_pmd_fm10k_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hinic/rte_pmd_hinic_version.map b/drivers/net/hinic/rte_pmd_hinic_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/hinic/rte_pmd_hinic_version.map
+++ b/drivers/net/hinic/rte_pmd_hinic_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/hns3/rte_pmd_hns3_version.map b/drivers/net/hns3/rte_pmd_hns3_version.map
index 35e5f2debb..f9f17e4f6e 100644
--- a/drivers/net/hns3/rte_pmd_hns3_version.map
+++ b/drivers/net/hns3/rte_pmd_hns3_version.map
@@ -1,3 +1,3 @@
-DPDK_19.11 {
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/i40e/rte_pmd_i40e_version.map b/drivers/net/i40e/rte_pmd_i40e_version.map
index cccd5768c2..a80e69b93e 100644
--- a/drivers/net/i40e/rte_pmd_i40e_version.map
+++ b/drivers/net/i40e/rte_pmd_i40e_version.map
@@ -1,23 +1,34 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_i40e_add_vf_mac_addr;
+ rte_pmd_i40e_flow_add_del_packet_template;
+ rte_pmd_i40e_flow_type_mapping_get;
+ rte_pmd_i40e_flow_type_mapping_reset;
+ rte_pmd_i40e_flow_type_mapping_update;
+ rte_pmd_i40e_get_ddp_info;
+ rte_pmd_i40e_get_ddp_list;
rte_pmd_i40e_get_vf_stats;
+ rte_pmd_i40e_inset_get;
+ rte_pmd_i40e_inset_set;
rte_pmd_i40e_ping_vfs;
+ rte_pmd_i40e_process_ddp_package;
rte_pmd_i40e_ptype_mapping_get;
rte_pmd_i40e_ptype_mapping_replace;
rte_pmd_i40e_ptype_mapping_reset;
rte_pmd_i40e_ptype_mapping_update;
+ rte_pmd_i40e_query_vfid_by_mac;
rte_pmd_i40e_reset_vf_stats;
+ rte_pmd_i40e_rss_queue_region_conf;
+ rte_pmd_i40e_set_tc_strict_prio;
rte_pmd_i40e_set_tx_loopback;
rte_pmd_i40e_set_vf_broadcast;
rte_pmd_i40e_set_vf_mac_addr;
rte_pmd_i40e_set_vf_mac_anti_spoof;
+ rte_pmd_i40e_set_vf_max_bw;
rte_pmd_i40e_set_vf_multicast_promisc;
+ rte_pmd_i40e_set_vf_tc_bw_alloc;
+ rte_pmd_i40e_set_vf_tc_max_bw;
rte_pmd_i40e_set_vf_unicast_promisc;
rte_pmd_i40e_set_vf_vlan_anti_spoof;
rte_pmd_i40e_set_vf_vlan_filter;
@@ -25,43 +36,5 @@ DPDK_17.02 {
rte_pmd_i40e_set_vf_vlan_stripq;
rte_pmd_i40e_set_vf_vlan_tag;
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_pmd_i40e_set_tc_strict_prio;
- rte_pmd_i40e_set_vf_max_bw;
- rte_pmd_i40e_set_vf_tc_bw_alloc;
- rte_pmd_i40e_set_vf_tc_max_bw;
- rte_pmd_i40e_process_ddp_package;
- rte_pmd_i40e_get_ddp_list;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_i40e_get_ddp_info;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_pmd_i40e_add_vf_mac_addr;
- rte_pmd_i40e_flow_add_del_packet_template;
- rte_pmd_i40e_flow_type_mapping_update;
- rte_pmd_i40e_flow_type_mapping_get;
- rte_pmd_i40e_flow_type_mapping_reset;
- rte_pmd_i40e_query_vfid_by_mac;
- rte_pmd_i40e_rss_queue_region_conf;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_pmd_i40e_inset_get;
- rte_pmd_i40e_inset_set;
-} DPDK_17.11;
\ No newline at end of file
+ local: *;
+};
diff --git a/drivers/net/iavf/rte_pmd_iavf_version.map b/drivers/net/iavf/rte_pmd_iavf_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/iavf/rte_pmd_iavf_version.map
+++ b/drivers/net/iavf/rte_pmd_iavf_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ice/rte_pmd_ice_version.map b/drivers/net/ice/rte_pmd_ice_version.map
index 7b23b609da..f9f17e4f6e 100644
--- a/drivers/net/ice/rte_pmd_ice_version.map
+++ b/drivers/net/ice/rte_pmd_ice_version.map
@@ -1,4 +1,3 @@
-DPDK_19.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ifc/rte_pmd_ifc_version.map b/drivers/net/ifc/rte_pmd_ifc_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/net/ifc/rte_pmd_ifc_version.map
+++ b/drivers/net/ifc/rte_pmd_ifc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
+++ b/drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
index c814f96d72..21534dbc3d 100644
--- a/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
+++ b/drivers/net/ixgbe/rte_pmd_ixgbe_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
- rte_pmd_ixgbe_set_all_queues_drop_en;
- rte_pmd_ixgbe_set_tx_loopback;
- rte_pmd_ixgbe_set_vf_mac_addr;
- rte_pmd_ixgbe_set_vf_mac_anti_spoof;
- rte_pmd_ixgbe_set_vf_split_drop_en;
- rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
- rte_pmd_ixgbe_set_vf_vlan_insert;
- rte_pmd_ixgbe_set_vf_vlan_stripq;
-} DPDK_2.0;
-
-DPDK_17.02 {
+DPDK_20.0 {
global:
+ rte_pmd_ixgbe_bypass_event_show;
+ rte_pmd_ixgbe_bypass_event_store;
+ rte_pmd_ixgbe_bypass_init;
+ rte_pmd_ixgbe_bypass_state_set;
+ rte_pmd_ixgbe_bypass_state_show;
+ rte_pmd_ixgbe_bypass_ver_show;
+ rte_pmd_ixgbe_bypass_wd_reset;
+ rte_pmd_ixgbe_bypass_wd_timeout_show;
+ rte_pmd_ixgbe_bypass_wd_timeout_store;
rte_pmd_ixgbe_macsec_config_rxsc;
rte_pmd_ixgbe_macsec_config_txsc;
rte_pmd_ixgbe_macsec_disable;
rte_pmd_ixgbe_macsec_enable;
rte_pmd_ixgbe_macsec_select_rxsa;
rte_pmd_ixgbe_macsec_select_txsa;
+ rte_pmd_ixgbe_ping_vf;
+ rte_pmd_ixgbe_set_all_queues_drop_en;
+ rte_pmd_ixgbe_set_tc_bw_alloc;
+ rte_pmd_ixgbe_set_tx_loopback;
+ rte_pmd_ixgbe_set_vf_mac_addr;
+ rte_pmd_ixgbe_set_vf_mac_anti_spoof;
rte_pmd_ixgbe_set_vf_rate_limit;
rte_pmd_ixgbe_set_vf_rx;
rte_pmd_ixgbe_set_vf_rxmode;
+ rte_pmd_ixgbe_set_vf_split_drop_en;
rte_pmd_ixgbe_set_vf_tx;
+ rte_pmd_ixgbe_set_vf_vlan_anti_spoof;
rte_pmd_ixgbe_set_vf_vlan_filter;
-} DPDK_16.11;
+ rte_pmd_ixgbe_set_vf_vlan_insert;
+ rte_pmd_ixgbe_set_vf_vlan_stripq;
-DPDK_17.05 {
- global:
-
- rte_pmd_ixgbe_ping_vf;
- rte_pmd_ixgbe_set_tc_bw_alloc;
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_pmd_ixgbe_bypass_event_show;
- rte_pmd_ixgbe_bypass_event_store;
- rte_pmd_ixgbe_bypass_init;
- rte_pmd_ixgbe_bypass_state_set;
- rte_pmd_ixgbe_bypass_state_show;
- rte_pmd_ixgbe_bypass_ver_show;
- rte_pmd_ixgbe_bypass_wd_reset;
- rte_pmd_ixgbe_bypass_wd_timeout_show;
- rte_pmd_ixgbe_bypass_wd_timeout_store;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/drivers/net/kni/rte_pmd_kni_version.map b/drivers/net/kni/rte_pmd_kni_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/kni/rte_pmd_kni_version.map
+++ b/drivers/net/kni/rte_pmd_kni_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/liquidio/rte_pmd_liquidio_version.map b/drivers/net/liquidio/rte_pmd_liquidio_version.map
index 8591cc0b18..f9f17e4f6e 100644
--- a/drivers/net/liquidio/rte_pmd_liquidio_version.map
+++ b/drivers/net/liquidio/rte_pmd_liquidio_version.map
@@ -1,4 +1,3 @@
-DPDK_17.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/memif/rte_pmd_memif_version.map b/drivers/net/memif/rte_pmd_memif_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/net/memif/rte_pmd_memif_version.map
+++ b/drivers/net/memif/rte_pmd_memif_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/net/mlx4/rte_pmd_mlx4_version.map b/drivers/net/mlx4/rte_pmd_mlx4_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/mlx4/rte_pmd_mlx4_version.map
+++ b/drivers/net/mlx4/rte_pmd_mlx4_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mlx5/rte_pmd_mlx5_version.map b/drivers/net/mlx5/rte_pmd_mlx5_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/mlx5/rte_pmd_mlx5_version.map
+++ b/drivers/net/mlx5/rte_pmd_mlx5_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvneta/rte_pmd_mvneta_version.map b/drivers/net/mvneta/rte_pmd_mvneta_version.map
index 24bd5cdb35..f9f17e4f6e 100644
--- a/drivers/net/mvneta/rte_pmd_mvneta_version.map
+++ b/drivers/net/mvneta/rte_pmd_mvneta_version.map
@@ -1,3 +1,3 @@
-DPDK_18.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
index a753031720..f9f17e4f6e 100644
--- a/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
+++ b/drivers/net/mvpp2/rte_pmd_mvpp2_version.map
@@ -1,3 +1,3 @@
-DPDK_17.11 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/netvsc/rte_pmd_netvsc_version.map b/drivers/net/netvsc/rte_pmd_netvsc_version.map
index d534019a6b..f9f17e4f6e 100644
--- a/drivers/net/netvsc/rte_pmd_netvsc_version.map
+++ b/drivers/net/netvsc/rte_pmd_netvsc_version.map
@@ -1,5 +1,3 @@
-/* SPDX-License-Identifier: BSD-3-Clause */
-
-DPDK_18.08 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfb/rte_pmd_nfb_version.map b/drivers/net/nfb/rte_pmd_nfb_version.map
index fc8c95e919..f9f17e4f6e 100644
--- a/drivers/net/nfb/rte_pmd_nfb_version.map
+++ b/drivers/net/nfb/rte_pmd_nfb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/nfp/rte_pmd_nfp_version.map b/drivers/net/nfp/rte_pmd_nfp_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/nfp/rte_pmd_nfp_version.map
+++ b/drivers/net/nfp/rte_pmd_nfp_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/null/rte_pmd_null_version.map b/drivers/net/null/rte_pmd_null_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/null/rte_pmd_null_version.map
+++ b/drivers/net/null/rte_pmd_null_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/octeontx/rte_pmd_octeontx_version.map b/drivers/net/octeontx/rte_pmd_octeontx_version.map
index a3161b14d0..f7cae02fac 100644
--- a/drivers/net/octeontx/rte_pmd_octeontx_version.map
+++ b/drivers/net/octeontx/rte_pmd_octeontx_version.map
@@ -1,11 +1,7 @@
-DPDK_17.11 {
-
- local: *;
-};
-
-DPDK_18.02 {
+DPDK_20.0 {
global:
rte_octeontx_pchan_map;
-} DPDK_17.11;
+ local: *;
+};
diff --git a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
+++ b/drivers/net/octeontx2/rte_pmd_octeontx2_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/pcap/rte_pmd_pcap_version.map b/drivers/net/pcap/rte_pmd_pcap_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/pcap/rte_pmd_pcap_version.map
+++ b/drivers/net/pcap/rte_pmd_pcap_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/qede/rte_pmd_qede_version.map b/drivers/net/qede/rte_pmd_qede_version.map
index 349c6e1c22..f9f17e4f6e 100644
--- a/drivers/net/qede/rte_pmd_qede_version.map
+++ b/drivers/net/qede/rte_pmd_qede_version.map
@@ -1,4 +1,3 @@
-DPDK_16.04 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/ring/rte_pmd_ring_version.map b/drivers/net/ring/rte_pmd_ring_version.map
index 1f785d9409..ebb6be2733 100644
--- a/drivers/net/ring/rte_pmd_ring_version.map
+++ b/drivers/net/ring/rte_pmd_ring_version.map
@@ -1,14 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_eth_from_ring;
rte_eth_from_rings;
local: *;
};
-
-DPDK_2.2 {
- global:
-
- rte_eth_from_ring;
-
-} DPDK_2.0;
diff --git a/drivers/net/sfc/rte_pmd_sfc_version.map b/drivers/net/sfc/rte_pmd_sfc_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/sfc/rte_pmd_sfc_version.map
+++ b/drivers/net/sfc/rte_pmd_sfc_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/softnic/rte_pmd_softnic_version.map b/drivers/net/softnic/rte_pmd_softnic_version.map
index bc44b06f98..50f113d5a2 100644
--- a/drivers/net/softnic/rte_pmd_softnic_version.map
+++ b/drivers/net/softnic/rte_pmd_softnic_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_pmd_softnic_run;
diff --git a/drivers/net/szedata2/rte_pmd_szedata2_version.map b/drivers/net/szedata2/rte_pmd_szedata2_version.map
index ad607bbedd..f9f17e4f6e 100644
--- a/drivers/net/szedata2/rte_pmd_szedata2_version.map
+++ b/drivers/net/szedata2/rte_pmd_szedata2_version.map
@@ -1,3 +1,3 @@
-DPDK_2.2 {
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/tap/rte_pmd_tap_version.map b/drivers/net/tap/rte_pmd_tap_version.map
index 31eca32ebe..f9f17e4f6e 100644
--- a/drivers/net/tap/rte_pmd_tap_version.map
+++ b/drivers/net/tap/rte_pmd_tap_version.map
@@ -1,4 +1,3 @@
-DPDK_17.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/thunderx/rte_pmd_thunderx_version.map b/drivers/net/thunderx/rte_pmd_thunderx_version.map
index 1901bcb3b3..f9f17e4f6e 100644
--- a/drivers/net/thunderx/rte_pmd_thunderx_version.map
+++ b/drivers/net/thunderx/rte_pmd_thunderx_version.map
@@ -1,4 +1,3 @@
-DPDK_16.07 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
+++ b/drivers/net/vdev_netvsc/rte_pmd_vdev_netvsc_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vhost/rte_pmd_vhost_version.map b/drivers/net/vhost/rte_pmd_vhost_version.map
index 695db85749..16b591ccc4 100644
--- a/drivers/net/vhost/rte_pmd_vhost_version.map
+++ b/drivers/net/vhost/rte_pmd_vhost_version.map
@@ -1,13 +1,8 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
rte_eth_vhost_get_queue_event;
-
- local: *;
-};
-
-DPDK_16.11 {
- global:
-
rte_eth_vhost_get_vid_from_port_id;
+
+ local: *;
};
diff --git a/drivers/net/virtio/rte_pmd_virtio_version.map b/drivers/net/virtio/rte_pmd_virtio_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/virtio/rte_pmd_virtio_version.map
+++ b/drivers/net/virtio/rte_pmd_virtio_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
index ef35398402..f9f17e4f6e 100644
--- a/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
+++ b/drivers/net/vmxnet3/rte_pmd_vmxnet3_version.map
@@ -1,4 +1,3 @@
-DPDK_2.0 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
+++ b/drivers/raw/dpaa2_cmdif/rte_rawdev_dpaa2_cmdif_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
index d16a136fc8..ca6a0d7626 100644
--- a/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
+++ b/drivers/raw/dpaa2_qdma/rte_rawdev_dpaa2_qdma_version.map
@@ -1,4 +1,4 @@
-DPDK_19.05 {
+DPDK_20.0 {
global:
rte_qdma_attr_get;
@@ -9,9 +9,9 @@ DPDK_19.05 {
rte_qdma_start;
rte_qdma_stop;
rte_qdma_vq_create;
- rte_qdma_vq_destroy;
rte_qdma_vq_dequeue;
rte_qdma_vq_dequeue_multi;
+ rte_qdma_vq_destroy;
rte_qdma_vq_enqueue;
rte_qdma_vq_enqueue_multi;
rte_qdma_vq_stats;
diff --git a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
index 9b9ab1a4cf..f9f17e4f6e 100644
--- a/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
+++ b/drivers/raw/ifpga/rte_rawdev_ifpga_version.map
@@ -1,4 +1,3 @@
-DPDK_18.05 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ioat/rte_rawdev_ioat_version.map b/drivers/raw/ioat/rte_rawdev_ioat_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/ioat/rte_rawdev_ioat_version.map
+++ b/drivers/raw/ioat/rte_rawdev_ioat_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/ntb/rte_rawdev_ntb_version.map b/drivers/raw/ntb/rte_rawdev_ntb_version.map
index 8861484fb3..f9f17e4f6e 100644
--- a/drivers/raw/ntb/rte_rawdev_ntb_version.map
+++ b/drivers/raw/ntb/rte_rawdev_ntb_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
- local: *;
+DPDK_20.0 {
+ local: *;
};
diff --git a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
index 9a61188cd5..f9f17e4f6e 100644
--- a/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
+++ b/drivers/raw/octeontx2_dma/rte_rawdev_octeontx2_dma_version.map
@@ -1,4 +1,3 @@
-DPDK_19.08 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
index 179140fb87..f9f17e4f6e 100644
--- a/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
+++ b/drivers/raw/skeleton/rte_rawdev_skeleton_version.map
@@ -1,4 +1,3 @@
-DPDK_18.02 {
-
+DPDK_20.0 {
local: *;
};
diff --git a/lib/librte_acl/rte_acl_version.map b/lib/librte_acl/rte_acl_version.map
index b09370a104..c3daca8115 100644
--- a/lib/librte_acl/rte_acl_version.map
+++ b/lib/librte_acl/rte_acl_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_acl_add_rules;
diff --git a/lib/librte_bbdev/rte_bbdev_version.map b/lib/librte_bbdev/rte_bbdev_version.map
index 3624eb1cb4..45b560dbe7 100644
--- a/lib/librte_bbdev/rte_bbdev_version.map
+++ b/lib/librte_bbdev/rte_bbdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_bitratestats/rte_bitratestats_version.map b/lib/librte_bitratestats/rte_bitratestats_version.map
index fe7454452d..88fc2912db 100644
--- a/lib/librte_bitratestats/rte_bitratestats_version.map
+++ b/lib/librte_bitratestats/rte_bitratestats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_stats_bitrate_calc;
diff --git a/lib/librte_bpf/rte_bpf_version.map b/lib/librte_bpf/rte_bpf_version.map
index a203e088ea..e1ec43faa0 100644
--- a/lib/librte_bpf/rte_bpf_version.map
+++ b/lib/librte_bpf/rte_bpf_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cfgfile/rte_cfgfile_version.map b/lib/librte_cfgfile/rte_cfgfile_version.map
index a0a11cea8d..906eee96bf 100644
--- a/lib/librte_cfgfile/rte_cfgfile_version.map
+++ b/lib/librte_cfgfile/rte_cfgfile_version.map
@@ -1,40 +1,22 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_cfgfile_add_entry;
+ rte_cfgfile_add_section;
rte_cfgfile_close;
+ rte_cfgfile_create;
rte_cfgfile_get_entry;
rte_cfgfile_has_entry;
rte_cfgfile_has_section;
rte_cfgfile_load;
+ rte_cfgfile_load_with_params;
rte_cfgfile_num_sections;
+ rte_cfgfile_save;
rte_cfgfile_section_entries;
+ rte_cfgfile_section_entries_by_index;
rte_cfgfile_section_num_entries;
rte_cfgfile_sections;
+ rte_cfgfile_set_entry;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_cfgfile_section_entries_by_index;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_cfgfile_load_with_params;
-
-} DPDK_16.04;
-
-DPDK_17.11 {
- global:
-
- rte_cfgfile_add_entry;
- rte_cfgfile_add_section;
- rte_cfgfile_create;
- rte_cfgfile_save;
- rte_cfgfile_set_entry;
-
-} DPDK_17.05;
diff --git a/lib/librte_cmdline/rte_cmdline_version.map b/lib/librte_cmdline/rte_cmdline_version.map
index 04bcb387f2..95fce812ff 100644
--- a/lib/librte_cmdline/rte_cmdline_version.map
+++ b/lib/librte_cmdline/rte_cmdline_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
cirbuf_add_buf_head;
@@ -40,6 +40,7 @@ DPDK_2.0 {
cmdline_parse_num;
cmdline_parse_portlist;
cmdline_parse_string;
+ cmdline_poll;
cmdline_printf;
cmdline_quit;
cmdline_set_prompt;
@@ -68,10 +69,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_2.1 {
- global:
-
- cmdline_poll;
-
-} DPDK_2.0;
diff --git a/lib/librte_compressdev/rte_compressdev_version.map b/lib/librte_compressdev/rte_compressdev_version.map
index e2a108b650..cfcd50ac1c 100644
--- a/lib/librte_compressdev/rte_compressdev_version.map
+++ b/lib/librte_compressdev/rte_compressdev_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 3deb265ac2..1dd1e259a0 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -1,92 +1,62 @@
-DPDK_16.04 {
+DPDK_20.0 {
global:
- rte_cryptodevs;
+ rte_crypto_aead_algorithm_strings;
+ rte_crypto_aead_operation_strings;
+ rte_crypto_auth_algorithm_strings;
+ rte_crypto_auth_operation_strings;
+ rte_crypto_cipher_algorithm_strings;
+ rte_crypto_cipher_operation_strings;
+ rte_crypto_op_pool_create;
+ rte_cryptodev_allocate_driver;
rte_cryptodev_callback_register;
rte_cryptodev_callback_unregister;
rte_cryptodev_close;
- rte_cryptodev_count;
rte_cryptodev_configure;
+ rte_cryptodev_count;
+ rte_cryptodev_device_count_by_driver;
+ rte_cryptodev_devices_get;
+ rte_cryptodev_driver_id_get;
+ rte_cryptodev_driver_name_get;
+ rte_cryptodev_get_aead_algo_enum;
+ rte_cryptodev_get_auth_algo_enum;
+ rte_cryptodev_get_cipher_algo_enum;
rte_cryptodev_get_dev_id;
rte_cryptodev_get_feature_name;
+ rte_cryptodev_get_sec_ctx;
rte_cryptodev_info_get;
+ rte_cryptodev_name_get;
rte_cryptodev_pmd_allocate;
rte_cryptodev_pmd_callback_process;
+ rte_cryptodev_pmd_create;
+ rte_cryptodev_pmd_create_dev_name;
+ rte_cryptodev_pmd_destroy;
+ rte_cryptodev_pmd_get_dev;
+ rte_cryptodev_pmd_get_named_dev;
+ rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_pmd_parse_input_args;
rte_cryptodev_pmd_release_device;
- rte_cryptodev_sym_session_create;
- rte_cryptodev_sym_session_free;
+ rte_cryptodev_queue_pair_count;
+ rte_cryptodev_queue_pair_setup;
rte_cryptodev_socket_id;
rte_cryptodev_start;
rte_cryptodev_stats_get;
rte_cryptodev_stats_reset;
rte_cryptodev_stop;
- rte_cryptodev_queue_pair_count;
- rte_cryptodev_queue_pair_setup;
- rte_crypto_op_pool_create;
-
- local: *;
-};
-
-DPDK_17.02 {
- global:
-
- rte_cryptodev_devices_get;
- rte_cryptodev_pmd_create_dev_name;
- rte_cryptodev_pmd_get_dev;
- rte_cryptodev_pmd_get_named_dev;
- rte_cryptodev_pmd_is_valid_dev;
+ rte_cryptodev_sym_capability_check_aead;
rte_cryptodev_sym_capability_check_auth;
rte_cryptodev_sym_capability_check_cipher;
rte_cryptodev_sym_capability_get;
- rte_crypto_auth_algorithm_strings;
- rte_crypto_auth_operation_strings;
- rte_crypto_cipher_algorithm_strings;
- rte_crypto_cipher_operation_strings;
-
-} DPDK_16.04;
-
-DPDK_17.05 {
- global:
-
- rte_cryptodev_get_auth_algo_enum;
- rte_cryptodev_get_cipher_algo_enum;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_cryptodev_allocate_driver;
- rte_cryptodev_device_count_by_driver;
- rte_cryptodev_driver_id_get;
- rte_cryptodev_driver_name_get;
- rte_cryptodev_get_aead_algo_enum;
- rte_cryptodev_sym_capability_check_aead;
- rte_cryptodev_sym_session_init;
- rte_cryptodev_sym_session_clear;
- rte_crypto_aead_algorithm_strings;
- rte_crypto_aead_operation_strings;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_cryptodev_get_sec_ctx;
- rte_cryptodev_name_get;
- rte_cryptodev_pmd_create;
- rte_cryptodev_pmd_destroy;
- rte_cryptodev_pmd_parse_input_args;
-
-} DPDK_17.08;
-
-DPDK_18.05 {
- global:
-
rte_cryptodev_sym_get_header_session_size;
rte_cryptodev_sym_get_private_session_size;
+ rte_cryptodev_sym_session_clear;
+ rte_cryptodev_sym_session_create;
+ rte_cryptodev_sym_session_free;
+ rte_cryptodev_sym_session_init;
+ rte_cryptodevs;
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_distributor/rte_distributor_version.map b/lib/librte_distributor/rte_distributor_version.map
index 3a285b394e..1b7c643005 100644
--- a/lib/librte_distributor/rte_distributor_version.map
+++ b/lib/librte_distributor/rte_distributor_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_distributor_clear_returns;
@@ -13,17 +13,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_17.05 {
- global:
-
- rte_distributor_clear_returns;
- rte_distributor_create;
- rte_distributor_flush;
- rte_distributor_get_pkt;
- rte_distributor_poll_pkt;
- rte_distributor_process;
- rte_distributor_request_pkt;
- rte_distributor_return_pkt;
- rte_distributor_returned_pkts;
-} DPDK_2.0;
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7cbf82d37b..8c41999317 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
__rte_panic;
@@ -7,46 +7,111 @@ DPDK_2.0 {
lcore_config;
per_lcore__lcore_id;
per_lcore__rte_errno;
+ rte_bus_dump;
+ rte_bus_find;
+ rte_bus_find_by_device;
+ rte_bus_find_by_name;
+ rte_bus_get_iommu_class;
+ rte_bus_probe;
+ rte_bus_register;
+ rte_bus_scan;
+ rte_bus_unregister;
rte_calloc;
rte_calloc_socket;
rte_cpu_check_supported;
rte_cpu_get_flag_enabled;
+ rte_cpu_get_flag_name;
+ rte_cpu_is_supported;
+ rte_ctrl_thread_create;
rte_cycles_vmware_tsc_map;
rte_delay_us;
+ rte_delay_us_block;
+ rte_delay_us_callback_register;
+ rte_dev_is_probed;
+ rte_dev_probe;
+ rte_dev_remove;
+ rte_devargs_add;
+ rte_devargs_dump;
+ rte_devargs_insert;
+ rte_devargs_next;
+ rte_devargs_parse;
+ rte_devargs_parsef;
+ rte_devargs_remove;
+ rte_devargs_type_count;
rte_dump_physmem_layout;
rte_dump_registers;
rte_dump_stack;
rte_dump_tailq;
rte_eal_alarm_cancel;
rte_eal_alarm_set;
+ rte_eal_cleanup;
+ rte_eal_create_uio_dev;
rte_eal_get_configuration;
rte_eal_get_lcore_state;
rte_eal_get_physmem_size;
+ rte_eal_get_runtime_dir;
rte_eal_has_hugepages;
+ rte_eal_has_pci;
+ rte_eal_hotplug_add;
+ rte_eal_hotplug_remove;
rte_eal_hpet_init;
rte_eal_init;
rte_eal_iopl_init;
+ rte_eal_iova_mode;
rte_eal_lcore_role;
+ rte_eal_mbuf_user_pool_ops;
rte_eal_mp_remote_launch;
rte_eal_mp_wait_lcore;
+ rte_eal_primary_proc_alive;
rte_eal_process_type;
rte_eal_remote_launch;
rte_eal_tailq_lookup;
rte_eal_tailq_register;
+ rte_eal_using_phys_addrs;
+ rte_eal_vfio_intr_mode;
rte_eal_wait_lcore;
+ rte_epoll_ctl;
+ rte_epoll_wait;
rte_exit;
rte_free;
rte_get_hpet_cycles;
rte_get_hpet_hz;
rte_get_tsc_hz;
rte_hexdump;
+ rte_hypervisor_get;
+ rte_hypervisor_get_name;
+ rte_intr_allow_others;
rte_intr_callback_register;
rte_intr_callback_unregister;
+ rte_intr_cap_multiple;
rte_intr_disable;
+ rte_intr_dp_is_en;
+ rte_intr_efd_disable;
+ rte_intr_efd_enable;
rte_intr_enable;
+ rte_intr_free_epoll_fd;
+ rte_intr_rx_ctl;
+ rte_intr_tls_epfd;
+ rte_keepalive_create;
+ rte_keepalive_dispatch_pings;
+ rte_keepalive_mark_alive;
+ rte_keepalive_mark_sleep;
+ rte_keepalive_register_core;
+ rte_keepalive_register_relay_callback;
+ rte_lcore_has_role;
+ rte_lcore_index;
+ rte_lcore_to_socket_id;
rte_log;
rte_log_cur_msg_loglevel;
rte_log_cur_msg_logtype;
+ rte_log_dump;
+ rte_log_get_global_level;
+ rte_log_get_level;
+ rte_log_register;
+ rte_log_set_global_level;
+ rte_log_set_level;
+ rte_log_set_level_pattern;
+ rte_log_set_level_regexp;
rte_logs;
rte_malloc;
rte_malloc_dump_stats;
@@ -54,155 +119,38 @@ DPDK_2.0 {
rte_malloc_set_limit;
rte_malloc_socket;
rte_malloc_validate;
+ rte_malloc_virt2iova;
+ rte_mcfg_mem_read_lock;
+ rte_mcfg_mem_read_unlock;
+ rte_mcfg_mem_write_lock;
+ rte_mcfg_mem_write_unlock;
+ rte_mcfg_mempool_read_lock;
+ rte_mcfg_mempool_read_unlock;
+ rte_mcfg_mempool_write_lock;
+ rte_mcfg_mempool_write_unlock;
+ rte_mcfg_tailq_read_lock;
+ rte_mcfg_tailq_read_unlock;
+ rte_mcfg_tailq_write_lock;
+ rte_mcfg_tailq_write_unlock;
rte_mem_lock_page;
+ rte_mem_virt2iova;
rte_mem_virt2phy;
rte_memdump;
rte_memory_get_nchannel;
rte_memory_get_nrank;
rte_memzone_dump;
+ rte_memzone_free;
rte_memzone_lookup;
rte_memzone_reserve;
rte_memzone_reserve_aligned;
rte_memzone_reserve_bounded;
rte_memzone_walk;
rte_openlog_stream;
+ rte_rand;
rte_realloc;
- rte_set_application_usage_hook;
- rte_socket_id;
- rte_strerror;
- rte_strsplit;
- rte_sys_gettid;
- rte_thread_get_affinity;
- rte_thread_set_affinity;
- rte_vlog;
- rte_zmalloc;
- rte_zmalloc_socket;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_epoll_ctl;
- rte_epoll_wait;
- rte_intr_allow_others;
- rte_intr_dp_is_en;
- rte_intr_efd_disable;
- rte_intr_efd_enable;
- rte_intr_rx_ctl;
- rte_intr_tls_epfd;
- rte_memzone_free;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_intr_cap_multiple;
- rte_keepalive_create;
- rte_keepalive_dispatch_pings;
- rte_keepalive_mark_alive;
- rte_keepalive_register_core;
-
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_cpu_get_flag_name;
- rte_eal_primary_proc_alive;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_keepalive_mark_sleep;
- rte_keepalive_register_relay_callback;
- rte_rtm_supported;
- rte_thread_setname;
-
-} DPDK_16.04;
-
-DPDK_16.11 {
- global:
-
- rte_delay_us_block;
- rte_delay_us_callback_register;
-
-} DPDK_16.07;
-
-DPDK_17.02 {
- global:
-
- rte_bus_dump;
- rte_bus_probe;
- rte_bus_register;
- rte_bus_scan;
- rte_bus_unregister;
-
-} DPDK_16.11;
-
-DPDK_17.05 {
- global:
-
- rte_cpu_is_supported;
- rte_intr_free_epoll_fd;
- rte_log_dump;
- rte_log_get_global_level;
- rte_log_register;
- rte_log_set_global_level;
- rte_log_set_level;
- rte_log_set_level_regexp;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- rte_bus_find;
- rte_bus_find_by_device;
- rte_bus_find_by_name;
- rte_log_get_level;
-
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eal_create_uio_dev;
- rte_bus_get_iommu_class;
- rte_eal_has_pci;
- rte_eal_iova_mode;
- rte_eal_using_phys_addrs;
- rte_eal_vfio_intr_mode;
- rte_lcore_has_role;
- rte_malloc_virt2iova;
- rte_mem_virt2iova;
- rte_vfio_enable;
- rte_vfio_is_enabled;
- rte_vfio_noiommu_is_enabled;
- rte_vfio_release_device;
- rte_vfio_setup_device;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_hypervisor_get;
- rte_hypervisor_get_name;
- rte_vfio_clear_group;
rte_reciprocal_value;
rte_reciprocal_value_u64;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_log_set_level_pattern;
+ rte_rtm_supported;
rte_service_attr_get;
rte_service_attr_reset_all;
rte_service_component_register;
@@ -215,6 +163,8 @@ DPDK_18.05 {
rte_service_get_count;
rte_service_get_name;
rte_service_lcore_add;
+ rte_service_lcore_attr_get;
+ rte_service_lcore_attr_reset_all;
rte_service_lcore_count;
rte_service_lcore_count_services;
rte_service_lcore_del;
@@ -224,6 +174,7 @@ DPDK_18.05 {
rte_service_lcore_stop;
rte_service_map_lcore_get;
rte_service_map_lcore_set;
+ rte_service_may_be_active;
rte_service_probe_capability;
rte_service_run_iter_on_app_lcore;
rte_service_runstate_get;
@@ -231,17 +182,23 @@ DPDK_18.05 {
rte_service_set_runstate_mapped_check;
rte_service_set_stats_enable;
rte_service_start_with_defaults;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eal_mbuf_user_pool_ops;
+ rte_set_application_usage_hook;
+ rte_socket_count;
+ rte_socket_id;
+ rte_socket_id_by_idx;
+ rte_srand;
+ rte_strerror;
+ rte_strscpy;
+ rte_strsplit;
+ rte_sys_gettid;
+ rte_thread_get_affinity;
+ rte_thread_set_affinity;
+ rte_thread_setname;
rte_uuid_compare;
rte_uuid_is_null;
rte_uuid_parse;
rte_uuid_unparse;
+ rte_vfio_clear_group;
rte_vfio_container_create;
rte_vfio_container_destroy;
rte_vfio_container_dma_map;
@@ -250,67 +207,20 @@ DPDK_18.08 {
rte_vfio_container_group_unbind;
rte_vfio_dma_map;
rte_vfio_dma_unmap;
+ rte_vfio_enable;
rte_vfio_get_container_fd;
rte_vfio_get_group_fd;
rte_vfio_get_group_num;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_dev_probe;
- rte_dev_remove;
- rte_eal_get_runtime_dir;
- rte_eal_hotplug_add;
- rte_eal_hotplug_remove;
- rte_strscpy;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_ctrl_thread_create;
- rte_dev_is_probed;
- rte_devargs_add;
- rte_devargs_dump;
- rte_devargs_insert;
- rte_devargs_next;
- rte_devargs_parse;
- rte_devargs_parsef;
- rte_devargs_remove;
- rte_devargs_type_count;
- rte_eal_cleanup;
- rte_socket_count;
- rte_socket_id_by_idx;
-
-} DPDK_18.11;
-
-DPDK_19.08 {
- global:
-
- rte_lcore_index;
- rte_lcore_to_socket_id;
- rte_mcfg_mem_read_lock;
- rte_mcfg_mem_read_unlock;
- rte_mcfg_mem_write_lock;
- rte_mcfg_mem_write_unlock;
- rte_mcfg_mempool_read_lock;
- rte_mcfg_mempool_read_unlock;
- rte_mcfg_mempool_write_lock;
- rte_mcfg_mempool_write_unlock;
- rte_mcfg_tailq_read_lock;
- rte_mcfg_tailq_read_unlock;
- rte_mcfg_tailq_write_lock;
- rte_mcfg_tailq_write_unlock;
- rte_rand;
- rte_service_lcore_attr_get;
- rte_service_lcore_attr_reset_all;
- rte_service_may_be_active;
- rte_srand;
-
-} DPDK_19.05;
+ rte_vfio_is_enabled;
+ rte_vfio_noiommu_is_enabled;
+ rte_vfio_release_device;
+ rte_vfio_setup_device;
+ rte_vlog;
+ rte_zmalloc;
+ rte_zmalloc_socket;
+
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_efd/rte_efd_version.map b/lib/librte_efd/rte_efd_version.map
index ae60a64178..e010eecfe4 100644
--- a/lib/librte_efd/rte_efd_version.map
+++ b/lib/librte_efd/rte_efd_version.map
@@ -1,4 +1,4 @@
-DPDK_17.02 {
+DPDK_20.0 {
global:
rte_efd_create;
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 6df42a47b8..9e1dbdebb4 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -1,35 +1,53 @@
-DPDK_2.2 {
+DPDK_20.0 {
global:
+ _rte_eth_dev_callback_process;
+ _rte_eth_dev_reset;
+ rte_eth_add_first_rx_callback;
rte_eth_add_rx_callback;
rte_eth_add_tx_callback;
rte_eth_allmulticast_disable;
rte_eth_allmulticast_enable;
rte_eth_allmulticast_get;
+ rte_eth_dev_adjust_nb_rx_tx_desc;
rte_eth_dev_allocate;
rte_eth_dev_allocated;
+ rte_eth_dev_attach_secondary;
rte_eth_dev_callback_register;
rte_eth_dev_callback_unregister;
rte_eth_dev_close;
rte_eth_dev_configure;
rte_eth_dev_count;
+ rte_eth_dev_count_avail;
+ rte_eth_dev_count_total;
rte_eth_dev_default_mac_addr_set;
+ rte_eth_dev_filter_ctrl;
rte_eth_dev_filter_supported;
rte_eth_dev_flow_ctrl_get;
rte_eth_dev_flow_ctrl_set;
+ rte_eth_dev_fw_version_get;
rte_eth_dev_get_dcb_info;
rte_eth_dev_get_eeprom;
rte_eth_dev_get_eeprom_length;
rte_eth_dev_get_mtu;
+ rte_eth_dev_get_name_by_port;
+ rte_eth_dev_get_port_by_name;
rte_eth_dev_get_reg_info;
+ rte_eth_dev_get_sec_ctx;
+ rte_eth_dev_get_supported_ptypes;
rte_eth_dev_get_vlan_offload;
- rte_eth_devices;
rte_eth_dev_info_get;
rte_eth_dev_is_valid_port;
+ rte_eth_dev_l2_tunnel_eth_type_conf;
+ rte_eth_dev_l2_tunnel_offload_set;
+ rte_eth_dev_logtype;
rte_eth_dev_mac_addr_add;
rte_eth_dev_mac_addr_remove;
+ rte_eth_dev_pool_ops_supported;
rte_eth_dev_priority_flow_ctrl_set;
+ rte_eth_dev_probing_finish;
rte_eth_dev_release_port;
+ rte_eth_dev_reset;
rte_eth_dev_rss_hash_conf_get;
rte_eth_dev_rss_hash_update;
rte_eth_dev_rss_reta_query;
@@ -38,6 +56,7 @@ DPDK_2.2 {
rte_eth_dev_rx_intr_ctl_q;
rte_eth_dev_rx_intr_disable;
rte_eth_dev_rx_intr_enable;
+ rte_eth_dev_rx_offload_name;
rte_eth_dev_rx_queue_start;
rte_eth_dev_rx_queue_stop;
rte_eth_dev_set_eeprom;
@@ -47,18 +66,28 @@ DPDK_2.2 {
rte_eth_dev_set_mtu;
rte_eth_dev_set_rx_queue_stats_mapping;
rte_eth_dev_set_tx_queue_stats_mapping;
+ rte_eth_dev_set_vlan_ether_type;
rte_eth_dev_set_vlan_offload;
rte_eth_dev_set_vlan_pvid;
rte_eth_dev_set_vlan_strip_on_queue;
rte_eth_dev_socket_id;
rte_eth_dev_start;
rte_eth_dev_stop;
+ rte_eth_dev_tx_offload_name;
rte_eth_dev_tx_queue_start;
rte_eth_dev_tx_queue_stop;
rte_eth_dev_uc_all_hash_table_set;
rte_eth_dev_uc_hash_table_set;
+ rte_eth_dev_udp_tunnel_port_add;
+ rte_eth_dev_udp_tunnel_port_delete;
rte_eth_dev_vlan_filter;
+ rte_eth_devices;
rte_eth_dma_zone_reserve;
+ rte_eth_find_next;
+ rte_eth_find_next_owned_by;
+ rte_eth_iterator_cleanup;
+ rte_eth_iterator_init;
+ rte_eth_iterator_next;
rte_eth_led_off;
rte_eth_led_on;
rte_eth_link;
@@ -75,6 +104,7 @@ DPDK_2.2 {
rte_eth_rx_queue_info_get;
rte_eth_rx_queue_setup;
rte_eth_set_queue_rate_limit;
+ rte_eth_speed_bitflag;
rte_eth_stats;
rte_eth_stats_get;
rte_eth_stats_reset;
@@ -85,66 +115,27 @@ DPDK_2.2 {
rte_eth_timesync_read_time;
rte_eth_timesync_read_tx_timestamp;
rte_eth_timesync_write_time;
- rte_eth_tx_queue_info_get;
- rte_eth_tx_queue_setup;
- rte_eth_xstats_get;
- rte_eth_xstats_reset;
-
- local: *;
-};
-
-DPDK_16.04 {
- global:
-
- rte_eth_dev_get_supported_ptypes;
- rte_eth_dev_l2_tunnel_eth_type_conf;
- rte_eth_dev_l2_tunnel_offload_set;
- rte_eth_dev_set_vlan_ether_type;
- rte_eth_dev_udp_tunnel_port_add;
- rte_eth_dev_udp_tunnel_port_delete;
- rte_eth_speed_bitflag;
rte_eth_tx_buffer_count_callback;
rte_eth_tx_buffer_drop_callback;
rte_eth_tx_buffer_init;
rte_eth_tx_buffer_set_err_callback;
-
-} DPDK_2.2;
-
-DPDK_16.07 {
- global:
-
- rte_eth_add_first_rx_callback;
- rte_eth_dev_get_name_by_port;
- rte_eth_dev_get_port_by_name;
- rte_eth_xstats_get_names;
-
-} DPDK_16.04;
-
-DPDK_17.02 {
- global:
-
- _rte_eth_dev_reset;
- rte_eth_dev_fw_version_get;
-
-} DPDK_16.07;
-
-DPDK_17.05 {
- global:
-
- rte_eth_dev_attach_secondary;
- rte_eth_find_next;
rte_eth_tx_done_cleanup;
+ rte_eth_tx_queue_info_get;
+ rte_eth_tx_queue_setup;
+ rte_eth_xstats_get;
rte_eth_xstats_get_by_id;
rte_eth_xstats_get_id_by_name;
+ rte_eth_xstats_get_names;
rte_eth_xstats_get_names_by_id;
-
-} DPDK_17.02;
-
-DPDK_17.08 {
- global:
-
- _rte_eth_dev_callback_process;
- rte_eth_dev_adjust_nb_rx_tx_desc;
+ rte_eth_xstats_reset;
+ rte_flow_copy;
+ rte_flow_create;
+ rte_flow_destroy;
+ rte_flow_error_set;
+ rte_flow_flush;
+ rte_flow_isolate;
+ rte_flow_query;
+ rte_flow_validate;
rte_tm_capabilities_get;
rte_tm_get_number_of_leaf_nodes;
rte_tm_hierarchy_commit;
@@ -176,65 +167,8 @@ DPDK_17.08 {
rte_tm_wred_profile_add;
rte_tm_wred_profile_delete;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_eth_dev_get_sec_ctx;
- rte_eth_dev_pool_ops_supported;
- rte_eth_dev_reset;
-
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_eth_dev_filter_ctrl;
-
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_eth_dev_count_avail;
- rte_eth_dev_probing_finish;
- rte_eth_find_next_owned_by;
- rte_flow_copy;
- rte_flow_create;
- rte_flow_destroy;
- rte_flow_error_set;
- rte_flow_flush;
- rte_flow_isolate;
- rte_flow_query;
- rte_flow_validate;
-
-} DPDK_18.02;
-
-DPDK_18.08 {
- global:
-
- rte_eth_dev_logtype;
-
-} DPDK_18.05;
-
-DPDK_18.11 {
- global:
-
- rte_eth_dev_rx_offload_name;
- rte_eth_dev_tx_offload_name;
- rte_eth_iterator_cleanup;
- rte_eth_iterator_init;
- rte_eth_iterator_next;
-
-} DPDK_18.08;
-
-DPDK_19.05 {
- global:
-
- rte_eth_dev_count_total;
-
-} DPDK_18.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_eventdev/rte_eventdev_version.map b/lib/librte_eventdev/rte_eventdev_version.map
index 76b3021d3a..edfc15282d 100644
--- a/lib/librte_eventdev/rte_eventdev_version.map
+++ b/lib/librte_eventdev/rte_eventdev_version.map
@@ -1,61 +1,38 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
- rte_eventdevs;
-
+ rte_event_crypto_adapter_caps_get;
+ rte_event_crypto_adapter_create;
+ rte_event_crypto_adapter_create_ext;
+ rte_event_crypto_adapter_event_port_get;
+ rte_event_crypto_adapter_free;
+ rte_event_crypto_adapter_queue_pair_add;
+ rte_event_crypto_adapter_queue_pair_del;
+ rte_event_crypto_adapter_service_id_get;
+ rte_event_crypto_adapter_start;
+ rte_event_crypto_adapter_stats_get;
+ rte_event_crypto_adapter_stats_reset;
+ rte_event_crypto_adapter_stop;
+ rte_event_dequeue_timeout_ticks;
+ rte_event_dev_attr_get;
+ rte_event_dev_close;
+ rte_event_dev_configure;
rte_event_dev_count;
+ rte_event_dev_dump;
rte_event_dev_get_dev_id;
- rte_event_dev_socket_id;
rte_event_dev_info_get;
- rte_event_dev_configure;
+ rte_event_dev_selftest;
+ rte_event_dev_service_id_get;
+ rte_event_dev_socket_id;
rte_event_dev_start;
rte_event_dev_stop;
- rte_event_dev_close;
- rte_event_dev_dump;
+ rte_event_dev_stop_flush_callback_register;
rte_event_dev_xstats_by_name_get;
rte_event_dev_xstats_get;
rte_event_dev_xstats_names_get;
rte_event_dev_xstats_reset;
-
- rte_event_port_default_conf_get;
- rte_event_port_setup;
- rte_event_port_link;
- rte_event_port_unlink;
- rte_event_port_links_get;
-
- rte_event_queue_default_conf_get;
- rte_event_queue_setup;
-
- rte_event_dequeue_timeout_ticks;
-
- rte_event_pmd_allocate;
- rte_event_pmd_release;
- rte_event_pmd_vdev_init;
- rte_event_pmd_vdev_uninit;
- rte_event_pmd_pci_probe;
- rte_event_pmd_pci_remove;
-
- local: *;
-};
-
-DPDK_17.08 {
- global:
-
- rte_event_ring_create;
- rte_event_ring_free;
- rte_event_ring_init;
- rte_event_ring_lookup;
-} DPDK_17.05;
-
-DPDK_17.11 {
- global:
-
- rte_event_dev_attr_get;
- rte_event_dev_service_id_get;
- rte_event_port_attr_get;
- rte_event_queue_attr_get;
-
rte_event_eth_rx_adapter_caps_get;
+ rte_event_eth_rx_adapter_cb_register;
rte_event_eth_rx_adapter_create;
rte_event_eth_rx_adapter_create_ext;
rte_event_eth_rx_adapter_free;
@@ -63,38 +40,9 @@ DPDK_17.11 {
rte_event_eth_rx_adapter_queue_del;
rte_event_eth_rx_adapter_service_id_get;
rte_event_eth_rx_adapter_start;
+ rte_event_eth_rx_adapter_stats_get;
rte_event_eth_rx_adapter_stats_reset;
rte_event_eth_rx_adapter_stop;
-} DPDK_17.08;
-
-DPDK_18.02 {
- global:
-
- rte_event_dev_selftest;
-} DPDK_17.11;
-
-DPDK_18.05 {
- global:
-
- rte_event_dev_stop_flush_callback_register;
-} DPDK_18.02;
-
-DPDK_19.05 {
- global:
-
- rte_event_crypto_adapter_caps_get;
- rte_event_crypto_adapter_create;
- rte_event_crypto_adapter_create_ext;
- rte_event_crypto_adapter_event_port_get;
- rte_event_crypto_adapter_free;
- rte_event_crypto_adapter_queue_pair_add;
- rte_event_crypto_adapter_queue_pair_del;
- rte_event_crypto_adapter_service_id_get;
- rte_event_crypto_adapter_start;
- rte_event_crypto_adapter_stats_get;
- rte_event_crypto_adapter_stats_reset;
- rte_event_crypto_adapter_stop;
- rte_event_port_unlinks_in_progress;
rte_event_eth_tx_adapter_caps_get;
rte_event_eth_tx_adapter_create;
rte_event_eth_tx_adapter_create_ext;
@@ -107,6 +55,26 @@ DPDK_19.05 {
rte_event_eth_tx_adapter_stats_get;
rte_event_eth_tx_adapter_stats_reset;
rte_event_eth_tx_adapter_stop;
+ rte_event_pmd_allocate;
+ rte_event_pmd_pci_probe;
+ rte_event_pmd_pci_remove;
+ rte_event_pmd_release;
+ rte_event_pmd_vdev_init;
+ rte_event_pmd_vdev_uninit;
+ rte_event_port_attr_get;
+ rte_event_port_default_conf_get;
+ rte_event_port_link;
+ rte_event_port_links_get;
+ rte_event_port_setup;
+ rte_event_port_unlink;
+ rte_event_port_unlinks_in_progress;
+ rte_event_queue_attr_get;
+ rte_event_queue_default_conf_get;
+ rte_event_queue_setup;
+ rte_event_ring_create;
+ rte_event_ring_free;
+ rte_event_ring_init;
+ rte_event_ring_lookup;
rte_event_timer_adapter_caps_get;
rte_event_timer_adapter_create;
rte_event_timer_adapter_create_ext;
@@ -121,11 +89,7 @@ DPDK_19.05 {
rte_event_timer_arm_burst;
rte_event_timer_arm_tmo_tick_burst;
rte_event_timer_cancel_burst;
-} DPDK_18.05;
+ rte_eventdevs;
-DPDK_19.08 {
- global:
-
- rte_event_eth_rx_adapter_cb_register;
- rte_event_eth_rx_adapter_stats_get;
-} DPDK_19.05;
+ local: *;
+};
diff --git a/lib/librte_flow_classify/rte_flow_classify_version.map b/lib/librte_flow_classify/rte_flow_classify_version.map
index 49bc25c6a0..001ff660e3 100644
--- a/lib/librte_flow_classify/rte_flow_classify_version.map
+++ b/lib/librte_flow_classify/rte_flow_classify_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_gro/rte_gro_version.map b/lib/librte_gro/rte_gro_version.map
index 1606b6dc72..9f6fe79e57 100644
--- a/lib/librte_gro/rte_gro_version.map
+++ b/lib/librte_gro/rte_gro_version.map
@@ -1,4 +1,4 @@
-DPDK_17.08 {
+DPDK_20.0 {
global:
rte_gro_ctx_create;
diff --git a/lib/librte_gso/rte_gso_version.map b/lib/librte_gso/rte_gso_version.map
index e1fd453edb..8505a59c27 100644
--- a/lib/librte_gso/rte_gso_version.map
+++ b/lib/librte_gso/rte_gso_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_gso_segment;
diff --git a/lib/librte_hash/rte_hash_version.map b/lib/librte_hash/rte_hash_version.map
index 734ae28b04..138c130c1b 100644
--- a/lib/librte_hash/rte_hash_version.map
+++ b/lib/librte_hash/rte_hash_version.map
@@ -1,58 +1,33 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_fbk_hash_create;
rte_fbk_hash_find_existing;
rte_fbk_hash_free;
rte_hash_add_key;
+ rte_hash_add_key_data;
rte_hash_add_key_with_hash;
+ rte_hash_add_key_with_hash_data;
+ rte_hash_count;
rte_hash_create;
rte_hash_del_key;
rte_hash_del_key_with_hash;
rte_hash_find_existing;
rte_hash_free;
+ rte_hash_get_key_with_position;
rte_hash_hash;
+ rte_hash_iterate;
rte_hash_lookup;
rte_hash_lookup_bulk;
- rte_hash_lookup_with_hash;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_hash_add_key_data;
- rte_hash_add_key_with_hash_data;
- rte_hash_iterate;
rte_hash_lookup_bulk_data;
rte_hash_lookup_data;
+ rte_hash_lookup_with_hash;
rte_hash_lookup_with_hash_data;
rte_hash_reset;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_hash_set_cmp_func;
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_hash_get_key_with_position;
-
-} DPDK_2.2;
-
-
-DPDK_18.08 {
- global:
-
- rte_hash_count;
-
-} DPDK_16.07;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_frag/rte_ip_frag_version.map
index a193007c61..5dd34f828c 100644
--- a/lib/librte_ip_frag/rte_ip_frag_version.map
+++ b/lib/librte_ip_frag/rte_ip_frag_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ip_frag_free_death_row;
rte_ip_frag_table_create;
+ rte_ip_frag_table_destroy;
rte_ip_frag_table_statistics_dump;
rte_ipv4_frag_reassemble_packet;
rte_ipv4_fragment_packet;
@@ -12,13 +13,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_17.08 {
- global:
-
- rte_ip_frag_table_destroy;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_ipsec/rte_ipsec_version.map b/lib/librte_ipsec/rte_ipsec_version.map
index ee9f1961b0..3723b812fc 100644
--- a/lib/librte_ipsec/rte_ipsec_version.map
+++ b/lib/librte_ipsec/rte_ipsec_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_jobstats/rte_jobstats_version.map b/lib/librte_jobstats/rte_jobstats_version.map
index f89441438e..dbd2664ae2 100644
--- a/lib/librte_jobstats/rte_jobstats_version.map
+++ b/lib/librte_jobstats/rte_jobstats_version.map
@@ -1,6 +1,7 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_jobstats_abort;
rte_jobstats_context_finish;
rte_jobstats_context_init;
rte_jobstats_context_reset;
@@ -17,10 +18,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_jobstats_abort;
-
-} DPDK_2.0;
diff --git a/lib/librte_kni/rte_kni_version.map b/lib/librte_kni/rte_kni_version.map
index c877dc6aaa..9cd3cedc54 100644
--- a/lib/librte_kni/rte_kni_version.map
+++ b/lib/librte_kni/rte_kni_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kni_alloc;
diff --git a/lib/librte_kvargs/rte_kvargs_version.map b/lib/librte_kvargs/rte_kvargs_version.map
index 8f4b4e3f8f..3ba0f4b59c 100644
--- a/lib/librte_kvargs/rte_kvargs_version.map
+++ b/lib/librte_kvargs/rte_kvargs_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_kvargs_count;
@@ -15,4 +15,4 @@ EXPERIMENTAL {
rte_kvargs_parse_delim;
rte_kvargs_strcmp;
-} DPDK_2.0;
+};
diff --git a/lib/librte_latencystats/rte_latencystats_version.map b/lib/librte_latencystats/rte_latencystats_version.map
index ac8403e821..e04e63463f 100644
--- a/lib/librte_latencystats/rte_latencystats_version.map
+++ b/lib/librte_latencystats/rte_latencystats_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_latencystats_get;
diff --git a/lib/librte_lpm/rte_lpm_version.map b/lib/librte_lpm/rte_lpm_version.map
index 90beac853d..500f58b806 100644
--- a/lib/librte_lpm/rte_lpm_version.map
+++ b/lib/librte_lpm/rte_lpm_version.map
@@ -1,13 +1,6 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
- rte_lpm_add;
- rte_lpm_create;
- rte_lpm_delete;
- rte_lpm_delete_all;
- rte_lpm_find_existing;
- rte_lpm_free;
- rte_lpm_is_rule_present;
rte_lpm6_add;
rte_lpm6_create;
rte_lpm6_delete;
@@ -18,29 +11,13 @@ DPDK_2.0 {
rte_lpm6_is_rule_present;
rte_lpm6_lookup;
rte_lpm6_lookup_bulk_func;
+ rte_lpm_add;
+ rte_lpm_create;
+ rte_lpm_delete;
+ rte_lpm_delete_all;
+ rte_lpm_find_existing;
+ rte_lpm_free;
+ rte_lpm_is_rule_present;
local: *;
};
-
-DPDK_16.04 {
- global:
-
- rte_lpm_add;
- rte_lpm_find_existing;
- rte_lpm_create;
- rte_lpm_free;
- rte_lpm_is_rule_present;
- rte_lpm_delete;
- rte_lpm_delete_all;
-
-} DPDK_2.0;
-
-DPDK_17.05 {
- global:
-
- rte_lpm6_add;
- rte_lpm6_is_rule_present;
- rte_lpm6_lookup;
- rte_lpm6_lookup_bulk_func;
-
-} DPDK_16.04;
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index 2662a37bf6..d20aa31857 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -1,24 +1,4 @@
-DPDK_2.0 {
- global:
-
- rte_get_rx_ol_flag_name;
- rte_get_tx_ol_flag_name;
- rte_mbuf_sanity_check;
- rte_pktmbuf_dump;
- rte_pktmbuf_init;
- rte_pktmbuf_pool_init;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pktmbuf_pool_create;
-
-} DPDK_2.0;
-
-DPDK_16.11 {
+DPDK_20.0 {
global:
__rte_pktmbuf_read;
@@ -31,23 +11,26 @@ DPDK_16.11 {
rte_get_ptype_name;
rte_get_ptype_tunnel_name;
rte_get_rx_ol_flag_list;
+ rte_get_rx_ol_flag_name;
rte_get_tx_ol_flag_list;
-
-} DPDK_2.1;
-
-DPDK_18.08 {
- global:
-
+ rte_get_tx_ol_flag_name;
rte_mbuf_best_mempool_ops;
rte_mbuf_platform_mempool_ops;
+ rte_mbuf_sanity_check;
rte_mbuf_set_platform_mempool_ops;
rte_mbuf_set_user_mempool_ops;
rte_mbuf_user_mempool_ops;
+ rte_pktmbuf_dump;
+ rte_pktmbuf_init;
+ rte_pktmbuf_pool_create;
rte_pktmbuf_pool_create_by_ops;
-} DPDK_16.11;
+ rte_pktmbuf_pool_init;
+
+ local: *;
+};
EXPERIMENTAL {
global:
rte_mbuf_check;
-} DPDK_18.08;
+};
diff --git a/lib/librte_member/rte_member_version.map b/lib/librte_member/rte_member_version.map
index 019e4cd962..87780ae611 100644
--- a/lib/librte_member/rte_member_version.map
+++ b/lib/librte_member/rte_member_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_member_add;
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 17cbca4607..6a425d203a 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -1,57 +1,39 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_mempool_audit;
- rte_mempool_calc_obj_size;
- rte_mempool_create;
- rte_mempool_dump;
- rte_mempool_list_dump;
- rte_mempool_lookup;
- rte_mempool_walk;
-
- local: *;
-};
-
-DPDK_16.07 {
- global:
-
rte_mempool_avail_count;
rte_mempool_cache_create;
rte_mempool_cache_flush;
rte_mempool_cache_free;
+ rte_mempool_calc_obj_size;
rte_mempool_check_cookies;
+ rte_mempool_contig_blocks_check_cookies;
+ rte_mempool_create;
rte_mempool_create_empty;
rte_mempool_default_cache;
+ rte_mempool_dump;
rte_mempool_free;
rte_mempool_generic_get;
rte_mempool_generic_put;
rte_mempool_in_use_count;
+ rte_mempool_list_dump;
+ rte_mempool_lookup;
rte_mempool_mem_iter;
rte_mempool_obj_iter;
+ rte_mempool_op_calc_mem_size_default;
+ rte_mempool_op_populate_default;
rte_mempool_ops_table;
rte_mempool_populate_anon;
rte_mempool_populate_default;
+ rte_mempool_populate_iova;
rte_mempool_populate_virt;
rte_mempool_register_ops;
rte_mempool_set_ops_byname;
+ rte_mempool_walk;
-} DPDK_2.0;
-
-DPDK_17.11 {
- global:
-
- rte_mempool_populate_iova;
-
-} DPDK_16.07;
-
-DPDK_18.05 {
- global:
-
- rte_mempool_contig_blocks_check_cookies;
- rte_mempool_op_calc_mem_size_default;
- rte_mempool_op_populate_default;
-
-} DPDK_17.11;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 4b460d5803..46410b0369 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -1,21 +1,16 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_meter_srtcm_color_aware_check;
rte_meter_srtcm_color_blind_check;
rte_meter_srtcm_config;
+ rte_meter_srtcm_profile_config;
rte_meter_trtcm_color_aware_check;
rte_meter_trtcm_color_blind_check;
rte_meter_trtcm_config;
-
- local: *;
-};
-
-DPDK_18.08 {
- global:
-
- rte_meter_srtcm_profile_config;
rte_meter_trtcm_profile_config;
+
+ local: *;
};
EXPERIMENTAL {
diff --git a/lib/librte_metrics/rte_metrics_version.map b/lib/librte_metrics/rte_metrics_version.map
index 6ac99a44a1..85663f356e 100644
--- a/lib/librte_metrics/rte_metrics_version.map
+++ b/lib/librte_metrics/rte_metrics_version.map
@@ -1,4 +1,4 @@
-DPDK_17.05 {
+DPDK_20.0 {
global:
rte_metrics_get_names;
diff --git a/lib/librte_net/rte_net_version.map b/lib/librte_net/rte_net_version.map
index fffc4a3723..8a4e75a3a0 100644
--- a/lib/librte_net/rte_net_version.map
+++ b/lib/librte_net/rte_net_version.map
@@ -1,25 +1,14 @@
-DPDK_16.11 {
- global:
- rte_net_get_ptype;
-
- local: *;
-};
-
-DPDK_17.05 {
- global:
-
- rte_net_crc_calc;
- rte_net_crc_set_alg;
-
-} DPDK_16.11;
-
-DPDK_19.08 {
+DPDK_20.0 {
global:
rte_eth_random_addr;
rte_ether_format_addr;
+ rte_net_crc_calc;
+ rte_net_crc_set_alg;
+ rte_net_get_ptype;
-} DPDK_17.05;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_pci/rte_pci_version.map b/lib/librte_pci/rte_pci_version.map
index c0280277bb..539785f5f4 100644
--- a/lib/librte_pci/rte_pci_version.map
+++ b/lib/librte_pci/rte_pci_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
eal_parse_pci_BDF;
diff --git a/lib/librte_pdump/rte_pdump_version.map b/lib/librte_pdump/rte_pdump_version.map
index 3e744f3012..6d02ccce6d 100644
--- a/lib/librte_pdump/rte_pdump_version.map
+++ b/lib/librte_pdump/rte_pdump_version.map
@@ -1,4 +1,4 @@
-DPDK_16.07 {
+DPDK_20.0 {
global:
rte_pdump_disable;
diff --git a/lib/librte_pipeline/rte_pipeline_version.map b/lib/librte_pipeline/rte_pipeline_version.map
index 420f065d6e..64d38afecd 100644
--- a/lib/librte_pipeline/rte_pipeline_version.map
+++ b/lib/librte_pipeline/rte_pipeline_version.map
@@ -1,6 +1,8 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_pipeline_ah_packet_drop;
+ rte_pipeline_ah_packet_hijack;
rte_pipeline_check;
rte_pipeline_create;
rte_pipeline_flush;
@@ -9,42 +11,22 @@ DPDK_2.0 {
rte_pipeline_port_in_create;
rte_pipeline_port_in_disable;
rte_pipeline_port_in_enable;
+ rte_pipeline_port_in_stats_read;
rte_pipeline_port_out_create;
rte_pipeline_port_out_packet_insert;
+ rte_pipeline_port_out_stats_read;
rte_pipeline_run;
rte_pipeline_table_create;
rte_pipeline_table_default_entry_add;
rte_pipeline_table_default_entry_delete;
rte_pipeline_table_entry_add;
- rte_pipeline_table_entry_delete;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_pipeline_port_in_stats_read;
- rte_pipeline_port_out_stats_read;
- rte_pipeline_table_stats_read;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
rte_pipeline_table_entry_add_bulk;
+ rte_pipeline_table_entry_delete;
rte_pipeline_table_entry_delete_bulk;
+ rte_pipeline_table_stats_read;
-} DPDK_2.1;
-
-DPDK_16.04 {
- global:
-
- rte_pipeline_ah_packet_hijack;
- rte_pipeline_ah_packet_drop;
-
-} DPDK_2.2;
+ local: *;
+};
EXPERIMENTAL {
global:
diff --git a/lib/librte_port/rte_port_version.map b/lib/librte_port/rte_port_version.map
index 609bcec3ff..db1b8681d9 100644
--- a/lib/librte_port/rte_port_version.map
+++ b/lib/librte_port/rte_port_version.map
@@ -1,62 +1,32 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_port_ethdev_reader_ops;
+ rte_port_ethdev_writer_nodrop_ops;
rte_port_ethdev_writer_ops;
+ rte_port_fd_reader_ops;
+ rte_port_fd_writer_nodrop_ops;
+ rte_port_fd_writer_ops;
+ rte_port_kni_reader_ops;
+ rte_port_kni_writer_nodrop_ops;
+ rte_port_kni_writer_ops;
+ rte_port_ring_multi_reader_ops;
+ rte_port_ring_multi_writer_nodrop_ops;
+ rte_port_ring_multi_writer_ops;
rte_port_ring_reader_ipv4_frag_ops;
+ rte_port_ring_reader_ipv6_frag_ops;
rte_port_ring_reader_ops;
rte_port_ring_writer_ipv4_ras_ops;
+ rte_port_ring_writer_ipv6_ras_ops;
+ rte_port_ring_writer_nodrop_ops;
rte_port_ring_writer_ops;
rte_port_sched_reader_ops;
rte_port_sched_writer_ops;
rte_port_sink_ops;
rte_port_source_ops;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_port_ethdev_writer_nodrop_ops;
- rte_port_ring_reader_ipv6_frag_ops;
- rte_port_ring_writer_ipv6_ras_ops;
- rte_port_ring_writer_nodrop_ops;
-
-} DPDK_2.0;
-
-DPDK_2.2 {
- global:
-
- rte_port_ring_multi_reader_ops;
- rte_port_ring_multi_writer_ops;
- rte_port_ring_multi_writer_nodrop_ops;
-
-} DPDK_2.1;
-
-DPDK_16.07 {
- global:
-
- rte_port_kni_reader_ops;
- rte_port_kni_writer_ops;
- rte_port_kni_writer_nodrop_ops;
-
-} DPDK_2.2;
-
-DPDK_16.11 {
- global:
-
- rte_port_fd_reader_ops;
- rte_port_fd_writer_ops;
- rte_port_fd_writer_nodrop_ops;
-
-} DPDK_16.07;
-
-DPDK_18.11 {
- global:
-
rte_port_sym_crypto_reader_ops;
- rte_port_sym_crypto_writer_ops;
rte_port_sym_crypto_writer_nodrop_ops;
+ rte_port_sym_crypto_writer_ops;
-} DPDK_16.11;
+ local: *;
+};
diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map
index 042917360e..a94ab30c3d 100644
--- a/lib/librte_power/rte_power_version.map
+++ b/lib/librte_power/rte_power_version.map
@@ -1,39 +1,27 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_power_exit;
+ rte_power_freq_disable_turbo;
rte_power_freq_down;
+ rte_power_freq_enable_turbo;
rte_power_freq_max;
rte_power_freq_min;
rte_power_freq_up;
rte_power_freqs;
+ rte_power_get_capabilities;
rte_power_get_env;
rte_power_get_freq;
+ rte_power_guest_channel_send_msg;
rte_power_init;
rte_power_set_env;
rte_power_set_freq;
+ rte_power_turbo_status;
rte_power_unset_env;
local: *;
};
-DPDK_17.11 {
- global:
-
- rte_power_guest_channel_send_msg;
- rte_power_freq_disable_turbo;
- rte_power_freq_enable_turbo;
- rte_power_turbo_status;
-
-} DPDK_2.0;
-
-DPDK_18.08 {
- global:
-
- rte_power_get_capabilities;
-
-} DPDK_17.11;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_rawdev/rte_rawdev_version.map b/lib/librte_rawdev/rte_rawdev_version.map
index b61dbff11c..d847c9e0d3 100644
--- a/lib/librte_rawdev/rte_rawdev_version.map
+++ b/lib/librte_rawdev/rte_rawdev_version.map
@@ -1,4 +1,4 @@
-DPDK_18.08 {
+DPDK_20.0 {
global:
rte_rawdev_close;
@@ -17,8 +17,8 @@ DPDK_18.08 {
rte_rawdev_pmd_release;
rte_rawdev_queue_conf_get;
rte_rawdev_queue_count;
- rte_rawdev_queue_setup;
rte_rawdev_queue_release;
+ rte_rawdev_queue_setup;
rte_rawdev_reset;
rte_rawdev_selftest;
rte_rawdev_set_attr;
diff --git a/lib/librte_rcu/rte_rcu_version.map b/lib/librte_rcu/rte_rcu_version.map
index f8b9ef2abb..787e51ef27 100644
--- a/lib/librte_rcu/rte_rcu_version.map
+++ b/lib/librte_rcu/rte_rcu_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_reorder/rte_reorder_version.map b/lib/librte_reorder/rte_reorder_version.map
index 0a8a54de83..cf444062df 100644
--- a/lib/librte_reorder/rte_reorder_version.map
+++ b/lib/librte_reorder/rte_reorder_version.map
@@ -1,13 +1,13 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_reorder_create;
- rte_reorder_init;
+ rte_reorder_drain;
rte_reorder_find_existing;
- rte_reorder_reset;
rte_reorder_free;
+ rte_reorder_init;
rte_reorder_insert;
- rte_reorder_drain;
+ rte_reorder_reset;
local: *;
};
diff --git a/lib/librte_ring/rte_ring_version.map b/lib/librte_ring/rte_ring_version.map
index 510c1386e0..89d84bcf48 100644
--- a/lib/librte_ring/rte_ring_version.map
+++ b/lib/librte_ring/rte_ring_version.map
@@ -1,8 +1,9 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_ring_create;
rte_ring_dump;
+ rte_ring_free;
rte_ring_get_memsize;
rte_ring_init;
rte_ring_list_dump;
@@ -11,13 +12,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.2 {
- global:
-
- rte_ring_free;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_sched/rte_sched_version.map b/lib/librte_sched/rte_sched_version.map
index 729588794e..1b48bfbf36 100644
--- a/lib/librte_sched/rte_sched_version.map
+++ b/lib/librte_sched/rte_sched_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_approx;
@@ -14,6 +14,9 @@ DPDK_2.0 {
rte_sched_port_enqueue;
rte_sched_port_free;
rte_sched_port_get_memory_footprint;
+ rte_sched_port_pkt_read_color;
+ rte_sched_port_pkt_read_tree_path;
+ rte_sched_port_pkt_write;
rte_sched_queue_read_stats;
rte_sched_subport_config;
rte_sched_subport_read_stats;
@@ -21,15 +24,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_2.1 {
- global:
-
- rte_sched_port_pkt_write;
- rte_sched_port_pkt_read_tree_path;
- rte_sched_port_pkt_read_color;
-
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_security/rte_security_version.map b/lib/librte_security/rte_security_version.map
index 53267bf3cc..b07314bbf4 100644
--- a/lib/librte_security/rte_security_version.map
+++ b/lib/librte_security/rte_security_version.map
@@ -1,4 +1,4 @@
-DPDK_18.11 {
+DPDK_20.0 {
global:
rte_security_attach_session;
diff --git a/lib/librte_stack/rte_stack_version.map b/lib/librte_stack/rte_stack_version.map
index 6662679c36..adbb7be9d9 100644
--- a/lib/librte_stack/rte_stack_version.map
+++ b/lib/librte_stack/rte_stack_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_table/rte_table_version.map b/lib/librte_table/rte_table_version.map
index 6237252bec..40f72b1fe8 100644
--- a/lib/librte_table/rte_table_version.map
+++ b/lib/librte_table/rte_table_version.map
@@ -1,4 +1,4 @@
-DPDK_17.11 {
+DPDK_20.0 {
global:
rte_table_acl_ops;
diff --git a/lib/librte_telemetry/rte_telemetry_version.map b/lib/librte_telemetry/rte_telemetry_version.map
index fa62d7718c..c1f4613af5 100644
--- a/lib/librte_telemetry/rte_telemetry_version.map
+++ b/lib/librte_telemetry/rte_telemetry_version.map
@@ -1,3 +1,7 @@
+DPDK_20.0 {
+ local: *;
+};
+
EXPERIMENTAL {
global:
diff --git a/lib/librte_timer/rte_timer_version.map b/lib/librte_timer/rte_timer_version.map
index 72f75c8181..2a59d3f081 100644
--- a/lib/librte_timer/rte_timer_version.map
+++ b/lib/librte_timer/rte_timer_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
rte_timer_dump_stats;
@@ -14,16 +14,6 @@ DPDK_2.0 {
local: *;
};
-DPDK_19.05 {
- global:
-
- rte_timer_dump_stats;
- rte_timer_manage;
- rte_timer_reset;
- rte_timer_stop;
- rte_timer_subsystem_init;
-} DPDK_2.0;
-
EXPERIMENTAL {
global:
diff --git a/lib/librte_vhost/rte_vhost_version.map b/lib/librte_vhost/rte_vhost_version.map
index 5f1d4a75c2..8e9ffac2c2 100644
--- a/lib/librte_vhost/rte_vhost_version.map
+++ b/lib/librte_vhost/rte_vhost_version.map
@@ -1,64 +1,34 @@
-DPDK_2.0 {
+DPDK_20.0 {
global:
+ rte_vhost_avail_entries;
rte_vhost_dequeue_burst;
rte_vhost_driver_callback_register;
- rte_vhost_driver_register;
- rte_vhost_enable_guest_notification;
- rte_vhost_enqueue_burst;
-
- local: *;
-};
-
-DPDK_2.1 {
- global:
-
- rte_vhost_driver_unregister;
-
-} DPDK_2.0;
-
-DPDK_16.07 {
- global:
-
- rte_vhost_avail_entries;
- rte_vhost_get_ifname;
- rte_vhost_get_numa_node;
- rte_vhost_get_queue_num;
-
-} DPDK_2.1;
-
-DPDK_17.05 {
- global:
-
rte_vhost_driver_disable_features;
rte_vhost_driver_enable_features;
rte_vhost_driver_get_features;
+ rte_vhost_driver_register;
rte_vhost_driver_set_features;
rte_vhost_driver_start;
+ rte_vhost_driver_unregister;
+ rte_vhost_enable_guest_notification;
+ rte_vhost_enqueue_burst;
+ rte_vhost_get_ifname;
rte_vhost_get_mem_table;
rte_vhost_get_mtu;
rte_vhost_get_negotiated_features;
+ rte_vhost_get_numa_node;
+ rte_vhost_get_queue_num;
rte_vhost_get_vhost_vring;
rte_vhost_get_vring_num;
rte_vhost_gpa_to_vva;
rte_vhost_log_used_vring;
rte_vhost_log_write;
-
-} DPDK_16.07;
-
-DPDK_17.08 {
- global:
-
rte_vhost_rx_queue_count;
-
-} DPDK_17.05;
-
-DPDK_18.02 {
- global:
-
rte_vhost_vring_call;
-} DPDK_17.08;
+ local: *;
+};
EXPERIMENTAL {
global:
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v3 9/9] buildtools: add ABI versioning check script
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (8 preceding siblings ...)
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 8/9] build: change ABI version to 20.0 Anatoly Burakov
@ 2019-10-16 17:03 23% ` Anatoly Burakov
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
Add a shell script that checks whether built libraries are
versioned with expected ABI (current ABI, current ABI + 1,
or EXPERIMENTAL).
The following command was used to verify current source tree
(assuming build directory is in ./build):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to the end of the patchset
- Fixed bug when ABI symbols were not found because the .so
did not declare any public symbols
buildtools/check-abi-version.sh | 54 +++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100755 buildtools/check-abi-version.sh
diff --git a/buildtools/check-abi-version.sh b/buildtools/check-abi-version.sh
new file mode 100755
index 0000000000..29aea97735
--- /dev/null
+++ b/buildtools/check-abi-version.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# Check whether library symbols have correct
+# version (provided ABI number or provided ABI
+# number + 1 or EXPERIMENTAL).
+# Args:
+# $1: path of the library .so file
+# $2: ABI major version number to check
+# (defaults to ABI_VERSION file value)
+
+if [ -z "$1" ]; then
+ echo "Script checks whether library symbols have"
+ echo "correct version (ABI_VER/ABI_VER+1/EXPERIMENTAL)"
+ echo "Usage:"
+ echo " $0 SO_FILE_PATH [ABI_VER]"
+ exit 1
+fi
+
+LIB="$1"
+DEFAULT_ABI=$(cat "$(dirname \
+ $(readlink -f $0))/../config/ABI_VERSION" | \
+ cut -d'.' -f 1)
+ABIVER="DPDK_${2-$DEFAULT_ABI}"
+NEXT_ABIVER="DPDK_$((${2-$DEFAULT_ABI}+1))"
+
+ret=0
+
+# get output of objdump
+OBJ_DUMP_OUTPUT=`objdump -TC --section=.text ${LIB} 2>&1 | grep ".text"`
+
+# there may not be any .text sections in the .so file, in which case exit early
+echo "${OBJ_DUMP_OUTPUT}" | grep "not found in any input file" -q
+if [ "$?" -eq 0 ]; then
+ exit 0
+fi
+
+# we have symbols, so let's see if the versions are correct
+for SYM in `echo "${OBJ_DUMP_OUTPUT}" | awk '{print $(NF-1) "-" $NF}'`
+do
+ version=$(echo $SYM | cut -d'-' -f 1)
+ symbol=$(echo $SYM | cut -d'-' -f 2)
+ case $version in (*"$ABIVER"*|*"$NEXT_ABIVER"*|"EXPERIMENTAL")
+ ;;
+ (*)
+ echo "Warning: symbol $symbol ($version) should be annotated " \
+ "as ABI version $ABIVER / $NEXT_ABIVER, or EXPERIMENTAL."
+ ret=1
+ ;;
+ esac
+done
+
+exit $ret
--
2.17.1
^ permalink raw reply [relevance 23%]
* [dpdk-dev] [PATCH v3 7/9] drivers/octeontx: add missing public symbol
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (6 preceding siblings ...)
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 6/9] distributor: " Anatoly Burakov
@ 2019-10-16 17:03 3% ` Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 8/9] build: change ABI version to 20.0 Anatoly Burakov
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 9/9] buildtools: add ABI versioning check script Anatoly Burakov
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Jerin Jacob, john.mcnamara, bruce.richardson, thomas,
david.marchand, pbhagavatula, stable
The logtype symbol was missing from the .map file. Add it.
Fixes: d8dd31652cf4 ("common/octeontx: move mbox to common folder")
Cc: pbhagavatula@caviumnetworks.com
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- add this patch to avoid compile breakage when bumping ABI
drivers/common/octeontx/rte_common_octeontx_version.map | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index f04b3b7f8a..a9b3cff9bc 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,6 +1,7 @@
DPDK_18.05 {
global:
+ octeontx_logtype_mbox;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
octeontx_mbox_send;
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3 6/9] distributor: remove deprecated code
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (5 preceding siblings ...)
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 5/9] lpm: " Anatoly Burakov
@ 2019-10-16 17:03 2% ` Anatoly Burakov
2019-10-17 10:53 0% ` Hunt, David
2019-10-16 17:03 3% ` [dpdk-dev] [PATCH v3 7/9] drivers/octeontx: add missing public symbol Anatoly Burakov
` (2 subsequent siblings)
9 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, David Hunt, john.mcnamara, bruce.richardson,
thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v3:
- Removed single mode from distributor as per Dave's comments
v2:
- Moved this to before ABI version bump to avoid compile breakage
app/test/test_distributor.c | 102 ++---
app/test/test_distributor_perf.c | 12 -
lib/librte_distributor/Makefile | 1 -
lib/librte_distributor/meson.build | 2 +-
lib/librte_distributor/rte_distributor.c | 126 +-----
lib/librte_distributor/rte_distributor.h | 1 -
.../rte_distributor_private.h | 35 --
.../rte_distributor_v1705.h | 61 ---
lib/librte_distributor/rte_distributor_v20.c | 402 ------------------
lib/librte_distributor/rte_distributor_v20.h | 218 ----------
.../rte_distributor_version.map | 16 +-
11 files changed, 38 insertions(+), 938 deletions(-)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
delete mode 100644 lib/librte_distributor/rte_distributor_v20.c
delete mode 100644 lib/librte_distributor/rte_distributor_v20.h
diff --git a/app/test/test_distributor.c b/app/test/test_distributor.c
index 7090b55f88..af42f3a991 100644
--- a/app/test/test_distributor.c
+++ b/app/test/test_distributor.c
@@ -511,18 +511,9 @@ test_flush_with_worker_shutdown(struct worker_params *wp,
static
int test_error_distributor_create_name(void)
{
- struct rte_distributor *d = NULL;
struct rte_distributor *db = NULL;
char *name = NULL;
- d = rte_distributor_create(name, rte_socket_id(),
- rte_lcore_count() - 1,
- RTE_DIST_ALG_SINGLE);
- if (d != NULL || rte_errno != EINVAL) {
- printf("ERROR: No error on create() with NULL name param\n");
- return -1;
- }
-
db = rte_distributor_create(name, rte_socket_id(),
rte_lcore_count() - 1,
RTE_DIST_ALG_BURST);
@@ -538,17 +529,8 @@ int test_error_distributor_create_name(void)
static
int test_error_distributor_create_numworkers(void)
{
- struct rte_distributor *ds = NULL;
struct rte_distributor *db = NULL;
- ds = rte_distributor_create("test_numworkers", rte_socket_id(),
- RTE_MAX_LCORE + 10,
- RTE_DIST_ALG_SINGLE);
- if (ds != NULL || rte_errno != EINVAL) {
- printf("ERROR: No error on create() with num_workers > MAX\n");
- return -1;
- }
-
db = rte_distributor_create("test_numworkers", rte_socket_id(),
RTE_MAX_LCORE + 10,
RTE_DIST_ALG_BURST);
@@ -589,11 +571,8 @@ quit_workers(struct worker_params *wp, struct rte_mempool *p)
static int
test_distributor(void)
{
- static struct rte_distributor *ds;
static struct rte_distributor *db;
- static struct rte_distributor *dist[2];
static struct rte_mempool *p;
- int i;
if (rte_lcore_count() < 2) {
printf("Not enough cores for distributor_autotest, expecting at least 2\n");
@@ -613,20 +592,6 @@ test_distributor(void)
rte_distributor_clear_returns(db);
}
- if (ds == NULL) {
- ds = rte_distributor_create("Test_dist_single",
- rte_socket_id(),
- rte_lcore_count() - 1,
- RTE_DIST_ALG_SINGLE);
- if (ds == NULL) {
- printf("Error creating single distributor\n");
- return -1;
- }
- } else {
- rte_distributor_flush(ds);
- rte_distributor_clear_returns(ds);
- }
-
const unsigned nb_bufs = (511 * rte_lcore_count()) < BIG_BATCH ?
(BIG_BATCH * 2) - 1 : (511 * rte_lcore_count());
if (p == NULL) {
@@ -638,52 +603,39 @@ test_distributor(void)
}
}
- dist[0] = ds;
- dist[1] = db;
-
- for (i = 0; i < 2; i++) {
-
- worker_params.dist = dist[i];
- if (i)
- strlcpy(worker_params.name, "burst",
- sizeof(worker_params.name));
- else
- strlcpy(worker_params.name, "single",
- sizeof(worker_params.name));
-
- rte_eal_mp_remote_launch(handle_work,
- &worker_params, SKIP_MASTER);
- if (sanity_test(&worker_params, p) < 0)
+ worker_params.dist = db;
+
+ rte_eal_mp_remote_launch(handle_work,
+ &worker_params, SKIP_MASTER);
+ if (sanity_test(&worker_params, p) < 0)
+ goto err;
+ quit_workers(&worker_params, p);
+
+ rte_eal_mp_remote_launch(handle_work_with_free_mbufs,
+ &worker_params, SKIP_MASTER);
+ if (sanity_test_with_mbuf_alloc(&worker_params, p) < 0)
+ goto err;
+ quit_workers(&worker_params, p);
+
+ if (rte_lcore_count() > 2) {
+ rte_eal_mp_remote_launch(handle_work_for_shutdown_test,
+ &worker_params,
+ SKIP_MASTER);
+ if (sanity_test_with_worker_shutdown(&worker_params,
+ p) < 0)
goto err;
quit_workers(&worker_params, p);
- rte_eal_mp_remote_launch(handle_work_with_free_mbufs,
- &worker_params, SKIP_MASTER);
- if (sanity_test_with_mbuf_alloc(&worker_params, p) < 0)
+ rte_eal_mp_remote_launch(handle_work_for_shutdown_test,
+ &worker_params,
+ SKIP_MASTER);
+ if (test_flush_with_worker_shutdown(&worker_params,
+ p) < 0)
goto err;
quit_workers(&worker_params, p);
- if (rte_lcore_count() > 2) {
- rte_eal_mp_remote_launch(handle_work_for_shutdown_test,
- &worker_params,
- SKIP_MASTER);
- if (sanity_test_with_worker_shutdown(&worker_params,
- p) < 0)
- goto err;
- quit_workers(&worker_params, p);
-
- rte_eal_mp_remote_launch(handle_work_for_shutdown_test,
- &worker_params,
- SKIP_MASTER);
- if (test_flush_with_worker_shutdown(&worker_params,
- p) < 0)
- goto err;
- quit_workers(&worker_params, p);
-
- } else {
- printf("Too few cores to run worker shutdown test\n");
- }
-
+ } else {
+ printf("Too few cores to run worker shutdown test\n");
}
if (test_error_distributor_create_numworkers() == -1 ||
diff --git a/app/test/test_distributor_perf.c b/app/test/test_distributor_perf.c
index 664530ff9e..a0bbae1a16 100644
--- a/app/test/test_distributor_perf.c
+++ b/app/test/test_distributor_perf.c
@@ -215,18 +215,6 @@ test_distributor_perf(void)
/* first time how long it takes to round-trip a cache line */
time_cache_line_switch();
- if (ds == NULL) {
- ds = rte_distributor_create("Test_perf", rte_socket_id(),
- rte_lcore_count() - 1,
- RTE_DIST_ALG_SINGLE);
- if (ds == NULL) {
- printf("Error creating distributor\n");
- return -1;
- }
- } else {
- rte_distributor_clear_returns(ds);
- }
-
if (db == NULL) {
db = rte_distributor_create("Test_burst", rte_socket_id(),
rte_lcore_count() - 1,
diff --git a/lib/librte_distributor/Makefile b/lib/librte_distributor/Makefile
index 0ef80dcff4..54e9b0cc27 100644
--- a/lib/librte_distributor/Makefile
+++ b/lib/librte_distributor/Makefile
@@ -15,7 +15,6 @@ EXPORT_MAP := rte_distributor_version.map
LIBABIVER := 1
# all source are stored in SRCS-y
-SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) := rte_distributor_v20.c
SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += rte_distributor.c
ifeq ($(CONFIG_RTE_ARCH_X86),y)
SRCS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += rte_distributor_match_sse.c
diff --git a/lib/librte_distributor/meson.build b/lib/librte_distributor/meson.build
index dba7e3b2aa..d3e2aaa9e0 100644
--- a/lib/librte_distributor/meson.build
+++ b/lib/librte_distributor/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-sources = files('rte_distributor.c', 'rte_distributor_v20.c')
+sources = files('rte_distributor.c')
if arch_subdir == 'x86'
sources += files('rte_distributor_match_sse.c')
else
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index 21eb1fb0a1..d74fa468c8 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -18,8 +18,6 @@
#include "rte_distributor_private.h"
#include "rte_distributor.h"
-#include "rte_distributor_v20.h"
-#include "rte_distributor_v1705.h"
TAILQ_HEAD(rte_dist_burst_list, rte_distributor);
@@ -33,7 +31,7 @@ EAL_REGISTER_TAILQ(rte_dist_burst_tailq)
/**** Burst Packet APIs called by workers ****/
void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
+rte_distributor_request_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt,
unsigned int count)
{
@@ -42,12 +40,6 @@ rte_distributor_request_pkt_v1705(struct rte_distributor *d,
volatile int64_t *retptr64;
- if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- rte_distributor_request_pkt_v20(d->d_v20,
- worker_id, oldpkt[0]);
- return;
- }
-
retptr64 = &(buf->retptr64[0]);
/* Spin while handshake bits are set (scheduler clears it) */
while (unlikely(*retptr64 & RTE_DISTRIB_GET_BUF)) {
@@ -78,14 +70,9 @@ rte_distributor_request_pkt_v1705(struct rte_distributor *d,
*/
*retptr64 |= RTE_DISTRIB_GET_BUF;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_request_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_request_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count),
- rte_distributor_request_pkt_v1705);
int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
+rte_distributor_poll_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -93,11 +80,6 @@ rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
int count = 0;
unsigned int i;
- if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- pkts[0] = rte_distributor_poll_pkt_v20(d->d_v20, worker_id);
- return (pkts[0]) ? 1 : 0;
- }
-
/* If bit is set, return */
if (buf->bufptr64[0] & RTE_DISTRIB_GET_BUF)
return -1;
@@ -119,27 +101,14 @@ rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_poll_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_poll_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts),
- rte_distributor_poll_pkt_v1705);
int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
+rte_distributor_get_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts,
struct rte_mbuf **oldpkt, unsigned int return_count)
{
int count;
- if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- if (return_count <= 1) {
- pkts[0] = rte_distributor_get_pkt_v20(d->d_v20,
- worker_id, oldpkt[0]);
- return (pkts[0]) ? 1 : 0;
- } else
- return -EINVAL;
- }
-
rte_distributor_request_pkt(d, worker_id, oldpkt, return_count);
count = rte_distributor_poll_pkt(d, worker_id, pkts);
@@ -153,27 +122,14 @@ rte_distributor_get_pkt_v1705(struct rte_distributor *d,
}
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_get_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_get_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int return_count),
- rte_distributor_get_pkt_v1705);
int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
+rte_distributor_return_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt, int num)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
unsigned int i;
- if (unlikely(d->alg_type == RTE_DIST_ALG_SINGLE)) {
- if (num == 1)
- return rte_distributor_return_pkt_v20(d->d_v20,
- worker_id, oldpkt[0]);
- else
- return -EINVAL;
- }
-
for (i = 0; i < RTE_DIST_BURST_SIZE; i++)
/* Switch off the return bit first */
buf->retptr64[i] &= ~RTE_DISTRIB_RETURN_BUF;
@@ -187,10 +143,6 @@ rte_distributor_return_pkt_v1705(struct rte_distributor *d,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_return_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_return_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num),
- rte_distributor_return_pkt_v1705);
/**** APIs called on distributor core ***/
@@ -336,7 +288,7 @@ release(struct rte_distributor *d, unsigned int wkr)
/* process a set of packets to distribute them to workers */
int
-rte_distributor_process_v1705(struct rte_distributor *d,
+rte_distributor_process(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int num_mbufs)
{
unsigned int next_idx = 0;
@@ -347,11 +299,6 @@ rte_distributor_process_v1705(struct rte_distributor *d,
uint16_t flows[RTE_DIST_BURST_SIZE] __rte_cache_aligned;
unsigned int i, j, w, wid;
- if (d->alg_type == RTE_DIST_ALG_SINGLE) {
- /* Call the old API */
- return rte_distributor_process_v20(d->d_v20, mbufs, num_mbufs);
- }
-
if (unlikely(num_mbufs == 0)) {
/* Flush out all non-full cache-lines to workers. */
for (wid = 0 ; wid < d->num_workers; wid++) {
@@ -470,14 +417,10 @@ rte_distributor_process_v1705(struct rte_distributor *d,
return num_mbufs;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_process, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_process(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs),
- rte_distributor_process_v1705);
/* return to the caller, packets returned from workers */
int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
+rte_distributor_returned_pkts(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int max_mbufs)
{
struct rte_distributor_returned_pkts *returns = &d->returns;
@@ -485,12 +428,6 @@ rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
max_mbufs : returns->count;
unsigned int i;
- if (d->alg_type == RTE_DIST_ALG_SINGLE) {
- /* Call the old API */
- return rte_distributor_returned_pkts_v20(d->d_v20,
- mbufs, max_mbufs);
- }
-
for (i = 0; i < retval; i++) {
unsigned int idx = (returns->start + i) &
RTE_DISTRIB_RETURNS_MASK;
@@ -502,10 +439,6 @@ rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
return retval;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_returned_pkts, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_returned_pkts(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs),
- rte_distributor_returned_pkts_v1705);
/*
* Return the number of packets in-flight in a distributor, i.e. packets
@@ -527,16 +460,11 @@ total_outstanding(const struct rte_distributor *d)
* queued up.
*/
int
-rte_distributor_flush_v1705(struct rte_distributor *d)
+rte_distributor_flush(struct rte_distributor *d)
{
unsigned int flushed;
unsigned int wkr;
- if (d->alg_type == RTE_DIST_ALG_SINGLE) {
- /* Call the old API */
- return rte_distributor_flush_v20(d->d_v20);
- }
-
flushed = total_outstanding(d);
while (total_outstanding(d) > 0)
@@ -556,33 +484,21 @@ rte_distributor_flush_v1705(struct rte_distributor *d)
return flushed;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_flush, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_flush(struct rte_distributor *d),
- rte_distributor_flush_v1705);
/* clears the internal returns array in the distributor */
void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d)
+rte_distributor_clear_returns(struct rte_distributor *d)
{
unsigned int wkr;
- if (d->alg_type == RTE_DIST_ALG_SINGLE) {
- /* Call the old API */
- rte_distributor_clear_returns_v20(d->d_v20);
- return;
- }
-
/* throw away returns, so workers can exit */
for (wkr = 0; wkr < d->num_workers; wkr++)
d->bufs[wkr].retptr64[0] = 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_clear_returns, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_clear_returns(struct rte_distributor *d),
- rte_distributor_clear_returns_v1705);
/* creates a distributor instance */
struct rte_distributor *
-rte_distributor_create_v1705(const char *name,
+rte_distributor_create(const char *name,
unsigned int socket_id,
unsigned int num_workers,
unsigned int alg_type)
@@ -593,8 +509,6 @@ rte_distributor_create_v1705(const char *name,
const struct rte_memzone *mz;
unsigned int i;
- /* TODO Reorganise function properly around RTE_DIST_ALG_SINGLE/BURST */
-
/* compilation-time checks */
RTE_BUILD_BUG_ON((sizeof(*d) & RTE_CACHE_LINE_MASK) != 0);
RTE_BUILD_BUG_ON((RTE_DISTRIB_MAX_WORKERS & 7) != 0);
@@ -605,23 +519,6 @@ rte_distributor_create_v1705(const char *name,
return NULL;
}
- if (alg_type == RTE_DIST_ALG_SINGLE) {
- d = malloc(sizeof(struct rte_distributor));
- if (d == NULL) {
- rte_errno = ENOMEM;
- return NULL;
- }
- d->d_v20 = rte_distributor_create_v20(name,
- socket_id, num_workers);
- if (d->d_v20 == NULL) {
- free(d);
- /* rte_errno will have been set */
- return NULL;
- }
- d->alg_type = alg_type;
- return d;
- }
-
snprintf(mz_name, sizeof(mz_name), RTE_DISTRIB_PREFIX"%s", name);
mz = rte_memzone_reserve(mz_name, sizeof(*d), socket_id, NO_FLAGS);
if (mz == NULL) {
@@ -656,8 +553,3 @@ rte_distributor_create_v1705(const char *name,
return d;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_create, _v1705, 17.05);
-MAP_STATIC_SYMBOL(struct rte_distributor *rte_distributor_create(
- const char *name, unsigned int socket_id,
- unsigned int num_workers, unsigned int alg_type),
- rte_distributor_create_v1705);
diff --git a/lib/librte_distributor/rte_distributor.h b/lib/librte_distributor/rte_distributor.h
index 327c0c4ab2..41c06093ee 100644
--- a/lib/librte_distributor/rte_distributor.h
+++ b/lib/librte_distributor/rte_distributor.h
@@ -20,7 +20,6 @@ extern "C" {
/* Type of distribution (burst/single) */
enum rte_distributor_alg_type {
RTE_DIST_ALG_BURST = 0,
- RTE_DIST_ALG_SINGLE,
RTE_DIST_NUM_ALG_TYPES
};
diff --git a/lib/librte_distributor/rte_distributor_private.h b/lib/librte_distributor/rte_distributor_private.h
index 33cd89410c..552eecc88f 100644
--- a/lib/librte_distributor/rte_distributor_private.h
+++ b/lib/librte_distributor/rte_distributor_private.h
@@ -48,18 +48,6 @@ extern "C" {
#define RTE_DISTRIBUTOR_NAMESIZE 32 /**< Length of name for instance */
-/**
- * Buffer structure used to pass the pointer data between cores. This is cache
- * line aligned, but to improve performance and prevent adjacent cache-line
- * prefetches of buffers for other workers, e.g. when worker 1's buffer is on
- * the next cache line to worker 0, we pad this out to three cache lines.
- * Only 64-bits of the memory is actually used though.
- */
-union rte_distributor_buffer_v20 {
- volatile int64_t bufptr64;
- char pad[RTE_CACHE_LINE_SIZE*3];
-} __rte_cache_aligned;
-
/*
* Transfer up to 8 mbufs at a time to/from workers, and
* flow matching algorithm optimized for 8 flow IDs at a time
@@ -80,27 +68,6 @@ struct rte_distributor_returned_pkts {
struct rte_mbuf *mbufs[RTE_DISTRIB_MAX_RETURNS];
};
-struct rte_distributor_v20 {
- TAILQ_ENTRY(rte_distributor_v20) next; /**< Next in list. */
-
- char name[RTE_DISTRIBUTOR_NAMESIZE]; /**< Name of the ring. */
- unsigned int num_workers; /**< Number of workers polling */
-
- uint32_t in_flight_tags[RTE_DISTRIB_MAX_WORKERS];
- /**< Tracks the tag being processed per core */
- uint64_t in_flight_bitmask;
- /**< on/off bits for in-flight tags.
- * Note that if RTE_DISTRIB_MAX_WORKERS is larger than 64 then
- * the bitmask has to expand.
- */
-
- struct rte_distributor_backlog backlog[RTE_DISTRIB_MAX_WORKERS];
-
- union rte_distributor_buffer_v20 bufs[RTE_DISTRIB_MAX_WORKERS];
-
- struct rte_distributor_returned_pkts returns;
-};
-
/* All different signature compare functions */
enum rte_distributor_match_function {
RTE_DIST_MATCH_SCALAR = 0,
@@ -153,8 +120,6 @@ struct rte_distributor {
struct rte_distributor_returned_pkts returns;
enum rte_distributor_match_function dist_match_fn;
-
- struct rte_distributor_v20 *d_v20;
};
void
diff --git a/lib/librte_distributor/rte_distributor_v1705.h b/lib/librte_distributor/rte_distributor_v1705.h
deleted file mode 100644
index df4d9e8150..0000000000
--- a/lib/librte_distributor/rte_distributor_v1705.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017 Intel Corporation
- */
-
-#ifndef _RTE_DISTRIB_V1705_H_
-#define _RTE_DISTRIB_V1705_H_
-
-/**
- * @file
- * RTE distributor
- *
- * The distributor is a component which is designed to pass packets
- * one-at-a-time to workers, with dynamic load balancing.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_distributor *
-rte_distributor_create_v1705(const char *name, unsigned int socket_id,
- unsigned int num_workers,
- unsigned int alg_type);
-
-int
-rte_distributor_process_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs);
-
-int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs);
-
-int
-rte_distributor_flush_v1705(struct rte_distributor *d);
-
-void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d);
-
-int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int retcount);
-
-int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
-
-void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count);
-
-int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **mbufs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_distributor/rte_distributor_v20.c b/lib/librte_distributor/rte_distributor_v20.c
deleted file mode 100644
index cdc0969a89..0000000000
--- a/lib/librte_distributor/rte_distributor_v20.c
+++ /dev/null
@@ -1,402 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#include <stdio.h>
-#include <sys/queue.h>
-#include <string.h>
-#include <rte_mbuf.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_errno.h>
-#include <rte_compat.h>
-#include <rte_string_fns.h>
-#include <rte_eal_memconfig.h>
-#include <rte_pause.h>
-#include <rte_tailq.h>
-
-#include "rte_distributor_v20.h"
-#include "rte_distributor_private.h"
-
-TAILQ_HEAD(rte_distributor_list, rte_distributor_v20);
-
-static struct rte_tailq_elem rte_distributor_tailq = {
- .name = "RTE_DISTRIBUTOR",
-};
-EAL_REGISTER_TAILQ(rte_distributor_tailq)
-
-/**** APIs called by workers ****/
-
-void
-rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d,
- unsigned worker_id, struct rte_mbuf *oldpkt)
-{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
- int64_t req = (((int64_t)(uintptr_t)oldpkt) << RTE_DISTRIB_FLAG_BITS)
- | RTE_DISTRIB_GET_BUF;
- while (unlikely(buf->bufptr64 & RTE_DISTRIB_FLAGS_MASK))
- rte_pause();
- buf->bufptr64 = req;
-}
-VERSION_SYMBOL(rte_distributor_request_pkt, _v20, 2.0);
-
-struct rte_mbuf *
-rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d,
- unsigned worker_id)
-{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
- if (buf->bufptr64 & RTE_DISTRIB_GET_BUF)
- return NULL;
-
- /* since bufptr64 is signed, this should be an arithmetic shift */
- int64_t ret = buf->bufptr64 >> RTE_DISTRIB_FLAG_BITS;
- return (struct rte_mbuf *)((uintptr_t)ret);
-}
-VERSION_SYMBOL(rte_distributor_poll_pkt, _v20, 2.0);
-
-struct rte_mbuf *
-rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d,
- unsigned worker_id, struct rte_mbuf *oldpkt)
-{
- struct rte_mbuf *ret;
- rte_distributor_request_pkt_v20(d, worker_id, oldpkt);
- while ((ret = rte_distributor_poll_pkt_v20(d, worker_id)) == NULL)
- rte_pause();
- return ret;
-}
-VERSION_SYMBOL(rte_distributor_get_pkt, _v20, 2.0);
-
-int
-rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d,
- unsigned worker_id, struct rte_mbuf *oldpkt)
-{
- union rte_distributor_buffer_v20 *buf = &d->bufs[worker_id];
- uint64_t req = (((int64_t)(uintptr_t)oldpkt) << RTE_DISTRIB_FLAG_BITS)
- | RTE_DISTRIB_RETURN_BUF;
- buf->bufptr64 = req;
- return 0;
-}
-VERSION_SYMBOL(rte_distributor_return_pkt, _v20, 2.0);
-
-/**** APIs called on distributor core ***/
-
-/* as name suggests, adds a packet to the backlog for a particular worker */
-static int
-add_to_backlog(struct rte_distributor_backlog *bl, int64_t item)
-{
- if (bl->count == RTE_DISTRIB_BACKLOG_SIZE)
- return -1;
-
- bl->pkts[(bl->start + bl->count++) & (RTE_DISTRIB_BACKLOG_MASK)]
- = item;
- return 0;
-}
-
-/* takes the next packet for a worker off the backlog */
-static int64_t
-backlog_pop(struct rte_distributor_backlog *bl)
-{
- bl->count--;
- return bl->pkts[bl->start++ & RTE_DISTRIB_BACKLOG_MASK];
-}
-
-/* stores a packet returned from a worker inside the returns array */
-static inline void
-store_return(uintptr_t oldbuf, struct rte_distributor_v20 *d,
- unsigned *ret_start, unsigned *ret_count)
-{
- /* store returns in a circular buffer - code is branch-free */
- d->returns.mbufs[(*ret_start + *ret_count) & RTE_DISTRIB_RETURNS_MASK]
- = (void *)oldbuf;
- *ret_start += (*ret_count == RTE_DISTRIB_RETURNS_MASK) & !!(oldbuf);
- *ret_count += (*ret_count != RTE_DISTRIB_RETURNS_MASK) & !!(oldbuf);
-}
-
-static inline void
-handle_worker_shutdown(struct rte_distributor_v20 *d, unsigned int wkr)
-{
- d->in_flight_tags[wkr] = 0;
- d->in_flight_bitmask &= ~(1UL << wkr);
- d->bufs[wkr].bufptr64 = 0;
- if (unlikely(d->backlog[wkr].count != 0)) {
- /* On return of a packet, we need to move the
- * queued packets for this core elsewhere.
- * Easiest solution is to set things up for
- * a recursive call. That will cause those
- * packets to be queued up for the next free
- * core, i.e. it will return as soon as a
- * core becomes free to accept the first
- * packet, as subsequent ones will be added to
- * the backlog for that core.
- */
- struct rte_mbuf *pkts[RTE_DISTRIB_BACKLOG_SIZE];
- unsigned i;
- struct rte_distributor_backlog *bl = &d->backlog[wkr];
-
- for (i = 0; i < bl->count; i++) {
- unsigned idx = (bl->start + i) &
- RTE_DISTRIB_BACKLOG_MASK;
- pkts[i] = (void *)((uintptr_t)(bl->pkts[idx] >>
- RTE_DISTRIB_FLAG_BITS));
- }
- /* recursive call.
- * Note that the tags were set before first level call
- * to rte_distributor_process.
- */
- rte_distributor_process_v20(d, pkts, i);
- bl->count = bl->start = 0;
- }
-}
-
-/* this function is called when process() fn is called without any new
- * packets. It goes through all the workers and clears any returned packets
- * to do a partial flush.
- */
-static int
-process_returns(struct rte_distributor_v20 *d)
-{
- unsigned wkr;
- unsigned flushed = 0;
- unsigned ret_start = d->returns.start,
- ret_count = d->returns.count;
-
- for (wkr = 0; wkr < d->num_workers; wkr++) {
-
- const int64_t data = d->bufs[wkr].bufptr64;
- uintptr_t oldbuf = 0;
-
- if (data & RTE_DISTRIB_GET_BUF) {
- flushed++;
- if (d->backlog[wkr].count)
- d->bufs[wkr].bufptr64 =
- backlog_pop(&d->backlog[wkr]);
- else {
- d->bufs[wkr].bufptr64 = RTE_DISTRIB_GET_BUF;
- d->in_flight_tags[wkr] = 0;
- d->in_flight_bitmask &= ~(1UL << wkr);
- }
- oldbuf = data >> RTE_DISTRIB_FLAG_BITS;
- } else if (data & RTE_DISTRIB_RETURN_BUF) {
- handle_worker_shutdown(d, wkr);
- oldbuf = data >> RTE_DISTRIB_FLAG_BITS;
- }
-
- store_return(oldbuf, d, &ret_start, &ret_count);
- }
-
- d->returns.start = ret_start;
- d->returns.count = ret_count;
-
- return flushed;
-}
-
-/* process a set of packets to distribute them to workers */
-int
-rte_distributor_process_v20(struct rte_distributor_v20 *d,
- struct rte_mbuf **mbufs, unsigned num_mbufs)
-{
- unsigned next_idx = 0;
- unsigned wkr = 0;
- struct rte_mbuf *next_mb = NULL;
- int64_t next_value = 0;
- uint32_t new_tag = 0;
- unsigned ret_start = d->returns.start,
- ret_count = d->returns.count;
-
- if (unlikely(num_mbufs == 0))
- return process_returns(d);
-
- while (next_idx < num_mbufs || next_mb != NULL) {
-
- int64_t data = d->bufs[wkr].bufptr64;
- uintptr_t oldbuf = 0;
-
- if (!next_mb) {
- next_mb = mbufs[next_idx++];
- next_value = (((int64_t)(uintptr_t)next_mb)
- << RTE_DISTRIB_FLAG_BITS);
- /*
- * User is advocated to set tag value for each
- * mbuf before calling rte_distributor_process.
- * User defined tags are used to identify flows,
- * or sessions.
- */
- new_tag = next_mb->hash.usr;
-
- /*
- * Note that if RTE_DISTRIB_MAX_WORKERS is larger than 64
- * then the size of match has to be expanded.
- */
- uint64_t match = 0;
- unsigned i;
- /*
- * to scan for a match use "xor" and "not" to get a 0/1
- * value, then use shifting to merge to single "match"
- * variable, where a one-bit indicates a match for the
- * worker given by the bit-position
- */
- for (i = 0; i < d->num_workers; i++)
- match |= (!(d->in_flight_tags[i] ^ new_tag)
- << i);
-
- /* Only turned-on bits are considered as match */
- match &= d->in_flight_bitmask;
-
- if (match) {
- next_mb = NULL;
- unsigned worker = __builtin_ctzl(match);
- if (add_to_backlog(&d->backlog[worker],
- next_value) < 0)
- next_idx--;
- }
- }
-
- if ((data & RTE_DISTRIB_GET_BUF) &&
- (d->backlog[wkr].count || next_mb)) {
-
- if (d->backlog[wkr].count)
- d->bufs[wkr].bufptr64 =
- backlog_pop(&d->backlog[wkr]);
-
- else {
- d->bufs[wkr].bufptr64 = next_value;
- d->in_flight_tags[wkr] = new_tag;
- d->in_flight_bitmask |= (1UL << wkr);
- next_mb = NULL;
- }
- oldbuf = data >> RTE_DISTRIB_FLAG_BITS;
- } else if (data & RTE_DISTRIB_RETURN_BUF) {
- handle_worker_shutdown(d, wkr);
- oldbuf = data >> RTE_DISTRIB_FLAG_BITS;
- }
-
- /* store returns in a circular buffer */
- store_return(oldbuf, d, &ret_start, &ret_count);
-
- if (++wkr == d->num_workers)
- wkr = 0;
- }
- /* to finish, check all workers for backlog and schedule work for them
- * if they are ready */
- for (wkr = 0; wkr < d->num_workers; wkr++)
- if (d->backlog[wkr].count &&
- (d->bufs[wkr].bufptr64 & RTE_DISTRIB_GET_BUF)) {
-
- int64_t oldbuf = d->bufs[wkr].bufptr64 >>
- RTE_DISTRIB_FLAG_BITS;
- store_return(oldbuf, d, &ret_start, &ret_count);
-
- d->bufs[wkr].bufptr64 = backlog_pop(&d->backlog[wkr]);
- }
-
- d->returns.start = ret_start;
- d->returns.count = ret_count;
- return num_mbufs;
-}
-VERSION_SYMBOL(rte_distributor_process, _v20, 2.0);
-
-/* return to the caller, packets returned from workers */
-int
-rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
- struct rte_mbuf **mbufs, unsigned max_mbufs)
-{
- struct rte_distributor_returned_pkts *returns = &d->returns;
- unsigned retval = (max_mbufs < returns->count) ?
- max_mbufs : returns->count;
- unsigned i;
-
- for (i = 0; i < retval; i++) {
- unsigned idx = (returns->start + i) & RTE_DISTRIB_RETURNS_MASK;
- mbufs[i] = returns->mbufs[idx];
- }
- returns->start += i;
- returns->count -= i;
-
- return retval;
-}
-VERSION_SYMBOL(rte_distributor_returned_pkts, _v20, 2.0);
-
-/* return the number of packets in-flight in a distributor, i.e. packets
- * being worked on or queued up in a backlog.
- */
-static inline unsigned
-total_outstanding(const struct rte_distributor_v20 *d)
-{
- unsigned wkr, total_outstanding;
-
- total_outstanding = __builtin_popcountl(d->in_flight_bitmask);
-
- for (wkr = 0; wkr < d->num_workers; wkr++)
- total_outstanding += d->backlog[wkr].count;
-
- return total_outstanding;
-}
-
-/* flush the distributor, so that there are no outstanding packets in flight or
- * queued up. */
-int
-rte_distributor_flush_v20(struct rte_distributor_v20 *d)
-{
- const unsigned flushed = total_outstanding(d);
-
- while (total_outstanding(d) > 0)
- rte_distributor_process_v20(d, NULL, 0);
-
- return flushed;
-}
-VERSION_SYMBOL(rte_distributor_flush, _v20, 2.0);
-
-/* clears the internal returns array in the distributor */
-void
-rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d)
-{
- d->returns.start = d->returns.count = 0;
-#ifndef __OPTIMIZE__
- memset(d->returns.mbufs, 0, sizeof(d->returns.mbufs));
-#endif
-}
-VERSION_SYMBOL(rte_distributor_clear_returns, _v20, 2.0);
-
-/* creates a distributor instance */
-struct rte_distributor_v20 *
-rte_distributor_create_v20(const char *name,
- unsigned socket_id,
- unsigned num_workers)
-{
- struct rte_distributor_v20 *d;
- struct rte_distributor_list *distributor_list;
- char mz_name[RTE_MEMZONE_NAMESIZE];
- const struct rte_memzone *mz;
-
- /* compilation-time checks */
- RTE_BUILD_BUG_ON((sizeof(*d) & RTE_CACHE_LINE_MASK) != 0);
- RTE_BUILD_BUG_ON((RTE_DISTRIB_MAX_WORKERS & 7) != 0);
- RTE_BUILD_BUG_ON(RTE_DISTRIB_MAX_WORKERS >
- sizeof(d->in_flight_bitmask) * CHAR_BIT);
-
- if (name == NULL || num_workers >= RTE_DISTRIB_MAX_WORKERS) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- snprintf(mz_name, sizeof(mz_name), RTE_DISTRIB_PREFIX"%s", name);
- mz = rte_memzone_reserve(mz_name, sizeof(*d), socket_id, NO_FLAGS);
- if (mz == NULL) {
- rte_errno = ENOMEM;
- return NULL;
- }
-
- d = mz->addr;
- strlcpy(d->name, name, sizeof(d->name));
- d->num_workers = num_workers;
-
- distributor_list = RTE_TAILQ_CAST(rte_distributor_tailq.head,
- rte_distributor_list);
-
- rte_mcfg_tailq_write_lock();
- TAILQ_INSERT_TAIL(distributor_list, d, next);
- rte_mcfg_tailq_write_unlock();
-
- return d;
-}
-VERSION_SYMBOL(rte_distributor_create, _v20, 2.0);
diff --git a/lib/librte_distributor/rte_distributor_v20.h b/lib/librte_distributor/rte_distributor_v20.h
deleted file mode 100644
index 12865658ba..0000000000
--- a/lib/librte_distributor/rte_distributor_v20.h
+++ /dev/null
@@ -1,218 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2014 Intel Corporation
- */
-
-#ifndef _RTE_DISTRIB_V20_H_
-#define _RTE_DISTRIB_V20_H_
-
-/**
- * @file
- * RTE distributor
- *
- * The distributor is a component which is designed to pass packets
- * one-at-a-time to workers, with dynamic load balancing.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define RTE_DISTRIBUTOR_NAMESIZE 32 /**< Length of name for instance */
-
-struct rte_distributor_v20;
-struct rte_mbuf;
-
-/**
- * Function to create a new distributor instance
- *
- * Reserves the memory needed for the distributor operation and
- * initializes the distributor to work with the configured number of workers.
- *
- * @param name
- * The name to be given to the distributor instance.
- * @param socket_id
- * The NUMA node on which the memory is to be allocated
- * @param num_workers
- * The maximum number of workers that will request packets from this
- * distributor
- * @return
- * The newly created distributor instance
- */
-struct rte_distributor_v20 *
-rte_distributor_create_v20(const char *name, unsigned int socket_id,
- unsigned int num_workers);
-
-/* *** APIS to be called on the distributor lcore *** */
-/*
- * The following APIs are the public APIs which are designed for use on a
- * single lcore which acts as the distributor lcore for a given distributor
- * instance. These functions cannot be called on multiple cores simultaneously
- * without using locking to protect access to the internals of the distributor.
- *
- * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
- * for the same distributor instance, otherwise deadlock will result.
- */
-
-/**
- * Process a set of packets by distributing them among workers that request
- * packets. The distributor will ensure that no two packets that have the
- * same flow id, or tag, in the mbuf will be processed at the same time.
- *
- * The user is advocated to set tag for each mbuf before calling this function.
- * If user doesn't set the tag, the tag value can be various values depending on
- * driver implementation and configuration.
- *
- * This is not multi-thread safe and should only be called on a single lcore.
- *
- * @param d
- * The distributor instance to be used
- * @param mbufs
- * The mbufs to be distributed
- * @param num_mbufs
- * The number of mbufs in the mbufs array
- * @return
- * The number of mbufs processed.
- */
-int
-rte_distributor_process_v20(struct rte_distributor_v20 *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs);
-
-/**
- * Get a set of mbufs that have been returned to the distributor by workers
- *
- * This should only be called on the same lcore as rte_distributor_process()
- *
- * @param d
- * The distributor instance to be used
- * @param mbufs
- * The mbufs pointer array to be filled in
- * @param max_mbufs
- * The size of the mbufs array
- * @return
- * The number of mbufs returned in the mbufs array.
- */
-int
-rte_distributor_returned_pkts_v20(struct rte_distributor_v20 *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs);
-
-/**
- * Flush the distributor component, so that there are no in-flight or
- * backlogged packets awaiting processing
- *
- * This should only be called on the same lcore as rte_distributor_process()
- *
- * @param d
- * The distributor instance to be used
- * @return
- * The number of queued/in-flight packets that were completed by this call.
- */
-int
-rte_distributor_flush_v20(struct rte_distributor_v20 *d);
-
-/**
- * Clears the array of returned packets used as the source for the
- * rte_distributor_returned_pkts() API call.
- *
- * This should only be called on the same lcore as rte_distributor_process()
- *
- * @param d
- * The distributor instance to be used
- */
-void
-rte_distributor_clear_returns_v20(struct rte_distributor_v20 *d);
-
-/* *** APIS to be called on the worker lcores *** */
-/*
- * The following APIs are the public APIs which are designed for use on
- * multiple lcores which act as workers for a distributor. Each lcore should use
- * a unique worker id when requesting packets.
- *
- * NOTE: a given lcore cannot act as both a distributor lcore and a worker lcore
- * for the same distributor instance, otherwise deadlock will result.
- */
-
-/**
- * API called by a worker to get a new packet to process. Any previous packet
- * given to the worker is assumed to have completed processing, and may be
- * optionally returned to the distributor via the oldpkt parameter.
- *
- * @param d
- * The distributor instance to be used
- * @param worker_id
- * The worker instance number to use - must be less that num_workers passed
- * at distributor creation time.
- * @param oldpkt
- * The previous packet, if any, being processed by the worker
- *
- * @return
- * A new packet to be processed by the worker thread.
- */
-struct rte_mbuf *
-rte_distributor_get_pkt_v20(struct rte_distributor_v20 *d,
- unsigned int worker_id, struct rte_mbuf *oldpkt);
-
-/**
- * API called by a worker to return a completed packet without requesting a
- * new packet, for example, because a worker thread is shutting down
- *
- * @param d
- * The distributor instance to be used
- * @param worker_id
- * The worker instance number to use - must be less that num_workers passed
- * at distributor creation time.
- * @param mbuf
- * The previous packet being processed by the worker
- */
-int
-rte_distributor_return_pkt_v20(struct rte_distributor_v20 *d,
- unsigned int worker_id, struct rte_mbuf *mbuf);
-
-/**
- * API called by a worker to request a new packet to process.
- * Any previous packet given to the worker is assumed to have completed
- * processing, and may be optionally returned to the distributor via
- * the oldpkt parameter.
- * Unlike rte_distributor_get_pkt(), this function does not wait for a new
- * packet to be provided by the distributor.
- *
- * NOTE: after calling this function, rte_distributor_poll_pkt() should
- * be used to poll for the packet requested. The rte_distributor_get_pkt()
- * API should *not* be used to try and retrieve the new packet.
- *
- * @param d
- * The distributor instance to be used
- * @param worker_id
- * The worker instance number to use - must be less that num_workers passed
- * at distributor creation time.
- * @param oldpkt
- * The previous packet, if any, being processed by the worker
- */
-void
-rte_distributor_request_pkt_v20(struct rte_distributor_v20 *d,
- unsigned int worker_id, struct rte_mbuf *oldpkt);
-
-/**
- * API called by a worker to check for a new packet that was previously
- * requested by a call to rte_distributor_request_pkt(). It does not wait
- * for the new packet to be available, but returns NULL if the request has
- * not yet been fulfilled by the distributor.
- *
- * @param d
- * The distributor instance to be used
- * @param worker_id
- * The worker instance number to use - must be less that num_workers passed
- * at distributor creation time.
- *
- * @return
- * A new packet to be processed by the worker thread, or NULL if no
- * packet is yet available.
- */
-struct rte_mbuf *
-rte_distributor_poll_pkt_v20(struct rte_distributor_v20 *d,
- unsigned int worker_id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_distributor/rte_distributor_version.map b/lib/librte_distributor/rte_distributor_version.map
index 3a285b394e..5643ab85fb 100644
--- a/lib/librte_distributor/rte_distributor_version.map
+++ b/lib/librte_distributor/rte_distributor_version.map
@@ -1,4 +1,4 @@
-DPDK_2.0 {
+DPDK_17.05 {
global:
rte_distributor_clear_returns;
@@ -13,17 +13,3 @@ DPDK_2.0 {
local: *;
};
-
-DPDK_17.05 {
- global:
-
- rte_distributor_clear_returns;
- rte_distributor_create;
- rte_distributor_flush;
- rte_distributor_get_pkt;
- rte_distributor_poll_pkt;
- rte_distributor_process;
- rte_distributor_request_pkt;
- rte_distributor_return_pkt;
- rte_distributor_returned_pkts;
-} DPDK_2.0;
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v3 5/9] lpm: remove deprecated code
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (4 preceding siblings ...)
2019-10-16 17:03 4% ` [dpdk-dev] [PATCH v3 4/9] timer: remove deprecated code Anatoly Burakov
@ 2019-10-16 17:03 2% ` Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 6/9] distributor: " Anatoly Burakov
` (3 subsequent siblings)
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Bruce Richardson, Vladimir Medvedkin,
john.mcnamara, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_lpm/rte_lpm.c | 996 ++------------------------------------
lib/librte_lpm/rte_lpm.h | 88 ----
lib/librte_lpm/rte_lpm6.c | 132 +----
lib/librte_lpm/rte_lpm6.h | 25 -
4 files changed, 48 insertions(+), 1193 deletions(-)
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 3a929a1b16..2687564194 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -89,34 +89,8 @@ depth_to_range(uint8_t depth)
/*
* Find an existing lpm table and return a pointer to it.
*/
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name)
-{
- struct rte_lpm_v20 *l = NULL;
- struct rte_tailq_entry *te;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_read_lock();
- TAILQ_FOREACH(te, lpm_list, next) {
- l = te->data;
- if (strncmp(name, l->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
- rte_mcfg_tailq_read_unlock();
-
- if (te == NULL) {
- rte_errno = ENOENT;
- return NULL;
- }
-
- return l;
-}
-VERSION_SYMBOL(rte_lpm_find_existing, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name)
+rte_lpm_find_existing(const char *name)
{
struct rte_lpm *l = NULL;
struct rte_tailq_entry *te;
@@ -139,88 +113,12 @@ rte_lpm_find_existing_v1604(const char *name)
return l;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_find_existing, _v1604, 16.04);
-MAP_STATIC_SYMBOL(struct rte_lpm *rte_lpm_find_existing(const char *name),
- rte_lpm_find_existing_v1604);
/*
* Allocates memory for LPM object
*/
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
-{
- char mem_name[RTE_LPM_NAMESIZE];
- struct rte_lpm_v20 *lpm = NULL;
- struct rte_tailq_entry *te;
- uint32_t mem_size;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry_v20) != 2);
-
- /* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
-
- /* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
-
- rte_mcfg_tailq_write_lock();
-
- /* guarantee there's no existing */
- TAILQ_FOREACH(te, lpm_list, next) {
- lpm = te->data;
- if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
-
- if (te != NULL) {
- lpm = NULL;
- rte_errno = EEXIST;
- goto exit;
- }
-
- /* allocate tailq entry */
- te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0);
- if (te == NULL) {
- RTE_LOG(ERR, LPM, "Failed to allocate tailq entry\n");
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Allocate memory to store the LPM data structures. */
- lpm = rte_zmalloc_socket(mem_name, mem_size,
- RTE_CACHE_LINE_SIZE, socket_id);
- if (lpm == NULL) {
- RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
- rte_free(te);
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Save user arguments. */
- lpm->max_rules = max_rules;
- strlcpy(lpm->name, name, sizeof(lpm->name));
-
- te->data = lpm;
-
- TAILQ_INSERT_TAIL(lpm_list, te, next);
-
-exit:
- rte_mcfg_tailq_write_unlock();
-
- return lpm;
-}
-VERSION_SYMBOL(rte_lpm_create, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
+rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
@@ -320,45 +218,12 @@ rte_lpm_create_v1604(const char *name, int socket_id,
return lpm;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 16.04);
-MAP_STATIC_SYMBOL(
- struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
*/
void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm)
-{
- struct rte_lpm_list *lpm_list;
- struct rte_tailq_entry *te;
-
- /* Check user arguments. */
- if (lpm == NULL)
- return;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_write_lock();
-
- /* find our tailq entry */
- TAILQ_FOREACH(te, lpm_list, next) {
- if (te->data == (void *) lpm)
- break;
- }
- if (te != NULL)
- TAILQ_REMOVE(lpm_list, te, next);
-
- rte_mcfg_tailq_write_unlock();
-
- rte_free(lpm);
- rte_free(te);
-}
-VERSION_SYMBOL(rte_lpm_free, _v20, 2.0);
-
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm)
+rte_lpm_free(struct rte_lpm *lpm)
{
struct rte_lpm_list *lpm_list;
struct rte_tailq_entry *te;
@@ -386,9 +251,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
rte_free(lpm);
rte_free(te);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
- rte_lpm_free_v1604);
/*
* Adds a rule to the rule table.
@@ -401,79 +263,7 @@ MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t rule_gindex, rule_index, last_rule;
- int i;
-
- VERIFY_DEPTH(depth);
-
- /* Scan through rule group to see if rule already exists. */
- if (lpm->rule_info[depth - 1].used_rules > 0) {
-
- /* rule_gindex stands for rule group index. */
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- /* Initialise rule_index to point to start of rule group. */
- rule_index = rule_gindex;
- /* Last rule = Last used rule in this rule group. */
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- for (; rule_index < last_rule; rule_index++) {
-
- /* If rule already exists update its next_hop and return. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked) {
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- return rule_index;
- }
- }
-
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
- } else {
- /* Calculate the position in which the rule will be stored. */
- rule_index = 0;
-
- for (i = depth - 1; i > 0; i--) {
- if (lpm->rule_info[i - 1].used_rules > 0) {
- rule_index = lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules;
- break;
- }
- }
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
-
- lpm->rule_info[depth - 1].first_rule = rule_index;
- }
-
- /* Make room for the new rule in the array. */
- for (i = RTE_LPM_MAX_DEPTH; i > depth; i--) {
- if (lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules == lpm->max_rules)
- return -ENOSPC;
-
- if (lpm->rule_info[i - 1].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules]
- = lpm->rules_tbl[lpm->rule_info[i - 1].first_rule];
- lpm->rule_info[i - 1].first_rule++;
- }
- }
-
- /* Add the new rule. */
- lpm->rules_tbl[rule_index].ip = ip_masked;
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- /* Increment the used rules counter for this rule group. */
- lpm->rule_info[depth - 1].used_rules++;
-
- return rule_index;
-}
-
-static int32_t
-rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+rule_add(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
uint32_t rule_gindex, rule_index, last_rule;
@@ -549,30 +339,7 @@ rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static void
-rule_delete_v20(struct rte_lpm_v20 *lpm, int32_t rule_index, uint8_t depth)
-{
- int i;
-
- VERIFY_DEPTH(depth);
-
- lpm->rules_tbl[rule_index] =
- lpm->rules_tbl[lpm->rule_info[depth - 1].first_rule
- + lpm->rule_info[depth - 1].used_rules - 1];
-
- for (i = depth; i < RTE_LPM_MAX_DEPTH; i++) {
- if (lpm->rule_info[i].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i].first_rule - 1] =
- lpm->rules_tbl[lpm->rule_info[i].first_rule
- + lpm->rule_info[i].used_rules - 1];
- lpm->rule_info[i].first_rule--;
- }
- }
-
- lpm->rule_info[depth - 1].used_rules--;
-}
-
-static void
-rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
+rule_delete(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
{
int i;
@@ -599,28 +366,7 @@ rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_find_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth)
-{
- uint32_t rule_gindex, last_rule, rule_index;
-
- VERIFY_DEPTH(depth);
-
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- /* Scan used rules at given depth to find rule. */
- for (rule_index = rule_gindex; rule_index < last_rule; rule_index++) {
- /* If rule is found return the rule index. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked)
- return rule_index;
- }
-
- /* If rule is not found return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
+rule_find(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
{
uint32_t rule_gindex, last_rule, rule_index;
@@ -644,42 +390,7 @@ rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
* Find, clean and allocate a tbl8.
*/
static int32_t
-tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
-{
- uint32_t group_idx; /* tbl8 group index. */
- struct rte_lpm_tbl_entry_v20 *tbl8_entry;
-
- /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
- tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
- /* If a free tbl8 group is found clean it and set as VALID. */
- if (!tbl8_entry->valid_group) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = VALID,
- };
- new_tbl8_entry.next_hop = 0;
-
- memset(&tbl8_entry[0], 0,
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES *
- sizeof(tbl8_entry[0]));
-
- __atomic_store(tbl8_entry, &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- /* Return group index for allocated tbl8 group. */
- return group_idx;
- }
- }
-
- /* If there are no tbl8 groups free then return error. */
- return -ENOSPC;
-}
-
-static int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
+tbl8_alloc(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
@@ -713,22 +424,7 @@ tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
}
static void
-tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start)
-{
- /* Set tbl8 group invalid*/
- struct rte_lpm_tbl_entry_v20 zero_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = INVALID,
- };
- zero_tbl8_entry.next_hop = 0;
-
- __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
- __ATOMIC_RELAXED);
-}
-
-static void
-tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
+tbl8_free(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
{
/* Set tbl8 group invalid*/
struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
@@ -738,78 +434,7 @@ tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
}
static __rte_noinline int32_t
-add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index, tbl24_range, tbl8_index, tbl8_group_end, i, j;
-
- /* Calculate the index into Table24. */
- tbl24_index = ip >> 8;
- tbl24_range = depth_to_range(depth);
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
- /*
- * For invalid OR valid and non-extended tbl 24 entries set
- * entry.
- */
- if (!lpm->tbl24[i].valid || (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth)) {
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .valid = VALID,
- .valid_group = 0,
- .depth = depth,
- };
- new_tbl24_entry.next_hop = next_hop;
-
- /* Setting tbl24 entry in one go to avoid race
- * conditions
- */
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- continue;
- }
-
- if (lpm->tbl24[i].valid_group == 1) {
- /* If tbl24 entry is valid and extended calculate the
- * index into tbl8.
- */
- tbl8_index = lpm->tbl24[i].group_idx *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < tbl8_group_end; j++) {
- if (!lpm->tbl8[j].valid ||
- lpm->tbl8[j].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = depth,
- };
- new_tbl8_entry.next_hop = next_hop;
-
- /*
- * Setting tbl8 entry in one go to avoid
- * race conditions
- */
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+add_depth_small(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -881,150 +506,7 @@ add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
static __rte_noinline int32_t
-add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index;
- int32_t tbl8_group_index, tbl8_group_start, tbl8_group_end, tbl8_index,
- tbl8_range, i;
-
- tbl24_index = (ip_masked >> 8);
- tbl8_range = depth_to_range(depth);
-
- if (!lpm->tbl24[tbl24_index].valid) {
- /* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- /* Check tbl8 allocation was successful. */
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- /* Find index into tbl8 and range. */
- tbl8_index = (tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES) +
- (ip_masked & 0xFF);
-
- /* Set tbl8 entry. */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } /* If valid entry but not extended calculate the index into Table8. */
- else if (lpm->tbl24[tbl24_index].valid_group == 0) {
- /* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_group_start +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /* Populate new tbl8 with tbl24 value. */
- for (i = tbl8_group_start; i < tbl8_group_end; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = lpm->tbl24[tbl24_index].depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop =
- lpm->tbl24[tbl24_index].next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- /* Insert new rule into the tbl8 entry. */
- for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } else { /*
- * If it is valid, extended entry calculate the index into tbl8.
- */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
-
- if (!lpm->tbl8[i].valid ||
- lpm->tbl8[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- /*
- * Setting tbl8 entry in one go to avoid race
- * condition
- */
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+add_depth_big(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -1037,7 +519,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1083,7 +565,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1177,48 +659,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* Add a route
*/
int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- int32_t rule_index, status = 0;
- uint32_t ip_masked;
-
- /* Check user arguments. */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- ip_masked = ip & depth_to_mask(depth);
-
- /* Add the rule to the rule table. */
- rule_index = rule_add_v20(lpm, ip_masked, depth, next_hop);
-
- /* If the is no space available for new rule return error. */
- if (rule_index < 0) {
- return rule_index;
- }
-
- if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v20(lpm, ip_masked, depth, next_hop);
- } else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v20(lpm, ip_masked, depth, next_hop);
-
- /*
- * If add fails due to exhaustion of tbl8 extensions delete
- * rule that was added to rule table.
- */
- if (status < 0) {
- rule_delete_v20(lpm, rule_index, depth);
-
- return status;
- }
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_add, _v20, 2.0);
-
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
int32_t rule_index, status = 0;
@@ -1231,7 +672,7 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
ip_masked = ip & depth_to_mask(depth);
/* Add the rule to the rule table. */
- rule_index = rule_add_v1604(lpm, ip_masked, depth, next_hop);
+ rule_index = rule_add(lpm, ip_masked, depth, next_hop);
/* If the is no space available for new rule return error. */
if (rule_index < 0) {
@@ -1239,16 +680,16 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_small(lpm, ip_masked, depth, next_hop);
} else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_big(lpm, ip_masked, depth, next_hop);
/*
* If add fails due to exhaustion of tbl8 extensions delete
* rule that was added to rule table.
*/
if (status < 0) {
- rule_delete_v1604(lpm, rule_index, depth);
+ rule_delete(lpm, rule_index, depth);
return status;
}
@@ -1256,42 +697,12 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_add, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_add(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t next_hop), rte_lpm_add_v1604);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop)
-{
- uint32_t ip_masked;
- int32_t rule_index;
-
- /* Check user arguments. */
- if ((lpm == NULL) ||
- (next_hop == NULL) ||
- (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- /* Look for the rule using rule_find. */
- ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v20(lpm, ip_masked, depth);
-
- if (rule_index >= 0) {
- *next_hop = lpm->rules_tbl[rule_index].next_hop;
- return 1;
- }
-
- /* If rule is not found return 0. */
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop)
{
uint32_t ip_masked;
@@ -1305,7 +716,7 @@ uint32_t *next_hop)
/* Look for the rule using rule_find. */
ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v1604(lpm, ip_masked, depth);
+ rule_index = rule_find(lpm, ip_masked, depth);
if (rule_index >= 0) {
*next_hop = lpm->rules_tbl[rule_index].next_hop;
@@ -1315,12 +726,9 @@ uint32_t *next_hop)
/* If rule is not found return 0. */
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_is_rule_present, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t *next_hop), rte_lpm_is_rule_present_v1604);
static int32_t
-find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
+find_previous_rule(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint8_t *sub_rule_depth)
{
int32_t rule_index;
@@ -1330,7 +738,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
ip_masked = ip & depth_to_mask(prev_depth);
- rule_index = rule_find_v20(lpm, ip_masked, prev_depth);
+ rule_index = rule_find(lpm, ip_masked, prev_depth);
if (rule_index >= 0) {
*sub_rule_depth = prev_depth;
@@ -1342,133 +750,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
}
static int32_t
-find_previous_rule_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint8_t *sub_rule_depth)
-{
- int32_t rule_index;
- uint32_t ip_masked;
- uint8_t prev_depth;
-
- for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
- ip_masked = ip & depth_to_mask(prev_depth);
-
- rule_index = rule_find_v1604(lpm, ip_masked, prev_depth);
-
- if (rule_index >= 0) {
- *sub_rule_depth = prev_depth;
- return rule_index;
- }
- }
-
- return -1;
-}
-
-static int32_t
-delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_range, tbl24_index, tbl8_group_index, tbl8_index, i, j;
-
- /* Calculate the range and index into Table24. */
- tbl24_range = depth_to_range(depth);
- tbl24_index = (ip_masked >> 8);
-
- /*
- * Firstly check the sub_rule_index. A -1 indicates no replacement rule
- * and a positive number indicates a sub_rule_index.
- */
- if (sub_rule_index < 0) {
- /*
- * If no replacement rule exists then invalidate entries
- * associated with this rule.
- */
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- zero_tbl24_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = 0,
- };
- zero_tbl24_entry.next_hop = 0;
- __atomic_store(&lpm->tbl24[i],
- &zero_tbl24_entry, __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- lpm->tbl8[j].valid = INVALID;
- }
- }
- }
- } else {
- /*
- * If a replacement rule exists then modify entries
- * associated with this rule.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->rules_tbl[sub_rule_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = sub_rule_depth,
- };
-
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = sub_rule_depth,
- };
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1575,7 +857,7 @@ delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* thus can be recycled
*/
static int32_t
-tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
+tbl8_recycle_check(struct rte_lpm_tbl_entry *tbl8,
uint32_t tbl8_group_start)
{
uint32_t tbl8_group_end, i;
@@ -1622,140 +904,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
}
static int32_t
-tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
- uint32_t tbl8_group_start)
-{
- uint32_t tbl8_group_end, i;
- tbl8_group_end = tbl8_group_start + RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /*
- * Check the first entry of the given tbl8. If it is invalid we know
- * this tbl8 does not contain any rule with a depth < RTE_LPM_MAX_DEPTH
- * (As they would affect all entries in a tbl8) and thus this table
- * can not be recycled.
- */
- if (tbl8[tbl8_group_start].valid) {
- /*
- * If first entry is valid check if the depth is less than 24
- * and if so check the rest of the entries to verify that they
- * are all of this depth.
- */
- if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
- for (i = (tbl8_group_start + 1); i < tbl8_group_end;
- i++) {
-
- if (tbl8[i].depth !=
- tbl8[tbl8_group_start].depth) {
-
- return -EEXIST;
- }
- }
- /* If all entries are the same return the tb8 index */
- return tbl8_group_start;
- }
-
- return -EEXIST;
- }
- /*
- * If the first entry is invalid check if the rest of the entries in
- * the tbl8 are invalid.
- */
- for (i = (tbl8_group_start + 1); i < tbl8_group_end; i++) {
- if (tbl8[i].valid)
- return -EEXIST;
- }
- /* If no valid entries are found then return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_index, tbl8_group_index, tbl8_group_start, tbl8_index,
- tbl8_range, i;
- int32_t tbl8_recycle_index;
-
- /*
- * Calculate the index into tbl24 and range. Note: All depths larger
- * than MAX_DEPTH_TBL24 are associated with only one tbl24 entry.
- */
- tbl24_index = ip_masked >> 8;
-
- /* Calculate the index into tbl8 and range. */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
- tbl8_range = depth_to_range(depth);
-
- if (sub_rule_index < 0) {
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be removed or modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- lpm->tbl8[i].valid = INVALID;
- }
- } else {
- /* Set new tbl8 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = sub_rule_depth,
- .valid_group = lpm->tbl8[tbl8_group_start].valid_group,
- };
-
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
-
- /*
- * Check if there are any valid entries in this tbl8 group. If all
- * tbl8 entries are invalid we can free the tbl8 and invalidate the
- * associated tbl24 entry.
- */
-
- tbl8_recycle_index = tbl8_recycle_check_v20(lpm->tbl8, tbl8_group_start);
-
- if (tbl8_recycle_index == -EINVAL) {
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- lpm->tbl24[tbl24_index].valid = 0;
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- } else if (tbl8_recycle_index > -1) {
- /* Update tbl24 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = lpm->tbl8[tbl8_recycle_index].depth,
- };
-
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELAXED);
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_big(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1810,7 +959,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* associated tbl24 entry.
*/
- tbl8_recycle_index = tbl8_recycle_check_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_recycle_index = tbl8_recycle_check(lpm->tbl8, tbl8_group_start);
if (tbl8_recycle_index == -EINVAL) {
/* Set tbl24 before freeing tbl8 to avoid race condition.
@@ -1818,7 +967,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
*/
lpm->tbl24[tbl24_index].valid = 0;
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
} else if (tbl8_recycle_index > -1) {
/* Update tbl24 entry. */
struct rte_lpm_tbl_entry new_tbl24_entry = {
@@ -1834,7 +983,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
__atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
__ATOMIC_RELAXED);
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
}
#undef group_idx
return 0;
@@ -1844,7 +993,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* Deletes a rule
*/
int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
+rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
{
int32_t rule_to_delete_index, sub_rule_index;
uint32_t ip_masked;
@@ -1863,7 +1012,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* Find the index of the input rule, that needs to be deleted, in the
* rule table.
*/
- rule_to_delete_index = rule_find_v20(lpm, ip_masked, depth);
+ rule_to_delete_index = rule_find(lpm, ip_masked, depth);
/*
* Check if rule_to_delete_index was found. If no rule was found the
@@ -1873,7 +1022,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
return -EINVAL;
/* Delete the rule from the rule table. */
- rule_delete_v20(lpm, rule_to_delete_index, depth);
+ rule_delete(lpm, rule_to_delete_index, depth);
/*
* Find rule to replace the rule_to_delete. If there is no rule to
@@ -1881,100 +1030,26 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* entries associated with this rule.
*/
sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v20(lpm, ip, depth, &sub_rule_depth);
+ sub_rule_index = find_previous_rule(lpm, ip, depth, &sub_rule_depth);
/*
* If the input depth value is less than 25 use function
* delete_depth_small otherwise use delete_depth_big.
*/
if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v20(lpm, ip_masked, depth,
+ return delete_depth_small(lpm, ip_masked, depth,
sub_rule_index, sub_rule_depth);
} else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v20(lpm, ip_masked, depth, sub_rule_index,
+ return delete_depth_big(lpm, ip_masked, depth, sub_rule_index,
sub_rule_depth);
}
}
-VERSION_SYMBOL(rte_lpm_delete, _v20, 2.0);
-
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
-{
- int32_t rule_to_delete_index, sub_rule_index;
- uint32_t ip_masked;
- uint8_t sub_rule_depth;
- /*
- * Check input arguments. Note: IP must be a positive integer of 32
- * bits in length therefore it need not be checked.
- */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH)) {
- return -EINVAL;
- }
-
- ip_masked = ip & depth_to_mask(depth);
-
- /*
- * Find the index of the input rule, that needs to be deleted, in the
- * rule table.
- */
- rule_to_delete_index = rule_find_v1604(lpm, ip_masked, depth);
-
- /*
- * Check if rule_to_delete_index was found. If no rule was found the
- * function rule_find returns -EINVAL.
- */
- if (rule_to_delete_index < 0)
- return -EINVAL;
-
- /* Delete the rule from the rule table. */
- rule_delete_v1604(lpm, rule_to_delete_index, depth);
-
- /*
- * Find rule to replace the rule_to_delete. If there is no rule to
- * replace the rule_to_delete we return -1 and invalidate the table
- * entries associated with this rule.
- */
- sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v1604(lpm, ip, depth, &sub_rule_depth);
-
- /*
- * If the input depth value is less than 25 use function
- * delete_depth_small otherwise use delete_depth_big.
- */
- if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v1604(lpm, ip_masked, depth,
- sub_rule_index, sub_rule_depth);
- } else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v1604(lpm, ip_masked, depth, sub_rule_index,
- sub_rule_depth);
- }
-}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth), rte_lpm_delete_v1604);
/*
* Delete all rules from the LPM table.
*/
void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm)
-{
- /* Zero rule information. */
- memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
-
- /* Zero tbl24. */
- memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
-
- /* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
-
- /* Delete all rules form the rules table. */
- memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
-}
-VERSION_SYMBOL(rte_lpm_delete_all, _v20, 2.0);
-
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
+rte_lpm_delete_all(struct rte_lpm *lpm)
{
/* Zero rule information. */
memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
@@ -1989,6 +1064,3 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete_all, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_delete_all(struct rte_lpm *lpm),
- rte_lpm_delete_all_v1604);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index 906ec44830..ca9627a141 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -65,31 +65,6 @@ extern "C" {
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- /**
- * Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
- * a group index pointing to a tbl8 structure (tbl24 only, when
- * valid_group is set)
- */
- RTE_STD_C11
- union {
- uint8_t next_hop;
- uint8_t group_idx;
- };
- /* Using single uint8_t to store 3 values. */
- uint8_t valid :1; /**< Validation flag. */
- /**
- * For tbl24:
- * - valid_group == 0: entry stores a next hop
- * - valid_group == 1: entry stores a group_index pointing to a tbl8
- * For tbl8:
- * - valid_group indicates whether the current tbl8 is in use or not
- */
- uint8_t valid_group :1;
- uint8_t depth :6; /**< Rule depth. */
-} __rte_aligned(sizeof(uint16_t));
-
__extension__
struct rte_lpm_tbl_entry {
/**
@@ -112,16 +87,6 @@ struct rte_lpm_tbl_entry {
};
#else
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- uint8_t depth :6;
- uint8_t valid_group :1;
- uint8_t valid :1;
- union {
- uint8_t group_idx;
- uint8_t next_hop;
- };
-} __rte_aligned(sizeof(uint16_t));
__extension__
struct rte_lpm_tbl_entry {
@@ -142,11 +107,6 @@ struct rte_lpm_config {
};
/** @internal Rule structure. */
-struct rte_lpm_rule_v20 {
- uint32_t ip; /**< Rule IP address. */
- uint8_t next_hop; /**< Rule next hop. */
-};
-
struct rte_lpm_rule {
uint32_t ip; /**< Rule IP address. */
uint32_t next_hop; /**< Rule next hop. */
@@ -159,21 +119,6 @@ struct rte_lpm_rule_info {
};
/** @internal LPM structure. */
-struct rte_lpm_v20 {
- /* LPM metadata. */
- char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
- uint32_t max_rules; /**< Max. balanced rules per lpm. */
- struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
-
- /* LPM Tables. */
- struct rte_lpm_tbl_entry_v20 tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry_v20 tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule_v20 rules_tbl[]
- __rte_cache_aligned; /**< LPM rules. */
-};
-
struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
@@ -210,11 +155,6 @@ struct rte_lpm {
struct rte_lpm *
rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config);
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
-struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
- const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
@@ -228,10 +168,6 @@ rte_lpm_create_v1604(const char *name, int socket_id,
*/
struct rte_lpm *
rte_lpm_find_existing(const char *name);
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name);
-struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name);
/**
* Free an LPM object.
@@ -243,10 +179,6 @@ rte_lpm_find_existing_v1604(const char *name);
*/
void
rte_lpm_free(struct rte_lpm *lpm);
-void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm);
/**
* Add a rule to the LPM table.
@@ -264,12 +196,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm);
*/
int
rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop);
-int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -289,12 +215,6 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
int
rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop);
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
-uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -310,10 +230,6 @@ uint32_t *next_hop);
*/
int
rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
/**
* Delete all rules from the LPM table.
@@ -323,10 +239,6 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
*/
void
rte_lpm_delete_all(struct rte_lpm *lpm);
-void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm);
/**
* Lookup an IP into the LPM table.
diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c
index 9b8aeb9721..b981e40714 100644
--- a/lib/librte_lpm/rte_lpm6.c
+++ b/lib/librte_lpm/rte_lpm6.c
@@ -808,18 +808,6 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
return 1;
}
-/*
- * Add a route
- */
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop)
-{
- return rte_lpm6_add_v1705(lpm, ip, depth, next_hop);
-}
-VERSION_SYMBOL(rte_lpm6_add, _v20, 2.0);
-
-
/*
* Simulate adding a route to LPM
*
@@ -841,7 +829,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
/* Inspect the first three bytes through tbl24 on the first step. */
ret = simulate_add_step(lpm, lpm->tbl24, &tbl_next, masked_ip,
- ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
+ ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
total_need_tbl_nb = need_tbl_nb;
/*
* Inspect one by one the rest of the bytes until
@@ -850,7 +838,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && ret == 1; i++) {
tbl = tbl_next;
ret = simulate_add_step(lpm, tbl, &tbl_next, masked_ip, 1,
- (uint8_t)(i+1), depth, &need_tbl_nb);
+ (uint8_t)(i + 1), depth, &need_tbl_nb);
total_need_tbl_nb += need_tbl_nb;
}
@@ -861,9 +849,12 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
return 0;
}
+/*
+ * Add a route
+ */
int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop)
+rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+ uint32_t next_hop)
{
struct rte_lpm6_tbl_entry *tbl;
struct rte_lpm6_tbl_entry *tbl_next = NULL;
@@ -895,8 +886,8 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
/* Inspect the first three bytes through tbl24 on the first step. */
tbl = lpm->tbl24;
status = add_step(lpm, tbl, TBL24_IND, &tbl_next, &tbl_next_num,
- masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
- is_new_rule);
+ masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
+ is_new_rule);
assert(status >= 0);
/*
@@ -906,17 +897,13 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && status == 1; i++) {
tbl = tbl_next;
status = add_step(lpm, tbl, tbl_next_num, &tbl_next,
- &tbl_next_num, masked_ip, 1, (uint8_t)(i+1),
- depth, next_hop, is_new_rule);
+ &tbl_next_num, masked_ip, 1, (uint8_t)(i + 1),
+ depth, next_hop, is_new_rule);
assert(status >= 0);
}
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_add, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip,
- uint8_t depth, uint32_t next_hop),
- rte_lpm6_add_v1705);
/*
* Takes a pointer to a table entry and inspect one level.
@@ -955,25 +942,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl,
* Looks up an IP
*/
int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_lookup_v1705(lpm, ip, &next_hop32);
- if (status == 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-}
-VERSION_SYMBOL(rte_lpm6_lookup, _v20, 2.0);
-
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
+rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
uint32_t *next_hop)
{
const struct rte_lpm6_tbl_entry *tbl;
@@ -1000,56 +969,12 @@ rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop), rte_lpm6_lookup_v1705);
/*
* Looks up a group of IP addresses
*/
int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t * next_hops, unsigned n)
-{
- unsigned i;
- const struct rte_lpm6_tbl_entry *tbl;
- const struct rte_lpm6_tbl_entry *tbl_next = NULL;
- uint32_t tbl24_index, next_hop;
- uint8_t first_byte;
- int status;
-
- /* DEBUG: Check user input arguments. */
- if ((lpm == NULL) || (ips == NULL) || (next_hops == NULL))
- return -EINVAL;
-
- for (i = 0; i < n; i++) {
- first_byte = LOOKUP_FIRST_BYTE;
- tbl24_index = (ips[i][0] << BYTES2_SIZE) |
- (ips[i][1] << BYTE_SIZE) | ips[i][2];
-
- /* Calculate pointer to the first entry to be inspected */
- tbl = &lpm->tbl24[tbl24_index];
-
- do {
- /* Continue inspecting following levels until success or failure */
- status = lookup_step(lpm, tbl, &tbl_next, ips[i], first_byte++,
- &next_hop);
- tbl = tbl_next;
- } while (status == 1);
-
- if (status < 0)
- next_hops[i] = -1;
- else
- next_hops[i] = (int16_t)next_hop;
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm6_lookup_bulk_func, _v20, 2.0);
-
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
+rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n)
{
@@ -1089,37 +1014,12 @@ rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup_bulk_func, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n),
- rte_lpm6_lookup_bulk_func_v1705);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_is_rule_present_v1705(lpm, ip, depth, &next_hop32);
- if (status > 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-
-}
-VERSION_SYMBOL(rte_lpm6_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop)
{
uint8_t masked_ip[RTE_LPM6_IPV6_ADDR_SIZE];
@@ -1135,10 +1035,6 @@ rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
return rule_find(lpm, masked_ip, depth, next_hop);
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_is_rule_present, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm,
- uint8_t *ip, uint8_t depth, uint32_t *next_hop),
- rte_lpm6_is_rule_present_v1705);
/*
* Delete a rule from the rule table.
diff --git a/lib/librte_lpm/rte_lpm6.h b/lib/librte_lpm/rte_lpm6.h
index 5d59ccb1fe..37dfb20249 100644
--- a/lib/librte_lpm/rte_lpm6.h
+++ b/lib/librte_lpm/rte_lpm6.h
@@ -96,12 +96,6 @@ rte_lpm6_free(struct rte_lpm6 *lpm);
int
rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t next_hop);
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -121,12 +115,6 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
int
rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop);
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -184,11 +172,6 @@ rte_lpm6_delete_all(struct rte_lpm6 *lpm);
*/
int
rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint32_t *next_hop);
-int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop);
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop);
/**
* Lookup multiple IP addresses in an LPM table.
@@ -210,14 +193,6 @@ int
rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n);
#ifdef __cplusplus
}
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v3 4/9] timer: remove deprecated code
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (3 preceding siblings ...)
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 3/9] buildtools: add ABI update shell script Anatoly Burakov
@ 2019-10-16 17:03 4% ` Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 5/9] lpm: " Anatoly Burakov
` (4 subsequent siblings)
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, bruce.richardson, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_timer/rte_timer.c | 90 ++----------------------------------
lib/librte_timer/rte_timer.h | 15 ------
2 files changed, 5 insertions(+), 100 deletions(-)
diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
index bdcf05d06b..de6959b809 100644
--- a/lib/librte_timer/rte_timer.c
+++ b/lib/librte_timer/rte_timer.c
@@ -68,9 +68,6 @@ static struct rte_timer_data *rte_timer_data_arr;
static const uint32_t default_data_id;
static uint32_t rte_timer_subsystem_initialized;
-/* For maintaining older interfaces for a period */
-static struct rte_timer_data default_timer_data;
-
/* when debug is enabled, store some statistics */
#ifdef RTE_LIBRTE_TIMER_DEBUG
#define __TIMER_STAT_ADD(priv_timer, name, n) do { \
@@ -131,22 +128,6 @@ rte_timer_data_dealloc(uint32_t id)
return 0;
}
-void
-rte_timer_subsystem_init_v20(void)
-{
- unsigned lcore_id;
- struct priv_timer *priv_timer = default_timer_data.priv_timer;
-
- /* since priv_timer is static, it's zeroed by default, so only init some
- * fields.
- */
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) {
- rte_spinlock_init(&priv_timer[lcore_id].list_lock);
- priv_timer[lcore_id].prev_lcore = lcore_id;
- }
-}
-VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
-
/* Init the timer library. Allocate an array of timer data structs in shared
* memory, and allocate the zeroth entry for use with original timer
* APIs. Since the intersection of the sets of lcore ids in primary and
@@ -154,7 +135,7 @@ VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
* multiple processes.
*/
int
-rte_timer_subsystem_init_v1905(void)
+rte_timer_subsystem_init(void)
{
const struct rte_memzone *mz;
struct rte_timer_data *data;
@@ -209,9 +190,6 @@ rte_timer_subsystem_init_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_subsystem_init(void),
- rte_timer_subsystem_init_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_subsystem_init, _v1905, 19.05);
void
rte_timer_subsystem_finalize(void)
@@ -552,42 +530,13 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
/* Reset and start the timer associated with the timer handle tim */
int
-rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg)
-{
- uint64_t cur_time = rte_get_timer_cycles();
- uint64_t period;
-
- if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
- !(rte_lcore_is_enabled(tim_lcore) ||
- rte_lcore_has_role(tim_lcore, ROLE_SERVICE))))
- return -1;
-
- if (type == PERIODICAL)
- period = ticks;
- else
- period = 0;
-
- return __rte_timer_reset(tim, cur_time + ticks, period, tim_lcore,
- fct, arg, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_reset, _v20, 2.0);
-
-int
-rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
+rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned int tim_lcore,
rte_timer_cb_t fct, void *arg)
{
return rte_timer_alt_reset(default_data_id, tim, ticks, type,
tim_lcore, fct, arg);
}
-MAP_STATIC_SYMBOL(int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type,
- unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg),
- rte_timer_reset_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_reset, _v1905, 19.05);
int
rte_timer_alt_reset(uint32_t timer_data_id, struct rte_timer *tim,
@@ -658,20 +607,10 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked,
/* Stop the timer associated with the timer handle tim */
int
-rte_timer_stop_v20(struct rte_timer *tim)
-{
- return __rte_timer_stop(tim, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_stop, _v20, 2.0);
-
-int
-rte_timer_stop_v1905(struct rte_timer *tim)
+rte_timer_stop(struct rte_timer *tim)
{
return rte_timer_alt_stop(default_data_id, tim);
}
-MAP_STATIC_SYMBOL(int rte_timer_stop(struct rte_timer *tim),
- rte_timer_stop_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_stop, _v1905, 19.05);
int
rte_timer_alt_stop(uint32_t timer_data_id, struct rte_timer *tim)
@@ -817,15 +756,8 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
priv_timer[lcore_id].running_tim = NULL;
}
-void
-rte_timer_manage_v20(void)
-{
- __rte_timer_manage(&default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_manage, _v20, 2.0);
-
int
-rte_timer_manage_v1905(void)
+rte_timer_manage(void)
{
struct rte_timer_data *timer_data;
@@ -835,8 +767,6 @@ rte_timer_manage_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_manage(void), rte_timer_manage_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_manage, _v1905, 19.05);
int
rte_timer_alt_manage(uint32_t timer_data_id,
@@ -1074,21 +1004,11 @@ __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f)
#endif
}
-void
-rte_timer_dump_stats_v20(FILE *f)
-{
- __rte_timer_dump_stats(&default_timer_data, f);
-}
-VERSION_SYMBOL(rte_timer_dump_stats, _v20, 2.0);
-
int
-rte_timer_dump_stats_v1905(FILE *f)
+rte_timer_dump_stats(FILE *f)
{
return rte_timer_alt_dump_stats(default_data_id, f);
}
-MAP_STATIC_SYMBOL(int rte_timer_dump_stats(FILE *f),
- rte_timer_dump_stats_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_dump_stats, _v1905, 19.05);
int
rte_timer_alt_dump_stats(uint32_t timer_data_id __rte_unused, FILE *f)
diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h
index 05d287d8f2..9dc5fc3092 100644
--- a/lib/librte_timer/rte_timer.h
+++ b/lib/librte_timer/rte_timer.h
@@ -181,8 +181,6 @@ int rte_timer_data_dealloc(uint32_t id);
* subsystem
*/
int rte_timer_subsystem_init(void);
-int rte_timer_subsystem_init_v1905(void);
-void rte_timer_subsystem_init_v20(void);
/**
* @warning
@@ -250,13 +248,6 @@ void rte_timer_init(struct rte_timer *tim);
int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned tim_lcore,
rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-
/**
* Loop until rte_timer_reset() succeeds.
@@ -313,8 +304,6 @@ rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
* - (-1): The timer is in the RUNNING or CONFIG state.
*/
int rte_timer_stop(struct rte_timer *tim);
-int rte_timer_stop_v1905(struct rte_timer *tim);
-int rte_timer_stop_v20(struct rte_timer *tim);
/**
* Loop until rte_timer_stop() succeeds.
@@ -358,8 +347,6 @@ int rte_timer_pending(struct rte_timer *tim);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_manage(void);
-int rte_timer_manage_v1905(void);
-void rte_timer_manage_v20(void);
/**
* Dump statistics about timers.
@@ -371,8 +358,6 @@ void rte_timer_manage_v20(void);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_dump_stats(FILE *f);
-int rte_timer_dump_stats_v1905(FILE *f);
-void rte_timer_dump_stats_v20(FILE *f);
/**
* @warning
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 3/9] buildtools: add ABI update shell script
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (2 preceding siblings ...)
2019-10-16 17:03 14% ` [dpdk-dev] [PATCH v3 2/9] buildtools: add script for updating symbols abi version Anatoly Burakov
@ 2019-10-16 17:03 23% ` Anatoly Burakov
2019-10-16 17:03 4% ` [dpdk-dev] [PATCH v3 4/9] timer: remove deprecated code Anatoly Burakov
` (5 subsequent siblings)
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
In order to facilitate mass updating of version files, add a shell
script that recurses into lib/ and drivers/ directories and calls
the ABI version update script.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v3:
- Switch to sh rather than bash, and remove bash-isms
- Address review comments
v2:
- Add this patch to split the shell script from previous commit
- Fixup miscellaneous bugs
buildtools/update-abi.sh | 42 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
create mode 100755 buildtools/update-abi.sh
diff --git a/buildtools/update-abi.sh b/buildtools/update-abi.sh
new file mode 100755
index 0000000000..89ba5804a6
--- /dev/null
+++ b/buildtools/update-abi.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+abi_version=$1
+abi_version_file="./config/ABI_VERSION"
+update_path="lib drivers"
+
+if [ -z "$1" ]; then
+ # output to stderr
+ >&2 echo "Please provide ABI version"
+ exit 1
+fi
+
+# check version string format
+echo $abi_version | grep -q -e "^[[:digit:]]\{1,2\}\.[[:digit:]]\{1,2\}$"
+if [ "$?" -ne 0 ]; then
+ # output to stderr
+ >&2 echo "ABI version must be formatted as MAJOR.MINOR version"
+ exit 1
+fi
+
+if [ -n "$2" ]; then
+ abi_version_file=$2
+fi
+
+if [ -n "$3" ]; then
+ # drop $1 and $2
+ shift 2
+ # assign all other arguments as update paths
+ update_path=$@
+fi
+
+echo "New ABI version:" $abi_version
+echo "ABI_VERSION path:" $abi_version_file
+echo "Path to update:" $update_path
+
+echo $abi_version > $abi_version_file
+
+find $update_path -name \*version.map -exec \
+ ./buildtools/update_version_map_abi.py {} \
+ $abi_version \; -print
--
2.17.1
^ permalink raw reply [relevance 23%]
* [dpdk-dev] [PATCH v3 2/9] buildtools: add script for updating symbols abi version
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
2019-10-16 17:03 7% ` [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global Anatoly Burakov
@ 2019-10-16 17:03 14% ` Anatoly Burakov
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 3/9] buildtools: add ABI update shell script Anatoly Burakov
` (6 subsequent siblings)
9 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev; +Cc: Pawel Modrak, john.mcnamara, bruce.richardson, thomas, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Add a script that automatically merges all stable ABI's under one
ABI section with the new version, while leaving experimental
section exactly as it is.
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v3:
- Add comments to regex patterns
v2:
- Reworked script to be pep8-compliant and more reliable
buildtools/update_version_map_abi.py | 170 +++++++++++++++++++++++++++
1 file changed, 170 insertions(+)
create mode 100755 buildtools/update_version_map_abi.py
diff --git a/buildtools/update_version_map_abi.py b/buildtools/update_version_map_abi.py
new file mode 100755
index 0000000000..50283e6a3d
--- /dev/null
+++ b/buildtools/update_version_map_abi.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+"""
+A Python program to update the ABI version and function names in a DPDK
+lib_*_version.map file. Called from the buildtools/update_abi.sh utility.
+"""
+
+from __future__ import print_function
+import argparse
+import sys
+import re
+
+
+def __parse_map_file(f_in):
+ # match function name, followed by semicolon, followed by EOL, optionally
+ # with whitespace inbetween each item
+ func_line_regex = re.compile(r"\s*"
+ r"(?P<func>[a-zA-Z_0-9]+)"
+ r"\s*"
+ r";"
+ r"\s*"
+ r"$")
+ # match section name, followed by opening bracked, followed by EOL,
+ # optionally with whitespace inbetween each item
+ section_begin_regex = re.compile(r"\s*"
+ r"(?P<version>[a-zA-Z0-9_\.]+)"
+ r"\s*"
+ r"{"
+ r"\s*"
+ r"$")
+ # match closing bracket, optionally followed by section name (for when we
+ # inherit from another ABI version), followed by semicolon, followed by
+ # EOL, optionally with whitespace inbetween each item
+ section_end_regex = re.compile(r"\s*"
+ r"}"
+ r"\s*"
+ r"(?P<parent>[a-zA-Z0-9_\.]+)?"
+ r"\s*"
+ r";"
+ r"\s*"
+ r"$")
+
+ # for stable ABI, we don't care about which version introduced which
+ # function, we just flatten the list. there are dupes in certain files, so
+ # use a set instead of a list
+ stable_lines = set()
+ # copy experimental section as is
+ experimental_lines = []
+ is_experimental = False
+
+ # gather all functions
+ for line in f_in:
+ # clean up the line
+ line = line.strip('\n').strip()
+
+ # is this an end of section?
+ match = section_end_regex.match(line)
+ if match:
+ # whatever section this was, it's not active any more
+ is_experimental = False
+ continue
+
+ # if we're in the middle of experimental section, we need to copy
+ # the section verbatim, so just add the line
+ if is_experimental:
+ experimental_lines += [line]
+ continue
+
+ # skip empty lines
+ if not line:
+ continue
+
+ # is this a beginning of a new section?
+ match = section_begin_regex.match(line)
+ if match:
+ cur_section = match.group("version")
+ # is it experimental?
+ is_experimental = cur_section == "EXPERIMENTAL"
+ continue
+
+ # is this a function?
+ match = func_line_regex.match(line)
+ if match:
+ stable_lines.add(match.group("func"))
+
+ return stable_lines, experimental_lines
+
+
+def __regenerate_map_file(f_out, abi_version, stable_lines,
+ experimental_lines):
+ # print ABI version header
+ print("DPDK_{} {{".format(abi_version), file=f_out)
+
+ if stable_lines:
+ # print global section
+ print("\tglobal:", file=f_out)
+ # blank line
+ print(file=f_out)
+
+ # print all stable lines, alphabetically sorted
+ for line in sorted(stable_lines):
+ print("\t{};".format(line), file=f_out)
+
+ # another blank line
+ print(file=f_out)
+
+ # print local section
+ print("\tlocal: *;", file=f_out)
+
+ # end stable version
+ print("};", file=f_out)
+
+ # do we have experimental lines?
+ if not experimental_lines:
+ return
+
+ # another blank line
+ print(file=f_out)
+
+ # start experimental section
+ print("EXPERIMENTAL {", file=f_out)
+
+ # print all experimental lines as they were
+ for line in experimental_lines:
+ # don't print empty whitespace
+ if not line:
+ print("", file=f_out)
+ else:
+ print("\t{}".format(line), file=f_out)
+
+ # end section
+ print("};", file=f_out)
+
+
+def __main():
+ arg_parser = argparse.ArgumentParser(
+ description='Merge versions in linker version script.')
+
+ arg_parser.add_argument("map_file", type=str,
+ help='path to linker version script file '
+ '(pattern: *version.map)')
+ arg_parser.add_argument("abi_version", type=str,
+ help='target ABI version (pattern: MAJOR.MINOR)')
+
+ parsed = arg_parser.parse_args()
+
+ if not parsed.map_file.endswith('version.map'):
+ print("Invalid input file: {}".format(parsed.map_file),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ if not re.match(r"\d{1,2}\.\d{1,2}", parsed.abi_version):
+ print("Invalid ABI version: {}".format(parsed.abi_version),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ with open(parsed.map_file) as f_in:
+ stable_lines, experimental_lines = __parse_map_file(f_in)
+
+ with open(parsed.map_file, 'w') as f_out:
+ __regenerate_map_file(f_out, parsed.abi_version, stable_lines,
+ experimental_lines)
+
+
+if __name__ == "__main__":
+ __main()
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
@ 2019-10-16 17:03 7% ` Anatoly Burakov
2019-10-17 8:44 9% ` Bruce Richardson
2019-10-16 17:03 14% ` [dpdk-dev] [PATCH v3 2/9] buildtools: add script for updating symbols abi version Anatoly Burakov
` (7 subsequent siblings)
9 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Thomas Monjalon, Bruce Richardson, john.mcnamara,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
As per new ABI policy, all of the libraries are now versioned using
one global ABI version. Changes in this patch implement the
necessary steps to enable that.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v3:
- Removed Windows support from Makefile changes
- Removed unneeded path conversions from meson files
buildtools/meson.build | 2 ++
config/ABI_VERSION | 1 +
config/meson.build | 5 +++--
drivers/meson.build | 20 ++++++++++++--------
lib/meson.build | 18 +++++++++++-------
meson_options.txt | 2 --
mk/rte.lib.mk | 13 ++++---------
7 files changed, 33 insertions(+), 28 deletions(-)
create mode 100644 config/ABI_VERSION
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 32c79c1308..78ce69977d 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -12,3 +12,5 @@ if python3.found()
else
map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
endif
+
+is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
diff --git a/config/ABI_VERSION b/config/ABI_VERSION
new file mode 100644
index 0000000000..9a7c1e503f
--- /dev/null
+++ b/config/ABI_VERSION
@@ -0,0 +1 @@
+20.0
diff --git a/config/meson.build b/config/meson.build
index a27f731f85..3cfc02406c 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -17,7 +17,8 @@ endforeach
# set the major version, which might be used by drivers and libraries
# depending on the configuration options
pver = meson.project_version().split('.')
-major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
+abi_version = run_command(find_program('cat', 'more'),
+ files('ABI_VERSION')).stdout().strip()
# extract all version information into the build configuration
dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
@@ -37,7 +38,7 @@ endif
pmd_subdir_opt = get_option('drivers_install_subdir')
if pmd_subdir_opt.contains('<VERSION>')
- pmd_subdir_opt = major_version.join(pmd_subdir_opt.split('<VERSION>'))
+ pmd_subdir_opt = abi_version.join(pmd_subdir_opt.split('<VERSION>'))
endif
driver_install_path = join_paths(get_option('libdir'), pmd_subdir_opt)
eal_pmd_path = join_paths(get_option('prefix'), driver_install_path)
diff --git a/drivers/meson.build b/drivers/meson.build
index 2ed2e95411..fd628d9587 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -110,12 +110,19 @@ foreach class:dpdk_driver_classes
output: out_filename,
depends: [pmdinfogen, tmp_lib])
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/@2@_version.map'.format(
+ meson.current_source_dir(),
+ drv_path, lib_name)
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
- lib_version = major_version
- so_version = major_version
+ lib_version = abi_version
+ so_version = abi_version
endif
# now build the static driver
@@ -128,9 +135,6 @@ foreach class:dpdk_driver_classes
install: true)
# now build the shared driver
- version_map = '@0@/@1@/@2@_version.map'.format(
- meson.current_source_dir(),
- drv_path, lib_name)
shared_lib = shared_library(lib_name,
sources,
objects: objs,
diff --git a/lib/meson.build b/lib/meson.build
index e5ff838934..e626da778c 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -97,12 +97,18 @@ foreach l:libraries
cflags += '-DALLOW_EXPERIMENTAL_API'
endif
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/rte_@2@_version.map'.format(
+ meson.current_source_dir(), dir_name, name)
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
- lib_version = major_version
- so_version = major_version
+ lib_version = abi_version
+ so_version = abi_version
endif
# first build static lib
@@ -120,8 +126,6 @@ foreach l:libraries
# then use pre-build objects to build shared lib
sources = []
objs += static_lib.extract_all_objects(recursive: false)
- version_map = '@0@/@1@/rte_@2@_version.map'.format(
- meson.current_source_dir(), dir_name, name)
implib = dir_name + '.dll.a'
def_file = custom_target(name + '_def',
diff --git a/meson_options.txt b/meson_options.txt
index 448f3e63dc..000e38fd98 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -28,8 +28,6 @@ option('max_lcores', type: 'integer', value: 128,
description: 'maximum number of cores/threads supported by EAL')
option('max_numa_nodes', type: 'integer', value: 4,
description: 'maximum number of NUMA nodes supported by EAL')
-option('per_library_versions', type: 'boolean', value: true,
- description: 'true: each lib gets its own version number, false: DPDK version used for each lib')
option('tests', type: 'boolean', value: true,
description: 'build unit tests')
option('use_hpet', type: 'boolean', value: false,
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 4df8849a08..e1ea292b6e 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -11,20 +11,15 @@ EXTLIB_BUILD ?= n
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifneq ($(CONFIG_RTE_MAJOR_ABI),)
-ifneq ($(LIBABIVER),)
-LIBABIVER := $(CONFIG_RTE_MAJOR_ABI)
-endif
+ifneq ($(shell grep "^DPDK_" $(SRCDIR)/$(EXPORT_MAP)),)
+LIBABIVER := $(shell cat $(RTE_SRCDIR)/config/ABI_VERSION)
+else
+LIBABIVER := 0
endif
ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
ifeq ($(EXTLIB_BUILD),n)
-ifeq ($(CONFIG_RTE_MAJOR_ABI),)
-ifeq ($(CONFIG_RTE_NEXT_ABI),y)
-LIB := $(LIB).1
-endif
-endif
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
endif
endif
--
2.17.1
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v3 0/9] Implement the new ABI policy and add helper scripts
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
@ 2019-10-16 17:03 8% ` Anatoly Burakov
2019-10-17 8:50 4% ` Bruce Richardson
` (11 more replies)
2019-10-16 17:03 7% ` [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global Anatoly Burakov
` (8 subsequent siblings)
9 siblings, 12 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 17:03 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
This patchset prepares the codebase for the new ABI policy and
adds a few helper scripts.
There are two new scripts for managing ABI versions added. The
first one is a Python script that will read in a .map file,
flatten it and update the ABI version to the ABI version
specified on the command-line.
The second one is a shell script that will run the above mentioned
Python script recursively over the source tree and set the ABI
version to either that which is defined in config/ABI_VERSION, or
a user-specified one.
Example of its usage: buildtools/update-abi.sh 20.0
This will recurse into lib/ and drivers/ directory and update
whatever .map files it can find.
The other shell script that's added is one that can take in a .so
file and ensure that its declared public ABI matches either
current ABI, next ABI, or EXPERIMENTAL. This was moved to the
last commit because it made no sense to have it beforehand.
The source tree was verified to follow the new ABI policy using
the following command (assuming built binaries are in build/):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
This returns 0.
Changes since v2:
- Addressed Bruce's review comments
- Removed single distributor mode as per Dave's suggestion
Changes since v1:
- Reordered patchset to have removal of old ABI's before introducing
the new one to avoid compile breakages between patches
- Added a new patch fixing missing symbol in octeontx common
- Split script commits into multiple commits and reordered them
- Re-generated the ABI bump commit
- Verified all scripts to work
Anatoly Burakov (2):
buildtools: add ABI update shell script
drivers/octeontx: add missing public symbol
Marcin Baran (5):
config: change ABI versioning to global
timer: remove deprecated code
lpm: remove deprecated code
distributor: remove deprecated code
buildtools: add ABI versioning check script
Pawel Modrak (2):
buildtools: add script for updating symbols abi version
build: change ABI version to 20.0
app/test/test_distributor.c | 102 +-
app/test/test_distributor_perf.c | 12 -
buildtools/check-abi-version.sh | 54 +
buildtools/meson.build | 2 +
buildtools/update-abi.sh | 42 +
buildtools/update_version_map_abi.py | 170 +++
config/ABI_VERSION | 1 +
config/meson.build | 5 +-
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +-
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++-
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 7 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
drivers/meson.build | 20 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +-
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 +-
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 +-
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 +-
lib/librte_distributor/Makefile | 1 -
lib/librte_distributor/meson.build | 2 +-
lib/librte_distributor/rte_distributor.c | 126 +--
lib/librte_distributor/rte_distributor.h | 1 -
.../rte_distributor_private.h | 35 -
.../rte_distributor_v1705.h | 61 --
lib/librte_distributor/rte_distributor_v20.c | 402 -------
lib/librte_distributor/rte_distributor_v20.h | 218 ----
.../rte_distributor_version.map | 16 +-
lib/librte_eal/rte_eal_version.map | 310 ++----
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +--
lib/librte_eventdev/rte_eventdev_version.map | 130 +--
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +-
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm.c | 996 +-----------------
lib/librte_lpm/rte_lpm.h | 88 --
lib/librte_lpm/rte_lpm6.c | 132 +--
lib/librte_lpm/rte_lpm6.h | 25 -
lib/librte_lpm/rte_lpm_version.map | 39 +-
lib/librte_mbuf/rte_mbuf_version.map | 41 +-
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +-
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +-
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer.c | 90 +-
lib/librte_timer/rte_timer.h | 15 -
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +-
lib/meson.build | 18 +-
meson_options.txt | 2 -
mk/rte.lib.mk | 13 +-
180 files changed, 1111 insertions(+), 3657 deletions(-)
create mode 100755 buildtools/check-abi-version.sh
create mode 100755 buildtools/update-abi.sh
create mode 100755 buildtools/update_version_map_abi.py
create mode 100644 config/ABI_VERSION
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
delete mode 100644 lib/librte_distributor/rte_distributor_v20.c
delete mode 100644 lib/librte_distributor/rte_distributor_v20.h
--
2.17.1
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script
2019-10-16 12:43 22% ` [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script Anatoly Burakov
@ 2019-10-16 13:33 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-16 13:33 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev, john.mcnamara, thomas, david.marchand
On Wed, Oct 16, 2019 at 01:43:18PM +0100, Anatoly Burakov wrote:
> In order to facilitate mass updating of version files, add a shell
> script that recurses into lib/ and drivers/ directories and calls
> the ABI version update script.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v2:
> - Add this patch to split the shell script from previous commit
> - Fixup miscellaneous bugs
>
> buildtools/update-abi.sh | 36 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 36 insertions(+)
> create mode 100755 buildtools/update-abi.sh
>
> diff --git a/buildtools/update-abi.sh b/buildtools/update-abi.sh
> new file mode 100755
> index 0000000000..a6f916a437
> --- /dev/null
> +++ b/buildtools/update-abi.sh
> @@ -0,0 +1,36 @@
> +#!/bin/bash
Does this actually need to be bash? Most of our scripts use plain "sh".
Also on FreeBSD bash is generally in /usr/local/bin not /bin.
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2019 Intel Corporation
> +
> +abi_version=""
> +abi_version_file="./config/ABI_VERSION"
> +update_path="lib drivers"
> +
> +if [ -z "$1" ]
> +then
While there are a few scripts in DPDK putting the "then" on the next line
most scripts put it on the same line as the "if", after a ";".
> + # output to stderr
> + >&2 echo "provide ABI version"
> + exit 1
> +fi
> +
> +abi_version=$1
I think you can just do this assignment at the top when you define
abi_version in the first place. Using $1 when it doesn't exist isn't a
problem.
> +
> +if [ -n "$2" ]
> +then
> + abi_version_file=$2
> +fi
> +
> +if [ -n "$3" ]
> +then
> + update_path=${@:3}
I think this might be a bash-ism, right? If so, I think using "shift" and
then directly using $@ should work instead to make it sh-compatible..
> +fi
> +
> +echo "New ABI version:" $abi_version
> +echo "ABI_VERSION path:" $abi_version_file
> +echo "Path to update:" $update_path
> +
> +echo $abi_version > $abi_version_file
Do we need to check the abi_version provided is in the correct format?
Should it have both major and minor components, or just major. I think the
former, so we can do minor bumps which keeping major compatibility.
> +
> +find $update_path -name \*version.map -exec \
> + ./buildtools/update_version_map_abi.py {} \
> + $abi_version \; -print
> --
> 2.17.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version
2019-10-16 12:43 14% ` [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
@ 2019-10-16 13:25 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-16 13:25 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev, Pawel Modrak, john.mcnamara, thomas, david.marchand
On Wed, Oct 16, 2019 at 01:43:17PM +0100, Anatoly Burakov wrote:
> From: Pawel Modrak <pawelx.modrak@intel.com>
>
> Add a script that automatically merges all stable ABI's under one
> ABI section with the new version, while leaving experimental
> section exactly as it is.
>
> Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
>
> Notes:
> v2:
> - Reworked script to be pep8-compliant and more reliable
>
> buildtools/update_version_map_abi.py | 148 +++++++++++++++++++++++++++
> 1 file changed, 148 insertions(+)
> create mode 100755 buildtools/update_version_map_abi.py
>
> diff --git a/buildtools/update_version_map_abi.py b/buildtools/update_version_map_abi.py
> new file mode 100755
> index 0000000000..ea9044cc81
> --- /dev/null
> +++ b/buildtools/update_version_map_abi.py
> @@ -0,0 +1,148 @@
> +#!/usr/bin/env python
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright(c) 2019 Intel Corporation
> +
> +"""
> +A Python program to update the ABI version and function names in a DPDK
> +lib_*_version.map file. Called from the buildtools/update_abi.sh utility.
> +"""
> +
> +from __future__ import print_function
> +import argparse
> +import sys
> +import re
> +
> +
> +def __parse_map_file(f_in):
> + func_line_regex = re.compile(r"\s*(?P<func>[a-zA-Z_0-9]+)\s*;\s*$")
> + section_begin_regex = re.compile(
> + r"\s*(?P<version>[a-zA-Z0-9_\.]+)\s*{\s*$")
> + section_end_regex = re.compile(
> + r"\s*}\s*(?P<parent>[a-zA-Z0-9_\.]+)?\s*;\s*$")
> +
To help readers of the code, can you put in a line or two of comment
explaining each regex a bit above.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global
2019-10-16 12:43 7% ` [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global Anatoly Burakov
@ 2019-10-16 13:22 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-16 13:22 UTC (permalink / raw)
To: Anatoly Burakov
Cc: dev, Marcin Baran, Thomas Monjalon, john.mcnamara,
david.marchand, Pawel Modrak
On Wed, Oct 16, 2019 at 01:43:16PM +0100, Anatoly Burakov wrote:
> From: Marcin Baran <marcinx.baran@intel.com>
>
> The libraries should be maintained using global
> ABI versioning. The changes includes adding global
> ABI version support for both makefile and meson
> build system. Experimental libraries should be
> marked as 0.
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
Some comments inline below.
/Bruce
> buildtools/meson.build | 2 ++
> config/ABI_VERSION | 1 +
> config/meson.build | 3 ++-
> drivers/meson.build | 20 ++++++++++++++------
> lib/meson.build | 18 +++++++++++++-----
> meson_options.txt | 2 --
> mk/rte.lib.mk | 19 +++++++++++--------
> 7 files changed, 43 insertions(+), 22 deletions(-)
> create mode 100644 config/ABI_VERSION
>
> diff --git a/buildtools/meson.build b/buildtools/meson.build
> index 32c79c1308..78ce69977d 100644
> --- a/buildtools/meson.build
> +++ b/buildtools/meson.build
> @@ -12,3 +12,5 @@ if python3.found()
> else
> map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
> endif
> +
> +is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
> diff --git a/config/ABI_VERSION b/config/ABI_VERSION
> new file mode 100644
> index 0000000000..9a7c1e503f
> --- /dev/null
> +++ b/config/ABI_VERSION
> @@ -0,0 +1 @@
> +20.0
> diff --git a/config/meson.build b/config/meson.build
> index a27f731f85..25ecf928e4 100644
> --- a/config/meson.build
> +++ b/config/meson.build
> @@ -17,7 +17,8 @@ endforeach
> # set the major version, which might be used by drivers and libraries
> # depending on the configuration options
> pver = meson.project_version().split('.')
> -major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
> +major_version = run_command(find_program('cat', 'more'),
> + files('ABI_VERSION')).stdout().strip()
>
I wonder if we should rename this to abi_version rather than major_version?
> # extract all version information into the build configuration
> dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
> diff --git a/drivers/meson.build b/drivers/meson.build
> index 2ed2e95411..5c5fe87c7e 100644
> --- a/drivers/meson.build
> +++ b/drivers/meson.build
> @@ -110,9 +110,20 @@ foreach class:dpdk_driver_classes
> output: out_filename,
> depends: [pmdinfogen, tmp_lib])
>
> - if get_option('per_library_versions')
> - lib_version = '@0@.1'.format(version)
> - so_version = '@0@'.format(version)
> + version_map = '@0@/@1@/@2@_version.map'.format(
> + meson.current_source_dir(),
> + drv_path, lib_name)
> +
> + if is_windows
> + version_map = '\\'.join(version_map.split('/'))
> + endif
Don't think this block should be needed. Windows generally supports using
"/" as a separator, even if traditionally "\" was used.
> +
> + is_experimental = run_command(is_experimental_cmd,
> + files(version_map)).returncode()
> +
> + if is_experimental != 0
> + lib_version = '0.1'
> + so_version = '0'
> else
> lib_version = major_version
> so_version = major_version
> @@ -128,9 +139,6 @@ foreach class:dpdk_driver_classes
> install: true)
>
> # now build the shared driver
> - version_map = '@0@/@1@/@2@_version.map'.format(
> - meson.current_source_dir(),
> - drv_path, lib_name)
> shared_lib = shared_library(lib_name,
> sources,
> objects: objs,
> diff --git a/lib/meson.build b/lib/meson.build
> index e5ff838934..3892c16e8f 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -97,9 +97,19 @@ foreach l:libraries
> cflags += '-DALLOW_EXPERIMENTAL_API'
> endif
>
> - if get_option('per_library_versions')
> - lib_version = '@0@.1'.format(version)
> - so_version = '@0@'.format(version)
> + version_map = '@0@/@1@/rte_@2@_version.map'.format(
> + meson.current_source_dir(), dir_name, name)
> +
> + if is_windows
> + version_map = '\\'.join(version_map.split('/'))
> + endif
As above.
> +
> + is_experimental = run_command(is_experimental_cmd,
> + files(version_map)).returncode()
> +
> + if is_experimental != 0
> + lib_version = '0.1'
> + so_version = '0'
> else
> lib_version = major_version
> so_version = major_version
> @@ -120,8 +130,6 @@ foreach l:libraries
> # then use pre-build objects to build shared lib
> sources = []
> objs += static_lib.extract_all_objects(recursive: false)
> - version_map = '@0@/@1@/rte_@2@_version.map'.format(
> - meson.current_source_dir(), dir_name, name)
> implib = dir_name + '.dll.a'
>
> def_file = custom_target(name + '_def',
> diff --git a/meson_options.txt b/meson_options.txt
> index 448f3e63dc..000e38fd98 100644
> --- a/meson_options.txt
> +++ b/meson_options.txt
> @@ -28,8 +28,6 @@ option('max_lcores', type: 'integer', value: 128,
> description: 'maximum number of cores/threads supported by EAL')
> option('max_numa_nodes', type: 'integer', value: 4,
> description: 'maximum number of NUMA nodes supported by EAL')
> -option('per_library_versions', type: 'boolean', value: true,
> - description: 'true: each lib gets its own version number, false: DPDK version used for each lib')
> option('tests', type: 'boolean', value: true,
> description: 'build unit tests')
> option('use_hpet', type: 'boolean', value: false,
> diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
> index 4df8849a08..f84161c6d5 100644
> --- a/mk/rte.lib.mk
> +++ b/mk/rte.lib.mk
> @@ -11,20 +11,23 @@ EXTLIB_BUILD ?= n
> # VPATH contains at least SRCDIR
> VPATH += $(SRCDIR)
>
> -ifneq ($(CONFIG_RTE_MAJOR_ABI),)
> -ifneq ($(LIBABIVER),)
> -LIBABIVER := $(CONFIG_RTE_MAJOR_ABI)
> +ifeq ($(OS), Windows_NT)
> +search_cmd = findstr
> +print_cmd = more
> +else
> +search_cmd = grep
> +print_cmd = cat
We don't support make on windows, so no need for using findstr.
> endif
> +
> +ifneq ($(shell $(search_cmd) "^DPDK_" $(SRCDIR)/$(EXPORT_MAP)),)
> +LIBABIVER := $(shell $(print_cmd) $(RTE_SRCDIR)/config/ABI_VERSION)
> +else
> +LIBABIVER := 0
> endif
>
> ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
> LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
> ifeq ($(EXTLIB_BUILD),n)
> -ifeq ($(CONFIG_RTE_MAJOR_ABI),)
> -ifeq ($(CONFIG_RTE_NEXT_ABI),y)
> -LIB := $(LIB).1
> -endif
> -endif
> CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
> endif
> endif
> --
> 2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 10/10] buildtools: add ABI versioning check script
` (11 preceding siblings ...)
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 09/10] build: change ABI version to 20.0 Anatoly Burakov
@ 2019-10-16 12:43 23% ` Anatoly Burakov
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, john.mcnamara, bruce.richardson, thomas,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
Add a shell script that checks whether built libraries are
versioned with expected ABI (current ABI, current ABI + 1,
or EXPERIMENTAL).
The following command was used to verify current source tree
(assuming build directory is in ./build):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to the end of the patchset
- Fixed bug when ABI symbols were not found because the .so
did not declare any public symbols
buildtools/check-abi-version.sh | 54 +++++++++++++++++++++++++++++++++
1 file changed, 54 insertions(+)
create mode 100755 buildtools/check-abi-version.sh
diff --git a/buildtools/check-abi-version.sh b/buildtools/check-abi-version.sh
new file mode 100755
index 0000000000..29aea97735
--- /dev/null
+++ b/buildtools/check-abi-version.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+# Check whether library symbols have correct
+# version (provided ABI number or provided ABI
+# number + 1 or EXPERIMENTAL).
+# Args:
+# $1: path of the library .so file
+# $2: ABI major version number to check
+# (defaults to ABI_VERSION file value)
+
+if [ -z "$1" ]; then
+ echo "Script checks whether library symbols have"
+ echo "correct version (ABI_VER/ABI_VER+1/EXPERIMENTAL)"
+ echo "Usage:"
+ echo " $0 SO_FILE_PATH [ABI_VER]"
+ exit 1
+fi
+
+LIB="$1"
+DEFAULT_ABI=$(cat "$(dirname \
+ $(readlink -f $0))/../config/ABI_VERSION" | \
+ cut -d'.' -f 1)
+ABIVER="DPDK_${2-$DEFAULT_ABI}"
+NEXT_ABIVER="DPDK_$((${2-$DEFAULT_ABI}+1))"
+
+ret=0
+
+# get output of objdump
+OBJ_DUMP_OUTPUT=`objdump -TC --section=.text ${LIB} 2>&1 | grep ".text"`
+
+# there may not be any .text sections in the .so file, in which case exit early
+echo "${OBJ_DUMP_OUTPUT}" | grep "not found in any input file" -q
+if [ "$?" -eq 0 ]; then
+ exit 0
+fi
+
+# we have symbols, so let's see if the versions are correct
+for SYM in `echo "${OBJ_DUMP_OUTPUT}" | awk '{print $(NF-1) "-" $NF}'`
+do
+ version=$(echo $SYM | cut -d'-' -f 1)
+ symbol=$(echo $SYM | cut -d'-' -f 2)
+ case $version in (*"$ABIVER"*|*"$NEXT_ABIVER"*|"EXPERIMENTAL")
+ ;;
+ (*)
+ echo "Warning: symbol $symbol ($version) should be annotated " \
+ "as ABI version $ABIVER / $NEXT_ABIVER, or EXPERIMENTAL."
+ ret=1
+ ;;
+ esac
+done
+
+exit $ret
--
2.17.1
^ permalink raw reply [relevance 23%]
* [dpdk-dev] [PATCH v2 08/10] drivers/octeontx: add missing public symbol
` (9 preceding siblings ...)
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 06/10] distributor: " Anatoly Burakov
@ 2019-10-16 12:43 3% ` Anatoly Burakov
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 09/10] build: change ABI version to 20.0 Anatoly Burakov
2019-10-16 12:43 23% ` [dpdk-dev] [PATCH v2 10/10] buildtools: add ABI versioning check script Anatoly Burakov
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Jerin Jacob, john.mcnamara, bruce.richardson, thomas,
david.marchand, pbhagavatula, stable
The logtype symbol was missing from the .map file. Add it.
Fixes: d8dd31652cf4 ("common/octeontx: move mbox to common folder")
Cc: pbhagavatula@caviumnetworks.com
Cc: stable@dpdk.org
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- add this patch to avoid compile breakage when bumping ABI
drivers/common/octeontx/rte_common_octeontx_version.map | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/common/octeontx/rte_common_octeontx_version.map b/drivers/common/octeontx/rte_common_octeontx_version.map
index f04b3b7f8a..a9b3cff9bc 100644
--- a/drivers/common/octeontx/rte_common_octeontx_version.map
+++ b/drivers/common/octeontx/rte_common_octeontx_version.map
@@ -1,6 +1,7 @@
DPDK_18.05 {
global:
+ octeontx_logtype_mbox;
octeontx_mbox_set_ram_mbox_base;
octeontx_mbox_set_reg;
octeontx_mbox_send;
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 06/10] distributor: remove deprecated code
` (8 preceding siblings ...)
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 05/10] lpm: " Anatoly Burakov
@ 2019-10-16 12:43 4% ` Anatoly Burakov
2019-10-16 12:43 3% ` [dpdk-dev] [PATCH v2 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
` (2 subsequent siblings)
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, David Hunt, john.mcnamara, bruce.richardson,
thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_distributor/rte_distributor.c | 56 +++--------------
.../rte_distributor_v1705.h | 61 -------------------
2 files changed, 9 insertions(+), 108 deletions(-)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index 21eb1fb0a1..ca3f21b833 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -19,7 +19,6 @@
#include "rte_distributor_private.h"
#include "rte_distributor.h"
#include "rte_distributor_v20.h"
-#include "rte_distributor_v1705.h"
TAILQ_HEAD(rte_dist_burst_list, rte_distributor);
@@ -33,7 +32,7 @@ EAL_REGISTER_TAILQ(rte_dist_burst_tailq)
/**** Burst Packet APIs called by workers ****/
void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
+rte_distributor_request_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt,
unsigned int count)
{
@@ -78,14 +77,9 @@ rte_distributor_request_pkt_v1705(struct rte_distributor *d,
*/
*retptr64 |= RTE_DISTRIB_GET_BUF;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_request_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_request_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count),
- rte_distributor_request_pkt_v1705);
int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
+rte_distributor_poll_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -119,13 +113,9 @@ rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_poll_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_poll_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts),
- rte_distributor_poll_pkt_v1705);
int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
+rte_distributor_get_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts,
struct rte_mbuf **oldpkt, unsigned int return_count)
{
@@ -153,14 +143,9 @@ rte_distributor_get_pkt_v1705(struct rte_distributor *d,
}
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_get_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_get_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int return_count),
- rte_distributor_get_pkt_v1705);
int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
+rte_distributor_return_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt, int num)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -187,10 +172,6 @@ rte_distributor_return_pkt_v1705(struct rte_distributor *d,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_return_pkt, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_return_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num),
- rte_distributor_return_pkt_v1705);
/**** APIs called on distributor core ***/
@@ -336,7 +317,7 @@ release(struct rte_distributor *d, unsigned int wkr)
/* process a set of packets to distribute them to workers */
int
-rte_distributor_process_v1705(struct rte_distributor *d,
+rte_distributor_process(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int num_mbufs)
{
unsigned int next_idx = 0;
@@ -470,14 +451,10 @@ rte_distributor_process_v1705(struct rte_distributor *d,
return num_mbufs;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_process, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_process(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs),
- rte_distributor_process_v1705);
/* return to the caller, packets returned from workers */
int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
+rte_distributor_returned_pkts(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int max_mbufs)
{
struct rte_distributor_returned_pkts *returns = &d->returns;
@@ -502,10 +479,6 @@ rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
return retval;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_returned_pkts, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_returned_pkts(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs),
- rte_distributor_returned_pkts_v1705);
/*
* Return the number of packets in-flight in a distributor, i.e. packets
@@ -527,7 +500,7 @@ total_outstanding(const struct rte_distributor *d)
* queued up.
*/
int
-rte_distributor_flush_v1705(struct rte_distributor *d)
+rte_distributor_flush(struct rte_distributor *d)
{
unsigned int flushed;
unsigned int wkr;
@@ -556,13 +529,10 @@ rte_distributor_flush_v1705(struct rte_distributor *d)
return flushed;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_flush, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_distributor_flush(struct rte_distributor *d),
- rte_distributor_flush_v1705);
/* clears the internal returns array in the distributor */
void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d)
+rte_distributor_clear_returns(struct rte_distributor *d)
{
unsigned int wkr;
@@ -576,13 +546,10 @@ rte_distributor_clear_returns_v1705(struct rte_distributor *d)
for (wkr = 0; wkr < d->num_workers; wkr++)
d->bufs[wkr].retptr64[0] = 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_clear_returns, _v1705, 17.05);
-MAP_STATIC_SYMBOL(void rte_distributor_clear_returns(struct rte_distributor *d),
- rte_distributor_clear_returns_v1705);
/* creates a distributor instance */
struct rte_distributor *
-rte_distributor_create_v1705(const char *name,
+rte_distributor_create(const char *name,
unsigned int socket_id,
unsigned int num_workers,
unsigned int alg_type)
@@ -656,8 +623,3 @@ rte_distributor_create_v1705(const char *name,
return d;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_create, _v1705, 17.05);
-MAP_STATIC_SYMBOL(struct rte_distributor *rte_distributor_create(
- const char *name, unsigned int socket_id,
- unsigned int num_workers, unsigned int alg_type),
- rte_distributor_create_v1705);
diff --git a/lib/librte_distributor/rte_distributor_v1705.h b/lib/librte_distributor/rte_distributor_v1705.h
deleted file mode 100644
index df4d9e8150..0000000000
--- a/lib/librte_distributor/rte_distributor_v1705.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017 Intel Corporation
- */
-
-#ifndef _RTE_DISTRIB_V1705_H_
-#define _RTE_DISTRIB_V1705_H_
-
-/**
- * @file
- * RTE distributor
- *
- * The distributor is a component which is designed to pass packets
- * one-at-a-time to workers, with dynamic load balancing.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_distributor *
-rte_distributor_create_v1705(const char *name, unsigned int socket_id,
- unsigned int num_workers,
- unsigned int alg_type);
-
-int
-rte_distributor_process_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs);
-
-int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs);
-
-int
-rte_distributor_flush_v1705(struct rte_distributor *d);
-
-void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d);
-
-int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int retcount);
-
-int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
-
-void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count);
-
-int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **mbufs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 05/10] lpm: remove deprecated code
` (7 preceding siblings ...)
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 04/10] timer: remove deprecated code Anatoly Burakov
@ 2019-10-16 12:43 2% ` Anatoly Burakov
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 06/10] distributor: " Anatoly Burakov
` (3 subsequent siblings)
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Bruce Richardson, Vladimir Medvedkin,
john.mcnamara, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_lpm/rte_lpm.c | 996 ++------------------------------------
lib/librte_lpm/rte_lpm.h | 88 ----
lib/librte_lpm/rte_lpm6.c | 132 +----
lib/librte_lpm/rte_lpm6.h | 25 -
4 files changed, 48 insertions(+), 1193 deletions(-)
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 3a929a1b16..2687564194 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -89,34 +89,8 @@ depth_to_range(uint8_t depth)
/*
* Find an existing lpm table and return a pointer to it.
*/
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name)
-{
- struct rte_lpm_v20 *l = NULL;
- struct rte_tailq_entry *te;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_read_lock();
- TAILQ_FOREACH(te, lpm_list, next) {
- l = te->data;
- if (strncmp(name, l->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
- rte_mcfg_tailq_read_unlock();
-
- if (te == NULL) {
- rte_errno = ENOENT;
- return NULL;
- }
-
- return l;
-}
-VERSION_SYMBOL(rte_lpm_find_existing, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name)
+rte_lpm_find_existing(const char *name)
{
struct rte_lpm *l = NULL;
struct rte_tailq_entry *te;
@@ -139,88 +113,12 @@ rte_lpm_find_existing_v1604(const char *name)
return l;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_find_existing, _v1604, 16.04);
-MAP_STATIC_SYMBOL(struct rte_lpm *rte_lpm_find_existing(const char *name),
- rte_lpm_find_existing_v1604);
/*
* Allocates memory for LPM object
*/
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
-{
- char mem_name[RTE_LPM_NAMESIZE];
- struct rte_lpm_v20 *lpm = NULL;
- struct rte_tailq_entry *te;
- uint32_t mem_size;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry_v20) != 2);
-
- /* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
-
- /* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
-
- rte_mcfg_tailq_write_lock();
-
- /* guarantee there's no existing */
- TAILQ_FOREACH(te, lpm_list, next) {
- lpm = te->data;
- if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
-
- if (te != NULL) {
- lpm = NULL;
- rte_errno = EEXIST;
- goto exit;
- }
-
- /* allocate tailq entry */
- te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0);
- if (te == NULL) {
- RTE_LOG(ERR, LPM, "Failed to allocate tailq entry\n");
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Allocate memory to store the LPM data structures. */
- lpm = rte_zmalloc_socket(mem_name, mem_size,
- RTE_CACHE_LINE_SIZE, socket_id);
- if (lpm == NULL) {
- RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
- rte_free(te);
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Save user arguments. */
- lpm->max_rules = max_rules;
- strlcpy(lpm->name, name, sizeof(lpm->name));
-
- te->data = lpm;
-
- TAILQ_INSERT_TAIL(lpm_list, te, next);
-
-exit:
- rte_mcfg_tailq_write_unlock();
-
- return lpm;
-}
-VERSION_SYMBOL(rte_lpm_create, _v20, 2.0);
-
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
+rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
@@ -320,45 +218,12 @@ rte_lpm_create_v1604(const char *name, int socket_id,
return lpm;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 16.04);
-MAP_STATIC_SYMBOL(
- struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
*/
void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm)
-{
- struct rte_lpm_list *lpm_list;
- struct rte_tailq_entry *te;
-
- /* Check user arguments. */
- if (lpm == NULL)
- return;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_write_lock();
-
- /* find our tailq entry */
- TAILQ_FOREACH(te, lpm_list, next) {
- if (te->data == (void *) lpm)
- break;
- }
- if (te != NULL)
- TAILQ_REMOVE(lpm_list, te, next);
-
- rte_mcfg_tailq_write_unlock();
-
- rte_free(lpm);
- rte_free(te);
-}
-VERSION_SYMBOL(rte_lpm_free, _v20, 2.0);
-
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm)
+rte_lpm_free(struct rte_lpm *lpm)
{
struct rte_lpm_list *lpm_list;
struct rte_tailq_entry *te;
@@ -386,9 +251,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
rte_free(lpm);
rte_free(te);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
- rte_lpm_free_v1604);
/*
* Adds a rule to the rule table.
@@ -401,79 +263,7 @@ MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t rule_gindex, rule_index, last_rule;
- int i;
-
- VERIFY_DEPTH(depth);
-
- /* Scan through rule group to see if rule already exists. */
- if (lpm->rule_info[depth - 1].used_rules > 0) {
-
- /* rule_gindex stands for rule group index. */
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- /* Initialise rule_index to point to start of rule group. */
- rule_index = rule_gindex;
- /* Last rule = Last used rule in this rule group. */
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- for (; rule_index < last_rule; rule_index++) {
-
- /* If rule already exists update its next_hop and return. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked) {
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- return rule_index;
- }
- }
-
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
- } else {
- /* Calculate the position in which the rule will be stored. */
- rule_index = 0;
-
- for (i = depth - 1; i > 0; i--) {
- if (lpm->rule_info[i - 1].used_rules > 0) {
- rule_index = lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules;
- break;
- }
- }
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
-
- lpm->rule_info[depth - 1].first_rule = rule_index;
- }
-
- /* Make room for the new rule in the array. */
- for (i = RTE_LPM_MAX_DEPTH; i > depth; i--) {
- if (lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules == lpm->max_rules)
- return -ENOSPC;
-
- if (lpm->rule_info[i - 1].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules]
- = lpm->rules_tbl[lpm->rule_info[i - 1].first_rule];
- lpm->rule_info[i - 1].first_rule++;
- }
- }
-
- /* Add the new rule. */
- lpm->rules_tbl[rule_index].ip = ip_masked;
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- /* Increment the used rules counter for this rule group. */
- lpm->rule_info[depth - 1].used_rules++;
-
- return rule_index;
-}
-
-static int32_t
-rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+rule_add(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
uint32_t rule_gindex, rule_index, last_rule;
@@ -549,30 +339,7 @@ rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static void
-rule_delete_v20(struct rte_lpm_v20 *lpm, int32_t rule_index, uint8_t depth)
-{
- int i;
-
- VERIFY_DEPTH(depth);
-
- lpm->rules_tbl[rule_index] =
- lpm->rules_tbl[lpm->rule_info[depth - 1].first_rule
- + lpm->rule_info[depth - 1].used_rules - 1];
-
- for (i = depth; i < RTE_LPM_MAX_DEPTH; i++) {
- if (lpm->rule_info[i].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i].first_rule - 1] =
- lpm->rules_tbl[lpm->rule_info[i].first_rule
- + lpm->rule_info[i].used_rules - 1];
- lpm->rule_info[i].first_rule--;
- }
- }
-
- lpm->rule_info[depth - 1].used_rules--;
-}
-
-static void
-rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
+rule_delete(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
{
int i;
@@ -599,28 +366,7 @@ rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_find_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth)
-{
- uint32_t rule_gindex, last_rule, rule_index;
-
- VERIFY_DEPTH(depth);
-
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- /* Scan used rules at given depth to find rule. */
- for (rule_index = rule_gindex; rule_index < last_rule; rule_index++) {
- /* If rule is found return the rule index. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked)
- return rule_index;
- }
-
- /* If rule is not found return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
+rule_find(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
{
uint32_t rule_gindex, last_rule, rule_index;
@@ -644,42 +390,7 @@ rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
* Find, clean and allocate a tbl8.
*/
static int32_t
-tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
-{
- uint32_t group_idx; /* tbl8 group index. */
- struct rte_lpm_tbl_entry_v20 *tbl8_entry;
-
- /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
- tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
- /* If a free tbl8 group is found clean it and set as VALID. */
- if (!tbl8_entry->valid_group) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = VALID,
- };
- new_tbl8_entry.next_hop = 0;
-
- memset(&tbl8_entry[0], 0,
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES *
- sizeof(tbl8_entry[0]));
-
- __atomic_store(tbl8_entry, &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- /* Return group index for allocated tbl8 group. */
- return group_idx;
- }
- }
-
- /* If there are no tbl8 groups free then return error. */
- return -ENOSPC;
-}
-
-static int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
+tbl8_alloc(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
@@ -713,22 +424,7 @@ tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
}
static void
-tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start)
-{
- /* Set tbl8 group invalid*/
- struct rte_lpm_tbl_entry_v20 zero_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = INVALID,
- };
- zero_tbl8_entry.next_hop = 0;
-
- __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
- __ATOMIC_RELAXED);
-}
-
-static void
-tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
+tbl8_free(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
{
/* Set tbl8 group invalid*/
struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
@@ -738,78 +434,7 @@ tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
}
static __rte_noinline int32_t
-add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index, tbl24_range, tbl8_index, tbl8_group_end, i, j;
-
- /* Calculate the index into Table24. */
- tbl24_index = ip >> 8;
- tbl24_range = depth_to_range(depth);
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
- /*
- * For invalid OR valid and non-extended tbl 24 entries set
- * entry.
- */
- if (!lpm->tbl24[i].valid || (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth)) {
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .valid = VALID,
- .valid_group = 0,
- .depth = depth,
- };
- new_tbl24_entry.next_hop = next_hop;
-
- /* Setting tbl24 entry in one go to avoid race
- * conditions
- */
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- continue;
- }
-
- if (lpm->tbl24[i].valid_group == 1) {
- /* If tbl24 entry is valid and extended calculate the
- * index into tbl8.
- */
- tbl8_index = lpm->tbl24[i].group_idx *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < tbl8_group_end; j++) {
- if (!lpm->tbl8[j].valid ||
- lpm->tbl8[j].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = depth,
- };
- new_tbl8_entry.next_hop = next_hop;
-
- /*
- * Setting tbl8 entry in one go to avoid
- * race conditions
- */
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+add_depth_small(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -881,150 +506,7 @@ add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
static __rte_noinline int32_t
-add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index;
- int32_t tbl8_group_index, tbl8_group_start, tbl8_group_end, tbl8_index,
- tbl8_range, i;
-
- tbl24_index = (ip_masked >> 8);
- tbl8_range = depth_to_range(depth);
-
- if (!lpm->tbl24[tbl24_index].valid) {
- /* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- /* Check tbl8 allocation was successful. */
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- /* Find index into tbl8 and range. */
- tbl8_index = (tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES) +
- (ip_masked & 0xFF);
-
- /* Set tbl8 entry. */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } /* If valid entry but not extended calculate the index into Table8. */
- else if (lpm->tbl24[tbl24_index].valid_group == 0) {
- /* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_group_start +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /* Populate new tbl8 with tbl24 value. */
- for (i = tbl8_group_start; i < tbl8_group_end; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = lpm->tbl24[tbl24_index].depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop =
- lpm->tbl24[tbl24_index].next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- /* Insert new rule into the tbl8 entry. */
- for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } else { /*
- * If it is valid, extended entry calculate the index into tbl8.
- */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
-
- if (!lpm->tbl8[i].valid ||
- lpm->tbl8[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- /*
- * Setting tbl8 entry in one go to avoid race
- * condition
- */
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+add_depth_big(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -1037,7 +519,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1083,7 +565,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1177,48 +659,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* Add a route
*/
int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- int32_t rule_index, status = 0;
- uint32_t ip_masked;
-
- /* Check user arguments. */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- ip_masked = ip & depth_to_mask(depth);
-
- /* Add the rule to the rule table. */
- rule_index = rule_add_v20(lpm, ip_masked, depth, next_hop);
-
- /* If the is no space available for new rule return error. */
- if (rule_index < 0) {
- return rule_index;
- }
-
- if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v20(lpm, ip_masked, depth, next_hop);
- } else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v20(lpm, ip_masked, depth, next_hop);
-
- /*
- * If add fails due to exhaustion of tbl8 extensions delete
- * rule that was added to rule table.
- */
- if (status < 0) {
- rule_delete_v20(lpm, rule_index, depth);
-
- return status;
- }
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_add, _v20, 2.0);
-
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
int32_t rule_index, status = 0;
@@ -1231,7 +672,7 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
ip_masked = ip & depth_to_mask(depth);
/* Add the rule to the rule table. */
- rule_index = rule_add_v1604(lpm, ip_masked, depth, next_hop);
+ rule_index = rule_add(lpm, ip_masked, depth, next_hop);
/* If the is no space available for new rule return error. */
if (rule_index < 0) {
@@ -1239,16 +680,16 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_small(lpm, ip_masked, depth, next_hop);
} else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_big(lpm, ip_masked, depth, next_hop);
/*
* If add fails due to exhaustion of tbl8 extensions delete
* rule that was added to rule table.
*/
if (status < 0) {
- rule_delete_v1604(lpm, rule_index, depth);
+ rule_delete(lpm, rule_index, depth);
return status;
}
@@ -1256,42 +697,12 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_add, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_add(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t next_hop), rte_lpm_add_v1604);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop)
-{
- uint32_t ip_masked;
- int32_t rule_index;
-
- /* Check user arguments. */
- if ((lpm == NULL) ||
- (next_hop == NULL) ||
- (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- /* Look for the rule using rule_find. */
- ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v20(lpm, ip_masked, depth);
-
- if (rule_index >= 0) {
- *next_hop = lpm->rules_tbl[rule_index].next_hop;
- return 1;
- }
-
- /* If rule is not found return 0. */
- return 0;
-}
-VERSION_SYMBOL(rte_lpm_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop)
{
uint32_t ip_masked;
@@ -1305,7 +716,7 @@ uint32_t *next_hop)
/* Look for the rule using rule_find. */
ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v1604(lpm, ip_masked, depth);
+ rule_index = rule_find(lpm, ip_masked, depth);
if (rule_index >= 0) {
*next_hop = lpm->rules_tbl[rule_index].next_hop;
@@ -1315,12 +726,9 @@ uint32_t *next_hop)
/* If rule is not found return 0. */
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_is_rule_present, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t *next_hop), rte_lpm_is_rule_present_v1604);
static int32_t
-find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
+find_previous_rule(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint8_t *sub_rule_depth)
{
int32_t rule_index;
@@ -1330,7 +738,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
ip_masked = ip & depth_to_mask(prev_depth);
- rule_index = rule_find_v20(lpm, ip_masked, prev_depth);
+ rule_index = rule_find(lpm, ip_masked, prev_depth);
if (rule_index >= 0) {
*sub_rule_depth = prev_depth;
@@ -1342,133 +750,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
}
static int32_t
-find_previous_rule_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint8_t *sub_rule_depth)
-{
- int32_t rule_index;
- uint32_t ip_masked;
- uint8_t prev_depth;
-
- for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
- ip_masked = ip & depth_to_mask(prev_depth);
-
- rule_index = rule_find_v1604(lpm, ip_masked, prev_depth);
-
- if (rule_index >= 0) {
- *sub_rule_depth = prev_depth;
- return rule_index;
- }
- }
-
- return -1;
-}
-
-static int32_t
-delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_range, tbl24_index, tbl8_group_index, tbl8_index, i, j;
-
- /* Calculate the range and index into Table24. */
- tbl24_range = depth_to_range(depth);
- tbl24_index = (ip_masked >> 8);
-
- /*
- * Firstly check the sub_rule_index. A -1 indicates no replacement rule
- * and a positive number indicates a sub_rule_index.
- */
- if (sub_rule_index < 0) {
- /*
- * If no replacement rule exists then invalidate entries
- * associated with this rule.
- */
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- zero_tbl24_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = 0,
- };
- zero_tbl24_entry.next_hop = 0;
- __atomic_store(&lpm->tbl24[i],
- &zero_tbl24_entry, __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- lpm->tbl8[j].valid = INVALID;
- }
- }
- }
- } else {
- /*
- * If a replacement rule exists then modify entries
- * associated with this rule.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->rules_tbl[sub_rule_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = sub_rule_depth,
- };
-
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = sub_rule_depth,
- };
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1575,7 +857,7 @@ delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* thus can be recycled
*/
static int32_t
-tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
+tbl8_recycle_check(struct rte_lpm_tbl_entry *tbl8,
uint32_t tbl8_group_start)
{
uint32_t tbl8_group_end, i;
@@ -1622,140 +904,7 @@ tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
}
static int32_t
-tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
- uint32_t tbl8_group_start)
-{
- uint32_t tbl8_group_end, i;
- tbl8_group_end = tbl8_group_start + RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /*
- * Check the first entry of the given tbl8. If it is invalid we know
- * this tbl8 does not contain any rule with a depth < RTE_LPM_MAX_DEPTH
- * (As they would affect all entries in a tbl8) and thus this table
- * can not be recycled.
- */
- if (tbl8[tbl8_group_start].valid) {
- /*
- * If first entry is valid check if the depth is less than 24
- * and if so check the rest of the entries to verify that they
- * are all of this depth.
- */
- if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
- for (i = (tbl8_group_start + 1); i < tbl8_group_end;
- i++) {
-
- if (tbl8[i].depth !=
- tbl8[tbl8_group_start].depth) {
-
- return -EEXIST;
- }
- }
- /* If all entries are the same return the tb8 index */
- return tbl8_group_start;
- }
-
- return -EEXIST;
- }
- /*
- * If the first entry is invalid check if the rest of the entries in
- * the tbl8 are invalid.
- */
- for (i = (tbl8_group_start + 1); i < tbl8_group_end; i++) {
- if (tbl8[i].valid)
- return -EEXIST;
- }
- /* If no valid entries are found then return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_index, tbl8_group_index, tbl8_group_start, tbl8_index,
- tbl8_range, i;
- int32_t tbl8_recycle_index;
-
- /*
- * Calculate the index into tbl24 and range. Note: All depths larger
- * than MAX_DEPTH_TBL24 are associated with only one tbl24 entry.
- */
- tbl24_index = ip_masked >> 8;
-
- /* Calculate the index into tbl8 and range. */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
- tbl8_range = depth_to_range(depth);
-
- if (sub_rule_index < 0) {
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be removed or modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- lpm->tbl8[i].valid = INVALID;
- }
- } else {
- /* Set new tbl8 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = sub_rule_depth,
- .valid_group = lpm->tbl8[tbl8_group_start].valid_group,
- };
-
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
-
- /*
- * Check if there are any valid entries in this tbl8 group. If all
- * tbl8 entries are invalid we can free the tbl8 and invalidate the
- * associated tbl24 entry.
- */
-
- tbl8_recycle_index = tbl8_recycle_check_v20(lpm->tbl8, tbl8_group_start);
-
- if (tbl8_recycle_index == -EINVAL) {
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- lpm->tbl24[tbl24_index].valid = 0;
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- } else if (tbl8_recycle_index > -1) {
- /* Update tbl24 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = lpm->tbl8[tbl8_recycle_index].depth,
- };
-
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELAXED);
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_big(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1810,7 +959,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* associated tbl24 entry.
*/
- tbl8_recycle_index = tbl8_recycle_check_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_recycle_index = tbl8_recycle_check(lpm->tbl8, tbl8_group_start);
if (tbl8_recycle_index == -EINVAL) {
/* Set tbl24 before freeing tbl8 to avoid race condition.
@@ -1818,7 +967,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
*/
lpm->tbl24[tbl24_index].valid = 0;
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
} else if (tbl8_recycle_index > -1) {
/* Update tbl24 entry. */
struct rte_lpm_tbl_entry new_tbl24_entry = {
@@ -1834,7 +983,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
__atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
__ATOMIC_RELAXED);
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
}
#undef group_idx
return 0;
@@ -1844,7 +993,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* Deletes a rule
*/
int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
+rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
{
int32_t rule_to_delete_index, sub_rule_index;
uint32_t ip_masked;
@@ -1863,7 +1012,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* Find the index of the input rule, that needs to be deleted, in the
* rule table.
*/
- rule_to_delete_index = rule_find_v20(lpm, ip_masked, depth);
+ rule_to_delete_index = rule_find(lpm, ip_masked, depth);
/*
* Check if rule_to_delete_index was found. If no rule was found the
@@ -1873,7 +1022,7 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
return -EINVAL;
/* Delete the rule from the rule table. */
- rule_delete_v20(lpm, rule_to_delete_index, depth);
+ rule_delete(lpm, rule_to_delete_index, depth);
/*
* Find rule to replace the rule_to_delete. If there is no rule to
@@ -1881,100 +1030,26 @@ rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
* entries associated with this rule.
*/
sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v20(lpm, ip, depth, &sub_rule_depth);
+ sub_rule_index = find_previous_rule(lpm, ip, depth, &sub_rule_depth);
/*
* If the input depth value is less than 25 use function
* delete_depth_small otherwise use delete_depth_big.
*/
if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v20(lpm, ip_masked, depth,
+ return delete_depth_small(lpm, ip_masked, depth,
sub_rule_index, sub_rule_depth);
} else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v20(lpm, ip_masked, depth, sub_rule_index,
+ return delete_depth_big(lpm, ip_masked, depth, sub_rule_index,
sub_rule_depth);
}
}
-VERSION_SYMBOL(rte_lpm_delete, _v20, 2.0);
-
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
-{
- int32_t rule_to_delete_index, sub_rule_index;
- uint32_t ip_masked;
- uint8_t sub_rule_depth;
- /*
- * Check input arguments. Note: IP must be a positive integer of 32
- * bits in length therefore it need not be checked.
- */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH)) {
- return -EINVAL;
- }
-
- ip_masked = ip & depth_to_mask(depth);
-
- /*
- * Find the index of the input rule, that needs to be deleted, in the
- * rule table.
- */
- rule_to_delete_index = rule_find_v1604(lpm, ip_masked, depth);
-
- /*
- * Check if rule_to_delete_index was found. If no rule was found the
- * function rule_find returns -EINVAL.
- */
- if (rule_to_delete_index < 0)
- return -EINVAL;
-
- /* Delete the rule from the rule table. */
- rule_delete_v1604(lpm, rule_to_delete_index, depth);
-
- /*
- * Find rule to replace the rule_to_delete. If there is no rule to
- * replace the rule_to_delete we return -1 and invalidate the table
- * entries associated with this rule.
- */
- sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v1604(lpm, ip, depth, &sub_rule_depth);
-
- /*
- * If the input depth value is less than 25 use function
- * delete_depth_small otherwise use delete_depth_big.
- */
- if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v1604(lpm, ip_masked, depth,
- sub_rule_index, sub_rule_depth);
- } else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v1604(lpm, ip_masked, depth, sub_rule_index,
- sub_rule_depth);
- }
-}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete, _v1604, 16.04);
-MAP_STATIC_SYMBOL(int rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth), rte_lpm_delete_v1604);
/*
* Delete all rules from the LPM table.
*/
void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm)
-{
- /* Zero rule information. */
- memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
-
- /* Zero tbl24. */
- memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
-
- /* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
-
- /* Delete all rules form the rules table. */
- memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
-}
-VERSION_SYMBOL(rte_lpm_delete_all, _v20, 2.0);
-
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
+rte_lpm_delete_all(struct rte_lpm *lpm)
{
/* Zero rule information. */
memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
@@ -1989,6 +1064,3 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete_all, _v1604, 16.04);
-MAP_STATIC_SYMBOL(void rte_lpm_delete_all(struct rte_lpm *lpm),
- rte_lpm_delete_all_v1604);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index 906ec44830..ca9627a141 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -65,31 +65,6 @@ extern "C" {
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- /**
- * Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
- * a group index pointing to a tbl8 structure (tbl24 only, when
- * valid_group is set)
- */
- RTE_STD_C11
- union {
- uint8_t next_hop;
- uint8_t group_idx;
- };
- /* Using single uint8_t to store 3 values. */
- uint8_t valid :1; /**< Validation flag. */
- /**
- * For tbl24:
- * - valid_group == 0: entry stores a next hop
- * - valid_group == 1: entry stores a group_index pointing to a tbl8
- * For tbl8:
- * - valid_group indicates whether the current tbl8 is in use or not
- */
- uint8_t valid_group :1;
- uint8_t depth :6; /**< Rule depth. */
-} __rte_aligned(sizeof(uint16_t));
-
__extension__
struct rte_lpm_tbl_entry {
/**
@@ -112,16 +87,6 @@ struct rte_lpm_tbl_entry {
};
#else
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- uint8_t depth :6;
- uint8_t valid_group :1;
- uint8_t valid :1;
- union {
- uint8_t group_idx;
- uint8_t next_hop;
- };
-} __rte_aligned(sizeof(uint16_t));
__extension__
struct rte_lpm_tbl_entry {
@@ -142,11 +107,6 @@ struct rte_lpm_config {
};
/** @internal Rule structure. */
-struct rte_lpm_rule_v20 {
- uint32_t ip; /**< Rule IP address. */
- uint8_t next_hop; /**< Rule next hop. */
-};
-
struct rte_lpm_rule {
uint32_t ip; /**< Rule IP address. */
uint32_t next_hop; /**< Rule next hop. */
@@ -159,21 +119,6 @@ struct rte_lpm_rule_info {
};
/** @internal LPM structure. */
-struct rte_lpm_v20 {
- /* LPM metadata. */
- char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
- uint32_t max_rules; /**< Max. balanced rules per lpm. */
- struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
-
- /* LPM Tables. */
- struct rte_lpm_tbl_entry_v20 tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry_v20 tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule_v20 rules_tbl[]
- __rte_cache_aligned; /**< LPM rules. */
-};
-
struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
@@ -210,11 +155,6 @@ struct rte_lpm {
struct rte_lpm *
rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config);
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
-struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
- const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
@@ -228,10 +168,6 @@ rte_lpm_create_v1604(const char *name, int socket_id,
*/
struct rte_lpm *
rte_lpm_find_existing(const char *name);
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name);
-struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name);
/**
* Free an LPM object.
@@ -243,10 +179,6 @@ rte_lpm_find_existing_v1604(const char *name);
*/
void
rte_lpm_free(struct rte_lpm *lpm);
-void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm);
/**
* Add a rule to the LPM table.
@@ -264,12 +196,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm);
*/
int
rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop);
-int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -289,12 +215,6 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
int
rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop);
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
-uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -310,10 +230,6 @@ uint32_t *next_hop);
*/
int
rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
/**
* Delete all rules from the LPM table.
@@ -323,10 +239,6 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
*/
void
rte_lpm_delete_all(struct rte_lpm *lpm);
-void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm);
/**
* Lookup an IP into the LPM table.
diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c
index 9b8aeb9721..b981e40714 100644
--- a/lib/librte_lpm/rte_lpm6.c
+++ b/lib/librte_lpm/rte_lpm6.c
@@ -808,18 +808,6 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
return 1;
}
-/*
- * Add a route
- */
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop)
-{
- return rte_lpm6_add_v1705(lpm, ip, depth, next_hop);
-}
-VERSION_SYMBOL(rte_lpm6_add, _v20, 2.0);
-
-
/*
* Simulate adding a route to LPM
*
@@ -841,7 +829,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
/* Inspect the first three bytes through tbl24 on the first step. */
ret = simulate_add_step(lpm, lpm->tbl24, &tbl_next, masked_ip,
- ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
+ ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
total_need_tbl_nb = need_tbl_nb;
/*
* Inspect one by one the rest of the bytes until
@@ -850,7 +838,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && ret == 1; i++) {
tbl = tbl_next;
ret = simulate_add_step(lpm, tbl, &tbl_next, masked_ip, 1,
- (uint8_t)(i+1), depth, &need_tbl_nb);
+ (uint8_t)(i + 1), depth, &need_tbl_nb);
total_need_tbl_nb += need_tbl_nb;
}
@@ -861,9 +849,12 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
return 0;
}
+/*
+ * Add a route
+ */
int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop)
+rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+ uint32_t next_hop)
{
struct rte_lpm6_tbl_entry *tbl;
struct rte_lpm6_tbl_entry *tbl_next = NULL;
@@ -895,8 +886,8 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
/* Inspect the first three bytes through tbl24 on the first step. */
tbl = lpm->tbl24;
status = add_step(lpm, tbl, TBL24_IND, &tbl_next, &tbl_next_num,
- masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
- is_new_rule);
+ masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
+ is_new_rule);
assert(status >= 0);
/*
@@ -906,17 +897,13 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && status == 1; i++) {
tbl = tbl_next;
status = add_step(lpm, tbl, tbl_next_num, &tbl_next,
- &tbl_next_num, masked_ip, 1, (uint8_t)(i+1),
- depth, next_hop, is_new_rule);
+ &tbl_next_num, masked_ip, 1, (uint8_t)(i + 1),
+ depth, next_hop, is_new_rule);
assert(status >= 0);
}
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_add, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip,
- uint8_t depth, uint32_t next_hop),
- rte_lpm6_add_v1705);
/*
* Takes a pointer to a table entry and inspect one level.
@@ -955,25 +942,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl,
* Looks up an IP
*/
int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_lookup_v1705(lpm, ip, &next_hop32);
- if (status == 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-}
-VERSION_SYMBOL(rte_lpm6_lookup, _v20, 2.0);
-
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
+rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
uint32_t *next_hop)
{
const struct rte_lpm6_tbl_entry *tbl;
@@ -1000,56 +969,12 @@ rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop), rte_lpm6_lookup_v1705);
/*
* Looks up a group of IP addresses
*/
int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t * next_hops, unsigned n)
-{
- unsigned i;
- const struct rte_lpm6_tbl_entry *tbl;
- const struct rte_lpm6_tbl_entry *tbl_next = NULL;
- uint32_t tbl24_index, next_hop;
- uint8_t first_byte;
- int status;
-
- /* DEBUG: Check user input arguments. */
- if ((lpm == NULL) || (ips == NULL) || (next_hops == NULL))
- return -EINVAL;
-
- for (i = 0; i < n; i++) {
- first_byte = LOOKUP_FIRST_BYTE;
- tbl24_index = (ips[i][0] << BYTES2_SIZE) |
- (ips[i][1] << BYTE_SIZE) | ips[i][2];
-
- /* Calculate pointer to the first entry to be inspected */
- tbl = &lpm->tbl24[tbl24_index];
-
- do {
- /* Continue inspecting following levels until success or failure */
- status = lookup_step(lpm, tbl, &tbl_next, ips[i], first_byte++,
- &next_hop);
- tbl = tbl_next;
- } while (status == 1);
-
- if (status < 0)
- next_hops[i] = -1;
- else
- next_hops[i] = (int16_t)next_hop;
- }
-
- return 0;
-}
-VERSION_SYMBOL(rte_lpm6_lookup_bulk_func, _v20, 2.0);
-
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
+rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n)
{
@@ -1089,37 +1014,12 @@ rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup_bulk_func, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n),
- rte_lpm6_lookup_bulk_func_v1705);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_is_rule_present_v1705(lpm, ip, depth, &next_hop32);
- if (status > 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-
-}
-VERSION_SYMBOL(rte_lpm6_is_rule_present, _v20, 2.0);
-
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop)
{
uint8_t masked_ip[RTE_LPM6_IPV6_ADDR_SIZE];
@@ -1135,10 +1035,6 @@ rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
return rule_find(lpm, masked_ip, depth, next_hop);
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_is_rule_present, _v1705, 17.05);
-MAP_STATIC_SYMBOL(int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm,
- uint8_t *ip, uint8_t depth, uint32_t *next_hop),
- rte_lpm6_is_rule_present_v1705);
/*
* Delete a rule from the rule table.
diff --git a/lib/librte_lpm/rte_lpm6.h b/lib/librte_lpm/rte_lpm6.h
index 5d59ccb1fe..37dfb20249 100644
--- a/lib/librte_lpm/rte_lpm6.h
+++ b/lib/librte_lpm/rte_lpm6.h
@@ -96,12 +96,6 @@ rte_lpm6_free(struct rte_lpm6 *lpm);
int
rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t next_hop);
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -121,12 +115,6 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
int
rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop);
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -184,11 +172,6 @@ rte_lpm6_delete_all(struct rte_lpm6 *lpm);
*/
int
rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint32_t *next_hop);
-int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop);
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop);
/**
* Lookup multiple IP addresses in an LPM table.
@@ -210,14 +193,6 @@ int
rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n);
#ifdef __cplusplus
}
--
2.17.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2 04/10] timer: remove deprecated code
` (6 preceding siblings ...)
2019-10-16 12:43 22% ` [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script Anatoly Burakov
@ 2019-10-16 12:43 4% ` Anatoly Burakov
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 05/10] lpm: " Anatoly Burakov
` (4 subsequent siblings)
12 siblings, 0 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Robert Sanford, Erik Gabriel Carrillo,
john.mcnamara, bruce.richardson, thomas, david.marchand
From: Marcin Baran <marcinx.baran@intel.com>
Remove code for old ABI versions ahead of ABI version bump.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Moved this to before ABI version bump to avoid compile breakage
lib/librte_timer/rte_timer.c | 90 ++----------------------------------
lib/librte_timer/rte_timer.h | 15 ------
2 files changed, 5 insertions(+), 100 deletions(-)
diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
index bdcf05d06b..de6959b809 100644
--- a/lib/librte_timer/rte_timer.c
+++ b/lib/librte_timer/rte_timer.c
@@ -68,9 +68,6 @@ static struct rte_timer_data *rte_timer_data_arr;
static const uint32_t default_data_id;
static uint32_t rte_timer_subsystem_initialized;
-/* For maintaining older interfaces for a period */
-static struct rte_timer_data default_timer_data;
-
/* when debug is enabled, store some statistics */
#ifdef RTE_LIBRTE_TIMER_DEBUG
#define __TIMER_STAT_ADD(priv_timer, name, n) do { \
@@ -131,22 +128,6 @@ rte_timer_data_dealloc(uint32_t id)
return 0;
}
-void
-rte_timer_subsystem_init_v20(void)
-{
- unsigned lcore_id;
- struct priv_timer *priv_timer = default_timer_data.priv_timer;
-
- /* since priv_timer is static, it's zeroed by default, so only init some
- * fields.
- */
- for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++) {
- rte_spinlock_init(&priv_timer[lcore_id].list_lock);
- priv_timer[lcore_id].prev_lcore = lcore_id;
- }
-}
-VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
-
/* Init the timer library. Allocate an array of timer data structs in shared
* memory, and allocate the zeroth entry for use with original timer
* APIs. Since the intersection of the sets of lcore ids in primary and
@@ -154,7 +135,7 @@ VERSION_SYMBOL(rte_timer_subsystem_init, _v20, 2.0);
* multiple processes.
*/
int
-rte_timer_subsystem_init_v1905(void)
+rte_timer_subsystem_init(void)
{
const struct rte_memzone *mz;
struct rte_timer_data *data;
@@ -209,9 +190,6 @@ rte_timer_subsystem_init_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_subsystem_init(void),
- rte_timer_subsystem_init_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_subsystem_init, _v1905, 19.05);
void
rte_timer_subsystem_finalize(void)
@@ -552,42 +530,13 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
/* Reset and start the timer associated with the timer handle tim */
int
-rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg)
-{
- uint64_t cur_time = rte_get_timer_cycles();
- uint64_t period;
-
- if (unlikely((tim_lcore != (unsigned)LCORE_ID_ANY) &&
- !(rte_lcore_is_enabled(tim_lcore) ||
- rte_lcore_has_role(tim_lcore, ROLE_SERVICE))))
- return -1;
-
- if (type == PERIODICAL)
- period = ticks;
- else
- period = 0;
-
- return __rte_timer_reset(tim, cur_time + ticks, period, tim_lcore,
- fct, arg, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_reset, _v20, 2.0);
-
-int
-rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
+rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned int tim_lcore,
rte_timer_cb_t fct, void *arg)
{
return rte_timer_alt_reset(default_data_id, tim, ticks, type,
tim_lcore, fct, arg);
}
-MAP_STATIC_SYMBOL(int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type,
- unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg),
- rte_timer_reset_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_reset, _v1905, 19.05);
int
rte_timer_alt_reset(uint32_t timer_data_id, struct rte_timer *tim,
@@ -658,20 +607,10 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked,
/* Stop the timer associated with the timer handle tim */
int
-rte_timer_stop_v20(struct rte_timer *tim)
-{
- return __rte_timer_stop(tim, 0, &default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_stop, _v20, 2.0);
-
-int
-rte_timer_stop_v1905(struct rte_timer *tim)
+rte_timer_stop(struct rte_timer *tim)
{
return rte_timer_alt_stop(default_data_id, tim);
}
-MAP_STATIC_SYMBOL(int rte_timer_stop(struct rte_timer *tim),
- rte_timer_stop_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_stop, _v1905, 19.05);
int
rte_timer_alt_stop(uint32_t timer_data_id, struct rte_timer *tim)
@@ -817,15 +756,8 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
priv_timer[lcore_id].running_tim = NULL;
}
-void
-rte_timer_manage_v20(void)
-{
- __rte_timer_manage(&default_timer_data);
-}
-VERSION_SYMBOL(rte_timer_manage, _v20, 2.0);
-
int
-rte_timer_manage_v1905(void)
+rte_timer_manage(void)
{
struct rte_timer_data *timer_data;
@@ -835,8 +767,6 @@ rte_timer_manage_v1905(void)
return 0;
}
-MAP_STATIC_SYMBOL(int rte_timer_manage(void), rte_timer_manage_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_manage, _v1905, 19.05);
int
rte_timer_alt_manage(uint32_t timer_data_id,
@@ -1074,21 +1004,11 @@ __rte_timer_dump_stats(struct rte_timer_data *timer_data __rte_unused, FILE *f)
#endif
}
-void
-rte_timer_dump_stats_v20(FILE *f)
-{
- __rte_timer_dump_stats(&default_timer_data, f);
-}
-VERSION_SYMBOL(rte_timer_dump_stats, _v20, 2.0);
-
int
-rte_timer_dump_stats_v1905(FILE *f)
+rte_timer_dump_stats(FILE *f)
{
return rte_timer_alt_dump_stats(default_data_id, f);
}
-MAP_STATIC_SYMBOL(int rte_timer_dump_stats(FILE *f),
- rte_timer_dump_stats_v1905);
-BIND_DEFAULT_SYMBOL(rte_timer_dump_stats, _v1905, 19.05);
int
rte_timer_alt_dump_stats(uint32_t timer_data_id __rte_unused, FILE *f)
diff --git a/lib/librte_timer/rte_timer.h b/lib/librte_timer/rte_timer.h
index 05d287d8f2..9dc5fc3092 100644
--- a/lib/librte_timer/rte_timer.h
+++ b/lib/librte_timer/rte_timer.h
@@ -181,8 +181,6 @@ int rte_timer_data_dealloc(uint32_t id);
* subsystem
*/
int rte_timer_subsystem_init(void);
-int rte_timer_subsystem_init_v1905(void);
-void rte_timer_subsystem_init_v20(void);
/**
* @warning
@@ -250,13 +248,6 @@ void rte_timer_init(struct rte_timer *tim);
int rte_timer_reset(struct rte_timer *tim, uint64_t ticks,
enum rte_timer_type type, unsigned tim_lcore,
rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v1905(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-int rte_timer_reset_v20(struct rte_timer *tim, uint64_t ticks,
- enum rte_timer_type type, unsigned int tim_lcore,
- rte_timer_cb_t fct, void *arg);
-
/**
* Loop until rte_timer_reset() succeeds.
@@ -313,8 +304,6 @@ rte_timer_reset_sync(struct rte_timer *tim, uint64_t ticks,
* - (-1): The timer is in the RUNNING or CONFIG state.
*/
int rte_timer_stop(struct rte_timer *tim);
-int rte_timer_stop_v1905(struct rte_timer *tim);
-int rte_timer_stop_v20(struct rte_timer *tim);
/**
* Loop until rte_timer_stop() succeeds.
@@ -358,8 +347,6 @@ int rte_timer_pending(struct rte_timer *tim);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_manage(void);
-int rte_timer_manage_v1905(void);
-void rte_timer_manage_v20(void);
/**
* Dump statistics about timers.
@@ -371,8 +358,6 @@ void rte_timer_manage_v20(void);
* - -EINVAL: timer subsystem not yet initialized
*/
int rte_timer_dump_stats(FILE *f);
-int rte_timer_dump_stats_v1905(FILE *f);
-void rte_timer_dump_stats_v20(FILE *f);
/**
* @warning
--
2.17.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script
` (5 preceding siblings ...)
2019-10-16 12:43 14% ` [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
@ 2019-10-16 12:43 22% ` Anatoly Burakov
2019-10-16 13:33 4% ` Bruce Richardson
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 04/10] timer: remove deprecated code Anatoly Burakov
` (5 subsequent siblings)
12 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
In order to facilitate mass updating of version files, add a shell
script that recurses into lib/ and drivers/ directories and calls
the ABI version update script.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Add this patch to split the shell script from previous commit
- Fixup miscellaneous bugs
buildtools/update-abi.sh | 36 ++++++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
create mode 100755 buildtools/update-abi.sh
diff --git a/buildtools/update-abi.sh b/buildtools/update-abi.sh
new file mode 100755
index 0000000000..a6f916a437
--- /dev/null
+++ b/buildtools/update-abi.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+abi_version=""
+abi_version_file="./config/ABI_VERSION"
+update_path="lib drivers"
+
+if [ -z "$1" ]
+then
+ # output to stderr
+ >&2 echo "provide ABI version"
+ exit 1
+fi
+
+abi_version=$1
+
+if [ -n "$2" ]
+then
+ abi_version_file=$2
+fi
+
+if [ -n "$3" ]
+then
+ update_path=${@:3}
+fi
+
+echo "New ABI version:" $abi_version
+echo "ABI_VERSION path:" $abi_version_file
+echo "Path to update:" $update_path
+
+echo $abi_version > $abi_version_file
+
+find $update_path -name \*version.map -exec \
+ ./buildtools/update_version_map_abi.py {} \
+ $abi_version \; -print
--
2.17.1
^ permalink raw reply [relevance 22%]
* [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version
` (4 preceding siblings ...)
2019-10-16 12:43 7% ` [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global Anatoly Burakov
@ 2019-10-16 12:43 14% ` Anatoly Burakov
2019-10-16 13:25 4% ` Bruce Richardson
2019-10-16 12:43 22% ` [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script Anatoly Burakov
` (6 subsequent siblings)
12 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev; +Cc: Pawel Modrak, john.mcnamara, bruce.richardson, thomas, david.marchand
From: Pawel Modrak <pawelx.modrak@intel.com>
Add a script that automatically merges all stable ABI's under one
ABI section with the new version, while leaving experimental
section exactly as it is.
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
Notes:
v2:
- Reworked script to be pep8-compliant and more reliable
buildtools/update_version_map_abi.py | 148 +++++++++++++++++++++++++++
1 file changed, 148 insertions(+)
create mode 100755 buildtools/update_version_map_abi.py
diff --git a/buildtools/update_version_map_abi.py b/buildtools/update_version_map_abi.py
new file mode 100755
index 0000000000..ea9044cc81
--- /dev/null
+++ b/buildtools/update_version_map_abi.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2019 Intel Corporation
+
+"""
+A Python program to update the ABI version and function names in a DPDK
+lib_*_version.map file. Called from the buildtools/update_abi.sh utility.
+"""
+
+from __future__ import print_function
+import argparse
+import sys
+import re
+
+
+def __parse_map_file(f_in):
+ func_line_regex = re.compile(r"\s*(?P<func>[a-zA-Z_0-9]+)\s*;\s*$")
+ section_begin_regex = re.compile(
+ r"\s*(?P<version>[a-zA-Z0-9_\.]+)\s*{\s*$")
+ section_end_regex = re.compile(
+ r"\s*}\s*(?P<parent>[a-zA-Z0-9_\.]+)?\s*;\s*$")
+
+ # for stable ABI, we don't care about which version introduced which
+ # function, we just flatten the list. there are dupes in certain files, so
+ # use a set instead of a list
+ stable_lines = set()
+ # copy experimental section as is
+ experimental_lines = []
+ is_experimental = False
+
+ # gather all functions
+ for line in f_in:
+ # clean up the line
+ line = line.strip('\n').strip()
+
+ # is this an end of section?
+ match = section_end_regex.match(line)
+ if match:
+ # whatever section this was, it's not active any more
+ is_experimental = False
+ continue
+
+ # if we're in the middle of experimental section, we need to copy
+ # the section verbatim, so just add the line
+ if is_experimental:
+ experimental_lines += [line]
+ continue
+
+ # skip empty lines
+ if not line:
+ continue
+
+ # is this a beginning of a new section?
+ match = section_begin_regex.match(line)
+ if match:
+ cur_section = match.group("version")
+ # is it experimental?
+ is_experimental = cur_section == "EXPERIMENTAL"
+ continue
+
+ # is this a function?
+ match = func_line_regex.match(line)
+ if match:
+ stable_lines.add(match.group("func"))
+
+ return stable_lines, experimental_lines
+
+
+def __regenerate_map_file(f_out, abi_version, stable_lines,
+ experimental_lines):
+ # print ABI version header
+ print("DPDK_{} {{".format(abi_version), file=f_out)
+
+ if stable_lines:
+ # print global section
+ print("\tglobal:", file=f_out)
+ # blank line
+ print(file=f_out)
+
+ # print all stable lines, alphabetically sorted
+ for line in sorted(stable_lines):
+ print("\t{};".format(line), file=f_out)
+
+ # another blank line
+ print(file=f_out)
+
+ # print local section
+ print("\tlocal: *;", file=f_out)
+
+ # end stable version
+ print("};", file=f_out)
+
+ # do we have experimental lines?
+ if not experimental_lines:
+ return
+
+ # another blank line
+ print(file=f_out)
+
+ # start experimental section
+ print("EXPERIMENTAL {", file=f_out)
+
+ # print all experimental lines as they were
+ for line in experimental_lines:
+ # don't print empty whitespace
+ if not line:
+ print("", file=f_out)
+ else:
+ print("\t{}".format(line), file=f_out)
+
+ # end section
+ print("};", file=f_out)
+
+
+def __main():
+ arg_parser = argparse.ArgumentParser(
+ description='Merge versions in linker version script.')
+
+ arg_parser.add_argument("map_file", type=str,
+ help='path to linker version script file '
+ '(pattern: *version.map)')
+ arg_parser.add_argument("abi_version", type=str,
+ help='target ABI version (pattern: MAJOR.MINOR)')
+
+ parsed = arg_parser.parse_args()
+
+ if not parsed.map_file.endswith('version.map'):
+ print("Invalid input file: {}".format(parsed.map_file),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ if not re.match(r"\d{1,2}\.\d{1,2}", parsed.abi_version):
+ print("Invalid ABI version: {}".format(parsed.abi_version),
+ file=sys.stderr)
+ arg_parser.print_help()
+ sys.exit(1)
+
+ with open(parsed.map_file) as f_in:
+ stable_lines, experimental_lines = __parse_map_file(f_in)
+
+ with open(parsed.map_file, 'w') as f_out:
+ __regenerate_map_file(f_out, parsed.abi_version, stable_lines,
+ experimental_lines)
+
+
+if __name__ == "__main__":
+ __main()
--
2.17.1
^ permalink raw reply [relevance 14%]
* [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global
` (3 preceding siblings ...)
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
@ 2019-10-16 12:43 7% ` Anatoly Burakov
2019-10-16 13:22 4% ` Bruce Richardson
2019-10-16 12:43 14% ` [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
` (7 subsequent siblings)
12 siblings, 1 reply; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev
Cc: Marcin Baran, Thomas Monjalon, Bruce Richardson, john.mcnamara,
david.marchand, Pawel Modrak
From: Marcin Baran <marcinx.baran@intel.com>
The libraries should be maintained using global
ABI versioning. The changes includes adding global
ABI version support for both makefile and meson
build system. Experimental libraries should be
marked as 0.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
buildtools/meson.build | 2 ++
config/ABI_VERSION | 1 +
config/meson.build | 3 ++-
drivers/meson.build | 20 ++++++++++++++------
lib/meson.build | 18 +++++++++++++-----
meson_options.txt | 2 --
mk/rte.lib.mk | 19 +++++++++++--------
7 files changed, 43 insertions(+), 22 deletions(-)
create mode 100644 config/ABI_VERSION
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 32c79c1308..78ce69977d 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -12,3 +12,5 @@ if python3.found()
else
map_to_def_cmd = ['meson', 'runpython', files('map_to_def.py')]
endif
+
+is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
diff --git a/config/ABI_VERSION b/config/ABI_VERSION
new file mode 100644
index 0000000000..9a7c1e503f
--- /dev/null
+++ b/config/ABI_VERSION
@@ -0,0 +1 @@
+20.0
diff --git a/config/meson.build b/config/meson.build
index a27f731f85..25ecf928e4 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -17,7 +17,8 @@ endforeach
# set the major version, which might be used by drivers and libraries
# depending on the configuration options
pver = meson.project_version().split('.')
-major_version = '@0@.@1@'.format(pver.get(0), pver.get(1))
+major_version = run_command(find_program('cat', 'more'),
+ files('ABI_VERSION')).stdout().strip()
# extract all version information into the build configuration
dpdk_conf.set('RTE_VER_YEAR', pver.get(0).to_int())
diff --git a/drivers/meson.build b/drivers/meson.build
index 2ed2e95411..5c5fe87c7e 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -110,9 +110,20 @@ foreach class:dpdk_driver_classes
output: out_filename,
depends: [pmdinfogen, tmp_lib])
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/@2@_version.map'.format(
+ meson.current_source_dir(),
+ drv_path, lib_name)
+
+ if is_windows
+ version_map = '\\'.join(version_map.split('/'))
+ endif
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
lib_version = major_version
so_version = major_version
@@ -128,9 +139,6 @@ foreach class:dpdk_driver_classes
install: true)
# now build the shared driver
- version_map = '@0@/@1@/@2@_version.map'.format(
- meson.current_source_dir(),
- drv_path, lib_name)
shared_lib = shared_library(lib_name,
sources,
objects: objs,
diff --git a/lib/meson.build b/lib/meson.build
index e5ff838934..3892c16e8f 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -97,9 +97,19 @@ foreach l:libraries
cflags += '-DALLOW_EXPERIMENTAL_API'
endif
- if get_option('per_library_versions')
- lib_version = '@0@.1'.format(version)
- so_version = '@0@'.format(version)
+ version_map = '@0@/@1@/rte_@2@_version.map'.format(
+ meson.current_source_dir(), dir_name, name)
+
+ if is_windows
+ version_map = '\\'.join(version_map.split('/'))
+ endif
+
+ is_experimental = run_command(is_experimental_cmd,
+ files(version_map)).returncode()
+
+ if is_experimental != 0
+ lib_version = '0.1'
+ so_version = '0'
else
lib_version = major_version
so_version = major_version
@@ -120,8 +130,6 @@ foreach l:libraries
# then use pre-build objects to build shared lib
sources = []
objs += static_lib.extract_all_objects(recursive: false)
- version_map = '@0@/@1@/rte_@2@_version.map'.format(
- meson.current_source_dir(), dir_name, name)
implib = dir_name + '.dll.a'
def_file = custom_target(name + '_def',
diff --git a/meson_options.txt b/meson_options.txt
index 448f3e63dc..000e38fd98 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -28,8 +28,6 @@ option('max_lcores', type: 'integer', value: 128,
description: 'maximum number of cores/threads supported by EAL')
option('max_numa_nodes', type: 'integer', value: 4,
description: 'maximum number of NUMA nodes supported by EAL')
-option('per_library_versions', type: 'boolean', value: true,
- description: 'true: each lib gets its own version number, false: DPDK version used for each lib')
option('tests', type: 'boolean', value: true,
description: 'build unit tests')
option('use_hpet', type: 'boolean', value: false,
diff --git a/mk/rte.lib.mk b/mk/rte.lib.mk
index 4df8849a08..f84161c6d5 100644
--- a/mk/rte.lib.mk
+++ b/mk/rte.lib.mk
@@ -11,20 +11,23 @@ EXTLIB_BUILD ?= n
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
-ifneq ($(CONFIG_RTE_MAJOR_ABI),)
-ifneq ($(LIBABIVER),)
-LIBABIVER := $(CONFIG_RTE_MAJOR_ABI)
+ifeq ($(OS), Windows_NT)
+search_cmd = findstr
+print_cmd = more
+else
+search_cmd = grep
+print_cmd = cat
endif
+
+ifneq ($(shell $(search_cmd) "^DPDK_" $(SRCDIR)/$(EXPORT_MAP)),)
+LIBABIVER := $(shell $(print_cmd) $(RTE_SRCDIR)/config/ABI_VERSION)
+else
+LIBABIVER := 0
endif
ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),y)
LIB := $(patsubst %.a,%.so.$(LIBABIVER),$(LIB))
ifeq ($(EXTLIB_BUILD),n)
-ifeq ($(CONFIG_RTE_MAJOR_ABI),)
-ifeq ($(CONFIG_RTE_NEXT_ABI),y)
-LIB := $(LIB).1
-endif
-endif
CPU_LDFLAGS += --version-script=$(SRCDIR)/$(EXPORT_MAP)
endif
endif
--
2.17.1
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts
` (2 preceding siblings ...)
2019-09-30 9:21 2% ` [dpdk-dev] [PATCH 7/8] lib: remove dead code from distributor Marcin Baran
@ 2019-10-16 12:43 8% ` Anatoly Burakov
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
` (9 more replies)
2019-10-16 12:43 7% ` [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global Anatoly Burakov
` (8 subsequent siblings)
12 siblings, 10 replies; 200+ results
From: Anatoly Burakov @ 2019-10-16 12:43 UTC (permalink / raw)
To: dev; +Cc: john.mcnamara, bruce.richardson, thomas, david.marchand
This patchset prepares the codebase for the new ABI policy and
adds a few helper scripts.
There are two new scripts for managing ABI versions added. The
first one is a Python script that will read in a .map file,
flatten it and update the ABI version to the ABI version
specified on the command-line.
The second one is a shell script that will run the above mentioned
Python script recursively over the source tree and set the ABI
version to either that which is defined in config/ABI_VERSION, or
a user-specified one.
Example of its usage: buildtools/update-abi.sh 20.0
This will recurse into lib/ and drivers/ directory and update
whatever .map files it can find.
The other shell script that's added is one that can take in a .so
file and ensure that its declared public ABI matches either
current ABI, next ABI, or EXPERIMENTAL. This was moved to the
last commit because it made no sense to have it beforehand.
The source tree was verified to follow the new ABI policy using
the following command (assuming built binaries are in build/):
find ./build/lib ./build/drivers -name \*.so \
-exec ./buildtools/check-abi-version.sh {} \; -print
This returns 0.
Changes since v1:
- Reordered patchset to have removal of old ABI's before introducing
the new one to avoid compile breakages between patches
- Added a new patch fixing missing symbol in octeontx common
- Split script commits into multiple commits and reordered them
- Re-generated the ABI bump commit
- Verified all scripts to work
Anatoly Burakov (2):
buildtools: add ABI update shell script
drivers/octeontx: add missing public symbol
Marcin Baran (6):
config: change ABI versioning for global
timer: remove deprecated code
lpm: remove deprecated code
distributor: remove deprecated code
lib: change function suffix in distributor
buildtools: add ABI versioning check script
Pawel Modrak (2):
buildtools: add script for updating symbols abi version
build: change ABI version to 20.0
buildtools/check-abi-version.sh | 54 +
buildtools/meson.build | 2 +
buildtools/update-abi.sh | 36 +
buildtools/update_version_map_abi.py | 148 +++
config/ABI_VERSION | 1 +
config/meson.build | 3 +-
.../rte_pmd_bbdev_fpga_lte_fec_version.map | 8 +-
.../null/rte_pmd_bbdev_null_version.map | 2 +-
.../rte_pmd_bbdev_turbo_sw_version.map | 2 +-
drivers/bus/dpaa/rte_bus_dpaa_version.map | 115 +-
drivers/bus/fslmc/rte_bus_fslmc_version.map | 154 ++-
drivers/bus/ifpga/rte_bus_ifpga_version.map | 14 +-
drivers/bus/pci/rte_bus_pci_version.map | 2 +-
drivers/bus/vdev/rte_bus_vdev_version.map | 12 +-
drivers/bus/vmbus/rte_bus_vmbus_version.map | 12 +-
drivers/common/cpt/rte_common_cpt_version.map | 4 +-
.../common/dpaax/rte_common_dpaax_version.map | 4 +-
.../common/mvep/rte_common_mvep_version.map | 6 +-
.../octeontx/rte_common_octeontx_version.map | 7 +-
.../rte_common_octeontx2_version.map | 16 +-
.../compress/isal/rte_pmd_isal_version.map | 2 +-
.../rte_pmd_octeontx_compress_version.map | 2 +-
drivers/compress/qat/rte_pmd_qat_version.map | 2 +-
.../compress/zlib/rte_pmd_zlib_version.map | 2 +-
.../aesni_gcm/rte_pmd_aesni_gcm_version.map | 2 +-
.../aesni_mb/rte_pmd_aesni_mb_version.map | 2 +-
.../crypto/armv8/rte_pmd_armv8_version.map | 2 +-
.../caam_jr/rte_pmd_caam_jr_version.map | 3 +-
drivers/crypto/ccp/rte_pmd_ccp_version.map | 3 +-
.../dpaa2_sec/rte_pmd_dpaa2_sec_version.map | 10 +-
.../dpaa_sec/rte_pmd_dpaa_sec_version.map | 10 +-
.../crypto/kasumi/rte_pmd_kasumi_version.map | 2 +-
.../crypto/mvsam/rte_pmd_mvsam_version.map | 2 +-
.../crypto/nitrox/rte_pmd_nitrox_version.map | 2 +-
.../null/rte_pmd_null_crypto_version.map | 2 +-
.../rte_pmd_octeontx_crypto_version.map | 3 +-
.../openssl/rte_pmd_openssl_version.map | 2 +-
.../rte_pmd_crypto_scheduler_version.map | 19 +-
.../crypto/snow3g/rte_pmd_snow3g_version.map | 2 +-
.../virtio/rte_pmd_virtio_crypto_version.map | 2 +-
drivers/crypto/zuc/rte_pmd_zuc_version.map | 2 +-
.../event/dpaa/rte_pmd_dpaa_event_version.map | 3 +-
.../dpaa2/rte_pmd_dpaa2_event_version.map | 2 +-
.../event/dsw/rte_pmd_dsw_event_version.map | 2 +-
.../rte_pmd_octeontx_event_version.map | 2 +-
.../rte_pmd_octeontx2_event_version.map | 3 +-
.../event/opdl/rte_pmd_opdl_event_version.map | 2 +-
.../rte_pmd_skeleton_event_version.map | 3 +-
drivers/event/sw/rte_pmd_sw_event_version.map | 2 +-
.../bucket/rte_mempool_bucket_version.map | 3 +-
.../mempool/dpaa/rte_mempool_dpaa_version.map | 2 +-
.../dpaa2/rte_mempool_dpaa2_version.map | 12 +-
.../octeontx/rte_mempool_octeontx_version.map | 2 +-
.../rte_mempool_octeontx2_version.map | 4 +-
.../mempool/ring/rte_mempool_ring_version.map | 3 +-
.../stack/rte_mempool_stack_version.map | 3 +-
drivers/meson.build | 20 +-
.../af_packet/rte_pmd_af_packet_version.map | 3 +-
drivers/net/af_xdp/rte_pmd_af_xdp_version.map | 2 +-
drivers/net/ark/rte_pmd_ark_version.map | 5 +-
.../net/atlantic/rte_pmd_atlantic_version.map | 4 +-
drivers/net/avp/rte_pmd_avp_version.map | 2 +-
drivers/net/axgbe/rte_pmd_axgbe_version.map | 2 +-
drivers/net/bnx2x/rte_pmd_bnx2x_version.map | 3 +-
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +-
drivers/net/bonding/rte_pmd_bond_version.map | 47 +-
drivers/net/cxgbe/rte_pmd_cxgbe_version.map | 3 +-
drivers/net/dpaa/rte_pmd_dpaa_version.map | 11 +-
drivers/net/dpaa2/rte_pmd_dpaa2_version.map | 12 +-
drivers/net/e1000/rte_pmd_e1000_version.map | 3 +-
drivers/net/ena/rte_pmd_ena_version.map | 3 +-
drivers/net/enetc/rte_pmd_enetc_version.map | 3 +-
drivers/net/enic/rte_pmd_enic_version.map | 3 +-
.../net/failsafe/rte_pmd_failsafe_version.map | 3 +-
drivers/net/fm10k/rte_pmd_fm10k_version.map | 3 +-
drivers/net/hinic/rte_pmd_hinic_version.map | 3 +-
drivers/net/hns3/rte_pmd_hns3_version.map | 4 +-
drivers/net/i40e/rte_pmd_i40e_version.map | 65 +-
drivers/net/iavf/rte_pmd_iavf_version.map | 3 +-
drivers/net/ice/rte_pmd_ice_version.map | 3 +-
drivers/net/ifc/rte_pmd_ifc_version.map | 3 +-
drivers/net/ipn3ke/rte_pmd_ipn3ke_version.map | 3 +-
drivers/net/ixgbe/rte_pmd_ixgbe_version.map | 62 +-
drivers/net/kni/rte_pmd_kni_version.map | 3 +-
.../net/liquidio/rte_pmd_liquidio_version.map | 3 +-
drivers/net/memif/rte_pmd_memif_version.map | 5 +-
drivers/net/mlx4/rte_pmd_mlx4_version.map | 3 +-
drivers/net/mlx5/rte_pmd_mlx5_version.map | 2 +-
drivers/net/mvneta/rte_pmd_mvneta_version.map | 2 +-
drivers/net/mvpp2/rte_pmd_mvpp2_version.map | 2 +-
drivers/net/netvsc/rte_pmd_netvsc_version.map | 4 +-
drivers/net/nfb/rte_pmd_nfb_version.map | 3 +-
drivers/net/nfp/rte_pmd_nfp_version.map | 2 +-
drivers/net/null/rte_pmd_null_version.map | 3 +-
.../net/octeontx/rte_pmd_octeontx_version.map | 10 +-
.../octeontx2/rte_pmd_octeontx2_version.map | 3 +-
drivers/net/pcap/rte_pmd_pcap_version.map | 3 +-
drivers/net/qede/rte_pmd_qede_version.map | 3 +-
drivers/net/ring/rte_pmd_ring_version.map | 10 +-
drivers/net/sfc/rte_pmd_sfc_version.map | 3 +-
.../net/softnic/rte_pmd_softnic_version.map | 2 +-
.../net/szedata2/rte_pmd_szedata2_version.map | 2 +-
drivers/net/tap/rte_pmd_tap_version.map | 3 +-
.../net/thunderx/rte_pmd_thunderx_version.map | 3 +-
.../rte_pmd_vdev_netvsc_version.map | 3 +-
drivers/net/vhost/rte_pmd_vhost_version.map | 11 +-
drivers/net/virtio/rte_pmd_virtio_version.map | 3 +-
.../net/vmxnet3/rte_pmd_vmxnet3_version.map | 3 +-
.../rte_rawdev_dpaa2_cmdif_version.map | 3 +-
.../rte_rawdev_dpaa2_qdma_version.map | 4 +-
.../raw/ifpga/rte_rawdev_ifpga_version.map | 3 +-
drivers/raw/ioat/rte_rawdev_ioat_version.map | 3 +-
drivers/raw/ntb/rte_rawdev_ntb_version.map | 5 +-
.../rte_rawdev_octeontx2_dma_version.map | 3 +-
.../skeleton/rte_rawdev_skeleton_version.map | 3 +-
lib/librte_acl/rte_acl_version.map | 2 +-
lib/librte_bbdev/rte_bbdev_version.map | 4 +
.../rte_bitratestats_version.map | 2 +-
lib/librte_bpf/rte_bpf_version.map | 4 +
lib/librte_cfgfile/rte_cfgfile_version.map | 34 +-
lib/librte_cmdline/rte_cmdline_version.map | 10 +-
.../rte_compressdev_version.map | 4 +
.../rte_cryptodev_version.map | 102 +-
lib/librte_distributor/Makefile | 2 +-
lib/librte_distributor/meson.build | 2 +-
lib/librte_distributor/rte_distributor.c | 80 +-
.../rte_distributor_private.h | 10 +-
...ributor_v20.c => rte_distributor_single.c} | 48 +-
...ributor_v20.h => rte_distributor_single.h} | 26 +-
.../rte_distributor_v1705.h | 61 --
.../rte_distributor_version.map | 16 +-
lib/librte_eal/rte_eal_version.map | 310 ++----
lib/librte_efd/rte_efd_version.map | 2 +-
lib/librte_ethdev/rte_ethdev_version.map | 160 +--
lib/librte_eventdev/rte_eventdev_version.map | 130 +--
.../rte_flow_classify_version.map | 4 +
lib/librte_gro/rte_gro_version.map | 2 +-
lib/librte_gso/rte_gso_version.map | 2 +-
lib/librte_hash/rte_hash_version.map | 43 +-
lib/librte_ip_frag/rte_ip_frag_version.map | 10 +-
lib/librte_ipsec/rte_ipsec_version.map | 4 +
lib/librte_jobstats/rte_jobstats_version.map | 10 +-
lib/librte_kni/rte_kni_version.map | 2 +-
lib/librte_kvargs/rte_kvargs_version.map | 4 +-
.../rte_latencystats_version.map | 2 +-
lib/librte_lpm/rte_lpm.c | 996 +-----------------
lib/librte_lpm/rte_lpm.h | 88 --
lib/librte_lpm/rte_lpm6.c | 132 +--
lib/librte_lpm/rte_lpm6.h | 25 -
lib/librte_lpm/rte_lpm_version.map | 39 +-
lib/librte_mbuf/rte_mbuf_version.map | 41 +-
lib/librte_member/rte_member_version.map | 2 +-
lib/librte_mempool/rte_mempool_version.map | 44 +-
lib/librte_meter/rte_meter_version.map | 13 +-
lib/librte_metrics/rte_metrics_version.map | 2 +-
lib/librte_net/rte_net_version.map | 23 +-
lib/librte_pci/rte_pci_version.map | 2 +-
lib/librte_pdump/rte_pdump_version.map | 2 +-
lib/librte_pipeline/rte_pipeline_version.map | 36 +-
lib/librte_port/rte_port_version.map | 64 +-
lib/librte_power/rte_power_version.map | 24 +-
lib/librte_rawdev/rte_rawdev_version.map | 4 +-
lib/librte_rcu/rte_rcu_version.map | 4 +
lib/librte_reorder/rte_reorder_version.map | 8 +-
lib/librte_ring/rte_ring_version.map | 10 +-
lib/librte_sched/rte_sched_version.map | 14 +-
lib/librte_security/rte_security_version.map | 2 +-
lib/librte_stack/rte_stack_version.map | 4 +
lib/librte_table/rte_table_version.map | 2 +-
.../rte_telemetry_version.map | 4 +
lib/librte_timer/rte_timer.c | 90 +-
lib/librte_timer/rte_timer.h | 15 -
lib/librte_timer/rte_timer_version.map | 12 +-
lib/librte_vhost/rte_vhost_version.map | 52 +-
lib/meson.build | 18 +-
meson_options.txt | 2 -
mk/rte.lib.mk | 19 +-
177 files changed, 1122 insertions(+), 2891 deletions(-)
create mode 100755 buildtools/check-abi-version.sh
create mode 100755 buildtools/update-abi.sh
create mode 100755 buildtools/update_version_map_abi.py
create mode 100644 config/ABI_VERSION
rename lib/librte_distributor/{rte_distributor_v20.c => rte_distributor_single.c} (87%)
rename lib/librte_distributor/{rte_distributor_v20.h => rte_distributor_single.h} (89%)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
--
2.17.1
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic compare exchange
@ 2019-10-16 9:04 4% ` Phil Yang (Arm Technology China)
2019-10-17 12:45 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Phil Yang (Arm Technology China) @ 2019-10-16 9:04 UTC (permalink / raw)
To: David Marchand
Cc: thomas, jerinj, Gage Eads, dev, hemant.agrawal,
Honnappa Nagarahalli, Gavin Hu (Arm Technology China),
nd, nd
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Tuesday, October 15, 2019 8:16 PM
> To: Phil Yang (Arm Technology China) <Phil.Yang@arm.com>
> Cc: thomas@monjalon.net; jerinj@marvell.com; Gage Eads
> <gage.eads@intel.com>; dev <dev@dpdk.org>; hemant.agrawal@nxp.com;
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu (Arm
> Technology China) <Gavin.Hu@arm.com>; nd <nd@arm.com>
> Subject: Re: [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic
> compare exchange
>
> On Tue, Oct 15, 2019 at 1:32 PM Phil Yang (Arm Technology China)
> <Phil.Yang@arm.com> wrote:
> > > -----Original Message-----
> > > From: David Marchand <david.marchand@redhat.com>
> > > If LSE is available, we expose __rte_cas_XX (explicitely) *non*
> > > inlined functions, while without LSE, we expose inlined __rte_ldr_XX
> > > and __rte_stx_XX functions.
> > > So we have a first disparity with non-inlined vs inlined functions
> > > depending on a #ifdef.
>
> You did not comment on the inline / no inline part and I still see
> this in the v10.
> Is this __rte_noinline on the CAS function intentional?
Apologize for missing this item. Yes, it is to avoid ABI break.
Please check
5b40ec6b966260e0ff66a8a2c689664f75d6a0e6 ("mempool/octeontx2: fix possible arm64 ABI break")
>
>
> > > Then, we have a second disparity with two sets of "apis" depending on
> > > this #ifdef.
> > >
> > > And we expose those sets with a rte_ prefix, meaning people will try
> > > to use them, but those are not part of a public api.
> > >
> > > Can't we do without them ? (see below [2] for a proposal with ldr/stx,
> > > cas should be the same)
> >
> > No, it doesn't work.
> > Because we need to verify the return value at the end of the loop for these
> macros.
>
> Do you mean the return value for the stores?
It is my bad. I missed the ret option in the macro. This approach works.
However, I suggest to keep them as static inline functions rather than a piece of macro in the rte_atomic128_cmp_exchange API.
One reason is APIs name can indicate the memory ordering of these operations.
Moreover, it uses the register type to pass the value in the inline function, so it should not have too much cost comparing with the macro.
I also think these 128bit load and store functions can be used in other places, once it has been proved valuable in rte_atomic128_cmp_exchange API. But let's keep them private for the current stage.
BTW, Linux kernel implemented in the same way. https://github.com/torvalds/linux/blob/master/arch/arm64/include/asm/atomic_lse.h#L19
> > > #define __STORE_128(op_string, dst, val, ret) \
> > > asm volatile( \
> > > op_string " %w0, %1, %2, %3" \
> > > : "=&r" (ret) \
> > > : "r" (val.val[0]), \
> > > "r" (val.val[1]), \
> > > "Q" (dst->val[0]) \
> > > : "memory")
>
> The ret variable is still passed in this macro and the while loop can
> check it later.
>
>
> > > > diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h
> > > b/lib/librte_eal/common/include/generic/rte_atomic.h
> > > > index 24ff7dc..e6ab15a 100644
> > > > --- a/lib/librte_eal/common/include/generic/rte_atomic.h
> > > > +++ b/lib/librte_eal/common/include/generic/rte_atomic.h
> > > > @@ -1081,6 +1081,20 @@ static inline void
> > > rte_atomic64_clear(rte_atomic64_t *v)
> > > >
> > > > /*------------------------ 128 bit atomic operations -------------------------*/
> > > >
> > > > +/**
> > > > + * 128-bit integer structure.
> > > > + */
> > > > +RTE_STD_C11
> > > > +typedef struct {
> > > > + RTE_STD_C11
> > > > + union {
> > > > + uint64_t val[2];
> > > > +#ifdef RTE_ARCH_64
> > > > + __extension__ __int128 int128;
> > > > +#endif
> > >
> > > You hid this field for x86.
> > > What is the reason?
> > No, we are not hid it for x86. The RTE_ARCH_64 flag covered x86 as well.
>
> Ah indeed, I read it wrong, ARCH_64 ... AARCH64 ... :-)
>
>
>
> --
> David Marchand
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 2/2] sched: modify internal structs and functions for 64 bit values
2019-10-15 15:47 4% ` Dumitrescu, Cristian
@ 2019-10-15 16:01 0% ` Singh, Jasvinder
0 siblings, 0 replies; 200+ results
From: Singh, Jasvinder @ 2019-10-15 16:01 UTC (permalink / raw)
To: Dumitrescu, Cristian, dev; +Cc: Krakowiak, LukaszX
> -----Original Message-----
> From: Dumitrescu, Cristian
> Sent: Tuesday, October 15, 2019 4:47 PM
> To: Singh, Jasvinder <jasvinder.singh@intel.com>; dev@dpdk.org
> Cc: Krakowiak, LukaszX <lukaszx.krakowiak@intel.com>
> Subject: RE: [PATCH 2/2] sched: modify internal structs and functions for 64 bit
> values
>
> Hi Jasvinder,
>
> > -----Original Message-----
> > From: Singh, Jasvinder
> > Sent: Monday, October 14, 2019 6:25 PM
> > To: dev@dpdk.org
> > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Krakowiak,
> > LukaszX <lukaszx.krakowiak@intel.com>
> > Subject: [PATCH 2/2] sched: modify internal structs and functions for
> > 64 bit values
> >
> > Modify internal structure and functions to support 64-bit values for
> > rates and stats parameters.
> >
> > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com>
> > ---
> > lib/librte_sched/rte_approx.c | 57 ++++----
> > lib/librte_sched/rte_approx.h | 3 +-
> > lib/librte_sched/rte_sched.c | 211 +++++++++++++++-------------
> > lib/librte_sched/rte_sched_common.h | 12 +-
> > 4 files changed, 156 insertions(+), 127 deletions(-)
> >
> > diff --git a/lib/librte_sched/rte_approx.c
> > b/lib/librte_sched/rte_approx.c index 30620b83d..4883d3969 100644
> > --- a/lib/librte_sched/rte_approx.c
> > +++ b/lib/librte_sched/rte_approx.c
> > @@ -18,22 +18,23 @@
> > */
> >
> > /* fraction comparison: compare (a/b) and (c/d) */ -static inline
> > uint32_t -less(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
> > +static inline sched_counter_t
> > +less(sched_counter_t a, sched_counter_t b, sched_counter_t c,
> > sched_counter_t d)
> > {
> > return a*d < b*c;
> > }
> >
> > -static inline uint32_t
> > -less_or_equal(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
> > +static inline sched_counter_t
> > +less_or_equal(sched_counter_t a, sched_counter_t b, sched_counter_t c,
> > + sched_counter_t d)
> > {
> > return a*d <= b*c;
> > }
> >
> > /* check whether a/b is a valid approximation */ -static inline
> > uint32_t -matches(uint32_t a, uint32_t b,
> > - uint32_t alpha_num, uint32_t d_num, uint32_t denum)
> > +static inline sched_counter_t
> > +matches(sched_counter_t a, sched_counter_t b,
> > + sched_counter_t alpha_num, sched_counter_t d_num,
> > sched_counter_t denum)
> > {
> > if (less_or_equal(a, b, alpha_num - d_num, denum))
> > return 0;
> > @@ -45,33 +46,39 @@ matches(uint32_t a, uint32_t b, }
> >
> > static inline void
> > -find_exact_solution_left(uint32_t p_a, uint32_t q_a, uint32_t p_b,
> > uint32_t q_b,
> > - uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p,
> > uint32_t *q)
> > +find_exact_solution_left(sched_counter_t p_a, sched_counter_t q_a,
> > + sched_counter_t p_b, sched_counter_t q_b, sched_counter_t
> > alpha_num,
> > + sched_counter_t d_num, sched_counter_t denum,
> > sched_counter_t *p,
> > + sched_counter_t *q)
> > {
> > - uint32_t k_num = denum * p_b - (alpha_num + d_num) * q_b;
> > - uint32_t k_denum = (alpha_num + d_num) * q_a - denum * p_a;
> > - uint32_t k = (k_num / k_denum) + 1;
> > + sched_counter_t k_num = denum * p_b - (alpha_num + d_num) *
> > q_b;
> > + sched_counter_t k_denum = (alpha_num + d_num) * q_a - denum *
> > p_a;
> > + sched_counter_t k = (k_num / k_denum) + 1;
> >
> > *p = p_b + k * p_a;
> > *q = q_b + k * q_a;
> > }
> >
> > static inline void
> > -find_exact_solution_right(uint32_t p_a, uint32_t q_a, uint32_t p_b,
> > uint32_t q_b,
> > - uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p,
> > uint32_t *q)
> > +find_exact_solution_right(sched_counter_t p_a, sched_counter_t q_a,
> > + sched_counter_t p_b, sched_counter_t q_b, sched_counter_t
> > alpha_num,
> > + sched_counter_t d_num, sched_counter_t denum,
> > sched_counter_t *p,
> > + sched_counter_t *q)
> > {
> > - uint32_t k_num = - denum * p_b + (alpha_num - d_num) * q_b;
> > - uint32_t k_denum = - (alpha_num - d_num) * q_a + denum * p_a;
> > - uint32_t k = (k_num / k_denum) + 1;
> > + sched_counter_t k_num = -denum * p_b + (alpha_num - d_num) *
> > q_b;
> > + sched_counter_t k_denum = -(alpha_num - d_num) * q_a + denum
> > * p_a;
> > + sched_counter_t k = (k_num / k_denum) + 1;
> >
> > *p = p_b + k * p_a;
> > *q = q_b + k * q_a;
> > }
> >
> > static int
> > -find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num,
> > uint32_t denum, uint32_t *p, uint32_t *q)
> > +find_best_rational_approximation(sched_counter_t alpha_num,
> > + sched_counter_t d_num, sched_counter_t denum,
> > sched_counter_t *p,
> > + sched_counter_t *q)
> > {
> > - uint32_t p_a, q_a, p_b, q_b;
> > + sched_counter_t p_a, q_a, p_b, q_b;
> >
> > /* check assumptions on the inputs */
> > if (!((0 < d_num) && (d_num < alpha_num) && (alpha_num <
> > denum) && (d_num + alpha_num < denum))) { @@ -85,8 +92,8 @@
> > find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num,
> > uint32_t de
> > q_b = 1;
> >
> > while (1) {
> > - uint32_t new_p_a, new_q_a, new_p_b, new_q_b;
> > - uint32_t x_num, x_denum, x;
> > + sched_counter_t new_p_a, new_q_a, new_p_b, new_q_b;
> > + sched_counter_t x_num, x_denum, x;
> > int aa, bb;
> >
> > /* compute the number of steps to the left */ @@ -139,9
> +146,9 @@
> > find_best_rational_approximation(uint32_t
> > alpha_num, uint32_t d_num, uint32_t de
> > }
> > }
> >
> > -int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q)
> > +int rte_approx(double alpha, double d, sched_counter_t *p,
> > sched_counter_t *q)
> > {
> > - uint32_t alpha_num, d_num, denum;
> > + sched_counter_t alpha_num, d_num, denum;
> >
> > /* Check input arguments */
> > if (!((0.0 < d) && (d < alpha) && (alpha < 1.0))) { @@ -159,8 +166,8
> > @@ int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q)
> > d *= 10;
> > denum *= 10;
> > }
> > - alpha_num = (uint32_t) alpha;
> > - d_num = (uint32_t) d;
> > + alpha_num = (sched_counter_t) alpha;
> > + d_num = (sched_counter_t) d;
> >
> > /* Perform approximation */
> > return find_best_rational_approximation(alpha_num, d_num, denum,
> p,
> > q); diff --git a/lib/librte_sched/rte_approx.h
> > b/lib/librte_sched/rte_approx.h index 0244d98f1..e591e122d 100644
> > --- a/lib/librte_sched/rte_approx.h
> > +++ b/lib/librte_sched/rte_approx.h
> > @@ -20,6 +20,7 @@ extern "C" {
> > ***/
> >
> > #include <stdint.h>
> > +#include "rte_sched_common.h"
> >
> > /**
> > * Find best rational approximation
> > @@ -37,7 +38,7 @@ extern "C" {
> > * @return
> > * 0 upon success, error code otherwise
> > */
> > -int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q);
> > +int rte_approx(double alpha, double d, sched_counter_t *p,
> > sched_counter_t *q);
> >
> > #ifdef __cplusplus
> > }
>
> Please keep the rte_approx.[hc] independent of the librte_sched library, so use
> unit32_t or uint64_t instead of sched_counter_t that is librte_sched dependent.
> Also, for the same reason, remove the above inclusion of rte_sched_common.h.
Ok, will make these changes.
> Please keep the existing 32-bit functions with their current name & prototype
> and create new 64-bit functions that have the "64" suffix to their name, and use
> the 64-bit versions in the rte_sched.c implementation. Makes sense?
Yes, will add new functions with suffix "64" in rte_approx.[hc].
> The rte_approx.[hc] files represent the implementation of an arithmetic
> algorithm that is completely independent of the scheduler library. In fact, they
> could be moved to a more generic location in DPDK where they could be
> leveraged by other libraries without the need to create a (fake) dependency to
> librte_sched.
>
> > diff --git a/lib/librte_sched/rte_sched.c
> > b/lib/librte_sched/rte_sched.c index 710ecf65a..11d1febe2 100644
> > --- a/lib/librte_sched/rte_sched.c
> > +++ b/lib/librte_sched/rte_sched.c
> > @@ -49,13 +49,13 @@
> >
> > struct rte_sched_pipe_profile {
> > /* Token bucket (TB) */
> > - uint32_t tb_period;
> > - uint32_t tb_credits_per_period;
> > - uint32_t tb_size;
> > + sched_counter_t tb_period;
> > + sched_counter_t tb_credits_per_period;
> > + sched_counter_t tb_size;
> >
> > /* Pipe traffic classes */
> > - uint32_t tc_period;
> > - uint32_t
> > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t tc_period;
> > + sched_counter_t
> > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > uint8_t tc_ov_weight;
> >
> > /* Pipe best-effort traffic class queues */ @@ -65,20 +65,20 @@
> > struct rte_sched_pipe_profile { struct rte_sched_pipe {
> > /* Token bucket (TB) */
> > uint64_t tb_time; /* time of last update */
> > - uint32_t tb_credits;
> > + sched_counter_t tb_credits;
> >
> > /* Pipe profile and flags */
> > uint32_t profile;
> >
> > /* Traffic classes (TCs) */
> > uint64_t tc_time; /* time of next update */
> > - uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t
> > tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> >
> > /* Weighted Round Robin (WRR) */
> > uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE];
> >
> > /* TC oversubscription */
> > - uint32_t tc_ov_credits;
> > + sched_counter_t tc_ov_credits;
> > uint8_t tc_ov_period_id;
> > } __rte_cache_aligned;
> >
> > @@ -141,28 +141,28 @@ struct rte_sched_grinder { struct
> > rte_sched_subport {
> > /* Token bucket (TB) */
> > uint64_t tb_time; /* time of last update */
> > - uint32_t tb_period;
> > - uint32_t tb_credits_per_period;
> > - uint32_t tb_size;
> > - uint32_t tb_credits;
> > + sched_counter_t tb_period;
> > + sched_counter_t tb_credits_per_period;
> > + sched_counter_t tb_size;
> > + sched_counter_t tb_credits;
> >
> > /* Traffic classes (TCs) */
> > uint64_t tc_time; /* time of next update */
> > - uint32_t
> > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > - uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > - uint32_t tc_period;
> > + sched_counter_t
> > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t
> > tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t tc_period;
> >
> > /* TC oversubscription */
> > - uint32_t tc_ov_wm;
> > - uint32_t tc_ov_wm_min;
> > - uint32_t tc_ov_wm_max;
> > + sched_counter_t tc_ov_wm;
> > + sched_counter_t tc_ov_wm_min;
> > + sched_counter_t tc_ov_wm_max;
> > uint8_t tc_ov_period_id;
> > uint8_t tc_ov;
> > uint32_t tc_ov_n;
> > double tc_ov_rate;
> >
> > /* Statistics */
> > - struct rte_sched_subport_stats stats;
> > + struct rte_sched_subport_stats stats __rte_cache_aligned;
> >
> > /* Subport pipes */
> > uint32_t n_pipes_per_subport_enabled; @@ -170,7 +170,7 @@ struct
> > rte_sched_subport {
> > uint32_t n_max_pipe_profiles;
> >
> > /* Pipe best-effort TC rate */
> > - uint32_t pipe_tc_be_rate_max;
> > + sched_counter_t pipe_tc_be_rate_max;
> >
> > /* Pipe queues size */
> > uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > @@ -212,7 +212,7 @@ struct rte_sched_port {
> > uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
> > uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
> > - uint32_t rate;
> > + sched_counter_t rate;
> > uint32_t mtu;
> > uint32_t frame_overhead;
> > int socket;
> > @@ -517,33 +517,35 @@ rte_sched_port_log_pipe_profile(struct
> > rte_sched_subport *subport, uint32_t i)
> > struct rte_sched_pipe_profile *p = subport->pipe_profiles + i;
> >
> > RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n"
> > - " Token bucket: period = %u, credits per period = %u,
> > size = %u\n"
> > - " Traffic classes: period = %u,\n"
> > - " credits per period = [%u, %u, %u, %u, %u, %u, %u,
> > %u, %u, %u, %u, %u, %u]\n"
> > + " Token bucket: period = %"PRIu64", credits per period
> > = %"PRIu64", size = %"PRIu64"\n"
> > + " Traffic classes: period = %"PRIu64",\n"
> > + " credits per period = [%"PRIu64", %"PRIu64",
> > %"PRIu64", %"PRIu64
> > + ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64",
> > %"PRIu64
> > + ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
> > " Best-effort traffic class oversubscription: weight =
> > %hhu\n"
> > " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n",
> > i,
> >
> > /* Token bucket */
> > - p->tb_period,
> > - p->tb_credits_per_period,
> > - p->tb_size,
> > + (uint64_t)p->tb_period,
> > + (uint64_t)p->tb_credits_per_period,
> > + (uint64_t)p->tb_size,
> >
> > /* Traffic classes */
> > - p->tc_period,
> > - p->tc_credits_per_period[0],
> > - p->tc_credits_per_period[1],
> > - p->tc_credits_per_period[2],
> > - p->tc_credits_per_period[3],
> > - p->tc_credits_per_period[4],
> > - p->tc_credits_per_period[5],
> > - p->tc_credits_per_period[6],
> > - p->tc_credits_per_period[7],
> > - p->tc_credits_per_period[8],
> > - p->tc_credits_per_period[9],
> > - p->tc_credits_per_period[10],
> > - p->tc_credits_per_period[11],
> > - p->tc_credits_per_period[12],
> > + (uint64_t)p->tc_period,
> > + (uint64_t)p->tc_credits_per_period[0],
> > + (uint64_t)p->tc_credits_per_period[1],
> > + (uint64_t)p->tc_credits_per_period[2],
> > + (uint64_t)p->tc_credits_per_period[3],
> > + (uint64_t)p->tc_credits_per_period[4],
> > + (uint64_t)p->tc_credits_per_period[5],
> > + (uint64_t)p->tc_credits_per_period[6],
> > + (uint64_t)p->tc_credits_per_period[7],
> > + (uint64_t)p->tc_credits_per_period[8],
> > + (uint64_t)p->tc_credits_per_period[9],
> > + (uint64_t)p->tc_credits_per_period[10],
> > + (uint64_t)p->tc_credits_per_period[11],
> > + (uint64_t)p->tc_credits_per_period[12],
> >
> > /* Best-effort traffic class oversubscription */
> > p->tc_ov_weight,
> > @@ -553,7 +555,7 @@ rte_sched_port_log_pipe_profile(struct
> > rte_sched_subport *subport, uint32_t i) }
> >
> > static inline uint64_t
> > -rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate)
> > +rte_sched_time_ms_to_bytes(sched_counter_t time_ms,
> > sched_counter_t rate)
> > {
> > uint64_t time = time_ms;
> >
> > @@ -566,7 +568,7 @@ static void
> > rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
> > struct rte_sched_pipe_params *src,
> > struct rte_sched_pipe_profile *dst,
> > - uint32_t rate)
> > + sched_counter_t rate)
> > {
> > uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE];
> > uint32_t lcd1, lcd2, lcd;
> > @@ -581,8 +583,8 @@ rte_sched_pipe_profile_convert(struct
> > rte_sched_subport *subport,
> > / (double) rate;
> > double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
> >
> > - rte_approx(tb_rate, d,
> > - &dst->tb_credits_per_period, &dst->tb_period);
> > + rte_approx(tb_rate, d, &dst->tb_credits_per_period,
> > + &dst->tb_period);
> > }
> >
> > dst->tb_size = src->tb_size;
> > @@ -594,8 +596,8 @@ rte_sched_pipe_profile_convert(struct
> > rte_sched_subport *subport,
> > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
> > if (subport->qsize[i])
> > dst->tc_credits_per_period[i]
> > - = rte_sched_time_ms_to_bytes(src-
> > >tc_period,
> > - src->tc_rate[i]);
> > + = (sched_counter_t)
> > rte_sched_time_ms_to_bytes(
> > + src->tc_period, src->tc_rate[i]);
> >
> > dst->tc_ov_weight = src->tc_ov_weight;
> >
> > @@ -637,7 +639,8 @@ rte_sched_subport_config_pipe_profile_table(struct
> > rte_sched_subport *subport,
> > subport->pipe_tc_be_rate_max = 0;
> > for (i = 0; i < subport->n_pipe_profiles; i++) {
> > struct rte_sched_pipe_params *src = params->pipe_profiles
> > + i;
> > - uint32_t pipe_tc_be_rate = src-
> > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
> > + sched_counter_t pipe_tc_be_rate =
> > + src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
> >
> > if (subport->pipe_tc_be_rate_max < pipe_tc_be_rate)
> > subport->pipe_tc_be_rate_max = pipe_tc_be_rate;
> @@ -647,7 +650,7
> > @@ rte_sched_subport_config_pipe_profile_table(struct
> > rte_sched_subport *subport,
> > static int
> > rte_sched_subport_check_params(struct rte_sched_subport_params
> > *params,
> > uint32_t n_max_pipes_per_subport,
> > - uint32_t rate)
> > + sched_counter_t rate)
> > {
> > uint32_t i;
> >
> > @@ -684,7 +687,7 @@ rte_sched_subport_check_params(struct
> > rte_sched_subport_params *params,
> > }
> >
> > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
> > - uint32_t tc_rate = params->tc_rate[i];
> > + sched_counter_t tc_rate = params->tc_rate[i];
> > uint16_t qsize = params->qsize[i];
> >
> > if ((qsize == 0 && tc_rate != 0) || @@ -910,36 +913,40 @@
> > rte_sched_port_log_subport_config(struct
> > rte_sched_port *port, uint32_t i)
> > struct rte_sched_subport *s = port->subports[i];
> >
> > RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n"
> > - " Token bucket: period = %u, credits per period = %u,
> > size = %u\n"
> > - " Traffic classes: period = %u\n"
> > - " credits per period = [%u, %u, %u, %u, %u, %u, %u,
> > %u, %u, %u, %u, %u, %u]\n"
> > - " Best effort traffic class oversubscription: wm min =
> > %u, wm max = %u\n",
> > + " Token bucket: period = %"PRIu64", credits per period
> > = %"PRIu64
> > + ", size = %"PRIu64"\n"
> > + " Traffic classes: period = %"PRIu64"\n"
> > + " credits per period = [%"PRIu64", %"PRIu64",
> > %"PRIu64", %"PRIu64
> > + ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64",
> > %"PRIu64
> > + ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
> > + " Best effort traffic class oversubscription: wm min =
> > %"PRIu64
> > + ", wm max = %"PRIu64"\n",
> > i,
> >
> > /* Token bucket */
> > - s->tb_period,
> > - s->tb_credits_per_period,
> > - s->tb_size,
> > + (uint64_t)s->tb_period,
> > + (uint64_t)s->tb_credits_per_period,
> > + (uint64_t)s->tb_size,
> >
> > /* Traffic classes */
> > - s->tc_period,
> > - s->tc_credits_per_period[0],
> > - s->tc_credits_per_period[1],
> > - s->tc_credits_per_period[2],
> > - s->tc_credits_per_period[3],
> > - s->tc_credits_per_period[4],
> > - s->tc_credits_per_period[5],
> > - s->tc_credits_per_period[6],
> > - s->tc_credits_per_period[7],
> > - s->tc_credits_per_period[8],
> > - s->tc_credits_per_period[9],
> > - s->tc_credits_per_period[10],
> > - s->tc_credits_per_period[11],
> > - s->tc_credits_per_period[12],
> > + (uint64_t)s->tc_period,
> > + (uint64_t)s->tc_credits_per_period[0],
> > + (uint64_t)s->tc_credits_per_period[1],
> > + (uint64_t)s->tc_credits_per_period[2],
> > + (uint64_t)s->tc_credits_per_period[3],
> > + (uint64_t)s->tc_credits_per_period[4],
> > + (uint64_t)s->tc_credits_per_period[5],
> > + (uint64_t)s->tc_credits_per_period[6],
> > + (uint64_t)s->tc_credits_per_period[7],
> > + (uint64_t)s->tc_credits_per_period[8],
> > + (uint64_t)s->tc_credits_per_period[9],
> > + (uint64_t)s->tc_credits_per_period[10],
> > + (uint64_t)s->tc_credits_per_period[11],
> > + (uint64_t)s->tc_credits_per_period[12],
> >
> > /* Best effort traffic class oversubscription */
> > - s->tc_ov_wm_min,
> > - s->tc_ov_wm_max);
> > + (uint64_t)s->tc_ov_wm_min,
> > + (uint64_t)s->tc_ov_wm_max);
> > }
> >
> > static void
> > @@ -1023,7 +1030,8 @@ rte_sched_subport_config(struct rte_sched_port
> > *port,
> > double tb_rate = ((double) params->tb_rate) / ((double)
> > port->rate);
> > double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
> >
> > - rte_approx(tb_rate, d, &s->tb_credits_per_period, &s-
> > >tb_period);
> > + rte_approx(tb_rate, d, &s->tb_credits_per_period,
> > + &s->tb_period);
> > }
> >
> > s->tb_size = params->tb_size;
> > @@ -1035,8 +1043,8 @@ rte_sched_subport_config(struct rte_sched_port
> > *port,
> > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
> > if (params->qsize[i])
> > s->tc_credits_per_period[i]
> > - = rte_sched_time_ms_to_bytes(params-
> > >tc_period,
> > - params->tc_rate[i]);
> > + = (sched_counter_t)
> > rte_sched_time_ms_to_bytes(
> > + params->tc_period, params-
> > >tc_rate[i]);
> > }
> > s->tc_time = port->time + s->tc_period;
> > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) @@ -
> 1970,13
> > +1978,15 @@ grinder_credits_update(struct rte_sched_port *port,
> > /* Subport TB */
> > n_periods = (port->time - subport->tb_time) / subport->tb_period;
> > subport->tb_credits += n_periods * subport-
> > >tb_credits_per_period;
> > - subport->tb_credits = rte_sched_min_val_2_u32(subport-
> > >tb_credits, subport->tb_size);
> > + subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
> > + subport->tb_size);
> > subport->tb_time += n_periods * subport->tb_period;
> >
> > /* Pipe TB */
> > n_periods = (port->time - pipe->tb_time) / params->tb_period;
> > pipe->tb_credits += n_periods * params->tb_credits_per_period;
> > - pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits,
> > params->tb_size);
> > + pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
> > + params->tb_size);
>
> Can we remove all the usages of rte_sched_min_val() (including its definition in
> rte_sched_common.h) and replace it with RTE_MIN, please?
>
> > pipe->tb_time += n_periods * params->tb_period;
> >
> > /* Subport TCs */
> > @@ -1998,13 +2008,13 @@ grinder_credits_update(struct rte_sched_port
> > *port,
> >
> > #else
> >
> > -static inline uint32_t
> > +static inline sched_counter_t
> > grinder_tc_ov_credits_update(struct rte_sched_port *port,
> > struct rte_sched_subport *subport)
> > {
> > - uint32_t
> > tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > - uint32_t tc_consumption = 0, tc_ov_consumption_max;
> > - uint32_t tc_ov_wm = subport->tc_ov_wm;
> > + sched_counter_t
> > tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t tc_consumption = 0, tc_ov_consumption_max;
> > + sched_counter_t tc_ov_wm = subport->tc_ov_wm;
> > uint32_t i;
> >
> > if (subport->tc_ov == 0)
> > @@ -2053,13 +2063,15 @@ grinder_credits_update(struct rte_sched_port
> > *port,
> > /* Subport TB */
> > n_periods = (port->time - subport->tb_time) / subport->tb_period;
> > subport->tb_credits += n_periods * subport-
> > >tb_credits_per_period;
> > - subport->tb_credits = rte_sched_min_val_2_u32(subport-
> > >tb_credits, subport->tb_size);
> > + subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
> > + subport->tb_size);
> > subport->tb_time += n_periods * subport->tb_period;
> >
> > /* Pipe TB */
> > n_periods = (port->time - pipe->tb_time) / params->tb_period;
> > pipe->tb_credits += n_periods * params->tb_credits_per_period;
> > - pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits,
> > params->tb_size);
> > + pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
> > + params->tb_size);
> > pipe->tb_time += n_periods * params->tb_period;
> >
> > /* Subport TCs */
> > @@ -2101,11 +2113,11 @@ grinder_credits_check(struct rte_sched_port
> > *port,
> > struct rte_sched_pipe *pipe = grinder->pipe;
> > struct rte_mbuf *pkt = grinder->pkt;
> > uint32_t tc_index = grinder->tc_index;
> > - uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
> > - uint32_t subport_tb_credits = subport->tb_credits;
> > - uint32_t subport_tc_credits = subport->tc_credits[tc_index];
> > - uint32_t pipe_tb_credits = pipe->tb_credits;
> > - uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
> > + sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
> > + sched_counter_t subport_tb_credits = subport->tb_credits;
> > + sched_counter_t subport_tc_credits = subport-
> > >tc_credits[tc_index];
> > + sched_counter_t pipe_tb_credits = pipe->tb_credits;
> > + sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
> > int enough_credits;
> >
> > /* Check queue credits */
> > @@ -2136,21 +2148,22 @@ grinder_credits_check(struct rte_sched_port
> > *port,
> > struct rte_sched_pipe *pipe = grinder->pipe;
> > struct rte_mbuf *pkt = grinder->pkt;
> > uint32_t tc_index = grinder->tc_index;
> > - uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
> > - uint32_t subport_tb_credits = subport->tb_credits;
> > - uint32_t subport_tc_credits = subport->tc_credits[tc_index];
> > - uint32_t pipe_tb_credits = pipe->tb_credits;
> > - uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
> > - uint32_t
> > pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > - uint32_t
> > pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
> > - uint32_t pipe_tc_ov_credits, i;
> > + sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
> > + sched_counter_t subport_tb_credits = subport->tb_credits;
> > + sched_counter_t subport_tc_credits = subport-
> > >tc_credits[tc_index];
> > + sched_counter_t pipe_tb_credits = pipe->tb_credits;
> > + sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
> > + sched_counter_t
> > pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> > + sched_counter_t
> > pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
> > + sched_counter_t pipe_tc_ov_credits;
> > + uint32_t i;
> > int enough_credits;
> >
> > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
> > - pipe_tc_ov_mask1[i] = UINT32_MAX;
> > + pipe_tc_ov_mask1[i] = ~0;
>
> Please use ~0LLU (or UINT64_MAX) to cover the 64-bit case gracefully. Please
> also double-check that there are no usages of UINT32_MAX left in this code,
> unless there is a reason for it. Translation from 32-bit to 64-bit arithmetic can
> be very tricky and yield some very difficult to debug issues.
Ok, will make this change. Also will make sure the there are no usage of UINT32_MAX left.
> >
> > pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe-
> > >tc_ov_credits;
> > - pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] =
> > UINT32_MAX;
> > + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = ~0;
> > pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index];
> >
> > /* Check pipe and subport credits */ diff --git
> > a/lib/librte_sched/rte_sched_common.h
> > b/lib/librte_sched/rte_sched_common.h
> > index 8c191a9b8..06520a686 100644
> > --- a/lib/librte_sched/rte_sched_common.h
> > +++ b/lib/librte_sched/rte_sched_common.h
> > @@ -14,8 +14,16 @@ extern "C" {
> >
> > #define __rte_aligned_16 __attribute__((__aligned__(16)))
> >
> > -static inline uint32_t
> > -rte_sched_min_val_2_u32(uint32_t x, uint32_t y)
> > +//#define COUNTER_SIZE_64
> > +
> > +#ifdef COUNTER_SIZE_64
> > +typedef uint64_t sched_counter_t;
> > +#else
> > +typedef uint32_t sched_counter_t;
> > +#endif
> > +
> > +static inline sched_counter_t
> > +rte_sched_min_val_2(sched_counter_t x, sched_counter_t y)
> > {
> > return (x < y)? x : y;
> > }
> > --
> > 2.21.0
>
> I know I have previously suggested the creation of sched_counter_t, but this
> was meant to be a temporary solution until the full implementation is made
> available. Now that 19.11 is meant to be an ABI stable release, we cannot
> really afford this trick (which might not be necessary either, since you have the
> full implementation), as this #ifdef COUNTER_SIZE is a massive ABI breakage.
>
> Therefore, I strongly suggest we remove the sched_counter_t and use uint64_t
> everywhere throughout the implementation. Agree?
Yes, will make changes.
Thank you for the detailed review. I'll send revised version.
Regards,
Jasvinder
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 2/2] sched: modify internal structs and functions for 64 bit values
@ 2019-10-15 15:47 4% ` Dumitrescu, Cristian
2019-10-15 16:01 0% ` Singh, Jasvinder
0 siblings, 1 reply; 200+ results
From: Dumitrescu, Cristian @ 2019-10-15 15:47 UTC (permalink / raw)
To: Singh, Jasvinder, dev; +Cc: Krakowiak, LukaszX
Hi Jasvinder,
> -----Original Message-----
> From: Singh, Jasvinder
> Sent: Monday, October 14, 2019 6:25 PM
> To: dev@dpdk.org
> Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Krakowiak,
> LukaszX <lukaszx.krakowiak@intel.com>
> Subject: [PATCH 2/2] sched: modify internal structs and functions for 64 bit
> values
>
> Modify internal structure and functions to support 64-bit
> values for rates and stats parameters.
>
> Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com>
> ---
> lib/librte_sched/rte_approx.c | 57 ++++----
> lib/librte_sched/rte_approx.h | 3 +-
> lib/librte_sched/rte_sched.c | 211 +++++++++++++++-------------
> lib/librte_sched/rte_sched_common.h | 12 +-
> 4 files changed, 156 insertions(+), 127 deletions(-)
>
> diff --git a/lib/librte_sched/rte_approx.c b/lib/librte_sched/rte_approx.c
> index 30620b83d..4883d3969 100644
> --- a/lib/librte_sched/rte_approx.c
> +++ b/lib/librte_sched/rte_approx.c
> @@ -18,22 +18,23 @@
> */
>
> /* fraction comparison: compare (a/b) and (c/d) */
> -static inline uint32_t
> -less(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
> +static inline sched_counter_t
> +less(sched_counter_t a, sched_counter_t b, sched_counter_t c,
> sched_counter_t d)
> {
> return a*d < b*c;
> }
>
> -static inline uint32_t
> -less_or_equal(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
> +static inline sched_counter_t
> +less_or_equal(sched_counter_t a, sched_counter_t b, sched_counter_t c,
> + sched_counter_t d)
> {
> return a*d <= b*c;
> }
>
> /* check whether a/b is a valid approximation */
> -static inline uint32_t
> -matches(uint32_t a, uint32_t b,
> - uint32_t alpha_num, uint32_t d_num, uint32_t denum)
> +static inline sched_counter_t
> +matches(sched_counter_t a, sched_counter_t b,
> + sched_counter_t alpha_num, sched_counter_t d_num,
> sched_counter_t denum)
> {
> if (less_or_equal(a, b, alpha_num - d_num, denum))
> return 0;
> @@ -45,33 +46,39 @@ matches(uint32_t a, uint32_t b,
> }
>
> static inline void
> -find_exact_solution_left(uint32_t p_a, uint32_t q_a, uint32_t p_b, uint32_t
> q_b,
> - uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p,
> uint32_t *q)
> +find_exact_solution_left(sched_counter_t p_a, sched_counter_t q_a,
> + sched_counter_t p_b, sched_counter_t q_b, sched_counter_t
> alpha_num,
> + sched_counter_t d_num, sched_counter_t denum,
> sched_counter_t *p,
> + sched_counter_t *q)
> {
> - uint32_t k_num = denum * p_b - (alpha_num + d_num) * q_b;
> - uint32_t k_denum = (alpha_num + d_num) * q_a - denum * p_a;
> - uint32_t k = (k_num / k_denum) + 1;
> + sched_counter_t k_num = denum * p_b - (alpha_num + d_num) *
> q_b;
> + sched_counter_t k_denum = (alpha_num + d_num) * q_a - denum *
> p_a;
> + sched_counter_t k = (k_num / k_denum) + 1;
>
> *p = p_b + k * p_a;
> *q = q_b + k * q_a;
> }
>
> static inline void
> -find_exact_solution_right(uint32_t p_a, uint32_t q_a, uint32_t p_b,
> uint32_t q_b,
> - uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p,
> uint32_t *q)
> +find_exact_solution_right(sched_counter_t p_a, sched_counter_t q_a,
> + sched_counter_t p_b, sched_counter_t q_b, sched_counter_t
> alpha_num,
> + sched_counter_t d_num, sched_counter_t denum,
> sched_counter_t *p,
> + sched_counter_t *q)
> {
> - uint32_t k_num = - denum * p_b + (alpha_num - d_num) * q_b;
> - uint32_t k_denum = - (alpha_num - d_num) * q_a + denum * p_a;
> - uint32_t k = (k_num / k_denum) + 1;
> + sched_counter_t k_num = -denum * p_b + (alpha_num - d_num) *
> q_b;
> + sched_counter_t k_denum = -(alpha_num - d_num) * q_a + denum
> * p_a;
> + sched_counter_t k = (k_num / k_denum) + 1;
>
> *p = p_b + k * p_a;
> *q = q_b + k * q_a;
> }
>
> static int
> -find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num,
> uint32_t denum, uint32_t *p, uint32_t *q)
> +find_best_rational_approximation(sched_counter_t alpha_num,
> + sched_counter_t d_num, sched_counter_t denum,
> sched_counter_t *p,
> + sched_counter_t *q)
> {
> - uint32_t p_a, q_a, p_b, q_b;
> + sched_counter_t p_a, q_a, p_b, q_b;
>
> /* check assumptions on the inputs */
> if (!((0 < d_num) && (d_num < alpha_num) && (alpha_num <
> denum) && (d_num + alpha_num < denum))) {
> @@ -85,8 +92,8 @@ find_best_rational_approximation(uint32_t alpha_num,
> uint32_t d_num, uint32_t de
> q_b = 1;
>
> while (1) {
> - uint32_t new_p_a, new_q_a, new_p_b, new_q_b;
> - uint32_t x_num, x_denum, x;
> + sched_counter_t new_p_a, new_q_a, new_p_b, new_q_b;
> + sched_counter_t x_num, x_denum, x;
> int aa, bb;
>
> /* compute the number of steps to the left */
> @@ -139,9 +146,9 @@ find_best_rational_approximation(uint32_t
> alpha_num, uint32_t d_num, uint32_t de
> }
> }
>
> -int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q)
> +int rte_approx(double alpha, double d, sched_counter_t *p,
> sched_counter_t *q)
> {
> - uint32_t alpha_num, d_num, denum;
> + sched_counter_t alpha_num, d_num, denum;
>
> /* Check input arguments */
> if (!((0.0 < d) && (d < alpha) && (alpha < 1.0))) {
> @@ -159,8 +166,8 @@ int rte_approx(double alpha, double d, uint32_t *p,
> uint32_t *q)
> d *= 10;
> denum *= 10;
> }
> - alpha_num = (uint32_t) alpha;
> - d_num = (uint32_t) d;
> + alpha_num = (sched_counter_t) alpha;
> + d_num = (sched_counter_t) d;
>
> /* Perform approximation */
> return find_best_rational_approximation(alpha_num, d_num,
> denum, p, q);
> diff --git a/lib/librte_sched/rte_approx.h b/lib/librte_sched/rte_approx.h
> index 0244d98f1..e591e122d 100644
> --- a/lib/librte_sched/rte_approx.h
> +++ b/lib/librte_sched/rte_approx.h
> @@ -20,6 +20,7 @@ extern "C" {
> ***/
>
> #include <stdint.h>
> +#include "rte_sched_common.h"
>
> /**
> * Find best rational approximation
> @@ -37,7 +38,7 @@ extern "C" {
> * @return
> * 0 upon success, error code otherwise
> */
> -int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q);
> +int rte_approx(double alpha, double d, sched_counter_t *p,
> sched_counter_t *q);
>
> #ifdef __cplusplus
> }
Please keep the rte_approx.[hc] independent of the librte_sched library, so use unit32_t or uint64_t instead of sched_counter_t that is librte_sched dependent. Also, for the same reason, remove the above inclusion of rte_sched_common.h.
Please keep the existing 32-bit functions with their current name & prototype and create new 64-bit functions that have the "64" suffix to their name, and use the 64-bit versions in the rte_sched.c implementation. Makes sense?
The rte_approx.[hc] files represent the implementation of an arithmetic algorithm that is completely independent of the scheduler library. In fact, they could be moved to a more generic location in DPDK where they could be leveraged by other libraries without the need to create a (fake) dependency to librte_sched.
> diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
> index 710ecf65a..11d1febe2 100644
> --- a/lib/librte_sched/rte_sched.c
> +++ b/lib/librte_sched/rte_sched.c
> @@ -49,13 +49,13 @@
>
> struct rte_sched_pipe_profile {
> /* Token bucket (TB) */
> - uint32_t tb_period;
> - uint32_t tb_credits_per_period;
> - uint32_t tb_size;
> + sched_counter_t tb_period;
> + sched_counter_t tb_credits_per_period;
> + sched_counter_t tb_size;
>
> /* Pipe traffic classes */
> - uint32_t tc_period;
> - uint32_t
> tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t tc_period;
> + sched_counter_t
> tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> uint8_t tc_ov_weight;
>
> /* Pipe best-effort traffic class queues */
> @@ -65,20 +65,20 @@ struct rte_sched_pipe_profile {
> struct rte_sched_pipe {
> /* Token bucket (TB) */
> uint64_t tb_time; /* time of last update */
> - uint32_t tb_credits;
> + sched_counter_t tb_credits;
>
> /* Pipe profile and flags */
> uint32_t profile;
>
> /* Traffic classes (TCs) */
> uint64_t tc_time; /* time of next update */
> - uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t
> tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
>
> /* Weighted Round Robin (WRR) */
> uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE];
>
> /* TC oversubscription */
> - uint32_t tc_ov_credits;
> + sched_counter_t tc_ov_credits;
> uint8_t tc_ov_period_id;
> } __rte_cache_aligned;
>
> @@ -141,28 +141,28 @@ struct rte_sched_grinder {
> struct rte_sched_subport {
> /* Token bucket (TB) */
> uint64_t tb_time; /* time of last update */
> - uint32_t tb_period;
> - uint32_t tb_credits_per_period;
> - uint32_t tb_size;
> - uint32_t tb_credits;
> + sched_counter_t tb_period;
> + sched_counter_t tb_credits_per_period;
> + sched_counter_t tb_size;
> + sched_counter_t tb_credits;
>
> /* Traffic classes (TCs) */
> uint64_t tc_time; /* time of next update */
> - uint32_t
> tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> - uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> - uint32_t tc_period;
> + sched_counter_t
> tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t
> tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t tc_period;
>
> /* TC oversubscription */
> - uint32_t tc_ov_wm;
> - uint32_t tc_ov_wm_min;
> - uint32_t tc_ov_wm_max;
> + sched_counter_t tc_ov_wm;
> + sched_counter_t tc_ov_wm_min;
> + sched_counter_t tc_ov_wm_max;
> uint8_t tc_ov_period_id;
> uint8_t tc_ov;
> uint32_t tc_ov_n;
> double tc_ov_rate;
>
> /* Statistics */
> - struct rte_sched_subport_stats stats;
> + struct rte_sched_subport_stats stats __rte_cache_aligned;
>
> /* Subport pipes */
> uint32_t n_pipes_per_subport_enabled;
> @@ -170,7 +170,7 @@ struct rte_sched_subport {
> uint32_t n_max_pipe_profiles;
>
> /* Pipe best-effort TC rate */
> - uint32_t pipe_tc_be_rate_max;
> + sched_counter_t pipe_tc_be_rate_max;
>
> /* Pipe queues size */
> uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> @@ -212,7 +212,7 @@ struct rte_sched_port {
> uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
> uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
> - uint32_t rate;
> + sched_counter_t rate;
> uint32_t mtu;
> uint32_t frame_overhead;
> int socket;
> @@ -517,33 +517,35 @@ rte_sched_port_log_pipe_profile(struct
> rte_sched_subport *subport, uint32_t i)
> struct rte_sched_pipe_profile *p = subport->pipe_profiles + i;
>
> RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n"
> - " Token bucket: period = %u, credits per period = %u,
> size = %u\n"
> - " Traffic classes: period = %u,\n"
> - " credits per period = [%u, %u, %u, %u, %u, %u, %u,
> %u, %u, %u, %u, %u, %u]\n"
> + " Token bucket: period = %"PRIu64", credits per period
> = %"PRIu64", size = %"PRIu64"\n"
> + " Traffic classes: period = %"PRIu64",\n"
> + " credits per period = [%"PRIu64", %"PRIu64",
> %"PRIu64", %"PRIu64
> + ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64",
> %"PRIu64
> + ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
> " Best-effort traffic class oversubscription: weight =
> %hhu\n"
> " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n",
> i,
>
> /* Token bucket */
> - p->tb_period,
> - p->tb_credits_per_period,
> - p->tb_size,
> + (uint64_t)p->tb_period,
> + (uint64_t)p->tb_credits_per_period,
> + (uint64_t)p->tb_size,
>
> /* Traffic classes */
> - p->tc_period,
> - p->tc_credits_per_period[0],
> - p->tc_credits_per_period[1],
> - p->tc_credits_per_period[2],
> - p->tc_credits_per_period[3],
> - p->tc_credits_per_period[4],
> - p->tc_credits_per_period[5],
> - p->tc_credits_per_period[6],
> - p->tc_credits_per_period[7],
> - p->tc_credits_per_period[8],
> - p->tc_credits_per_period[9],
> - p->tc_credits_per_period[10],
> - p->tc_credits_per_period[11],
> - p->tc_credits_per_period[12],
> + (uint64_t)p->tc_period,
> + (uint64_t)p->tc_credits_per_period[0],
> + (uint64_t)p->tc_credits_per_period[1],
> + (uint64_t)p->tc_credits_per_period[2],
> + (uint64_t)p->tc_credits_per_period[3],
> + (uint64_t)p->tc_credits_per_period[4],
> + (uint64_t)p->tc_credits_per_period[5],
> + (uint64_t)p->tc_credits_per_period[6],
> + (uint64_t)p->tc_credits_per_period[7],
> + (uint64_t)p->tc_credits_per_period[8],
> + (uint64_t)p->tc_credits_per_period[9],
> + (uint64_t)p->tc_credits_per_period[10],
> + (uint64_t)p->tc_credits_per_period[11],
> + (uint64_t)p->tc_credits_per_period[12],
>
> /* Best-effort traffic class oversubscription */
> p->tc_ov_weight,
> @@ -553,7 +555,7 @@ rte_sched_port_log_pipe_profile(struct
> rte_sched_subport *subport, uint32_t i)
> }
>
> static inline uint64_t
> -rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate)
> +rte_sched_time_ms_to_bytes(sched_counter_t time_ms,
> sched_counter_t rate)
> {
> uint64_t time = time_ms;
>
> @@ -566,7 +568,7 @@ static void
> rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
> struct rte_sched_pipe_params *src,
> struct rte_sched_pipe_profile *dst,
> - uint32_t rate)
> + sched_counter_t rate)
> {
> uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE];
> uint32_t lcd1, lcd2, lcd;
> @@ -581,8 +583,8 @@ rte_sched_pipe_profile_convert(struct
> rte_sched_subport *subport,
> / (double) rate;
> double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
>
> - rte_approx(tb_rate, d,
> - &dst->tb_credits_per_period, &dst->tb_period);
> + rte_approx(tb_rate, d, &dst->tb_credits_per_period,
> + &dst->tb_period);
> }
>
> dst->tb_size = src->tb_size;
> @@ -594,8 +596,8 @@ rte_sched_pipe_profile_convert(struct
> rte_sched_subport *subport,
> for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
> if (subport->qsize[i])
> dst->tc_credits_per_period[i]
> - = rte_sched_time_ms_to_bytes(src-
> >tc_period,
> - src->tc_rate[i]);
> + = (sched_counter_t)
> rte_sched_time_ms_to_bytes(
> + src->tc_period, src->tc_rate[i]);
>
> dst->tc_ov_weight = src->tc_ov_weight;
>
> @@ -637,7 +639,8 @@ rte_sched_subport_config_pipe_profile_table(struct
> rte_sched_subport *subport,
> subport->pipe_tc_be_rate_max = 0;
> for (i = 0; i < subport->n_pipe_profiles; i++) {
> struct rte_sched_pipe_params *src = params->pipe_profiles
> + i;
> - uint32_t pipe_tc_be_rate = src-
> >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
> + sched_counter_t pipe_tc_be_rate =
> + src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
>
> if (subport->pipe_tc_be_rate_max < pipe_tc_be_rate)
> subport->pipe_tc_be_rate_max = pipe_tc_be_rate;
> @@ -647,7 +650,7 @@ rte_sched_subport_config_pipe_profile_table(struct
> rte_sched_subport *subport,
> static int
> rte_sched_subport_check_params(struct rte_sched_subport_params
> *params,
> uint32_t n_max_pipes_per_subport,
> - uint32_t rate)
> + sched_counter_t rate)
> {
> uint32_t i;
>
> @@ -684,7 +687,7 @@ rte_sched_subport_check_params(struct
> rte_sched_subport_params *params,
> }
>
> for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
> - uint32_t tc_rate = params->tc_rate[i];
> + sched_counter_t tc_rate = params->tc_rate[i];
> uint16_t qsize = params->qsize[i];
>
> if ((qsize == 0 && tc_rate != 0) ||
> @@ -910,36 +913,40 @@ rte_sched_port_log_subport_config(struct
> rte_sched_port *port, uint32_t i)
> struct rte_sched_subport *s = port->subports[i];
>
> RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n"
> - " Token bucket: period = %u, credits per period = %u,
> size = %u\n"
> - " Traffic classes: period = %u\n"
> - " credits per period = [%u, %u, %u, %u, %u, %u, %u,
> %u, %u, %u, %u, %u, %u]\n"
> - " Best effort traffic class oversubscription: wm min =
> %u, wm max = %u\n",
> + " Token bucket: period = %"PRIu64", credits per period
> = %"PRIu64
> + ", size = %"PRIu64"\n"
> + " Traffic classes: period = %"PRIu64"\n"
> + " credits per period = [%"PRIu64", %"PRIu64",
> %"PRIu64", %"PRIu64
> + ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64",
> %"PRIu64
> + ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
> + " Best effort traffic class oversubscription: wm min =
> %"PRIu64
> + ", wm max = %"PRIu64"\n",
> i,
>
> /* Token bucket */
> - s->tb_period,
> - s->tb_credits_per_period,
> - s->tb_size,
> + (uint64_t)s->tb_period,
> + (uint64_t)s->tb_credits_per_period,
> + (uint64_t)s->tb_size,
>
> /* Traffic classes */
> - s->tc_period,
> - s->tc_credits_per_period[0],
> - s->tc_credits_per_period[1],
> - s->tc_credits_per_period[2],
> - s->tc_credits_per_period[3],
> - s->tc_credits_per_period[4],
> - s->tc_credits_per_period[5],
> - s->tc_credits_per_period[6],
> - s->tc_credits_per_period[7],
> - s->tc_credits_per_period[8],
> - s->tc_credits_per_period[9],
> - s->tc_credits_per_period[10],
> - s->tc_credits_per_period[11],
> - s->tc_credits_per_period[12],
> + (uint64_t)s->tc_period,
> + (uint64_t)s->tc_credits_per_period[0],
> + (uint64_t)s->tc_credits_per_period[1],
> + (uint64_t)s->tc_credits_per_period[2],
> + (uint64_t)s->tc_credits_per_period[3],
> + (uint64_t)s->tc_credits_per_period[4],
> + (uint64_t)s->tc_credits_per_period[5],
> + (uint64_t)s->tc_credits_per_period[6],
> + (uint64_t)s->tc_credits_per_period[7],
> + (uint64_t)s->tc_credits_per_period[8],
> + (uint64_t)s->tc_credits_per_period[9],
> + (uint64_t)s->tc_credits_per_period[10],
> + (uint64_t)s->tc_credits_per_period[11],
> + (uint64_t)s->tc_credits_per_period[12],
>
> /* Best effort traffic class oversubscription */
> - s->tc_ov_wm_min,
> - s->tc_ov_wm_max);
> + (uint64_t)s->tc_ov_wm_min,
> + (uint64_t)s->tc_ov_wm_max);
> }
>
> static void
> @@ -1023,7 +1030,8 @@ rte_sched_subport_config(struct rte_sched_port
> *port,
> double tb_rate = ((double) params->tb_rate) / ((double)
> port->rate);
> double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
>
> - rte_approx(tb_rate, d, &s->tb_credits_per_period, &s-
> >tb_period);
> + rte_approx(tb_rate, d, &s->tb_credits_per_period,
> + &s->tb_period);
> }
>
> s->tb_size = params->tb_size;
> @@ -1035,8 +1043,8 @@ rte_sched_subport_config(struct rte_sched_port
> *port,
> for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
> if (params->qsize[i])
> s->tc_credits_per_period[i]
> - = rte_sched_time_ms_to_bytes(params-
> >tc_period,
> - params->tc_rate[i]);
> + = (sched_counter_t)
> rte_sched_time_ms_to_bytes(
> + params->tc_period, params-
> >tc_rate[i]);
> }
> s->tc_time = port->time + s->tc_period;
> for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
> @@ -1970,13 +1978,15 @@ grinder_credits_update(struct rte_sched_port
> *port,
> /* Subport TB */
> n_periods = (port->time - subport->tb_time) / subport->tb_period;
> subport->tb_credits += n_periods * subport-
> >tb_credits_per_period;
> - subport->tb_credits = rte_sched_min_val_2_u32(subport-
> >tb_credits, subport->tb_size);
> + subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
> + subport->tb_size);
> subport->tb_time += n_periods * subport->tb_period;
>
> /* Pipe TB */
> n_periods = (port->time - pipe->tb_time) / params->tb_period;
> pipe->tb_credits += n_periods * params->tb_credits_per_period;
> - pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits,
> params->tb_size);
> + pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
> + params->tb_size);
Can we remove all the usages of rte_sched_min_val() (including its definition in rte_sched_common.h) and replace it with RTE_MIN, please?
> pipe->tb_time += n_periods * params->tb_period;
>
> /* Subport TCs */
> @@ -1998,13 +2008,13 @@ grinder_credits_update(struct rte_sched_port
> *port,
>
> #else
>
> -static inline uint32_t
> +static inline sched_counter_t
> grinder_tc_ov_credits_update(struct rte_sched_port *port,
> struct rte_sched_subport *subport)
> {
> - uint32_t
> tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> - uint32_t tc_consumption = 0, tc_ov_consumption_max;
> - uint32_t tc_ov_wm = subport->tc_ov_wm;
> + sched_counter_t
> tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t tc_consumption = 0, tc_ov_consumption_max;
> + sched_counter_t tc_ov_wm = subport->tc_ov_wm;
> uint32_t i;
>
> if (subport->tc_ov == 0)
> @@ -2053,13 +2063,15 @@ grinder_credits_update(struct rte_sched_port
> *port,
> /* Subport TB */
> n_periods = (port->time - subport->tb_time) / subport->tb_period;
> subport->tb_credits += n_periods * subport-
> >tb_credits_per_period;
> - subport->tb_credits = rte_sched_min_val_2_u32(subport-
> >tb_credits, subport->tb_size);
> + subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
> + subport->tb_size);
> subport->tb_time += n_periods * subport->tb_period;
>
> /* Pipe TB */
> n_periods = (port->time - pipe->tb_time) / params->tb_period;
> pipe->tb_credits += n_periods * params->tb_credits_per_period;
> - pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits,
> params->tb_size);
> + pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
> + params->tb_size);
> pipe->tb_time += n_periods * params->tb_period;
>
> /* Subport TCs */
> @@ -2101,11 +2113,11 @@ grinder_credits_check(struct rte_sched_port
> *port,
> struct rte_sched_pipe *pipe = grinder->pipe;
> struct rte_mbuf *pkt = grinder->pkt;
> uint32_t tc_index = grinder->tc_index;
> - uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
> - uint32_t subport_tb_credits = subport->tb_credits;
> - uint32_t subport_tc_credits = subport->tc_credits[tc_index];
> - uint32_t pipe_tb_credits = pipe->tb_credits;
> - uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
> + sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
> + sched_counter_t subport_tb_credits = subport->tb_credits;
> + sched_counter_t subport_tc_credits = subport-
> >tc_credits[tc_index];
> + sched_counter_t pipe_tb_credits = pipe->tb_credits;
> + sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
> int enough_credits;
>
> /* Check queue credits */
> @@ -2136,21 +2148,22 @@ grinder_credits_check(struct rte_sched_port
> *port,
> struct rte_sched_pipe *pipe = grinder->pipe;
> struct rte_mbuf *pkt = grinder->pkt;
> uint32_t tc_index = grinder->tc_index;
> - uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
> - uint32_t subport_tb_credits = subport->tb_credits;
> - uint32_t subport_tc_credits = subport->tc_credits[tc_index];
> - uint32_t pipe_tb_credits = pipe->tb_credits;
> - uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
> - uint32_t
> pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> - uint32_t
> pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
> - uint32_t pipe_tc_ov_credits, i;
> + sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
> + sched_counter_t subport_tb_credits = subport->tb_credits;
> + sched_counter_t subport_tc_credits = subport-
> >tc_credits[tc_index];
> + sched_counter_t pipe_tb_credits = pipe->tb_credits;
> + sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
> + sched_counter_t
> pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
> + sched_counter_t
> pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
> + sched_counter_t pipe_tc_ov_credits;
> + uint32_t i;
> int enough_credits;
>
> for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
> - pipe_tc_ov_mask1[i] = UINT32_MAX;
> + pipe_tc_ov_mask1[i] = ~0;
Please use ~0LLU (or UINT64_MAX) to cover the 64-bit case gracefully. Please also double-check that there are no usages of UINT32_MAX left in this code, unless there is a reason for it. Translation from 32-bit to 64-bit arithmetic can be very tricky and yield some very difficult to debug issues.
>
> pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe-
> >tc_ov_credits;
> - pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] =
> UINT32_MAX;
> + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = ~0;
> pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index];
>
> /* Check pipe and subport credits */
> diff --git a/lib/librte_sched/rte_sched_common.h
> b/lib/librte_sched/rte_sched_common.h
> index 8c191a9b8..06520a686 100644
> --- a/lib/librte_sched/rte_sched_common.h
> +++ b/lib/librte_sched/rte_sched_common.h
> @@ -14,8 +14,16 @@ extern "C" {
>
> #define __rte_aligned_16 __attribute__((__aligned__(16)))
>
> -static inline uint32_t
> -rte_sched_min_val_2_u32(uint32_t x, uint32_t y)
> +//#define COUNTER_SIZE_64
> +
> +#ifdef COUNTER_SIZE_64
> +typedef uint64_t sched_counter_t;
> +#else
> +typedef uint32_t sched_counter_t;
> +#endif
> +
> +static inline sched_counter_t
> +rte_sched_min_val_2(sched_counter_t x, sched_counter_t y)
> {
> return (x < y)? x : y;
> }
> --
> 2.21.0
I know I have previously suggested the creation of sched_counter_t, but this was meant to be a temporary solution until the full implementation is made available. Now that 19.11 is meant to be an ABI stable release, we cannot really afford this trick (which might not be necessary either, since you have the full implementation), as this #ifdef COUNTER_SIZE is a massive ABI breakage.
Therefore, I strongly suggest we remove the sched_counter_t and use uint64_t everywhere throughout the implementation. Agree?
Regards,
Cristian
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v6 2/4] doc: changes to abi policy introducing major abi versions
@ 2019-10-15 15:11 5% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-15 15:11 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, Thomas Monjalon, Stephen Hemminger, Bruce Richardson, Yigit,
Ferruh, Ananyev, Konstantin, Jerin Jacob Kollanukkaran,
Olivier Matz, Neil Horman, Maxime Coquelin, Mcnamara, John,
Kovacevic, Marko, Hemant Agrawal, Kevin Traynor, Aaron Conole
Hello,
On Fri, Sep 27, 2019 at 6:55 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>
> This policy change introduces major ABI versions, these are
> declared every year, typically aligned with the LTS release
> and are supported by subsequent releases in the following year.
> This change is intended to improve ABI stabilty for those projects
> consuming DPDK.
I spotted a few typos (far from being a complete report of them).
We can wait later in the release to fix those, but it would be more
efficient if native speakers proofread those docs.
John and Marko?
Volunteers?
Thanks.
>
> Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
> ---
> doc/guides/contributing/abi_policy.rst | 321 +++++++++++++++------
> .../contributing/img/abi_stability_policy.png | Bin 0 -> 61277 bytes
> doc/guides/contributing/img/what_is_an_abi.png | Bin 0 -> 151683 bytes
> doc/guides/contributing/stable.rst | 12 +-
> 4 files changed, 241 insertions(+), 92 deletions(-)
> create mode 100644 doc/guides/contributing/img/abi_stability_policy.png
> create mode 100644 doc/guides/contributing/img/what_is_an_abi.png
>
> diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
> index 55bacb4..8862d24 100644
> --- a/doc/guides/contributing/abi_policy.rst
> +++ b/doc/guides/contributing/abi_policy.rst
> @@ -1,33 +1,46 @@
> .. SPDX-License-Identifier: BSD-3-Clause
> - Copyright 2018 The DPDK contributors
> + Copyright 2019 The DPDK contributors
>
> -.. abi_api_policy:
> +.. _abi_policy:
>
> -DPDK ABI/API policy
> -===================
> +ABI Policy
> +==========
>
> Description
> -----------
>
> -This document details some methods for handling ABI management in the DPDK.
> +This document details the management policy that ensures the long-term stability
> +of the DPDK ABI and API.
>
> General Guidelines
> ------------------
>
> -#. Whenever possible, ABI should be preserved
> -#. ABI/API may be changed with a deprecation process
> -#. The modification of symbols can generally be managed with versioning
> -#. Libraries or APIs marked in ``experimental`` state may change without constraint
> -#. New APIs will be marked as ``experimental`` for at least one release to allow
> - any issues found by users of the new API to be fixed quickly
> -#. The addition of symbols is generally not problematic
> -#. The removal of symbols generally is an ABI break and requires bumping of the
> - LIBABIVER macro
> -#. Updates to the minimum hardware requirements, which drop support for hardware which
> - was previously supported, should be treated as an ABI change.
> -
> -What is an ABI
> -~~~~~~~~~~~~~~
> +#. Major ABI versions are declared every **year** and are then supported for one
> + year, typically aligned with the :ref:`LTS release <stable_lts_releases>`.
> +#. The ABI version is managed at a project level in DPDK, with the ABI version
> + reflected in all :ref:`library's soname <what_is_soname>`.
> +#. The ABI should be preserved and not changed lightly. ABI changes must follow
> + the outlined :ref:`deprecation process <abi_changes>`.
> +#. The addition of symbols is generally not problematic. The modification of
> + symbols is managed with :ref:`ABI Versioning <abi_versioning>`.
> +#. The removal of symbols is considered an :ref:`ABI breakage <abi_breakages>`,
> + once approved these will form part of the next ABI version.
> +#. Libraries or APIs marked as :ref:`Experimental <experimental_apis>` are not
> + considered part of an ABI version and may change without constraint.
> +#. Updates to the :ref:`minimum hardware requirements <hw_rqmts>`, which drop
> + support for hardware which was previously supported, should be treated as an
> + ABI change.
> +
> +.. note::
> +
> + In 2019, the DPDK community stated it's intention to move to ABI stable
its?
> + releases, over a number of release cycles. Beginning with maintaining ABI
> + stability through one year of DPDK releases starting from DPDK 19.11. This
sentence without a verb?
> + policy will be reviewed in 2020, with intention of lengthening the stability
> + period.
> +
> +What is an ABI?
> +~~~~~~~~~~~~~~~
>
> An ABI (Application Binary Interface) is the set of runtime interfaces exposed
> by a library. It is similar to an API (Application Programming Interface) but
> @@ -39,30 +52,80 @@ Therefore, in the case of dynamic linking, it is critical that an ABI is
> preserved, or (when modified), done in such a way that the application is unable
> to behave improperly or in an unexpected fashion.
>
> +.. _figure_what_is_an_abi:
> +
> +.. figure:: img/what_is_an_abi.*
> +
> +*Figure 1. Illustration of DPDK API and ABI .*
>
> -ABI/API Deprecation
> --------------------
> +
> +What is an ABI version?
> +~~~~~~~~~~~~~~~~~~~~~~~
> +
> +An ABI version is an instance of a library's ABI at a specific release. Certain
> +releases are considered by the community to be milestone releases, the yearly
> +LTS for example. Supporting those milestone release's ABI for some number of
> +subsequent releases is desirable to facilitate application upgrade. Those ABI
> +version's aligned with milestones release are therefore called 'ABI major
versions?
milestone releases
> +versions' and are supported for some number of releases.
> +
> +More details on major ABI version can be found in the :ref:`ABI versioning
> +<major_abi_versions>` guide.
>
> The DPDK ABI policy
> -~~~~~~~~~~~~~~~~~~~
> +-------------------
> +
> +A major ABI version is declared every year, aligned with that year's LTS
> +release, e.g. v19.11. This ABI version is then supported for one year by all
> +subsequent releases within that time period, until the next LTS release, e.g.
> +v20.11.
> +
> +At the declaration of a major ABI version, major version numbers encoded in
> +libraries soname's are bumped to indicate the new version, with the minor
> +version reset to ``0``. An example would be ``librte_eal.so.20.3`` would become
> +``librte_eal.so.21.0``.
>
> -ABI versions are set at the time of major release labeling, and the ABI may
> -change multiple times, without warning, between the last release label and the
> -HEAD label of the git tree.
> +The ABI may then change multiple times, without warning, between the last major
> +ABI version increment and the HEAD label of the git tree, with the condition
> +that ABI compatibility with the major ABI version is preserved and therefore
> +soname's do not change.
>
> -ABI versions, once released, are available until such time as their
> -deprecation has been noted in the Release Notes for at least one major release
> -cycle. For example consider the case where the ABI for DPDK 2.0 has been
> -shipped and then a decision is made to modify it during the development of
> -DPDK 2.1. The decision will be recorded in the Release Notes for the DPDK 2.1
> -release and the modification will be made available in the DPDK 2.2 release.
> +Minor versions are incremented to indicate the release of a new ABI compatible
> +DPDK release, typically the DPDK quarterly releases. An example of this, might
> +be that ``librte_eal.so.20.1`` would indicate the first ABI compatible DPDK
> +release, following the declaration of the new major ABI version ``20``.
>
> -ABI versions may be deprecated in whole or in part as needed by a given
> -update.
> +ABI versions, are supported by each release until such time as the next major
> +ABI version is declared. At that time, the deprecation of the previous major ABI
> +version will be noted in the Release Notes with guidance on individual symbol
> +depreciation and upgrade notes provided.
deprecation?
>
> -Some ABI changes may be too significant to reasonably maintain multiple
> -versions. In those cases ABI's may be updated without backward compatibility
> -being provided. The requirements for doing so are:
> +.. _figure_abi_stability_policy:
> +
> +.. figure:: img/abi_stability_policy.*
> +
> +*Figure 2. Mapping of new ABI versions and ABI version compatibility to DPDK
> +releases.*
> +
> +.. _abi_changes:
> +
> +ABI Changes
> +~~~~~~~~~~~
> +
> +The ABI may still change after the declaration of a major ABI version, that is
> +new APIs may be still added or existing APIs may be modified.
> +
> +.. Warning::
> +
> + Note that, this policy details the method by which the ABI may be changed,
> + with due regard to preserving compatibility and observing depreciation
deprecation?
> + notices. This process however should not be undertaken lightly, as a general
> + rule ABI stability is extremely important for downstream consumers of DPDK.
> + The ABI should only be changed for significant reasons, such as performance
> + enhancements. ABI breakages due to changes such as reorganizing public
> + structure fields for aesthetic or readability purposes should be avoided.
> +
> +The requirements for changing the ABI are:
[snip]
--
David Marchand
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v10 1/3] eal/arm64: add 128-bit atomic compare exchange
2019-10-14 15:43 0% ` David Marchand
@ 2019-10-15 11:38 2% ` Phil Yang
2019-10-18 11:21 4% ` [dpdk-dev] [PATCH v11 " Phil Yang
1 sibling, 1 reply; 200+ results
From: Phil Yang @ 2019-10-15 11:38 UTC (permalink / raw)
To: david.marchand, jerinj, gage.eads, dev
Cc: thomas, hemant.agrawal, Honnappa.Nagarahalli, gavin.hu, nd
This patch adds the implementation of the 128-bit atomic compare
exchange API on AArch64. Using 64-bit 'ldxp/stxp' instructions
can perform this operation. Moreover, on the LSE atomic extension
accelerated platforms, it implemented by 'casp' instructions for
better performance.
Since the '__ARM_FEATURE_ATOMICS' flag only supports GCC-9, so this
patch adds a new config flag 'RTE_ARM_FEATURE_ATOMICS' to enable the
'cas' version on elder version compilers.
Suggested-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---
v10:
1.Removed all the rte tag for internal functions.
2.Removed __MO_LOAD and _MO_STORE macros and keep define __HAS_ACQ
and __HAS_REL under non LSE conditional branch.
3.Undef the macro once it is unused.
4.Reword the 1/3 and 2/3 patches' commitlog more specific.
v9:
Updated 19.11 release note.
v8:
Fixed "WARNING:LONG_LINE: line over 80 characters" warnings with latest kernel
checkpatch.pl
v7:
1. Adjust code comment.
v6:
1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
3. Fixed 32 bit build issue.
v5:
1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
2. Record the reason of introducing "rte_stack_lf_stubs.h" in git
commit.
(Jerin, Jocob)
3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
Jocob)
v4:
1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions.
(Jerin Jocob)
2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin
Jocob)
3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage
Eads/Jerin Jocob)
v3:
1. Avoid duplication code with macro. (Jerin Jocob)
2. Make invalid memory order to strongest barrier. (Jerin Jocob)
3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
4. Fix 32-bit x86 builds issue. (Gage Eads)
5. Correct documentation issues in UT. (Gage Eads)
v2:
Initial version.
config/arm/meson.build | 2 +
config/common_base | 3 +
config/defconfig_arm64-octeontx2-linuxapp-gcc | 1 +
config/defconfig_arm64-thunderx2-linuxapp-gcc | 1 +
.../common/include/arch/arm/rte_atomic_64.h | 173 +++++++++++++++++++++
.../common/include/arch/x86/rte_atomic_64.h | 12 --
lib/librte_eal/common/include/generic/rte_atomic.h | 17 +-
7 files changed, 196 insertions(+), 13 deletions(-)
diff --git a/config/arm/meson.build b/config/arm/meson.build
index 979018e..9f28271 100644
--- a/config/arm/meson.build
+++ b/config/arm/meson.build
@@ -71,11 +71,13 @@ flags_thunderx2_extra = [
['RTE_CACHE_LINE_SIZE', 64],
['RTE_MAX_NUMA_NODES', 2],
['RTE_MAX_LCORE', 256],
+ ['RTE_ARM_FEATURE_ATOMICS', true],
['RTE_USE_C11_MEM_MODEL', true]]
flags_octeontx2_extra = [
['RTE_MACHINE', '"octeontx2"'],
['RTE_MAX_NUMA_NODES', 1],
['RTE_MAX_LCORE', 24],
+ ['RTE_ARM_FEATURE_ATOMICS', true],
['RTE_EAL_IGB_UIO', false],
['RTE_USE_C11_MEM_MODEL', true]]
diff --git a/config/common_base b/config/common_base
index e843a21..a96beb9 100644
--- a/config/common_base
+++ b/config/common_base
@@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
CONFIG_RTE_MAX_NUMA_NODES=8
CONFIG_RTE_MAX_HEAPS=32
CONFIG_RTE_MAX_MEMSEG_LISTS=64
+
+# Use ARM LSE ATOMIC instructions
+CONFIG_RTE_ARM_FEATURE_ATOMICS=n
# each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
# or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
index f20da24..7687dbe 100644
--- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
+++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
@@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
CONFIG_RTE_CACHE_LINE_SIZE=128
CONFIG_RTE_MAX_NUMA_NODES=1
CONFIG_RTE_MAX_LCORE=24
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
# Doesn't support NUMA
CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
index cc5c64b..af4a89c 100644
--- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
+++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
@@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
CONFIG_RTE_CACHE_LINE_SIZE=64
CONFIG_RTE_MAX_NUMA_NODES=2
CONFIG_RTE_MAX_LCORE=256
+CONFIG_RTE_ARM_FEATURE_ATOMICS=y
diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
index 97060e4..7854c07 100644
--- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
@@ -1,5 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2015 Cavium, Inc
+ * Copyright(c) 2019 Arm Limited
*/
#ifndef _RTE_ATOMIC_ARM64_H_
@@ -14,6 +15,9 @@ extern "C" {
#endif
#include "generic/rte_atomic.h"
+#include <rte_branch_prediction.h>
+#include <rte_compat.h>
+#include <rte_debug.h>
#define dsb(opt) asm volatile("dsb " #opt : : : "memory")
#define dmb(opt) asm volatile("dmb " #opt : : : "memory")
@@ -40,6 +44,175 @@ extern "C" {
#define rte_cio_rmb() dmb(oshld)
+/*------------------------ 128 bit atomic operations -------------------------*/
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+#define __ATOMIC128_CAS_OP(cas_op_name, op_string) \
+static __rte_noinline rte_int128_t \
+cas_op_name(rte_int128_t *dst, rte_int128_t old, \
+ rte_int128_t updated) \
+{ \
+ /* caspX instructions register pair must start from even-numbered
+ * register at operand 1.
+ * So, specify registers for local variables here.
+ */ \
+ register uint64_t x0 __asm("x0") = (uint64_t)old.val[0]; \
+ register uint64_t x1 __asm("x1") = (uint64_t)old.val[1]; \
+ register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0]; \
+ register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1]; \
+ asm volatile( \
+ op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]" \
+ : [old0] "+r" (x0), \
+ [old1] "+r" (x1) \
+ : [upd0] "r" (x2), \
+ [upd1] "r" (x3), \
+ [dst] "r" (dst) \
+ : "memory"); \
+ old.val[0] = x0; \
+ old.val[1] = x1; \
+ return old; \
+}
+
+__ATOMIC128_CAS_OP(__cas_relaxed, "casp")
+__ATOMIC128_CAS_OP(__cas_acquire, "caspa")
+__ATOMIC128_CAS_OP(__cas_release, "caspl")
+__ATOMIC128_CAS_OP(__cas_acq_rel, "caspal")
+
+#undef __ATOMIC128_CAS_OP
+
+#else
+#define __ATOMIC128_LDX_OP(ldx_op_name, op_string) \
+static inline rte_int128_t \
+ldx_op_name(const rte_int128_t *src) \
+{ \
+ rte_int128_t ret; \
+ asm volatile( \
+ op_string " %0, %1, %2" \
+ : "=&r" (ret.val[0]), \
+ "=&r" (ret.val[1]) \
+ : "Q" (src->val[0]) \
+ : "memory"); \
+ return ret; \
+}
+
+__ATOMIC128_LDX_OP(__ldx_relaxed, "ldxp")
+__ATOMIC128_LDX_OP(__ldx_acquire, "ldaxp")
+
+#undef __ATOMIC128_LDX_OP
+
+#define __ATOMIC128_STX_OP(stx_op_name, op_string) \
+static inline uint32_t \
+stx_op_name(rte_int128_t *dst, const rte_int128_t src) \
+{ \
+ uint32_t ret; \
+ asm volatile( \
+ op_string " %w0, %1, %2, %3" \
+ : "=&r" (ret) \
+ : "r" (src.val[0]), \
+ "r" (src.val[1]), \
+ "Q" (dst->val[0]) \
+ : "memory"); \
+ /* Return 0 on success, 1 on failure */ \
+ return ret; \
+}
+
+__ATOMIC128_STX_OP(__stx_relaxed, "stxp")
+__ATOMIC128_STX_OP(__stx_release, "stlxp")
+
+#undef __ATOMIC128_STX_OP
+
+#endif
+
+__rte_experimental
+static inline int
+rte_atomic128_cmp_exchange(rte_int128_t *dst,
+ rte_int128_t *exp,
+ const rte_int128_t *src,
+ unsigned int weak,
+ int success,
+ int failure)
+{
+ /* Always do strong CAS */
+ RTE_SET_USED(weak);
+ /* Ignore memory ordering for failure, memory order for
+ * success must be stronger or equal
+ */
+ RTE_SET_USED(failure);
+ /* Find invalid memory order */
+ RTE_ASSERT(success == __ATOMIC_RELAXED
+ || success == __ATOMIC_ACQUIRE
+ || success == __ATOMIC_RELEASE
+ || success == __ATOMIC_ACQ_REL
+ || success == __ATOMIC_SEQ_CST);
+
+#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
+ rte_int128_t expected = *exp;
+ rte_int128_t desired = *src;
+ rte_int128_t old;
+
+ if (success == __ATOMIC_RELAXED)
+ old = __cas_relaxed(dst, expected, desired);
+ else if (success == __ATOMIC_ACQUIRE)
+ old = __cas_acquire(dst, expected, desired);
+ else if (success == __ATOMIC_RELEASE)
+ old = __cas_release(dst, expected, desired);
+ else
+ old = __cas_acq_rel(dst, expected, desired);
+#else
+#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
+#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
+ (mo) == __ATOMIC_SEQ_CST)
+
+ int ldx_mo = __HAS_ACQ(success) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED;
+ int stx_mo = __HAS_RLS(success) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED;
+
+#undef __HAS_ACQ
+#undef __HAS_RLS
+
+ uint32_t ret = 1;
+ register rte_int128_t expected = *exp;
+ register rte_int128_t desired = *src;
+ register rte_int128_t old;
+
+ /* ldx128 can not guarantee atomic,
+ * Must write back src or old to verify atomicity of ldx128;
+ */
+ do {
+ if (ldx_mo == __ATOMIC_RELAXED)
+ old = __ldx_relaxed(dst);
+ else
+ old = __ldx_acquire(dst);
+
+ if (likely(old.int128 == expected.int128)) {
+ if (stx_mo == __ATOMIC_RELAXED)
+ ret = __stx_relaxed(dst, desired);
+ else
+ ret = __stx_release(dst, desired);
+ } else {
+ /* In the failure case (since 'weak' is ignored and only
+ * weak == 0 is implemented), expected should contain
+ * the atomically read value of dst. This means, 'old'
+ * needs to be stored back to ensure it was read
+ * atomically.
+ */
+ if (stx_mo == __ATOMIC_RELAXED)
+ ret = __stx_relaxed(dst, old);
+ else
+ ret = __stx_release(dst, old);
+ }
+ } while (unlikely(ret));
+#endif
+
+ /* Unconditionally updating expected removes
+ * an 'if' statement.
+ * expected should already be in register if
+ * not in the cache.
+ */
+ *exp = old;
+
+ return (old.int128 == expected.int128);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
index 1335d92..cfe7067 100644
--- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
+++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
@@ -183,18 +183,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
/*------------------------ 128 bit atomic operations -------------------------*/
-/**
- * 128-bit integer structure.
- */
-RTE_STD_C11
-typedef struct {
- RTE_STD_C11
- union {
- uint64_t val[2];
- __extension__ __int128 int128;
- };
-} __rte_aligned(16) rte_int128_t;
-
__rte_experimental
static inline int
rte_atomic128_cmp_exchange(rte_int128_t *dst,
diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
index 24ff7dc..e6ab15a 100644
--- a/lib/librte_eal/common/include/generic/rte_atomic.h
+++ b/lib/librte_eal/common/include/generic/rte_atomic.h
@@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
/*------------------------ 128 bit atomic operations -------------------------*/
+/**
+ * 128-bit integer structure.
+ */
+RTE_STD_C11
+typedef struct {
+ RTE_STD_C11
+ union {
+ uint64_t val[2];
+#ifdef RTE_ARCH_64
+ __extension__ __int128 int128;
+#endif
+ };
+} __rte_aligned(16) rte_int128_t;
+
#ifdef __DOXYGEN__
/**
@@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
* *exp = *dst
* @endcode
*
- * @note This function is currently only available for the x86-64 platform.
+ * @note This function is currently available for the x86-64 and aarch64
+ * platforms.
*
* @note The success and failure arguments must be one of the __ATOMIC_* values
* defined in the C++11 standard. For details on their behavior, refer to the
--
2.7.4
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v3 1/3] lib/lpm: integrate RCU QSBR
2019-10-13 4:36 3% ` Honnappa Nagarahalli
@ 2019-10-15 11:15 0% ` Ananyev, Konstantin
2019-10-18 3:32 0% ` Honnappa Nagarahalli
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-15 11:15 UTC (permalink / raw)
To: Honnappa Nagarahalli, Richardson, Bruce, Medvedkin, Vladimir,
olivier.matz
Cc: dev, stephen, paulmck, Gavin Hu (Arm Technology China),
Dharmik Thakkar, Ruifeng Wang (Arm Technology China),
nd, Ruifeng Wang (Arm Technology China),
nd
> <snip>
>
> > Hi guys,
> I have tried to consolidate design related questions here. If I have missed anything, please add.
>
> >
> > >
> > > From: Ruifeng Wang <ruifeng.wang@arm.com>
> > >
> > > Currently, the tbl8 group is freed even though the readers might be
> > > using the tbl8 group entries. The freed tbl8 group can be reallocated
> > > quickly. This results in incorrect lookup results.
> > >
> > > RCU QSBR process is integrated for safe tbl8 group reclaim.
> > > Refer to RCU documentation to understand various aspects of
> > > integrating RCU library into other libraries.
> > >
> > > Signed-off-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > ---
> > > lib/librte_lpm/Makefile | 3 +-
> > > lib/librte_lpm/meson.build | 2 +
> > > lib/librte_lpm/rte_lpm.c | 102 +++++++++++++++++++++++++----
> > > lib/librte_lpm/rte_lpm.h | 21 ++++++
> > > lib/librte_lpm/rte_lpm_version.map | 6 ++
> > > 5 files changed, 122 insertions(+), 12 deletions(-)
> > >
> > > diff --git a/lib/librte_lpm/Makefile b/lib/librte_lpm/Makefile index
> > > a7946a1c5..ca9e16312 100644
> > > --- a/lib/librte_lpm/Makefile
> > > +++ b/lib/librte_lpm/Makefile
> > > @@ -6,9 +6,10 @@ include $(RTE_SDK)/mk/rte.vars.mk # library name
> > > LIB = librte_lpm.a
> > >
> > > +CFLAGS += -DALLOW_EXPERIMENTAL_API
> > > CFLAGS += -O3
> > > CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -LDLIBS += -lrte_eal -lrte_hash
> > > +LDLIBS += -lrte_eal -lrte_hash -lrte_rcu
> > >
> > > EXPORT_MAP := rte_lpm_version.map
> > >
> > > diff --git a/lib/librte_lpm/meson.build b/lib/librte_lpm/meson.build
> > > index a5176d8ae..19a35107f 100644
> > > --- a/lib/librte_lpm/meson.build
> > > +++ b/lib/librte_lpm/meson.build
> > > @@ -2,9 +2,11 @@
> > > # Copyright(c) 2017 Intel Corporation
> > >
> > > version = 2
> > > +allow_experimental_apis = true
> > > sources = files('rte_lpm.c', 'rte_lpm6.c') headers =
> > > files('rte_lpm.h', 'rte_lpm6.h') # since header files have different
> > > names, we can install all vector headers # without worrying about
> > > which architecture we actually need headers +=
> > > files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h') deps +=
> > > ['hash']
> > > +deps += ['rcu']
> > > diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c index
> > > 3a929a1b1..ca58d4b35 100644
> > > --- a/lib/librte_lpm/rte_lpm.c
> > > +++ b/lib/librte_lpm/rte_lpm.c
> > > @@ -1,5 +1,6 @@
> > > /* SPDX-License-Identifier: BSD-3-Clause
> > > * Copyright(c) 2010-2014 Intel Corporation
> > > + * Copyright(c) 2019 Arm Limited
> > > */
> > >
> > > #include <string.h>
> > > @@ -381,6 +382,8 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
> > >
> > > rte_mcfg_tailq_write_unlock();
> > >
> > > + if (lpm->dq)
> > > + rte_rcu_qsbr_dq_delete(lpm->dq);
> > > rte_free(lpm->tbl8);
> > > rte_free(lpm->rules_tbl);
> > > rte_free(lpm);
> > > @@ -390,6 +393,59 @@ BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604,
> > 16.04);
> > > MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
> > > rte_lpm_free_v1604);
> > >
> > > +struct __rte_lpm_rcu_dq_entry {
> > > + uint32_t tbl8_group_index;
> > > + uint32_t pad;
> > > +};
> > > +
> > > +static void
> > > +__lpm_rcu_qsbr_free_resource(void *p, void *data) {
> > > + struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > > + struct __rte_lpm_rcu_dq_entry *e =
> > > + (struct __rte_lpm_rcu_dq_entry *)data;
> > > + struct rte_lpm_tbl_entry *tbl8 = (struct rte_lpm_tbl_entry *)p;
> > > +
> > > + /* Set tbl8 group invalid */
> > > + __atomic_store(&tbl8[e->tbl8_group_index], &zero_tbl8_entry,
> > > + __ATOMIC_RELAXED);
> > > +}
> > > +
> > > +/* Associate QSBR variable with an LPM object.
> > > + */
> > > +int
> > > +rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr *v) {
> > > + char rcu_dq_name[RTE_RCU_QSBR_DQ_NAMESIZE];
> > > + struct rte_rcu_qsbr_dq_parameters params;
> > > +
> > > + if ((lpm == NULL) || (v == NULL)) {
> > > + rte_errno = EINVAL;
> > > + return 1;
> > > + }
> > > +
> > > + if (lpm->dq) {
> > > + rte_errno = EEXIST;
> > > + return 1;
> > > + }
> > > +
> > > + /* Init QSBR defer queue. */
> > > + snprintf(rcu_dq_name, sizeof(rcu_dq_name), "LPM_RCU_%s", lpm-
> > >name);
> > > + params.name = rcu_dq_name;
> > > + params.size = lpm->number_tbl8s;
> > > + params.esize = sizeof(struct __rte_lpm_rcu_dq_entry);
> > > + params.f = __lpm_rcu_qsbr_free_resource;
> > > + params.p = lpm->tbl8;
> > > + params.v = v;
> > > + lpm->dq = rte_rcu_qsbr_dq_create(¶ms);
> > > + if (lpm->dq == NULL) {
> > > + RTE_LOG(ERR, LPM, "LPM QS defer queue creation failed\n");
> > > + return 1;
> > > + }
> >
> > Few thoughts about that function:
> Few things to keep in mind, the goal of the design is to make it easy for the applications to adopt lock-free algorithms. The reclamation
> process in the writer is a major portion of code one has to write for using lock-free algorithms. The current design is such that the writer
> does not have to change any code or write additional code other than calling 'rte_lpm_rcu_qsbr_add'.
>
> > It names rcu_qsbr_add() but in fact it allocates defer queue for give rcu var.
> > So first thought - is it always necessary?
> This is part of the design. If the application does not want to use this integrated logic then, it does not have to call this API. It can use the
> RCU defer APIs to implement its own logic. But, if I ask the question, does this integrated logic address most of the use cases of the LPM
> library, I think the answer is yes.
>
> > For some use-cases I suppose user might be ok to wait for quiescent state
> > change
> > inside tbl8_free()?
> Yes, that is a possibility (for ex: no frequent route changes). But, I think that is very trivial for the application to implement. Though, the LPM
> library has to separate the 'delete' and 'free' operations.
Exactly.
That's why it is not trivial with current LPM library.
In fact to do that himself right now, user would have to implement and support his own version of LPM code.
Honestly, I don't understand why you consider it as a drawback.
From my perspective only few things need to be changed:
1. Add 2 parameters to 'rte_lpm_rcu_qsbr_add():
number of elems in defer_queue
reclaim() threshold value.
If the user doesn't want to provide any values, that's fine we can use default ones here
(as you do it right now).
2. Make rte_lpm_rcu_qsbr_add() to return pointer to the defer_queue.
Again if user doesn't want to call reclaim() himself, he can just ignore return value.
These 2 changes will provide us with necessary flexibility that would help to cover more use-cases:
- user can decide how big should be the defer queue
- user can decide when/how he wants to do reclaim()
Konstantin
>Similar operations are provided in rte_hash library. IMO, we should follow
> consistent approach.
>
> > Another thing you do allocate defer queue, but it is internal, so user can't call
> > reclaim() manually, which looks strange.
> > Why not to return defer_queue pointer to the user, so he can call reclaim()
> > himself at appropriate time?
> The intention of the design is to take the complexity away from the user of LPM library. IMO, the current design will address most uses
> cases of LPM library. If we expose the 2 parameters (when to trigger reclamation and how much to reclaim) in the 'rte_lpm_rcu_qsbr_add'
> API, it should provide enough flexibility to the application.
>
> > Third thing - you always allocate defer queue with size equal to number of
> > tbl8.
> > Though I understand it could be up to 16M tbl8 groups inside the LPM.
> > Do we really need defer queue that long?
> No, we do not need it to be this long. It is this long today to avoid returning no-space on the defer queue error.
>
> > Especially considering that current rcu_defer_queue will start reclamation
> > when 1/8 of defer_quueue becomes full and wouldn't reclaim more then
> > 1/16 of it.
> > Probably better to let user to decide himself how long defer_queue he needs
> > for that LPM?
> It makes sense to expose it to the user if the writer-writer concurrency is lock-free (no memory allocation allowed to expand the defer
> queue size when the queue is full). However, LPM is not lock-free on the writer side. If we think the writer could be lock-free in the future, it
> has to be exposed to the user.
>
> >
> > Konstantin
> Pulling questions/comments from other threads:
> Can we leave reclamation to some other house-keeping thread to do (sort of garbage collector). Or such mode is not supported/planned?
>
> [Honnappa] If the reclamation cost is small, the current method provides advantages over having a separate thread to do reclamation. I did
> not plan to provide such an option. But may be it makes sense to keep the options open (especially from ABI perspective). May be we
> should add a flags field which will allow us to implement different methods in the future?
>
> >
> >
> > > +
> > > + return 0;
> > > +}
> > > +
> > > /*
> > > * Adds a rule to the rule table.
> > > *
> > > @@ -679,14 +735,15 @@ tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20
> > > *tbl8) }
> > >
> > > static int32_t
> > > -tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > > number_tbl8s)
> > > +__tbl8_alloc_v1604(struct rte_lpm *lpm)
> > > {
> > > uint32_t group_idx; /* tbl8 group index. */
> > > struct rte_lpm_tbl_entry *tbl8_entry;
> > >
> > > /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
> > > - for (group_idx = 0; group_idx < number_tbl8s; group_idx++) {
> > > - tbl8_entry = &tbl8[group_idx *
> > RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > > + for (group_idx = 0; group_idx < lpm->number_tbl8s; group_idx++) {
> > > + tbl8_entry = &lpm->tbl8[group_idx *
> > > +
> > RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > > /* If a free tbl8 group is found clean it and set as VALID. */
> > > if (!tbl8_entry->valid_group) {
> > > struct rte_lpm_tbl_entry new_tbl8_entry = { @@ -
> > 712,6 +769,21 @@
> > > tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
> > > return -ENOSPC;
> > > }
> > >
> > > +static int32_t
> > > +tbl8_alloc_v1604(struct rte_lpm *lpm) {
> > > + int32_t group_idx; /* tbl8 group index. */
> > > +
> > > + group_idx = __tbl8_alloc_v1604(lpm);
> > > + if ((group_idx < 0) && (lpm->dq != NULL)) {
> > > + /* If there are no tbl8 groups try to reclaim some. */
> > > + if (rte_rcu_qsbr_dq_reclaim(lpm->dq) == 0)
> > > + group_idx = __tbl8_alloc_v1604(lpm);
> > > + }
> > > +
> > > + return group_idx;
> > > +}
> > > +
> > > static void
> > > tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t
> > > tbl8_group_start) { @@ -728,13 +800,21 @@ tbl8_free_v20(struct
> > > rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start) }
> > >
> > > static void
> > > -tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > > tbl8_group_start)
> > > +tbl8_free_v1604(struct rte_lpm *lpm, uint32_t tbl8_group_start)
> > > {
> > > - /* Set tbl8 group invalid*/
> > > struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > > + struct __rte_lpm_rcu_dq_entry e;
> > >
> > > - __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
> > > - __ATOMIC_RELAXED);
> > > + if (lpm->dq != NULL) {
> > > + e.tbl8_group_index = tbl8_group_start;
> > > + e.pad = 0;
> > > + /* Push into QSBR defer queue. */
> > > + rte_rcu_qsbr_dq_enqueue(lpm->dq, (void *)&e);
> > > + } else {
> > > + /* Set tbl8 group invalid*/
> > > + __atomic_store(&lpm->tbl8[tbl8_group_start],
> > &zero_tbl8_entry,
> > > + __ATOMIC_RELAXED);
> > > + }
> > > }
> > >
> > > static __rte_noinline int32_t
> > > @@ -1037,7 +1117,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> > > uint32_t ip_masked, uint8_t depth,
> > >
> > > if (!lpm->tbl24[tbl24_index].valid) {
> > > /* Search for a free tbl8 group. */
> > > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> > >number_tbl8s);
> > > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> > >
> > > /* Check tbl8 allocation was successful. */
> > > if (tbl8_group_index < 0) {
> > > @@ -1083,7 +1163,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> > uint32_t ip_masked, uint8_t depth,
> > > } /* If valid entry but not extended calculate the index into Table8. */
> > > else if (lpm->tbl24[tbl24_index].valid_group == 0) {
> > > /* Search for free tbl8 group. */
> > > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> > >number_tbl8s);
> > > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> > >
> > > if (tbl8_group_index < 0) {
> > > return tbl8_group_index;
> > > @@ -1818,7 +1898,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm,
> > uint32_t ip_masked,
> > > */
> > > lpm->tbl24[tbl24_index].valid = 0;
> > > __atomic_thread_fence(__ATOMIC_RELEASE);
> > > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > > + tbl8_free_v1604(lpm, tbl8_group_start);
> > > } else if (tbl8_recycle_index > -1) {
> > > /* Update tbl24 entry. */
> > > struct rte_lpm_tbl_entry new_tbl24_entry = { @@ -1834,7
> > +1914,7 @@
> > > delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
> > > __atomic_store(&lpm->tbl24[tbl24_index],
> > &new_tbl24_entry,
> > > __ATOMIC_RELAXED);
> > > __atomic_thread_fence(__ATOMIC_RELEASE);
> > > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > > + tbl8_free_v1604(lpm, tbl8_group_start);
> > > }
> > > #undef group_idx
> > > return 0;
> > > diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h index
> > > 906ec4483..49c12a68d 100644
> > > --- a/lib/librte_lpm/rte_lpm.h
> > > +++ b/lib/librte_lpm/rte_lpm.h
> > > @@ -1,5 +1,6 @@
> > > /* SPDX-License-Identifier: BSD-3-Clause
> > > * Copyright(c) 2010-2014 Intel Corporation
> > > + * Copyright(c) 2019 Arm Limited
> > > */
> > >
> > > #ifndef _RTE_LPM_H_
> > > @@ -21,6 +22,7 @@
> > > #include <rte_common.h>
> > > #include <rte_vect.h>
> > > #include <rte_compat.h>
> > > +#include <rte_rcu_qsbr.h>
> > >
> > > #ifdef __cplusplus
> > > extern "C" {
> > > @@ -186,6 +188,7 @@ struct rte_lpm {
> > > __rte_cache_aligned; /**< LPM tbl24 table. */
> > > struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
> > > struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
> > > + struct rte_rcu_qsbr_dq *dq; /**< RCU QSBR defer queue.*/
> > > };
> > >
> > > /**
> > > @@ -248,6 +251,24 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
> > void
> > > rte_lpm_free_v1604(struct rte_lpm *lpm);
> > >
> > > +/**
> > > + * Associate RCU QSBR variable with an LPM object.
> > > + *
> > > + * @param lpm
> > > + * the lpm object to add RCU QSBR
> > > + * @param v
> > > + * RCU QSBR variable
> > > + * @return
> > > + * On success - 0
> > > + * On error - 1 with error code set in rte_errno.
> > > + * Possible rte_errno codes are:
> > > + * - EINVAL - invalid pointer
> > > + * - EEXIST - already added QSBR
> > > + * - ENOMEM - memory allocation failure
> > > + */
> > > +__rte_experimental
> > > +int rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr
> > > +*v);
> > > +
> > > /**
> > > * Add a rule to the LPM table.
> > > *
> > > diff --git a/lib/librte_lpm/rte_lpm_version.map
> > > b/lib/librte_lpm/rte_lpm_version.map
> > > index 90beac853..b353aabd2 100644
> > > --- a/lib/librte_lpm/rte_lpm_version.map
> > > +++ b/lib/librte_lpm/rte_lpm_version.map
> > > @@ -44,3 +44,9 @@ DPDK_17.05 {
> > > rte_lpm6_lookup_bulk_func;
> > >
> > > } DPDK_16.04;
> > > +
> > > +EXPERIMENTAL {
> > > + global:
> > > +
> > > + rte_lpm_rcu_qsbr_add;
> > > +};
> > > --
> > > 2.17.1
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v6 00/13] vhost packed ring performance optimization
2019-10-15 14:30 3% ` [dpdk-dev] [PATCH v5 00/13] " Marvin Liu
@ 2019-10-15 16:07 3% ` Marvin Liu
2019-10-17 7:31 0% ` Maxime Coquelin
2019-10-21 15:40 3% ` [dpdk-dev] [PATCH v7 " Marvin Liu
0 siblings, 2 replies; 200+ results
From: Marvin Liu @ 2019-10-15 16:07 UTC (permalink / raw)
To: maxime.coquelin, tiwei.bie, zhihong.wang, stephen, gavin.hu
Cc: dev, Marvin Liu
Packed ring has more compact ring format and thus can significantly
reduce the number of cache miss. It can lead to better performance.
This has been approved in virtio user driver, on normal E5 Xeon cpu
single core performance can raise 12%.
http://mails.dpdk.org/archives/dev/2018-April/095470.html
However vhost performance with packed ring performance was decreased.
Through analysis, mostly extra cost was from the calculating of each
descriptor flag which depended on ring wrap counter. Moreover, both
frontend and backend need to write same descriptors which will cause
cache contention. Especially when doing vhost enqueue function, virtio
refill packed ring function may write same cache line when vhost doing
enqueue function. This kind of extra cache cost will reduce the benefit
of reducing cache misses.
For optimizing vhost packed ring performance, vhost enqueue and dequeue
function will be splitted into fast and normal path.
Several methods will be taken in fast path:
Handle descriptors in one cache line by batch.
Split loop function into more pieces and unroll them.
Prerequisite check that whether I/O space can copy directly into mbuf
space and vice versa.
Prerequisite check that whether descriptor mapping is successful.
Distinguish vhost used ring update function by enqueue and dequeue
function.
Buffer dequeue used descriptors as many as possible.
Update enqueue used descriptors by cache line.
After all these methods done, single core vhost PvP performance with 64B
packet on Xeon 8180 can boost 35%.
v6:
- Fix dequeue zcopy result check
v5:
- Remove disable sw prefetch as performance impact is small
- Change unroll pragma macro format
- Rename shadow counter elements names
- Clean dequeue update check condition
- Add inline functions replace of duplicated code
- Unify code style
v4:
- Support meson build
- Remove memory region cache for no clear performance gain and ABI break
- Not assume ring size is power of two
v3:
- Check available index overflow
- Remove dequeue remained descs number check
- Remove changes in split ring datapath
- Call memory write barriers once when updating used flags
- Rename some functions and macros
- Code style optimization
v2:
- Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
- Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
- Optimize dequeue used ring update when in_order negotiated
Marvin Liu (13):
vhost: add packed ring indexes increasing function
vhost: add packed ring single enqueue
vhost: try to unroll for each loop
vhost: add packed ring batch enqueue
vhost: add packed ring single dequeue
vhost: add packed ring batch dequeue
vhost: flush enqueue updates by batch
vhost: flush batched enqueue descs directly
vhost: buffer packed ring dequeue updates
vhost: optimize packed ring enqueue
vhost: add packed ring zcopy batch and single dequeue
vhost: optimize packed ring dequeue
vhost: optimize packed ring dequeue when in-order
lib/librte_vhost/Makefile | 18 +
lib/librte_vhost/meson.build | 7 +
lib/librte_vhost/vhost.h | 57 +++
lib/librte_vhost/virtio_net.c | 924 +++++++++++++++++++++++++++-------
4 files changed, 812 insertions(+), 194 deletions(-)
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v5 00/13] vhost packed ring performance optimization
2019-10-09 13:38 3% ` [dpdk-dev] [PATCH v4 00/14] vhost packed ring performance optimization Marvin Liu
@ 2019-10-15 14:30 3% ` Marvin Liu
2019-10-15 16:07 3% ` [dpdk-dev] [PATCH v6 " Marvin Liu
0 siblings, 1 reply; 200+ results
From: Marvin Liu @ 2019-10-15 14:30 UTC (permalink / raw)
To: maxime.coquelin, tiwei.bie, zhihong.wang, stephen, gavin.hu
Cc: dev, Marvin Liu
Packed ring has more compact ring format and thus can significantly
reduce the number of cache miss. It can lead to better performance.
This has been approved in virtio user driver, on normal E5 Xeon cpu
single core performance can raise 12%.
http://mails.dpdk.org/archives/dev/2018-April/095470.html
However vhost performance with packed ring performance was decreased.
Through analysis, mostly extra cost was from the calculating of each
descriptor flag which depended on ring wrap counter. Moreover, both
frontend and backend need to write same descriptors which will cause
cache contention. Especially when doing vhost enqueue function, virtio
refill packed ring function may write same cache line when vhost doing
enqueue function. This kind of extra cache cost will reduce the benefit
of reducing cache misses.
For optimizing vhost packed ring performance, vhost enqueue and dequeue
function will be splitted into fast and normal path.
Several methods will be taken in fast path:
Handle descriptors in one cache line by batch.
Split loop function into more pieces and unroll them.
Prerequisite check that whether I/O space can copy directly into mbuf
space and vice versa.
Prerequisite check that whether descriptor mapping is successful.
Distinguish vhost used ring update function by enqueue and dequeue
function.
Buffer dequeue used descriptors as many as possible.
Update enqueue used descriptors by cache line.
After all these methods done, single core vhost PvP performance with 64B
packet on Xeon 8180 can boost 35%.
v5:
- Remove disable sw prefetch as performance impact is small
- change unroll pragma macro format
- Rename shadow counter elements names
- clean dequeue update check condition
- add inline functions replace of duplicated code
- unify code style
v4:
- Support meson build
- Remove memory region cache for no clear performance gain and ABI break
- Not assume ring size is power of two
v3:
- Check available index overflow
- Remove dequeue remained descs number check
- Remove changes in split ring datapath
- Call memory write barriers once when updating used flags
- Rename some functions and macros
- Code style optimization
v2:
- Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
- Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
- Optimize dequeue used ring update when in_order negotiated
Marvin Liu (13):
vhost: add packed ring indexes increasing function
vhost: add packed ring single enqueue
vhost: try to unroll for each loop
vhost: add packed ring batch enqueue
vhost: add packed ring single dequeue
vhost: add packed ring batch dequeue
vhost: flush enqueue updates by batch
vhost: flush batched enqueue descs flags directly
vhost: buffer packed ring dequeue updates
vhost: optimize packed ring enqueue
vhost: add packed ring zcopy batch and single dequeue
vhost: optimize packed ring dequeue
vhost: optimize packed ring dequeue when in-order
lib/librte_vhost/Makefile | 18 +
lib/librte_vhost/meson.build | 7 +
lib/librte_vhost/vhost.h | 57 +++
lib/librte_vhost/virtio_net.c | 927 +++++++++++++++++++++++++++-------
4 files changed, 814 insertions(+), 195 deletions(-)
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v5 15/15] sched: remove redundant code
@ 2019-10-14 17:23 4% ` Jasvinder Singh
0 siblings, 0 replies; 200+ results
From: Jasvinder Singh @ 2019-10-14 17:23 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu, Lukasz Krakowiak
Remove redundant data structure fields from port level data
structures and update the release notes.
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com>
---
doc/guides/rel_notes/release_19_11.rst | 7 ++++-
lib/librte_sched/rte_sched.c | 42 +-------------------------
lib/librte_sched/rte_sched.h | 22 --------------
3 files changed, 7 insertions(+), 64 deletions(-)
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 23ceb8f67..87812b32c 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -172,6 +172,11 @@ API Changes
* ethdev: changed ``rte_eth_dev_owner_delete`` return value from ``void`` to
``int`` to provide a way to report various error conditions.
+* sched: The pipe nodes configuration parameters such as number of pipes,
+ pipe queue sizes, pipe profiles, etc., are moved from port level structure
+ to subport level. This allows different subports of the same port to
+ have different configuration for the pipe nodes.
+
ABI Changes
-----------
@@ -259,7 +264,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rcu.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.3
+ + librte_sched.so.4
librte_security.so.2
librte_stack.so.1
librte_table.so.3
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 1faa580d0..710ecf65a 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -216,13 +216,6 @@ struct rte_sched_port {
uint32_t mtu;
uint32_t frame_overhead;
int socket;
- uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint32_t n_pipe_profiles;
- uint32_t n_max_pipe_profiles;
- uint32_t pipe_tc_be_rate_max;
-#ifdef RTE_SCHED_RED
- struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
/* Timing */
uint64_t time_cpu_cycles; /* Current CPU time measured in CPU cyles */
@@ -230,48 +223,15 @@ struct rte_sched_port {
uint64_t time; /* Current NIC TX time measured in bytes */
struct rte_reciprocal inv_cycles_per_byte; /* CPU cycles per byte */
- /* Scheduling loop detection */
- uint32_t pipe_loop;
- uint32_t pipe_exhaustion;
-
- /* Bitmap */
- struct rte_bitmap *bmp;
- uint32_t grinder_base_bmp_pos[RTE_SCHED_PORT_N_GRINDERS] __rte_aligned_16;
-
/* Grinders */
- struct rte_sched_grinder grinder[RTE_SCHED_PORT_N_GRINDERS];
- uint32_t busy_grinders;
struct rte_mbuf **pkts_out;
uint32_t n_pkts_out;
uint32_t subport_id;
- /* Queue base calculation */
- uint32_t qsize_add[RTE_SCHED_QUEUES_PER_PIPE];
- uint32_t qsize_sum;
-
/* Large data structures */
- struct rte_sched_subport *subports[0];
- struct rte_sched_subport *subport;
- struct rte_sched_pipe *pipe;
- struct rte_sched_queue *queue;
- struct rte_sched_queue_extra *queue_extra;
- struct rte_sched_pipe_profile *pipe_profiles;
- uint8_t *bmp_array;
- struct rte_mbuf **queue_array;
- uint8_t memory[0] __rte_cache_aligned;
+ struct rte_sched_subport *subports[0] __rte_cache_aligned;
} __rte_cache_aligned;
-enum rte_sched_port_array {
- e_RTE_SCHED_PORT_ARRAY_SUBPORT = 0,
- e_RTE_SCHED_PORT_ARRAY_PIPE,
- e_RTE_SCHED_PORT_ARRAY_QUEUE,
- e_RTE_SCHED_PORT_ARRAY_QUEUE_EXTRA,
- e_RTE_SCHED_PORT_ARRAY_PIPE_PROFILES,
- e_RTE_SCHED_PORT_ARRAY_BMP_ARRAY,
- e_RTE_SCHED_PORT_ARRAY_QUEUE_ARRAY,
- e_RTE_SCHED_PORT_ARRAY_TOTAL,
-};
-
enum rte_sched_subport_array {
e_RTE_SCHED_SUBPORT_ARRAY_PIPE = 0,
e_RTE_SCHED_SUBPORT_ARRAY_QUEUE,
diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h
index 40f02f124..c82c23c14 100644
--- a/lib/librte_sched/rte_sched.h
+++ b/lib/librte_sched/rte_sched.h
@@ -260,28 +260,6 @@ struct rte_sched_port_params {
* the subports of the same port.
*/
uint32_t n_pipes_per_subport;
-
- /** Packet queue size for each traffic class.
- * All the pipes within the same subport share the similar
- * configuration for the queues.
- */
- uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-
- /** Pipe profile table.
- * Every pipe is configured using one of the profiles from this table.
- */
- struct rte_sched_pipe_params *pipe_profiles;
-
- /** Profiles in the pipe profile table */
- uint32_t n_pipe_profiles;
-
- /** Max profiles allowed in the pipe profile table */
- uint32_t n_max_pipe_profiles;
-
-#ifdef RTE_SCHED_RED
- /** RED parameters */
- struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS];
-#endif
};
/*
--
2.21.0
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v9 1/3] eal/arm64: add 128-bit atomic compare exchange
@ 2019-10-14 15:43 0% ` David Marchand
2019-10-15 11:38 2% ` [dpdk-dev] [PATCH v10 " Phil Yang
1 sibling, 1 reply; 200+ results
From: David Marchand @ 2019-10-14 15:43 UTC (permalink / raw)
To: Phil Yang
Cc: Thomas Monjalon, Jerin Jacob Kollanukkaran, Gage Eads, dev,
Hemant Agrawal, Honnappa Nagarahalli, Gavin Hu, nd
On Wed, Aug 14, 2019 at 10:29 AM Phil Yang <phil.yang@arm.com> wrote:
>
> Add 128-bit atomic compare exchange on aarch64.
A bit short, seeing the complexity of the code and the additional
RTE_ARM_FEATURE_ATOMICS config flag.
Comments inline.
>
> Suggested-by: Jerin Jacob <jerinj@marvell.com>
> Signed-off-by: Phil Yang <phil.yang@arm.com>
> Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Tested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Acked-by: Jerin Jacob <jerinj@marvell.com>
> ---
>
> v9:
> Updated 19.11 release note.
>
> v8:
> Fixed "WARNING:LONG_LINE: line over 80 characters" warnings with latest kernel
> checkpatch.pl
>
> v7:
> 1. Adjust code comment.
>
> v6:
> 1. Put the RTE_ARM_FEATURE_ATOMICS flag into EAL group. (Jerin Jocob)
> 2. Keep rte_stack_lf_stubs.h doing nothing. (Gage Eads)
> 3. Fixed 32 bit build issue.
>
> v5:
> 1. Enable RTE_ARM_FEATURE_ATOMICS on octeontx2 in default. (Jerin Jocob)
> 2. Record the reason of introducing "rte_stack_lf_stubs.h" in git
> commit.
> (Jerin, Jocob)
> 3. Fixed a conditional MACRO error in rte_atomic128_cmp_exchange. (Jerin
> Jocob)
>
> v4:
> 1. Add RTE_ARM_FEATURE_ATOMICS flag to support LSE CASP instructions.
> (Jerin Jocob)
> 2. Fix possible arm64 ABI break by making casp_op_name noinline. (Jerin
> Jocob)
> 3. Add rte_stack_lf_stubs.h to reduce the ifdef clutter. (Gage
> Eads/Jerin Jocob)
>
> v3:
> 1. Avoid duplication code with macro. (Jerin Jocob)
> 2. Make invalid memory order to strongest barrier. (Jerin Jocob)
> 3. Update doc/guides/prog_guide/env_abstraction_layer.rst. (Gage Eads)
> 4. Fix 32-bit x86 builds issue. (Gage Eads)
> 5. Correct documentation issues in UT. (Gage Eads)
>
> v2:
> Initial version.
>
> config/arm/meson.build | 2 +
> config/common_base | 3 +
> config/defconfig_arm64-octeontx2-linuxapp-gcc | 1 +
> config/defconfig_arm64-thunderx2-linuxapp-gcc | 1 +
> .../common/include/arch/arm/rte_atomic_64.h | 163 +++++++++++++++++++++
> .../common/include/arch/x86/rte_atomic_64.h | 12 --
> lib/librte_eal/common/include/generic/rte_atomic.h | 17 ++-
> 7 files changed, 186 insertions(+), 13 deletions(-)
>
> diff --git a/config/arm/meson.build b/config/arm/meson.build
> index 979018e..9f28271 100644
> --- a/config/arm/meson.build
> +++ b/config/arm/meson.build
> @@ -71,11 +71,13 @@ flags_thunderx2_extra = [
> ['RTE_CACHE_LINE_SIZE', 64],
> ['RTE_MAX_NUMA_NODES', 2],
> ['RTE_MAX_LCORE', 256],
> + ['RTE_ARM_FEATURE_ATOMICS', true],
> ['RTE_USE_C11_MEM_MODEL', true]]
> flags_octeontx2_extra = [
> ['RTE_MACHINE', '"octeontx2"'],
> ['RTE_MAX_NUMA_NODES', 1],
> ['RTE_MAX_LCORE', 24],
> + ['RTE_ARM_FEATURE_ATOMICS', true],
> ['RTE_EAL_IGB_UIO', false],
> ['RTE_USE_C11_MEM_MODEL', true]]
>
> diff --git a/config/common_base b/config/common_base
> index 8ef75c2..2054480 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -82,6 +82,9 @@ CONFIG_RTE_MAX_LCORE=128
> CONFIG_RTE_MAX_NUMA_NODES=8
> CONFIG_RTE_MAX_HEAPS=32
> CONFIG_RTE_MAX_MEMSEG_LISTS=64
> +
> +# Use ARM LSE ATOMIC instructions
> +CONFIG_RTE_ARM_FEATURE_ATOMICS=n
> # each memseg list will be limited to either RTE_MAX_MEMSEG_PER_LIST pages
> # or RTE_MAX_MEM_MB_PER_LIST megabytes worth of memory, whichever is smaller
> CONFIG_RTE_MAX_MEMSEG_PER_LIST=8192
> diff --git a/config/defconfig_arm64-octeontx2-linuxapp-gcc b/config/defconfig_arm64-octeontx2-linuxapp-gcc
> index f20da24..7687dbe 100644
> --- a/config/defconfig_arm64-octeontx2-linuxapp-gcc
> +++ b/config/defconfig_arm64-octeontx2-linuxapp-gcc
> @@ -9,6 +9,7 @@ CONFIG_RTE_MACHINE="octeontx2"
> CONFIG_RTE_CACHE_LINE_SIZE=128
> CONFIG_RTE_MAX_NUMA_NODES=1
> CONFIG_RTE_MAX_LCORE=24
> +CONFIG_RTE_ARM_FEATURE_ATOMICS=y
>
> # Doesn't support NUMA
> CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
> diff --git a/config/defconfig_arm64-thunderx2-linuxapp-gcc b/config/defconfig_arm64-thunderx2-linuxapp-gcc
> index cc5c64b..af4a89c 100644
> --- a/config/defconfig_arm64-thunderx2-linuxapp-gcc
> +++ b/config/defconfig_arm64-thunderx2-linuxapp-gcc
> @@ -9,3 +9,4 @@ CONFIG_RTE_MACHINE="thunderx2"
> CONFIG_RTE_CACHE_LINE_SIZE=64
> CONFIG_RTE_MAX_NUMA_NODES=2
> CONFIG_RTE_MAX_LCORE=256
> +CONFIG_RTE_ARM_FEATURE_ATOMICS=y
> diff --git a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
> index 97060e4..14d869b 100644
> --- a/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
> +++ b/lib/librte_eal/common/include/arch/arm/rte_atomic_64.h
> @@ -1,5 +1,6 @@
> /* SPDX-License-Identifier: BSD-3-Clause
> * Copyright(c) 2015 Cavium, Inc
> + * Copyright(c) 2019 Arm Limited
> */
>
> #ifndef _RTE_ATOMIC_ARM64_H_
> @@ -14,6 +15,9 @@ extern "C" {
> #endif
>
> #include "generic/rte_atomic.h"
> +#include <rte_branch_prediction.h>
> +#include <rte_compat.h>
> +#include <rte_debug.h>
>
> #define dsb(opt) asm volatile("dsb " #opt : : : "memory")
> #define dmb(opt) asm volatile("dmb " #opt : : : "memory")
> @@ -40,6 +44,165 @@ extern "C" {
>
> #define rte_cio_rmb() dmb(oshld)
>
> +/*------------------------ 128 bit atomic operations -------------------------*/
> +
> +#define __HAS_ACQ(mo) ((mo) != __ATOMIC_RELAXED && (mo) != __ATOMIC_RELEASE)
> +#define __HAS_RLS(mo) ((mo) == __ATOMIC_RELEASE || (mo) == __ATOMIC_ACQ_REL || \
> + (mo) == __ATOMIC_SEQ_CST)
> +
> +#define __MO_LOAD(mo) (__HAS_ACQ((mo)) ? __ATOMIC_ACQUIRE : __ATOMIC_RELAXED)
> +#define __MO_STORE(mo) (__HAS_RLS((mo)) ? __ATOMIC_RELEASE : __ATOMIC_RELAXED)
Those 4 first macros only make sense when LSE is not available (see below [1]).
Besides, they are used only once, why not directly use those
conditions where needed?
> +
> +#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
> +#define __ATOMIC128_CAS_OP(cas_op_name, op_string) \
> +static __rte_noinline rte_int128_t \
> +cas_op_name(rte_int128_t *dst, rte_int128_t old, \
> + rte_int128_t updated) \
> +{ \
> + /* caspX instructions register pair must start from even-numbered
> + * register at operand 1.
> + * So, specify registers for local variables here.
> + */ \
> + register uint64_t x0 __asm("x0") = (uint64_t)old.val[0]; \
> + register uint64_t x1 __asm("x1") = (uint64_t)old.val[1]; \
> + register uint64_t x2 __asm("x2") = (uint64_t)updated.val[0]; \
> + register uint64_t x3 __asm("x3") = (uint64_t)updated.val[1]; \
> + asm volatile( \
> + op_string " %[old0], %[old1], %[upd0], %[upd1], [%[dst]]" \
> + : [old0] "+r" (x0), \
> + [old1] "+r" (x1) \
> + : [upd0] "r" (x2), \
> + [upd1] "r" (x3), \
> + [dst] "r" (dst) \
> + : "memory"); \
> + old.val[0] = x0; \
> + old.val[1] = x1; \
> + return old; \
> +}
> +
> +__ATOMIC128_CAS_OP(__rte_cas_relaxed, "casp")
> +__ATOMIC128_CAS_OP(__rte_cas_acquire, "caspa")
> +__ATOMIC128_CAS_OP(__rte_cas_release, "caspl")
> +__ATOMIC128_CAS_OP(__rte_cas_acq_rel, "caspal")
If LSE is available, we expose __rte_cas_XX (explicitely) *non*
inlined functions, while without LSE, we expose inlined __rte_ldr_XX
and __rte_stx_XX functions.
So we have a first disparity with non-inlined vs inlined functions
depending on a #ifdef.
Then, we have a second disparity with two sets of "apis" depending on
this #ifdef.
And we expose those sets with a rte_ prefix, meaning people will try
to use them, but those are not part of a public api.
Can't we do without them ? (see below [2] for a proposal with ldr/stx,
cas should be the same)
> +#else
> +#define __ATOMIC128_LDX_OP(ldx_op_name, op_string) \
> +static inline rte_int128_t \
> +ldx_op_name(const rte_int128_t *src) \
> +{ \
> + rte_int128_t ret; \
> + asm volatile( \
> + op_string " %0, %1, %2" \
> + : "=&r" (ret.val[0]), \
> + "=&r" (ret.val[1]) \
> + : "Q" (src->val[0]) \
> + : "memory"); \
> + return ret; \
> +}
> +
> +__ATOMIC128_LDX_OP(__rte_ldx_relaxed, "ldxp")
> +__ATOMIC128_LDX_OP(__rte_ldx_acquire, "ldaxp")
> +
> +#define __ATOMIC128_STX_OP(stx_op_name, op_string) \
> +static inline uint32_t \
> +stx_op_name(rte_int128_t *dst, const rte_int128_t src) \
> +{ \
> + uint32_t ret; \
> + asm volatile( \
> + op_string " %w0, %1, %2, %3" \
> + : "=&r" (ret) \
> + : "r" (src.val[0]), \
> + "r" (src.val[1]), \
> + "Q" (dst->val[0]) \
> + : "memory"); \
> + /* Return 0 on success, 1 on failure */ \
> + return ret; \
> +}
> +
> +__ATOMIC128_STX_OP(__rte_stx_relaxed, "stxp")
> +__ATOMIC128_STX_OP(__rte_stx_release, "stlxp")
> +#endif
> +
> +static inline int __rte_experimental
The __rte_experimental tag comes first.
> +rte_atomic128_cmp_exchange(rte_int128_t *dst,
> + rte_int128_t *exp,
> + const rte_int128_t *src,
> + unsigned int weak,
> + int success,
> + int failure)
> +{
> + /* Always do strong CAS */
> + RTE_SET_USED(weak);
> + /* Ignore memory ordering for failure, memory order for
> + * success must be stronger or equal
> + */
> + RTE_SET_USED(failure);
> + /* Find invalid memory order */
> + RTE_ASSERT(success == __ATOMIC_RELAXED
> + || success == __ATOMIC_ACQUIRE
> + || success == __ATOMIC_RELEASE
> + || success == __ATOMIC_ACQ_REL
> + || success == __ATOMIC_SEQ_CST);
> +
> +#if defined(__ARM_FEATURE_ATOMICS) || defined(RTE_ARM_FEATURE_ATOMICS)
> + rte_int128_t expected = *exp;
> + rte_int128_t desired = *src;
> + rte_int128_t old;
> +
> + if (success == __ATOMIC_RELAXED)
> + old = __rte_cas_relaxed(dst, expected, desired);
> + else if (success == __ATOMIC_ACQUIRE)
> + old = __rte_cas_acquire(dst, expected, desired);
> + else if (success == __ATOMIC_RELEASE)
> + old = __rte_cas_release(dst, expected, desired);
> + else
> + old = __rte_cas_acq_rel(dst, expected, desired);
> +#else
1: the four first macros (on the memory ordering constraints) can be
moved here then undef'd once unused.
Or you can just do without them.
> + int ldx_mo = __MO_LOAD(success);
> + int stx_mo = __MO_STORE(success);
> + uint32_t ret = 1;
> + register rte_int128_t expected = *exp;
> + register rte_int128_t desired = *src;
> + register rte_int128_t old;
> +
> + /* ldx128 can not guarantee atomic,
> + * Must write back src or old to verify atomicity of ldx128;
> + */
> + do {
> + if (ldx_mo == __ATOMIC_RELAXED)
> + old = __rte_ldx_relaxed(dst);
> + else
> + old = __rte_ldx_acquire(dst);
2: how about using a simple macro that gets passed the op string?
Something like (untested):
#define __READ_128(op_string, src, dst) \
asm volatile( \
op_string " %0, %1, %2" \
: "=&r" (dst.val[0]), \
"=&r" (dst.val[1]) \
: "Q" (src->val[0]) \
: "memory")
Then used like this:
if (ldx_mo == __ATOMIC_RELAXED)
__READ_128("ldxp", dst, old);
else
__READ_128("ldaxp", dst, old);
#undef __READ_128
> +
> + if (likely(old.int128 == expected.int128)) {
> + if (stx_mo == __ATOMIC_RELAXED)
> + ret = __rte_stx_relaxed(dst, desired);
> + else
> + ret = __rte_stx_release(dst, desired);
> + } else {
> + /* In the failure case (since 'weak' is ignored and only
> + * weak == 0 is implemented), expected should contain
> + * the atomically read value of dst. This means, 'old'
> + * needs to be stored back to ensure it was read
> + * atomically.
> + */
> + if (stx_mo == __ATOMIC_RELAXED)
> + ret = __rte_stx_relaxed(dst, old);
> + else
> + ret = __rte_stx_release(dst, old);
And:
#define __STORE_128(op_string, dst, val, ret) \
asm volatile( \
op_string " %w0, %1, %2, %3" \
: "=&r" (ret) \
: "r" (val.val[0]), \
"r" (val.val[1]), \
"Q" (dst->val[0]) \
: "memory")
Used like this:
if (likely(old.int128 == expected.int128)) {
if (stx_mo == __ATOMIC_RELAXED)
__STORE_128("stxp", dst, desired, ret);
else
__STORE_128("stlxp", dst, desired, ret);
} else {
/* In the failure case (since 'weak' is ignored and only
* weak == 0 is implemented), expected should contain
* the atomically read value of dst. This means, 'old'
* needs to be stored back to ensure it was read
* atomically.
*/
if (stx_mo == __ATOMIC_RELAXED)
__STORE_128("stxp", dst, old, ret);
else
__STORE_128("stlxp", dst, old, ret);
}
#undef __STORE_128
> + }
> + } while (unlikely(ret));
> +#endif
> +
> + /* Unconditionally updating expected removes
> + * an 'if' statement.
> + * expected should already be in register if
> + * not in the cache.
> + */
> + *exp = old;
> +
> + return (old.int128 == expected.int128);
> +}
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
> index 1335d92..cfe7067 100644
> --- a/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
> +++ b/lib/librte_eal/common/include/arch/x86/rte_atomic_64.h
> @@ -183,18 +183,6 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
>
> /*------------------------ 128 bit atomic operations -------------------------*/
>
> -/**
> - * 128-bit integer structure.
> - */
> -RTE_STD_C11
> -typedef struct {
> - RTE_STD_C11
> - union {
> - uint64_t val[2];
> - __extension__ __int128 int128;
> - };
> -} __rte_aligned(16) rte_int128_t;
> -
> __rte_experimental
> static inline int
> rte_atomic128_cmp_exchange(rte_int128_t *dst,
> diff --git a/lib/librte_eal/common/include/generic/rte_atomic.h b/lib/librte_eal/common/include/generic/rte_atomic.h
> index 24ff7dc..e6ab15a 100644
> --- a/lib/librte_eal/common/include/generic/rte_atomic.h
> +++ b/lib/librte_eal/common/include/generic/rte_atomic.h
> @@ -1081,6 +1081,20 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
>
> /*------------------------ 128 bit atomic operations -------------------------*/
>
> +/**
> + * 128-bit integer structure.
> + */
> +RTE_STD_C11
> +typedef struct {
> + RTE_STD_C11
> + union {
> + uint64_t val[2];
> +#ifdef RTE_ARCH_64
> + __extension__ __int128 int128;
> +#endif
You hid this field for x86.
What is the reason?
> + };
> +} __rte_aligned(16) rte_int128_t;
> +
> #ifdef __DOXYGEN__
>
> /**
> @@ -1093,7 +1107,8 @@ static inline void rte_atomic64_clear(rte_atomic64_t *v)
> * *exp = *dst
> * @endcode
> *
> - * @note This function is currently only available for the x86-64 platform.
> + * @note This function is currently available for the x86-64 and aarch64
> + * platforms.
> *
> * @note The success and failure arguments must be one of the __ATOMIC_* values
> * defined in the C++11 standard. For details on their behavior, refer to the
> --
> 2.7.4
>
--
David Marchand
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 17/17] sched: modify internal structs and functions for 64 bit values
@ 2019-10-14 12:09 2% ` Jasvinder Singh
1 sibling, 0 replies; 200+ results
From: Jasvinder Singh @ 2019-10-14 12:09 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu, Lukasz Krakowiak
Modify internal structure and functions to support 64-bit
values for rates and stats parameters.
Release note is updated and deprecation notice is removed.
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 6 -
doc/guides/rel_notes/release_19_11.rst | 7 +-
lib/librte_sched/rte_approx.c | 57 ++++---
lib/librte_sched/rte_approx.h | 3 +-
lib/librte_sched/rte_sched.c | 211 +++++++++++++------------
lib/librte_sched/rte_sched_common.h | 12 +-
6 files changed, 162 insertions(+), 134 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 237813b64..91916d4ac 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -125,12 +125,6 @@ Deprecation Notices
to one it means it represents IV, when is set to zero it means J0 is used
directly, in this case 16 bytes of J0 need to be passed.
-* sched: To allow more traffic classes, flexible mapping of pipe queues to
- traffic classes, and subport level configuration of pipes and queues
- changes will be made to macros, data structures and API functions defined
- in "rte_sched.h". These changes are aligned to improvements suggested in the
- RFC https://mails.dpdk.org/archives/dev/2018-November/120035.html.
-
* metrics: The function ``rte_metrics_init`` will have a non-void return
in order to notify errors instead of calling ``rte_exit``.
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 23ceb8f67..87812b32c 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -172,6 +172,11 @@ API Changes
* ethdev: changed ``rte_eth_dev_owner_delete`` return value from ``void`` to
``int`` to provide a way to report various error conditions.
+* sched: The pipe nodes configuration parameters such as number of pipes,
+ pipe queue sizes, pipe profiles, etc., are moved from port level structure
+ to subport level. This allows different subports of the same port to
+ have different configuration for the pipe nodes.
+
ABI Changes
-----------
@@ -259,7 +264,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_rcu.so.1
librte_reorder.so.1
librte_ring.so.2
- librte_sched.so.3
+ + librte_sched.so.4
librte_security.so.2
librte_stack.so.1
librte_table.so.3
diff --git a/lib/librte_sched/rte_approx.c b/lib/librte_sched/rte_approx.c
index 30620b83d..4883d3969 100644
--- a/lib/librte_sched/rte_approx.c
+++ b/lib/librte_sched/rte_approx.c
@@ -18,22 +18,23 @@
*/
/* fraction comparison: compare (a/b) and (c/d) */
-static inline uint32_t
-less(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
+static inline sched_counter_t
+less(sched_counter_t a, sched_counter_t b, sched_counter_t c, sched_counter_t d)
{
return a*d < b*c;
}
-static inline uint32_t
-less_or_equal(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
+static inline sched_counter_t
+less_or_equal(sched_counter_t a, sched_counter_t b, sched_counter_t c,
+ sched_counter_t d)
{
return a*d <= b*c;
}
/* check whether a/b is a valid approximation */
-static inline uint32_t
-matches(uint32_t a, uint32_t b,
- uint32_t alpha_num, uint32_t d_num, uint32_t denum)
+static inline sched_counter_t
+matches(sched_counter_t a, sched_counter_t b,
+ sched_counter_t alpha_num, sched_counter_t d_num, sched_counter_t denum)
{
if (less_or_equal(a, b, alpha_num - d_num, denum))
return 0;
@@ -45,33 +46,39 @@ matches(uint32_t a, uint32_t b,
}
static inline void
-find_exact_solution_left(uint32_t p_a, uint32_t q_a, uint32_t p_b, uint32_t q_b,
- uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p, uint32_t *q)
+find_exact_solution_left(sched_counter_t p_a, sched_counter_t q_a,
+ sched_counter_t p_b, sched_counter_t q_b, sched_counter_t alpha_num,
+ sched_counter_t d_num, sched_counter_t denum, sched_counter_t *p,
+ sched_counter_t *q)
{
- uint32_t k_num = denum * p_b - (alpha_num + d_num) * q_b;
- uint32_t k_denum = (alpha_num + d_num) * q_a - denum * p_a;
- uint32_t k = (k_num / k_denum) + 1;
+ sched_counter_t k_num = denum * p_b - (alpha_num + d_num) * q_b;
+ sched_counter_t k_denum = (alpha_num + d_num) * q_a - denum * p_a;
+ sched_counter_t k = (k_num / k_denum) + 1;
*p = p_b + k * p_a;
*q = q_b + k * q_a;
}
static inline void
-find_exact_solution_right(uint32_t p_a, uint32_t q_a, uint32_t p_b, uint32_t q_b,
- uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p, uint32_t *q)
+find_exact_solution_right(sched_counter_t p_a, sched_counter_t q_a,
+ sched_counter_t p_b, sched_counter_t q_b, sched_counter_t alpha_num,
+ sched_counter_t d_num, sched_counter_t denum, sched_counter_t *p,
+ sched_counter_t *q)
{
- uint32_t k_num = - denum * p_b + (alpha_num - d_num) * q_b;
- uint32_t k_denum = - (alpha_num - d_num) * q_a + denum * p_a;
- uint32_t k = (k_num / k_denum) + 1;
+ sched_counter_t k_num = -denum * p_b + (alpha_num - d_num) * q_b;
+ sched_counter_t k_denum = -(alpha_num - d_num) * q_a + denum * p_a;
+ sched_counter_t k = (k_num / k_denum) + 1;
*p = p_b + k * p_a;
*q = q_b + k * q_a;
}
static int
-find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num, uint32_t denum, uint32_t *p, uint32_t *q)
+find_best_rational_approximation(sched_counter_t alpha_num,
+ sched_counter_t d_num, sched_counter_t denum, sched_counter_t *p,
+ sched_counter_t *q)
{
- uint32_t p_a, q_a, p_b, q_b;
+ sched_counter_t p_a, q_a, p_b, q_b;
/* check assumptions on the inputs */
if (!((0 < d_num) && (d_num < alpha_num) && (alpha_num < denum) && (d_num + alpha_num < denum))) {
@@ -85,8 +92,8 @@ find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num, uint32_t de
q_b = 1;
while (1) {
- uint32_t new_p_a, new_q_a, new_p_b, new_q_b;
- uint32_t x_num, x_denum, x;
+ sched_counter_t new_p_a, new_q_a, new_p_b, new_q_b;
+ sched_counter_t x_num, x_denum, x;
int aa, bb;
/* compute the number of steps to the left */
@@ -139,9 +146,9 @@ find_best_rational_approximation(uint32_t alpha_num, uint32_t d_num, uint32_t de
}
}
-int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q)
+int rte_approx(double alpha, double d, sched_counter_t *p, sched_counter_t *q)
{
- uint32_t alpha_num, d_num, denum;
+ sched_counter_t alpha_num, d_num, denum;
/* Check input arguments */
if (!((0.0 < d) && (d < alpha) && (alpha < 1.0))) {
@@ -159,8 +166,8 @@ int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q)
d *= 10;
denum *= 10;
}
- alpha_num = (uint32_t) alpha;
- d_num = (uint32_t) d;
+ alpha_num = (sched_counter_t) alpha;
+ d_num = (sched_counter_t) d;
/* Perform approximation */
return find_best_rational_approximation(alpha_num, d_num, denum, p, q);
diff --git a/lib/librte_sched/rte_approx.h b/lib/librte_sched/rte_approx.h
index 0244d98f1..e591e122d 100644
--- a/lib/librte_sched/rte_approx.h
+++ b/lib/librte_sched/rte_approx.h
@@ -20,6 +20,7 @@ extern "C" {
***/
#include <stdint.h>
+#include "rte_sched_common.h"
/**
* Find best rational approximation
@@ -37,7 +38,7 @@ extern "C" {
* @return
* 0 upon success, error code otherwise
*/
-int rte_approx(double alpha, double d, uint32_t *p, uint32_t *q);
+int rte_approx(double alpha, double d, sched_counter_t *p, sched_counter_t *q);
#ifdef __cplusplus
}
diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c
index 710ecf65a..11d1febe2 100644
--- a/lib/librte_sched/rte_sched.c
+++ b/lib/librte_sched/rte_sched.c
@@ -49,13 +49,13 @@
struct rte_sched_pipe_profile {
/* Token bucket (TB) */
- uint32_t tb_period;
- uint32_t tb_credits_per_period;
- uint32_t tb_size;
+ sched_counter_t tb_period;
+ sched_counter_t tb_credits_per_period;
+ sched_counter_t tb_size;
/* Pipe traffic classes */
- uint32_t tc_period;
- uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t tc_period;
+ sched_counter_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
uint8_t tc_ov_weight;
/* Pipe best-effort traffic class queues */
@@ -65,20 +65,20 @@ struct rte_sched_pipe_profile {
struct rte_sched_pipe {
/* Token bucket (TB) */
uint64_t tb_time; /* time of last update */
- uint32_t tb_credits;
+ sched_counter_t tb_credits;
/* Pipe profile and flags */
uint32_t profile;
/* Traffic classes (TCs) */
uint64_t tc_time; /* time of next update */
- uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
/* Weighted Round Robin (WRR) */
uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE];
/* TC oversubscription */
- uint32_t tc_ov_credits;
+ sched_counter_t tc_ov_credits;
uint8_t tc_ov_period_id;
} __rte_cache_aligned;
@@ -141,28 +141,28 @@ struct rte_sched_grinder {
struct rte_sched_subport {
/* Token bucket (TB) */
uint64_t tb_time; /* time of last update */
- uint32_t tb_period;
- uint32_t tb_credits_per_period;
- uint32_t tb_size;
- uint32_t tb_credits;
+ sched_counter_t tb_period;
+ sched_counter_t tb_credits_per_period;
+ sched_counter_t tb_size;
+ sched_counter_t tb_credits;
/* Traffic classes (TCs) */
uint64_t tc_time; /* time of next update */
- uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint32_t tc_period;
+ sched_counter_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t tc_period;
/* TC oversubscription */
- uint32_t tc_ov_wm;
- uint32_t tc_ov_wm_min;
- uint32_t tc_ov_wm_max;
+ sched_counter_t tc_ov_wm;
+ sched_counter_t tc_ov_wm_min;
+ sched_counter_t tc_ov_wm_max;
uint8_t tc_ov_period_id;
uint8_t tc_ov;
uint32_t tc_ov_n;
double tc_ov_rate;
/* Statistics */
- struct rte_sched_subport_stats stats;
+ struct rte_sched_subport_stats stats __rte_cache_aligned;
/* Subport pipes */
uint32_t n_pipes_per_subport_enabled;
@@ -170,7 +170,7 @@ struct rte_sched_subport {
uint32_t n_max_pipe_profiles;
/* Pipe best-effort TC rate */
- uint32_t pipe_tc_be_rate_max;
+ sched_counter_t pipe_tc_be_rate_max;
/* Pipe queues size */
uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
@@ -212,7 +212,7 @@ struct rte_sched_port {
uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
- uint32_t rate;
+ sched_counter_t rate;
uint32_t mtu;
uint32_t frame_overhead;
int socket;
@@ -517,33 +517,35 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i)
struct rte_sched_pipe_profile *p = subport->pipe_profiles + i;
RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n"
- " Token bucket: period = %u, credits per period = %u, size = %u\n"
- " Traffic classes: period = %u,\n"
- " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n"
+ " Token bucket: period = %"PRIu64", credits per period = %"PRIu64", size = %"PRIu64"\n"
+ " Traffic classes: period = %"PRIu64",\n"
+ " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
" Best-effort traffic class oversubscription: weight = %hhu\n"
" WRR cost: [%hhu, %hhu, %hhu, %hhu]\n",
i,
/* Token bucket */
- p->tb_period,
- p->tb_credits_per_period,
- p->tb_size,
+ (uint64_t)p->tb_period,
+ (uint64_t)p->tb_credits_per_period,
+ (uint64_t)p->tb_size,
/* Traffic classes */
- p->tc_period,
- p->tc_credits_per_period[0],
- p->tc_credits_per_period[1],
- p->tc_credits_per_period[2],
- p->tc_credits_per_period[3],
- p->tc_credits_per_period[4],
- p->tc_credits_per_period[5],
- p->tc_credits_per_period[6],
- p->tc_credits_per_period[7],
- p->tc_credits_per_period[8],
- p->tc_credits_per_period[9],
- p->tc_credits_per_period[10],
- p->tc_credits_per_period[11],
- p->tc_credits_per_period[12],
+ (uint64_t)p->tc_period,
+ (uint64_t)p->tc_credits_per_period[0],
+ (uint64_t)p->tc_credits_per_period[1],
+ (uint64_t)p->tc_credits_per_period[2],
+ (uint64_t)p->tc_credits_per_period[3],
+ (uint64_t)p->tc_credits_per_period[4],
+ (uint64_t)p->tc_credits_per_period[5],
+ (uint64_t)p->tc_credits_per_period[6],
+ (uint64_t)p->tc_credits_per_period[7],
+ (uint64_t)p->tc_credits_per_period[8],
+ (uint64_t)p->tc_credits_per_period[9],
+ (uint64_t)p->tc_credits_per_period[10],
+ (uint64_t)p->tc_credits_per_period[11],
+ (uint64_t)p->tc_credits_per_period[12],
/* Best-effort traffic class oversubscription */
p->tc_ov_weight,
@@ -553,7 +555,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i)
}
static inline uint64_t
-rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate)
+rte_sched_time_ms_to_bytes(sched_counter_t time_ms, sched_counter_t rate)
{
uint64_t time = time_ms;
@@ -566,7 +568,7 @@ static void
rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
struct rte_sched_pipe_params *src,
struct rte_sched_pipe_profile *dst,
- uint32_t rate)
+ sched_counter_t rate)
{
uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE];
uint32_t lcd1, lcd2, lcd;
@@ -581,8 +583,8 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
/ (double) rate;
double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
- rte_approx(tb_rate, d,
- &dst->tb_credits_per_period, &dst->tb_period);
+ rte_approx(tb_rate, d, &dst->tb_credits_per_period,
+ &dst->tb_period);
}
dst->tb_size = src->tb_size;
@@ -594,8 +596,8 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
if (subport->qsize[i])
dst->tc_credits_per_period[i]
- = rte_sched_time_ms_to_bytes(src->tc_period,
- src->tc_rate[i]);
+ = (sched_counter_t) rte_sched_time_ms_to_bytes(
+ src->tc_period, src->tc_rate[i]);
dst->tc_ov_weight = src->tc_ov_weight;
@@ -637,7 +639,8 @@ rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport,
subport->pipe_tc_be_rate_max = 0;
for (i = 0; i < subport->n_pipe_profiles; i++) {
struct rte_sched_pipe_params *src = params->pipe_profiles + i;
- uint32_t pipe_tc_be_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
+ sched_counter_t pipe_tc_be_rate =
+ src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE];
if (subport->pipe_tc_be_rate_max < pipe_tc_be_rate)
subport->pipe_tc_be_rate_max = pipe_tc_be_rate;
@@ -647,7 +650,7 @@ rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport,
static int
rte_sched_subport_check_params(struct rte_sched_subport_params *params,
uint32_t n_max_pipes_per_subport,
- uint32_t rate)
+ sched_counter_t rate)
{
uint32_t i;
@@ -684,7 +687,7 @@ rte_sched_subport_check_params(struct rte_sched_subport_params *params,
}
for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
- uint32_t tc_rate = params->tc_rate[i];
+ sched_counter_t tc_rate = params->tc_rate[i];
uint16_t qsize = params->qsize[i];
if ((qsize == 0 && tc_rate != 0) ||
@@ -910,36 +913,40 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i)
struct rte_sched_subport *s = port->subports[i];
RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n"
- " Token bucket: period = %u, credits per period = %u, size = %u\n"
- " Traffic classes: period = %u\n"
- " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n"
- " Best effort traffic class oversubscription: wm min = %u, wm max = %u\n",
+ " Token bucket: period = %"PRIu64", credits per period = %"PRIu64
+ ", size = %"PRIu64"\n"
+ " Traffic classes: period = %"PRIu64"\n"
+ " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
+ " Best effort traffic class oversubscription: wm min = %"PRIu64
+ ", wm max = %"PRIu64"\n",
i,
/* Token bucket */
- s->tb_period,
- s->tb_credits_per_period,
- s->tb_size,
+ (uint64_t)s->tb_period,
+ (uint64_t)s->tb_credits_per_period,
+ (uint64_t)s->tb_size,
/* Traffic classes */
- s->tc_period,
- s->tc_credits_per_period[0],
- s->tc_credits_per_period[1],
- s->tc_credits_per_period[2],
- s->tc_credits_per_period[3],
- s->tc_credits_per_period[4],
- s->tc_credits_per_period[5],
- s->tc_credits_per_period[6],
- s->tc_credits_per_period[7],
- s->tc_credits_per_period[8],
- s->tc_credits_per_period[9],
- s->tc_credits_per_period[10],
- s->tc_credits_per_period[11],
- s->tc_credits_per_period[12],
+ (uint64_t)s->tc_period,
+ (uint64_t)s->tc_credits_per_period[0],
+ (uint64_t)s->tc_credits_per_period[1],
+ (uint64_t)s->tc_credits_per_period[2],
+ (uint64_t)s->tc_credits_per_period[3],
+ (uint64_t)s->tc_credits_per_period[4],
+ (uint64_t)s->tc_credits_per_period[5],
+ (uint64_t)s->tc_credits_per_period[6],
+ (uint64_t)s->tc_credits_per_period[7],
+ (uint64_t)s->tc_credits_per_period[8],
+ (uint64_t)s->tc_credits_per_period[9],
+ (uint64_t)s->tc_credits_per_period[10],
+ (uint64_t)s->tc_credits_per_period[11],
+ (uint64_t)s->tc_credits_per_period[12],
/* Best effort traffic class oversubscription */
- s->tc_ov_wm_min,
- s->tc_ov_wm_max);
+ (uint64_t)s->tc_ov_wm_min,
+ (uint64_t)s->tc_ov_wm_max);
}
static void
@@ -1023,7 +1030,8 @@ rte_sched_subport_config(struct rte_sched_port *port,
double tb_rate = ((double) params->tb_rate) / ((double) port->rate);
double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
- rte_approx(tb_rate, d, &s->tb_credits_per_period, &s->tb_period);
+ rte_approx(tb_rate, d, &s->tb_credits_per_period,
+ &s->tb_period);
}
s->tb_size = params->tb_size;
@@ -1035,8 +1043,8 @@ rte_sched_subport_config(struct rte_sched_port *port,
for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
if (params->qsize[i])
s->tc_credits_per_period[i]
- = rte_sched_time_ms_to_bytes(params->tc_period,
- params->tc_rate[i]);
+ = (sched_counter_t) rte_sched_time_ms_to_bytes(
+ params->tc_period, params->tc_rate[i]);
}
s->tc_time = port->time + s->tc_period;
for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
@@ -1970,13 +1978,15 @@ grinder_credits_update(struct rte_sched_port *port,
/* Subport TB */
n_periods = (port->time - subport->tb_time) / subport->tb_period;
subport->tb_credits += n_periods * subport->tb_credits_per_period;
- subport->tb_credits = rte_sched_min_val_2_u32(subport->tb_credits, subport->tb_size);
+ subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
+ subport->tb_size);
subport->tb_time += n_periods * subport->tb_period;
/* Pipe TB */
n_periods = (port->time - pipe->tb_time) / params->tb_period;
pipe->tb_credits += n_periods * params->tb_credits_per_period;
- pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits, params->tb_size);
+ pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
+ params->tb_size);
pipe->tb_time += n_periods * params->tb_period;
/* Subport TCs */
@@ -1998,13 +2008,13 @@ grinder_credits_update(struct rte_sched_port *port,
#else
-static inline uint32_t
+static inline sched_counter_t
grinder_tc_ov_credits_update(struct rte_sched_port *port,
struct rte_sched_subport *subport)
{
- uint32_t tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint32_t tc_consumption = 0, tc_ov_consumption_max;
- uint32_t tc_ov_wm = subport->tc_ov_wm;
+ sched_counter_t tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t tc_consumption = 0, tc_ov_consumption_max;
+ sched_counter_t tc_ov_wm = subport->tc_ov_wm;
uint32_t i;
if (subport->tc_ov == 0)
@@ -2053,13 +2063,15 @@ grinder_credits_update(struct rte_sched_port *port,
/* Subport TB */
n_periods = (port->time - subport->tb_time) / subport->tb_period;
subport->tb_credits += n_periods * subport->tb_credits_per_period;
- subport->tb_credits = rte_sched_min_val_2_u32(subport->tb_credits, subport->tb_size);
+ subport->tb_credits = rte_sched_min_val_2(subport->tb_credits,
+ subport->tb_size);
subport->tb_time += n_periods * subport->tb_period;
/* Pipe TB */
n_periods = (port->time - pipe->tb_time) / params->tb_period;
pipe->tb_credits += n_periods * params->tb_credits_per_period;
- pipe->tb_credits = rte_sched_min_val_2_u32(pipe->tb_credits, params->tb_size);
+ pipe->tb_credits = rte_sched_min_val_2(pipe->tb_credits,
+ params->tb_size);
pipe->tb_time += n_periods * params->tb_period;
/* Subport TCs */
@@ -2101,11 +2113,11 @@ grinder_credits_check(struct rte_sched_port *port,
struct rte_sched_pipe *pipe = grinder->pipe;
struct rte_mbuf *pkt = grinder->pkt;
uint32_t tc_index = grinder->tc_index;
- uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
- uint32_t subport_tb_credits = subport->tb_credits;
- uint32_t subport_tc_credits = subport->tc_credits[tc_index];
- uint32_t pipe_tb_credits = pipe->tb_credits;
- uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
+ sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
+ sched_counter_t subport_tb_credits = subport->tb_credits;
+ sched_counter_t subport_tc_credits = subport->tc_credits[tc_index];
+ sched_counter_t pipe_tb_credits = pipe->tb_credits;
+ sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
int enough_credits;
/* Check queue credits */
@@ -2136,21 +2148,22 @@ grinder_credits_check(struct rte_sched_port *port,
struct rte_sched_pipe *pipe = grinder->pipe;
struct rte_mbuf *pkt = grinder->pkt;
uint32_t tc_index = grinder->tc_index;
- uint32_t pkt_len = pkt->pkt_len + port->frame_overhead;
- uint32_t subport_tb_credits = subport->tb_credits;
- uint32_t subport_tc_credits = subport->tc_credits[tc_index];
- uint32_t pipe_tb_credits = pipe->tb_credits;
- uint32_t pipe_tc_credits = pipe->tc_credits[tc_index];
- uint32_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint32_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
- uint32_t pipe_tc_ov_credits, i;
+ sched_counter_t pkt_len = pkt->pkt_len + port->frame_overhead;
+ sched_counter_t subport_tb_credits = subport->tb_credits;
+ sched_counter_t subport_tc_credits = subport->tc_credits[tc_index];
+ sched_counter_t pipe_tb_credits = pipe->tb_credits;
+ sched_counter_t pipe_tc_credits = pipe->tc_credits[tc_index];
+ sched_counter_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ sched_counter_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0};
+ sched_counter_t pipe_tc_ov_credits;
+ uint32_t i;
int enough_credits;
for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
- pipe_tc_ov_mask1[i] = UINT32_MAX;
+ pipe_tc_ov_mask1[i] = ~0;
pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe->tc_ov_credits;
- pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = UINT32_MAX;
+ pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = ~0;
pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index];
/* Check pipe and subport credits */
diff --git a/lib/librte_sched/rte_sched_common.h b/lib/librte_sched/rte_sched_common.h
index 8c191a9b8..06520a686 100644
--- a/lib/librte_sched/rte_sched_common.h
+++ b/lib/librte_sched/rte_sched_common.h
@@ -14,8 +14,16 @@ extern "C" {
#define __rte_aligned_16 __attribute__((__aligned__(16)))
-static inline uint32_t
-rte_sched_min_val_2_u32(uint32_t x, uint32_t y)
+//#define COUNTER_SIZE_64
+
+#ifdef COUNTER_SIZE_64
+typedef uint64_t sched_counter_t;
+#else
+typedef uint32_t sched_counter_t;
+#endif
+
+static inline sched_counter_t
+rte_sched_min_val_2(sched_counter_t x, sched_counter_t y)
{
return (x < y)? x : y;
}
--
2.21.0
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-13 23:07 0% ` Zhang, Roy Fan
@ 2019-10-14 11:10 0% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2019-10-14 11:10 UTC (permalink / raw)
To: Zhang, Roy Fan, Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Doherty, Declan
Cc: 'Anoob Joseph', Jerin Jacob, Hemant Agrawal
> Hi Akhil,
>
> Thanks for the review and comments!
> Knowing you are extremely busy. Here is my point in brief:
> I think placing the CPU synchronous crypto in the rte_security make sense, as
>
> 1. rte_security contains inline crypto and lookaside crypto action type already, adding cpu_crypto action type is reasonable.
> 2. rte_security contains the security features may not supported by all devices, such as crypto, ipsec, and PDCP. cpu_crypto follow this
> category, again crypto.
> 3. placing CPU synchronous crypto API in rte_security is natural - as inline mode works synchronously, too. However cryptodev doesn't.
> 4. placing CPU synchronous crypto API in rte_security helps boosting SW crypto performance, I have already provided a simple perf test
> inside the unit test in the patchset for the user to try out - just comparing its output against DPDK crypto perf app output.
> 5. placing CPU synchronous crypto API in cryptodev will never serve HW lookaside crypto PMDs, as making them to work synchronously
> have huge performance penalty. However Cryptodev framework's existing design is providing APIs that will work in all crypto PMDs
> (rte_cryptodev_enqueue_burst / dequeue_burst for example), this does not fit in cryptodev's principle.
> 6. placing CPU synchronous crypto API in cryptodev confuses the user, as:
> - the session created for async mode may not work in sync mode
> - both enqueue/dequeue and cpu_crypto_process does the same crypto processing, but one PMD may support only one API (set),
> the other may support another, and the third PMD supports both. We have to provide another API to let the user query which one to
> support which.
> - two completely different code paths for async/sync mode.
> 7. You said in the end of the email - placing CPU synchronous crypto API into rte_security is not acceptable as it does not do any
> rte_security stuff - crypto isn't? You may call this a quibble, but in my idea, in the patchset both PMDs' implementations did offload the work
> to the CPU's special circuit designed dedicated to accelerate the crypto processing.
>
> To me cryptodev is the one CPU synchronous crypto API should not go into, rte_security is.
I also don't understand why rte_security is not an option here.
We do have inline-crypto right now, why we can't have cpu-crypto with new process() API here?
Actually would like to hear more opinions from the community here -
what other interested parties think is the best way for introducing cpu-crypto specific API?
Konstantin
>
> Regards,
> Fan
>
> > -----Original Message-----
> > From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> > Sent: Friday, October 11, 2019 2:24 PM
> > To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; 'dev@dpdk.org'
> > <dev@dpdk.org>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>;
> > 'Thomas Monjalon' <thomas@monjalon.net>; Zhang, Roy Fan
> > <roy.fan.zhang@intel.com>; Doherty, Declan <declan.doherty@intel.com>
> > Cc: 'Anoob Joseph' <anoobj@marvell.com>
> > Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action type and
> > API
> >
> > Hi Konstantin,
> >
> > >
> > > Hi Akhil,
> > >
> > ..[snip]
> >
> > > > > > > > OK let us assume that you have a separate structure. But I
> > > > > > > > have a few
> > > > > queries:
> > > > > > > > 1. how can multiple drivers use a same session
> > > > > > >
> > > > > > > As a short answer: they can't.
> > > > > > > It is pretty much the same approach as with rte_security -
> > > > > > > each device
> > > needs
> > > > > to
> > > > > > > create/init its own session.
> > > > > > > So upper layer would need to maintain its own array (or so) for such
> > case.
> > > > > > > Though the question is why would you like to have same session
> > > > > > > over
> > > > > multiple
> > > > > > > SW backed devices?
> > > > > > > As it would be anyway just a synchronous function call that
> > > > > > > will be
> > > executed
> > > > > on
> > > > > > > the same cpu.
> > > > > >
> > > > > > I may have single FAT tunnel which may be distributed over
> > > > > > multiple Cores, and each core is affined to a different SW device.
> > > > >
> > > > > If it is pure SW, then we don't need multiple devices for such scenario.
> > > > > Device in that case is pure abstraction that we can skip.
> > > >
> > > > Yes agreed, but that liberty is given to the application whether it
> > > > need multiple devices with single queue or a single device with multiple
> > queues.
> > > > I think that independence should not be broken in this new API.
> > > > >
> > > > > > So a single session may be accessed by multiple devices.
> > > > > >
> > > > > > One more example would be depending on packet sizes, I may
> > > > > > switch
> > > between
> > > > > > HW/SW PMDs with the same session.
> > > > >
> > > > > Sure, but then we'll have multiple sessions.
> > > >
> > > > No, the session will be same and it will have multiple private data
> > > > for each of
> > > the PMD.
> > > >
> > > > > BTW, we have same thing now - these private session pointers are
> > > > > just
> > > stored
> > > > > inside the same rte_crypto_sym_session.
> > > > > And if user wants to support this model, he would also need to
> > > > > store <dev_id, queue_id> pair for each HW device anyway.
> > > >
> > > > Yes agreed, but how is that thing happening in your new struct, you
> > > > cannot
> > > support that.
> > >
> > > User can store all these info in his own struct.
> > > That's exactly what we have right now.
> > > Let say ipsec-secgw has to store for each IPsec SA:
> > > pointer to crypto-session and/or pointer to security session plus (for
> > > lookaside-devices) cdev_id_qp that allows it to extract dev_id +
> > > queue_id information.
> > > As I understand that works for now, as each ipsec_sa uses only one
> > > dev+queue. Though if someone would like to use multiple devices/queues
> > > for the same SA - he would need to have an array of these <dev+queue>
> > pairs.
> > > So even right now rte_cryptodev_sym_session is not self-consistent and
> > > requires extra information to be maintained by user.
> >
> > Why are you increasing the complexity for the user application.
> > The new APIs and struct should be such that it need to do minimum changes
> > in the stack so that stack is portable on multiple vendors.
> > You should try to hide as much complexity in the driver or lib to give the user
> > simple APIs.
> >
> > Having a same session for multiple devices was added by Intel only for some
> > use cases.
> > And we had split that session create API into 2. Now if those are not useful
> > shall we move back to the single API. I think @Doherty, Declan and @De Lara
> > Guarch, Pablo can comment on this.
> >
> > >
> > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > > > 2. Can somebody use the scheduler pmd for scheduling the
> > > > > > > > different
> > > type
> > > > > of
> > > > > > > payloads for the same session?
> > > > > > >
> > > > > > > In theory yes.
> > > > > > > Though for that scheduler pmd should have inside it's
> > > > > > > rte_crypto_cpu_sym_session an array of pointers to the
> > > > > > > underlying devices sessions.
> > > > > > >
> > > > > > > >
> > > > > > > > With your proposal the APIs would be very specific to your
> > > > > > > > use case
> > > only.
> > > > > > >
> > > > > > > Yes in some way.
> > > > > > > I consider that API specific for SW backed crypto PMDs.
> > > > > > > I can hardly see how any 'real HW' PMDs (lksd-none,
> > > > > > > lksd-proto) will
> > > benefit
> > > > > > > from it.
> > > > > > > Current crypto-op API is very much HW oriented.
> > > > > > > Which is ok, that's for it was intended for, but I think we
> > > > > > > also need one
> > > that
> > > > > > > would be designed
> > > > > > > for SW backed implementation in mind.
> > > > > >
> > > > > > We may re-use your API for HW PMDs as well which do not have
> > > requirement
> > > > > of
> > > > > > Crypto-op/mbuf etc.
> > > > > > The return type of your new process API may have a status which
> > > > > > say
> > > > > 'processed'
> > > > > > Or can be say 'enqueued'. So if it is 'enqueued', we may have a
> > > > > > new API for
> > > > > raw
> > > > > > Bufs dequeue as well.
> > > > > >
> > > > > > This requirement can be for any hardware PMDs like QAT as well.
> > > > >
> > > > > I don't think it is a good idea to extend this API for async (lookaside)
> > devices.
> > > > > You'll need to:
> > > > > - provide dev_id and queue_id for each process(enqueue) and
> > > > > dequeuer operation.
> > > > > - provide IOVA for all buffers passing to that function (data
> > > > > buffers, digest,
> > > IV,
> > > > > aad).
> > > > > - On dequeue provide some way to associate dequed data and digest
> > > > > buffers with
> > > > > crypto-session that was used (and probably with mbuf).
> > > > > So most likely we'll end up with another just version of our
> > > > > current crypto-op structure.
> > > > > If you'd like to get rid of mbufs dependency within current
> > > > > crypto-op API that understandable, but I don't think we should
> > > > > have same API for both sync (CPU) and async
> > > > > (lookaside) cases.
> > > > > It doesn't seem feasible at all and voids whole purpose of that patch.
> > > >
> > > > At this moment we are not much concerned about the dequeue API and
> > > > about
> > > the
> > > > HW PMD support. It is just that the new API should be generic enough
> > > > to be
> > > used in
> > > > some future scenarios as well. I am just highlighting the possible
> > > > usecases
> > > which can
> > > > be there in future.
> > >
> > > Sorry, but I strongly disagree with such approach.
> > > We should stop adding/modifying API 'just in case' and because 'it
> > > might be useful for some future HW'.
> > > Inside DPDK we already do have too many dev level APIs without any
> > > implementations.
> > > That's quite bad practice and very dis-orienting for end-users.
> > > I think to justify API additions/changes we need at least one proper
> > > implementation for it, or at least some strong evidence that people
> > > are really committed to support it in nearest future.
> > > BTW, that what TB agreed on, nearly a year ago.
> > >
> > > This new API (if we'll go ahead with it of course) would stay
> > > experimental for some time anyway to make sure we don't miss anything
> > > needed (I think for about a year time- frame).
> > > So if you guys *really* want to extend it support _async_ devices too
> > > - I am open for modifications/additions here.
> > > Though personally I think such addition would over-complicate things
> > > and we'll end up with another reincarnation of current crypto-op.
> > > We actually discussed it internally, and decided to drop that idea because
> > of that.
> > > Again, my opinion - for lookaside devices it might be better to try to
> > > optimize current crypto-op path (remove mbuf requirement, probably add
> > > ability to group by session on enqueue/dequeue, etc.).
> >
> > I agree that the new API is experimental and can be modified later. So no
> > issues in that, but we can keep some things in mind while defining APIs.
> > These were some comments from my side, if those are impacting the current
> > scenario, you can drop those. We will take care of those later.
> >
> > >
> > > >
> > > > What is the issue that you face in making a dev-op for this new API.
> > > > Do you see
> > > any
> > > > performance impact with that?
> > >
> > > There are two main things:
> > > 1. user would need to maintain and provide for each process() call
> > > dev_id+queue_id.
> > > That's means extra (and totally unnecessary for SW) overhead.
> >
> > You are using a crypto device for performing the processing, you must use
> > dev_id to identify which SW device it is. This is how the DPDK Framework
> > works.
> > .
> >
> > > 2. yes I would expect some perf overhead too - it would be extra call or
> > branch.
> > > Again as it would be data-dependency - most likely cpu wouldn't be
> > > able to pipeline it efficiently:
> > >
> > > rte_crypto_sym_process(uint8_t dev_id, uint16 qp_id,
> > > rte_crypto_sym_session *ses, ...) {
> > > struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
> > > return (*dev->process)(sess->data[dev->driver_id, ...); }
> > >
> > > driver_specific_process(driver_specific_sym_session *sess) {
> > > return sess->process(sess, ...) ;
> > > }
> > >
> > > I didn't make any exact measurements but sure it would be slower than
> > just:
> > > session_udata->process(session->udata->sess, ...); Again it would be
> > > much more noticeable on low end cpus.
> > > Let say here:
> > > http://mails.dpdk.org/archives/dev/2019-September/144350.html
> > > Jerin claims 1.5-3% drop for introducing extra call via hiding eth_dev
> > > contents - I suppose we would have something similar here.
> > > I do realize that in majority of cases crypto is more expensive then
> > > RX/TX, but still.
> > >
> > > If it would be a really unavoidable tradeoff (support already existing
> > > API, or so) I wouldn't mind, but I don't see any real need for it right now.
> >
> > Calling session_udata->process(session->udata->sess, ...); from the
> > application and Application need to maintain for each PMD the process() API
> > in its memory will make the application not portable to other vendors.
> >
> > What we are doing here is defining another way to create sessions for the
> > same stuff that is already done. This make applications non-portable and
> > confusing for the application writer.
> >
> > I would say you should do some profiling first. As you also mentioned crypto
> > workload is more Cycle consuming, it will not impact this case.
> >
> >
> > >
> > > >
> > > > >
> > > > > > That is why a dev-ops would be a better option.
> > > > > >
> > > > > > >
> > > > > > > > When you would add more functionality to this sync
> > > > > > > > API/struct, it will
> > > end
> > > > > up
> > > > > > > being the same API/struct.
> > > > > > > >
> > > > > > > > Let us see how close/ far we are from the existing APIs
> > > > > > > > when the
> > > actual
> > > > > > > implementation is done.
> > > > > > > >
> > > > > > > > > > I am not sure if that would be needed.
> > > > > > > > > > It would be internal to the driver that if synchronous
> > > > > > > > > > processing is
> > > > > > > > > supported(from feature flag) and
> > > > > > > > > > Have relevant fields in xform(the newly added ones which
> > > > > > > > > > are
> > > packed
> > > > > as
> > > > > > > per
> > > > > > > > > your suggestions) set,
> > > > > > > > > > It will create that type of session.
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > > + * Main points:
> > > > > > > > > > > + * - Current crypto-dev API is reasonably mature and
> > > > > > > > > > > + it is
> > > desirable
> > > > > > > > > > > + * to keep it unchanged (API/ABI stability). From other
> > side, this
> > > > > > > > > > > + * new sync API is new one and probably would require
> > extra
> > > > > changes.
> > > > > > > > > > > + * Having it as a new one allows to mark it as experimental,
> > > without
> > > > > > > > > > > + * affecting existing one.
> > > > > > > > > > > + * - Fully opaque cpu_sym_session structure gives more
> > flexibility
> > > > > > > > > > > + * to the PMD writers and again allows to avoid ABI
> > breakages
> > > in
> > > > > future.
> > > > > > > > > > > + * - process() function per set of xforms
> > > > > > > > > > > + * allows to expose different process() functions for
> > different
> > > > > > > > > > > + * xform combinations. PMD writer can decide, does he
> > wants
> > > to
> > > > > > > > > > > + * push all supported algorithms into one process()
> > function,
> > > > > > > > > > > + * or spread it across several ones.
> > > > > > > > > > > + * I.E. More flexibility for PMD writer.
> > > > > > > > > >
> > > > > > > > > > Which process function should be chosen is internal to
> > > > > > > > > > PMD, how
> > > > > would
> > > > > > > that
> > > > > > > > > info
> > > > > > > > > > be visible to the application or the library. These will
> > > > > > > > > > get stored in
> > > the
> > > > > > > session
> > > > > > > > > private
> > > > > > > > > > data. It would be upto the PMD writer, to store the per
> > > > > > > > > > session
> > > process
> > > > > > > > > function in
> > > > > > > > > > the session private data.
> > > > > > > > > >
> > > > > > > > > > Process function would be a dev ops just like enc/deq
> > > > > > > > > > operations
> > > and it
> > > > > > > should
> > > > > > > > > call
> > > > > > > > > > The respective process API stored in the session private data.
> > > > > > > > >
> > > > > > > > > That model (via devops) is possible, but has several
> > > > > > > > > drawbacks from
> > > my
> > > > > > > > > perspective:
> > > > > > > > >
> > > > > > > > > 1. It means we'll need to pass dev_id as a parameter to
> > > > > > > > > process()
> > > function.
> > > > > > > > > Though in fact dev_id is not a relevant information for us
> > > > > > > > > here (all we need is pointer to the session and pointer to
> > > > > > > > > the fuction to call) and I tried to avoid using it in data-path
> > functions for that API.
> > > > > > > >
> > > > > > > > You have a single vdev, but someone may have multiple vdevs
> > > > > > > > for each
> > > > > thread,
> > > > > > > or may
> > > > > > > > Have same dev with multiple queues for each core.
> > > > > > >
> > > > > > > That's fine. As I said above it is a SW backed implementation.
> > > > > > > Each session has to be a separate entity that contains all
> > > > > > > necessary
> > > > > information
> > > > > > > (keys, alg/mode info, etc.) to process input buffers.
> > > > > > > Plus we need the actual function pointer to call.
> > > > > > > I just don't see what for we need a dev_id in that situation.
> > > > > >
> > > > > > To iterate the session private data in the session.
> > > > > >
> > > > > > > Again, here we don't need care about queues and their pinning to
> > cores.
> > > > > > > If let say someone would like to process buffers from the same
> > > > > > > IPsec SA
> > > on 2
> > > > > > > different cores in parallel, he can just create 2 sessions for
> > > > > > > the same
> > > xform,
> > > > > > > give one to thread #1 and second to thread #2.
> > > > > > > After that both threads are free to call process(this_thread_ses, ...)
> > at will.
> > > > > >
> > > > > > Say you have a 16core device to handle 100G of traffic on a single
> > tunnel.
> > > > > > Will we make 16 sessions with same parameters?
> > > > >
> > > > > Absolutely same question we can ask for current crypto-op API.
> > > > > You have lookaside crypto-dev with 16 HW queues, each queue is
> > > > > serviced by different CPU.
> > > > > For the same SA, do you need a separate session per queue, or is
> > > > > it ok to
> > > reuse
> > > > > current one?
> > > > > AFAIK, right now this is a grey area not clearly defined.
> > > > > For crypto-devs I am aware - user can reuse the same session (as
> > > > > PMD uses it read-only).
> > > > > But again, right now I think it is not clearly defined and is
> > > > > implementation specific.
> > > >
> > > > User can use the same session, that is what I am also insisting, but
> > > > it may have
> > > separate
> > > > Session private data. Cryptodev session create API provide that
> > > > functionality
> > > and we can
> > > > Leverage that.
> > >
> > > rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which
> > > means we can't use the same rte_cryptodev_sym_session to hold sessions
> > > for both sync and async mode for the same device. Off course we can
> > > add a hard requirement that any driver that wants to support process()
> > > has to create sessions that can handle both process and
> > > enqueue/dequeue, but then again what for to create such overhead?
> > >
> > > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > > construct for multiple device_ids:
> > > __extension__ struct {
> > > void *data;
> > > uint16_t refcnt;
> > > } sess_data[0];
> > > /**< Driver specific session material, variable size */
> > >
> > Yes I also feel the same. I was also not in favor of this when it was introduced.
> > Please go ahead and remove this. I have no issues with that.
> >
> > > as an advantage.
> > > It looks too error prone for me:
> > > 1. Simultaneous session initialization/de-initialization for devices
> > > with the same driver_id is not possible.
> > > 2. It assumes that all device driver will be loaded before we start to
> > > create session pools.
> > >
> > > Right now it seems ok, as no-one requires such functionality, but I
> > > don't know how it will be in future.
> > > For me rte_security session model, where for each security context
> > > user have to create new session looks much more robust.
> > Agreed
> >
> > >
> > > >
> > > > BTW, I can see a v2 to this RFC which is still based on security library.
> > >
> > > Yes, v2 was concentrated on fixing found issues, some code
> > > restructuring, i.e. - changes that would be needed anyway whatever API
> > aproach we'll choose.
> > >
> > > > When do you plan
> > > > To submit the patches for crypto based APIs. We have RC1 merge
> > > > deadline for
> > > this
> > > > patchset on 21st Oct.
> > >
> > > We'd like to start working on it ASAP, but it seems we still have a
> > > major disagreement about how this crypto-dev API should look like.
> > > Which makes me think - should we return to our original proposal via
> > > rte_security?
> > > It still looks to me like clean and straightforward way to enable this
> > > new API, and probably wouldn't cause that much controversy.
> > > What do you think?
> >
> > I cannot spend more time discussing on this until RC1 date. I have some other
> > stuff pending.
> > You can send the patches early next week with the approach that I
> > mentioned or else we can discuss this post RC1(which would mean deferring
> > to 20.02).
> >
> > But moving back to security is not acceptable to me. The code should be put
> > where it is intended and not where it is easy to put. You are not doing any
> > rte_security stuff.
> >
> >
> > Regards,
> > Akhil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-11 13:23 0% ` Akhil Goyal
@ 2019-10-13 23:07 0% ` Zhang, Roy Fan
2019-10-14 11:10 0% ` Ananyev, Konstantin
2019-10-16 22:07 3% ` Ananyev, Konstantin
1 sibling, 1 reply; 200+ results
From: Zhang, Roy Fan @ 2019-10-13 23:07 UTC (permalink / raw)
To: Akhil Goyal, Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Doherty, Declan
Cc: 'Anoob Joseph'
Hi Akhil,
Thanks for the review and comments!
Knowing you are extremely busy. Here is my point in brief:
I think placing the CPU synchronous crypto in the rte_security make sense, as
1. rte_security contains inline crypto and lookaside crypto action type already, adding cpu_crypto action type is reasonable.
2. rte_security contains the security features may not supported by all devices, such as crypto, ipsec, and PDCP. cpu_crypto follow this category, again crypto.
3. placing CPU synchronous crypto API in rte_security is natural - as inline mode works synchronously, too. However cryptodev doesn't.
4. placing CPU synchronous crypto API in rte_security helps boosting SW crypto performance, I have already provided a simple perf test inside the unit test in the patchset for the user to try out - just comparing its output against DPDK crypto perf app output.
5. placing CPU synchronous crypto API in cryptodev will never serve HW lookaside crypto PMDs, as making them to work synchronously have huge performance penalty. However Cryptodev framework's existing design is providing APIs that will work in all crypto PMDs (rte_cryptodev_enqueue_burst / dequeue_burst for example), this does not fit in cryptodev's principle.
6. placing CPU synchronous crypto API in cryptodev confuses the user, as:
- the session created for async mode may not work in sync mode
- both enqueue/dequeue and cpu_crypto_process does the same crypto processing, but one PMD may support only one API (set), the other may support another, and the third PMD supports both. We have to provide another API to let the user query which one to support which.
- two completely different code paths for async/sync mode.
7. You said in the end of the email - placing CPU synchronous crypto API into rte_security is not acceptable as it does not do any rte_security stuff - crypto isn't? You may call this a quibble, but in my idea, in the patchset both PMDs' implementations did offload the work to the CPU's special circuit designed dedicated to accelerate the crypto processing.
To me cryptodev is the one CPU synchronous crypto API should not go into, rte_security is.
Regards,
Fan
> -----Original Message-----
> From: Akhil Goyal [mailto:akhil.goyal@nxp.com]
> Sent: Friday, October 11, 2019 2:24 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; 'dev@dpdk.org'
> <dev@dpdk.org>; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>;
> 'Thomas Monjalon' <thomas@monjalon.net>; Zhang, Roy Fan
> <roy.fan.zhang@intel.com>; Doherty, Declan <declan.doherty@intel.com>
> Cc: 'Anoob Joseph' <anoobj@marvell.com>
> Subject: RE: [RFC PATCH 1/9] security: introduce CPU Crypto action type and
> API
>
> Hi Konstantin,
>
> >
> > Hi Akhil,
> >
> ..[snip]
>
> > > > > > > OK let us assume that you have a separate structure. But I
> > > > > > > have a few
> > > > queries:
> > > > > > > 1. how can multiple drivers use a same session
> > > > > >
> > > > > > As a short answer: they can't.
> > > > > > It is pretty much the same approach as with rte_security -
> > > > > > each device
> > needs
> > > > to
> > > > > > create/init its own session.
> > > > > > So upper layer would need to maintain its own array (or so) for such
> case.
> > > > > > Though the question is why would you like to have same session
> > > > > > over
> > > > multiple
> > > > > > SW backed devices?
> > > > > > As it would be anyway just a synchronous function call that
> > > > > > will be
> > executed
> > > > on
> > > > > > the same cpu.
> > > > >
> > > > > I may have single FAT tunnel which may be distributed over
> > > > > multiple Cores, and each core is affined to a different SW device.
> > > >
> > > > If it is pure SW, then we don't need multiple devices for such scenario.
> > > > Device in that case is pure abstraction that we can skip.
> > >
> > > Yes agreed, but that liberty is given to the application whether it
> > > need multiple devices with single queue or a single device with multiple
> queues.
> > > I think that independence should not be broken in this new API.
> > > >
> > > > > So a single session may be accessed by multiple devices.
> > > > >
> > > > > One more example would be depending on packet sizes, I may
> > > > > switch
> > between
> > > > > HW/SW PMDs with the same session.
> > > >
> > > > Sure, but then we'll have multiple sessions.
> > >
> > > No, the session will be same and it will have multiple private data
> > > for each of
> > the PMD.
> > >
> > > > BTW, we have same thing now - these private session pointers are
> > > > just
> > stored
> > > > inside the same rte_crypto_sym_session.
> > > > And if user wants to support this model, he would also need to
> > > > store <dev_id, queue_id> pair for each HW device anyway.
> > >
> > > Yes agreed, but how is that thing happening in your new struct, you
> > > cannot
> > support that.
> >
> > User can store all these info in his own struct.
> > That's exactly what we have right now.
> > Let say ipsec-secgw has to store for each IPsec SA:
> > pointer to crypto-session and/or pointer to security session plus (for
> > lookaside-devices) cdev_id_qp that allows it to extract dev_id +
> > queue_id information.
> > As I understand that works for now, as each ipsec_sa uses only one
> > dev+queue. Though if someone would like to use multiple devices/queues
> > for the same SA - he would need to have an array of these <dev+queue>
> pairs.
> > So even right now rte_cryptodev_sym_session is not self-consistent and
> > requires extra information to be maintained by user.
>
> Why are you increasing the complexity for the user application.
> The new APIs and struct should be such that it need to do minimum changes
> in the stack so that stack is portable on multiple vendors.
> You should try to hide as much complexity in the driver or lib to give the user
> simple APIs.
>
> Having a same session for multiple devices was added by Intel only for some
> use cases.
> And we had split that session create API into 2. Now if those are not useful
> shall we move back to the single API. I think @Doherty, Declan and @De Lara
> Guarch, Pablo can comment on this.
>
> >
> > >
> > > >
> > > > >
> > > > > >
> > > > > > > 2. Can somebody use the scheduler pmd for scheduling the
> > > > > > > different
> > type
> > > > of
> > > > > > payloads for the same session?
> > > > > >
> > > > > > In theory yes.
> > > > > > Though for that scheduler pmd should have inside it's
> > > > > > rte_crypto_cpu_sym_session an array of pointers to the
> > > > > > underlying devices sessions.
> > > > > >
> > > > > > >
> > > > > > > With your proposal the APIs would be very specific to your
> > > > > > > use case
> > only.
> > > > > >
> > > > > > Yes in some way.
> > > > > > I consider that API specific for SW backed crypto PMDs.
> > > > > > I can hardly see how any 'real HW' PMDs (lksd-none,
> > > > > > lksd-proto) will
> > benefit
> > > > > > from it.
> > > > > > Current crypto-op API is very much HW oriented.
> > > > > > Which is ok, that's for it was intended for, but I think we
> > > > > > also need one
> > that
> > > > > > would be designed
> > > > > > for SW backed implementation in mind.
> > > > >
> > > > > We may re-use your API for HW PMDs as well which do not have
> > requirement
> > > > of
> > > > > Crypto-op/mbuf etc.
> > > > > The return type of your new process API may have a status which
> > > > > say
> > > > 'processed'
> > > > > Or can be say 'enqueued'. So if it is 'enqueued', we may have a
> > > > > new API for
> > > > raw
> > > > > Bufs dequeue as well.
> > > > >
> > > > > This requirement can be for any hardware PMDs like QAT as well.
> > > >
> > > > I don't think it is a good idea to extend this API for async (lookaside)
> devices.
> > > > You'll need to:
> > > > - provide dev_id and queue_id for each process(enqueue) and
> > > > dequeuer operation.
> > > > - provide IOVA for all buffers passing to that function (data
> > > > buffers, digest,
> > IV,
> > > > aad).
> > > > - On dequeue provide some way to associate dequed data and digest
> > > > buffers with
> > > > crypto-session that was used (and probably with mbuf).
> > > > So most likely we'll end up with another just version of our
> > > > current crypto-op structure.
> > > > If you'd like to get rid of mbufs dependency within current
> > > > crypto-op API that understandable, but I don't think we should
> > > > have same API for both sync (CPU) and async
> > > > (lookaside) cases.
> > > > It doesn't seem feasible at all and voids whole purpose of that patch.
> > >
> > > At this moment we are not much concerned about the dequeue API and
> > > about
> > the
> > > HW PMD support. It is just that the new API should be generic enough
> > > to be
> > used in
> > > some future scenarios as well. I am just highlighting the possible
> > > usecases
> > which can
> > > be there in future.
> >
> > Sorry, but I strongly disagree with such approach.
> > We should stop adding/modifying API 'just in case' and because 'it
> > might be useful for some future HW'.
> > Inside DPDK we already do have too many dev level APIs without any
> > implementations.
> > That's quite bad practice and very dis-orienting for end-users.
> > I think to justify API additions/changes we need at least one proper
> > implementation for it, or at least some strong evidence that people
> > are really committed to support it in nearest future.
> > BTW, that what TB agreed on, nearly a year ago.
> >
> > This new API (if we'll go ahead with it of course) would stay
> > experimental for some time anyway to make sure we don't miss anything
> > needed (I think for about a year time- frame).
> > So if you guys *really* want to extend it support _async_ devices too
> > - I am open for modifications/additions here.
> > Though personally I think such addition would over-complicate things
> > and we'll end up with another reincarnation of current crypto-op.
> > We actually discussed it internally, and decided to drop that idea because
> of that.
> > Again, my opinion - for lookaside devices it might be better to try to
> > optimize current crypto-op path (remove mbuf requirement, probably add
> > ability to group by session on enqueue/dequeue, etc.).
>
> I agree that the new API is experimental and can be modified later. So no
> issues in that, but we can keep some things in mind while defining APIs.
> These were some comments from my side, if those are impacting the current
> scenario, you can drop those. We will take care of those later.
>
> >
> > >
> > > What is the issue that you face in making a dev-op for this new API.
> > > Do you see
> > any
> > > performance impact with that?
> >
> > There are two main things:
> > 1. user would need to maintain and provide for each process() call
> > dev_id+queue_id.
> > That's means extra (and totally unnecessary for SW) overhead.
>
> You are using a crypto device for performing the processing, you must use
> dev_id to identify which SW device it is. This is how the DPDK Framework
> works.
> .
>
> > 2. yes I would expect some perf overhead too - it would be extra call or
> branch.
> > Again as it would be data-dependency - most likely cpu wouldn't be
> > able to pipeline it efficiently:
> >
> > rte_crypto_sym_process(uint8_t dev_id, uint16 qp_id,
> > rte_crypto_sym_session *ses, ...) {
> > struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
> > return (*dev->process)(sess->data[dev->driver_id, ...); }
> >
> > driver_specific_process(driver_specific_sym_session *sess) {
> > return sess->process(sess, ...) ;
> > }
> >
> > I didn't make any exact measurements but sure it would be slower than
> just:
> > session_udata->process(session->udata->sess, ...); Again it would be
> > much more noticeable on low end cpus.
> > Let say here:
> > http://mails.dpdk.org/archives/dev/2019-September/144350.html
> > Jerin claims 1.5-3% drop for introducing extra call via hiding eth_dev
> > contents - I suppose we would have something similar here.
> > I do realize that in majority of cases crypto is more expensive then
> > RX/TX, but still.
> >
> > If it would be a really unavoidable tradeoff (support already existing
> > API, or so) I wouldn't mind, but I don't see any real need for it right now.
>
> Calling session_udata->process(session->udata->sess, ...); from the
> application and Application need to maintain for each PMD the process() API
> in its memory will make the application not portable to other vendors.
>
> What we are doing here is defining another way to create sessions for the
> same stuff that is already done. This make applications non-portable and
> confusing for the application writer.
>
> I would say you should do some profiling first. As you also mentioned crypto
> workload is more Cycle consuming, it will not impact this case.
>
>
> >
> > >
> > > >
> > > > > That is why a dev-ops would be a better option.
> > > > >
> > > > > >
> > > > > > > When you would add more functionality to this sync
> > > > > > > API/struct, it will
> > end
> > > > up
> > > > > > being the same API/struct.
> > > > > > >
> > > > > > > Let us see how close/ far we are from the existing APIs
> > > > > > > when the
> > actual
> > > > > > implementation is done.
> > > > > > >
> > > > > > > > > I am not sure if that would be needed.
> > > > > > > > > It would be internal to the driver that if synchronous
> > > > > > > > > processing is
> > > > > > > > supported(from feature flag) and
> > > > > > > > > Have relevant fields in xform(the newly added ones which
> > > > > > > > > are
> > packed
> > > > as
> > > > > > per
> > > > > > > > your suggestions) set,
> > > > > > > > > It will create that type of session.
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > > + * Main points:
> > > > > > > > > > + * - Current crypto-dev API is reasonably mature and
> > > > > > > > > > + it is
> > desirable
> > > > > > > > > > + * to keep it unchanged (API/ABI stability). From other
> side, this
> > > > > > > > > > + * new sync API is new one and probably would require
> extra
> > > > changes.
> > > > > > > > > > + * Having it as a new one allows to mark it as experimental,
> > without
> > > > > > > > > > + * affecting existing one.
> > > > > > > > > > + * - Fully opaque cpu_sym_session structure gives more
> flexibility
> > > > > > > > > > + * to the PMD writers and again allows to avoid ABI
> breakages
> > in
> > > > future.
> > > > > > > > > > + * - process() function per set of xforms
> > > > > > > > > > + * allows to expose different process() functions for
> different
> > > > > > > > > > + * xform combinations. PMD writer can decide, does he
> wants
> > to
> > > > > > > > > > + * push all supported algorithms into one process()
> function,
> > > > > > > > > > + * or spread it across several ones.
> > > > > > > > > > + * I.E. More flexibility for PMD writer.
> > > > > > > > >
> > > > > > > > > Which process function should be chosen is internal to
> > > > > > > > > PMD, how
> > > > would
> > > > > > that
> > > > > > > > info
> > > > > > > > > be visible to the application or the library. These will
> > > > > > > > > get stored in
> > the
> > > > > > session
> > > > > > > > private
> > > > > > > > > data. It would be upto the PMD writer, to store the per
> > > > > > > > > session
> > process
> > > > > > > > function in
> > > > > > > > > the session private data.
> > > > > > > > >
> > > > > > > > > Process function would be a dev ops just like enc/deq
> > > > > > > > > operations
> > and it
> > > > > > should
> > > > > > > > call
> > > > > > > > > The respective process API stored in the session private data.
> > > > > > > >
> > > > > > > > That model (via devops) is possible, but has several
> > > > > > > > drawbacks from
> > my
> > > > > > > > perspective:
> > > > > > > >
> > > > > > > > 1. It means we'll need to pass dev_id as a parameter to
> > > > > > > > process()
> > function.
> > > > > > > > Though in fact dev_id is not a relevant information for us
> > > > > > > > here (all we need is pointer to the session and pointer to
> > > > > > > > the fuction to call) and I tried to avoid using it in data-path
> functions for that API.
> > > > > > >
> > > > > > > You have a single vdev, but someone may have multiple vdevs
> > > > > > > for each
> > > > thread,
> > > > > > or may
> > > > > > > Have same dev with multiple queues for each core.
> > > > > >
> > > > > > That's fine. As I said above it is a SW backed implementation.
> > > > > > Each session has to be a separate entity that contains all
> > > > > > necessary
> > > > information
> > > > > > (keys, alg/mode info, etc.) to process input buffers.
> > > > > > Plus we need the actual function pointer to call.
> > > > > > I just don't see what for we need a dev_id in that situation.
> > > > >
> > > > > To iterate the session private data in the session.
> > > > >
> > > > > > Again, here we don't need care about queues and their pinning to
> cores.
> > > > > > If let say someone would like to process buffers from the same
> > > > > > IPsec SA
> > on 2
> > > > > > different cores in parallel, he can just create 2 sessions for
> > > > > > the same
> > xform,
> > > > > > give one to thread #1 and second to thread #2.
> > > > > > After that both threads are free to call process(this_thread_ses, ...)
> at will.
> > > > >
> > > > > Say you have a 16core device to handle 100G of traffic on a single
> tunnel.
> > > > > Will we make 16 sessions with same parameters?
> > > >
> > > > Absolutely same question we can ask for current crypto-op API.
> > > > You have lookaside crypto-dev with 16 HW queues, each queue is
> > > > serviced by different CPU.
> > > > For the same SA, do you need a separate session per queue, or is
> > > > it ok to
> > reuse
> > > > current one?
> > > > AFAIK, right now this is a grey area not clearly defined.
> > > > For crypto-devs I am aware - user can reuse the same session (as
> > > > PMD uses it read-only).
> > > > But again, right now I think it is not clearly defined and is
> > > > implementation specific.
> > >
> > > User can use the same session, that is what I am also insisting, but
> > > it may have
> > separate
> > > Session private data. Cryptodev session create API provide that
> > > functionality
> > and we can
> > > Leverage that.
> >
> > rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which
> > means we can't use the same rte_cryptodev_sym_session to hold sessions
> > for both sync and async mode for the same device. Off course we can
> > add a hard requirement that any driver that wants to support process()
> > has to create sessions that can handle both process and
> > enqueue/dequeue, but then again what for to create such overhead?
> >
> > BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> > construct for multiple device_ids:
> > __extension__ struct {
> > void *data;
> > uint16_t refcnt;
> > } sess_data[0];
> > /**< Driver specific session material, variable size */
> >
> Yes I also feel the same. I was also not in favor of this when it was introduced.
> Please go ahead and remove this. I have no issues with that.
>
> > as an advantage.
> > It looks too error prone for me:
> > 1. Simultaneous session initialization/de-initialization for devices
> > with the same driver_id is not possible.
> > 2. It assumes that all device driver will be loaded before we start to
> > create session pools.
> >
> > Right now it seems ok, as no-one requires such functionality, but I
> > don't know how it will be in future.
> > For me rte_security session model, where for each security context
> > user have to create new session looks much more robust.
> Agreed
>
> >
> > >
> > > BTW, I can see a v2 to this RFC which is still based on security library.
> >
> > Yes, v2 was concentrated on fixing found issues, some code
> > restructuring, i.e. - changes that would be needed anyway whatever API
> aproach we'll choose.
> >
> > > When do you plan
> > > To submit the patches for crypto based APIs. We have RC1 merge
> > > deadline for
> > this
> > > patchset on 21st Oct.
> >
> > We'd like to start working on it ASAP, but it seems we still have a
> > major disagreement about how this crypto-dev API should look like.
> > Which makes me think - should we return to our original proposal via
> > rte_security?
> > It still looks to me like clean and straightforward way to enable this
> > new API, and probably wouldn't cause that much controversy.
> > What do you think?
>
> I cannot spend more time discussing on this until RC1 date. I have some other
> stuff pending.
> You can send the patches early next week with the approach that I
> mentioned or else we can discuss this post RC1(which would mean deferring
> to 20.02).
>
> But moving back to security is not acceptable to me. The code should be put
> where it is intended and not where it is easy to put. You are not doing any
> rte_security stuff.
>
>
> Regards,
> Akhil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/3] lib/lpm: integrate RCU QSBR
@ 2019-10-13 4:36 3% ` Honnappa Nagarahalli
2019-10-15 11:15 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2019-10-13 4:36 UTC (permalink / raw)
To: Ananyev, Konstantin, Richardson, Bruce, Medvedkin, Vladimir,
olivier.matz
Cc: dev, stephen, paulmck, Gavin Hu (Arm Technology China),
Dharmik Thakkar, Ruifeng Wang (Arm Technology China),
nd, Ruifeng Wang (Arm Technology China),
Honnappa Nagarahalli, nd
<snip>
> Hi guys,
I have tried to consolidate design related questions here. If I have missed anything, please add.
>
> >
> > From: Ruifeng Wang <ruifeng.wang@arm.com>
> >
> > Currently, the tbl8 group is freed even though the readers might be
> > using the tbl8 group entries. The freed tbl8 group can be reallocated
> > quickly. This results in incorrect lookup results.
> >
> > RCU QSBR process is integrated for safe tbl8 group reclaim.
> > Refer to RCU documentation to understand various aspects of
> > integrating RCU library into other libraries.
> >
> > Signed-off-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > ---
> > lib/librte_lpm/Makefile | 3 +-
> > lib/librte_lpm/meson.build | 2 +
> > lib/librte_lpm/rte_lpm.c | 102 +++++++++++++++++++++++++----
> > lib/librte_lpm/rte_lpm.h | 21 ++++++
> > lib/librte_lpm/rte_lpm_version.map | 6 ++
> > 5 files changed, 122 insertions(+), 12 deletions(-)
> >
> > diff --git a/lib/librte_lpm/Makefile b/lib/librte_lpm/Makefile index
> > a7946a1c5..ca9e16312 100644
> > --- a/lib/librte_lpm/Makefile
> > +++ b/lib/librte_lpm/Makefile
> > @@ -6,9 +6,10 @@ include $(RTE_SDK)/mk/rte.vars.mk # library name
> > LIB = librte_lpm.a
> >
> > +CFLAGS += -DALLOW_EXPERIMENTAL_API
> > CFLAGS += -O3
> > CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -LDLIBS += -lrte_eal -lrte_hash
> > +LDLIBS += -lrte_eal -lrte_hash -lrte_rcu
> >
> > EXPORT_MAP := rte_lpm_version.map
> >
> > diff --git a/lib/librte_lpm/meson.build b/lib/librte_lpm/meson.build
> > index a5176d8ae..19a35107f 100644
> > --- a/lib/librte_lpm/meson.build
> > +++ b/lib/librte_lpm/meson.build
> > @@ -2,9 +2,11 @@
> > # Copyright(c) 2017 Intel Corporation
> >
> > version = 2
> > +allow_experimental_apis = true
> > sources = files('rte_lpm.c', 'rte_lpm6.c') headers =
> > files('rte_lpm.h', 'rte_lpm6.h') # since header files have different
> > names, we can install all vector headers # without worrying about
> > which architecture we actually need headers +=
> > files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h') deps +=
> > ['hash']
> > +deps += ['rcu']
> > diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c index
> > 3a929a1b1..ca58d4b35 100644
> > --- a/lib/librte_lpm/rte_lpm.c
> > +++ b/lib/librte_lpm/rte_lpm.c
> > @@ -1,5 +1,6 @@
> > /* SPDX-License-Identifier: BSD-3-Clause
> > * Copyright(c) 2010-2014 Intel Corporation
> > + * Copyright(c) 2019 Arm Limited
> > */
> >
> > #include <string.h>
> > @@ -381,6 +382,8 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
> >
> > rte_mcfg_tailq_write_unlock();
> >
> > + if (lpm->dq)
> > + rte_rcu_qsbr_dq_delete(lpm->dq);
> > rte_free(lpm->tbl8);
> > rte_free(lpm->rules_tbl);
> > rte_free(lpm);
> > @@ -390,6 +393,59 @@ BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604,
> 16.04);
> > MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
> > rte_lpm_free_v1604);
> >
> > +struct __rte_lpm_rcu_dq_entry {
> > + uint32_t tbl8_group_index;
> > + uint32_t pad;
> > +};
> > +
> > +static void
> > +__lpm_rcu_qsbr_free_resource(void *p, void *data) {
> > + struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > + struct __rte_lpm_rcu_dq_entry *e =
> > + (struct __rte_lpm_rcu_dq_entry *)data;
> > + struct rte_lpm_tbl_entry *tbl8 = (struct rte_lpm_tbl_entry *)p;
> > +
> > + /* Set tbl8 group invalid */
> > + __atomic_store(&tbl8[e->tbl8_group_index], &zero_tbl8_entry,
> > + __ATOMIC_RELAXED);
> > +}
> > +
> > +/* Associate QSBR variable with an LPM object.
> > + */
> > +int
> > +rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr *v) {
> > + char rcu_dq_name[RTE_RCU_QSBR_DQ_NAMESIZE];
> > + struct rte_rcu_qsbr_dq_parameters params;
> > +
> > + if ((lpm == NULL) || (v == NULL)) {
> > + rte_errno = EINVAL;
> > + return 1;
> > + }
> > +
> > + if (lpm->dq) {
> > + rte_errno = EEXIST;
> > + return 1;
> > + }
> > +
> > + /* Init QSBR defer queue. */
> > + snprintf(rcu_dq_name, sizeof(rcu_dq_name), "LPM_RCU_%s", lpm-
> >name);
> > + params.name = rcu_dq_name;
> > + params.size = lpm->number_tbl8s;
> > + params.esize = sizeof(struct __rte_lpm_rcu_dq_entry);
> > + params.f = __lpm_rcu_qsbr_free_resource;
> > + params.p = lpm->tbl8;
> > + params.v = v;
> > + lpm->dq = rte_rcu_qsbr_dq_create(¶ms);
> > + if (lpm->dq == NULL) {
> > + RTE_LOG(ERR, LPM, "LPM QS defer queue creation failed\n");
> > + return 1;
> > + }
>
> Few thoughts about that function:
Few things to keep in mind, the goal of the design is to make it easy for the applications to adopt lock-free algorithms. The reclamation process in the writer is a major portion of code one has to write for using lock-free algorithms. The current design is such that the writer does not have to change any code or write additional code other than calling 'rte_lpm_rcu_qsbr_add'.
> It names rcu_qsbr_add() but in fact it allocates defer queue for give rcu var.
> So first thought - is it always necessary?
This is part of the design. If the application does not want to use this integrated logic then, it does not have to call this API. It can use the RCU defer APIs to implement its own logic. But, if I ask the question, does this integrated logic address most of the use cases of the LPM library, I think the answer is yes.
> For some use-cases I suppose user might be ok to wait for quiescent state
> change
> inside tbl8_free()?
Yes, that is a possibility (for ex: no frequent route changes). But, I think that is very trivial for the application to implement. Though, the LPM library has to separate the 'delete' and 'free' operations. Similar operations are provided in rte_hash library. IMO, we should follow consistent approach.
> Another thing you do allocate defer queue, but it is internal, so user can't call
> reclaim() manually, which looks strange.
> Why not to return defer_queue pointer to the user, so he can call reclaim()
> himself at appropriate time?
The intention of the design is to take the complexity away from the user of LPM library. IMO, the current design will address most uses cases of LPM library. If we expose the 2 parameters (when to trigger reclamation and how much to reclaim) in the 'rte_lpm_rcu_qsbr_add' API, it should provide enough flexibility to the application.
> Third thing - you always allocate defer queue with size equal to number of
> tbl8.
> Though I understand it could be up to 16M tbl8 groups inside the LPM.
> Do we really need defer queue that long?
No, we do not need it to be this long. It is this long today to avoid returning no-space on the defer queue error.
> Especially considering that current rcu_defer_queue will start reclamation
> when 1/8 of defer_quueue becomes full and wouldn't reclaim more then
> 1/16 of it.
> Probably better to let user to decide himself how long defer_queue he needs
> for that LPM?
It makes sense to expose it to the user if the writer-writer concurrency is lock-free (no memory allocation allowed to expand the defer queue size when the queue is full). However, LPM is not lock-free on the writer side. If we think the writer could be lock-free in the future, it has to be exposed to the user.
>
> Konstantin
Pulling questions/comments from other threads:
Can we leave reclamation to some other house-keeping thread to do (sort of garbage collector). Or such mode is not supported/planned?
[Honnappa] If the reclamation cost is small, the current method provides advantages over having a separate thread to do reclamation. I did not plan to provide such an option. But may be it makes sense to keep the options open (especially from ABI perspective). May be we should add a flags field which will allow us to implement different methods in the future?
>
>
> > +
> > + return 0;
> > +}
> > +
> > /*
> > * Adds a rule to the rule table.
> > *
> > @@ -679,14 +735,15 @@ tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20
> > *tbl8) }
> >
> > static int32_t
> > -tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > number_tbl8s)
> > +__tbl8_alloc_v1604(struct rte_lpm *lpm)
> > {
> > uint32_t group_idx; /* tbl8 group index. */
> > struct rte_lpm_tbl_entry *tbl8_entry;
> >
> > /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
> > - for (group_idx = 0; group_idx < number_tbl8s; group_idx++) {
> > - tbl8_entry = &tbl8[group_idx *
> RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > + for (group_idx = 0; group_idx < lpm->number_tbl8s; group_idx++) {
> > + tbl8_entry = &lpm->tbl8[group_idx *
> > +
> RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
> > /* If a free tbl8 group is found clean it and set as VALID. */
> > if (!tbl8_entry->valid_group) {
> > struct rte_lpm_tbl_entry new_tbl8_entry = { @@ -
> 712,6 +769,21 @@
> > tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
> > return -ENOSPC;
> > }
> >
> > +static int32_t
> > +tbl8_alloc_v1604(struct rte_lpm *lpm) {
> > + int32_t group_idx; /* tbl8 group index. */
> > +
> > + group_idx = __tbl8_alloc_v1604(lpm);
> > + if ((group_idx < 0) && (lpm->dq != NULL)) {
> > + /* If there are no tbl8 groups try to reclaim some. */
> > + if (rte_rcu_qsbr_dq_reclaim(lpm->dq) == 0)
> > + group_idx = __tbl8_alloc_v1604(lpm);
> > + }
> > +
> > + return group_idx;
> > +}
> > +
> > static void
> > tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t
> > tbl8_group_start) { @@ -728,13 +800,21 @@ tbl8_free_v20(struct
> > rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start) }
> >
> > static void
> > -tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t
> > tbl8_group_start)
> > +tbl8_free_v1604(struct rte_lpm *lpm, uint32_t tbl8_group_start)
> > {
> > - /* Set tbl8 group invalid*/
> > struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
> > + struct __rte_lpm_rcu_dq_entry e;
> >
> > - __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
> > - __ATOMIC_RELAXED);
> > + if (lpm->dq != NULL) {
> > + e.tbl8_group_index = tbl8_group_start;
> > + e.pad = 0;
> > + /* Push into QSBR defer queue. */
> > + rte_rcu_qsbr_dq_enqueue(lpm->dq, (void *)&e);
> > + } else {
> > + /* Set tbl8 group invalid*/
> > + __atomic_store(&lpm->tbl8[tbl8_group_start],
> &zero_tbl8_entry,
> > + __ATOMIC_RELAXED);
> > + }
> > }
> >
> > static __rte_noinline int32_t
> > @@ -1037,7 +1117,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> > uint32_t ip_masked, uint8_t depth,
> >
> > if (!lpm->tbl24[tbl24_index].valid) {
> > /* Search for a free tbl8 group. */
> > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> >number_tbl8s);
> > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> >
> > /* Check tbl8 allocation was successful. */
> > if (tbl8_group_index < 0) {
> > @@ -1083,7 +1163,7 @@ add_depth_big_v1604(struct rte_lpm *lpm,
> uint32_t ip_masked, uint8_t depth,
> > } /* If valid entry but not extended calculate the index into Table8. */
> > else if (lpm->tbl24[tbl24_index].valid_group == 0) {
> > /* Search for free tbl8 group. */
> > - tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm-
> >number_tbl8s);
> > + tbl8_group_index = tbl8_alloc_v1604(lpm);
> >
> > if (tbl8_group_index < 0) {
> > return tbl8_group_index;
> > @@ -1818,7 +1898,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm,
> uint32_t ip_masked,
> > */
> > lpm->tbl24[tbl24_index].valid = 0;
> > __atomic_thread_fence(__ATOMIC_RELEASE);
> > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > + tbl8_free_v1604(lpm, tbl8_group_start);
> > } else if (tbl8_recycle_index > -1) {
> > /* Update tbl24 entry. */
> > struct rte_lpm_tbl_entry new_tbl24_entry = { @@ -1834,7
> +1914,7 @@
> > delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
> > __atomic_store(&lpm->tbl24[tbl24_index],
> &new_tbl24_entry,
> > __ATOMIC_RELAXED);
> > __atomic_thread_fence(__ATOMIC_RELEASE);
> > - tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
> > + tbl8_free_v1604(lpm, tbl8_group_start);
> > }
> > #undef group_idx
> > return 0;
> > diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h index
> > 906ec4483..49c12a68d 100644
> > --- a/lib/librte_lpm/rte_lpm.h
> > +++ b/lib/librte_lpm/rte_lpm.h
> > @@ -1,5 +1,6 @@
> > /* SPDX-License-Identifier: BSD-3-Clause
> > * Copyright(c) 2010-2014 Intel Corporation
> > + * Copyright(c) 2019 Arm Limited
> > */
> >
> > #ifndef _RTE_LPM_H_
> > @@ -21,6 +22,7 @@
> > #include <rte_common.h>
> > #include <rte_vect.h>
> > #include <rte_compat.h>
> > +#include <rte_rcu_qsbr.h>
> >
> > #ifdef __cplusplus
> > extern "C" {
> > @@ -186,6 +188,7 @@ struct rte_lpm {
> > __rte_cache_aligned; /**< LPM tbl24 table. */
> > struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
> > struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
> > + struct rte_rcu_qsbr_dq *dq; /**< RCU QSBR defer queue.*/
> > };
> >
> > /**
> > @@ -248,6 +251,24 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
> void
> > rte_lpm_free_v1604(struct rte_lpm *lpm);
> >
> > +/**
> > + * Associate RCU QSBR variable with an LPM object.
> > + *
> > + * @param lpm
> > + * the lpm object to add RCU QSBR
> > + * @param v
> > + * RCU QSBR variable
> > + * @return
> > + * On success - 0
> > + * On error - 1 with error code set in rte_errno.
> > + * Possible rte_errno codes are:
> > + * - EINVAL - invalid pointer
> > + * - EEXIST - already added QSBR
> > + * - ENOMEM - memory allocation failure
> > + */
> > +__rte_experimental
> > +int rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_rcu_qsbr
> > +*v);
> > +
> > /**
> > * Add a rule to the LPM table.
> > *
> > diff --git a/lib/librte_lpm/rte_lpm_version.map
> > b/lib/librte_lpm/rte_lpm_version.map
> > index 90beac853..b353aabd2 100644
> > --- a/lib/librte_lpm/rte_lpm_version.map
> > +++ b/lib/librte_lpm/rte_lpm_version.map
> > @@ -44,3 +44,9 @@ DPDK_17.05 {
> > rte_lpm6_lookup_bulk_func;
> >
> > } DPDK_16.04;
> > +
> > +EXPERIMENTAL {
> > + global:
> > +
> > + rte_lpm_rcu_qsbr_add;
> > +};
> > --
> > 2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource reclamation APIs
2019-10-07 10:46 0% ` Ananyev, Konstantin
@ 2019-10-13 4:35 0% ` Honnappa Nagarahalli
0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2019-10-13 4:35 UTC (permalink / raw)
To: Ananyev, Konstantin, stephen, paulmck
Cc: Wang, Yipeng1, Medvedkin, Vladimir,
Ruifeng Wang (Arm Technology China),
Dharmik Thakkar, dev, Honnappa Nagarahalli, nd, nd
<snip>
> > > > > > Add resource reclamation APIs to make it simple for
> > > > > > applications and libraries to integrate rte_rcu library.
> > > > > >
> > > > > > Signed-off-by: Honnappa Nagarahalli
> > > > > > <honnappa.nagarahalli@arm.com>
> > > > > > Reviewed-by: Ola Liljedhal <ola.liljedhal@arm.com>
> > > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > > ---
> > > > > > app/test/test_rcu_qsbr.c | 291
> ++++++++++++++++++++++++++++-
> > > > > > lib/librte_rcu/meson.build | 2 +
> > > > > > lib/librte_rcu/rte_rcu_qsbr.c | 185 ++++++++++++++++++
> > > > > > lib/librte_rcu/rte_rcu_qsbr.h | 169 +++++++++++++++++
> > > > > > lib/librte_rcu/rte_rcu_qsbr_pvt.h | 46 +++++
> > > > > > lib/librte_rcu/rte_rcu_version.map | 4 +
> > > > > > lib/meson.build | 6 +-
> > > > > > 7 files changed, 700 insertions(+), 3 deletions(-) create
> > > > > > mode
> > > > > > 100644 lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > > >
> > > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > > b/lib/librte_rcu/rte_rcu_qsbr.c index ce7f93dd3..76814f50b
> > > > > > 100644
> > > > > > --- a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > > @@ -21,6 +21,7 @@
> > > > > > #include <rte_errno.h>
> > > > > >
> > > > > > #include "rte_rcu_qsbr.h"
> > > > > > +#include "rte_rcu_qsbr_pvt.h"
> > > > > >
> > > > > > /* Get the memory size of QSBR variable */ size_t @@ -267,6
> > > > > > +268,190 @@ rte_rcu_qsbr_dump(FILE *f, struct rte_rcu_qsbr *v)
> > > > > > return 0;
> > > > > > }
> > > > > >
> > > > > > +/* Create a queue used to store the data structure elements
> > > > > > +that can
> > > > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > > > + */
> > > > > > +struct rte_rcu_qsbr_dq *
> > > > > > +rte_rcu_qsbr_dq_create(const struct
> > > > > > +rte_rcu_qsbr_dq_parameters
> > > > > > +*params) {
> > > > > > + struct rte_rcu_qsbr_dq *dq;
> > > > > > + uint32_t qs_fifo_size;
> > > > > > +
> > > > > > + if (params == NULL || params->f == NULL ||
> > > > > > + params->v == NULL || params->name == NULL ||
> > > > > > + params->size == 0 || params->esize == 0 ||
> > > > > > + (params->esize % 8 != 0)) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > > + rte_errno = EINVAL;
> > > > > > +
> > > > > > + return NULL;
> > > > > > + }
> > > > > > +
> > > > > > + dq = rte_zmalloc(NULL,
> > > > > > + (sizeof(struct rte_rcu_qsbr_dq) + params->esize),
> > > > > > + RTE_CACHE_LINE_SIZE);
> > > > > > + if (dq == NULL) {
> > > > > > + rte_errno = ENOMEM;
> > > > > > +
> > > > > > + return NULL;
> > > > > > + }
> > > > > > +
> > > > > > + /* round up qs_fifo_size to next power of two that is not less
> than
> > > > > > + * max_size.
> > > > > > + */
> > > > > > + qs_fifo_size = rte_align32pow2((((params->esize/8) + 1)
> > > > > > + * params->size) + 1);
> > > > > > + dq->r = rte_ring_create(params->name, qs_fifo_size,
> > > > > > + SOCKET_ID_ANY, 0);
> > > > >
> > > > > If it is going to be not MT safe, then why not to create the
> > > > > ring with (RING_F_SP_ENQ | RING_F_SC_DEQ) flags set?
> > > > Agree.
> > > >
> > > > > Though I think it could be changed to allow MT safe multiple
> > > > > enqeue/single dequeue, see below.
> > > > The MT safe issue is due to reclaim code. The reclaim code has the
> > > > following
> > > sequence:
> > > >
> > > > rte_ring_peek
> > > > rte_rcu_qsbr_check
> > > > rte_ring_dequeue
> > > >
> > > > This entire sequence needs to be atomic as the entry cannot be
> > > > dequeued
> > > without knowing that the grace period for that entry is over.
> > >
> > > I understand that, though I believe at least it should be possible
> > > to support multiple-enqueue/single dequeuer and reclaim mode.
> > > With serialized dequeue() even multiple dequeue should be possible.
> > Agreed. Please see the response on the other thread.
> >
> > >
> > > > Note that due to optimizations in rte_rcu_qsbr_check API, this
> > > > sequence should not be large in most cases. I do not have ideas on
> > > > how to
> > > make this sequence lock-free.
> > > >
> > > > If the writer is on the control plane, most use cases will use
> > > > mutex locks for synchronization if they are multi-threaded. That
> > > > lock should be
> > > enough to provide the thread safety for these APIs.
> > >
> > > In that is case, why do we need ring at all?
> > > For sure people can create their own queue quite easily with mutex and
> TAILQ.
> > > If performance is not an issue, they can even add pthread_cond to
> > > it, and have an ability for the consumer to sleep/wakeup on empty/full
> queue.
> > >
> > > >
> > > > If the writer is multi-threaded and lock-free, then one should use
> > > > per thread
> > > defer queue.
> > >
> > > If that's the only working model, then the question is why do we
> > > need that API at all?
> > > Just simple array with counter or linked-list should do for majority of
> cases.
> > Please see the other thread.
> >
> > >
> > > >
> > > > >
> > > > > > + if (dq->r == NULL) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): defer queue create failed\n",
> __func__);
> > > > > > + rte_free(dq);
> > > > > > + return NULL;
> > > > > > + }
> > > > > > +
> > > > > > + dq->v = params->v;
> > > > > > + dq->size = params->size;
> > > > > > + dq->esize = params->esize;
> > > > > > + dq->f = params->f;
> > > > > > + dq->p = params->p;
> > > > > > +
> > > > > > + return dq;
> > > > > > +}
> > > > > > +
> > > > > > +/* Enqueue one resource to the defer queue to free after the
> > > > > > +grace
> > > > > > + * period is over.
> > > > > > + */
> > > > > > +int rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e)
> {
> > > > > > + uint64_t token;
> > > > > > + uint64_t *tmp;
> > > > > > + uint32_t i;
> > > > > > + uint32_t cur_size, free_size;
> > > > > > +
> > > > > > + if (dq == NULL || e == NULL) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > > + rte_errno = EINVAL;
> > > > > > +
> > > > > > + return 1;
> > > > >
> > > > > Why just not to return -EINVAL straightway?
> > > > > I think there is no much point to set rte_errno in that function
> > > > > at all, just return value should do.
> > > > I am trying to keep these consistent with the existing APIs. They
> > > > return 0 or 1
> > > and set the rte_errno.
> > >
> > > A lot of public DPDK API functions do use return value to return
> > > status code (0, or some positive numbers of success, negative errno
> > > values on failure), I am not inventing anything new here.
> > Agree, you are not proposing a new thing here. May be I was not clear.
> > I really do not have an opinion on how this should be done. But, I do have
> an opinion on consistency. These new APIs follow what has been done in the
> existing RCU APIs. I think we have 2 options here.
> > 1) Either we change existing RCU APIs to get rid of rte_errno (is it
> > an ABI change?) or
> > 2) The new APIs follow what has been done in the existing RCU APIs.
> > I want to make sure we are consistent at least within RCU APIs.
>
> But as I can see right now rcu API sets rte_errno only for control-path
> functions (get_memsize, init, register, unregister, dump).
> All fast-path (inline) function don't set/use it.
> So from perspective that is consistent behavior, no?
Agree. I am treating this as a control plane function mainly (hence it is a non-inline function as well).
>
> >
> > >
> > > >
> > > > >
> > > > > > + }
> > > > > > +
> > > > > > + /* Start the grace period */
> > > > > > + token = rte_rcu_qsbr_start(dq->v);
> > > > > > +
> > > > > > + /* Reclaim resources if the queue is 1/8th full. This helps
> > > > > > + * the queue from growing too large and allows time for
> reader
> > > > > > + * threads to report their quiescent state.
> > > > > > + */
> > > > > > + cur_size = rte_ring_count(dq->r) / (dq->esize/8 + 1);
> > > > >
> > > > > Probably would be a bit easier if you just store in dq->esize
> > > > > (elt size + token
> > > > > size) / 8.
> > > > Agree
> > > >
> > > > >
> > > > > > + if (cur_size > (dq->size >>
> > > > > > +RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT)) {
> > > > >
> > > > > Why to make this threshold value hard-coded?
> > > > > Why either not to put it into create parameter, or just return a
> > > > > special return value, to indicate that threshold is reached?
> > > > My thinking was to keep the programming interface easy to use. The
> > > > more the parameters, the more painful it is for the user. IMO, the
> > > > constants chosen should be good enough for most cases. More
> > > > advanced
> > > users could modify the constants. However, we could make these as
> > > part of the parameters, but make them optional for the user. For ex:
> > > if they set them to 0, default values can be used.
> > > >
> > > > > Or even return number of filled/free entroes on success, so
> > > > > caller can decide to reclaim or not based on that information on his
> own?
> > > > This means more code on the user side.
> > >
> > > I personally think it it really wouldn't be that big problem to the
> > > user to pass extra parameter to the function.
> > I will convert the 2 constants into optional parameters (user can set
> > them to 0 to make the algorithm use default values)
> >
> > > Again what if user doesn't want to reclaim() in enqueue() thread at all?
> > 'enqueue' has to do reclamation if the defer queue is full. I do not think this
> is trivial.
> >
> > In the current design, reclamation in enqueue is also done on regular
> > basis (automatic triggering of reclamation when the queue reaches
> > certain limit) to keep the queue from growing too large. This is
> > required when we implement a dynamically adjusting defer queue. The
> current algorithm keeps the cost of reclamation spread across multiple calls
> and puts an upper bound on cycles for delete API by reclaiming a fixed
> number of entries.
> >
> > This algorithm is proven to work in the LPM integration performance
> > tests at a very low performance over head (~1%). So, I do not know why a
> user would not want to use this.
>
> Yeh, I looked at LPM implementation and one thing I found strange -
> defer_queue is hidden inside LPM struct and all reclamations are done
> internally.
> Yes for sure it allows to defer and group actual reclaim(), which hopefully will
> lead to better performance.
> But why not to allow user to call reclaim() for it directly too?
> In that way user might avoid/(minimize) doing reclaim() in LPM write() at all.
> And let say do it somewhere later in the same thread (when no other tasks to
> do), or even leave it to some other house-keeping thread to do (sort of
> garbage collector).
> Or such mode is not supported/planned?
The goal of integrating the RCU defer APIs with libraries is to take away the complexity on the writer to adopt the lock-free algorithms. I am looking to address most used use cases. There will be use cases which are not very common and I think those should be addressed by the application by using the base RCU APIs. Let us discuss this more in the other thread, where you have similar questions.
>
> > The 2 additional parameters should give the user more flexibility.
>
> Ok, let's keep it as config params.
> After another though - I think you right, it should be good enough.
>
> >
> > However, if the user wants his own algorithm, he can create one with the
> base APIs provided.
> >
> > >
> > > > I think adding these to parameters seems like a better option.
> > > >
> > > > >
> > > > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > > > + "%s(): Triggering reclamation\n", __func__);
> > > > > > + rte_rcu_qsbr_dq_reclaim(dq);
> > > > > > + }
> > > > > > +
> > > > > > + /* Check if there is space for atleast for 1 resource */
> > > > > > + free_size = rte_ring_free_count(dq->r) / (dq->esize/8 + 1);
> > > > > > + if (!free_size) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): Defer queue is full\n", __func__);
> > > > > > + rte_errno = ENOSPC;
> > > > > > + return 1;
> > > > > > + }
> > > > > > +
> > > > > > + /* Enqueue the resource */
> > > > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)token);
> > > > > > +
> > > > > > + /* The resource to enqueue needs to be a multiple of 64b
> > > > > > + * due to the limitation of the rte_ring implementation.
> > > > > > + */
> > > > > > + for (i = 0, tmp = (uint64_t *)e; i < dq->esize/8; i++, tmp++)
> > > > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)*tmp);
> > > > >
> > > > >
> > > > > That whole construction above looks a bit clumsy and error prone...
> > > > > I suppose just:
> > > > >
> > > > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t free, n; ...
> > > > > n = rte_ring_enqueue_bulk(dq->r, e, nb_elt, &free); if (n == 0)
> > > > Yes, bulk enqueue can be used. But note that once the flexible
> > > > element size
> > > ring patch is done, this code will use that.
> > >
> > > Well, when it will be in the mainline, and it would provide a better
> > > way, for sure this code can be updated to use new API (if it is provide
> some improvements).
> > > But as I udenrstand, right now it is not there, while bulk
> enqueue/dequeue are.
> > Apologies, I was not clear. I agree we can go with bulk APIs for now.
> >
> > >
> > > >
> > > > > return -ENOSPC;
> > > > > return free;
> > > > >
> > > > > That way I think you can have MT-safe version of that function.
> > > > Please see the description of MT safe issue above.
> > > >
> > > > >
> > > > > > +
> > > > > > + return 0;
> > > > > > +}
> > > > > > +
> > > > > > +/* Reclaim resources from the defer queue. */ int
> > > > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq) {
> > > > > > + uint32_t max_cnt;
> > > > > > + uint32_t cnt;
> > > > > > + void *token;
> > > > > > + uint64_t *tmp;
> > > > > > + uint32_t i;
> > > > > > +
> > > > > > + if (dq == NULL) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > > + rte_errno = EINVAL;
> > > > > > +
> > > > > > + return 1;
> > > > >
> > > > > Same story as above - I think rte_errno is excessive in this function.
> > > > > Just return value should be enough.
> > > > >
> > > > >
> > > > > > + }
> > > > > > +
> > > > > > + /* Anything to reclaim? */
> > > > > > + if (rte_ring_count(dq->r) == 0)
> > > > > > + return 0;
> > > > >
> > > > > Not sure you need that, see below.
> > > > >
> > > > > > +
> > > > > > + /* Reclaim at the max 1/16th the total number of entries. */
> > > > > > + max_cnt = dq->size >> RTE_RCU_QSBR_MAX_RECLAIM_LIMIT;
> > > > > > + max_cnt = (max_cnt == 0) ? dq->size : max_cnt;
> > > > >
> > > > > Again why not to make max_cnt a configurable at create() parameter?
> > > > I think making this as an optional parameter for creating defer
> > > > queue is a
> > > better option.
> > > >
> > > > > Or even a parameter for that function?
> > > > >
> > > > > > + cnt = 0;
> > > > > > +
> > > > > > + /* Check reader threads quiescent state and reclaim
> resources */
> > > > > > + while ((cnt < max_cnt) && (rte_ring_peek(dq->r, &token) ==
> 0) &&
> > > > > > + (rte_rcu_qsbr_check(dq->v,
> (uint64_t)((uintptr_t)token), false)
> > > > > > + == 1)) {
> > > > >
> > > > >
> > > > > > + (void)rte_ring_sc_dequeue(dq->r, &token);
> > > > > > + /* The resource to dequeue needs to be a multiple of
> 64b
> > > > > > + * due to the limitation of the rte_ring
> implementation.
> > > > > > + */
> > > > > > + for (i = 0, tmp = (uint64_t *)dq->e; i < dq->esize/8;
> > > > > > + i++, tmp++)
> > > > > > + (void)rte_ring_sc_dequeue(dq->r,
> > > > > > + (void *)(uintptr_t)tmp);
> > > > >
> > > > > Again, no need for such constructs with multiple dequeuer I believe.
> > > > > Just:
> > > > >
> > > > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t n;
> > > > > uintptr_t elt[nb_elt]; ...
> > > > > n = rte_ring_dequeue_bulk(dq->r, elt, nb_elt, NULL); if (n != 0)
> > > > > {dq->f(dq->p, elt);}
> > > > Agree on bulk API use.
> > > >
> > > > >
> > > > > Seems enough.
> > > > > Again in that case you can have enqueue/reclaim running in
> > > > > different threads simultaneously, plus you don't need dq->e at all.
> > > > Will check on dq->e
> > > >
> > > > >
> > > > > > + dq->f(dq->p, dq->e);
> > > > > > +
> > > > > > + cnt++;
> > > > > > + }
> > > > > > +
> > > > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > > > + "%s(): Reclaimed %u resources\n", __func__, cnt);
> > > > > > +
> > > > > > + if (cnt == 0) {
> > > > > > + /* No resources were reclaimed */
> > > > > > + rte_errno = EAGAIN;
> > > > > > + return 1;
> > > > > > + }
> > > > > > +
> > > > > > + return 0;
> > > > >
> > > > > I'd suggest to return cnt on success.
> > > > I am trying to keep the APIs simple. I do not see much use for 'cnt'
> > > > as return value to the user. It exposes more details which I think
> > > > are internal
> > > to the library.
> > >
> > > Not sure what is the hassle to return number of completed reclamaitions?
> > > If user doesn't need that information, he simply wouldn't use it.
> > > But might be it would be usefull - he can decide should he try
> > > another attempt of reclaim() immediately or is it ok to do something else.
> > There is no hassle to return that information.
> >
> > As per the current design, user calls 'reclaim' when it is out of
> > resources while adding an entry to the data structure. At that point
> > the user wants to know if at least 1 resource was reclaimed because the
> user has to allocate 1 resource. He does not have a use for the number of
> resources reclaimed.
>
> Ok, but why user can't decide to do reclaim in advance, let say when he
> foresee that he would need a lot of allocations in nearest future?
> Or when there is some idle time? Or some combination of these things?
> At he would like to free some extra resources in that case to minimize
> number of reclaims in future peak interval?
If the user has free time he can call the reclaim API. By making the parameters configurable, he should be able to control how much he can reclaim.
If the user wants to make sure that he has enough free resources for the future. He should be able to do it by knowing how many free resources are available in his data structure currently.
But, I do not see it as a problem to return the number of resources reclaimed. I will add that.
>
> >
> > If this API returns 0, then the user can decide to repeat the call or
> > return failure. But that decision depends on the length of the grace period
> which is under user's control.
> >
> > >
> > > >
> > > > >
> > > > > > +}
> > > > > > +
> > > > > > +/* Delete a defer queue. */
> > > > > > +int
> > > > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq) {
> > > > > > + if (dq == NULL) {
> > > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > > + rte_errno = EINVAL;
> > > > > > +
> > > > > > + return 1;
> > > > > > + }
> > > > > > +
> > > > > > + /* Reclaim all the resources */
> > > > > > + if (rte_rcu_qsbr_dq_reclaim(dq) != 0)
> > > > > > + /* Error number is already set by the reclaim API */
> > > > > > + return 1;
> > > > >
> > > > > How do you know that you have reclaimed everything?
> > > > Good point, will come back with a different solution.
> > > >
> > > > >
> > > > > > +
> > > > > > + rte_ring_free(dq->r);
> > > > > > + rte_free(dq);
> > > > > > +
> > > > > > + return 0;
> > > > > > +}
> > > > > > +
> > > > > > int rte_rcu_log_type;
> > > > > >
> > > > > > RTE_INIT(rte_rcu_register)
> > > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > > b/lib/librte_rcu/rte_rcu_qsbr.h index c80f15c00..185d4b50a
> > > > > > 100644
> > > > > > --- a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > > @@ -34,6 +34,7 @@ extern "C" { #include <rte_lcore.h>
> > > > > > #include <rte_debug.h> #include <rte_atomic.h>
> > > > > > +#include <rte_ring.h>
> > > > > >
> > > > > > extern int rte_rcu_log_type;
> > > > > >
> > > > > > @@ -109,6 +110,67 @@ struct rte_rcu_qsbr {
> > > > > > */
> > > > > > } __rte_cache_aligned;
> > > > > >
> > > > > > +/**
> > > > > > + * Call back function called to free the resources.
> > > > > > + *
> > > > > > + * @param p
> > > > > > + * Pointer provided while creating the defer queue
> > > > > > + * @param e
> > > > > > + * Pointer to the resource data stored on the defer queue
> > > > > > + *
> > > > > > + * @return
> > > > > > + * None
> > > > > > + */
> > > > > > +typedef void (*rte_rcu_qsbr_free_resource)(void *p, void *e);
> > > > >
> > > > > Stylish thing - usually in DPDK we have typedf newtype_t ...
> > > > > Though I am not sure you need a new typedef at all - just a
> > > > > function pointer inside the struct seems enough.
> > > > Other libraries (for ex: rte_hash) use this approach. I think it
> > > > is better to keep
> > > it out of the structure to allow for better commenting.
> > >
> > > I am saying majority of DPDK code use _t suffix for typedef:
> > > typedef void (*rte_rcu_qsbr_free_resource_t)(void *p, void *e);
> > Apologies, got it, will change.
> >
> > >
> > > >
> > > > >
> > > > > > +
> > > > > > +#define RTE_RCU_QSBR_DQ_NAMESIZE RTE_RING_NAMESIZE
> > > > > > +
> > > > > > +/**
> > > > > > + * Trigger automatic reclamation after 1/8th the defer queue is full.
> > > > > > + */
> > > > > > +#define RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT 3
> > > > > > +
> > > > > > +/**
> > > > > > + * Reclaim at the max 1/16th the total number of resources.
> > > > > > + */
> > > > > > +#define RTE_RCU_QSBR_MAX_RECLAIM_LIMIT 4
> > > > >
> > > > >
> > > > > As I said above, I don't think these thresholds need to be hardcoded.
> > > > > In any case, there seems not much point to put them in the
> > > > > public header
> > > file.
> > > > >
> > > > > > +
> > > > > > +/**
> > > > > > + * Parameters used when creating the defer queue.
> > > > > > + */
> > > > > > +struct rte_rcu_qsbr_dq_parameters {
> > > > > > + const char *name;
> > > > > > + /**< Name of the queue. */
> > > > > > + uint32_t size;
> > > > > > + /**< Number of entries in queue. Typically, this will be
> > > > > > + * the same as the maximum number of entries supported in
> the
> > > > > > + * lock free data structure.
> > > > > > + * Data structures with unbounded number of entries is not
> > > > > > + * supported currently.
> > > > > > + */
> > > > > > + uint32_t esize;
> > > > > > + /**< Size (in bytes) of each element in the defer queue.
> > > > > > + * This has to be multiple of 8B as the rte_ring APIs
> > > > > > + * support 8B element sizes only.
> > > > > > + */
> > > > > > + rte_rcu_qsbr_free_resource f;
> > > > > > + /**< Function to call to free the resource. */
> > > > > > + void *p;
> > > > >
> > > > > Style nit again - I like short names myself, but that seems a
> > > > > bit extreme... :) Might be at least:
> > > > > void (*reclaim)(void *, void *);
> > > > May be 'free_fn'?
> > > >
> > > > > void * reclaim_data;
> > > > > ?
> > > > This is the pointer to the data structure to free the resource
> > > > into. For ex: In
> > > LPM data structure, it will be pointer to LPM. 'reclaim_data'
> > > > does not convey the meaning correctly.
> > >
> > > Ok, please free to comeup with your own names.
> > > I just wanted to say that 'f' and 'p' are a bit an extreme for public API.
> > ok, this is the hardest thing to do 😊
> >
> > >
> > > >
> > > > >
> > > > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > > > + * pointer to the data structure to which the resource to
> free
> > > > > > + * belongs. This can be NULL.
> > > > > > + */
> > > > > > + struct rte_rcu_qsbr *v;
> > > > >
> > > > > Does it need to be inside that struct?
> > > > > Might be better:
> > > > > rte_rcu_qsbr_dq_create(struct rte_rcu_qsbr *v, const struct
> > > > > rte_rcu_qsbr_dq_parameters *params);
> > > > The API takes a parameter structure as input anyway, why to add
> > > > another argument to the function? QSBR variable is also another
> parameter.
> > > >
> > > > >
> > > > > Another alternative: make both reclaim() and enqueue() to take v
> > > > > as a parameter.
> > > > But both of them need access to some of the parameters provided in
> > > > rte_rcu_qsbr_dq_create API. We would end up passing 2 arguments to
> > > > the
> > > functions.
> > >
> > > Pure stylish thing.
> > > From my perspective it just provides better visibility what is going in the
> code:
> > > For QSBR var 'v' create a new deferred queue.
> > > But no strong opinion here.
> > >
> > > >
> > > > >
> > > > > > + /**< RCU QSBR variable to use for this defer queue */ };
> > > > > > +
> > > > > > +/* RTE defer queue structure.
> > > > > > + * This structure holds the defer queue. The defer queue is
> > > > > > +used to
> > > > > > + * hold the deleted entries from the data structure that are
> > > > > > +not
> > > > > > + * yet freed.
> > > > > > + */
> > > > > > +struct rte_rcu_qsbr_dq;
> > > > > > +
> > > > > > /**
> > > > > > * @warning
> > > > > > * @b EXPERIMENTAL: this API may change without prior notice
> > > > > > @@
> > > > > > -648,6 +710,113 @@ __rte_experimental int
> > > > > > rte_rcu_qsbr_dump(FILE *f, struct rte_rcu_qsbr *v);
> > > > > >
> > > > > > +/**
> > > > > > + * @warning
> > > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > > + *
> > > > > > + * Create a queue used to store the data structure elements
> > > > > > +that can
> > > > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > > > + *
> > > > > > + * @param params
> > > > > > + * Parameters to create a defer queue.
> > > > > > + * @return
> > > > > > + * On success - Valid pointer to defer queue
> > > > > > + * On error - NULL
> > > > > > + * Possible rte_errno codes are:
> > > > > > + * - EINVAL - NULL parameters are passed
> > > > > > + * - ENOMEM - Not enough memory
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +struct rte_rcu_qsbr_dq *
> > > > > > +rte_rcu_qsbr_dq_create(const struct
> > > > > > +rte_rcu_qsbr_dq_parameters *params);
> > > > > > +
> > > > > > +/**
> > > > > > + * @warning
> > > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > > + *
> > > > > > + * Enqueue one resource to the defer queue and start the grace
> period.
> > > > > > + * The resource will be freed later after at least one grace
> > > > > > +period
> > > > > > + * is over.
> > > > > > + *
> > > > > > + * If the defer queue is full, it will attempt to reclaim resources.
> > > > > > + * It will also reclaim resources at regular intervals to
> > > > > > +avoid
> > > > > > + * the defer queue from growing too big.
> > > > > > + *
> > > > > > + * This API is not multi-thread safe. It is expected that the
> > > > > > +caller
> > > > > > + * provides multi-thread safety by locking a mutex or some other
> means.
> > > > > > + *
> > > > > > + * A lock free multi-thread writer algorithm could achieve
> > > > > > +multi-thread
> > > > > > + * safety by creating and using one defer queue per thread.
> > > > > > + *
> > > > > > + * @param dq
> > > > > > + * Defer queue to allocate an entry from.
> > > > > > + * @param e
> > > > > > + * Pointer to resource data to copy to the defer queue. The size of
> > > > > > + * the data to copy is equal to the element size provided when the
> > > > > > + * defer queue was created.
> > > > > > + * @return
> > > > > > + * On success - 0
> > > > > > + * On error - 1 with rte_errno set to
> > > > > > + * - EINVAL - NULL parameters are passed
> > > > > > + * - ENOSPC - Defer queue is full. This condition can not happen
> > > > > > + * if the defer queue size is equal (or larger) than the
> > > > > > + * number of elements in the data structure.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +int
> > > > > > +rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e);
> > > > > > +
> > > > > > +/**
> > > > > > + * @warning
> > > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > > + *
> > > > > > + * Reclaim resources from the defer queue.
> > > > > > + *
> > > > > > + * This API is not multi-thread safe. It is expected that the
> > > > > > +caller
> > > > > > + * provides multi-thread safety by locking a mutex or some other
> means.
> > > > > > + *
> > > > > > + * A lock free multi-thread writer algorithm could achieve
> > > > > > +multi-thread
> > > > > > + * safety by creating and using one defer queue per thread.
> > > > > > + *
> > > > > > + * @param dq
> > > > > > + * Defer queue to reclaim an entry from.
> > > > > > + * @return
> > > > > > + * On successful reclamation of at least 1 resource - 0
> > > > > > + * On error - 1 with rte_errno set to
> > > > > > + * - EINVAL - NULL parameters are passed
> > > > > > + * - EAGAIN - None of the resources have completed at least 1
> grace
> > > > > period,
> > > > > > + * try again.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +int
> > > > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq);
> > > > > > +
> > > > > > +/**
> > > > > > + * @warning
> > > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > > + *
> > > > > > + * Delete a defer queue.
> > > > > > + *
> > > > > > + * It tries to reclaim all the resources on the defer queue.
> > > > > > + * If any of the resources have not completed the grace
> > > > > > +period
> > > > > > + * the reclamation stops and returns immediately. The rest of
> > > > > > + * the resources are not reclaimed and the defer queue is not
> > > > > > + * freed.
> > > > > > + *
> > > > > > + * @param dq
> > > > > > + * Defer queue to delete.
> > > > > > + * @return
> > > > > > + * On success - 0
> > > > > > + * On error - 1
> > > > > > + * Possible rte_errno codes are:
> > > > > > + * - EINVAL - NULL parameters are passed
> > > > > > + * - EAGAIN - Some of the resources have not completed at least 1
> > > grace
> > > > > > + * period, try again.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +int
> > > > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq);
> > > > > > +
> > > > > > #ifdef __cplusplus
> > > > > > }
> > > > > > #endif
> > > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > > > b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > > > new file mode 100644
> > > > > > index 000000000..2122bc36a
> > > > > > --- /dev/null
> > > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > >
> > > > > Again style suggestion: as it is not public header - don't use
> > > > > rte_ prefix for naming.
> > > > > From my perspective - easier to relalize for reader what is
> > > > > public header, what is not.
> > > > Looks like the guidelines are not defined very well. I see one
> > > > private file with rte_ prefix. I see Stephen not using rte_
> > > > prefix. I do not have any
> > > preference. But, a consistent approach is required.
> > >
> > > That's just a suggestion.
> > > For me (and I hope for others) it would be a bit easier.
> > > When looking at the code for first time I had to look a t
> > > meson.build to check is it a public header or not.
> > > If the file doesn't have 'rte_' prefix, I assume that it is an
> > > internal one straightway.
> > > But , as you said, there is no exact guidelines here, so up to you to decide.
> > I think it makes sense to remove 'rte_' prefix. I will also change the file
> name to have '_private' suffix.
> > There are some inconsistencies in the existing code, will send a patch to
> correct them to follow this approach.
> >
> > >
> > > >
> > > > >
> > > > > > @@ -0,0 +1,46 @@
> > > > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > > > + * Copyright (c) 2019 Arm Limited */
> > > > > > +
> > > > > > +#ifndef _RTE_RCU_QSBR_PVT_H_
> > > > > > +#define _RTE_RCU_QSBR_PVT_H_
> > > > > > +
> > > > > > +/**
> > > > > > + * This file is private to the RCU library. It should not be
> > > > > > +included
> > > > > > + * by the user of this library.
> > > > > > + */
> > > > > > +
> > > > > > +#ifdef __cplusplus
> > > > > > +extern "C" {
> > > > > > +#endif
> > > > > > +
> > > > > > +#include "rte_rcu_qsbr.h"
> > > > > > +
> > > > > > +/* RTE defer queue structure.
> > > > > > + * This structure holds the defer queue. The defer queue is
> > > > > > +used to
> > > > > > + * hold the deleted entries from the data structure that are
> > > > > > +not
> > > > > > + * yet freed.
> > > > > > + */
> > > > > > +struct rte_rcu_qsbr_dq {
> > > > > > + struct rte_rcu_qsbr *v; /**< RCU QSBR variable used by this
> queue.*/
> > > > > > + struct rte_ring *r; /**< RCU QSBR defer queue. */
> > > > > > + uint32_t size;
> > > > > > + /**< Number of elements in the defer queue */
> > > > > > + uint32_t esize;
> > > > > > + /**< Size (in bytes) of data stored on the defer queue */
> > > > > > + rte_rcu_qsbr_free_resource f;
> > > > > > + /**< Function to call to free the resource. */
> > > > > > + void *p;
> > > > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > > > + * pointer to the data structure to which the resource to
> free
> > > > > > + * belongs.
> > > > > > + */
> > > > > > + char e[0];
> > > > > > + /**< Temporary storage to copy the defer queue element. */
> > > > >
> > > > > Do you really need 'e' at all?
> > > > > Can't it be just temporary stack variable?
> > > > Ok, will check.
> > > >
> > > > >
> > > > > > +};
> > > > > > +
> > > > > > +#ifdef __cplusplus
> > > > > > +}
> > > > > > +#endif
> > > > > > +
> > > > > > +#endif /* _RTE_RCU_QSBR_PVT_H_ */
> > > > > > diff --git a/lib/librte_rcu/rte_rcu_version.map
> > > > > > b/lib/librte_rcu/rte_rcu_version.map
> > > > > > index f8b9ef2ab..dfac88a37 100644
> > > > > > --- a/lib/librte_rcu/rte_rcu_version.map
> > > > > > +++ b/lib/librte_rcu/rte_rcu_version.map
> > > > > > @@ -8,6 +8,10 @@ EXPERIMENTAL {
> > > > > > rte_rcu_qsbr_synchronize;
> > > > > > rte_rcu_qsbr_thread_register;
> > > > > > rte_rcu_qsbr_thread_unregister;
> > > > > > + rte_rcu_qsbr_dq_create;
> > > > > > + rte_rcu_qsbr_dq_enqueue;
> > > > > > + rte_rcu_qsbr_dq_reclaim;
> > > > > > + rte_rcu_qsbr_dq_delete;
> > > > > >
> > > > > > local: *;
> > > > > > };
> > > > > > diff --git a/lib/meson.build b/lib/meson.build index
> > > > > > e5ff83893..0e1be8407 100644
> > > > > > --- a/lib/meson.build
> > > > > > +++ b/lib/meson.build
> > > > > > @@ -11,7 +11,9 @@
> > > > > > libraries = [
> > > > > > 'kvargs', # eal depends on kvargs
> > > > > > 'eal', # everything depends on eal
> > > > > > - 'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > > > + 'ring',
> > > > > > + 'rcu', # rcu depends on ring
> > > > > > + 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > > > 'cmdline',
> > > > > > 'metrics', # bitrate/latency stats depends on this
> > > > > > 'hash', # efd depends on this
> > > > > > @@ -22,7 +24,7 @@ libraries = [
> > > > > > 'gro', 'gso', 'ip_frag', 'jobstats',
> > > > > > 'kni', 'latencystats', 'lpm', 'member',
> > > > > > 'power', 'pdump', 'rawdev',
> > > > > > - 'rcu', 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > > > + 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > > > # ipsec lib depends on net, crypto and security
> > > > > > 'ipsec',
> > > > > > # add pkt framework libs which use other libs from above
> > > > > > --
> > > > > > 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] crypto/armv8: enable meson build
2019-10-11 20:14 2% ` Honnappa Nagarahalli
@ 2019-10-11 20:33 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2019-10-11 20:33 UTC (permalink / raw)
To: Honnappa Nagarahalli
Cc: Thomas Monjalon, Jerin Jacob, Dharmik Thakkar,
Akhil.goyal@nxp.com, hemant.agrawal, anoobj, pathreya,
Richardson, Bruce, dpdk-dev, nd, prasun.kapoor
On Sat, 12 Oct, 2019, 1:44 AM Honnappa Nagarahalli, <
Honnappa.Nagarahalli@arm.com> wrote:
> On Sat, 12 Oct, 2019, 12:44 AM Honnappa Nagarahalli, <
> Honnappa.Nagarahalli@arm.com> wrote:
>
> <snip>
>
>
>
> On Thu, 10 Oct, 2019, 10:17 AM Honnappa Nagarahalli, <
> Honnappa.Nagarahalli@arm.com> wrote:
>
> <snip>
>
>
>
> On Mon, 7 Oct, 2019, 3:49 PM Jerin Jacob, <jerinjacobk@gmail.com> wrote:
>
>
>
> On Sun, 6 Oct, 2019, 11:36 PM Thomas Monjalon, <thomas@monjalon.net>
> wrote:
>
> 05/10/2019 17:28, Jerin Jacob:
> > On Fri, Oct 4, 2019 at 4:27 AM Dharmik Thakkar <dharmik.thakkar@arm.com>
> wrote:
> > >
> > > Add new meson.build file for crypto/armv8
> > >
> > > Signed-off-by: Dharmik Thakkar <dharmik.thakkar@arm.com>
> > > ---
> > > drivers/crypto/armv8/meson.build | 25 +++++++++++++++++++++++++
> > > drivers/crypto/meson.build | 6 +++---
> > > meson_options.txt | 2 ++
> > > 3 files changed, 30 insertions(+), 3 deletions(-)
> > > create mode 100644 drivers/crypto/armv8/meson.build
> >
> > >
> > > option('allow_invalid_socket_id', type: 'boolean', value: false,
> > > description: 'allow out-of-range NUMA socket id\'s for
> platforms that don\'t report the value correctly')
> > > +option('armv8_crypto_dir', type: 'string', value: '',
> > > + description: 'path to the armv8_crypto library installation
> directory')
>
> You should not need such option if you provide a pkg-config file
> in your library.
>
>
> > It is not specific to this patch but it is connected to this patch.
> >
> > Three years back when Cavium contributed to this driver the situation
> > was different where only Cavium was contributing to DPDK and now we
> > have multiple vendors from
> > ARMv8 platform and ARM itself is contributing it.
> >
> > When it is submitted, I was not in favor of the external library. But
> > various reasons it happened to be the external library where 90% meat
> > in this library and shim PMD
> > the driver moved to DPDK.
> >
> > Now, I look back, It does not make sense to the external library.
> Reasons are
> > - It won't allow another ARMv8 player to contribute to this library as
> > Marvell owns this repo and there is no upstreaming path to this
> > library.
>
> This is a real issue and you are able to fix it.
>
>
>
> Note sure how I can fix it and why I need to fix it. I just dont want to
> start a parallel collaborating infrastructure for DPDK armv8.
>
>
>
>
>
> > - That made this library to not have 'any' change for the last three
> > year and everyone have there owned copy of this driver. In fact the
> > library was not compiling for last 2.5 years.
> > - AES-NI case it makes sense to have an external library as it is a
> > single vendor and it is not specific to DPDK. But in this, It is
> > another way around
>
> I don't see how it is different, except it is badly maintained.
>
>
>
> It is different because only one company contributing to it. In this case,
> multiple companies needs to contribute.
>
>
>
> The library badly maintained in upstream as there is no incentives to
> upstream to external library. I believe each vendor has it own copy of
> that. At least Some teams in Marvell internally has copy of it.
>
> What is their incentive to upstream? They ask me the same thing.
>
>
>
>
>
> > - If it an external library, we might as well add the PMD code as well
> > there and that only 10% of the real stuff.
> > We are not able able to improve anything in this library due to this
> situation.
> >
> > Does anyone care about this PMD? If not, we might as well remove this
> > DPDK and every vendor can manage the external library and external
> > PMD(Situation won't change much)
>
> External PMD is bad.
>
>
>
> It is SHIM layer. I would say external library also bad if it is specific
> to DPDK.
>
>
>
> I think this library should not be specific to DPDK,
>
>
>
> Sadly it is VERY specific to DPDK for doing authentication and encryption
> in one shot to improve the performance. Openssl has already has armv8
> instructions support for doing it as two pass just that performance is not
> good. For use cae such as IPsec it make sense do authentication and
> encryption in one shot for performance improvement.
>
> *[Honnappa] *I think there is a need for such a library not just for
> DPDK. It would be good if it could do UDP checksum validation for the inner
> packet as well.
>
>
>
> so it would make sense as an external library
>
>
>
> If it an external library, it does NOT make much sense for Marvell to
> maintain it(No incentive and it is pain due lack of collaboration)
>
>
>
> Either someone need to step up and maintain it if we NOT choose to make it
> as external else we can remove the PMD from dpdk(Makes life easy for
> everyone). I don't want to maintain something not upsteamble nor
> collaboration friendly aka less quality.
>
>
>
> .
>
>
>
>
> > Thoughts from ARM, other ARMv8 vendors or community?
>
>
>
> I have expressed my concerns. If there is no constructive feedback to fix
> the concern. I will plan for submitting a patch to remove the shim crypto
> Armv8 PMD from dpdk by next week.
>
> *[Honnappa] *I do not think there is a need to remove the PMD. As you
> have mentioned, many might have developed their own libraries and may be
> dependent on DPDK Armv8 PMD.
>
>
>
> Problem with that approach is that, No convergence/collaboration on this
> PMD aka no improvement and less quality.
>
> *[Honnappa] *Would not removing this fall under ABI/API compatibility?
> Essentially, DPDK defines how an external Armv8 Crypto library can work
> with DPDK. Is it possible to remove it considering that there might be
> users dependent on this?
>
> I agree with you on the improvements (features?), but not sure on quality.
> For the features that are supported, the quality should be good.
>
>
>
> The library was broken for last 2.5 years. Is that the high quality and no
> improvement for last 3 year and no single contribution otherthan Marvell in
> external library.
>
> *[Honnappa] *We need to separate the discussion about PMD and the
> external library. IMO, PMD cannot be removed as some might be using the
> interfaces with their own crypto library.
>
Multiple libraries for same job. That's same thing I would like to avoid.
And the PMD does not exist without external library. If some has their own
crypto library then please update in the documentation so that others can
use it. It is not open-source way of doing the stuff. Else I need assume no
one is using the PMD.
>
> From Arm side, there have been efforts to fix the situation. Some have not
> gone far and some have shown promise, but fell flat. I can say that this is
> still a priority but I am not sure when we will have something.
>
>
>
> If ARM is ready to take over the maintenance on PMD and external library
> then I am fine with any decision.
>
> Let us know. Personally, I don't like to maintain something not upsteamble
> friendly.
>
> *[Honnappa] *What is the maintenance burden on the PMD? Can you elaborate?
>
>
>
> Marvell open-source policy is bit different than cavium policy. We can not
> contribute to GitHub repository with out approval. The existing external
> library, not belongs to Marvell GitHub domain. I need to create a case to
> add new GitHub repo under Marvell to contribute to all armv8 partners. I
> don't have justification for that to legal. We have approvals to contribute
> to dpdk.org
>
>
>
> On the external library, I do not think this is the right forum to make a
> decision. There are channels provided to all our partners to discuss these
> kind of topics and I think those should be made use of.
>
> It is cavium created library for dpdk. Why we need to discuss in some
> other channel. I believe this is the correct forum for dpdk discussions.
>
> *[Honnappa] *May be I was not clear, please see my comment below.
>
>
>
> For example, Dharmik got comment to update the external library to
> support autoconfig for meson. What is the path for Dharmik to do that?
>
> *[Honnappa] *Is this mainly from testing purposes?
>
>
>
Not for testing. See Thomas comment
Don't you think, you need have access to the complete code base to
> contribute. That's the reason why I am saying remove the external library
> and have it in DPDK so that everyone can contribute and improve.
>
> *[Honnappa] *I don’t have any issues
>
But DPDK does have support for that.
>
> If you think, otherwise please take over the maintenance keeping initial
> author credit. If you need time to take decision that makes sense. You can
> share the ETA. Otherwise, this discussion going in circles.
>
> *[Honnappa] *This cannot be decided in this forum.
>
>
>
Then please start the discussion with the form you think it as appropriate.
>
> My suggestion, we should go ahead with adding the meson build for this PMD.
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] crypto/armv8: enable meson build
2019-10-11 20:02 0% ` Jerin Jacob
@ 2019-10-11 20:14 2% ` Honnappa Nagarahalli
2019-10-11 20:33 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2019-10-11 20:14 UTC (permalink / raw)
To: Jerin Jacob
Cc: thomas, jerinj, Dharmik Thakkar, Akhil.goyal@nxp.com,
hemant.agrawal, anoobj, pathreya, Richardson, Bruce, dpdk-dev,
Honnappa Nagarahalli, nd, prasun.kapoor, nd
On Sat, 12 Oct, 2019, 12:44 AM Honnappa Nagarahalli, <Honnappa.Nagarahalli@arm.com<mailto:Honnappa.Nagarahalli@arm.com>> wrote:
<snip>
On Thu, 10 Oct, 2019, 10:17 AM Honnappa Nagarahalli, <Honnappa.Nagarahalli@arm.com<mailto:Honnappa.Nagarahalli@arm.com>> wrote:
<snip>
On Mon, 7 Oct, 2019, 3:49 PM Jerin Jacob, <jerinjacobk@gmail.com<mailto:jerinjacobk@gmail.com>> wrote:
On Sun, 6 Oct, 2019, 11:36 PM Thomas Monjalon, <thomas@monjalon.net<mailto:thomas@monjalon.net>> wrote:
05/10/2019 17:28, Jerin Jacob:
> On Fri, Oct 4, 2019 at 4:27 AM Dharmik Thakkar <dharmik.thakkar@arm.com<mailto:dharmik.thakkar@arm.com>> wrote:
> >
> > Add new meson.build file for crypto/armv8
> >
> > Signed-off-by: Dharmik Thakkar <dharmik.thakkar@arm.com<mailto:dharmik.thakkar@arm.com>>
> > ---
> > drivers/crypto/armv8/meson.build | 25 +++++++++++++++++++++++++
> > drivers/crypto/meson.build | 6 +++---
> > meson_options.txt | 2 ++
> > 3 files changed, 30 insertions(+), 3 deletions(-)
> > create mode 100644 drivers/crypto/armv8/meson.build
>
> >
> > option('allow_invalid_socket_id', type: 'boolean', value: false,
> > description: 'allow out-of-range NUMA socket id\'s for platforms that don\'t report the value correctly')
> > +option('armv8_crypto_dir', type: 'string', value: '',
> > + description: 'path to the armv8_crypto library installation directory')
You should not need such option if you provide a pkg-config file
in your library.
> It is not specific to this patch but it is connected to this patch.
>
> Three years back when Cavium contributed to this driver the situation
> was different where only Cavium was contributing to DPDK and now we
> have multiple vendors from
> ARMv8 platform and ARM itself is contributing it.
>
> When it is submitted, I was not in favor of the external library. But
> various reasons it happened to be the external library where 90% meat
> in this library and shim PMD
> the driver moved to DPDK.
>
> Now, I look back, It does not make sense to the external library. Reasons are
> - It won't allow another ARMv8 player to contribute to this library as
> Marvell owns this repo and there is no upstreaming path to this
> library.
This is a real issue and you are able to fix it.
Note sure how I can fix it and why I need to fix it. I just dont want to start a parallel collaborating infrastructure for DPDK armv8.
> - That made this library to not have 'any' change for the last three
> year and everyone have there owned copy of this driver. In fact the
> library was not compiling for last 2.5 years.
> - AES-NI case it makes sense to have an external library as it is a
> single vendor and it is not specific to DPDK. But in this, It is
> another way around
I don't see how it is different, except it is badly maintained.
It is different because only one company contributing to it. In this case, multiple companies needs to contribute.
The library badly maintained in upstream as there is no incentives to upstream to external library. I believe each vendor has it own copy of that. At least Some teams in Marvell internally has copy of it.
What is their incentive to upstream? They ask me the same thing.
> - If it an external library, we might as well add the PMD code as well
> there and that only 10% of the real stuff.
> We are not able able to improve anything in this library due to this situation.
>
> Does anyone care about this PMD? If not, we might as well remove this
> DPDK and every vendor can manage the external library and external
> PMD(Situation won't change much)
External PMD is bad.
It is SHIM layer. I would say external library also bad if it is specific to DPDK.
I think this library should not be specific to DPDK,
Sadly it is VERY specific to DPDK for doing authentication and encryption in one shot to improve the performance. Openssl has already has armv8 instructions support for doing it as two pass just that performance is not good. For use cae such as IPsec it make sense do authentication and encryption in one shot for performance improvement.
[Honnappa] I think there is a need for such a library not just for DPDK. It would be good if it could do UDP checksum validation for the inner packet as well.
so it would make sense as an external library
If it an external library, it does NOT make much sense for Marvell to maintain it(No incentive and it is pain due lack of collaboration)
Either someone need to step up and maintain it if we NOT choose to make it as external else we can remove the PMD from dpdk(Makes life easy for everyone). I don't want to maintain something not upsteamble nor collaboration friendly aka less quality.
.
> Thoughts from ARM, other ARMv8 vendors or community?
I have expressed my concerns. If there is no constructive feedback to fix the concern. I will plan for submitting a patch to remove the shim crypto Armv8 PMD from dpdk by next week.
[Honnappa] I do not think there is a need to remove the PMD. As you have mentioned, many might have developed their own libraries and may be dependent on DPDK Armv8 PMD.
Problem with that approach is that, No convergence/collaboration on this PMD aka no improvement and less quality.
[Honnappa] Would not removing this fall under ABI/API compatibility? Essentially, DPDK defines how an external Armv8 Crypto library can work with DPDK. Is it possible to remove it considering that there might be users dependent on this?
I agree with you on the improvements (features?), but not sure on quality. For the features that are supported, the quality should be good.
The library was broken for last 2.5 years. Is that the high quality and no improvement for last 3 year and no single contribution otherthan Marvell in external library.
[Honnappa] We need to separate the discussion about PMD and the external library. IMO, PMD cannot be removed as some might be using the interfaces with their own crypto library.
From Arm side, there have been efforts to fix the situation. Some have not gone far and some have shown promise, but fell flat. I can say that this is still a priority but I am not sure when we will have something.
If ARM is ready to take over the maintenance on PMD and external library then I am fine with any decision.
Let us know. Personally, I don't like to maintain something not upsteamble friendly.
[Honnappa] What is the maintenance burden on the PMD? Can you elaborate?
Marvell open-source policy is bit different than cavium policy. We can not contribute to GitHub repository with out approval. The existing external library, not belongs to Marvell GitHub domain. I need to create a case to add new GitHub repo under Marvell to contribute to all armv8 partners. I don't have justification for that to legal. We have approvals to contribute to dpdk.org<http://dpdk.org>
On the external library, I do not think this is the right forum to make a decision. There are channels provided to all our partners to discuss these kind of topics and I think those should be made use of.
It is cavium created library for dpdk. Why we need to discuss in some other channel. I believe this is the correct forum for dpdk discussions.
[Honnappa] May be I was not clear, please see my comment below.
For example, Dharmik got comment to update the external library to support autoconfig for meson. What is the path for Dharmik to do that?
[Honnappa] Is this mainly from testing purposes?
Don't you think, you need have access to the complete code base to contribute. That's the reason why I am saying remove the external library and have it in DPDK so that everyone can contribute and improve.
[Honnappa] I don’t have any issues
If you think, otherwise please take over the maintenance keeping initial author credit. If you need time to take decision that makes sense. You can share the ETA. Otherwise, this discussion going in circles.
[Honnappa] This cannot be decided in this forum.
My suggestion, we should go ahead with adding the meson build for this PMD.
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH] crypto/armv8: enable meson build
2019-10-11 19:13 2% ` Honnappa Nagarahalli
@ 2019-10-11 20:02 0% ` Jerin Jacob
2019-10-11 20:14 2% ` Honnappa Nagarahalli
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-11 20:02 UTC (permalink / raw)
To: Honnappa Nagarahalli
Cc: Thomas Monjalon, Jerin Jacob, Dharmik Thakkar, Akhil Goyal,
Hemant Agrawal, anoobj, pathreya, Richardson, Bruce, dpdk-dev,
nd, prasun.kapoor
On Sat, 12 Oct, 2019, 12:44 AM Honnappa Nagarahalli, <
Honnappa.Nagarahalli@arm.com> wrote:
> <snip>
>
>
>
> On Thu, 10 Oct, 2019, 10:17 AM Honnappa Nagarahalli, <
> Honnappa.Nagarahalli@arm.com> wrote:
>
> <snip>
>
>
>
> On Mon, 7 Oct, 2019, 3:49 PM Jerin Jacob, <jerinjacobk@gmail.com> wrote:
>
>
>
> On Sun, 6 Oct, 2019, 11:36 PM Thomas Monjalon, <thomas@monjalon.net>
> wrote:
>
> 05/10/2019 17:28, Jerin Jacob:
> > On Fri, Oct 4, 2019 at 4:27 AM Dharmik Thakkar <dharmik.thakkar@arm.com>
> wrote:
> > >
> > > Add new meson.build file for crypto/armv8
> > >
> > > Signed-off-by: Dharmik Thakkar <dharmik.thakkar@arm.com>
> > > ---
> > > drivers/crypto/armv8/meson.build | 25 +++++++++++++++++++++++++
> > > drivers/crypto/meson.build | 6 +++---
> > > meson_options.txt | 2 ++
> > > 3 files changed, 30 insertions(+), 3 deletions(-)
> > > create mode 100644 drivers/crypto/armv8/meson.build
> >
> > >
> > > option('allow_invalid_socket_id', type: 'boolean', value: false,
> > > description: 'allow out-of-range NUMA socket id\'s for
> platforms that don\'t report the value correctly')
> > > +option('armv8_crypto_dir', type: 'string', value: '',
> > > + description: 'path to the armv8_crypto library installation
> directory')
>
> You should not need such option if you provide a pkg-config file
> in your library.
>
>
> > It is not specific to this patch but it is connected to this patch.
> >
> > Three years back when Cavium contributed to this driver the situation
> > was different where only Cavium was contributing to DPDK and now we
> > have multiple vendors from
> > ARMv8 platform and ARM itself is contributing it.
> >
> > When it is submitted, I was not in favor of the external library. But
> > various reasons it happened to be the external library where 90% meat
> > in this library and shim PMD
> > the driver moved to DPDK.
> >
> > Now, I look back, It does not make sense to the external library.
> Reasons are
> > - It won't allow another ARMv8 player to contribute to this library as
> > Marvell owns this repo and there is no upstreaming path to this
> > library.
>
> This is a real issue and you are able to fix it.
>
>
>
> Note sure how I can fix it and why I need to fix it. I just dont want to
> start a parallel collaborating infrastructure for DPDK armv8.
>
>
>
>
>
> > - That made this library to not have 'any' change for the last three
> > year and everyone have there owned copy of this driver. In fact the
> > library was not compiling for last 2.5 years.
> > - AES-NI case it makes sense to have an external library as it is a
> > single vendor and it is not specific to DPDK. But in this, It is
> > another way around
>
> I don't see how it is different, except it is badly maintained.
>
>
>
> It is different because only one company contributing to it. In this case,
> multiple companies needs to contribute.
>
>
>
> The library badly maintained in upstream as there is no incentives to
> upstream to external library. I believe each vendor has it own copy of
> that. At least Some teams in Marvell internally has copy of it.
>
> What is their incentive to upstream? They ask me the same thing.
>
>
>
>
>
> > - If it an external library, we might as well add the PMD code as well
> > there and that only 10% of the real stuff.
> > We are not able able to improve anything in this library due to this
> situation.
> >
> > Does anyone care about this PMD? If not, we might as well remove this
> > DPDK and every vendor can manage the external library and external
> > PMD(Situation won't change much)
>
> External PMD is bad.
>
>
>
> It is SHIM layer. I would say external library also bad if it is specific
> to DPDK.
>
>
>
> I think this library should not be specific to DPDK,
>
>
>
> Sadly it is VERY specific to DPDK for doing authentication and encryption
> in one shot to improve the performance. Openssl has already has armv8
> instructions support for doing it as two pass just that performance is not
> good. For use cae such as IPsec it make sense do authentication and
> encryption in one shot for performance improvement.
>
> *[Honnappa] *I think there is a need for such a library not just for
> DPDK. It would be good if it could do UDP checksum validation for the inner
> packet as well.
>
>
>
> so it would make sense as an external library
>
>
>
> If it an external library, it does NOT make much sense for Marvell to
> maintain it(No incentive and it is pain due lack of collaboration)
>
>
>
> Either someone need to step up and maintain it if we NOT choose to make it
> as external else we can remove the PMD from dpdk(Makes life easy for
> everyone). I don't want to maintain something not upsteamble nor
> collaboration friendly aka less quality.
>
>
>
> .
>
>
>
>
> > Thoughts from ARM, other ARMv8 vendors or community?
>
>
>
> I have expressed my concerns. If there is no constructive feedback to fix
> the concern. I will plan for submitting a patch to remove the shim crypto
> Armv8 PMD from dpdk by next week.
>
> *[Honnappa] *I do not think there is a need to remove the PMD. As you
> have mentioned, many might have developed their own libraries and may be
> dependent on DPDK Armv8 PMD.
>
>
>
> Problem with that approach is that, No convergence/collaboration on this
> PMD aka no improvement and less quality.
>
> *[Honnappa] *Would not removing this fall under ABI/API compatibility?
> Essentially, DPDK defines how an external Armv8 Crypto library can work
> with DPDK. Is it possible to remove it considering that there might be
> users dependent on this?
>
> I agree with you on the improvements (features?), but not sure on quality.
> For the features that are supported, the quality should be good.
>
The library was broken for last 2.5 years. Is that the high quality and no
improvement for last 3 year and no single contribution otherthan Marvell in
external library.
>
> From Arm side, there have been efforts to fix the situation. Some have not
> gone far and some have shown promise, but fell flat. I can say that this is
> still a priority but I am not sure when we will have something.
>
>
>
> If ARM is ready to take over the maintenance on PMD and external library
> then I am fine with any decision.
>
> Let us know. Personally, I don't like to maintain something not upsteamble
> friendly.
>
> *[Honnappa] *What is the maintenance burden on the PMD? Can you elaborate?
>
Marvell open-source policy is bit different than cavium policy. We can not
contribute to GitHub repository with out approval. The existing external
library, not belongs to Marvell GitHub domain. I need to create a case to
add new GitHub repo under Marvell to contribute to all armv8 partners. I
don't have justification for that to legal. We have approvals to contribute
to dpdk.org
On the external library, I do not think this is the right forum to make a
> decision. There are channels provided to all our partners to discuss these
> kind of topics and I think those should be made use of.
>
It is cavium created library for dpdk. Why we need to discuss in some other
channel. I believe this is the correct forum for dpdk discussions.
For example, Dharmik got comment to update the external library to support
autoconfig for meson. What is the path for Dharmik to do that?
Don't you think, you need have access to the complete code base to
contribute. That's the reason why I am saying remove the external library
and have it in DPDK so that everyone can contribute and improve.
If you think, otherwise please take over the maintenance keeping initial
author credit. If you need time to take decision that makes sense. You can
share the ETA. Otherwise, this discussion going in circles.
>
> My suggestion, we should go ahead with adding the meson build for this PMD.
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] crypto/armv8: enable meson build
@ 2019-10-11 19:13 2% ` Honnappa Nagarahalli
2019-10-11 20:02 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2019-10-11 19:13 UTC (permalink / raw)
To: Jerin Jacob
Cc: thomas, jerinj, Dharmik Thakkar, Akhil.goyal@nxp.com,
hemant.agrawal, anoobj, pathreya, Bruce Richardson, dpdk-dev,
Honnappa Nagarahalli, nd, nd
<snip>
On Thu, 10 Oct, 2019, 10:17 AM Honnappa Nagarahalli, <Honnappa.Nagarahalli@arm.com<mailto:Honnappa.Nagarahalli@arm.com>> wrote:
<snip>
On Mon, 7 Oct, 2019, 3:49 PM Jerin Jacob, <jerinjacobk@gmail.com<mailto:jerinjacobk@gmail.com>> wrote:
On Sun, 6 Oct, 2019, 11:36 PM Thomas Monjalon, <thomas@monjalon.net<mailto:thomas@monjalon.net>> wrote:
05/10/2019 17:28, Jerin Jacob:
> On Fri, Oct 4, 2019 at 4:27 AM Dharmik Thakkar <dharmik.thakkar@arm.com<mailto:dharmik.thakkar@arm.com>> wrote:
> >
> > Add new meson.build file for crypto/armv8
> >
> > Signed-off-by: Dharmik Thakkar <dharmik.thakkar@arm.com<mailto:dharmik.thakkar@arm.com>>
> > ---
> > drivers/crypto/armv8/meson.build | 25 +++++++++++++++++++++++++
> > drivers/crypto/meson.build | 6 +++---
> > meson_options.txt | 2 ++
> > 3 files changed, 30 insertions(+), 3 deletions(-)
> > create mode 100644 drivers/crypto/armv8/meson.build
>
> >
> > option('allow_invalid_socket_id', type: 'boolean', value: false,
> > description: 'allow out-of-range NUMA socket id\'s for platforms that don\'t report the value correctly')
> > +option('armv8_crypto_dir', type: 'string', value: '',
> > + description: 'path to the armv8_crypto library installation directory')
You should not need such option if you provide a pkg-config file
in your library.
> It is not specific to this patch but it is connected to this patch.
>
> Three years back when Cavium contributed to this driver the situation
> was different where only Cavium was contributing to DPDK and now we
> have multiple vendors from
> ARMv8 platform and ARM itself is contributing it.
>
> When it is submitted, I was not in favor of the external library. But
> various reasons it happened to be the external library where 90% meat
> in this library and shim PMD
> the driver moved to DPDK.
>
> Now, I look back, It does not make sense to the external library. Reasons are
> - It won't allow another ARMv8 player to contribute to this library as
> Marvell owns this repo and there is no upstreaming path to this
> library.
This is a real issue and you are able to fix it.
Note sure how I can fix it and why I need to fix it. I just dont want to start a parallel collaborating infrastructure for DPDK armv8.
> - That made this library to not have 'any' change for the last three
> year and everyone have there owned copy of this driver. In fact the
> library was not compiling for last 2.5 years.
> - AES-NI case it makes sense to have an external library as it is a
> single vendor and it is not specific to DPDK. But in this, It is
> another way around
I don't see how it is different, except it is badly maintained.
It is different because only one company contributing to it. In this case, multiple companies needs to contribute.
The library badly maintained in upstream as there is no incentives to upstream to external library. I believe each vendor has it own copy of that. At least Some teams in Marvell internally has copy of it.
What is their incentive to upstream? They ask me the same thing.
> - If it an external library, we might as well add the PMD code as well
> there and that only 10% of the real stuff.
> We are not able able to improve anything in this library due to this situation.
>
> Does anyone care about this PMD? If not, we might as well remove this
> DPDK and every vendor can manage the external library and external
> PMD(Situation won't change much)
External PMD is bad.
It is SHIM layer. I would say external library also bad if it is specific to DPDK.
I think this library should not be specific to DPDK,
Sadly it is VERY specific to DPDK for doing authentication and encryption in one shot to improve the performance. Openssl has already has armv8 instructions support for doing it as two pass just that performance is not good. For use cae such as IPsec it make sense do authentication and encryption in one shot for performance improvement.
[Honnappa] I think there is a need for such a library not just for DPDK. It would be good if it could do UDP checksum validation for the inner packet as well.
so it would make sense as an external library
If it an external library, it does NOT make much sense for Marvell to maintain it(No incentive and it is pain due lack of collaboration)
Either someone need to step up and maintain it if we NOT choose to make it as external else we can remove the PMD from dpdk(Makes life easy for everyone). I don't want to maintain something not upsteamble nor collaboration friendly aka less quality.
.
> Thoughts from ARM, other ARMv8 vendors or community?
I have expressed my concerns. If there is no constructive feedback to fix the concern. I will plan for submitting a patch to remove the shim crypto Armv8 PMD from dpdk by next week.
[Honnappa] I do not think there is a need to remove the PMD. As you have mentioned, many might have developed their own libraries and may be dependent on DPDK Armv8 PMD.
Problem with that approach is that, No convergence/collaboration on this PMD aka no improvement and less quality.
[Honnappa] Would not removing this fall under ABI/API compatibility? Essentially, DPDK defines how an external Armv8 Crypto library can work with DPDK. Is it possible to remove it considering that there might be users dependent on this?
I agree with you on the improvements (features?), but not sure on quality. For the features that are supported, the quality should be good.
From Arm side, there have been efforts to fix the situation. Some have not gone far and some have shown promise, but fell flat. I can say that this is still a priority but I am not sure when we will have something.
If ARM is ready to take over the maintenance on PMD and external library then I am fine with any decision.
Let us know. Personally, I don't like to maintain something not upsteamble friendly.
[Honnappa] What is the maintenance burden on the PMD? Can you elaborate?
On the external library, I do not think this is the right forum to make a decision. There are channels provided to all our partners to discuss these kind of topics and I think those should be made use of.
My suggestion, we should go ahead with adding the meson build for this PMD.
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-09 13:43 0% ` Ananyev, Konstantin
@ 2019-10-11 13:23 0% ` Akhil Goyal
2019-10-13 23:07 0% ` Zhang, Roy Fan
2019-10-16 22:07 3% ` Ananyev, Konstantin
0 siblings, 2 replies; 200+ results
From: Akhil Goyal @ 2019-10-11 13:23 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan, Doherty, Declan
Cc: 'Anoob Joseph'
Hi Konstantin,
>
> Hi Akhil,
>
..[snip]
> > > > > > OK let us assume that you have a separate structure. But I have a few
> > > queries:
> > > > > > 1. how can multiple drivers use a same session
> > > > >
> > > > > As a short answer: they can't.
> > > > > It is pretty much the same approach as with rte_security - each device
> needs
> > > to
> > > > > create/init its own session.
> > > > > So upper layer would need to maintain its own array (or so) for such case.
> > > > > Though the question is why would you like to have same session over
> > > multiple
> > > > > SW backed devices?
> > > > > As it would be anyway just a synchronous function call that will be
> executed
> > > on
> > > > > the same cpu.
> > > >
> > > > I may have single FAT tunnel which may be distributed over multiple
> > > > Cores, and each core is affined to a different SW device.
> > >
> > > If it is pure SW, then we don't need multiple devices for such scenario.
> > > Device in that case is pure abstraction that we can skip.
> >
> > Yes agreed, but that liberty is given to the application whether it need multiple
> > devices with single queue or a single device with multiple queues.
> > I think that independence should not be broken in this new API.
> > >
> > > > So a single session may be accessed by multiple devices.
> > > >
> > > > One more example would be depending on packet sizes, I may switch
> between
> > > > HW/SW PMDs with the same session.
> > >
> > > Sure, but then we'll have multiple sessions.
> >
> > No, the session will be same and it will have multiple private data for each of
> the PMD.
> >
> > > BTW, we have same thing now - these private session pointers are just
> stored
> > > inside the same rte_crypto_sym_session.
> > > And if user wants to support this model, he would also need to store <dev_id,
> > > queue_id>
> > > pair for each HW device anyway.
> >
> > Yes agreed, but how is that thing happening in your new struct, you cannot
> support that.
>
> User can store all these info in his own struct.
> That's exactly what we have right now.
> Let say ipsec-secgw has to store for each IPsec SA:
> pointer to crypto-session and/or pointer to security session
> plus (for lookaside-devices) cdev_id_qp that allows it to extract
> dev_id + queue_id information.
> As I understand that works for now, as each ipsec_sa uses only one
> dev+queue. Though if someone would like to use multiple devices/queues
> for the same SA - he would need to have an array of these <dev+queue> pairs.
> So even right now rte_cryptodev_sym_session is not self-consistent and
> requires extra information to be maintained by user.
Why are you increasing the complexity for the user application.
The new APIs and struct should be such that it need to do minimum changes in the stack
so that stack is portable on multiple vendors.
You should try to hide as much complexity in the driver or lib to give the user simple APIs.
Having a same session for multiple devices was added by Intel only for some use cases.
And we had split that session create API into 2. Now if those are not useful shall we move back
to the single API. I think @Doherty, Declan and @De Lara Guarch, Pablo can comment on this.
>
> >
> > >
> > > >
> > > > >
> > > > > > 2. Can somebody use the scheduler pmd for scheduling the different
> type
> > > of
> > > > > payloads for the same session?
> > > > >
> > > > > In theory yes.
> > > > > Though for that scheduler pmd should have inside it's
> > > > > rte_crypto_cpu_sym_session an array of pointers to
> > > > > the underlying devices sessions.
> > > > >
> > > > > >
> > > > > > With your proposal the APIs would be very specific to your use case
> only.
> > > > >
> > > > > Yes in some way.
> > > > > I consider that API specific for SW backed crypto PMDs.
> > > > > I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will
> benefit
> > > > > from it.
> > > > > Current crypto-op API is very much HW oriented.
> > > > > Which is ok, that's for it was intended for, but I think we also need one
> that
> > > > > would be designed
> > > > > for SW backed implementation in mind.
> > > >
> > > > We may re-use your API for HW PMDs as well which do not have
> requirement
> > > of
> > > > Crypto-op/mbuf etc.
> > > > The return type of your new process API may have a status which say
> > > 'processed'
> > > > Or can be say 'enqueued'. So if it is 'enqueued', we may have a new API for
> > > raw
> > > > Bufs dequeue as well.
> > > >
> > > > This requirement can be for any hardware PMDs like QAT as well.
> > >
> > > I don't think it is a good idea to extend this API for async (lookaside) devices.
> > > You'll need to:
> > > - provide dev_id and queue_id for each process(enqueue) and dequeuer
> > > operation.
> > > - provide IOVA for all buffers passing to that function (data buffers, digest,
> IV,
> > > aad).
> > > - On dequeue provide some way to associate dequed data and digest buffers
> > > with
> > > crypto-session that was used (and probably with mbuf).
> > > So most likely we'll end up with another just version of our current crypto-op
> > > structure.
> > > If you'd like to get rid of mbufs dependency within current crypto-op API that
> > > understandable,
> > > but I don't think we should have same API for both sync (CPU) and async
> > > (lookaside) cases.
> > > It doesn't seem feasible at all and voids whole purpose of that patch.
> >
> > At this moment we are not much concerned about the dequeue API and about
> the
> > HW PMD support. It is just that the new API should be generic enough to be
> used in
> > some future scenarios as well. I am just highlighting the possible usecases
> which can
> > be there in future.
>
> Sorry, but I strongly disagree with such approach.
> We should stop adding/modifying API 'just in case' and because 'it might be
> useful for some future HW'.
> Inside DPDK we already do have too many dev level APIs without any
> implementations.
> That's quite bad practice and very dis-orienting for end-users.
> I think to justify API additions/changes we need at least one proper
> implementation for it,
> or at least some strong evidence that people are really committed to support it
> in nearest future.
> BTW, that what TB agreed on, nearly a year ago.
>
> This new API (if we'll go ahead with it of course) would stay experimental for
> some time anyway
> to make sure we don't miss anything needed (I think for about a year time-
> frame).
> So if you guys *really* want to extend it support _async_ devices too -
> I am open for modifications/additions here.
> Though personally I think such addition would over-complicate things and we'll
> end up with
> another reincarnation of current crypto-op.
> We actually discussed it internally, and decided to drop that idea because of that.
> Again, my opinion - for lookaside devices it might be better to try to optimize
> current crypto-op path (remove mbuf requirement, probably add ability to
> group by session on enqueue/dequeue, etc.).
I agree that the new API is experimental and can be modified later. So no issues in that,
but we can keep some things in mind while defining APIs. These were some comments from
my side, if those are impacting the current scenario, you can drop those. We will take care of those
later.
>
> >
> > What is the issue that you face in making a dev-op for this new API. Do you see
> any
> > performance impact with that?
>
> There are two main things:
> 1. user would need to maintain and provide for each process() call
> dev_id+queue_id.
> That's means extra (and totally unnecessary for SW) overhead.
You are using a crypto device for performing the processing,
you must use dev_id to identify which SW device it is. This is how the DPDK
Framework works.
.
> 2. yes I would expect some perf overhead too - it would be extra call or branch.
> Again as it would be data-dependency - most likely cpu wouldn't be able to
> pipeline
> it efficiently:
>
> rte_crypto_sym_process(uint8_t dev_id, uint16 qp_id, rte_crypto_sym_session
> *ses, ...)
> {
> struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
> return (*dev->process)(sess->data[dev->driver_id, ...);
> }
>
> driver_specific_process(driver_specific_sym_session *sess)
> {
> return sess->process(sess, ...) ;
> }
>
> I didn't make any exact measurements but sure it would be slower than just:
> session_udata->process(session->udata->sess, ...);
> Again it would be much more noticeable on low end cpus.
> Let say here:
> http://mails.dpdk.org/archives/dev/2019-September/144350.html
> Jerin claims 1.5-3% drop for introducing extra call via hiding eth_dev contents -
> I suppose we would have something similar here.
> I do realize that in majority of cases crypto is more expensive then RX/TX, but
> still.
>
> If it would be a really unavoidable tradeoff (support already existing API, or so)
> I wouldn't mind, but I don't see any real need for it right now.
Calling session_udata->process(session->udata->sess, ...); from the application and
Application need to maintain for each PMD the process() API in its memory will make
the application not portable to other vendors.
What we are doing here is defining another way to create sessions for the same stuff
that is already done. This make applications non-portable and confusing for the application
writer.
I would say you should do some profiling first. As you also mentioned crypto workload is more
Cycle consuming, it will not impact this case.
>
> >
> > >
> > > > That is why a dev-ops would be a better option.
> > > >
> > > > >
> > > > > > When you would add more functionality to this sync API/struct, it will
> end
> > > up
> > > > > being the same API/struct.
> > > > > >
> > > > > > Let us see how close/ far we are from the existing APIs when the
> actual
> > > > > implementation is done.
> > > > > >
> > > > > > > > I am not sure if that would be needed.
> > > > > > > > It would be internal to the driver that if synchronous processing is
> > > > > > > supported(from feature flag) and
> > > > > > > > Have relevant fields in xform(the newly added ones which are
> packed
> > > as
> > > > > per
> > > > > > > your suggestions) set,
> > > > > > > > It will create that type of session.
> > > > > > > >
> > > > > > > >
> > > > > > > > > + * Main points:
> > > > > > > > > + * - Current crypto-dev API is reasonably mature and it is
> desirable
> > > > > > > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > > > > > > + * new sync API is new one and probably would require extra
> > > changes.
> > > > > > > > > + * Having it as a new one allows to mark it as experimental,
> without
> > > > > > > > > + * affecting existing one.
> > > > > > > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > > > > > > + * to the PMD writers and again allows to avoid ABI breakages
> in
> > > future.
> > > > > > > > > + * - process() function per set of xforms
> > > > > > > > > + * allows to expose different process() functions for different
> > > > > > > > > + * xform combinations. PMD writer can decide, does he wants
> to
> > > > > > > > > + * push all supported algorithms into one process() function,
> > > > > > > > > + * or spread it across several ones.
> > > > > > > > > + * I.E. More flexibility for PMD writer.
> > > > > > > >
> > > > > > > > Which process function should be chosen is internal to PMD, how
> > > would
> > > > > that
> > > > > > > info
> > > > > > > > be visible to the application or the library. These will get stored in
> the
> > > > > session
> > > > > > > private
> > > > > > > > data. It would be upto the PMD writer, to store the per session
> process
> > > > > > > function in
> > > > > > > > the session private data.
> > > > > > > >
> > > > > > > > Process function would be a dev ops just like enc/deq operations
> and it
> > > > > should
> > > > > > > call
> > > > > > > > The respective process API stored in the session private data.
> > > > > > >
> > > > > > > That model (via devops) is possible, but has several drawbacks from
> my
> > > > > > > perspective:
> > > > > > >
> > > > > > > 1. It means we'll need to pass dev_id as a parameter to process()
> function.
> > > > > > > Though in fact dev_id is not a relevant information for us here
> > > > > > > (all we need is pointer to the session and pointer to the fuction to call)
> > > > > > > and I tried to avoid using it in data-path functions for that API.
> > > > > >
> > > > > > You have a single vdev, but someone may have multiple vdevs for each
> > > thread,
> > > > > or may
> > > > > > Have same dev with multiple queues for each core.
> > > > >
> > > > > That's fine. As I said above it is a SW backed implementation.
> > > > > Each session has to be a separate entity that contains all necessary
> > > information
> > > > > (keys, alg/mode info, etc.) to process input buffers.
> > > > > Plus we need the actual function pointer to call.
> > > > > I just don't see what for we need a dev_id in that situation.
> > > >
> > > > To iterate the session private data in the session.
> > > >
> > > > > Again, here we don't need care about queues and their pinning to cores.
> > > > > If let say someone would like to process buffers from the same IPsec SA
> on 2
> > > > > different cores in parallel, he can just create 2 sessions for the same
> xform,
> > > > > give one to thread #1 and second to thread #2.
> > > > > After that both threads are free to call process(this_thread_ses, ...) at will.
> > > >
> > > > Say you have a 16core device to handle 100G of traffic on a single tunnel.
> > > > Will we make 16 sessions with same parameters?
> > >
> > > Absolutely same question we can ask for current crypto-op API.
> > > You have lookaside crypto-dev with 16 HW queues, each queue is serviced by
> > > different CPU.
> > > For the same SA, do you need a separate session per queue, or is it ok to
> reuse
> > > current one?
> > > AFAIK, right now this is a grey area not clearly defined.
> > > For crypto-devs I am aware - user can reuse the same session (as PMD uses it
> > > read-only).
> > > But again, right now I think it is not clearly defined and is implementation
> > > specific.
> >
> > User can use the same session, that is what I am also insisting, but it may have
> separate
> > Session private data. Cryptodev session create API provide that functionality
> and we can
> > Leverage that.
>
> rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means
> we can't use
> the same rte_cryptodev_sym_session to hold sessions for both sync and async
> mode
> for the same device. Off course we can add a hard requirement that any driver
> that wants to
> support process() has to create sessions that can handle both process and
> enqueue/dequeue,
> but then again what for to create such overhead?
>
> BTW, to be honest, I don't consider current rte_cryptodev_sym_session
> construct for multiple device_ids:
> __extension__ struct {
> void *data;
> uint16_t refcnt;
> } sess_data[0];
> /**< Driver specific session material, variable size */
>
Yes I also feel the same. I was also not in favor of this when it was introduced.
Please go ahead and remove this. I have no issues with that.
> as an advantage.
> It looks too error prone for me:
> 1. Simultaneous session initialization/de-initialization for devices with the same
> driver_id is not possible.
> 2. It assumes that all device driver will be loaded before we start to create
> session pools.
>
> Right now it seems ok, as no-one requires such functionality, but I don't know
> how it will be in future.
> For me rte_security session model, where for each security context user have to
> create new session
> looks much more robust.
Agreed
>
> >
> > BTW, I can see a v2 to this RFC which is still based on security library.
>
> Yes, v2 was concentrated on fixing found issues, some code restructuring,
> i.e. - changes that would be needed anyway whatever API aproach we'll choose.
>
> > When do you plan
> > To submit the patches for crypto based APIs. We have RC1 merge deadline for
> this
> > patchset on 21st Oct.
>
> We'd like to start working on it ASAP, but it seems we still have a major
> disagreement
> about how this crypto-dev API should look like.
> Which makes me think - should we return to our original proposal via
> rte_security?
> It still looks to me like clean and straightforward way to enable this new API,
> and probably wouldn't cause that much controversy.
> What do you think?
I cannot spend more time discussing on this until RC1 date. I have some other stuff pending.
You can send the patches early next week with the approach that I mentioned or else we
can discuss this post RC1(which would mean deferring to 20.02).
But moving back to security is not acceptable to me. The code should be put where it is
intended and not where it is easy to put. You are not doing any rte_security stuff.
Regards,
Akhil
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v5] eventdev: flag to identify same destined packets enqueue
` (4 preceding siblings ...)
2019-10-09 7:32 6% ` [dpdk-dev] [PATCH v4] " Nipun Gupta
@ 2019-10-11 13:03 6% ` Nipun Gupta
5 siblings, 0 replies; 200+ results
From: Nipun Gupta @ 2019-10-11 13:03 UTC (permalink / raw)
To: dev
Cc: jerinj, aconole, pbhagavatula, skori, hemant.agrawal,
bruce.richardson, marko.kovacevic, orika, radu.nicolau,
tomasz.kantecki, harry.van.haaren, nikhil.rao, Nipun Gupta
This patch introduces a `flag` in the Eth TX adapter enqueue API.
Some drivers may support burst functionality only with the packets
having same destination device and queue.
The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
to indicate this so the underlying driver, for drivers to utilize
burst functionality appropriately.
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---
Changes in v5:
- Assign 'txa_enqueue_same_dest' callback in octeontx drivers
Changes in v4:
- Update rel note specifying the API change
- Remove redundant rte_event_tx_adapter_enqueue_same_dest API
Changes in v3:
- remove flag from internal txa_enqueue_same_dest internal API
- ABI version update in makefile, meson and rel_notes
- Few comments update
Changes in v2:
- have separate internal API in tx adapter for sending burst packets to
same eth dev, queue pair on the basis of the passed flag
- fix compilation of examples/eventdev_pipeline/
app/test-eventdev/test_pipeline_common.h | 6 +++---
.../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
doc/guides/rel_notes/release_19_11.rst | 7 ++++++-
drivers/event/octeontx/ssovf_evdev.c | 1 +
drivers/event/octeontx2/otx2_evdev.c | 2 ++
.../eventdev_pipeline/pipeline_worker_tx.c | 2 +-
lib/librte_eventdev/Makefile | 2 +-
lib/librte_eventdev/meson.build | 2 +-
.../rte_event_eth_tx_adapter.h | 19 +++++++++++++++++--
lib/librte_eventdev/rte_eventdev.c | 1 +
lib/librte_eventdev/rte_eventdev.h | 10 ++++++++++
11 files changed, 45 insertions(+), 10 deletions(-)
diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
index 0440b9e29..6e73c6ab2 100644
--- a/app/test-eventdev/test_pipeline_common.h
+++ b/app/test-eventdev/test_pipeline_common.h
@@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t port,
struct rte_event * const ev)
{
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
@@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
{
uint16_t enq;
- enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
+ enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
while (enq < nb_rx) {
enq += rte_event_eth_tx_adapter_enqueue(dev, port,
- ev + enq, nb_rx - enq);
+ ev + enq, nb_rx - enq, 0);
}
}
diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
index 192f9e1cf..a8c13e136 100644
--- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
+++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
@@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()`` function.
if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
event.mbuf = m;
+ eq_flags = 0;
m->port = tx_port;
rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
- rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
+ rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags);
} else {
event.queue_id = qid; /* event queue linked to adapter port */
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e3..051ab26b8 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -94,6 +94,11 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* event: The function ``rte_event_eth_tx_adapter_enqueue`` takes an additional
+ input as ``flags``. Flag ``RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST`` which
+ has been introduced in this release is used when used when all the packets
+ enqueued in the tx adapter are destined for the same Ethernet port & Tx queue.
+
ABI Changes
-----------
@@ -146,7 +151,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_eal.so.11
librte_efd.so.1
librte_ethdev.so.12
- librte_eventdev.so.7
+ librte_eventdev.so.8
librte_flow_classify.so.1
librte_gro.so.1
librte_gso.so.1
diff --git a/drivers/event/octeontx/ssovf_evdev.c b/drivers/event/octeontx/ssovf_evdev.c
index a273d4c96..e4e7c44ed 100644
--- a/drivers/event/octeontx/ssovf_evdev.c
+++ b/drivers/event/octeontx/ssovf_evdev.c
@@ -147,6 +147,7 @@ ssovf_fastpath_fns_set(struct rte_eventdev *dev)
dev->dequeue = ssows_deq;
dev->dequeue_burst = ssows_deq_burst;
dev->txa_enqueue = sso_event_tx_adapter_enqueue;
+ dev->txa_enqueue_same_dest = dev->txa_enqueue;
if (edev->is_timeout_deq) {
dev->dequeue = ssows_deq_timeout;
diff --git a/drivers/event/octeontx2/otx2_evdev.c b/drivers/event/octeontx2/otx2_evdev.c
index 160ac94ee..318dc475c 100644
--- a/drivers/event/octeontx2/otx2_evdev.c
+++ b/drivers/event/octeontx2/otx2_evdev.c
@@ -428,6 +428,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
NIX_TX_OFFLOAD_L3_L4_CSUM_F)];
}
}
+
+ event_dev->txa_enqueue_same_dest = event_dev->txa_enqueue;
rte_mb();
}
diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c
index 8961cd656..a0f40c27c 100644
--- a/examples/eventdev_pipeline/pipeline_worker_tx.c
+++ b/examples/eventdev_pipeline/pipeline_worker_tx.c
@@ -40,7 +40,7 @@ worker_tx_pkt(const uint8_t dev, const uint8_t port, struct rte_event *ev)
{
exchange_mac(ev->mbuf);
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index cd3ff8040..9e6a99aa1 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_eventdev.a
# library version
-LIBABIVER := 7
+LIBABIVER := 8
# build flags
CFLAGS += -DALLOW_EXPERIMENTAL_API
diff --git a/lib/librte_eventdev/meson.build b/lib/librte_eventdev/meson.build
index 19541f23f..9ba6c0393 100644
--- a/lib/librte_eventdev/meson.build
+++ b/lib/librte_eventdev/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 7
+version = 8
allow_experimental_apis = true
if is_linux
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index c848261c4..93b717af9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
int
rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
+#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
+/**< This flag is used when all the packets enqueued in the tx adapter are
+ * destined for the same Ethernet port & Tx queue.
+ */
+
/**
* Enqueue a burst of events objects or an event object supplied in *rte_event*
* structure on an event device designated by its *dev_id* through the event
@@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
* The number of event objects to enqueue, typically number of
* rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
* available for this port.
+ * @param flags
+ * RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
+ * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
+ * which are enqueued are destined for the same Ethernet port & Tx queue.
*
* @return
* The number of event objects actually enqueued on the event device. The
@@ -343,7 +352,8 @@ static inline uint16_t
rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
uint8_t port_id,
struct rte_event ev[],
- uint16_t nb_events)
+ uint16_t nb_events,
+ const uint8_t flags)
{
const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
@@ -359,7 +369,12 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
return 0;
}
#endif
- return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
+ if (flags)
+ return dev->txa_enqueue_same_dest(dev->data->ports[port_id],
+ ev, nb_events);
+ else
+ return dev->txa_enqueue(dev->data->ports[port_id], ev,
+ nb_events);
}
/**
diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
index f44c869cb..b987e0745 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -1351,6 +1351,7 @@ rte_event_pmd_allocate(const char *name, int socket_id)
eventdev = &rte_eventdevs[dev_id];
eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
+ eventdev->txa_enqueue_same_dest = rte_event_tx_adapter_enqueue;
if (eventdev->data == NULL) {
struct rte_eventdev_data *eventdev_data = NULL;
diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
index 5044a13d0..ced6f29d9 100644
--- a/lib/librte_eventdev/rte_eventdev.h
+++ b/lib/librte_eventdev/rte_eventdev.h
@@ -1230,6 +1230,12 @@ typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
struct rte_event ev[], uint16_t nb_events);
/**< @internal Enqueue burst of events on port of a device */
+typedef uint16_t (*event_tx_adapter_enqueue_same_dest)(void *port,
+ struct rte_event ev[], uint16_t nb_events);
+/**< @internal Enqueue burst of events on port of a device supporting
+ * burst having same destination Ethernet port & Tx queue.
+ */
+
#define RTE_EVENTDEV_NAME_MAX_LEN (64)
/**< @internal Max length of name of event PMD */
@@ -1292,6 +1298,10 @@ struct rte_eventdev {
/**< Pointer to PMD dequeue function. */
event_dequeue_burst_t dequeue_burst;
/**< Pointer to PMD dequeue burst function. */
+ event_tx_adapter_enqueue_same_dest txa_enqueue_same_dest;
+ /**< Pointer to PMD eth Tx adapter burst enqueue function with
+ * events destined to same Eth port & Tx queue.
+ */
event_tx_adapter_enqueue txa_enqueue;
/**< Pointer to PMD eth Tx adapter enqueue function. */
struct rte_eventdev_data *data;
--
2.17.1
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH v4 00/19] Add advanced features for Huawei hinic pmd
2019-10-10 14:51 3% [dpdk-dev] [PATCH v4 00/19] Add advanced features for Huawei hinic pmd Xiaoyun wang
@ 2019-10-11 9:26 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-11 9:26 UTC (permalink / raw)
To: Xiaoyun wang
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman, zhouguoyang
On 10/10/2019 3:51 PM, Xiaoyun wang wrote:
> This patch set adds advanced features for Huawei hinic pmd,
> such as VLAN filter and VLAN offload, SR-IOV, FW version get,
> set link down and up, Flow director for LACP, VRRP, BGP and so on.
>
> --
> v2:
> - Fix RSS bugs for vxlan packets inner type
> - Add comments for new added func interface
> - Fix code review comments from patch v1
> - Fix code style problems
> - Remove ceq interfaces and definitions that not used
> - Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
> - Fix bar map bugs for VF Page size larger than PF
> - Modify link state set, add enable or disable fiber in tx direction
> - Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
> - Fix FDIR bugs for VRRP packets
> - Fit ABI changes from dpdk lib
>
> v3:
> - Split hinic.ini and hinic.rst to related feature patches
> - Add min_mtu & max_mtu initialization for hinic_dev_infos_get
> - Fix fdir config patch with net/hinic/base
> - Split link patch into link and fw version getting 2 patches
> - Update pmd doc files to new next version
> - Add comments for cover letter patch
> - Add rxq & txq info getting interfaces
> - Fix load intrinsics for receiving packets
>
> v4:
> - Fix receive performance code review comments
> - Fix 32-bit build errs for mbox logs
> - Modify skb description as mbuf
Series applied to dpdk-next-net/master, thanks.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd
2019-10-08 15:33 0% ` Ferruh Yigit
@ 2019-10-11 2:50 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
0 siblings, 0 replies; 200+ results
From: Wangxiaoyun (Cloud, Network Chip Application Development Dept) @ 2019-10-11 2:50 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1
Hi Ferruh,
I have deleted the seq_id getting logs, and we can get the infos by other method, which is updated by Patch V4.
Best Regards,
Xiaoyun Wang
在 2019/10/8 23:33, Ferruh Yigit 写道:
> On 10/8/2019 4:14 PM, Wangxiaoyun (Cloud, Network Chip Application Development
> Dept) wrote:
>> Hi Ferruh,
>> Thanks for your comments. hinic pmd driver doesn't support 32-bit build, we add descriptions with config file "defconfig_x86_x32-native-linuxapp-gcc".
>> and “defconfig_x86_x32-native-linux-gcc”. I don't know why it also build in 32-bit platform, can you tell me where also need me to add configuration.
>> Also I build it on 64-bit platform,That's OK.
> Hi Xiaoyun,
>
> You are right, driver doesn't support 32bit, I am force enabling it, just for build.
>
> Since the build error is only in the logging format identifiers, I think it make
> sense to fix it, and it is better to use more proper format identifiers.
>
>> Best regards
>> Xiaoyun Wang
>>
>> 在 2019/9/30 23:06, Ferruh Yigit 写道:
>>> On 9/30/2019 3:00 PM, Xiaoyun wang wrote:
>>>> This patch set adds advanced features for Huawei hinic pmd,
>>>> such as VLAN filter and VLAN offload, SR-IOV, FW version get,
>>>> set link down and up, Flow director for LACP, VRRP, BGP and so on.
>>>>
>>>> --
>>>> v2:
>>>> - Fix RSS bugs for vxlan packets inner type
>>>> - Add comments for new added func interface
>>>> - Fix code review comments from patch v1
>>>> - Fix code style problems
>>>> - Remove ceq interfaces and definitions that not used
>>>> - Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
>>>> - Fix bar map bugs for VF Page size larger than PF
>>>> - Modify link state set, add enable or disable fiber in tx direction
>>>> - Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
>>>> - Fix FDIR bugs for VRRP packets
>>>> - Fit ABI changes from dpdk lib
>>>>
>>>> v3:
>>>> - Split hinic.ini and hinic.rst to related feature patches
>>>> - Add min_mtu & max_mtu initialization for hinic_dev_infos_get
>>>> - Fix fdir config patch with net/hinic/base
>>>> - Split link patch into link and fw version getting 2 patches
>>>> - Update pmd doc files to new next version
>>>> - Add comments for cover letter patch
>>>> - Add rxq & txq info getting interfaces
>>>> - Fix load intrinsics for receiving packets
>>>>
>>>> Xiaoyun wang (19):
>>>> net/hinic/base: add mbox command channel for SRIOV
>>>> net/hinic/base: add HW interfaces for SR-IOV
>>>> net/hinic: add VF PMD operation interfaces
>>>> net/hinic: add VLAN filter and offload
>>>> net/hinic: add allmulticast mode and MTU set
>>>> net/hinic: add unicast and multicast MAC set
>>>> net/hinic/base: add fdir config interface
>>>> net/hinic: add fdir validate flow operations
>>>> net/hinic: create and destroy ntuple filter
>>>> net/hinic: create and destroy fdir filter
>>>> net/hinic: flush fdir filter
>>>> net/hinic: set link down and up
>>>> net/hinic: get firmware version
>>>> net/hinic: support inner L3 checksum offload
>>>> net/hinic: support LRO offload
>>>> net/hinic: add hinic PMD doc files
>>>> net/hinic/base: optimize aeq interfaces
>>>> net/hinic: optimize RX performance
>>>> net/hinic: add support for getting rxq or txq info
>>> There is following 32-bit build error because of the log formatting [1], can you
>>> please check it?
>>>
>>>
>>> [1]
>>> .../drivers/net/hinic/base/hinic_pmd_mbox.c(659):
>>> error #181: argument of type "unsigned long long" is incompatible with format
>>> "%lx", expecting argument of type "unsigned long"
>>> PMD_DRV_LOG(ERR, "Fail to send mbox seg, seq_id: 0x%lx,
>>> err: %d",
>>>
>>> .
>
> .
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 00/19] Add advanced features for Huawei hinic pmd
@ 2019-10-10 14:51 3% Xiaoyun wang
2019-10-11 9:26 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Xiaoyun wang @ 2019-10-10 14:51 UTC (permalink / raw)
To: ferruh.yigit
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, Xiaoyun wang
This patch set adds advanced features for Huawei hinic pmd,
such as VLAN filter and VLAN offload, SR-IOV, FW version get,
set link down and up, Flow director for LACP, VRRP, BGP and so on.
--
v2:
- Fix RSS bugs for vxlan packets inner type
- Add comments for new added func interface
- Fix code review comments from patch v1
- Fix code style problems
- Remove ceq interfaces and definitions that not used
- Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
- Fix bar map bugs for VF Page size larger than PF
- Modify link state set, add enable or disable fiber in tx direction
- Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
- Fix FDIR bugs for VRRP packets
- Fit ABI changes from dpdk lib
v3:
- Split hinic.ini and hinic.rst to related feature patches
- Add min_mtu & max_mtu initialization for hinic_dev_infos_get
- Fix fdir config patch with net/hinic/base
- Split link patch into link and fw version getting 2 patches
- Update pmd doc files to new next version
- Add comments for cover letter patch
- Add rxq & txq info getting interfaces
- Fix load intrinsics for receiving packets
v4:
- Fix receive performance code review comments
- Fix 32-bit build errs for mbox logs
- Modify skb description as mbuf
Xiaoyun wang (19):
net/hinic/base: add mbox command channel for SRIOV
net/hinic/base: add HW interfaces for SR-IOV
net/hinic: add VF PMD operation interfaces
net/hinic: add VLAN filter and offload
net/hinic: add allmulticast mode and MTU set
net/hinic: add unicast and multicast MAC set
net/hinic/base: add fdir config interface
net/hinic: add fdir validate flow operations
net/hinic: create and destroy ntuple filter
net/hinic: create and destroy fdir filter
net/hinic: flush fdir filter
net/hinic: set link down and up
net/hinic: get firmware version
net/hinic: support inner L3 checksum offload
net/hinic: support LRO offload
net/hinic: add hinic PMD doc files
net/hinic/base: optimize aeq interfaces
net/hinic: optimize RX performance
net/hinic: add support for getting rxq or txq info
doc/guides/nics/features/hinic.ini | 12 +-
doc/guides/nics/hinic.rst | 10 +
doc/guides/rel_notes/release_19_11.rst | 9 +
drivers/net/hinic/Makefile | 2 +
drivers/net/hinic/base/hinic_compat.h | 68 +-
drivers/net/hinic/base/hinic_csr.h | 29 +-
drivers/net/hinic/base/hinic_pmd_api_cmd.c | 60 +-
drivers/net/hinic/base/hinic_pmd_cfg.c | 35 +
drivers/net/hinic/base/hinic_pmd_cmd.h | 26 +-
drivers/net/hinic/base/hinic_pmd_eqs.c | 245 +--
drivers/net/hinic/base/hinic_pmd_eqs.h | 5 +-
drivers/net/hinic/base/hinic_pmd_hwdev.c | 214 ++-
drivers/net/hinic/base/hinic_pmd_hwdev.h | 11 +-
drivers/net/hinic/base/hinic_pmd_hwif.c | 85 +-
drivers/net/hinic/base/hinic_pmd_hwif.h | 15 +-
drivers/net/hinic/base/hinic_pmd_mbox.c | 937 +++++++++++
drivers/net/hinic/base/hinic_pmd_mbox.h | 93 ++
drivers/net/hinic/base/hinic_pmd_mgmt.c | 83 +-
drivers/net/hinic/base/hinic_pmd_mgmt.h | 2 +-
drivers/net/hinic/base/hinic_pmd_niccfg.c | 777 ++++++++-
drivers/net/hinic/base/hinic_pmd_niccfg.h | 203 +++
drivers/net/hinic/base/hinic_pmd_nicio.c | 15 +-
drivers/net/hinic/base/hinic_pmd_nicio.h | 3 +-
drivers/net/hinic/base/meson.build | 1 +
drivers/net/hinic/hinic_pmd_ethdev.c | 1026 ++++++++++--
drivers/net/hinic/hinic_pmd_ethdev.h | 139 +-
drivers/net/hinic/hinic_pmd_flow.c | 2385 ++++++++++++++++++++++++++++
drivers/net/hinic/hinic_pmd_rx.c | 34 +-
drivers/net/hinic/hinic_pmd_rx.h | 4 +-
drivers/net/hinic/hinic_pmd_tx.c | 203 ++-
drivers/net/hinic/hinic_pmd_tx.h | 2 +-
drivers/net/hinic/meson.build | 1 +
32 files changed, 6068 insertions(+), 666 deletions(-)
create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.c
create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.h
create mode 100644 drivers/net/hinic/hinic_pmd_flow.c
--
1.8.3.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] ether: remove packing and set two-byte alignment
@ 2019-10-10 10:46 4% Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-10 10:46 UTC (permalink / raw)
To: dev; +Cc: olivier.matz, thomas, Bruce Richardson, Stephen Hemminger
The ether header does not need to be packed since that makes no sense for
structures with only bytes in them, but it should be aligned to a two-byte
boundary to simplify access to it from code. Other packed structures that
use this also need to be updated to take account of the change, either by
removing packing - where it is clearly unneeded - or by explicitly giving
those structures 2-byte alignment also.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 10 ----------
doc/guides/rel_notes/release_19_11.rst | 6 ++++++
drivers/net/bonding/rte_eth_bond_8023ad.h | 14 +++++++-------
lib/librte_net/rte_arp.h | 4 ++--
lib/librte_net/rte_ether.h | 12 ++++++------
lib/librte_pipeline/rte_table_action.c | 22 +++++++++++-----------
6 files changed, 32 insertions(+), 36 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533b1..86ec962d0 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -61,16 +61,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* net: The Ethernet address and header definitions will change
- attributes. The Ethernet address struct will no longer be marked as
- packed since the packed attribute is meaningless on a byte
- array. The Ethernet header will be marked as aligned on a 2-byte
- boundary and will no longer have the packed attribute. This allows
- for efficient access on CPU architectures where unaligned access is
- expensive. These changes should not impact normal usage because drivers
- naturally align the Ethernet header on receive and all known
- encapsulations preserve the alignment of the header.
-
* ethdev: The function ``rte_eth_dev_count`` will be removed in DPDK 20.02.
It is replaced by the function ``rte_eth_dev_count_avail``.
If the intent is to iterate over ports, ``RTE_ETH_FOREACH_*`` macros
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e3..efaba7872 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -110,6 +110,12 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* net: The Ethernet address and other header definitions have changed
+ attributes. They have been modified to be aligned on 2-byte boundaries.
+ These changes should not impact normal usage because drivers naturally
+ align the Ethernet header on receive and all known encapsulations
+ preserve the alignment of the header.
+
Shared Library Versions
-----------------------
diff --git a/drivers/net/bonding/rte_eth_bond_8023ad.h b/drivers/net/bonding/rte_eth_bond_8023ad.h
index cbad59aa7..62265f449 100644
--- a/drivers/net/bonding/rte_eth_bond_8023ad.h
+++ b/drivers/net/bonding/rte_eth_bond_8023ad.h
@@ -60,7 +60,7 @@ struct slow_protocol {
struct slow_protocol_frame {
struct rte_ether_hdr eth_hdr;
struct slow_protocol slow_protocol;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct port_params {
uint16_t system_priority;
@@ -73,7 +73,7 @@ struct port_params {
/**< Priority of this (unused in current implementation) */
uint16_t port_number;
/**< Port number. It corresponds to slave port id. */
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct lacpdu_actor_partner_params {
uint8_t tlv_type_info;
@@ -81,7 +81,7 @@ struct lacpdu_actor_partner_params {
struct port_params port_params;
uint8_t state;
uint8_t reserved_3[3];
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
/** LACPDU structure (5.4.2 in 802.1AX documentation). */
struct lacpdu {
@@ -99,13 +99,13 @@ struct lacpdu {
uint8_t tlv_type_terminator;
uint8_t terminator_length;
uint8_t reserved_50[50];
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
/** LACPDU frame: Contains ethernet header and LACPDU. */
struct lacpdu_header {
struct rte_ether_hdr eth_hdr;
struct lacpdu lacpdu;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct marker {
uint8_t subtype;
@@ -121,12 +121,12 @@ struct marker {
uint8_t tlv_type_terminator;
uint8_t terminator_length;
uint8_t reserved_90[90];
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct marker_header {
struct rte_ether_hdr eth_hdr;
struct marker marker;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct rte_eth_bond_8023ad_conf {
uint32_t fast_periodic_ms;
diff --git a/lib/librte_net/rte_arp.h b/lib/librte_net/rte_arp.h
index ccb6875cf..fabd68624 100644
--- a/lib/librte_net/rte_arp.h
+++ b/lib/librte_net/rte_arp.h
@@ -26,7 +26,7 @@ struct rte_arp_ipv4 {
uint32_t arp_sip; /**< sender IP address */
struct rte_ether_addr arp_tha; /**< target hardware address */
uint32_t arp_tip; /**< target IP address */
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
/**
* ARP header.
@@ -47,7 +47,7 @@ struct rte_arp_hdr {
#define RTE_ARP_OP_INVREPLY 9 /* response identifying peer */
struct rte_arp_ipv4 arp_data;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
/**
* @warning
diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
index aa6eff037..5b81a7a96 100644
--- a/lib/librte_net/rte_ether.h
+++ b/lib/librte_net/rte_ether.h
@@ -59,7 +59,7 @@ extern "C" {
*/
struct rte_ether_addr {
uint8_t addr_bytes[RTE_ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
-} __attribute__((__packed__));
+} __attribute__((aligned(2)));
#define RTE_ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
#define RTE_ETHER_GROUP_ADDR 0x01 /**< Multicast or broadcast Eth. address. */
@@ -81,8 +81,8 @@ struct rte_ether_addr {
static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
const struct rte_ether_addr *ea2)
{
- const unaligned_uint16_t *w1 = (const uint16_t *)ea1;
- const unaligned_uint16_t *w2 = (const uint16_t *)ea2;
+ const uint16_t *w1 = (const uint16_t *)ea1;
+ const uint16_t *w2 = (const uint16_t *)ea2;
return ((w1[0] ^ w2[0]) | (w1[1] ^ w2[1]) | (w1[2] ^ w2[2])) == 0;
}
@@ -99,7 +99,7 @@ static inline int rte_is_same_ether_addr(const struct rte_ether_addr *ea1,
*/
static inline int rte_is_zero_ether_addr(const struct rte_ether_addr *ea)
{
- const unaligned_uint16_t *w = (const uint16_t *)ea;
+ const uint16_t *w = (const uint16_t *)ea;
return (w[0] | w[1] | w[2]) == 0;
}
@@ -146,7 +146,7 @@ static inline int rte_is_multicast_ether_addr(const struct rte_ether_addr *ea)
*/
static inline int rte_is_broadcast_ether_addr(const struct rte_ether_addr *ea)
{
- const unaligned_uint16_t *ea_words = (const unaligned_uint16_t *)ea;
+ const uint16_t *ea_words = (const uint16_t *)ea;
return (ea_words[0] == 0xFFFF && ea_words[1] == 0xFFFF &&
ea_words[2] == 0xFFFF);
@@ -273,7 +273,7 @@ struct rte_ether_hdr {
struct rte_ether_addr d_addr; /**< Destination address. */
struct rte_ether_addr s_addr; /**< Source address. */
uint16_t ether_type; /**< Frame type. */
-} __attribute__((__packed__));
+} __attribute__((aligned(2)));
/**
* Ethernet VLAN Header.
diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c
index 47d7efbc1..962404b7a 100644
--- a/lib/librte_pipeline/rte_table_action.c
+++ b/lib/librte_pipeline/rte_table_action.c
@@ -438,7 +438,7 @@ encap_cfg_check(struct rte_table_action_encap_config *encap)
struct encap_ether_data {
struct rte_ether_hdr ether;
-} __attribute__((__packed__));
+};
#define VLAN(pcp, dei, vid) \
((uint16_t)((((uint64_t)(pcp)) & 0x7LLU) << 13) | \
@@ -448,13 +448,13 @@ struct encap_ether_data {
struct encap_vlan_data {
struct rte_ether_hdr ether;
struct rte_vlan_hdr vlan;
-} __attribute__((__packed__));
+};
struct encap_qinq_data {
struct rte_ether_hdr ether;
struct rte_vlan_hdr svlan;
struct rte_vlan_hdr cvlan;
-} __attribute__((__packed__));
+};
#define ETHER_TYPE_MPLS_UNICAST 0x8847
@@ -470,7 +470,7 @@ struct encap_mpls_data {
struct rte_ether_hdr ether;
uint32_t mpls[RTE_TABLE_ACTION_MPLS_LABELS_MAX];
uint32_t mpls_count;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
#define PPP_PROTOCOL_IP 0x0021
@@ -479,12 +479,12 @@ struct pppoe_ppp_hdr {
uint16_t session_id;
uint16_t length;
uint16_t protocol;
-} __attribute__((__packed__));
+};
struct encap_pppoe_data {
struct rte_ether_hdr ether;
struct pppoe_ppp_hdr pppoe_ppp;
-} __attribute__((__packed__));
+};
#define IP_PROTO_UDP 17
@@ -493,7 +493,7 @@ struct encap_vxlan_ipv4_data {
struct rte_ipv4_hdr ipv4;
struct rte_udp_hdr udp;
struct rte_vxlan_hdr vxlan;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct encap_vxlan_ipv4_vlan_data {
struct rte_ether_hdr ether;
@@ -501,14 +501,14 @@ struct encap_vxlan_ipv4_vlan_data {
struct rte_ipv4_hdr ipv4;
struct rte_udp_hdr udp;
struct rte_vxlan_hdr vxlan;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct encap_vxlan_ipv6_data {
struct rte_ether_hdr ether;
struct rte_ipv6_hdr ipv6;
struct rte_udp_hdr udp;
struct rte_vxlan_hdr vxlan;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct encap_vxlan_ipv6_vlan_data {
struct rte_ether_hdr ether;
@@ -516,14 +516,14 @@ struct encap_vxlan_ipv6_vlan_data {
struct rte_ipv6_hdr ipv6;
struct rte_udp_hdr udp;
struct rte_vxlan_hdr vxlan;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
struct encap_qinq_pppoe_data {
struct rte_ether_hdr ether;
struct rte_vlan_hdr svlan;
struct rte_vlan_hdr cvlan;
struct pppoe_ppp_hdr pppoe_ppp;
-} __attribute__((__packed__));
+} __attribute__((__packed__)) __attribute__((aligned(2)));
static size_t
encap_data_size(struct rte_table_action_encap_config *encap)
--
2.21.0
^ permalink raw reply [relevance 4%]
* [dpdk-dev] DPDK Release Status Meeting 10/10/2019
@ 2019-10-10 10:06 4% Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-10 10:06 UTC (permalink / raw)
To: dpdk-dev; +Cc: Thomas Monjalon
Minutes 10 October 2019
-----------------------
Agenda:
* Release Dates
* Subtrees
* OvS
* Opens
Participants:
* Arm
* Debian/Microsoft
* Intel
* Mellanox
* NXP
* Red Hat
Release Dates
-------------
* v19.11 dates:
* Integration/Merge/RC1 Wednesday 23 October
* For sub-trees Monday 21 October
* Release Friday 22 November
* Proposed dates for 20.02 release on the mail list, please comment
https://mails.dpdk.org/archives/dev/2019-September/143311.html
These dates may affected from the 19.11 delays, please review again.
Subtrees
--------
* main
* Middle of pulling from sub-trees
* Will merge patches for main tree
* David pushed some patches and will have more
* David's main focus is ABI related patchset
* ABI check scripts will send another version soon
* next-net
* ~100 patches in backlog, can make rc1 dates, nothing critical
* Should get ethdev API and rte_flow patches for rc1, need more review
* Not all testpmd maintainers are active
* next-net-crypto
* Waiting for new version for new 'octeontx2' PMD
* ipsec patches under review, planning to merge soon
* More review requested on outstanding patch:
http://patches.dpdk.org/project/dpdk/list/?series=6727
* next-net-eventdev
* Pull request has been sent
* next-net-virtio
* Currently working on features
* Reviewing vhost packed ring performance optimization patches
* LTS
* v18.11.3-rc2 created
* More test from more companies is welcome
* Target release date is end of next week
OvS
---
* Testing 18.11.3-rc2
* For TSO support, DPDK patch has been sent, review going on
* https://patches.dpdk.org/patch/60373/
* OvS conference Call For Papers has closed.
https://www.eventbrite.com/e/ovsovn-19-conference-tickets-71912766019
Open
----
* Can rotate the meeting time for all time zones coverage, there wasn't enough
feedback, will discuss later.
DPDK Release Status Meetings
============================
The DPDK Release Status Meeting is intended for DPDK Committers to discuss
the status of the master tree and sub-trees, and for project managers to
track progress or milestone dates.
The meeting occurs on Thursdays at 8:30 UTC. If you wish to attend just
send an email to "John McNamara <john.mcnamara@intel.com>" for the invite.
^ permalink raw reply [relevance 4%]
* [dpdk-dev] DPDK techboard minutes of October 9
@ 2019-10-10 7:35 4% Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2019-10-10 7:35 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dpdk-techboard, Honnappa Nagarahalli, Kevin Traynor, dpdk-dev,
Kadam, Pallavi, Ranjit Menon
Meeting notes for the DPDK technical board meeting held on 2018-10-09
Attendees:
- Bruce Richardson
- Ferruh Yigit
- Konstantin Ananyev
- Maxime Coquelin
- Olivier Matz
- Stephen Hemminger
- Thomas Monjalon
1) extend techboard membership
- "Honnappa Nagarahalli" and "Kevin Traynor" has been accepted to the
DPDK technical board membership, welcome both!
- Technical board now has 11 members, quorum is 8, voting pass is 6.
- Decided to limit the technical board size to 11 members.
2) security pre-release disclosure list subscription
- Both requested companies are accepted to the list.
3) license exception for Windows DPDK
- Ranjit and Pallavi will prepare more detailed report and will share offline
via email about which files (with different license) are required, where any
why they are required.
- Topic will be discussed again in next technical board meeting with the help of
the provided data.
4) ABI change without depreciation notice in advance
- Specific to 19.11, because of the new ABI/API policy, reasonable ABI/API
breakage will be accepted without deprecation notice, but they will have
to be documented in release notes.
5) Next meeting will be on October 23 and Hemant will chair it
Thanks,
ferruh
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 0/2] Improve function versioning meson support
2019-10-07 15:45 3% ` [dpdk-dev] [PATCH v3 0/2] Improve function versioning meson support Bruce Richardson
@ 2019-10-09 22:59 0% ` Stephen Hemminger
2 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-09 22:59 UTC (permalink / raw)
To: Bruce Richardson
Cc: dev, Andrzej Ostruszka, Thomas Monjalon, Ray Kinsella, Neil Horman
On Fri, 27 Sep 2019 20:49:30 +0100
Bruce Richardson <bruce.richardson@intel.com> wrote:
> Adding support for LTO has exposed some issues with how the functions
> versioning was supported by meson, which was always set to build both
> shared and static libraries.
>
> For plain C code, so long as the -fPIC compiler flag was passed, the
> output is identical whether or not the code is to be included in a
> static library or a dynamic one. Unfortunately, when using function
> versioning that no longer held as different macros were used for the
> versioned functions depending on which type of build it was. This means
> that any files that use versioning need to be built twice, with
> different defines in each case.
>
> While the trivial solution here is just to rebuild everything twice,
> that involves a lot of unnecessary work when building DPDK. A better
> option is to identify those files or components which need multiple
> builds and rebuild only those. To do this, we add a new meson.build
> setting for libraries "use_function_versioning" and when that is set, we
> rebuild all source files twice, initially for static library and then
> with -DRTE_BUILD_SHARED_LIB for the shared library.
>
> If the flag is not set, then the static versioning setting only is used,
> which could lead to the build succeeding but later causing problems. To
> avoid that, we add a new define which must be set when the versioning
> header is included. This addition while solving 1 problem raises 2
> other, more minor problems:
> * what to do with make builds? since make only builds one library type,
> we can just always define the new value.
> * what about files that include rte_compat.h for the macro for
> "experimental"? To solve this, we can split compat.h in two, since the
> versioning macro should be internal only to DPDK (as no public header
> should expose anything but the latest APIs), while the experimental
> macros are primarily for public use.
>
> Bruce Richardson (2):
> eal: split compat header file
> build: support building ABI versioned files twice
>
> config/common_base | 1 +
> config/rte_config.h | 3 ---
> doc/api/doxy-api-index.md | 3 ++-
> doc/guides/contributing/coding_style.rst | 7 ++++++
> doc/guides/contributing/versioning.rst | 4 ++--
> lib/librte_distributor/meson.build | 1 +
> lib/librte_distributor/rte_distributor.c | 2 +-
> lib/librte_distributor/rte_distributor_v20.c | 2 +-
> lib/librte_eal/common/Makefile | 1 +
> ...rte_compat.h => rte_function_versioning.h} | 23 ++++++-------------
> lib/librte_lpm/meson.build | 1 +
> lib/librte_lpm/rte_lpm.c | 1 +
> lib/librte_lpm/rte_lpm.h | 1 -
> lib/librte_lpm/rte_lpm6.c | 1 +
> lib/librte_timer/meson.build | 1 +
> lib/librte_timer/rte_timer.c | 2 +-
> lib/meson.build | 16 ++++++++++---
> 17 files changed, 41 insertions(+), 29 deletions(-)
> rename lib/librte_eal/common/include/{rte_compat.h => rte_function_versioning.h} (89%)
>
Looks fine.
Acked-by: Stephen Hemminger <stephen@networkplumber.org>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-09 7:20 0% ` Akhil Goyal
@ 2019-10-09 13:43 0% ` Ananyev, Konstantin
2019-10-11 13:23 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-09 13:43 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan
Cc: Doherty, Declan, 'Anoob Joseph'
Hi Akhil,
> > > > > > > > > > > > > > > > > This action type allows the burst of symmetric crypto
> > > > > > workload
> > > > > > > > using
> > > > > > > > > > > the
> > > > > > > > > > > > > > > same
> > > > > > > > > > > > > > > > > algorithm, key, and direction being processed by CPU
> > > > cycles
> > > > > > > > > > > > > synchronously.
> > > > > > > > > > > > > > > > > This flexible action type does not require external
> > > > hardware
> > > > > > > > > > > involvement,
> > > > > > > > > > > > > > > > > having the crypto workload processed synchronously,
> > > > and is
> > > > > > > > more
> > > > > > > > > > > > > > > performant
> > > > > > > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on
> > > > removed
> > > > > > > > "async
> > > > > > > > > > > > > mode
> > > > > > > > > > > > > > > > > simulation" as well as 3 cacheline access of the
> > crypto
> > > > ops.
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > Does that mean application will not call the
> > > > > > > > cryptodev_enqueue_burst
> > > > > > > > > > > and
> > > > > > > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Yes, instead it just call
> > > > rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > It would be a new API something like process_packets
> > and
> > > > it
> > > > > > will
> > > > > > > > have
> > > > > > > > > > > the
> > > > > > > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Yes, though the plan is that API will operate on raw data
> > > > buffers,
> > > > > > > > not
> > > > > > > > > > > mbufs.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > > I still do not understand why we cannot do with the
> > > > > > conventional
> > > > > > > > > > > crypto lib
> > > > > > > > > > > > > > > only.
> > > > > > > > > > > > > > > > As far as I can understand, you are not doing any
> > protocol
> > > > > > > > processing
> > > > > > > > > > > or
> > > > > > > > > > > > > any
> > > > > > > > > > > > > > > value add
> > > > > > > > > > > > > > > > To the crypto processing. IMO, you just need a
> > > > synchronous
> > > > > > > > crypto
> > > > > > > > > > > > > processing
> > > > > > > > > > > > > > > API which
> > > > > > > > > > > > > > > > Can be defined in cryptodev, you don't need to re-
> > create a
> > > > > > crypto
> > > > > > > > > > > session
> > > > > > > > > > > > > in
> > > > > > > > > > > > > > > the name of
> > > > > > > > > > > > > > > > Security session in the driver just to do a synchronous
> > > > > > processing.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > > > > > > The main reason is that would require disruptive changes
> > in
> > > > > > existing
> > > > > > > > > > > > > cryptodev
> > > > > > > > > > > > > > > API
> > > > > > > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > > need
> > > > > > > > some
> > > > > > > > > > > extra
> > > > > > > > > > > > > > > information
> > > > > > > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > > > > > > (cipher offset from the start of the buffer, might be
> > > > something
> > > > > > extra
> > > > > > > > in
> > > > > > > > > > > > > future).
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > > > > > > >
> > > > > > > > > > > > > fill/read (+ alloc/free) is one of the main things that
> > slowdown
> > > > > > current
> > > > > > > > > > > crypto-op
> > > > > > > > > > > > > approach.
> > > > > > > > > > > > > That's why the general idea - have all data that wouldn't
> > change
> > > > > > from
> > > > > > > > packet
> > > > > > > > > > > to
> > > > > > > > > > > > > packet
> > > > > > > > > > > > > included into the session and setup it once at session_init().
> > > > > > > > > > > >
> > > > > > > > > > > > I agree that you cannot use crypto-op.
> > > > > > > > > > > > You can have the new API in crypto.
> > > > > > > > > > > > As per the current patch, you only need cipher_offset which
> > you
> > > > can
> > > > > > have
> > > > > > > > it as
> > > > > > > > > > > a parameter until
> > > > > > > > > > > > You get it approved in the crypto xform. I believe it will be
> > > > beneficial
> > > > > > in
> > > > > > > > case of
> > > > > > > > > > > other crypto cases as well.
> > > > > > > > > > > > We can have cipher offset at both places(crypto-op and
> > > > > > cipher_xform). It
> > > > > > > > will
> > > > > > > > > > > give flexibility to the user to
> > > > > > > > > > > > override it.
> > > > > > > > > > >
> > > > > > > > > > > After having another thought on your proposal:
> > > > > > > > > > > Probably we can introduce new rte_crypto_sym_xform_types
> > for
> > > > CPU
> > > > > > > > related
> > > > > > > > > > > stuff here?
> > > > > > > > > >
> > > > > > > > > > I also thought of adding new xforms, but that wont serve the
> > purpose
> > > > for
> > > > > > > > may be all the cases.
> > > > > > > > > > You would be needing all information currently available in the
> > > > current
> > > > > > > > xforms.
> > > > > > > > > > So if you are adding new fields in the new xform, the size will be
> > more
> > > > > > than
> > > > > > > > that of the union of xforms.
> > > > > > > > > > ABI breakage would still be there.
> > > > > > > > > >
> > > > > > > > > > If you think a valid compression of the AEAD xform can be done,
> > then
> > > > > > that
> > > > > > > > can be done for each of the
> > > > > > > > > > Xforms and we can have a solution to this issue.
> > > > > > > > >
> > > > > > > > > I think that we can re-use iv.offset for our purposes (for crypto
> > offset).
> > > > > > > > > So for now we can make that path work without any ABI breakage.
> > > > > > > > > Fan, please feel free to correct me here, if I missed something.
> > > > > > > > > If in future we would need to add some extra information it might
> > > > > > > > > require ABI breakage, though by now I don't envision anything
> > > > particular to
> > > > > > > > add.
> > > > > > > > > Anyway, if there is no objection to go that way, we can try to make
> > > > > > > > > these changes for v2.
> > > > > > > > >
> > > > > > > >
> > > > > > > > Actually, after looking at it more deeply it appears not that easy as I
> > > > thought
> > > > > > it
> > > > > > > > would be :)
> > > > > > > > Below is a very draft version of proposed API additions.
> > > > > > > > I think it avoids ABI breakages right now and provides enough
> > flexibility
> > > > for
> > > > > > > > future extensions (if any).
> > > > > > > > For now, it doesn't address your comments about naming
> > conventions
> > > > > > (_CPU_
> > > > > > > > vs _SYNC_) , etc.
> > > > > > > > but I suppose is comprehensive enough to provide a main idea
> > beyond it.
> > > > > > > > Akhil and other interested parties, please try to review and provide
> > > > feedback
> > > > > > > > ASAP,
> > > > > > > > as related changes would take some time and we still like to hit 19.11
> > > > > > deadline.
> > > > > > > > Konstantin
> > > > > > > >
> > > > > > > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > > index bc8da2466..c03069e23 100644
> > > > > > > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > > > > > > *
> > > > > > > > * This structure contains data relating to Cipher (Encryption and
> > > > Decryption)
> > > > > > > > * use to create a session.
> > > > > > > > + * Actually I was wrong saying that we don't have free space inside
> > > > xforms.
> > > > > > > > + * Making key struct packed (see below) allow us to regain 6B that
> > could
> > > > be
> > > > > > > > + * used for future extensions.
> > > > > > > > */
> > > > > > > > struct rte_crypto_cipher_xform {
> > > > > > > > enum rte_crypto_cipher_operation op;
> > > > > > > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > > > > > > struct {
> > > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > > - } key;
> > > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > > +
> > > > > > > > + /**
> > > > > > > > + * offset for cipher to start within user provided data buffer.
> > > > > > > > + * Fan suggested another (and less space consuming way) -
> > > > > > > > + * reuse iv.offset space below, by changing:
> > > > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > > > + * to uunamed union:
> > > > > > > > + * union {
> > > > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > > > > > > + * };
> > > > > > > > + * Both approaches seems ok to me in general.
> > > > > > >
> > > > > > > No strong opinions here. OK with this one.
> > > > > > >
> > > > > > > > + * Comments/suggestions are welcome.
> > > > > > > > + */
> > > > > > > > + uint16_t offset;
> > > > > >
> > > > > > After another thought - it is probably a bit better to have offset as a
> > separate
> > > > > > field.
> > > > > > In that case we can use the same xforms to create both type of sessions.
> > > > > ok
> > > > > >
> > > > > > > > +
> > > > > > > > + uint8_t reserved1[4];
> > > > > > > > +
> > > > > > > > /**< Cipher key
> > > > > > > > *
> > > > > > > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation,
> > > > key.data
> > > > > > will
> > > > > > > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > > > > > > struct {
> > > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > > - } key;
> > > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > > /**< Authentication key data.
> > > > > > > > * The authentication key length MUST be less than or equal to
> > the
> > > > > > > > * block size of the algorithm. It is the callers responsibility to
> > > > > > > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > > > > > > * (for example RFC 2104, FIPS 198a).
> > > > > > > > */
> > > > > > > >
> > > > > > > > + uint8_t reserved1[6];
> > > > > > > > +
> > > > > > > > struct {
> > > > > > > > uint16_t offset;
> > > > > > > > /**< Starting point for Initialisation Vector or Counter,
> > > > > > > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > > > > > > struct {
> > > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > > - } key;
> > > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > > +
> > > > > > > > + /** offset for cipher to start within data buffer */
> > > > > > > > + uint16_t cipher_offset;
> > > > > > > > +
> > > > > > > > + uint8_t reserved1[4];
> > > > > > > >
> > > > > > > > struct {
> > > > > > > > uint16_t offset;
> > > > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > > index e175b838c..c0c7bfed7 100644
> > > > > > > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > > @@ -1272,6 +1272,101 @@ void *
> > > > > > > > rte_cryptodev_sym_session_get_user_data(
> > > > > > > > struct rte_cryptodev_sym_session *sess);
> > > > > > > >
> > > > > > > > +/*
> > > > > > > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > > > > > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > > > > > > + * introduce an extentsion to it via new fully opaque
> > > > > > > > + * struct rte_crypto_cpu_sym_session and additional related API.
> > > > > > >
> > > > > > >
> > > > > > > What all things do we need to squeeze?
> > > > > > > In this proposal I do not see the new struct cpu_sym_session defined
> > here.
> > > > > >
> > > > > > The plan is to have it totally opaque to the user, i.e. just:
> > > > > > struct rte_crypto_cpu_sym_session;
> > > > > > in public header files.
> > > > > >
> > > > > > > I believe you will have same lib API/struct for cpu_sym_session and
> > > > > > sym_session.
> > > > > >
> > > > > > I thought about such way, but there are few things that looks clumsy to
> > me:
> > > > > > 1. Right now there is no 'type' (or so) field inside
> > rte_cryptodev_sym_session,
> > > > > > so it is not possible to easy distinguish what session do you have:
> > lksd_sym or
> > > > > > cpu_sym.
> > > > > > In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we
> > can
> > > > add
> > > > > > some extra field
> > > > > > here, but in that case we wouldn't be able to use the same xform for
> > both
> > > > > > lksd_sym or cpu_sym
> > > > > > (which seems really plausible thing for me).
> > > > > > 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary
> > for
> > > > > > rte_crypto_cpu_sym_session:
> > > > > > sess_data[], opaque_data, user_data, nb_drivers.
> > > > > > All that consumes space, that could be used somewhere else instead.
> > > > > > 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> > > > > > breakages I can't foresee right now.
> > > > > > From other side - if we'll add new functions/structs for cpu_sym_session
> > we
> > > > can
> > > > > > mark it
> > > > > > and keep it for some time as experimental, so further changes (if needed)
> > > > would
> > > > > > still be possible.
> > > > > >
> > > > >
> > > > > OK let us assume that you have a separate structure. But I have a few
> > queries:
> > > > > 1. how can multiple drivers use a same session
> > > >
> > > > As a short answer: they can't.
> > > > It is pretty much the same approach as with rte_security - each device needs
> > to
> > > > create/init its own session.
> > > > So upper layer would need to maintain its own array (or so) for such case.
> > > > Though the question is why would you like to have same session over
> > multiple
> > > > SW backed devices?
> > > > As it would be anyway just a synchronous function call that will be executed
> > on
> > > > the same cpu.
> > >
> > > I may have single FAT tunnel which may be distributed over multiple
> > > Cores, and each core is affined to a different SW device.
> >
> > If it is pure SW, then we don't need multiple devices for such scenario.
> > Device in that case is pure abstraction that we can skip.
>
> Yes agreed, but that liberty is given to the application whether it need multiple
> devices with single queue or a single device with multiple queues.
> I think that independence should not be broken in this new API.
> >
> > > So a single session may be accessed by multiple devices.
> > >
> > > One more example would be depending on packet sizes, I may switch between
> > > HW/SW PMDs with the same session.
> >
> > Sure, but then we'll have multiple sessions.
>
> No, the session will be same and it will have multiple private data for each of the PMD.
>
> > BTW, we have same thing now - these private session pointers are just stored
> > inside the same rte_crypto_sym_session.
> > And if user wants to support this model, he would also need to store <dev_id,
> > queue_id>
> > pair for each HW device anyway.
>
> Yes agreed, but how is that thing happening in your new struct, you cannot support that.
User can store all these info in his own struct.
That's exactly what we have right now.
Let say ipsec-secgw has to store for each IPsec SA:
pointer to crypto-session and/or pointer to security session
plus (for lookaside-devices) cdev_id_qp that allows it to extract
dev_id + queue_id information.
As I understand that works for now, as each ipsec_sa uses only one
dev+queue. Though if someone would like to use multiple devices/queues
for the same SA - he would need to have an array of these <dev+queue> pairs.
So even right now rte_cryptodev_sym_session is not self-consistent and
requires extra information to be maintained by user.
>
> >
> > >
> > > >
> > > > > 2. Can somebody use the scheduler pmd for scheduling the different type
> > of
> > > > payloads for the same session?
> > > >
> > > > In theory yes.
> > > > Though for that scheduler pmd should have inside it's
> > > > rte_crypto_cpu_sym_session an array of pointers to
> > > > the underlying devices sessions.
> > > >
> > > > >
> > > > > With your proposal the APIs would be very specific to your use case only.
> > > >
> > > > Yes in some way.
> > > > I consider that API specific for SW backed crypto PMDs.
> > > > I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will benefit
> > > > from it.
> > > > Current crypto-op API is very much HW oriented.
> > > > Which is ok, that's for it was intended for, but I think we also need one that
> > > > would be designed
> > > > for SW backed implementation in mind.
> > >
> > > We may re-use your API for HW PMDs as well which do not have requirement
> > of
> > > Crypto-op/mbuf etc.
> > > The return type of your new process API may have a status which say
> > 'processed'
> > > Or can be say 'enqueued'. So if it is 'enqueued', we may have a new API for
> > raw
> > > Bufs dequeue as well.
> > >
> > > This requirement can be for any hardware PMDs like QAT as well.
> >
> > I don't think it is a good idea to extend this API for async (lookaside) devices.
> > You'll need to:
> > - provide dev_id and queue_id for each process(enqueue) and dequeuer
> > operation.
> > - provide IOVA for all buffers passing to that function (data buffers, digest, IV,
> > aad).
> > - On dequeue provide some way to associate dequed data and digest buffers
> > with
> > crypto-session that was used (and probably with mbuf).
> > So most likely we'll end up with another just version of our current crypto-op
> > structure.
> > If you'd like to get rid of mbufs dependency within current crypto-op API that
> > understandable,
> > but I don't think we should have same API for both sync (CPU) and async
> > (lookaside) cases.
> > It doesn't seem feasible at all and voids whole purpose of that patch.
>
> At this moment we are not much concerned about the dequeue API and about the
> HW PMD support. It is just that the new API should be generic enough to be used in
> some future scenarios as well. I am just highlighting the possible usecases which can
> be there in future.
Sorry, but I strongly disagree with such approach.
We should stop adding/modifying API 'just in case' and because 'it might be useful for some future HW'.
Inside DPDK we already do have too many dev level APIs without any implementations.
That's quite bad practice and very dis-orienting for end-users.
I think to justify API additions/changes we need at least one proper implementation for it,
or at least some strong evidence that people are really committed to support it in nearest future.
BTW, that what TB agreed on, nearly a year ago.
This new API (if we'll go ahead with it of course) would stay experimental for some time anyway
to make sure we don't miss anything needed (I think for about a year time-frame).
So if you guys *really* want to extend it support _async_ devices too -
I am open for modifications/additions here.
Though personally I think such addition would over-complicate things and we'll end up with
another reincarnation of current crypto-op.
We actually discussed it internally, and decided to drop that idea because of that.
Again, my opinion - for lookaside devices it might be better to try to optimize
current crypto-op path (remove mbuf requirement, probably add ability to
group by session on enqueue/dequeue, etc.).
>
> What is the issue that you face in making a dev-op for this new API. Do you see any
> performance impact with that?
There are two main things:
1. user would need to maintain and provide for each process() call dev_id+queue_id.
That's means extra (and totally unnecessary for SW) overhead.
2. yes I would expect some perf overhead too - it would be extra call or branch.
Again as it would be data-dependency - most likely cpu wouldn't be able to pipeline
it efficiently:
rte_crypto_sym_process(uint8_t dev_id, uint16 qp_id, rte_crypto_sym_session *ses, ...)
{
struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
return (*dev->process)(sess->data[dev->driver_id, ...);
}
driver_specific_process(driver_specific_sym_session *sess)
{
return sess->process(sess, ...) ;
}
I didn't make any exact measurements but sure it would be slower than just:
session_udata->process(session->udata->sess, ...);
Again it would be much more noticeable on low end cpus.
Let say here: http://mails.dpdk.org/archives/dev/2019-September/144350.html
Jerin claims 1.5-3% drop for introducing extra call via hiding eth_dev contents -
I suppose we would have something similar here.
I do realize that in majority of cases crypto is more expensive then RX/TX, but still.
If it would be a really unavoidable tradeoff (support already existing API, or so)
I wouldn't mind, but I don't see any real need for it right now.
>
> >
> > > That is why a dev-ops would be a better option.
> > >
> > > >
> > > > > When you would add more functionality to this sync API/struct, it will end
> > up
> > > > being the same API/struct.
> > > > >
> > > > > Let us see how close/ far we are from the existing APIs when the actual
> > > > implementation is done.
> > > > >
> > > > > > > I am not sure if that would be needed.
> > > > > > > It would be internal to the driver that if synchronous processing is
> > > > > > supported(from feature flag) and
> > > > > > > Have relevant fields in xform(the newly added ones which are packed
> > as
> > > > per
> > > > > > your suggestions) set,
> > > > > > > It will create that type of session.
> > > > > > >
> > > > > > >
> > > > > > > > + * Main points:
> > > > > > > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > > > > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > > > > > + * new sync API is new one and probably would require extra
> > changes.
> > > > > > > > + * Having it as a new one allows to mark it as experimental, without
> > > > > > > > + * affecting existing one.
> > > > > > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > > > > > + * to the PMD writers and again allows to avoid ABI breakages in
> > future.
> > > > > > > > + * - process() function per set of xforms
> > > > > > > > + * allows to expose different process() functions for different
> > > > > > > > + * xform combinations. PMD writer can decide, does he wants to
> > > > > > > > + * push all supported algorithms into one process() function,
> > > > > > > > + * or spread it across several ones.
> > > > > > > > + * I.E. More flexibility for PMD writer.
> > > > > > >
> > > > > > > Which process function should be chosen is internal to PMD, how
> > would
> > > > that
> > > > > > info
> > > > > > > be visible to the application or the library. These will get stored in the
> > > > session
> > > > > > private
> > > > > > > data. It would be upto the PMD writer, to store the per session process
> > > > > > function in
> > > > > > > the session private data.
> > > > > > >
> > > > > > > Process function would be a dev ops just like enc/deq operations and it
> > > > should
> > > > > > call
> > > > > > > The respective process API stored in the session private data.
> > > > > >
> > > > > > That model (via devops) is possible, but has several drawbacks from my
> > > > > > perspective:
> > > > > >
> > > > > > 1. It means we'll need to pass dev_id as a parameter to process() function.
> > > > > > Though in fact dev_id is not a relevant information for us here
> > > > > > (all we need is pointer to the session and pointer to the fuction to call)
> > > > > > and I tried to avoid using it in data-path functions for that API.
> > > > >
> > > > > You have a single vdev, but someone may have multiple vdevs for each
> > thread,
> > > > or may
> > > > > Have same dev with multiple queues for each core.
> > > >
> > > > That's fine. As I said above it is a SW backed implementation.
> > > > Each session has to be a separate entity that contains all necessary
> > information
> > > > (keys, alg/mode info, etc.) to process input buffers.
> > > > Plus we need the actual function pointer to call.
> > > > I just don't see what for we need a dev_id in that situation.
> > >
> > > To iterate the session private data in the session.
> > >
> > > > Again, here we don't need care about queues and their pinning to cores.
> > > > If let say someone would like to process buffers from the same IPsec SA on 2
> > > > different cores in parallel, he can just create 2 sessions for the same xform,
> > > > give one to thread #1 and second to thread #2.
> > > > After that both threads are free to call process(this_thread_ses, ...) at will.
> > >
> > > Say you have a 16core device to handle 100G of traffic on a single tunnel.
> > > Will we make 16 sessions with same parameters?
> >
> > Absolutely same question we can ask for current crypto-op API.
> > You have lookaside crypto-dev with 16 HW queues, each queue is serviced by
> > different CPU.
> > For the same SA, do you need a separate session per queue, or is it ok to reuse
> > current one?
> > AFAIK, right now this is a grey area not clearly defined.
> > For crypto-devs I am aware - user can reuse the same session (as PMD uses it
> > read-only).
> > But again, right now I think it is not clearly defined and is implementation
> > specific.
>
> User can use the same session, that is what I am also insisting, but it may have separate
> Session private data. Cryptodev session create API provide that functionality and we can
> Leverage that.
rte_cryptodev_sym_session. sess_data[] is indexed by driver_id, which means we can't use
the same rte_cryptodev_sym_session to hold sessions for both sync and async mode
for the same device. Off course we can add a hard requirement that any driver that wants to
support process() has to create sessions that can handle both process and enqueue/dequeue,
but then again what for to create such overhead?
BTW, to be honest, I don't consider current rte_cryptodev_sym_session construct for multiple device_ids:
__extension__ struct {
void *data;
uint16_t refcnt;
} sess_data[0];
/**< Driver specific session material, variable size */
as an advantage.
It looks too error prone for me:
1. Simultaneous session initialization/de-initialization for devices with the same driver_id is not possible.
2. It assumes that all device driver will be loaded before we start to create session pools.
Right now it seems ok, as no-one requires such functionality, but I don't know how it will be in future.
For me rte_security session model, where for each security context user have to create new session
looks much more robust.
>
> BTW, I can see a v2 to this RFC which is still based on security library.
Yes, v2 was concentrated on fixing found issues, some code restructuring,
i.e. - changes that would be needed anyway whatever API aproach we'll choose.
> When do you plan
> To submit the patches for crypto based APIs. We have RC1 merge deadline for this
> patchset on 21st Oct.
We'd like to start working on it ASAP, but it seems we still have a major disagreement
about how this crypto-dev API should look like.
Which makes me think - should we return to our original proposal via rte_security?
It still looks to me like clean and straightforward way to enable this new API,
and probably wouldn't cause that much controversy.
What do you think?
>
> As per my understanding you only need a new dev-op for sync support. Session APIs
> Will remain the same and you will have some extra fields packed in xform structs.
>
> The PMD will need to maintain a pointer to the per session process function while creating
> Session and will be used by the dev-op API at runtime without any extra check at runtime.
>
> >
> > >
> > > >
> > > > >
> > > > > > 2. As you pointed in that case it will be just one process() function per
> > device.
> > > > > > So if PMD would like to have several process() functions for different type
> > of
> > > > > > sessions
> > > > > > (let say one per alg) first thing it has to do inside it's process() - read
> > session
> > > > data
> > > > > > and
> > > > > > based on that, do a jump/call to particular internal sub-routine.
> > > > > > Something like:
> > > > > > driver_id = get_pmd_driver_id();
> > > > > > priv_ses = ses->sess_data[driver_id];
> > > > > > Then either:
> > > > > > switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> > > > > > OR
> > > > > > priv_ses->process(priv_sess, ...);
> > > > > >
> > > > > > to select and call the proper function.
> > > > > > Looks like totally unnecessary overhead to me.
> > > > > > Though if we'll have ability to query/extract some sort session_ops based
> > on
> > > > the
> > > > > > xform -
> > > > > > we can avoid this extra de-refererence+jump/call thing.
> > > > >
> > > > > What is the issue in the priv_ses->process(); approach?
> > > >
> > > > Nothing at all.
> > > > What I am saying that schema with dev_ops
> > > > dev[dev_id]->dev_ops.process(ses->priv_ses[driver_id], ...)
> > > > |
> > > > |-> priv_ses->process(...)
> > > >
> > > > Has bigger overhead then just:
> > > > process(ses,...);
> > > >
> > > > So what for to introduce extra-level of indirection here?
> > >
> > > Explained above.
> > >
> > > >
> > > > > I don't understand what are you saving by not doing this.
> > > > > In any case you would need to identify which session correspond to which
> > > > process().
> > > >
> > > > Yes, sure, but I think we can make user to store information that relationship,
> > > > in a way he likes: store process() pointer for each session, or group sessions
> > > > that share the same process() somehow, or...
> > >
> > > So whatever relationship that user will make and store will make its life
> > complicated.
> > > If we can hide that information in the driver, then what is the issue in that and
> > user
> > > Will not need to worry. He would just call the process() and driver will choose
> > which
> > > Process need to be called.
> >
> > Driver can do that at config/init time.
> > Then at run-time we can avoid that choice at all and call already chosen function.
> >
> > >
> > > I think we should have a POC around this and see the difference in the cycle
> > count.
> > > IMO it would be negligible and we would end up making a generic API set
> > which
> > > can be used by others as well.
> > >
> > > >
> > > > > For that you would be doing it somewhere in your data path.
> > > >
> > > > Why at data-path?
> > > > Only once at session creation/initialization time.
> > > > Or might be even once per group of sessions.
> > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > > I am not sure if you would need a new session init API for this as
> > nothing
> > > > would
> > > > > > be visible to
> > > > > > > the app or lib.
> > > > > > >
> > > > > > > > + * - Not storing process() pointer inside the session -
> > > > > > > > + * Allows user to choose does he want to store a process() pointer
> > > > > > > > + * per session, or per group of sessions for that device that share
> > > > > > > > + * the same input xforms. I.E. extra flexibility for the user,
> > > > > > > > + * plus allows us to keep cpu_sym_session totally opaque, see
> > above.
> > > > > > >
> > > > > > > If multiple sessions need to be processed via the same process function,
> > > > > > > PMD would save the same process in all the sessions, I don't think there
> > > > would
> > > > > > > be any perf overhead with that.
> > > > > >
> > > > > > I think it would, see above.
> > > > > >
> > > > > > >
> > > > > > > > + * Sketched usage model:
> > > > > > > > + * ....
> > > > > > > > + * /* control path, alloc/init session */
> > > > > > > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > > > > > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > > > > > > + * rte_crypto_cpu_sym_process_t process =
> > > > > > > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > > > > > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > > > > > > + * ...
> > > > > > > > + * /* data-path*/
> > > > > > > > + * process(ses, ....);
> > > > > > > > + * ....
> > > > > > > > + * /* control path, termiante/free session */
> > > > > > > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > +/**
> > > > > > > > + * vector structure, contains pointer to vector array and the length
> > > > > > > > + * of the array
> > > > > > > > + */
> > > > > > > > +struct rte_crypto_vec {
> > > > > > > > + struct iovec *vec;
> > > > > > > > + uint32_t num;
> > > > > > > > +};
> > > > > > > > +
> > > > > > > > +/*
> > > > > > > > + * Data-path bulk process crypto function.
> > > > > > > > + */
> > > > > > > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > > > > > > + void *digest[], int status[], uint32_t num);
> > > > > > > > +/*
> > > > > > > > + * for given device return process function specific to input xforms
> > > > > > > > + * on error - return NULL and set rte_errno value.
> > > > > > > > + * Note that for same input xfroms for the same device should
> > return
> > > > > > > > + * the same process function.
> > > > > > > > + */
> > > > > > > > +__rte_experimental
> > > > > > > > +rte_crypto_cpu_sym_process_t
> > > > > > > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > +/*
> > > > > > > > + * Return required session size in bytes for given set of xforms.
> > > > > > > > + * if xforms == NULL, then return the max possible session size,
> > > > > > > > + * that would fit session for any supported by the device algorithm.
> > > > > > > > + * if CPU mode is not supported at all, or requeted in xform
> > > > > > > > + * algorithm is not supported, then return -ENOTSUP.
> > > > > > > > + */
> > > > > > > > +__rte_experimental
> > > > > > > > +int
> > > > > > > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > +/*
> > > > > > > > + * Initialize session.
> > > > > > > > + * It is caller responsibility to allocate enough space for it.
> > > > > > > > + * See rte_crypto_cpu_sym_session_size above.
> > > > > > > > + */
> > > > > > > > +__rte_experimental
> > > > > > > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > +__rte_experimental
> > > > > > > > +void
> > > > > > > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > > > +
> > > > > > > > +
> > > > > > > > #ifdef __cplusplus
> > > > > > > > }
> > > > > > > > #endif
> > > > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > > index defe05ea0..ed7e63fab 100644
> > > > > > > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > > @@ -310,6 +310,20 @@ typedef void
> > > > > > (*cryptodev_sym_free_session_t)(struct
> > > > > > > > rte_cryptodev *dev,
> > > > > > > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev
> > > > *dev,
> > > > > > > > struct rte_cryptodev_asym_session *sess);
> > > > > > > >
> > > > > > > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct
> > rte_cryptodev
> > > > > > *dev,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct
> > rte_cryptodev
> > > > > > *dev,
> > > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct
> > rte_cryptodev
> > > > > > *dev,
> > > > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > > > +
> > > > > > > > +typedef rte_crypto_cpu_sym_process_t
> > > > > > (*cryptodev_cpu_sym_session_func_t)
> > > > > > > > (
> > > > > > > > + struct rte_cryptodev *dev,
> > > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > > +
> > > > > > > > /** Crypto device operations function pointer table */
> > > > > > > > struct rte_cryptodev_ops {
> > > > > > > > cryptodev_configure_t dev_configure; /**< Configure device.
> > */
> > > > > > > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > > > cryptodev_asym_free_session_t asym_session_clear;
> > > > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > > > +
> > > > > > > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > > > > > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > > > > > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > > > > > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > > > > > > };
> > > > > > > >
> > > > > > > >
> > > > > > > >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4] eventdev: flag to identify same destined packets enqueue
` (3 preceding siblings ...)
2019-10-04 10:47 2% ` [dpdk-dev] [PATCH v3] " Nipun Gupta
@ 2019-10-09 7:32 6% ` Nipun Gupta
2019-10-11 13:03 6% ` [dpdk-dev] [PATCH v5] " Nipun Gupta
5 siblings, 0 replies; 200+ results
From: Nipun Gupta @ 2019-10-09 7:32 UTC (permalink / raw)
To: dev
Cc: jerinj, aconole, pbhagavatula, skori, hemant.agrawal,
bruce.richardson, marko.kovacevic, orika, radu.nicolau,
tomasz.kantecki, harry.van.haaren, nikhil.rao, Nipun Gupta
This patch introduces a `flag` in the Eth TX adapter enqueue API.
Some drivers may support burst functionality only with the packets
having same destination device and queue.
The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
to indicate this so the underlying driver, for drivers to utilize
burst functionality appropriately.
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
---
Changes in v4:
- Update rel note specifying the API change
- Remove redundant rte_event_tx_adapter_enqueue_same_dest API
Changes in v3:
- remove flag from internal txa_enqueue_same_dest internal API
- ABI version update in makefile, meson and rel_notes
- Few comments update
Changes in v2:
- have separate internal API in tx adapter for sending burst packets to
same eth dev, queue pair on the basis of the passed flag
- fix compilation of examples/eventdev_pipeline/
app/test-eventdev/test_pipeline_common.h | 6 +++---
.../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
doc/guides/rel_notes/release_19_11.rst | 7 ++++++-
.../eventdev_pipeline/pipeline_worker_tx.c | 2 +-
lib/librte_eventdev/Makefile | 2 +-
lib/librte_eventdev/meson.build | 2 +-
.../rte_event_eth_tx_adapter.h | 19 +++++++++++++++++--
lib/librte_eventdev/rte_eventdev.c | 1 +
lib/librte_eventdev/rte_eventdev.h | 10 ++++++++++
9 files changed, 42 insertions(+), 10 deletions(-)
diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
index 0440b9e29..6e73c6ab2 100644
--- a/app/test-eventdev/test_pipeline_common.h
+++ b/app/test-eventdev/test_pipeline_common.h
@@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t port,
struct rte_event * const ev)
{
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
@@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
{
uint16_t enq;
- enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
+ enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
while (enq < nb_rx) {
enq += rte_event_eth_tx_adapter_enqueue(dev, port,
- ev + enq, nb_rx - enq);
+ ev + enq, nb_rx - enq, 0);
}
}
diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
index 192f9e1cf..a8c13e136 100644
--- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
+++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
@@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()`` function.
if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
event.mbuf = m;
+ eq_flags = 0;
m->port = tx_port;
rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
- rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
+ rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags);
} else {
event.queue_id = qid; /* event queue linked to adapter port */
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e3..051ab26b8 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -94,6 +94,11 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* event: The function ``rte_event_eth_tx_adapter_enqueue`` takes an additional
+ input as ``flags``. Flag ``RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST`` which
+ has been introduced in this release is used when used when all the packets
+ enqueued in the tx adapter are destined for the same Ethernet port & Tx queue.
+
ABI Changes
-----------
@@ -146,7 +151,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_eal.so.11
librte_efd.so.1
librte_ethdev.so.12
- librte_eventdev.so.7
+ librte_eventdev.so.8
librte_flow_classify.so.1
librte_gro.so.1
librte_gso.so.1
diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c
index 8961cd656..a0f40c27c 100644
--- a/examples/eventdev_pipeline/pipeline_worker_tx.c
+++ b/examples/eventdev_pipeline/pipeline_worker_tx.c
@@ -40,7 +40,7 @@ worker_tx_pkt(const uint8_t dev, const uint8_t port, struct rte_event *ev)
{
exchange_mac(ev->mbuf);
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index cd3ff8040..9e6a99aa1 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_eventdev.a
# library version
-LIBABIVER := 7
+LIBABIVER := 8
# build flags
CFLAGS += -DALLOW_EXPERIMENTAL_API
diff --git a/lib/librte_eventdev/meson.build b/lib/librte_eventdev/meson.build
index 19541f23f..9ba6c0393 100644
--- a/lib/librte_eventdev/meson.build
+++ b/lib/librte_eventdev/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 7
+version = 8
allow_experimental_apis = true
if is_linux
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index c848261c4..93b717af9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
int
rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
+#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
+/**< This flag is used when all the packets enqueued in the tx adapter are
+ * destined for the same Ethernet port & Tx queue.
+ */
+
/**
* Enqueue a burst of events objects or an event object supplied in *rte_event*
* structure on an event device designated by its *dev_id* through the event
@@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
* The number of event objects to enqueue, typically number of
* rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
* available for this port.
+ * @param flags
+ * RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
+ * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
+ * which are enqueued are destined for the same Ethernet port & Tx queue.
*
* @return
* The number of event objects actually enqueued on the event device. The
@@ -343,7 +352,8 @@ static inline uint16_t
rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
uint8_t port_id,
struct rte_event ev[],
- uint16_t nb_events)
+ uint16_t nb_events,
+ const uint8_t flags)
{
const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
@@ -359,7 +369,12 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
return 0;
}
#endif
- return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
+ if (flags)
+ return dev->txa_enqueue_same_dest(dev->data->ports[port_id],
+ ev, nb_events);
+ else
+ return dev->txa_enqueue(dev->data->ports[port_id], ev,
+ nb_events);
}
/**
diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
index f44c869cb..b987e0745 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -1351,6 +1351,7 @@ rte_event_pmd_allocate(const char *name, int socket_id)
eventdev = &rte_eventdevs[dev_id];
eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
+ eventdev->txa_enqueue_same_dest = rte_event_tx_adapter_enqueue;
if (eventdev->data == NULL) {
struct rte_eventdev_data *eventdev_data = NULL;
diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
index 5044a13d0..ced6f29d9 100644
--- a/lib/librte_eventdev/rte_eventdev.h
+++ b/lib/librte_eventdev/rte_eventdev.h
@@ -1230,6 +1230,12 @@ typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
struct rte_event ev[], uint16_t nb_events);
/**< @internal Enqueue burst of events on port of a device */
+typedef uint16_t (*event_tx_adapter_enqueue_same_dest)(void *port,
+ struct rte_event ev[], uint16_t nb_events);
+/**< @internal Enqueue burst of events on port of a device supporting
+ * burst having same destination Ethernet port & Tx queue.
+ */
+
#define RTE_EVENTDEV_NAME_MAX_LEN (64)
/**< @internal Max length of name of event PMD */
@@ -1292,6 +1298,10 @@ struct rte_eventdev {
/**< Pointer to PMD dequeue function. */
event_dequeue_burst_t dequeue_burst;
/**< Pointer to PMD dequeue burst function. */
+ event_tx_adapter_enqueue_same_dest txa_enqueue_same_dest;
+ /**< Pointer to PMD eth Tx adapter burst enqueue function with
+ * events destined to same Eth port & Tx queue.
+ */
event_tx_adapter_enqueue txa_enqueue;
/**< Pointer to PMD eth Tx adapter enqueue function. */
struct rte_eventdev_data *data;
--
2.17.1
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-07 12:53 0% ` Ananyev, Konstantin
@ 2019-10-09 7:20 0% ` Akhil Goyal
2019-10-09 13:43 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-10-09 7:20 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon',
Zhang, Roy Fan
Cc: Doherty, Declan, 'Anoob Joseph'
Hi Konstantin,
>
>
> Hi Akhil,
>
> > > > > > > > > > > > > > > > This action type allows the burst of symmetric crypto
> > > > > workload
> > > > > > > using
> > > > > > > > > > the
> > > > > > > > > > > > > > same
> > > > > > > > > > > > > > > > algorithm, key, and direction being processed by CPU
> > > cycles
> > > > > > > > > > > > synchronously.
> > > > > > > > > > > > > > > > This flexible action type does not require external
> > > hardware
> > > > > > > > > > involvement,
> > > > > > > > > > > > > > > > having the crypto workload processed synchronously,
> > > and is
> > > > > > > more
> > > > > > > > > > > > > > performant
> > > > > > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on
> > > removed
> > > > > > > "async
> > > > > > > > > > > > mode
> > > > > > > > > > > > > > > > simulation" as well as 3 cacheline access of the
> crypto
> > > ops.
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > Does that mean application will not call the
> > > > > > > cryptodev_enqueue_burst
> > > > > > > > > > and
> > > > > > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Yes, instead it just call
> > > rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > > It would be a new API something like process_packets
> and
> > > it
> > > > > will
> > > > > > > have
> > > > > > > > > > the
> > > > > > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Yes, though the plan is that API will operate on raw data
> > > buffers,
> > > > > > > not
> > > > > > > > > > mbufs.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > >
> > > > > > > > > > > > > > > I still do not understand why we cannot do with the
> > > > > conventional
> > > > > > > > > > crypto lib
> > > > > > > > > > > > > > only.
> > > > > > > > > > > > > > > As far as I can understand, you are not doing any
> protocol
> > > > > > > processing
> > > > > > > > > > or
> > > > > > > > > > > > any
> > > > > > > > > > > > > > value add
> > > > > > > > > > > > > > > To the crypto processing. IMO, you just need a
> > > synchronous
> > > > > > > crypto
> > > > > > > > > > > > processing
> > > > > > > > > > > > > > API which
> > > > > > > > > > > > > > > Can be defined in cryptodev, you don't need to re-
> create a
> > > > > crypto
> > > > > > > > > > session
> > > > > > > > > > > > in
> > > > > > > > > > > > > > the name of
> > > > > > > > > > > > > > > Security session in the driver just to do a synchronous
> > > > > processing.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > > > > > The main reason is that would require disruptive changes
> in
> > > > > existing
> > > > > > > > > > > > cryptodev
> > > > > > > > > > > > > > API
> > > > > > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > > need
> > > > > > > some
> > > > > > > > > > extra
> > > > > > > > > > > > > > information
> > > > > > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > > > > > (cipher offset from the start of the buffer, might be
> > > something
> > > > > extra
> > > > > > > in
> > > > > > > > > > > > future).
> > > > > > > > > > > > >
> > > > > > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > > > > > >
> > > > > > > > > > > > fill/read (+ alloc/free) is one of the main things that
> slowdown
> > > > > current
> > > > > > > > > > crypto-op
> > > > > > > > > > > > approach.
> > > > > > > > > > > > That's why the general idea - have all data that wouldn't
> change
> > > > > from
> > > > > > > packet
> > > > > > > > > > to
> > > > > > > > > > > > packet
> > > > > > > > > > > > included into the session and setup it once at session_init().
> > > > > > > > > > >
> > > > > > > > > > > I agree that you cannot use crypto-op.
> > > > > > > > > > > You can have the new API in crypto.
> > > > > > > > > > > As per the current patch, you only need cipher_offset which
> you
> > > can
> > > > > have
> > > > > > > it as
> > > > > > > > > > a parameter until
> > > > > > > > > > > You get it approved in the crypto xform. I believe it will be
> > > beneficial
> > > > > in
> > > > > > > case of
> > > > > > > > > > other crypto cases as well.
> > > > > > > > > > > We can have cipher offset at both places(crypto-op and
> > > > > cipher_xform). It
> > > > > > > will
> > > > > > > > > > give flexibility to the user to
> > > > > > > > > > > override it.
> > > > > > > > > >
> > > > > > > > > > After having another thought on your proposal:
> > > > > > > > > > Probably we can introduce new rte_crypto_sym_xform_types
> for
> > > CPU
> > > > > > > related
> > > > > > > > > > stuff here?
> > > > > > > > >
> > > > > > > > > I also thought of adding new xforms, but that wont serve the
> purpose
> > > for
> > > > > > > may be all the cases.
> > > > > > > > > You would be needing all information currently available in the
> > > current
> > > > > > > xforms.
> > > > > > > > > So if you are adding new fields in the new xform, the size will be
> more
> > > > > than
> > > > > > > that of the union of xforms.
> > > > > > > > > ABI breakage would still be there.
> > > > > > > > >
> > > > > > > > > If you think a valid compression of the AEAD xform can be done,
> then
> > > > > that
> > > > > > > can be done for each of the
> > > > > > > > > Xforms and we can have a solution to this issue.
> > > > > > > >
> > > > > > > > I think that we can re-use iv.offset for our purposes (for crypto
> offset).
> > > > > > > > So for now we can make that path work without any ABI breakage.
> > > > > > > > Fan, please feel free to correct me here, if I missed something.
> > > > > > > > If in future we would need to add some extra information it might
> > > > > > > > require ABI breakage, though by now I don't envision anything
> > > particular to
> > > > > > > add.
> > > > > > > > Anyway, if there is no objection to go that way, we can try to make
> > > > > > > > these changes for v2.
> > > > > > > >
> > > > > > >
> > > > > > > Actually, after looking at it more deeply it appears not that easy as I
> > > thought
> > > > > it
> > > > > > > would be :)
> > > > > > > Below is a very draft version of proposed API additions.
> > > > > > > I think it avoids ABI breakages right now and provides enough
> flexibility
> > > for
> > > > > > > future extensions (if any).
> > > > > > > For now, it doesn't address your comments about naming
> conventions
> > > > > (_CPU_
> > > > > > > vs _SYNC_) , etc.
> > > > > > > but I suppose is comprehensive enough to provide a main idea
> beyond it.
> > > > > > > Akhil and other interested parties, please try to review and provide
> > > feedback
> > > > > > > ASAP,
> > > > > > > as related changes would take some time and we still like to hit 19.11
> > > > > deadline.
> > > > > > > Konstantin
> > > > > > >
> > > > > > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > index bc8da2466..c03069e23 100644
> > > > > > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > > > > > *
> > > > > > > * This structure contains data relating to Cipher (Encryption and
> > > Decryption)
> > > > > > > * use to create a session.
> > > > > > > + * Actually I was wrong saying that we don't have free space inside
> > > xforms.
> > > > > > > + * Making key struct packed (see below) allow us to regain 6B that
> could
> > > be
> > > > > > > + * used for future extensions.
> > > > > > > */
> > > > > > > struct rte_crypto_cipher_xform {
> > > > > > > enum rte_crypto_cipher_operation op;
> > > > > > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > > > > > struct {
> > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > - } key;
> > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * offset for cipher to start within user provided data buffer.
> > > > > > > + * Fan suggested another (and less space consuming way) -
> > > > > > > + * reuse iv.offset space below, by changing:
> > > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > > + * to uunamed union:
> > > > > > > + * union {
> > > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > > > > > + * };
> > > > > > > + * Both approaches seems ok to me in general.
> > > > > >
> > > > > > No strong opinions here. OK with this one.
> > > > > >
> > > > > > > + * Comments/suggestions are welcome.
> > > > > > > + */
> > > > > > > + uint16_t offset;
> > > > >
> > > > > After another thought - it is probably a bit better to have offset as a
> separate
> > > > > field.
> > > > > In that case we can use the same xforms to create both type of sessions.
> > > > ok
> > > > >
> > > > > > > +
> > > > > > > + uint8_t reserved1[4];
> > > > > > > +
> > > > > > > /**< Cipher key
> > > > > > > *
> > > > > > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation,
> > > key.data
> > > > > will
> > > > > > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > > > > > struct {
> > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > - } key;
> > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > /**< Authentication key data.
> > > > > > > * The authentication key length MUST be less than or equal to
> the
> > > > > > > * block size of the algorithm. It is the callers responsibility to
> > > > > > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > > > > > * (for example RFC 2104, FIPS 198a).
> > > > > > > */
> > > > > > >
> > > > > > > + uint8_t reserved1[6];
> > > > > > > +
> > > > > > > struct {
> > > > > > > uint16_t offset;
> > > > > > > /**< Starting point for Initialisation Vector or Counter,
> > > > > > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > > > > > struct {
> > > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > > uint16_t length; /**< key length in bytes */
> > > > > > > - } key;
> > > > > > > + } __attribute__((__packed__)) key;
> > > > > > > +
> > > > > > > + /** offset for cipher to start within data buffer */
> > > > > > > + uint16_t cipher_offset;
> > > > > > > +
> > > > > > > + uint8_t reserved1[4];
> > > > > > >
> > > > > > > struct {
> > > > > > > uint16_t offset;
> > > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > index e175b838c..c0c7bfed7 100644
> > > > > > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > > @@ -1272,6 +1272,101 @@ void *
> > > > > > > rte_cryptodev_sym_session_get_user_data(
> > > > > > > struct rte_cryptodev_sym_session *sess);
> > > > > > >
> > > > > > > +/*
> > > > > > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > > > > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > > > > > + * introduce an extentsion to it via new fully opaque
> > > > > > > + * struct rte_crypto_cpu_sym_session and additional related API.
> > > > > >
> > > > > >
> > > > > > What all things do we need to squeeze?
> > > > > > In this proposal I do not see the new struct cpu_sym_session defined
> here.
> > > > >
> > > > > The plan is to have it totally opaque to the user, i.e. just:
> > > > > struct rte_crypto_cpu_sym_session;
> > > > > in public header files.
> > > > >
> > > > > > I believe you will have same lib API/struct for cpu_sym_session and
> > > > > sym_session.
> > > > >
> > > > > I thought about such way, but there are few things that looks clumsy to
> me:
> > > > > 1. Right now there is no 'type' (or so) field inside
> rte_cryptodev_sym_session,
> > > > > so it is not possible to easy distinguish what session do you have:
> lksd_sym or
> > > > > cpu_sym.
> > > > > In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we
> can
> > > add
> > > > > some extra field
> > > > > here, but in that case we wouldn't be able to use the same xform for
> both
> > > > > lksd_sym or cpu_sym
> > > > > (which seems really plausible thing for me).
> > > > > 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary
> for
> > > > > rte_crypto_cpu_sym_session:
> > > > > sess_data[], opaque_data, user_data, nb_drivers.
> > > > > All that consumes space, that could be used somewhere else instead.
> > > > > 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> > > > > breakages I can't foresee right now.
> > > > > From other side - if we'll add new functions/structs for cpu_sym_session
> we
> > > can
> > > > > mark it
> > > > > and keep it for some time as experimental, so further changes (if needed)
> > > would
> > > > > still be possible.
> > > > >
> > > >
> > > > OK let us assume that you have a separate structure. But I have a few
> queries:
> > > > 1. how can multiple drivers use a same session
> > >
> > > As a short answer: they can't.
> > > It is pretty much the same approach as with rte_security - each device needs
> to
> > > create/init its own session.
> > > So upper layer would need to maintain its own array (or so) for such case.
> > > Though the question is why would you like to have same session over
> multiple
> > > SW backed devices?
> > > As it would be anyway just a synchronous function call that will be executed
> on
> > > the same cpu.
> >
> > I may have single FAT tunnel which may be distributed over multiple
> > Cores, and each core is affined to a different SW device.
>
> If it is pure SW, then we don't need multiple devices for such scenario.
> Device in that case is pure abstraction that we can skip.
Yes agreed, but that liberty is given to the application whether it need multiple
devices with single queue or a single device with multiple queues.
I think that independence should not be broken in this new API.
>
> > So a single session may be accessed by multiple devices.
> >
> > One more example would be depending on packet sizes, I may switch between
> > HW/SW PMDs with the same session.
>
> Sure, but then we'll have multiple sessions.
No, the session will be same and it will have multiple private data for each of the PMD.
> BTW, we have same thing now - these private session pointers are just stored
> inside the same rte_crypto_sym_session.
> And if user wants to support this model, he would also need to store <dev_id,
> queue_id>
> pair for each HW device anyway.
Yes agreed, but how is that thing happening in your new struct, you cannot support that.
>
> >
> > >
> > > > 2. Can somebody use the scheduler pmd for scheduling the different type
> of
> > > payloads for the same session?
> > >
> > > In theory yes.
> > > Though for that scheduler pmd should have inside it's
> > > rte_crypto_cpu_sym_session an array of pointers to
> > > the underlying devices sessions.
> > >
> > > >
> > > > With your proposal the APIs would be very specific to your use case only.
> > >
> > > Yes in some way.
> > > I consider that API specific for SW backed crypto PMDs.
> > > I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will benefit
> > > from it.
> > > Current crypto-op API is very much HW oriented.
> > > Which is ok, that's for it was intended for, but I think we also need one that
> > > would be designed
> > > for SW backed implementation in mind.
> >
> > We may re-use your API for HW PMDs as well which do not have requirement
> of
> > Crypto-op/mbuf etc.
> > The return type of your new process API may have a status which say
> 'processed'
> > Or can be say 'enqueued'. So if it is 'enqueued', we may have a new API for
> raw
> > Bufs dequeue as well.
> >
> > This requirement can be for any hardware PMDs like QAT as well.
>
> I don't think it is a good idea to extend this API for async (lookaside) devices.
> You'll need to:
> - provide dev_id and queue_id for each process(enqueue) and dequeuer
> operation.
> - provide IOVA for all buffers passing to that function (data buffers, digest, IV,
> aad).
> - On dequeue provide some way to associate dequed data and digest buffers
> with
> crypto-session that was used (and probably with mbuf).
> So most likely we'll end up with another just version of our current crypto-op
> structure.
> If you'd like to get rid of mbufs dependency within current crypto-op API that
> understandable,
> but I don't think we should have same API for both sync (CPU) and async
> (lookaside) cases.
> It doesn't seem feasible at all and voids whole purpose of that patch.
At this moment we are not much concerned about the dequeue API and about the
HW PMD support. It is just that the new API should be generic enough to be used in
some future scenarios as well. I am just highlighting the possible usecases which can
be there in future.
What is the issue that you face in making a dev-op for this new API. Do you see any
performance impact with that?
>
> > That is why a dev-ops would be a better option.
> >
> > >
> > > > When you would add more functionality to this sync API/struct, it will end
> up
> > > being the same API/struct.
> > > >
> > > > Let us see how close/ far we are from the existing APIs when the actual
> > > implementation is done.
> > > >
> > > > > > I am not sure if that would be needed.
> > > > > > It would be internal to the driver that if synchronous processing is
> > > > > supported(from feature flag) and
> > > > > > Have relevant fields in xform(the newly added ones which are packed
> as
> > > per
> > > > > your suggestions) set,
> > > > > > It will create that type of session.
> > > > > >
> > > > > >
> > > > > > > + * Main points:
> > > > > > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > > > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > > > > + * new sync API is new one and probably would require extra
> changes.
> > > > > > > + * Having it as a new one allows to mark it as experimental, without
> > > > > > > + * affecting existing one.
> > > > > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > > > > + * to the PMD writers and again allows to avoid ABI breakages in
> future.
> > > > > > > + * - process() function per set of xforms
> > > > > > > + * allows to expose different process() functions for different
> > > > > > > + * xform combinations. PMD writer can decide, does he wants to
> > > > > > > + * push all supported algorithms into one process() function,
> > > > > > > + * or spread it across several ones.
> > > > > > > + * I.E. More flexibility for PMD writer.
> > > > > >
> > > > > > Which process function should be chosen is internal to PMD, how
> would
> > > that
> > > > > info
> > > > > > be visible to the application or the library. These will get stored in the
> > > session
> > > > > private
> > > > > > data. It would be upto the PMD writer, to store the per session process
> > > > > function in
> > > > > > the session private data.
> > > > > >
> > > > > > Process function would be a dev ops just like enc/deq operations and it
> > > should
> > > > > call
> > > > > > The respective process API stored in the session private data.
> > > > >
> > > > > That model (via devops) is possible, but has several drawbacks from my
> > > > > perspective:
> > > > >
> > > > > 1. It means we'll need to pass dev_id as a parameter to process() function.
> > > > > Though in fact dev_id is not a relevant information for us here
> > > > > (all we need is pointer to the session and pointer to the fuction to call)
> > > > > and I tried to avoid using it in data-path functions for that API.
> > > >
> > > > You have a single vdev, but someone may have multiple vdevs for each
> thread,
> > > or may
> > > > Have same dev with multiple queues for each core.
> > >
> > > That's fine. As I said above it is a SW backed implementation.
> > > Each session has to be a separate entity that contains all necessary
> information
> > > (keys, alg/mode info, etc.) to process input buffers.
> > > Plus we need the actual function pointer to call.
> > > I just don't see what for we need a dev_id in that situation.
> >
> > To iterate the session private data in the session.
> >
> > > Again, here we don't need care about queues and their pinning to cores.
> > > If let say someone would like to process buffers from the same IPsec SA on 2
> > > different cores in parallel, he can just create 2 sessions for the same xform,
> > > give one to thread #1 and second to thread #2.
> > > After that both threads are free to call process(this_thread_ses, ...) at will.
> >
> > Say you have a 16core device to handle 100G of traffic on a single tunnel.
> > Will we make 16 sessions with same parameters?
>
> Absolutely same question we can ask for current crypto-op API.
> You have lookaside crypto-dev with 16 HW queues, each queue is serviced by
> different CPU.
> For the same SA, do you need a separate session per queue, or is it ok to reuse
> current one?
> AFAIK, right now this is a grey area not clearly defined.
> For crypto-devs I am aware - user can reuse the same session (as PMD uses it
> read-only).
> But again, right now I think it is not clearly defined and is implementation
> specific.
User can use the same session, that is what I am also insisting, but it may have separate
Session private data. Cryptodev session create API provide that functionality and we can
Leverage that.
BTW, I can see a v2 to this RFC which is still based on security library. When do you plan
To submit the patches for crypto based APIs. We have RC1 merge deadline for this
patchset on 21st Oct.
As per my understanding you only need a new dev-op for sync support. Session APIs
Will remain the same and you will have some extra fields packed in xform structs.
The PMD will need to maintain a pointer to the per session process function while creating
Session and will be used by the dev-op API at runtime without any extra check at runtime.
>
> >
> > >
> > > >
> > > > > 2. As you pointed in that case it will be just one process() function per
> device.
> > > > > So if PMD would like to have several process() functions for different type
> of
> > > > > sessions
> > > > > (let say one per alg) first thing it has to do inside it's process() - read
> session
> > > data
> > > > > and
> > > > > based on that, do a jump/call to particular internal sub-routine.
> > > > > Something like:
> > > > > driver_id = get_pmd_driver_id();
> > > > > priv_ses = ses->sess_data[driver_id];
> > > > > Then either:
> > > > > switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> > > > > OR
> > > > > priv_ses->process(priv_sess, ...);
> > > > >
> > > > > to select and call the proper function.
> > > > > Looks like totally unnecessary overhead to me.
> > > > > Though if we'll have ability to query/extract some sort session_ops based
> on
> > > the
> > > > > xform -
> > > > > we can avoid this extra de-refererence+jump/call thing.
> > > >
> > > > What is the issue in the priv_ses->process(); approach?
> > >
> > > Nothing at all.
> > > What I am saying that schema with dev_ops
> > > dev[dev_id]->dev_ops.process(ses->priv_ses[driver_id], ...)
> > > |
> > > |-> priv_ses->process(...)
> > >
> > > Has bigger overhead then just:
> > > process(ses,...);
> > >
> > > So what for to introduce extra-level of indirection here?
> >
> > Explained above.
> >
> > >
> > > > I don't understand what are you saving by not doing this.
> > > > In any case you would need to identify which session correspond to which
> > > process().
> > >
> > > Yes, sure, but I think we can make user to store information that relationship,
> > > in a way he likes: store process() pointer for each session, or group sessions
> > > that share the same process() somehow, or...
> >
> > So whatever relationship that user will make and store will make its life
> complicated.
> > If we can hide that information in the driver, then what is the issue in that and
> user
> > Will not need to worry. He would just call the process() and driver will choose
> which
> > Process need to be called.
>
> Driver can do that at config/init time.
> Then at run-time we can avoid that choice at all and call already chosen function.
>
> >
> > I think we should have a POC around this and see the difference in the cycle
> count.
> > IMO it would be negligible and we would end up making a generic API set
> which
> > can be used by others as well.
> >
> > >
> > > > For that you would be doing it somewhere in your data path.
> > >
> > > Why at data-path?
> > > Only once at session creation/initialization time.
> > > Or might be even once per group of sessions.
> > >
> > > >
> > > > >
> > > > > >
> > > > > > I am not sure if you would need a new session init API for this as
> nothing
> > > would
> > > > > be visible to
> > > > > > the app or lib.
> > > > > >
> > > > > > > + * - Not storing process() pointer inside the session -
> > > > > > > + * Allows user to choose does he want to store a process() pointer
> > > > > > > + * per session, or per group of sessions for that device that share
> > > > > > > + * the same input xforms. I.E. extra flexibility for the user,
> > > > > > > + * plus allows us to keep cpu_sym_session totally opaque, see
> above.
> > > > > >
> > > > > > If multiple sessions need to be processed via the same process function,
> > > > > > PMD would save the same process in all the sessions, I don't think there
> > > would
> > > > > > be any perf overhead with that.
> > > > >
> > > > > I think it would, see above.
> > > > >
> > > > > >
> > > > > > > + * Sketched usage model:
> > > > > > > + * ....
> > > > > > > + * /* control path, alloc/init session */
> > > > > > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > > > > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > > > > > + * rte_crypto_cpu_sym_process_t process =
> > > > > > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > > > > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > > > > > + * ...
> > > > > > > + * /* data-path*/
> > > > > > > + * process(ses, ....);
> > > > > > > + * ....
> > > > > > > + * /* control path, termiante/free session */
> > > > > > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > > > > > + */
> > > > > > > +
> > > > > > > +/**
> > > > > > > + * vector structure, contains pointer to vector array and the length
> > > > > > > + * of the array
> > > > > > > + */
> > > > > > > +struct rte_crypto_vec {
> > > > > > > + struct iovec *vec;
> > > > > > > + uint32_t num;
> > > > > > > +};
> > > > > > > +
> > > > > > > +/*
> > > > > > > + * Data-path bulk process crypto function.
> > > > > > > + */
> > > > > > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > > > > > + void *digest[], int status[], uint32_t num);
> > > > > > > +/*
> > > > > > > + * for given device return process function specific to input xforms
> > > > > > > + * on error - return NULL and set rte_errno value.
> > > > > > > + * Note that for same input xfroms for the same device should
> return
> > > > > > > + * the same process function.
> > > > > > > + */
> > > > > > > +__rte_experimental
> > > > > > > +rte_crypto_cpu_sym_process_t
> > > > > > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > +/*
> > > > > > > + * Return required session size in bytes for given set of xforms.
> > > > > > > + * if xforms == NULL, then return the max possible session size,
> > > > > > > + * that would fit session for any supported by the device algorithm.
> > > > > > > + * if CPU mode is not supported at all, or requeted in xform
> > > > > > > + * algorithm is not supported, then return -ENOTSUP.
> > > > > > > + */
> > > > > > > +__rte_experimental
> > > > > > > +int
> > > > > > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > +/*
> > > > > > > + * Initialize session.
> > > > > > > + * It is caller responsibility to allocate enough space for it.
> > > > > > > + * See rte_crypto_cpu_sym_session_size above.
> > > > > > > + */
> > > > > > > +__rte_experimental
> > > > > > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > +__rte_experimental
> > > > > > > +void
> > > > > > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > > +
> > > > > > > +
> > > > > > > #ifdef __cplusplus
> > > > > > > }
> > > > > > > #endif
> > > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > index defe05ea0..ed7e63fab 100644
> > > > > > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > > @@ -310,6 +310,20 @@ typedef void
> > > > > (*cryptodev_sym_free_session_t)(struct
> > > > > > > rte_cryptodev *dev,
> > > > > > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev
> > > *dev,
> > > > > > > struct rte_cryptodev_asym_session *sess);
> > > > > > >
> > > > > > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct
> rte_cryptodev
> > > > > *dev,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct
> rte_cryptodev
> > > > > *dev,
> > > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct
> rte_cryptodev
> > > > > *dev,
> > > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > > +
> > > > > > > +typedef rte_crypto_cpu_sym_process_t
> > > > > (*cryptodev_cpu_sym_session_func_t)
> > > > > > > (
> > > > > > > + struct rte_cryptodev *dev,
> > > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > > +
> > > > > > > /** Crypto device operations function pointer table */
> > > > > > > struct rte_cryptodev_ops {
> > > > > > > cryptodev_configure_t dev_configure; /**< Configure device.
> */
> > > > > > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > > cryptodev_asym_free_session_t asym_session_clear;
> > > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > > +
> > > > > > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > > > > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > > > > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > > > > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > > > > > };
> > > > > > >
> > > > > > >
> > > > > > >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 00/14] vhost packed ring performance optimization
@ 2019-10-09 13:38 3% ` Marvin Liu
2019-10-15 14:30 3% ` [dpdk-dev] [PATCH v5 00/13] " Marvin Liu
1 sibling, 1 reply; 200+ results
From: Marvin Liu @ 2019-10-09 13:38 UTC (permalink / raw)
To: maxime.coquelin, tiwei.bie, zhihong.wang, stephen, gavin.hu
Cc: dev, Marvin Liu
Packed ring has more compact ring format and thus can significantly
reduce the number of cache miss. It can lead to better performance.
This has been approved in virtio user driver, on normal E5 Xeon cpu
single core performance can raise 12%.
http://mails.dpdk.org/archives/dev/2018-April/095470.html
However vhost performance with packed ring performance was decreased.
Through analysis, mostly extra cost was from the calculating of each
descriptor flag which depended on ring wrap counter. Moreover, both
frontend and backend need to write same descriptors which will cause
cache contention. Especially when doing vhost enqueue function, virtio
refill packed ring function may write same cache line when vhost doing
enqueue function. This kind of extra cache cost will reduce the benefit
of reducing cache misses.
For optimizing vhost packed ring performance, vhost enqueue and dequeue
function will be splitted into fast and normal path.
Several methods will be taken in fast path:
Handle descriptors in one cache line by batch.
Split loop function into more pieces and unroll them.
Prerequisite check that whether I/O space can copy directly into mbuf
space and vice versa.
Prerequisite check that whether descriptor mapping is successful.
Distinguish vhost used ring update function by enqueue and dequeue
function.
Buffer dequeue used descriptors as many as possible.
Update enqueue used descriptors by cache line.
Disable sofware prefetch if hardware can do better.
After all these methods done, single core vhost PvP performance with 64B
packet on Xeon 8180 can boost 40%.
v4:
- Support meson build
- Remove memory region cache for no clear performance gain and ABI break
- Not assume ring size is power of two
v3:
- Check available index overflow
- Remove dequeue remained descs number check
- Remove changes in split ring datapath
- Call memory write barriers once when updating used flags
- Rename some functions and macros
- Code style optimization
v2:
- Utilize compiler's pragma to unroll loop, distinguish clang/icc/gcc
- Buffered dequeue used desc number changed to (RING_SZ - PKT_BURST)
- Optimize dequeue used ring update when in_order negotiated
Marvin Liu (14):
vhost: add single packet enqueue function
vhost: unify unroll pragma parameter
vhost: add batch enqueue function for packed ring
vhost: add single packet dequeue function
vhost: add batch dequeue function
vhost: flush vhost enqueue shadow ring by batch
vhost: add flush function for batch enqueue
vhost: buffer vhost dequeue shadow ring
vhost: split enqueue and dequeue flush functions
vhost: optimize enqueue function of packed ring
vhost: add batch and single zero dequeue functions
vhost: optimize dequeue function of packed ring
vhost: check whether disable software pre-fetch
vhost: optimize packed ring dequeue when in-order
lib/librte_vhost/Makefile | 24 +
lib/librte_vhost/meson.build | 11 +
lib/librte_vhost/vhost.h | 33 ++
lib/librte_vhost/virtio_net.c | 993 +++++++++++++++++++++++++++-------
4 files changed, 878 insertions(+), 183 deletions(-)
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 13/15] vhost: cache address translation result
@ 2019-10-09 2:08 0% ` Liu, Yong
0 siblings, 0 replies; 200+ results
From: Liu, Yong @ 2019-10-09 2:08 UTC (permalink / raw)
To: Bie, Tiwei; +Cc: maxime.coquelin, Wang, Zhihong, stephen, gavin.hu, dev
> -----Original Message-----
> From: Bie, Tiwei
> Sent: Thursday, September 26, 2019 1:32 PM
> To: Liu, Yong <yong.liu@intel.com>
> Cc: maxime.coquelin@redhat.com; Wang, Zhihong <zhihong.wang@intel.com>;
> stephen@networkplumber.org; gavin.hu@arm.com; dev@dpdk.org
> Subject: Re: [PATCH v3 13/15] vhost: cache address translation result
>
> On Thu, Sep 26, 2019 at 01:13:27AM +0800, Marvin Liu wrote:
> > Cache address translation result and use it in next translation. Due
> > to limited regions are supported, buffers are most likely in same
> > region when doing data transmission.
> >
> > Signed-off-by: Marvin Liu <yong.liu@intel.com>
> >
> > diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
> > index 7fb172912..d90235cd6 100644
> > --- a/lib/librte_vhost/rte_vhost.h
> > +++ b/lib/librte_vhost/rte_vhost.h
> > @@ -91,10 +91,18 @@ struct rte_vhost_mem_region {
> > int fd;
> > };
> >
> > +struct rte_vhost_mem_region_cache {
> > + uint64_t guest_phys_addr;
> > + uint64_t guest_phys_addr_end;
> > + int64_t host_user_addr_offset;
> > + uint64_t size;
> > +};
> > +
> > /**
> > * Memory structure includes region and mapping information.
> > */
> > struct rte_vhost_memory {
> > + struct rte_vhost_mem_region_cache cache_region;
>
> This breaks ABI.
>
Got, will remove it as no clear performance gain with this patch.
> > uint32_t nregions;
> > struct rte_vhost_mem_region regions[];
> > };
> > @@ -232,11 +240,30 @@ rte_vhost_va_from_guest_pa(struct rte_vhost_memory
> *mem,
> > struct rte_vhost_mem_region *r;
> > uint32_t i;
> >
> > + struct rte_vhost_mem_region_cache *r_cache;
> > + /* check with cached region */
> > + r_cache = &mem->cache_region;
> > + if (likely(gpa >= r_cache->guest_phys_addr && gpa <
> > + r_cache->guest_phys_addr_end)) {
> > + if (unlikely(*len > r_cache->guest_phys_addr_end - gpa))
> > + *len = r_cache->guest_phys_addr_end - gpa;
> > +
> > + return gpa - r_cache->host_user_addr_offset;
> > + }
>
> Does this help a lot in performance?
> We can implement this caching for builtin backend first.
>
Tiwei,
It won’t help too much in performance as region number will be 1 at most of times.
Will remove cache function in next version.
Thanks,
Marvin
>
> > +
> > +
> > for (i = 0; i < mem->nregions; i++) {
> > r = &mem->regions[i];
> > if (gpa >= r->guest_phys_addr &&
> > gpa < r->guest_phys_addr + r->size) {
> >
> > + r_cache->guest_phys_addr = r->guest_phys_addr;
> > + r_cache->guest_phys_addr_end = r->guest_phys_addr +
> > + r->size;
> > + r_cache->size = r->size;
> > + r_cache->host_user_addr_offset = r->guest_phys_addr -
> > + r->host_user_addr;
> > +
> > if (unlikely(*len > r->guest_phys_addr + r->size - gpa))
> > *len = r->guest_phys_addr + r->size - gpa;
> >
> > --
> > 2.17.1
> >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v6 0/5] mbuf: copy/cloning enhancements
` (3 preceding siblings ...)
2019-10-07 15:43 3% ` [dpdk-dev] [PATCH v5 0/5] " Stephen Hemminger
@ 2019-10-08 16:33 3% ` Stephen Hemminger
4 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-08 16:33 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This patch set is all about improving the mbuf related cloning
and copying. They are motivated by seeing issues with mbuf copying
in rte_pdump and realized this a wider and more general problem.
The pdump copy could not handle different size pools and did
not handle meta data, etc.
They cause no functional or ABI changes. The only visible part
to older code is converting a couple of inlines to real functions.
This kind of change confuses checkpatch which thinks these new
functions should be marked experimental when they must not be.
v6 - incorporate feedback from Oliver for pktmbuf_copy
add more comments and tests for pktmbuf_copy
v5 - add back the test (dropped by accident in v4)
v4 - common mbuf header fields copy routine
v3 - split linearize into internal/external
copy private data in pktmbuf_copy
v2 - add pdump use of pktmbuf_copy
fix version in map
Stephen Hemminger (5):
mbuf: don't generate invalid mbuf in clone test
mbuf: delinline rte_pktmbuf_linearize
mbuf: deinline rte_pktmbuf_clone
mbuf: add a pktmbuf copy routine
mbuf: add pktmbuf copy test
app/test/test_mbuf.c | 160 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.c | 153 +++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 129 +++++++++------------
lib/librte_mbuf/rte_mbuf_version.map | 8 ++
4 files changed, 372 insertions(+), 78 deletions(-)
--
2.20.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd
2019-10-08 15:14 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
@ 2019-10-08 15:33 0% ` Ferruh Yigit
2019-10-11 2:50 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-10-08 15:33 UTC (permalink / raw)
To: Wangxiaoyun (Cloud, Network Chip Application Development Dept)
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1
On 10/8/2019 4:14 PM, Wangxiaoyun (Cloud, Network Chip Application Development
Dept) wrote:
> Hi Ferruh,
> Thanks for your comments. hinic pmd driver doesn't support 32-bit build, we add descriptions with config file "defconfig_x86_x32-native-linuxapp-gcc".
> and “defconfig_x86_x32-native-linux-gcc”. I don't know why it also build in 32-bit platform, can you tell me where also need me to add configuration.
> Also I build it on 64-bit platform,That's OK.
Hi Xiaoyun,
You are right, driver doesn't support 32bit, I am force enabling it, just for build.
Since the build error is only in the logging format identifiers, I think it make
sense to fix it, and it is better to use more proper format identifiers.
>
> Best regards
> Xiaoyun Wang
>
> 在 2019/9/30 23:06, Ferruh Yigit 写道:
>> On 9/30/2019 3:00 PM, Xiaoyun wang wrote:
>>> This patch set adds advanced features for Huawei hinic pmd,
>>> such as VLAN filter and VLAN offload, SR-IOV, FW version get,
>>> set link down and up, Flow director for LACP, VRRP, BGP and so on.
>>>
>>> --
>>> v2:
>>> - Fix RSS bugs for vxlan packets inner type
>>> - Add comments for new added func interface
>>> - Fix code review comments from patch v1
>>> - Fix code style problems
>>> - Remove ceq interfaces and definitions that not used
>>> - Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
>>> - Fix bar map bugs for VF Page size larger than PF
>>> - Modify link state set, add enable or disable fiber in tx direction
>>> - Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
>>> - Fix FDIR bugs for VRRP packets
>>> - Fit ABI changes from dpdk lib
>>>
>>> v3:
>>> - Split hinic.ini and hinic.rst to related feature patches
>>> - Add min_mtu & max_mtu initialization for hinic_dev_infos_get
>>> - Fix fdir config patch with net/hinic/base
>>> - Split link patch into link and fw version getting 2 patches
>>> - Update pmd doc files to new next version
>>> - Add comments for cover letter patch
>>> - Add rxq & txq info getting interfaces
>>> - Fix load intrinsics for receiving packets
>>>
>>> Xiaoyun wang (19):
>>> net/hinic/base: add mbox command channel for SRIOV
>>> net/hinic/base: add HW interfaces for SR-IOV
>>> net/hinic: add VF PMD operation interfaces
>>> net/hinic: add VLAN filter and offload
>>> net/hinic: add allmulticast mode and MTU set
>>> net/hinic: add unicast and multicast MAC set
>>> net/hinic/base: add fdir config interface
>>> net/hinic: add fdir validate flow operations
>>> net/hinic: create and destroy ntuple filter
>>> net/hinic: create and destroy fdir filter
>>> net/hinic: flush fdir filter
>>> net/hinic: set link down and up
>>> net/hinic: get firmware version
>>> net/hinic: support inner L3 checksum offload
>>> net/hinic: support LRO offload
>>> net/hinic: add hinic PMD doc files
>>> net/hinic/base: optimize aeq interfaces
>>> net/hinic: optimize RX performance
>>> net/hinic: add support for getting rxq or txq info
>> There is following 32-bit build error because of the log formatting [1], can you
>> please check it?
>>
>>
>> [1]
>> .../drivers/net/hinic/base/hinic_pmd_mbox.c(659):
>> error #181: argument of type "unsigned long long" is incompatible with format
>> "%lx", expecting argument of type "unsigned long"
>> PMD_DRV_LOG(ERR, "Fail to send mbox seg, seq_id: 0x%lx,
>> err: %d",
>>
>> .
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd
2019-09-30 15:06 0% ` Ferruh Yigit
@ 2019-10-08 15:14 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
2019-10-08 15:33 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Wangxiaoyun (Cloud, Network Chip Application Development Dept) @ 2019-10-08 15:14 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1
Hi Ferruh,
Thanks for your comments. hinic pmd driver doesn't support 32-bit build, we add descriptions with config file "defconfig_x86_x32-native-linuxapp-gcc".
and “defconfig_x86_x32-native-linux-gcc”. I don't know why it also build in 32-bit platform, can you tell me where also need me to add configuration.
Also I build it on 64-bit platform,That's OK.
Best regards
Xiaoyun Wang
在 2019/9/30 23:06, Ferruh Yigit 写道:
> On 9/30/2019 3:00 PM, Xiaoyun wang wrote:
>> This patch set adds advanced features for Huawei hinic pmd,
>> such as VLAN filter and VLAN offload, SR-IOV, FW version get,
>> set link down and up, Flow director for LACP, VRRP, BGP and so on.
>>
>> --
>> v2:
>> - Fix RSS bugs for vxlan packets inner type
>> - Add comments for new added func interface
>> - Fix code review comments from patch v1
>> - Fix code style problems
>> - Remove ceq interfaces and definitions that not used
>> - Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
>> - Fix bar map bugs for VF Page size larger than PF
>> - Modify link state set, add enable or disable fiber in tx direction
>> - Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
>> - Fix FDIR bugs for VRRP packets
>> - Fit ABI changes from dpdk lib
>>
>> v3:
>> - Split hinic.ini and hinic.rst to related feature patches
>> - Add min_mtu & max_mtu initialization for hinic_dev_infos_get
>> - Fix fdir config patch with net/hinic/base
>> - Split link patch into link and fw version getting 2 patches
>> - Update pmd doc files to new next version
>> - Add comments for cover letter patch
>> - Add rxq & txq info getting interfaces
>> - Fix load intrinsics for receiving packets
>>
>> Xiaoyun wang (19):
>> net/hinic/base: add mbox command channel for SRIOV
>> net/hinic/base: add HW interfaces for SR-IOV
>> net/hinic: add VF PMD operation interfaces
>> net/hinic: add VLAN filter and offload
>> net/hinic: add allmulticast mode and MTU set
>> net/hinic: add unicast and multicast MAC set
>> net/hinic/base: add fdir config interface
>> net/hinic: add fdir validate flow operations
>> net/hinic: create and destroy ntuple filter
>> net/hinic: create and destroy fdir filter
>> net/hinic: flush fdir filter
>> net/hinic: set link down and up
>> net/hinic: get firmware version
>> net/hinic: support inner L3 checksum offload
>> net/hinic: support LRO offload
>> net/hinic: add hinic PMD doc files
>> net/hinic/base: optimize aeq interfaces
>> net/hinic: optimize RX performance
>> net/hinic: add support for getting rxq or txq info
> There is following 32-bit build error because of the log formatting [1], can you
> please check it?
>
>
> [1]
> .../drivers/net/hinic/base/hinic_pmd_mbox.c(659):
> error #181: argument of type "unsigned long long" is incompatible with format
> "%lx", expecting argument of type "unsigned long"
> PMD_DRV_LOG(ERR, "Fail to send mbox seg, seq_id: 0x%lx,
> err: %d",
>
> .
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
2019-10-08 12:51 0% ` Yigit, Ferruh
@ 2019-10-08 13:17 0% ` Slava Ovsiienko
0 siblings, 0 replies; 200+ results
From: Slava Ovsiienko @ 2019-10-08 13:17 UTC (permalink / raw)
To: Yigit, Ferruh, Adrien Mazarguil, Andrew Rybchenko
Cc: Yongseok Koh, Thomas Monjalon, Olivier Matz, Bruce Richardson,
Shahaf Shuler, Ferruh Yigit, dev
> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@linux.intel.com>
> Sent: Tuesday, October 8, 2019 15:51
> To: Adrien Mazarguil <adrien.mazarguil@6wind.com>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Cc: Yongseok Koh <yskoh@mellanox.com>; Thomas Monjalon
> <thomas@monjalon.net>; Olivier Matz <olivier.matz@6wind.com>; Bruce
> Richardson <bruce.richardson@intel.com>; Shahaf Shuler
> <shahafs@mellanox.com>; Ferruh Yigit <ferruh.yigit@intel.com>; dev
> <dev@dpdk.org>; Slava Ovsiienko <viacheslavo@mellanox.com>
> Subject: Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
>
> On 7/29/2019 4:06 PM, Adrien Mazarguil wrote:
> > On Sun, Jul 14, 2019 at 02:46:58PM +0300, Andrew Rybchenko wrote:
> >> On 11.07.2019 10:44, Adrien Mazarguil wrote:
> >>> On Wed, Jul 10, 2019 at 04:37:46PM +0000, Yongseok Koh wrote:
> >>>>> On Jul 10, 2019, at 5:26 AM, Thomas Monjalon
> <thomas@monjalon.net> wrote:
> >>>>>
> >>>>> 10/07/2019 14:01, Bruce Richardson:
> >>>>>> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
> >>>>>>> On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson
> wrote:
> >>>>>>>> On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
> >>>>>>>>> On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
> >>>>>>>>>> Currently, metadata can be set on egress path via mbuf
> >>>>>>>>>> tx_meatadata field with PKT_TX_METADATA flag and
> RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
> >>>>>>>>>>
> >>>>>>>>>> This patch extends the usability.
> >>>>>>>>>>
> >>>>>>>>>> 1) RTE_FLOW_ACTION_TYPE_SET_META
> >>>>>>>>>>
> >>>>>>>>>> When supporting multiple tables, Tx metadata can also be set
> >>>>>>>>>> by a rule and matched by another rule. This new action allows
> >>>>>>>>>> metadata to be set as a result of flow match.
> >>>>>>>>>>
> >>>>>>>>>> 2) Metadata on ingress
> >>>>>>>>>>
> >>>>>>>>>> There's also need to support metadata on packet Rx. Metadata
> >>>>>>>>>> can be set by SET_META action and matched by META item like
> >>>>>>>>>> Tx. The final value set by the action will be delivered to
> >>>>>>>>>> application via mbuf metadata field with PKT_RX_METADATA
> ol_flag.
> >>>>>>>>>>
> >>>>>>>>>> For this purpose, mbuf->tx_metadata is moved as a separate
> >>>>>>>>>> new field and renamed to 'metadata' to support both Rx and Tx
> metadata.
> >>>>>>>>>>
> >>>>>>>>>> For loopback/hairpin packet, metadata set on Rx/Tx may or
> may
> >>>>>>>>>> not be propagated to the other path depending on HW
> capability.
> >>>>>>>>>>
> >>>>>>>>>> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
> >>>>>>>>>> --- a/lib/librte_mbuf/rte_mbuf.h
> >>>>>>>>>> +++ b/lib/librte_mbuf/rte_mbuf.h
> >>>>>>>>>> @@ -648,17 +653,6 @@ struct rte_mbuf {
> >>>>>>>>>> /**< User defined tags. See
> rte_distributor_process() */
> >>>>>>>>>> uint32_t usr;
> >>>>>>>>>> } hash; /**< hash information */
> >>>>>>>>>> - struct {
> >>>>>>>>>> - /**
> >>>>>>>>>> - * Application specific metadata value
> >>>>>>>>>> - * for egress flow rule match.
> >>>>>>>>>> - * Valid if PKT_TX_METADATA is set.
> >>>>>>>>>> - * Located here to allow conjunct use
> >>>>>>>>>> - * with hash.sched.hi.
> >>>>>>>>>> - */
> >>>>>>>>>> - uint32_t tx_metadata;
> >>>>>>>>>> - uint32_t reserved;
> >>>>>>>>>> - };
> >>>>>>>>>> };
> >>>>>>>>>>
> >>>>>>>>>> /** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set.
> >>>>>>>>>> */ @@ -727,6 +721,11 @@ struct rte_mbuf {
> >>>>>>>>>> */
> >>>>>>>>>> struct rte_mbuf_ext_shared_info *shinfo;
> >>>>>>>>>>
> >>>>>>>>>> + /** Application specific metadata value for flow rule match.
> >>>>>>>>>> + * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
> >>>>>>>>>> + */
> >>>>>>>>>> + uint32_t metadata;
> >>>>>>>>>> +
> >>>>>>>>>> } __rte_cache_aligned;
> >>>>>>>>> This will break the ABI, so we cannot put it in 19.08, and we
> >>>>>>>>> need a deprecation notice.
> >>>>>>>>>
> >>>>>>>> Does it actually break the ABI? Adding a new field to the mbuf
> >>>>>>>> should only break the ABI if it either causes new fields to
> >>>>>>>> move or changes the structure size. Since this is at the end,
> >>>>>>>> it's not going to move any older fields, and since everything
> >>>>>>>> is cache-aligned I don't think the structure size changes either.
> >>>>>>> I think it does break the ABI: in previous version, when the
> >>>>>>> PKT_TX_METADATA flag is set, the associated value is put in
> >>>>>>> m->tx_metadata (offset 44 on x86-64), and in the next version,
> >>>>>>> it will be in m->metadata (offset 112). So, these 2 versions are not
> binary compatible.
> >>>>>>>
> >>>>>>> Anyway, at least it breaks the API.
> >>>>>> Ok, I misunderstood. I thought it was the structure change itself
> >>>>>> you were saying broke the ABI. Yes, putting the data in a
> >>>>>> different place is indeed an ABI break.
> >>>>> We could add the new field and keep the old one unused, so it does
> >>>>> not break the ABI.
> >>>> Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to
> >>>> break it, I can keep the current union'd field (tx_metadata) as is
> >>>> with PKT_TX_METADATA, add the new one at the end and make it used
> with the new PKT_RX_METADATA.
> >>>>
> >>>>> However I suppose everybody will prefer a version using dynamic
> fields.
> >>>>> Is someone against using dynamic field for such usage?
> >>>> However, given that the amazing dynamic fields is coming soon
> >>>> (thanks for your effort, Olivier and Thomas!), I'd be honored to be the
> first user of it.
> >>>>
> >>>> Olivier, I'll take a look at your RFC.
> >>> Just got a crazy idea while reading this thread... How about
> >>> repurposing that "reserved" field as "rx_metadata" in the meantime?
> >>
> >> It overlaps with hash.fdir.hi which has RSS hash.
> >
> > While it does overlap with hash.fdir.hi, isn't the RSS hash stored in
> > the "rss" field overlapping with hash.fdir.lo? (see struct
> > rte_flow_action_rss)
> >
> > hash.fdir.hi was originally used by FDIR and later repurposed by
> > rte_flow for its MARK action, which neatly qualifies as Rx metadata so
> > renaming "reserved" as "rx_metadata" could already make sense.
> >
> > That is, assuming users do not need two different kinds of Rx metadata
> > returned simultaneously with their packets. I think it's safe.
> >
> >>> I know reserved fields are cursed and no one's ever supposed to
> >>> touch them but this risk is mitigated by having the end user
> >>> explicitly request its use, so the patch author (and his relatives)
> >>> should be safe from the resulting bad juju.
> >>>
> >>> Joke aside, while I like the idea of Tx/Rx META, I think the
> >>> similarities with MARK (and TAG eventually) is a problem. I wasn't
> >>> available and couldn't comment when META was originally added to the
> >>> Tx path, but there's a lot of overlap between these items/actions,
> >>> without anything explaining to the end user how and why they should
> >>> pick one over the other, if they can be combined at all and what happens
> in that case.
> >>>
> >>> All this must be documented, then we should think about unifying
> >>> their respective features and deprecate the less capable
> >>> items/actions. In my opinion, users need exactly one method to
> >>> mark/match some mark while processing Rx/Tx traffic and *optionally*
> >>> have that mark read from/written to the mbuf, which may or may not be
> possible depending on HW features.
> >
> > Thoughts regarding this suggestion? From a user perspective I think
> > all these actions should be unified but maybe there are good reasons
> > to keep them separate?
> >
>
> I think more recent plan is introducing dynamic fields for the remaining 16
> bytes in the second cacheline.
>
> I will update the patch as rejected, is there any objection?
v2 is coming, will be based on dynamic mbuf fields.
I think Superseded / Changes Requested is more relevant.
WBR, Slava
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: extend flow metadata
@ 2019-10-08 12:51 0% ` Yigit, Ferruh
2019-10-08 13:17 0% ` Slava Ovsiienko
0 siblings, 1 reply; 200+ results
From: Yigit, Ferruh @ 2019-10-08 12:51 UTC (permalink / raw)
To: Adrien Mazarguil, Andrew Rybchenko
Cc: Yongseok Koh, Thomas Monjalon, Olivier Matz, Bruce Richardson,
Shahaf Shuler, Ferruh Yigit, dev, Slava Ovsiienko
On 7/29/2019 4:06 PM, Adrien Mazarguil wrote:
> On Sun, Jul 14, 2019 at 02:46:58PM +0300, Andrew Rybchenko wrote:
>> On 11.07.2019 10:44, Adrien Mazarguil wrote:
>>> On Wed, Jul 10, 2019 at 04:37:46PM +0000, Yongseok Koh wrote:
>>>>> On Jul 10, 2019, at 5:26 AM, Thomas Monjalon <thomas@monjalon.net> wrote:
>>>>>
>>>>> 10/07/2019 14:01, Bruce Richardson:
>>>>>> On Wed, Jul 10, 2019 at 12:07:43PM +0200, Olivier Matz wrote:
>>>>>>> On Wed, Jul 10, 2019 at 10:55:34AM +0100, Bruce Richardson wrote:
>>>>>>>> On Wed, Jul 10, 2019 at 11:31:56AM +0200, Olivier Matz wrote:
>>>>>>>>> On Thu, Jul 04, 2019 at 04:21:22PM -0700, Yongseok Koh wrote:
>>>>>>>>>> Currently, metadata can be set on egress path via mbuf tx_meatadata field
>>>>>>>>>> with PKT_TX_METADATA flag and RTE_FLOW_ITEM_TYPE_RX_META matches metadata.
>>>>>>>>>>
>>>>>>>>>> This patch extends the usability.
>>>>>>>>>>
>>>>>>>>>> 1) RTE_FLOW_ACTION_TYPE_SET_META
>>>>>>>>>>
>>>>>>>>>> When supporting multiple tables, Tx metadata can also be set by a rule and
>>>>>>>>>> matched by another rule. This new action allows metadata to be set as a
>>>>>>>>>> result of flow match.
>>>>>>>>>>
>>>>>>>>>> 2) Metadata on ingress
>>>>>>>>>>
>>>>>>>>>> There's also need to support metadata on packet Rx. Metadata can be set by
>>>>>>>>>> SET_META action and matched by META item like Tx. The final value set by
>>>>>>>>>> the action will be delivered to application via mbuf metadata field with
>>>>>>>>>> PKT_RX_METADATA ol_flag.
>>>>>>>>>>
>>>>>>>>>> For this purpose, mbuf->tx_metadata is moved as a separate new field and
>>>>>>>>>> renamed to 'metadata' to support both Rx and Tx metadata.
>>>>>>>>>>
>>>>>>>>>> For loopback/hairpin packet, metadata set on Rx/Tx may or may not be
>>>>>>>>>> propagated to the other path depending on HW capability.
>>>>>>>>>>
>>>>>>>>>> Signed-off-by: Yongseok Koh <yskoh@mellanox.com>
>>>>>>>>>> --- a/lib/librte_mbuf/rte_mbuf.h
>>>>>>>>>> +++ b/lib/librte_mbuf/rte_mbuf.h
>>>>>>>>>> @@ -648,17 +653,6 @@ struct rte_mbuf {
>>>>>>>>>> /**< User defined tags. See rte_distributor_process() */
>>>>>>>>>> uint32_t usr;
>>>>>>>>>> } hash; /**< hash information */
>>>>>>>>>> - struct {
>>>>>>>>>> - /**
>>>>>>>>>> - * Application specific metadata value
>>>>>>>>>> - * for egress flow rule match.
>>>>>>>>>> - * Valid if PKT_TX_METADATA is set.
>>>>>>>>>> - * Located here to allow conjunct use
>>>>>>>>>> - * with hash.sched.hi.
>>>>>>>>>> - */
>>>>>>>>>> - uint32_t tx_metadata;
>>>>>>>>>> - uint32_t reserved;
>>>>>>>>>> - };
>>>>>>>>>> };
>>>>>>>>>>
>>>>>>>>>> /** Outer VLAN TCI (CPU order), valid if PKT_RX_QINQ is set. */
>>>>>>>>>> @@ -727,6 +721,11 @@ struct rte_mbuf {
>>>>>>>>>> */
>>>>>>>>>> struct rte_mbuf_ext_shared_info *shinfo;
>>>>>>>>>>
>>>>>>>>>> + /** Application specific metadata value for flow rule match.
>>>>>>>>>> + * Valid if PKT_RX_METADATA or PKT_TX_METADATA is set.
>>>>>>>>>> + */
>>>>>>>>>> + uint32_t metadata;
>>>>>>>>>> +
>>>>>>>>>> } __rte_cache_aligned;
>>>>>>>>> This will break the ABI, so we cannot put it in 19.08, and we need a
>>>>>>>>> deprecation notice.
>>>>>>>>>
>>>>>>>> Does it actually break the ABI? Adding a new field to the mbuf should only
>>>>>>>> break the ABI if it either causes new fields to move or changes the
>>>>>>>> structure size. Since this is at the end, it's not going to move any older
>>>>>>>> fields, and since everything is cache-aligned I don't think the structure
>>>>>>>> size changes either.
>>>>>>> I think it does break the ABI: in previous version, when the PKT_TX_METADATA
>>>>>>> flag is set, the associated value is put in m->tx_metadata (offset 44 on
>>>>>>> x86-64), and in the next version, it will be in m->metadata (offset 112). So,
>>>>>>> these 2 versions are not binary compatible.
>>>>>>>
>>>>>>> Anyway, at least it breaks the API.
>>>>>> Ok, I misunderstood. I thought it was the structure change itself you were
>>>>>> saying broke the ABI. Yes, putting the data in a different place is indeed
>>>>>> an ABI break.
>>>>> We could add the new field and keep the old one unused,
>>>>> so it does not break the ABI.
>>>> Still breaks ABI if PKT_TX_METADATA is set. :-) In order not to break it, I can
>>>> keep the current union'd field (tx_metadata) as is with PKT_TX_METADATA, add
>>>> the new one at the end and make it used with the new PKT_RX_METADATA.
>>>>
>>>>> However I suppose everybody will prefer a version using dynamic fields.
>>>>> Is someone against using dynamic field for such usage?
>>>> However, given that the amazing dynamic fields is coming soon (thanks for your
>>>> effort, Olivier and Thomas!), I'd be honored to be the first user of it.
>>>>
>>>> Olivier, I'll take a look at your RFC.
>>> Just got a crazy idea while reading this thread... How about repurposing
>>> that "reserved" field as "rx_metadata" in the meantime?
>>
>> It overlaps with hash.fdir.hi which has RSS hash.
>
> While it does overlap with hash.fdir.hi, isn't the RSS hash stored in the
> "rss" field overlapping with hash.fdir.lo? (see struct rte_flow_action_rss)
>
> hash.fdir.hi was originally used by FDIR and later repurposed by rte_flow
> for its MARK action, which neatly qualifies as Rx metadata so renaming
> "reserved" as "rx_metadata" could already make sense.
>
> That is, assuming users do not need two different kinds of Rx metadata
> returned simultaneously with their packets. I think it's safe.
>
>>> I know reserved fields are cursed and no one's ever supposed to touch them
>>> but this risk is mitigated by having the end user explicitly request its
>>> use, so the patch author (and his relatives) should be safe from the
>>> resulting bad juju.
>>>
>>> Joke aside, while I like the idea of Tx/Rx META, I think the similarities
>>> with MARK (and TAG eventually) is a problem. I wasn't available and couldn't
>>> comment when META was originally added to the Tx path, but there's a lot of
>>> overlap between these items/actions, without anything explaining to the end
>>> user how and why they should pick one over the other, if they can be
>>> combined at all and what happens in that case.
>>>
>>> All this must be documented, then we should think about unifying their
>>> respective features and deprecate the less capable items/actions. In my
>>> opinion, users need exactly one method to mark/match some mark while
>>> processing Rx/Tx traffic and *optionally* have that mark read from/written
>>> to the mbuf, which may or may not be possible depending on HW features.
>
> Thoughts regarding this suggestion? From a user perspective I think all
> these actions should be unified but maybe there are good reasons to keep
> them separate?
>
I think more recent plan is introducing dynamic fields for the remaining 16
bytes in the second cacheline.
I will update the patch as rejected, is there any objection?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 RESEND] eal: add tsc_hz to rte_mem_config
2019-10-07 15:28 3% ` [dpdk-dev] [PATCH v6 RESEND] eal: add tsc_hz to rte_mem_config Jim Harris
@ 2019-10-08 8:38 0% ` Bruce Richardson
2019-10-21 8:23 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2019-10-08 8:38 UTC (permalink / raw)
To: Jim Harris; +Cc: dev, anatoly.burakov
On Mon, Oct 07, 2019 at 08:28:21AM -0700, Jim Harris wrote:
> This ensures secondary processes never have to
> calculate the TSC rate themselves, which can be
> noticeable in VMs that don't have access to
> arch-specific detection mechanism (such as
> CPUID leaf 0x15 or MSR 0xCE on x86).
>
> Since rte_mem_config is now internal to the rte_eal
> library, we can add tsc_hz without ABI breakage
> concerns.
>
> Reduces rte_eal_init() execution time in a secondary
> process from 165ms to 66ms on my test system.
>
> Signed-off-by: Jim Harris <james.r.harris@intel.com>
> ---
This seems a good idea to me.
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v6 RESEND] eal: add tsc_hz to rte_mem_config
@ 2019-10-07 15:28 3% ` Jim Harris
2019-10-08 8:38 0% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Jim Harris @ 2019-10-07 15:28 UTC (permalink / raw)
To: dev, bruce.richardson, anatoly.burakov
This ensures secondary processes never have to
calculate the TSC rate themselves, which can be
noticeable in VMs that don't have access to
arch-specific detection mechanism (such as
CPUID leaf 0x15 or MSR 0xCE on x86).
Since rte_mem_config is now internal to the rte_eal
library, we can add tsc_hz without ABI breakage
concerns.
Reduces rte_eal_init() execution time in a secondary
process from 165ms to 66ms on my test system.
Signed-off-by: Jim Harris <james.r.harris@intel.com>
---
lib/librte_eal/common/eal_common_timer.c | 15 +++++++++++++++
lib/librte_eal/common/eal_memcfg.h | 3 +++
2 files changed, 18 insertions(+)
diff --git a/lib/librte_eal/common/eal_common_timer.c b/lib/librte_eal/common/eal_common_timer.c
index 145543de7..fa9ee1b22 100644
--- a/lib/librte_eal/common/eal_common_timer.c
+++ b/lib/librte_eal/common/eal_common_timer.c
@@ -15,8 +15,10 @@
#include <rte_log.h>
#include <rte_cycles.h>
#include <rte_pause.h>
+#include <rte_eal.h>
#include "eal_private.h"
+#include "eal_memcfg.h"
/* The frequency of the RDTSC timer resolution */
static uint64_t eal_tsc_resolution_hz;
@@ -77,8 +79,20 @@ estimate_tsc_freq(void)
void
set_tsc_freq(void)
{
+ struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
uint64_t freq;
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
+ /*
+ * Just use the primary process calculated TSC rate in any
+ * secondary process. It avoids any unnecessary overhead on
+ * systems where arch-specific frequency detection is not
+ * available.
+ */
+ eal_tsc_resolution_hz = mcfg->tsc_hz;
+ return;
+ }
+
freq = get_tsc_freq_arch();
if (!freq)
freq = get_tsc_freq();
@@ -87,6 +101,7 @@ set_tsc_freq(void)
RTE_LOG(DEBUG, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", freq / 1000);
eal_tsc_resolution_hz = freq;
+ mcfg->tsc_hz = freq;
}
void rte_delay_us_callback_register(void (*userfunc)(unsigned int))
diff --git a/lib/librte_eal/common/eal_memcfg.h b/lib/librte_eal/common/eal_memcfg.h
index 359beb216..73be6fbae 100644
--- a/lib/librte_eal/common/eal_memcfg.h
+++ b/lib/librte_eal/common/eal_memcfg.h
@@ -70,6 +70,9 @@ struct rte_mem_config {
uint32_t single_file_segments;
/**< stored single file segments parameter. */
+ uint64_t tsc_hz;
+ /**< TSC rate */
+
uint8_t dma_maskbits; /**< Keeps the more restricted dma mask. */
};
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 2/2] build: support building ABI versioned files twice
2019-10-01 16:53 4% ` Bruce Richardson
@ 2019-10-07 15:57 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-07 15:57 UTC (permalink / raw)
To: Andrzej Ostruszka; +Cc: dev, Thomas Monjalon, Ray Kinsella, Neil Horman, bluca
On Tue, Oct 01, 2019 at 05:53:05PM +0100, Bruce Richardson wrote:
> On Tue, Oct 01, 2019 at 03:23:47PM +0200, Andrzej Ostruszka wrote:
> > Thanks Bruce for the patch. I like the idea of splitting versioning out
> > of rte_compat.h, but I have some comments.
> >
> > On 9/27/19 10:59 PM, Bruce Richardson wrote:
> > [...]
> > > --- a/config/common_base
> > > +++ b/config/common_base
> > > @@ -111,6 +111,7 @@ CONFIG_RTE_MAX_VFIO_CONTAINERS=64
> > > CONFIG_RTE_MALLOC_DEBUG=n
> > > CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
> > > CONFIG_RTE_USE_LIBBSD=n
> > > +CONFIG_RTE_USE_FUNCTION_VERSIONING=y
> >
> > I'm not fond of this config option - it is not really an option to be
> > changed by the user. I would prefer to just add flag to CFLAGS in
> > mk/target/generic/rte.vars.mk.
> >
>
> Ok, that sounds reasonable enough.
Done in V3.
>
> > > #
> > > # Recognize/ignore the AVX/AVX512 CPU flags for performance/power testing.
> > > diff --git a/config/rte_config.h b/config/rte_config.h
> > > index 0bbbe274f..b63a2fdea 100644
> > > --- a/config/rte_config.h
> > > +++ b/config/rte_config.h
> > > @@ -31,9 +31,6 @@
> > >
> > > /****** library defines ********/
> > >
> > > -/* compat defines */
> > > -#define RTE_BUILD_SHARED_LIB
> > > -
> >
> > So now everything builds "as static lib" (but with "-fPIC") apart from
> > those libraries that use symbol versioning. I'm OK with that however
> > I'd like to note that code might be using RTE_BUILD_SHARED_LIB and do
> > different things e.g. app/test-bbdev/test_bbdev_perf.c. I know that was
> > already the case - just wanted to say that aloud to make sure we are all
> > aware of this :).
>
> Thanks for pointing this out, I wasn't aware of it! Doing a git grep this
> seems to be the only place in a C file (other than rte_config.h and
> rte_compat.h) where the SHARED_LIB flag is being checked. I'll need to
> follow up on that to see what the logic is there, because it seems strange
> to require such a check.
>
This #ifdef can be removed, see patchset:
http://patches.dpdk.org/project/dpdk/list/?series=6699
This then leaves function versioning as the only use-case where we need
different code paths for static vs shared builds.
> >
> > > diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
> > > index 449b33494..e95a1a2be 100644
> > > --- a/doc/guides/contributing/coding_style.rst
> > > +++ b/doc/guides/contributing/coding_style.rst
> > > @@ -948,6 +948,13 @@ reason
> > > built. For missing dependencies this should be of the form
> > > ``'missing dependency, "libname"'``.
> > >
> > > +use_function_versioning
> > > + **Default Value = false**.
> > > + Specifies if the library in question has ABI versioned functions. If it
> > > + has, this value should be set to ensure that the C files are compiled
> > > + twice with suitable parameters for each of shared or static library
> > > + builds.
> > > +
> >
> > Maybe a different name for this option? In general an "ideal
> > theoretical" solution would be for build system to figure out on its own
> > that separate build is necessary automatically - but that might incur
> > some performance penalty (additional grep'ing of sources or so).
>
> I was thinking about that, and how we can do it automatically. The trouble
> is that for correctness we would need to recheck every file after it had
> changed, and since the result of the check means that we have different
> build steps it would basically mean doing a full reconfiguration for every
> file change. That's not really practical, hence this proposed solution.
>
I've not made any changes here for the V3. However, if we want to reduce
the number of changes required, we could always switch to having the
rte_function_versioning.h header file included on the basis of the flag in
the meson.build file. Having the C flag compile vary based on the meson one
is normal, having the inverse is problematic because of what I explained
above - you'd basically need to reconfigure to check after each file
change.
Personally, I don't think changing things to auto-include the header is
worth it, hence the fact of no-change in v3.
Regards,
/Bruce
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 2/2] build: support building ABI versioned files twice
2019-10-07 15:45 3% ` [dpdk-dev] [PATCH v3 0/2] Improve function versioning meson support Bruce Richardson
2019-10-07 15:45 10% ` [dpdk-dev] [PATCH v3 1/2] eal: split compat header file Bruce Richardson
@ 2019-10-07 15:45 15% ` Bruce Richardson
1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-07 15:45 UTC (permalink / raw)
To: dev; +Cc: Andrzej Ostruszka, Neil Horman, bluca, thomas, Bruce Richardson
Any file with ABI versioned functions needs different macros for shared and
static builds, so we need to accomodate that. Rather than building
everything twice, we just flag to the build system which libraries need
that handling, by setting use_function_versioning in the meson.build files.
To ensure we don't get silent errors at build time due to this meson flag
being missed, we add an explicit error to the function versioning header
file if a known C macro is not defined. Since "make" builds always only
build one of shared or static libraries, this define can be always set, and
so is added to the global CFLAGS. For meson, the build flag - and therefore
the C define - is set for the three libraries that need the function
versioning: "distributor", "lpm" and "timer".
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Tested-by: Andrzej Ostruszka <amo@semihalf.com>
---
v3: move define from common_base to generic/rte.vars.mk
---
config/rte_config.h | 3 ---
doc/guides/contributing/coding_style.rst | 7 +++++++
lib/librte_distributor/meson.build | 1 +
.../common/include/rte_function_versioning.h | 4 ++++
lib/librte_lpm/meson.build | 1 +
lib/librte_timer/meson.build | 1 +
lib/meson.build | 16 +++++++++++++---
mk/target/generic/rte.vars.mk | 8 ++++++++
8 files changed, 35 insertions(+), 6 deletions(-)
diff --git a/config/rte_config.h b/config/rte_config.h
index 0bbbe274f..b63a2fdea 100644
--- a/config/rte_config.h
+++ b/config/rte_config.h
@@ -31,9 +31,6 @@
/****** library defines ********/
-/* compat defines */
-#define RTE_BUILD_SHARED_LIB
-
/* EAL defines */
#define RTE_MAX_HEAPS 32
#define RTE_MAX_MEMSEG_LISTS 128
diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
index 449b33494..e95a1a2be 100644
--- a/doc/guides/contributing/coding_style.rst
+++ b/doc/guides/contributing/coding_style.rst
@@ -948,6 +948,13 @@ reason
built. For missing dependencies this should be of the form
``'missing dependency, "libname"'``.
+use_function_versioning
+ **Default Value = false**.
+ Specifies if the library in question has ABI versioned functions. If it
+ has, this value should be set to ensure that the C files are compiled
+ twice with suitable parameters for each of shared or static library
+ builds.
+
version
**Default Value = 1**.
Specifies the ABI version of the library, and is used as the major
diff --git a/lib/librte_distributor/meson.build b/lib/librte_distributor/meson.build
index dba7e3b2a..5149f9bf5 100644
--- a/lib/librte_distributor/meson.build
+++ b/lib/librte_distributor/meson.build
@@ -9,3 +9,4 @@ else
endif
headers = files('rte_distributor.h')
deps += ['mbuf']
+use_function_versioning = true
diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h
index ce963d4b1..55e88ffae 100644
--- a/lib/librte_eal/common/include/rte_function_versioning.h
+++ b/lib/librte_eal/common/include/rte_function_versioning.h
@@ -7,6 +7,10 @@
#define _RTE_FUNCTION_VERSIONING_H_
#include <rte_common.h>
+#ifndef RTE_USE_FUNCTION_VERSIONING
+#error Use of function versioning disabled, is "use_function_versioning=true" in meson.build?
+#endif
+
#ifdef RTE_BUILD_SHARED_LIB
/*
diff --git a/lib/librte_lpm/meson.build b/lib/librte_lpm/meson.build
index a5176d8ae..4e3920660 100644
--- a/lib/librte_lpm/meson.build
+++ b/lib/librte_lpm/meson.build
@@ -8,3 +8,4 @@ headers = files('rte_lpm.h', 'rte_lpm6.h')
# without worrying about which architecture we actually need
headers += files('rte_lpm_altivec.h', 'rte_lpm_neon.h', 'rte_lpm_sse.h')
deps += ['hash']
+use_function_versioning = true
diff --git a/lib/librte_timer/meson.build b/lib/librte_timer/meson.build
index d3b828ce9..b7edfe2e7 100644
--- a/lib/librte_timer/meson.build
+++ b/lib/librte_timer/meson.build
@@ -4,3 +4,4 @@
sources = files('rte_timer.c')
headers = files('rte_timer.h')
allow_experimental_apis = true
+use_function_versioning = true
diff --git a/lib/meson.build b/lib/meson.build
index e5ff83893..1b0ed767c 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -47,6 +47,7 @@ foreach l:libraries
name = l
version = 1
allow_experimental_apis = false
+ use_function_versioning = false
sources = []
headers = []
includes = []
@@ -96,6 +97,9 @@ foreach l:libraries
if allow_experimental_apis
cflags += '-DALLOW_EXPERIMENTAL_API'
endif
+ if use_function_versioning
+ cflags += '-DRTE_USE_FUNCTION_VERSIONING'
+ endif
if get_option('per_library_versions')
lib_version = '@0@.1'.format(version)
@@ -117,9 +121,15 @@ foreach l:libraries
include_directories: includes,
dependencies: static_deps)
- # then use pre-build objects to build shared lib
- sources = []
- objs += static_lib.extract_all_objects(recursive: false)
+ if not use_function_versioning
+ # use pre-build objects to build shared lib
+ sources = []
+ objs += static_lib.extract_all_objects(recursive: false)
+ else
+ # for compat we need to rebuild with
+ # RTE_BUILD_SHARED_LIB defined
+ cflags += '-DRTE_BUILD_SHARED_LIB'
+ endif
version_map = '@0@/@1@/rte_@2@_version.map'.format(
meson.current_source_dir(), dir_name, name)
implib = dir_name + '.dll.a'
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index 5f00a0bfa..374722173 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -90,6 +90,14 @@ ASFLAGS += $(TARGET_ASFLAGS)
CFLAGS += -I$(RTE_OUTPUT)/include
LDFLAGS += -L$(RTE_OUTPUT)/lib
+# add in flag for supporting function versioning. The define is used in meson
+# builds to ensure that the user has properly flagged the unit in question as
+# using function versioning so it can be built twice - once for static lib and
+# then a second time for the shared lib. Since make only builds one library
+# type at a time, such precautions aren't necessary, so we can globally define
+# the flag
+CFLAGS += -DRTE_USE_FUNCTION_VERSIONING
+
# always include rte_config.h: the one in $(RTE_OUTPUT)/include is
# the configuration of SDK when $(BUILDING_RTE_SDK) is true, or the
# configuration of the application if $(BUILDING_RTE_SDK) is not
--
2.21.0
^ permalink raw reply [relevance 15%]
* [dpdk-dev] [PATCH v3 1/2] eal: split compat header file
2019-10-07 15:45 3% ` [dpdk-dev] [PATCH v3 0/2] Improve function versioning meson support Bruce Richardson
@ 2019-10-07 15:45 10% ` Bruce Richardson
2019-10-07 15:45 15% ` [dpdk-dev] [PATCH v3 2/2] build: support building ABI versioned files twice Bruce Richardson
1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2019-10-07 15:45 UTC (permalink / raw)
To: dev; +Cc: Andrzej Ostruszka, Neil Horman, bluca, thomas, Bruce Richardson
The compat.h header file provided macros for two purposes:
1. it provided the macros for marking functions as rte_experimental
2. it provided the macros for doing function versioning
Although these were in the same file, #1 is something that is for use by
public header files, which #2 is for internal use only. Therefore, we can
split these into two headers, keeping #1 in rte_compat.h and #2 in a new
file rte_function_versioning.h. For "make" builds, since internal objects
pick up the headers from the "include/" folder, we need to add the new
header to the installation list, but for "meson" builds it does not need to
be installed as it's not for public use.
The rework also serves to allow the use of the function versioning macros
to files that actually need them, so the use of experimental functions does
not need including of the versioning code.
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/api/doxy-api-index.md | 3 +-
doc/guides/contributing/versioning.rst | 4 +-
lib/librte_distributor/rte_distributor.c | 2 +-
lib/librte_distributor/rte_distributor_v20.c | 2 +-
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/include/rte_compat.h | 70 ----------------
.../common/include/rte_function_versioning.h | 79 +++++++++++++++++++
lib/librte_lpm/rte_lpm.c | 1 +
lib/librte_lpm/rte_lpm.h | 1 -
lib/librte_lpm/rte_lpm6.c | 1 +
lib/librte_timer/rte_timer.c | 2 +-
11 files changed, 89 insertions(+), 77 deletions(-)
create mode 100644 lib/librte_eal/common/include/rte_function_versioning.h
diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 6c2d888ee..9acf36ba1 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -171,5 +171,6 @@ The public API headers are grouped by topics:
- **misc**:
[EAL config] (@ref rte_eal.h),
[common] (@ref rte_common.h),
- [ABI compat] (@ref rte_compat.h),
+ [experimental APIs] (@ref rte_compat.h),
+ [ABI versioning] (@ref rte_function_versioning.h),
[version] (@ref rte_version.h)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 3ab2c4346..64984c54e 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -206,7 +206,7 @@ functionality or behavior. When that occurs, it is desirable to allow for
backward compatibility for a time with older binaries that are dynamically
linked to the DPDK.
-To support backward compatibility the ``rte_compat.h``
+To support backward compatibility the ``rte_function_versioning.h``
header file provides macros to use when updating exported functions. These
macros are used in conjunction with the ``rte_<library>_version.map`` file for
a given library to allow multiple versions of a symbol to exist in a shared
@@ -362,7 +362,7 @@ the function, we add this line of code
VERSION_SYMBOL(rte_acl_create, _v20, 2.0);
-Remembering to also add the rte_compat.h header to the requisite c file where
+Remembering to also add the rte_function_versioning.h header to the requisite c file where
these changes are being made. The above macro instructs the linker to create a
new symbol ``rte_acl_create@DPDK_2.0``, which matches the symbol created in older
builds, but now points to the above newly named function. We have now mapped
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index 21eb1fb0a..6d1e971a9 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -8,7 +8,7 @@
#include <rte_mbuf.h>
#include <rte_memory.h>
#include <rte_cycles.h>
-#include <rte_compat.h>
+#include <rte_function_versioning.h>
#include <rte_memzone.h>
#include <rte_errno.h>
#include <rte_string_fns.h>
diff --git a/lib/librte_distributor/rte_distributor_v20.c b/lib/librte_distributor/rte_distributor_v20.c
index cdc0969a8..64c611fa9 100644
--- a/lib/librte_distributor/rte_distributor_v20.c
+++ b/lib/librte_distributor/rte_distributor_v20.c
@@ -9,7 +9,7 @@
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_errno.h>
-#include <rte_compat.h>
+#include <rte_function_versioning.h>
#include <rte_string_fns.h>
#include <rte_eal_memconfig.h>
#include <rte_pause.h>
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index a00d4fcad..d70f84fd7 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -4,6 +4,7 @@
include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h rte_compat.h
+INC += rte_function_versioning.h
INC += rte_debug.h rte_eal.h rte_eal_interrupts.h
INC += rte_errno.h rte_launch.h rte_lcore.h
INC += rte_log.h rte_memory.h rte_memzone.h
diff --git a/lib/librte_eal/common/include/rte_compat.h b/lib/librte_eal/common/include/rte_compat.h
index 92ff28faf..3eb33784b 100644
--- a/lib/librte_eal/common/include/rte_compat.h
+++ b/lib/librte_eal/common/include/rte_compat.h
@@ -5,76 +5,6 @@
#ifndef _RTE_COMPAT_H_
#define _RTE_COMPAT_H_
-#include <rte_common.h>
-
-#ifdef RTE_BUILD_SHARED_LIB
-
-/*
- * Provides backwards compatibility when updating exported functions.
- * When a symol is exported from a library to provide an API, it also provides a
- * calling convention (ABI) that is embodied in its name, return type,
- * arguments, etc. On occasion that function may need to change to accommodate
- * new functionality, behavior, etc. When that occurs, it is desirable to
- * allow for backwards compatibility for a time with older binaries that are
- * dynamically linked to the dpdk. To support that, the __vsym and
- * VERSION_SYMBOL macros are created. They, in conjunction with the
- * <library>_version.map file for a given library allow for multiple versions of
- * a symbol to exist in a shared library so that older binaries need not be
- * immediately recompiled.
- *
- * Refer to the guidelines document in the docs subdirectory for details on the
- * use of these macros
- */
-
-/*
- * Macro Parameters:
- * b - function base name
- * e - function version extension, to be concatenated with base name
- * n - function symbol version string to be applied
- * f - function prototype
- * p - full function symbol name
- */
-
-/*
- * VERSION_SYMBOL
- * Creates a symbol version table entry binding symbol <b>@DPDK_<n> to the internal
- * function name <b>_<e>
- */
-#define VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
-
-/*
- * BIND_DEFAULT_SYMBOL
- * Creates a symbol version entry instructing the linker to bind references to
- * symbol <b> to the internal symbol <b>_<e>
- */
-#define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n))
-#define __vsym __attribute__((used))
-
-/*
- * MAP_STATIC_SYMBOL
- * If a function has been bifurcated into multiple versions, none of which
- * are defined as the exported symbol name in the map file, this macro can be
- * used to alias a specific version of the symbol to its exported name. For
- * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
- * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
- * building a shared library, this macro can be used to map either foo_v1 or
- * foo_v2 to the symbol foo when building a static library, e.g.:
- * MAP_STATIC_SYMBOL(void foo(), foo_v2);
- */
-#define MAP_STATIC_SYMBOL(f, p)
-
-#else
-/*
- * No symbol versioning in use
- */
-#define VERSION_SYMBOL(b, e, n)
-#define __vsym
-#define BIND_DEFAULT_SYMBOL(b, e, n)
-#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p))))
-/*
- * RTE_BUILD_SHARED_LIB=n
- */
-#endif
#ifndef ALLOW_EXPERIMENTAL_API
diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h
new file mode 100644
index 000000000..ce963d4b1
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_function_versioning.h
@@ -0,0 +1,79 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2015 Neil Horman <nhorman@tuxdriver.com>.
+ * All rights reserved.
+ */
+
+#ifndef _RTE_FUNCTION_VERSIONING_H_
+#define _RTE_FUNCTION_VERSIONING_H_
+#include <rte_common.h>
+
+#ifdef RTE_BUILD_SHARED_LIB
+
+/*
+ * Provides backwards compatibility when updating exported functions.
+ * When a symol is exported from a library to provide an API, it also provides a
+ * calling convention (ABI) that is embodied in its name, return type,
+ * arguments, etc. On occasion that function may need to change to accommodate
+ * new functionality, behavior, etc. When that occurs, it is desirable to
+ * allow for backwards compatibility for a time with older binaries that are
+ * dynamically linked to the dpdk. To support that, the __vsym and
+ * VERSION_SYMBOL macros are created. They, in conjunction with the
+ * <library>_version.map file for a given library allow for multiple versions of
+ * a symbol to exist in a shared library so that older binaries need not be
+ * immediately recompiled.
+ *
+ * Refer to the guidelines document in the docs subdirectory for details on the
+ * use of these macros
+ */
+
+/*
+ * Macro Parameters:
+ * b - function base name
+ * e - function version extension, to be concatenated with base name
+ * n - function symbol version string to be applied
+ * f - function prototype
+ * p - full function symbol name
+ */
+
+/*
+ * VERSION_SYMBOL
+ * Creates a symbol version table entry binding symbol <b>@DPDK_<n> to the internal
+ * function name <b>_<e>
+ */
+#define VERSION_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@DPDK_" RTE_STR(n))
+
+/*
+ * BIND_DEFAULT_SYMBOL
+ * Creates a symbol version entry instructing the linker to bind references to
+ * symbol <b> to the internal symbol <b>_<e>
+ */
+#define BIND_DEFAULT_SYMBOL(b, e, n) __asm__(".symver " RTE_STR(b) RTE_STR(e) ", " RTE_STR(b) "@@DPDK_" RTE_STR(n))
+#define __vsym __attribute__((used))
+
+/*
+ * MAP_STATIC_SYMBOL
+ * If a function has been bifurcated into multiple versions, none of which
+ * are defined as the exported symbol name in the map file, this macro can be
+ * used to alias a specific version of the symbol to its exported name. For
+ * example, if you have 2 versions of a function foo_v1 and foo_v2, where the
+ * former is mapped to foo@DPDK_1 and the latter is mapped to foo@DPDK_2 when
+ * building a shared library, this macro can be used to map either foo_v1 or
+ * foo_v2 to the symbol foo when building a static library, e.g.:
+ * MAP_STATIC_SYMBOL(void foo(), foo_v2);
+ */
+#define MAP_STATIC_SYMBOL(f, p)
+
+#else
+/*
+ * No symbol versioning in use
+ */
+#define VERSION_SYMBOL(b, e, n)
+#define __vsym
+#define BIND_DEFAULT_SYMBOL(b, e, n)
+#define MAP_STATIC_SYMBOL(f, p) f __attribute__((alias(RTE_STR(p))))
+/*
+ * RTE_BUILD_SHARED_LIB=n
+ */
+#endif
+
+#endif /* _RTE_FUNCTION_VERSIONING_H_ */
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index 3a929a1b1..c96395e26 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -22,6 +22,7 @@
#include <rte_rwlock.h>
#include <rte_spinlock.h>
#include <rte_tailq.h>
+#include <rte_function_versioning.h>
#include "rte_lpm.h"
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index 906ec4483..26303e628 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -20,7 +20,6 @@
#include <rte_memory.h>
#include <rte_common.h>
#include <rte_vect.h>
-#include <rte_compat.h>
#ifdef __cplusplus
extern "C" {
diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c
index 9b8aeb972..e20f82460 100644
--- a/lib/librte_lpm/rte_lpm6.c
+++ b/lib/librte_lpm/rte_lpm6.c
@@ -25,6 +25,7 @@
#include <assert.h>
#include <rte_jhash.h>
#include <rte_tailq.h>
+#include <rte_function_versioning.h>
#include "rte_lpm6.h"
diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
index bdcf05d06..3834c9473 100644
--- a/lib/librte_timer/rte_timer.c
+++ b/lib/librte_timer/rte_timer.c
@@ -25,8 +25,8 @@
#include <rte_pause.h>
#include <rte_memzone.h>
#include <rte_malloc.h>
-#include <rte_compat.h>
#include <rte_errno.h>
+#include <rte_function_versioning.h>
#include "rte_timer.h"
--
2.21.0
^ permalink raw reply [relevance 10%]
* [dpdk-dev] [PATCH v3 0/2] Improve function versioning meson support
@ 2019-10-07 15:45 3% ` Bruce Richardson
2019-10-07 15:45 10% ` [dpdk-dev] [PATCH v3 1/2] eal: split compat header file Bruce Richardson
2019-10-07 15:45 15% ` [dpdk-dev] [PATCH v3 2/2] build: support building ABI versioned files twice Bruce Richardson
2019-10-09 22:59 0% ` [dpdk-dev] [PATCH 0/2] Improve function versioning meson support Stephen Hemminger
2 siblings, 2 replies; 200+ results
From: Bruce Richardson @ 2019-10-07 15:45 UTC (permalink / raw)
To: dev; +Cc: Andrzej Ostruszka, Neil Horman, bluca, thomas, Bruce Richardson
Adding support for LTO has exposed some issues with how the functions
versioning was supported by meson, which was always set to build both
shared and static libraries.
For plain C code, so long as the -fPIC compiler flag was passed, the
output is identical whether or not the code is to be included in a
static library or a dynamic one. Unfortunately, when using function
versioning that no longer held as different macros were used for the
versioned functions depending on which type of build it was. This means
that any files that use versioning need to be built twice, with
different defines in each case.
While the trivial solution here is just to rebuild everything twice,
that involves a lot of unnecessary work when building DPDK. A better
option is to identify those files or components which need multiple
builds and rebuild only those. To do this, we add a new meson.build
setting for libraries "use_function_versioning" and when that is set, we
rebuild all source files twice, initially for static library and then
with -DRTE_BUILD_SHARED_LIB for the shared library.
If the flag is not set, then the static versioning setting only is used,
which could lead to the build succeeding but later causing problems. To
avoid that, we add a new define which must be set when the versioning
header is included. This addition while solving 1 problem raises 2
other, more minor problems:
* what to do with make builds? since make only builds one library type,
we can just always define the new value.
* what about files that include rte_compat.h for the macro for
"experimental"? To solve this, we can split compat.h in two, since the
versioning macro should be internal only to DPDK (as no public header
should expose anything but the latest APIs), while the experimental
macros are primarily for public use.
V3: following feedback, moved the define for make from the common_base
build config file to one of the global makefiles, as it's not user
tunable.
V2: added in file that missed a "git add" when doing V1
Bruce Richardson (2):
eal: split compat header file
build: support building ABI versioned files twice
config/rte_config.h | 3 -
doc/api/doxy-api-index.md | 3 +-
doc/guides/contributing/coding_style.rst | 7 ++
doc/guides/contributing/versioning.rst | 4 +-
lib/librte_distributor/meson.build | 1 +
lib/librte_distributor/rte_distributor.c | 2 +-
lib/librte_distributor/rte_distributor_v20.c | 2 +-
lib/librte_eal/common/Makefile | 1 +
lib/librte_eal/common/include/rte_compat.h | 70 ----------------
.../common/include/rte_function_versioning.h | 83 +++++++++++++++++++
lib/librte_lpm/meson.build | 1 +
lib/librte_lpm/rte_lpm.c | 1 +
lib/librte_lpm/rte_lpm.h | 1 -
lib/librte_lpm/rte_lpm6.c | 1 +
lib/librte_timer/meson.build | 1 +
lib/librte_timer/rte_timer.c | 2 +-
lib/meson.build | 16 +++-
mk/target/generic/rte.vars.mk | 8 ++
18 files changed, 124 insertions(+), 83 deletions(-)
create mode 100644 lib/librte_eal/common/include/rte_function_versioning.h
--
2.21.0
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v5 0/5] mbuf copy/cloning enhancements
` (2 preceding siblings ...)
2019-10-04 21:47 3% ` [dpdk-dev] [PATCH v4 0/4] " Stephen Hemminger
@ 2019-10-07 15:43 3% ` Stephen Hemminger
2019-10-08 16:33 3% ` [dpdk-dev] [PATCH v6 0/5] mbuf: " Stephen Hemminger
4 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-07 15:43 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This patch set is all about improving the mbuf related cloning
and copying. They are motivated by seeing issues with mbuf copying
in rte_pdump and realized this a wider and more general problem.
The pdump copy could not handle different size pools and did
not handle meta data, etc.
They cause no functional or ABI changes. The only visible part
to older code is converting a couple of inlines to real functions.
This kind of change confuses checkpatch which thinks these new
functions should be marked experimental when they must not be.
v5 - add back the test (dropped by accident in v4)
v4 - common mbuf header fields copy routine
v3 - split linearize into internal/external
copy private data in pktmbuf_copy
v2 - add pdump use of pktmbuf_copy
fix version in map
Stephen Hemminger (5):
mbuf: don't generate invalid mbuf in clone test
mbuf: delinline rte_pktmbuf_linearize
mbuf: deinline rte_pktmbuf_clone
mbuf: add a pktmbuf copy routine
mbuf: add pktmbuf copy test
app/test/test_mbuf.c | 129 ++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.c | 145 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 127 +++++++++--------------
lib/librte_mbuf/rte_mbuf_version.map | 8 ++
4 files changed, 332 insertions(+), 77 deletions(-)
--
2.20.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-03 13:24 0% ` Akhil Goyal
@ 2019-10-07 12:53 0% ` Ananyev, Konstantin
2019-10-09 7:20 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-07 12:53 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon'
Cc: Zhang, Roy Fan, Doherty, Declan, 'Anoob Joseph'
Hi Akhil,
> > > > > > > > > > > > > > > This action type allows the burst of symmetric crypto
> > > > workload
> > > > > > using
> > > > > > > > > the
> > > > > > > > > > > > > same
> > > > > > > > > > > > > > > algorithm, key, and direction being processed by CPU
> > cycles
> > > > > > > > > > > synchronously.
> > > > > > > > > > > > > > > This flexible action type does not require external
> > hardware
> > > > > > > > > involvement,
> > > > > > > > > > > > > > > having the crypto workload processed synchronously,
> > and is
> > > > > > more
> > > > > > > > > > > > > performant
> > > > > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on
> > removed
> > > > > > "async
> > > > > > > > > > > mode
> > > > > > > > > > > > > > > simulation" as well as 3 cacheline access of the crypto
> > ops.
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > Does that mean application will not call the
> > > > > > cryptodev_enqueue_burst
> > > > > > > > > and
> > > > > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Yes, instead it just call
> > rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > > > > >
> > > > > > > > > > > > > > It would be a new API something like process_packets and
> > it
> > > > will
> > > > > > have
> > > > > > > > > the
> > > > > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > > > > >
> > > > > > > > > > > > > Yes, though the plan is that API will operate on raw data
> > buffers,
> > > > > > not
> > > > > > > > > mbufs.
> > > > > > > > > > > > >
> > > > > > > > > > > > > >
> > > > > > > > > > > > > > I still do not understand why we cannot do with the
> > > > conventional
> > > > > > > > > crypto lib
> > > > > > > > > > > > > only.
> > > > > > > > > > > > > > As far as I can understand, you are not doing any protocol
> > > > > > processing
> > > > > > > > > or
> > > > > > > > > > > any
> > > > > > > > > > > > > value add
> > > > > > > > > > > > > > To the crypto processing. IMO, you just need a
> > synchronous
> > > > > > crypto
> > > > > > > > > > > processing
> > > > > > > > > > > > > API which
> > > > > > > > > > > > > > Can be defined in cryptodev, you don't need to re-create a
> > > > crypto
> > > > > > > > > session
> > > > > > > > > > > in
> > > > > > > > > > > > > the name of
> > > > > > > > > > > > > > Security session in the driver just to do a synchronous
> > > > processing.
> > > > > > > > > > > > >
> > > > > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > > > > The main reason is that would require disruptive changes in
> > > > existing
> > > > > > > > > > > cryptodev
> > > > > > > > > > > > > API
> > > > > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > need
> > > > > > some
> > > > > > > > > extra
> > > > > > > > > > > > > information
> > > > > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > > > > (cipher offset from the start of the buffer, might be
> > something
> > > > extra
> > > > > > in
> > > > > > > > > > > future).
> > > > > > > > > > > >
> > > > > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > > > > >
> > > > > > > > > > > fill/read (+ alloc/free) is one of the main things that slowdown
> > > > current
> > > > > > > > > crypto-op
> > > > > > > > > > > approach.
> > > > > > > > > > > That's why the general idea - have all data that wouldn't change
> > > > from
> > > > > > packet
> > > > > > > > > to
> > > > > > > > > > > packet
> > > > > > > > > > > included into the session and setup it once at session_init().
> > > > > > > > > >
> > > > > > > > > > I agree that you cannot use crypto-op.
> > > > > > > > > > You can have the new API in crypto.
> > > > > > > > > > As per the current patch, you only need cipher_offset which you
> > can
> > > > have
> > > > > > it as
> > > > > > > > > a parameter until
> > > > > > > > > > You get it approved in the crypto xform. I believe it will be
> > beneficial
> > > > in
> > > > > > case of
> > > > > > > > > other crypto cases as well.
> > > > > > > > > > We can have cipher offset at both places(crypto-op and
> > > > cipher_xform). It
> > > > > > will
> > > > > > > > > give flexibility to the user to
> > > > > > > > > > override it.
> > > > > > > > >
> > > > > > > > > After having another thought on your proposal:
> > > > > > > > > Probably we can introduce new rte_crypto_sym_xform_types for
> > CPU
> > > > > > related
> > > > > > > > > stuff here?
> > > > > > > >
> > > > > > > > I also thought of adding new xforms, but that wont serve the purpose
> > for
> > > > > > may be all the cases.
> > > > > > > > You would be needing all information currently available in the
> > current
> > > > > > xforms.
> > > > > > > > So if you are adding new fields in the new xform, the size will be more
> > > > than
> > > > > > that of the union of xforms.
> > > > > > > > ABI breakage would still be there.
> > > > > > > >
> > > > > > > > If you think a valid compression of the AEAD xform can be done, then
> > > > that
> > > > > > can be done for each of the
> > > > > > > > Xforms and we can have a solution to this issue.
> > > > > > >
> > > > > > > I think that we can re-use iv.offset for our purposes (for crypto offset).
> > > > > > > So for now we can make that path work without any ABI breakage.
> > > > > > > Fan, please feel free to correct me here, if I missed something.
> > > > > > > If in future we would need to add some extra information it might
> > > > > > > require ABI breakage, though by now I don't envision anything
> > particular to
> > > > > > add.
> > > > > > > Anyway, if there is no objection to go that way, we can try to make
> > > > > > > these changes for v2.
> > > > > > >
> > > > > >
> > > > > > Actually, after looking at it more deeply it appears not that easy as I
> > thought
> > > > it
> > > > > > would be :)
> > > > > > Below is a very draft version of proposed API additions.
> > > > > > I think it avoids ABI breakages right now and provides enough flexibility
> > for
> > > > > > future extensions (if any).
> > > > > > For now, it doesn't address your comments about naming conventions
> > > > (_CPU_
> > > > > > vs _SYNC_) , etc.
> > > > > > but I suppose is comprehensive enough to provide a main idea beyond it.
> > > > > > Akhil and other interested parties, please try to review and provide
> > feedback
> > > > > > ASAP,
> > > > > > as related changes would take some time and we still like to hit 19.11
> > > > deadline.
> > > > > > Konstantin
> > > > > >
> > > > > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > index bc8da2466..c03069e23 100644
> > > > > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > > > > *
> > > > > > * This structure contains data relating to Cipher (Encryption and
> > Decryption)
> > > > > > * use to create a session.
> > > > > > + * Actually I was wrong saying that we don't have free space inside
> > xforms.
> > > > > > + * Making key struct packed (see below) allow us to regain 6B that could
> > be
> > > > > > + * used for future extensions.
> > > > > > */
> > > > > > struct rte_crypto_cipher_xform {
> > > > > > enum rte_crypto_cipher_operation op;
> > > > > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > > > > struct {
> > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > uint16_t length; /**< key length in bytes */
> > > > > > - } key;
> > > > > > + } __attribute__((__packed__)) key;
> > > > > > +
> > > > > > + /**
> > > > > > + * offset for cipher to start within user provided data buffer.
> > > > > > + * Fan suggested another (and less space consuming way) -
> > > > > > + * reuse iv.offset space below, by changing:
> > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > + * to uunamed union:
> > > > > > + * union {
> > > > > > + * struct {uint16_t offset, length;} iv;
> > > > > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > > > > + * };
> > > > > > + * Both approaches seems ok to me in general.
> > > > >
> > > > > No strong opinions here. OK with this one.
> > > > >
> > > > > > + * Comments/suggestions are welcome.
> > > > > > + */
> > > > > > + uint16_t offset;
> > > >
> > > > After another thought - it is probably a bit better to have offset as a separate
> > > > field.
> > > > In that case we can use the same xforms to create both type of sessions.
> > > ok
> > > >
> > > > > > +
> > > > > > + uint8_t reserved1[4];
> > > > > > +
> > > > > > /**< Cipher key
> > > > > > *
> > > > > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation,
> > key.data
> > > > will
> > > > > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > > > > struct {
> > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > uint16_t length; /**< key length in bytes */
> > > > > > - } key;
> > > > > > + } __attribute__((__packed__)) key;
> > > > > > /**< Authentication key data.
> > > > > > * The authentication key length MUST be less than or equal to the
> > > > > > * block size of the algorithm. It is the callers responsibility to
> > > > > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > > > > * (for example RFC 2104, FIPS 198a).
> > > > > > */
> > > > > >
> > > > > > + uint8_t reserved1[6];
> > > > > > +
> > > > > > struct {
> > > > > > uint16_t offset;
> > > > > > /**< Starting point for Initialisation Vector or Counter,
> > > > > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > > > > struct {
> > > > > > const uint8_t *data; /**< pointer to key data */
> > > > > > uint16_t length; /**< key length in bytes */
> > > > > > - } key;
> > > > > > + } __attribute__((__packed__)) key;
> > > > > > +
> > > > > > + /** offset for cipher to start within data buffer */
> > > > > > + uint16_t cipher_offset;
> > > > > > +
> > > > > > + uint8_t reserved1[4];
> > > > > >
> > > > > > struct {
> > > > > > uint16_t offset;
> > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > index e175b838c..c0c7bfed7 100644
> > > > > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > > @@ -1272,6 +1272,101 @@ void *
> > > > > > rte_cryptodev_sym_session_get_user_data(
> > > > > > struct rte_cryptodev_sym_session *sess);
> > > > > >
> > > > > > +/*
> > > > > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > > > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > > > > + * introduce an extentsion to it via new fully opaque
> > > > > > + * struct rte_crypto_cpu_sym_session and additional related API.
> > > > >
> > > > >
> > > > > What all things do we need to squeeze?
> > > > > In this proposal I do not see the new struct cpu_sym_session defined here.
> > > >
> > > > The plan is to have it totally opaque to the user, i.e. just:
> > > > struct rte_crypto_cpu_sym_session;
> > > > in public header files.
> > > >
> > > > > I believe you will have same lib API/struct for cpu_sym_session and
> > > > sym_session.
> > > >
> > > > I thought about such way, but there are few things that looks clumsy to me:
> > > > 1. Right now there is no 'type' (or so) field inside rte_cryptodev_sym_session,
> > > > so it is not possible to easy distinguish what session do you have: lksd_sym or
> > > > cpu_sym.
> > > > In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we can
> > add
> > > > some extra field
> > > > here, but in that case we wouldn't be able to use the same xform for both
> > > > lksd_sym or cpu_sym
> > > > (which seems really plausible thing for me).
> > > > 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary for
> > > > rte_crypto_cpu_sym_session:
> > > > sess_data[], opaque_data, user_data, nb_drivers.
> > > > All that consumes space, that could be used somewhere else instead.
> > > > 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> > > > breakages I can't foresee right now.
> > > > From other side - if we'll add new functions/structs for cpu_sym_session we
> > can
> > > > mark it
> > > > and keep it for some time as experimental, so further changes (if needed)
> > would
> > > > still be possible.
> > > >
> > >
> > > OK let us assume that you have a separate structure. But I have a few queries:
> > > 1. how can multiple drivers use a same session
> >
> > As a short answer: they can't.
> > It is pretty much the same approach as with rte_security - each device needs to
> > create/init its own session.
> > So upper layer would need to maintain its own array (or so) for such case.
> > Though the question is why would you like to have same session over multiple
> > SW backed devices?
> > As it would be anyway just a synchronous function call that will be executed on
> > the same cpu.
>
> I may have single FAT tunnel which may be distributed over multiple
> Cores, and each core is affined to a different SW device.
If it is pure SW, then we don't need multiple devices for such scenario.
Device in that case is pure abstraction that we can skip.
> So a single session may be accessed by multiple devices.
>
> One more example would be depending on packet sizes, I may switch between
> HW/SW PMDs with the same session.
Sure, but then we'll have multiple sessions.
BTW, we have same thing now - these private session pointers are just stored
inside the same rte_crypto_sym_session.
And if user wants to support this model, he would also need to store <dev_id, queue_id>
pair for each HW device anyway.
>
> >
> > > 2. Can somebody use the scheduler pmd for scheduling the different type of
> > payloads for the same session?
> >
> > In theory yes.
> > Though for that scheduler pmd should have inside it's
> > rte_crypto_cpu_sym_session an array of pointers to
> > the underlying devices sessions.
> >
> > >
> > > With your proposal the APIs would be very specific to your use case only.
> >
> > Yes in some way.
> > I consider that API specific for SW backed crypto PMDs.
> > I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will benefit
> > from it.
> > Current crypto-op API is very much HW oriented.
> > Which is ok, that's for it was intended for, but I think we also need one that
> > would be designed
> > for SW backed implementation in mind.
>
> We may re-use your API for HW PMDs as well which do not have requirement of
> Crypto-op/mbuf etc.
> The return type of your new process API may have a status which say 'processed'
> Or can be say 'enqueued'. So if it is 'enqueued', we may have a new API for raw
> Bufs dequeue as well.
>
> This requirement can be for any hardware PMDs like QAT as well.
I don't think it is a good idea to extend this API for async (lookaside) devices.
You'll need to:
- provide dev_id and queue_id for each process(enqueue) and dequeuer operation.
- provide IOVA for all buffers passing to that function (data buffers, digest, IV, aad).
- On dequeue provide some way to associate dequed data and digest buffers with
crypto-session that was used (and probably with mbuf).
So most likely we'll end up with another just version of our current crypto-op structure.
If you'd like to get rid of mbufs dependency within current crypto-op API that understandable,
but I don't think we should have same API for both sync (CPU) and async (lookaside) cases.
It doesn't seem feasible at all and voids whole purpose of that patch.
> That is why a dev-ops would be a better option.
>
> >
> > > When you would add more functionality to this sync API/struct, it will end up
> > being the same API/struct.
> > >
> > > Let us see how close/ far we are from the existing APIs when the actual
> > implementation is done.
> > >
> > > > > I am not sure if that would be needed.
> > > > > It would be internal to the driver that if synchronous processing is
> > > > supported(from feature flag) and
> > > > > Have relevant fields in xform(the newly added ones which are packed as
> > per
> > > > your suggestions) set,
> > > > > It will create that type of session.
> > > > >
> > > > >
> > > > > > + * Main points:
> > > > > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > > > + * new sync API is new one and probably would require extra changes.
> > > > > > + * Having it as a new one allows to mark it as experimental, without
> > > > > > + * affecting existing one.
> > > > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > > > + * to the PMD writers and again allows to avoid ABI breakages in future.
> > > > > > + * - process() function per set of xforms
> > > > > > + * allows to expose different process() functions for different
> > > > > > + * xform combinations. PMD writer can decide, does he wants to
> > > > > > + * push all supported algorithms into one process() function,
> > > > > > + * or spread it across several ones.
> > > > > > + * I.E. More flexibility for PMD writer.
> > > > >
> > > > > Which process function should be chosen is internal to PMD, how would
> > that
> > > > info
> > > > > be visible to the application or the library. These will get stored in the
> > session
> > > > private
> > > > > data. It would be upto the PMD writer, to store the per session process
> > > > function in
> > > > > the session private data.
> > > > >
> > > > > Process function would be a dev ops just like enc/deq operations and it
> > should
> > > > call
> > > > > The respective process API stored in the session private data.
> > > >
> > > > That model (via devops) is possible, but has several drawbacks from my
> > > > perspective:
> > > >
> > > > 1. It means we'll need to pass dev_id as a parameter to process() function.
> > > > Though in fact dev_id is not a relevant information for us here
> > > > (all we need is pointer to the session and pointer to the fuction to call)
> > > > and I tried to avoid using it in data-path functions for that API.
> > >
> > > You have a single vdev, but someone may have multiple vdevs for each thread,
> > or may
> > > Have same dev with multiple queues for each core.
> >
> > That's fine. As I said above it is a SW backed implementation.
> > Each session has to be a separate entity that contains all necessary information
> > (keys, alg/mode info, etc.) to process input buffers.
> > Plus we need the actual function pointer to call.
> > I just don't see what for we need a dev_id in that situation.
>
> To iterate the session private data in the session.
>
> > Again, here we don't need care about queues and their pinning to cores.
> > If let say someone would like to process buffers from the same IPsec SA on 2
> > different cores in parallel, he can just create 2 sessions for the same xform,
> > give one to thread #1 and second to thread #2.
> > After that both threads are free to call process(this_thread_ses, ...) at will.
>
> Say you have a 16core device to handle 100G of traffic on a single tunnel.
> Will we make 16 sessions with same parameters?
Absolutely same question we can ask for current crypto-op API.
You have lookaside crypto-dev with 16 HW queues, each queue is serviced by different CPU.
For the same SA, do you need a separate session per queue, or is it ok to reuse current one?
AFAIK, right now this is a grey area not clearly defined.
For crypto-devs I am aware - user can reuse the same session (as PMD uses it read-only).
But again, right now I think it is not clearly defined and is implementation specific.
>
> >
> > >
> > > > 2. As you pointed in that case it will be just one process() function per device.
> > > > So if PMD would like to have several process() functions for different type of
> > > > sessions
> > > > (let say one per alg) first thing it has to do inside it's process() - read session
> > data
> > > > and
> > > > based on that, do a jump/call to particular internal sub-routine.
> > > > Something like:
> > > > driver_id = get_pmd_driver_id();
> > > > priv_ses = ses->sess_data[driver_id];
> > > > Then either:
> > > > switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> > > > OR
> > > > priv_ses->process(priv_sess, ...);
> > > >
> > > > to select and call the proper function.
> > > > Looks like totally unnecessary overhead to me.
> > > > Though if we'll have ability to query/extract some sort session_ops based on
> > the
> > > > xform -
> > > > we can avoid this extra de-refererence+jump/call thing.
> > >
> > > What is the issue in the priv_ses->process(); approach?
> >
> > Nothing at all.
> > What I am saying that schema with dev_ops
> > dev[dev_id]->dev_ops.process(ses->priv_ses[driver_id], ...)
> > |
> > |-> priv_ses->process(...)
> >
> > Has bigger overhead then just:
> > process(ses,...);
> >
> > So what for to introduce extra-level of indirection here?
>
> Explained above.
>
> >
> > > I don't understand what are you saving by not doing this.
> > > In any case you would need to identify which session correspond to which
> > process().
> >
> > Yes, sure, but I think we can make user to store information that relationship,
> > in a way he likes: store process() pointer for each session, or group sessions
> > that share the same process() somehow, or...
>
> So whatever relationship that user will make and store will make its life complicated.
> If we can hide that information in the driver, then what is the issue in that and user
> Will not need to worry. He would just call the process() and driver will choose which
> Process need to be called.
Driver can do that at config/init time.
Then at run-time we can avoid that choice at all and call already chosen function.
>
> I think we should have a POC around this and see the difference in the cycle count.
> IMO it would be negligible and we would end up making a generic API set which
> can be used by others as well.
>
> >
> > > For that you would be doing it somewhere in your data path.
> >
> > Why at data-path?
> > Only once at session creation/initialization time.
> > Or might be even once per group of sessions.
> >
> > >
> > > >
> > > > >
> > > > > I am not sure if you would need a new session init API for this as nothing
> > would
> > > > be visible to
> > > > > the app or lib.
> > > > >
> > > > > > + * - Not storing process() pointer inside the session -
> > > > > > + * Allows user to choose does he want to store a process() pointer
> > > > > > + * per session, or per group of sessions for that device that share
> > > > > > + * the same input xforms. I.E. extra flexibility for the user,
> > > > > > + * plus allows us to keep cpu_sym_session totally opaque, see above.
> > > > >
> > > > > If multiple sessions need to be processed via the same process function,
> > > > > PMD would save the same process in all the sessions, I don't think there
> > would
> > > > > be any perf overhead with that.
> > > >
> > > > I think it would, see above.
> > > >
> > > > >
> > > > > > + * Sketched usage model:
> > > > > > + * ....
> > > > > > + * /* control path, alloc/init session */
> > > > > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > > > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > > > > + * rte_crypto_cpu_sym_process_t process =
> > > > > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > > > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > > > > + * ...
> > > > > > + * /* data-path*/
> > > > > > + * process(ses, ....);
> > > > > > + * ....
> > > > > > + * /* control path, termiante/free session */
> > > > > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > > > > + */
> > > > > > +
> > > > > > +/**
> > > > > > + * vector structure, contains pointer to vector array and the length
> > > > > > + * of the array
> > > > > > + */
> > > > > > +struct rte_crypto_vec {
> > > > > > + struct iovec *vec;
> > > > > > + uint32_t num;
> > > > > > +};
> > > > > > +
> > > > > > +/*
> > > > > > + * Data-path bulk process crypto function.
> > > > > > + */
> > > > > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > > > > + void *digest[], int status[], uint32_t num);
> > > > > > +/*
> > > > > > + * for given device return process function specific to input xforms
> > > > > > + * on error - return NULL and set rte_errno value.
> > > > > > + * Note that for same input xfroms for the same device should return
> > > > > > + * the same process function.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +rte_crypto_cpu_sym_process_t
> > > > > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > +/*
> > > > > > + * Return required session size in bytes for given set of xforms.
> > > > > > + * if xforms == NULL, then return the max possible session size,
> > > > > > + * that would fit session for any supported by the device algorithm.
> > > > > > + * if CPU mode is not supported at all, or requeted in xform
> > > > > > + * algorithm is not supported, then return -ENOTSUP.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +int
> > > > > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > +/*
> > > > > > + * Initialize session.
> > > > > > + * It is caller responsibility to allocate enough space for it.
> > > > > > + * See rte_crypto_cpu_sym_session_size above.
> > > > > > + */
> > > > > > +__rte_experimental
> > > > > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > +__rte_experimental
> > > > > > +void
> > > > > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > +
> > > > > > +
> > > > > > #ifdef __cplusplus
> > > > > > }
> > > > > > #endif
> > > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > index defe05ea0..ed7e63fab 100644
> > > > > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > > @@ -310,6 +310,20 @@ typedef void
> > > > (*cryptodev_sym_free_session_t)(struct
> > > > > > rte_cryptodev *dev,
> > > > > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev
> > *dev,
> > > > > > struct rte_cryptodev_asym_session *sess);
> > > > > >
> > > > > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct rte_cryptodev
> > > > *dev,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct rte_cryptodev
> > > > *dev,
> > > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct rte_cryptodev
> > > > *dev,
> > > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > > +
> > > > > > +typedef rte_crypto_cpu_sym_process_t
> > > > (*cryptodev_cpu_sym_session_func_t)
> > > > > > (
> > > > > > + struct rte_cryptodev *dev,
> > > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > > +
> > > > > > /** Crypto device operations function pointer table */
> > > > > > struct rte_cryptodev_ops {
> > > > > > cryptodev_configure_t dev_configure; /**< Configure device. */
> > > > > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > cryptodev_asym_free_session_t asym_session_clear;
> > > > > > /**< Clear a Crypto sessions private data. */
> > > > > > +
> > > > > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > > > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > > > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > > > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > > > > };
> > > > > >
> > > > > >
> > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource reclamation APIs
2019-10-04 6:07 3% ` Honnappa Nagarahalli
@ 2019-10-07 10:46 0% ` Ananyev, Konstantin
2019-10-13 4:35 0% ` Honnappa Nagarahalli
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-07 10:46 UTC (permalink / raw)
To: Honnappa Nagarahalli, stephen, paulmck
Cc: Wang, Yipeng1, Medvedkin, Vladimir,
Ruifeng Wang (Arm Technology China),
Dharmik Thakkar, dev, nd, nd, nd
> > > > > Add resource reclamation APIs to make it simple for applications
> > > > > and libraries to integrate rte_rcu library.
> > > > >
> > > > > Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > > Reviewed-by: Ola Liljedhal <ola.liljedhal@arm.com>
> > > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > > ---
> > > > > app/test/test_rcu_qsbr.c | 291 ++++++++++++++++++++++++++++-
> > > > > lib/librte_rcu/meson.build | 2 +
> > > > > lib/librte_rcu/rte_rcu_qsbr.c | 185 ++++++++++++++++++
> > > > > lib/librte_rcu/rte_rcu_qsbr.h | 169 +++++++++++++++++
> > > > > lib/librte_rcu/rte_rcu_qsbr_pvt.h | 46 +++++
> > > > > lib/librte_rcu/rte_rcu_version.map | 4 +
> > > > > lib/meson.build | 6 +-
> > > > > 7 files changed, 700 insertions(+), 3 deletions(-) create mode
> > > > > 100644 lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > >
> > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > b/lib/librte_rcu/rte_rcu_qsbr.c index ce7f93dd3..76814f50b 100644
> > > > > --- a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.c
> > > > > @@ -21,6 +21,7 @@
> > > > > #include <rte_errno.h>
> > > > >
> > > > > #include "rte_rcu_qsbr.h"
> > > > > +#include "rte_rcu_qsbr_pvt.h"
> > > > >
> > > > > /* Get the memory size of QSBR variable */ size_t @@ -267,6
> > > > > +268,190 @@ rte_rcu_qsbr_dump(FILE *f, struct rte_rcu_qsbr *v)
> > > > > return 0;
> > > > > }
> > > > >
> > > > > +/* Create a queue used to store the data structure elements that
> > > > > +can
> > > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > > + */
> > > > > +struct rte_rcu_qsbr_dq *
> > > > > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > > > > +*params) {
> > > > > + struct rte_rcu_qsbr_dq *dq;
> > > > > + uint32_t qs_fifo_size;
> > > > > +
> > > > > + if (params == NULL || params->f == NULL ||
> > > > > + params->v == NULL || params->name == NULL ||
> > > > > + params->size == 0 || params->esize == 0 ||
> > > > > + (params->esize % 8 != 0)) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > + rte_errno = EINVAL;
> > > > > +
> > > > > + return NULL;
> > > > > + }
> > > > > +
> > > > > + dq = rte_zmalloc(NULL,
> > > > > + (sizeof(struct rte_rcu_qsbr_dq) + params->esize),
> > > > > + RTE_CACHE_LINE_SIZE);
> > > > > + if (dq == NULL) {
> > > > > + rte_errno = ENOMEM;
> > > > > +
> > > > > + return NULL;
> > > > > + }
> > > > > +
> > > > > + /* round up qs_fifo_size to next power of two that is not less than
> > > > > + * max_size.
> > > > > + */
> > > > > + qs_fifo_size = rte_align32pow2((((params->esize/8) + 1)
> > > > > + * params->size) + 1);
> > > > > + dq->r = rte_ring_create(params->name, qs_fifo_size,
> > > > > + SOCKET_ID_ANY, 0);
> > > >
> > > > If it is going to be not MT safe, then why not to create the ring
> > > > with (RING_F_SP_ENQ | RING_F_SC_DEQ) flags set?
> > > Agree.
> > >
> > > > Though I think it could be changed to allow MT safe multiple
> > > > enqeue/single dequeue, see below.
> > > The MT safe issue is due to reclaim code. The reclaim code has the following
> > sequence:
> > >
> > > rte_ring_peek
> > > rte_rcu_qsbr_check
> > > rte_ring_dequeue
> > >
> > > This entire sequence needs to be atomic as the entry cannot be dequeued
> > without knowing that the grace period for that entry is over.
> >
> > I understand that, though I believe at least it should be possible to support
> > multiple-enqueue/single dequeuer and reclaim mode.
> > With serialized dequeue() even multiple dequeue should be possible.
> Agreed. Please see the response on the other thread.
>
> >
> > > Note that due to optimizations in rte_rcu_qsbr_check API, this
> > > sequence should not be large in most cases. I do not have ideas on how to
> > make this sequence lock-free.
> > >
> > > If the writer is on the control plane, most use cases will use mutex
> > > locks for synchronization if they are multi-threaded. That lock should be
> > enough to provide the thread safety for these APIs.
> >
> > In that is case, why do we need ring at all?
> > For sure people can create their own queue quite easily with mutex and TAILQ.
> > If performance is not an issue, they can even add pthread_cond to it, and have
> > an ability for the consumer to sleep/wakeup on empty/full queue.
> >
> > >
> > > If the writer is multi-threaded and lock-free, then one should use per thread
> > defer queue.
> >
> > If that's the only working model, then the question is why do we need that API
> > at all?
> > Just simple array with counter or linked-list should do for majority of cases.
> Please see the other thread.
>
> >
> > >
> > > >
> > > > > + if (dq->r == NULL) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): defer queue create failed\n", __func__);
> > > > > + rte_free(dq);
> > > > > + return NULL;
> > > > > + }
> > > > > +
> > > > > + dq->v = params->v;
> > > > > + dq->size = params->size;
> > > > > + dq->esize = params->esize;
> > > > > + dq->f = params->f;
> > > > > + dq->p = params->p;
> > > > > +
> > > > > + return dq;
> > > > > +}
> > > > > +
> > > > > +/* Enqueue one resource to the defer queue to free after the
> > > > > +grace
> > > > > + * period is over.
> > > > > + */
> > > > > +int rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e) {
> > > > > + uint64_t token;
> > > > > + uint64_t *tmp;
> > > > > + uint32_t i;
> > > > > + uint32_t cur_size, free_size;
> > > > > +
> > > > > + if (dq == NULL || e == NULL) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > + rte_errno = EINVAL;
> > > > > +
> > > > > + return 1;
> > > >
> > > > Why just not to return -EINVAL straightway?
> > > > I think there is no much point to set rte_errno in that function at
> > > > all, just return value should do.
> > > I am trying to keep these consistent with the existing APIs. They return 0 or 1
> > and set the rte_errno.
> >
> > A lot of public DPDK API functions do use return value to return status code (0,
> > or some positive numbers of success, negative errno values on failure), I am
> > not inventing anything new here.
> Agree, you are not proposing a new thing here. May be I was not clear. I really do not have an opinion on how this should be done. But, I do
> have an opinion on consistency. These new APIs follow what has been done in the existing RCU APIs. I think we have 2 options here.
> 1) Either we change existing RCU APIs to get rid of rte_errno (is it an ABI change?) or
> 2) The new APIs follow what has been done in the existing RCU APIs.
> I want to make sure we are consistent at least within RCU APIs.
But as I can see right now rcu API sets rte_errno only for control-path functions
(get_memsize, init, register, unregister, dump).
All fast-path (inline) function don't set/use it.
So from perspective that is consistent behavior, no?
>
> >
> > >
> > > >
> > > > > + }
> > > > > +
> > > > > + /* Start the grace period */
> > > > > + token = rte_rcu_qsbr_start(dq->v);
> > > > > +
> > > > > + /* Reclaim resources if the queue is 1/8th full. This helps
> > > > > + * the queue from growing too large and allows time for reader
> > > > > + * threads to report their quiescent state.
> > > > > + */
> > > > > + cur_size = rte_ring_count(dq->r) / (dq->esize/8 + 1);
> > > >
> > > > Probably would be a bit easier if you just store in dq->esize (elt
> > > > size + token
> > > > size) / 8.
> > > Agree
> > >
> > > >
> > > > > + if (cur_size > (dq->size >> RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT)) {
> > > >
> > > > Why to make this threshold value hard-coded?
> > > > Why either not to put it into create parameter, or just return a
> > > > special return value, to indicate that threshold is reached?
> > > My thinking was to keep the programming interface easy to use. The
> > > more the parameters, the more painful it is for the user. IMO, the
> > > constants chosen should be good enough for most cases. More advanced
> > users could modify the constants. However, we could make these as part of the
> > parameters, but make them optional for the user. For ex: if they set them to 0,
> > default values can be used.
> > >
> > > > Or even return number of filled/free entroes on success, so caller
> > > > can decide to reclaim or not based on that information on his own?
> > > This means more code on the user side.
> >
> > I personally think it it really wouldn't be that big problem to the user to pass
> > extra parameter to the function.
> I will convert the 2 constants into optional parameters (user can set them to 0 to make the algorithm use default values)
>
> > Again what if user doesn't want to reclaim() in enqueue() thread at all?
> 'enqueue' has to do reclamation if the defer queue is full. I do not think this is trivial.
>
> In the current design, reclamation in enqueue is also done on regular basis (automatic triggering of reclamation when the queue reaches
> certain limit) to keep the queue from growing too large. This is required when we implement a dynamically adjusting defer queue. The
> current algorithm keeps the cost of reclamation spread across multiple calls and puts an upper bound on cycles for delete API by reclaiming
> a fixed number of entries.
>
> This algorithm is proven to work in the LPM integration performance tests at a very low performance over head (~1%). So, I do not know
> why a user would not want to use this.
Yeh, I looked at LPM implementation and one thing I found strange -
defer_queue is hidden inside LPM struct and all reclamations are done internally.
Yes for sure it allows to defer and group actual reclaim(), which hopefully will lead to better performance.
But why not to allow user to call reclaim() for it directly too?
In that way user might avoid/(minimize) doing reclaim() in LPM write() at all.
And let say do it somewhere later in the same thread (when no other tasks to do),
or even leave it to some other house-keeping thread to do (sort of garbage collector).
Or such mode is not supported/planned?
> The 2 additional parameters should give the user more flexibility.
Ok, let's keep it as config params.
After another though - I think you right, it should be good enough.
>
> However, if the user wants his own algorithm, he can create one with the base APIs provided.
>
> >
> > > I think adding these to parameters seems like a better option.
> > >
> > > >
> > > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > > + "%s(): Triggering reclamation\n", __func__);
> > > > > + rte_rcu_qsbr_dq_reclaim(dq);
> > > > > + }
> > > > > +
> > > > > + /* Check if there is space for atleast for 1 resource */
> > > > > + free_size = rte_ring_free_count(dq->r) / (dq->esize/8 + 1);
> > > > > + if (!free_size) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): Defer queue is full\n", __func__);
> > > > > + rte_errno = ENOSPC;
> > > > > + return 1;
> > > > > + }
> > > > > +
> > > > > + /* Enqueue the resource */
> > > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)token);
> > > > > +
> > > > > + /* The resource to enqueue needs to be a multiple of 64b
> > > > > + * due to the limitation of the rte_ring implementation.
> > > > > + */
> > > > > + for (i = 0, tmp = (uint64_t *)e; i < dq->esize/8; i++, tmp++)
> > > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)*tmp);
> > > >
> > > >
> > > > That whole construction above looks a bit clumsy and error prone...
> > > > I suppose just:
> > > >
> > > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t free, n; ...
> > > > n = rte_ring_enqueue_bulk(dq->r, e, nb_elt, &free); if (n == 0)
> > > Yes, bulk enqueue can be used. But note that once the flexible element size
> > ring patch is done, this code will use that.
> >
> > Well, when it will be in the mainline, and it would provide a better way, for sure
> > this code can be updated to use new API (if it is provide some improvements).
> > But as I udenrstand, right now it is not there, while bulk enqueue/dequeue are.
> Apologies, I was not clear. I agree we can go with bulk APIs for now.
>
> >
> > >
> > > > return -ENOSPC;
> > > > return free;
> > > >
> > > > That way I think you can have MT-safe version of that function.
> > > Please see the description of MT safe issue above.
> > >
> > > >
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > +/* Reclaim resources from the defer queue. */ int
> > > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq) {
> > > > > + uint32_t max_cnt;
> > > > > + uint32_t cnt;
> > > > > + void *token;
> > > > > + uint64_t *tmp;
> > > > > + uint32_t i;
> > > > > +
> > > > > + if (dq == NULL) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > + rte_errno = EINVAL;
> > > > > +
> > > > > + return 1;
> > > >
> > > > Same story as above - I think rte_errno is excessive in this function.
> > > > Just return value should be enough.
> > > >
> > > >
> > > > > + }
> > > > > +
> > > > > + /* Anything to reclaim? */
> > > > > + if (rte_ring_count(dq->r) == 0)
> > > > > + return 0;
> > > >
> > > > Not sure you need that, see below.
> > > >
> > > > > +
> > > > > + /* Reclaim at the max 1/16th the total number of entries. */
> > > > > + max_cnt = dq->size >> RTE_RCU_QSBR_MAX_RECLAIM_LIMIT;
> > > > > + max_cnt = (max_cnt == 0) ? dq->size : max_cnt;
> > > >
> > > > Again why not to make max_cnt a configurable at create() parameter?
> > > I think making this as an optional parameter for creating defer queue is a
> > better option.
> > >
> > > > Or even a parameter for that function?
> > > >
> > > > > + cnt = 0;
> > > > > +
> > > > > + /* Check reader threads quiescent state and reclaim resources */
> > > > > + while ((cnt < max_cnt) && (rte_ring_peek(dq->r, &token) == 0) &&
> > > > > + (rte_rcu_qsbr_check(dq->v, (uint64_t)((uintptr_t)token), false)
> > > > > + == 1)) {
> > > >
> > > >
> > > > > + (void)rte_ring_sc_dequeue(dq->r, &token);
> > > > > + /* The resource to dequeue needs to be a multiple of 64b
> > > > > + * due to the limitation of the rte_ring implementation.
> > > > > + */
> > > > > + for (i = 0, tmp = (uint64_t *)dq->e; i < dq->esize/8;
> > > > > + i++, tmp++)
> > > > > + (void)rte_ring_sc_dequeue(dq->r,
> > > > > + (void *)(uintptr_t)tmp);
> > > >
> > > > Again, no need for such constructs with multiple dequeuer I believe.
> > > > Just:
> > > >
> > > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t n; uintptr_t
> > > > elt[nb_elt]; ...
> > > > n = rte_ring_dequeue_bulk(dq->r, elt, nb_elt, NULL); if (n != 0)
> > > > {dq->f(dq->p, elt);}
> > > Agree on bulk API use.
> > >
> > > >
> > > > Seems enough.
> > > > Again in that case you can have enqueue/reclaim running in different
> > > > threads simultaneously, plus you don't need dq->e at all.
> > > Will check on dq->e
> > >
> > > >
> > > > > + dq->f(dq->p, dq->e);
> > > > > +
> > > > > + cnt++;
> > > > > + }
> > > > > +
> > > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > > + "%s(): Reclaimed %u resources\n", __func__, cnt);
> > > > > +
> > > > > + if (cnt == 0) {
> > > > > + /* No resources were reclaimed */
> > > > > + rte_errno = EAGAIN;
> > > > > + return 1;
> > > > > + }
> > > > > +
> > > > > + return 0;
> > > >
> > > > I'd suggest to return cnt on success.
> > > I am trying to keep the APIs simple. I do not see much use for 'cnt'
> > > as return value to the user. It exposes more details which I think are internal
> > to the library.
> >
> > Not sure what is the hassle to return number of completed reclamaitions?
> > If user doesn't need that information, he simply wouldn't use it.
> > But might be it would be usefull - he can decide should he try another attempt
> > of reclaim() immediately or is it ok to do something else.
> There is no hassle to return that information.
>
> As per the current design, user calls 'reclaim' when it is out of resources while adding an entry to the data structure. At that point the user
> wants to know if at least 1 resource was reclaimed because the user has to allocate 1 resource. He does not have a use for the number of
> resources reclaimed.
Ok, but why user can't decide to do reclaim in advance, let say when he foresee that he would need a lot of allocations in nearest future?
Or when there is some idle time? Or some combination of these things?
At he would like to free some extra resources in that case to minimize number of reclaims in future peak interval?
>
> If this API returns 0, then the user can decide to repeat the call or return failure. But that decision depends on the length of the grace period
> which is under user's control.
>
> >
> > >
> > > >
> > > > > +}
> > > > > +
> > > > > +/* Delete a defer queue. */
> > > > > +int
> > > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq) {
> > > > > + if (dq == NULL) {
> > > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > > + "%s(): Invalid input parameter\n", __func__);
> > > > > + rte_errno = EINVAL;
> > > > > +
> > > > > + return 1;
> > > > > + }
> > > > > +
> > > > > + /* Reclaim all the resources */
> > > > > + if (rte_rcu_qsbr_dq_reclaim(dq) != 0)
> > > > > + /* Error number is already set by the reclaim API */
> > > > > + return 1;
> > > >
> > > > How do you know that you have reclaimed everything?
> > > Good point, will come back with a different solution.
> > >
> > > >
> > > > > +
> > > > > + rte_ring_free(dq->r);
> > > > > + rte_free(dq);
> > > > > +
> > > > > + return 0;
> > > > > +}
> > > > > +
> > > > > int rte_rcu_log_type;
> > > > >
> > > > > RTE_INIT(rte_rcu_register)
> > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > b/lib/librte_rcu/rte_rcu_qsbr.h index c80f15c00..185d4b50a 100644
> > > > > --- a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.h
> > > > > @@ -34,6 +34,7 @@ extern "C" {
> > > > > #include <rte_lcore.h>
> > > > > #include <rte_debug.h>
> > > > > #include <rte_atomic.h>
> > > > > +#include <rte_ring.h>
> > > > >
> > > > > extern int rte_rcu_log_type;
> > > > >
> > > > > @@ -109,6 +110,67 @@ struct rte_rcu_qsbr {
> > > > > */
> > > > > } __rte_cache_aligned;
> > > > >
> > > > > +/**
> > > > > + * Call back function called to free the resources.
> > > > > + *
> > > > > + * @param p
> > > > > + * Pointer provided while creating the defer queue
> > > > > + * @param e
> > > > > + * Pointer to the resource data stored on the defer queue
> > > > > + *
> > > > > + * @return
> > > > > + * None
> > > > > + */
> > > > > +typedef void (*rte_rcu_qsbr_free_resource)(void *p, void *e);
> > > >
> > > > Stylish thing - usually in DPDK we have typedf newtype_t ...
> > > > Though I am not sure you need a new typedef at all - just a function
> > > > pointer inside the struct seems enough.
> > > Other libraries (for ex: rte_hash) use this approach. I think it is better to keep
> > it out of the structure to allow for better commenting.
> >
> > I am saying majority of DPDK code use _t suffix for typedef:
> > typedef void (*rte_rcu_qsbr_free_resource_t)(void *p, void *e);
> Apologies, got it, will change.
>
> >
> > >
> > > >
> > > > > +
> > > > > +#define RTE_RCU_QSBR_DQ_NAMESIZE RTE_RING_NAMESIZE
> > > > > +
> > > > > +/**
> > > > > + * Trigger automatic reclamation after 1/8th the defer queue is full.
> > > > > + */
> > > > > +#define RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT 3
> > > > > +
> > > > > +/**
> > > > > + * Reclaim at the max 1/16th the total number of resources.
> > > > > + */
> > > > > +#define RTE_RCU_QSBR_MAX_RECLAIM_LIMIT 4
> > > >
> > > >
> > > > As I said above, I don't think these thresholds need to be hardcoded.
> > > > In any case, there seems not much point to put them in the public header
> > file.
> > > >
> > > > > +
> > > > > +/**
> > > > > + * Parameters used when creating the defer queue.
> > > > > + */
> > > > > +struct rte_rcu_qsbr_dq_parameters {
> > > > > + const char *name;
> > > > > + /**< Name of the queue. */
> > > > > + uint32_t size;
> > > > > + /**< Number of entries in queue. Typically, this will be
> > > > > + * the same as the maximum number of entries supported in the
> > > > > + * lock free data structure.
> > > > > + * Data structures with unbounded number of entries is not
> > > > > + * supported currently.
> > > > > + */
> > > > > + uint32_t esize;
> > > > > + /**< Size (in bytes) of each element in the defer queue.
> > > > > + * This has to be multiple of 8B as the rte_ring APIs
> > > > > + * support 8B element sizes only.
> > > > > + */
> > > > > + rte_rcu_qsbr_free_resource f;
> > > > > + /**< Function to call to free the resource. */
> > > > > + void *p;
> > > >
> > > > Style nit again - I like short names myself, but that seems a bit
> > > > extreme... :) Might be at least:
> > > > void (*reclaim)(void *, void *);
> > > May be 'free_fn'?
> > >
> > > > void * reclaim_data;
> > > > ?
> > > This is the pointer to the data structure to free the resource into. For ex: In
> > LPM data structure, it will be pointer to LPM. 'reclaim_data'
> > > does not convey the meaning correctly.
> >
> > Ok, please free to comeup with your own names.
> > I just wanted to say that 'f' and 'p' are a bit an extreme for public API.
> ok, this is the hardest thing to do 😊
>
> >
> > >
> > > >
> > > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > > + * pointer to the data structure to which the resource to free
> > > > > + * belongs. This can be NULL.
> > > > > + */
> > > > > + struct rte_rcu_qsbr *v;
> > > >
> > > > Does it need to be inside that struct?
> > > > Might be better:
> > > > rte_rcu_qsbr_dq_create(struct rte_rcu_qsbr *v, const struct
> > > > rte_rcu_qsbr_dq_parameters *params);
> > > The API takes a parameter structure as input anyway, why to add
> > > another argument to the function? QSBR variable is also another parameter.
> > >
> > > >
> > > > Another alternative: make both reclaim() and enqueue() to take v as
> > > > a parameter.
> > > But both of them need access to some of the parameters provided in
> > > rte_rcu_qsbr_dq_create API. We would end up passing 2 arguments to the
> > functions.
> >
> > Pure stylish thing.
> > From my perspective it just provides better visibility what is going in the code:
> > For QSBR var 'v' create a new deferred queue.
> > But no strong opinion here.
> >
> > >
> > > >
> > > > > + /**< RCU QSBR variable to use for this defer queue */ };
> > > > > +
> > > > > +/* RTE defer queue structure.
> > > > > + * This structure holds the defer queue. The defer queue is used
> > > > > +to
> > > > > + * hold the deleted entries from the data structure that are not
> > > > > + * yet freed.
> > > > > + */
> > > > > +struct rte_rcu_qsbr_dq;
> > > > > +
> > > > > /**
> > > > > * @warning
> > > > > * @b EXPERIMENTAL: this API may change without prior notice @@
> > > > > -648,6 +710,113 @@ __rte_experimental int rte_rcu_qsbr_dump(FILE
> > > > > *f, struct rte_rcu_qsbr *v);
> > > > >
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > + *
> > > > > + * Create a queue used to store the data structure elements that
> > > > > +can
> > > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > > + *
> > > > > + * @param params
> > > > > + * Parameters to create a defer queue.
> > > > > + * @return
> > > > > + * On success - Valid pointer to defer queue
> > > > > + * On error - NULL
> > > > > + * Possible rte_errno codes are:
> > > > > + * - EINVAL - NULL parameters are passed
> > > > > + * - ENOMEM - Not enough memory
> > > > > + */
> > > > > +__rte_experimental
> > > > > +struct rte_rcu_qsbr_dq *
> > > > > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > > > > +*params);
> > > > > +
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > + *
> > > > > + * Enqueue one resource to the defer queue and start the grace period.
> > > > > + * The resource will be freed later after at least one grace
> > > > > +period
> > > > > + * is over.
> > > > > + *
> > > > > + * If the defer queue is full, it will attempt to reclaim resources.
> > > > > + * It will also reclaim resources at regular intervals to avoid
> > > > > + * the defer queue from growing too big.
> > > > > + *
> > > > > + * This API is not multi-thread safe. It is expected that the
> > > > > +caller
> > > > > + * provides multi-thread safety by locking a mutex or some other means.
> > > > > + *
> > > > > + * A lock free multi-thread writer algorithm could achieve
> > > > > +multi-thread
> > > > > + * safety by creating and using one defer queue per thread.
> > > > > + *
> > > > > + * @param dq
> > > > > + * Defer queue to allocate an entry from.
> > > > > + * @param e
> > > > > + * Pointer to resource data to copy to the defer queue. The size of
> > > > > + * the data to copy is equal to the element size provided when the
> > > > > + * defer queue was created.
> > > > > + * @return
> > > > > + * On success - 0
> > > > > + * On error - 1 with rte_errno set to
> > > > > + * - EINVAL - NULL parameters are passed
> > > > > + * - ENOSPC - Defer queue is full. This condition can not happen
> > > > > + * if the defer queue size is equal (or larger) than the
> > > > > + * number of elements in the data structure.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +int
> > > > > +rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e);
> > > > > +
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > + *
> > > > > + * Reclaim resources from the defer queue.
> > > > > + *
> > > > > + * This API is not multi-thread safe. It is expected that the
> > > > > +caller
> > > > > + * provides multi-thread safety by locking a mutex or some other means.
> > > > > + *
> > > > > + * A lock free multi-thread writer algorithm could achieve
> > > > > +multi-thread
> > > > > + * safety by creating and using one defer queue per thread.
> > > > > + *
> > > > > + * @param dq
> > > > > + * Defer queue to reclaim an entry from.
> > > > > + * @return
> > > > > + * On successful reclamation of at least 1 resource - 0
> > > > > + * On error - 1 with rte_errno set to
> > > > > + * - EINVAL - NULL parameters are passed
> > > > > + * - EAGAIN - None of the resources have completed at least 1 grace
> > > > period,
> > > > > + * try again.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +int
> > > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq);
> > > > > +
> > > > > +/**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > > + *
> > > > > + * Delete a defer queue.
> > > > > + *
> > > > > + * It tries to reclaim all the resources on the defer queue.
> > > > > + * If any of the resources have not completed the grace period
> > > > > + * the reclamation stops and returns immediately. The rest of
> > > > > + * the resources are not reclaimed and the defer queue is not
> > > > > + * freed.
> > > > > + *
> > > > > + * @param dq
> > > > > + * Defer queue to delete.
> > > > > + * @return
> > > > > + * On success - 0
> > > > > + * On error - 1
> > > > > + * Possible rte_errno codes are:
> > > > > + * - EINVAL - NULL parameters are passed
> > > > > + * - EAGAIN - Some of the resources have not completed at least 1
> > grace
> > > > > + * period, try again.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +int
> > > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq);
> > > > > +
> > > > > #ifdef __cplusplus
> > > > > }
> > > > > #endif
> > > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > > b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > > new file mode 100644
> > > > > index 000000000..2122bc36a
> > > > > --- /dev/null
> > > > > +++ b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > >
> > > > Again style suggestion: as it is not public header - don't use rte_
> > > > prefix for naming.
> > > > From my perspective - easier to relalize for reader what is public
> > > > header, what is not.
> > > Looks like the guidelines are not defined very well. I see one private
> > > file with rte_ prefix. I see Stephen not using rte_ prefix. I do not have any
> > preference. But, a consistent approach is required.
> >
> > That's just a suggestion.
> > For me (and I hope for others) it would be a bit easier.
> > When looking at the code for first time I had to look a t meson.build to check is
> > it a public header or not.
> > If the file doesn't have 'rte_' prefix, I assume that it is an internal one
> > straightway.
> > But , as you said, there is no exact guidelines here, so up to you to decide.
> I think it makes sense to remove 'rte_' prefix. I will also change the file name to have '_private' suffix.
> There are some inconsistencies in the existing code, will send a patch to correct them to follow this approach.
>
> >
> > >
> > > >
> > > > > @@ -0,0 +1,46 @@
> > > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > > + * Copyright (c) 2019 Arm Limited */
> > > > > +
> > > > > +#ifndef _RTE_RCU_QSBR_PVT_H_
> > > > > +#define _RTE_RCU_QSBR_PVT_H_
> > > > > +
> > > > > +/**
> > > > > + * This file is private to the RCU library. It should not be
> > > > > +included
> > > > > + * by the user of this library.
> > > > > + */
> > > > > +
> > > > > +#ifdef __cplusplus
> > > > > +extern "C" {
> > > > > +#endif
> > > > > +
> > > > > +#include "rte_rcu_qsbr.h"
> > > > > +
> > > > > +/* RTE defer queue structure.
> > > > > + * This structure holds the defer queue. The defer queue is used
> > > > > +to
> > > > > + * hold the deleted entries from the data structure that are not
> > > > > + * yet freed.
> > > > > + */
> > > > > +struct rte_rcu_qsbr_dq {
> > > > > + struct rte_rcu_qsbr *v; /**< RCU QSBR variable used by this queue.*/
> > > > > + struct rte_ring *r; /**< RCU QSBR defer queue. */
> > > > > + uint32_t size;
> > > > > + /**< Number of elements in the defer queue */
> > > > > + uint32_t esize;
> > > > > + /**< Size (in bytes) of data stored on the defer queue */
> > > > > + rte_rcu_qsbr_free_resource f;
> > > > > + /**< Function to call to free the resource. */
> > > > > + void *p;
> > > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > > + * pointer to the data structure to which the resource to free
> > > > > + * belongs.
> > > > > + */
> > > > > + char e[0];
> > > > > + /**< Temporary storage to copy the defer queue element. */
> > > >
> > > > Do you really need 'e' at all?
> > > > Can't it be just temporary stack variable?
> > > Ok, will check.
> > >
> > > >
> > > > > +};
> > > > > +
> > > > > +#ifdef __cplusplus
> > > > > +}
> > > > > +#endif
> > > > > +
> > > > > +#endif /* _RTE_RCU_QSBR_PVT_H_ */
> > > > > diff --git a/lib/librte_rcu/rte_rcu_version.map
> > > > > b/lib/librte_rcu/rte_rcu_version.map
> > > > > index f8b9ef2ab..dfac88a37 100644
> > > > > --- a/lib/librte_rcu/rte_rcu_version.map
> > > > > +++ b/lib/librte_rcu/rte_rcu_version.map
> > > > > @@ -8,6 +8,10 @@ EXPERIMENTAL {
> > > > > rte_rcu_qsbr_synchronize;
> > > > > rte_rcu_qsbr_thread_register;
> > > > > rte_rcu_qsbr_thread_unregister;
> > > > > + rte_rcu_qsbr_dq_create;
> > > > > + rte_rcu_qsbr_dq_enqueue;
> > > > > + rte_rcu_qsbr_dq_reclaim;
> > > > > + rte_rcu_qsbr_dq_delete;
> > > > >
> > > > > local: *;
> > > > > };
> > > > > diff --git a/lib/meson.build b/lib/meson.build index
> > > > > e5ff83893..0e1be8407 100644
> > > > > --- a/lib/meson.build
> > > > > +++ b/lib/meson.build
> > > > > @@ -11,7 +11,9 @@
> > > > > libraries = [
> > > > > 'kvargs', # eal depends on kvargs
> > > > > 'eal', # everything depends on eal
> > > > > - 'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > > + 'ring',
> > > > > + 'rcu', # rcu depends on ring
> > > > > + 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > > 'cmdline',
> > > > > 'metrics', # bitrate/latency stats depends on this
> > > > > 'hash', # efd depends on this
> > > > > @@ -22,7 +24,7 @@ libraries = [
> > > > > 'gro', 'gso', 'ip_frag', 'jobstats',
> > > > > 'kni', 'latencystats', 'lpm', 'member',
> > > > > 'power', 'pdump', 'rawdev',
> > > > > - 'rcu', 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > > + 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > > # ipsec lib depends on net, crypto and security
> > > > > 'ipsec',
> > > > > # add pkt framework libs which use other libs from above
> > > > > --
> > > > > 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] eventdev: flag to identify same destined packets enqueue
2019-10-04 10:47 2% ` [dpdk-dev] [PATCH v3] " Nipun Gupta
@ 2019-10-05 16:23 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2019-10-05 16:23 UTC (permalink / raw)
To: Nipun Gupta
Cc: dpdk-dev, Jerin Jacob, aconole, Pavan Nikhilesh,
Sunil Kumar Kori, Hemant Agrawal, Richardson, Bruce,
Marko Kovacevic, Ori Kam, Radu Nicolau, Tomasz Kantecki,
Van Haaren, Harry, Rao, Nikhil
On Fri, Oct 4, 2019 at 4:33 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
> This patch introduces a `flag` in the Eth TX adapter enqueue API.
> Some drivers may support burst functionality only with the packets
> having same destination device and queue.
>
> The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> to indicate this so the underlying driver, for drivers to utilize
> burst functionality appropriately.
>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>
> Changes in v3:
> - remove flag from internal txa_enqueue_same_dest internal API
> - ABI version update in makefile, meson and rel_notes
> - Few comments update
>
> Changes in v2:
> - have separate internal API in tx adapter for sending burst packets to
> same eth dev, queue pair on the basis of the passed flag
> - fix compilation of examples/eventdev_pipeline/
> event.queue_id = qid; /* event queue linked to adapter port */
> diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
> index 27cfbd9e3..e589e020e 100644
> --- a/doc/guides/rel_notes/release_19_11.rst
> +++ b/doc/guides/rel_notes/release_19_11.rst
> @@ -146,7 +146,7 @@ The libraries prepended with a plus sign were incremented in this version.
> librte_eal.so.11
> librte_efd.so.1
> librte_ethdev.so.12
> - librte_eventdev.so.7
> + librte_eventdev.so.8
> librte_flow_classify.so.1
> librte_gro.so.1
> librte_gso.so.1
Forgot to update "API Changes" section in doc/guides/rel_notes/release_19_11.rst
> +static uint16_t
> +rte_event_tx_adapter_enqueue_same_dest(__rte_unused void *port,
> + __rte_unused struct rte_event ev[],
> + __rte_unused uint16_t nb_events)
> +{
> + rte_errno = ENOTSUP;
> + return 0;
> +}
> +
> struct rte_eventdev *
> rte_event_pmd_allocate(const char *name, int socket_id)
> {
> @@ -1351,6 +1360,8 @@ rte_event_pmd_allocate(const char *name, int socket_id)
> eventdev = &rte_eventdevs[dev_id];
>
> eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
> + eventdev->txa_enqueue_same_dest =
> + rte_event_tx_adapter_enqueue_same_dest;
We may not need to add new rte_event_tx_adapter_enqueue_same_dest function
as it is same as rte_event_tx_adapter_enqueue() and can simply assign
txa_enqueue_same_dest as rte_event_tx_adapter_enqueue. No strong
opinion on this.
With the above changes:
Acked-by: Jerin Jacob <jerinj@marvell.com>
I wait for a week for any review comments, If none, I will merge your
next revision.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4 0/4] mbuf copy/cloning enhancements
2019-09-30 15:27 3% ` [dpdk-dev] [PATCH v2 0/6] mbuf copy related enhancements Stephen Hemminger
2019-09-30 19:20 3% ` [dpdk-dev] [PATCH v3 0/6] mbuf copy/cloning enhancements Stephen Hemminger
@ 2019-10-04 21:47 3% ` Stephen Hemminger
2019-10-07 15:43 3% ` [dpdk-dev] [PATCH v5 0/5] " Stephen Hemminger
2019-10-08 16:33 3% ` [dpdk-dev] [PATCH v6 0/5] mbuf: " Stephen Hemminger
4 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-10-04 21:47 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This patch set is all about improving the mbuf related cloning
and copying. They are motivated by seeing issues with mbuf copying
in rte_pdump and realized this a wider and more general problem.
The pdump copy could not handle different size pools and did
not handle meta data, etc.
They cause no functional or ABI changes. The only visible part
to older code is converting a couple of inlines to real functions.
This kind of change confuses checkpatch which thinks these new
functions should be marked experimental when they must not be.
v4 - common mbuf header fields copy routine
v3 - split linearize into internal/external
copy private data in pktmbuf_copy
v2 - add pdump use of pktmbuf_copy
fix version in map
Stephen Hemminger (4):
mbuf: don't generate invalid mbuf in clone test
mbuf: delinline rte_pktmbuf_linearize
mbuf: deinline rte_pktmbuf_clone
mbuf: add a pktmbuf copy routine
app/test/test_mbuf.c | 3 +
lib/librte_mbuf/rte_mbuf.c | 145 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 127 +++++++++--------------
lib/librte_mbuf/rte_mbuf_version.map | 8 ++
4 files changed, 206 insertions(+), 77 deletions(-)
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3] eventdev: flag to identify same destined packets enqueue
` (2 preceding siblings ...)
@ 2019-10-04 10:47 2% ` Nipun Gupta
2019-10-05 16:23 0% ` Jerin Jacob
2019-10-09 7:32 6% ` [dpdk-dev] [PATCH v4] " Nipun Gupta
2019-10-11 13:03 6% ` [dpdk-dev] [PATCH v5] " Nipun Gupta
5 siblings, 1 reply; 200+ results
From: Nipun Gupta @ 2019-10-04 10:47 UTC (permalink / raw)
To: dev
Cc: jerinj, aconole, pbhagavatula, skori, hemant.agrawal,
bruce.richardson, marko.kovacevic, orika, radu.nicolau,
tomasz.kantecki, harry.van.haaren, nikhil.rao, Nipun Gupta
This patch introduces a `flag` in the Eth TX adapter enqueue API.
Some drivers may support burst functionality only with the packets
having same destination device and queue.
The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
to indicate this so the underlying driver, for drivers to utilize
burst functionality appropriately.
Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
---
Changes in v3:
- remove flag from internal txa_enqueue_same_dest internal API
- ABI version update in makefile, meson and rel_notes
- Few comments update
Changes in v2:
- have separate internal API in tx adapter for sending burst packets to
same eth dev, queue pair on the basis of the passed flag
- fix compilation of examples/eventdev_pipeline/
app/test-eventdev/test_pipeline_common.h | 6 +++---
.../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
doc/guides/rel_notes/release_19_11.rst | 2 +-
.../eventdev_pipeline/pipeline_worker_tx.c | 2 +-
lib/librte_eventdev/Makefile | 2 +-
lib/librte_eventdev/meson.build | 2 +-
.../rte_event_eth_tx_adapter.h | 19 +++++++++++++++++--
lib/librte_eventdev/rte_eventdev.c | 11 +++++++++++
lib/librte_eventdev/rte_eventdev.h | 10 ++++++++++
9 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
index 0440b9e29..6e73c6ab2 100644
--- a/app/test-eventdev/test_pipeline_common.h
+++ b/app/test-eventdev/test_pipeline_common.h
@@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t port,
struct rte_event * const ev)
{
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
@@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
{
uint16_t enq;
- enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
+ enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
while (enq < nb_rx) {
enq += rte_event_eth_tx_adapter_enqueue(dev, port,
- ev + enq, nb_rx - enq);
+ ev + enq, nb_rx - enq, 0);
}
}
diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
index 192f9e1cf..a8c13e136 100644
--- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
+++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
@@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()`` function.
if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
event.mbuf = m;
+ eq_flags = 0;
m->port = tx_port;
rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
- rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
+ rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags);
} else {
event.queue_id = qid; /* event queue linked to adapter port */
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e3..e589e020e 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -146,7 +146,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_eal.so.11
librte_efd.so.1
librte_ethdev.so.12
- librte_eventdev.so.7
+ librte_eventdev.so.8
librte_flow_classify.so.1
librte_gro.so.1
librte_gso.so.1
diff --git a/examples/eventdev_pipeline/pipeline_worker_tx.c b/examples/eventdev_pipeline/pipeline_worker_tx.c
index 8961cd656..a0f40c27c 100644
--- a/examples/eventdev_pipeline/pipeline_worker_tx.c
+++ b/examples/eventdev_pipeline/pipeline_worker_tx.c
@@ -40,7 +40,7 @@ worker_tx_pkt(const uint8_t dev, const uint8_t port, struct rte_event *ev)
{
exchange_mac(ev->mbuf);
rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
- while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
+ while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
rte_pause();
}
diff --git a/lib/librte_eventdev/Makefile b/lib/librte_eventdev/Makefile
index cd3ff8040..9e6a99aa1 100644
--- a/lib/librte_eventdev/Makefile
+++ b/lib/librte_eventdev/Makefile
@@ -8,7 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
LIB = librte_eventdev.a
# library version
-LIBABIVER := 7
+LIBABIVER := 8
# build flags
CFLAGS += -DALLOW_EXPERIMENTAL_API
diff --git a/lib/librte_eventdev/meson.build b/lib/librte_eventdev/meson.build
index 19541f23f..9ba6c0393 100644
--- a/lib/librte_eventdev/meson.build
+++ b/lib/librte_eventdev/meson.build
@@ -1,7 +1,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright(c) 2017 Intel Corporation
-version = 7
+version = 8
allow_experimental_apis = true
if is_linux
diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
index c848261c4..93b717af9 100644
--- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
+++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
@@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
int
rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
+#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
+/**< This flag is used when all the packets enqueued in the tx adapter are
+ * destined for the same Ethernet port & Tx queue.
+ */
+
/**
* Enqueue a burst of events objects or an event object supplied in *rte_event*
* structure on an event device designated by its *dev_id* through the event
@@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
* The number of event objects to enqueue, typically number of
* rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
* available for this port.
+ * @param flags
+ * RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
+ * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
+ * which are enqueued are destined for the same Ethernet port & Tx queue.
*
* @return
* The number of event objects actually enqueued on the event device. The
@@ -343,7 +352,8 @@ static inline uint16_t
rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
uint8_t port_id,
struct rte_event ev[],
- uint16_t nb_events)
+ uint16_t nb_events,
+ const uint8_t flags)
{
const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
@@ -359,7 +369,12 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
return 0;
}
#endif
- return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
+ if (flags)
+ return dev->txa_enqueue_same_dest(dev->data->ports[port_id],
+ ev, nb_events);
+ else
+ return dev->txa_enqueue(dev->data->ports[port_id], ev,
+ nb_events);
}
/**
diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
index f44c869cb..c66b3e7ef 100644
--- a/lib/librte_eventdev/rte_eventdev.c
+++ b/lib/librte_eventdev/rte_eventdev.c
@@ -1330,6 +1330,15 @@ rte_event_tx_adapter_enqueue(__rte_unused void *port,
return 0;
}
+static uint16_t
+rte_event_tx_adapter_enqueue_same_dest(__rte_unused void *port,
+ __rte_unused struct rte_event ev[],
+ __rte_unused uint16_t nb_events)
+{
+ rte_errno = ENOTSUP;
+ return 0;
+}
+
struct rte_eventdev *
rte_event_pmd_allocate(const char *name, int socket_id)
{
@@ -1351,6 +1360,8 @@ rte_event_pmd_allocate(const char *name, int socket_id)
eventdev = &rte_eventdevs[dev_id];
eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
+ eventdev->txa_enqueue_same_dest =
+ rte_event_tx_adapter_enqueue_same_dest;
if (eventdev->data == NULL) {
struct rte_eventdev_data *eventdev_data = NULL;
diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
index 5044a13d0..ced6f29d9 100644
--- a/lib/librte_eventdev/rte_eventdev.h
+++ b/lib/librte_eventdev/rte_eventdev.h
@@ -1230,6 +1230,12 @@ typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
struct rte_event ev[], uint16_t nb_events);
/**< @internal Enqueue burst of events on port of a device */
+typedef uint16_t (*event_tx_adapter_enqueue_same_dest)(void *port,
+ struct rte_event ev[], uint16_t nb_events);
+/**< @internal Enqueue burst of events on port of a device supporting
+ * burst having same destination Ethernet port & Tx queue.
+ */
+
#define RTE_EVENTDEV_NAME_MAX_LEN (64)
/**< @internal Max length of name of event PMD */
@@ -1292,6 +1298,10 @@ struct rte_eventdev {
/**< Pointer to PMD dequeue function. */
event_dequeue_burst_t dequeue_burst;
/**< Pointer to PMD dequeue burst function. */
+ event_tx_adapter_enqueue_same_dest txa_enqueue_same_dest;
+ /**< Pointer to PMD eth Tx adapter burst enqueue function with
+ * events destined to same Eth port & Tx queue.
+ */
event_tx_adapter_enqueue txa_enqueue;
/**< Pointer to PMD eth Tx adapter enqueue function. */
struct rte_eventdev_data *data;
--
2.17.1
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v2] eventdev: flag to identify same destined packets enqueue
@ 2019-10-04 8:21 4% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2019-10-04 8:21 UTC (permalink / raw)
To: Nipun Gupta
Cc: dpdk-dev, Jerin Jacob, aconole, Pavan Nikhilesh,
Sunil Kumar Kori, Hemant Agrawal, Richardson, Bruce,
Marko Kovacevic, Ori Kam, Radu Nicolau, Tomasz Kantecki,
Van Haaren, Harry, Rao, Nikhil, Ray Kinsella, Thomas Monjalon,
techboard
On Fri, Oct 4, 2019 at 12:41 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
> This patch introduces a `flag` in the Eth TX adapter enqueue API.
> Some drivers may support burst functionality only with the packets
> having same destination device and queue.
>
> The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> to indicate this so the underlying driver, for drivers to utilize
> burst functionality appropriately.
>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
>
> Changes in v2:
> - have separate internal API in tx adapter for sending burst packets to
> same eth dev, queue pair on the basis of the passed flag
> - fix compilation of examples/eventdev_pipeline/
>
> app/test-eventdev/test_pipeline_common.h | 6 +++---
> .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> .../eventdev_pipeline/pipeline_worker_tx.c | 2 +-
> .../rte_event_eth_tx_adapter.h | 19 +++++++++++++++++--
> lib/librte_eventdev/rte_eventdev.c | 12 ++++++++++++
> lib/librte_eventdev/rte_eventdev.h | 9 +++++++++
It is an ABI change so please update
a) lib/librte_eventdev/Makefile
b) lib/librte_eventdev/meson.build
c) doc/guides/rel_notes/release_19_11.rst
Please see c2189c907dd191b909ce1f18487d46410782e370 as reference.
If anyone has any objection for treating this ABI change as an
exception(ABI change without depreciation notice in advance)
then please shout.
> 6 files changed, 44 insertions(+), 7 deletions(-)
>
> diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> index c848261c4..f552b6023 100644
> --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
> int
> rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
>
> +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> +/**< This flag is used when all the packets enqueued in the tx adapter are
> + * destined for the same Ethernet device, queue pair.
I would say "Ethernet port and Tx queue"
> + */
> +
> /**
> * Enqueue a burst of events objects or an event object supplied in *rte_event*
> * structure on an event device designated by its *dev_id* through the event
> @@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
> * The number of event objects to enqueue, typically number of
> * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> * available for this port.
> + * @param flags
> + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
Change to @see
> + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
> + * which are enqueued are destined for the same Ethernet device, queue pair.
Same as above. Please check generated doxgen API output.
> *
> * @return
> * The number of event objects actually enqueued on the event device. The
> @@ -343,7 +352,8 @@ static inline uint16_t
> rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> uint8_t port_id,
> struct rte_event ev[],
> - uint16_t nb_events)
> + uint16_t nb_events,
> + const uint8_t flags)
> {
> const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
>
> @@ -359,7 +369,12 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> return 0;
> }
> #endif
> - return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
> + if (flags)
> + return dev->txa_enqueue_same_dest(dev->data->ports[port_id],
> + ev, nb_events, flags);
> + else
> + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> + nb_events);
> }
>
> /**
> diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
> index f44c869cb..7c8ffdfef 100644
> --- a/lib/librte_eventdev/rte_eventdev.c
> +++ b/lib/librte_eventdev/rte_eventdev.c
> @@ -1330,6 +1330,16 @@ rte_event_tx_adapter_enqueue(__rte_unused void *port,
> return 0;
> }
>
> +static uint16_t
> +rte_event_tx_adapter_enqueue_same_dest(__rte_unused void *port,
> + __rte_unused struct rte_event ev[],
> + __rte_unused uint16_t nb_events,
> + __rte_unused const uint8_t flags)
> +{
> + rte_errno = ENOTSUP;
> + return 0;
> +}
> +
> struct rte_eventdev *
> rte_event_pmd_allocate(const char *name, int socket_id)
> {
> @@ -1351,6 +1361,8 @@ rte_event_pmd_allocate(const char *name, int socket_id)
> eventdev = &rte_eventdevs[dev_id];
>
> eventdev->txa_enqueue = rte_event_tx_adapter_enqueue;
> + eventdev->txa_enqueue_same_dest =
> + rte_event_tx_adapter_enqueue_same_dest;
>
> if (eventdev->data == NULL) {
> struct rte_eventdev_data *eventdev_data = NULL;
> diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
> index 5044a13d0..ea61f52f6 100644
> --- a/lib/librte_eventdev/rte_eventdev.h
> +++ b/lib/librte_eventdev/rte_eventdev.h
> @@ -1230,6 +1230,13 @@ typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> struct rte_event ev[], uint16_t nb_events);
> /**< @internal Enqueue burst of events on port of a device */
>
> +typedef uint16_t (*event_tx_adapter_enqueue_same_dest)(void *port,
> + struct rte_event ev[], uint16_t nb_events,
> + const uint8_t flags);
> +/**< @internal Enqueue burst of events on port of a device supporting flag to
> + * indicate burst having same dest eth port and queue.
s/queue/Tx queue
> + */
> +
> #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> /**< @internal Max length of name of event PMD */
>
> @@ -1292,6 +1299,8 @@ struct rte_eventdev {
> /**< Pointer to PMD dequeue function. */
> event_dequeue_burst_t dequeue_burst;
> /**< Pointer to PMD dequeue burst function. */
> + event_tx_adapter_enqueue_same_dest txa_enqueue_same_dest;
> + /**< Pointer to PMD eth Tx adapter enqueue burst function. */
Is it really burst function? enqueue supports already support burst.
Please change the description.
> event_tx_adapter_enqueue txa_enqueue;
> /**< Pointer to PMD eth Tx adapter enqueue function. */
> struct rte_eventdev_data *data;
> --
> 2.17.1
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource reclamation APIs
@ 2019-10-04 6:07 3% ` Honnappa Nagarahalli
2019-10-07 10:46 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2019-10-04 6:07 UTC (permalink / raw)
To: Ananyev, Konstantin, stephen, paulmck
Cc: Wang, Yipeng1, Medvedkin, Vladimir,
Ruifeng Wang (Arm Technology China),
Dharmik Thakkar, dev, nd, nd, nd
>
> Hi Honnappa,
>
> > > > Add resource reclamation APIs to make it simple for applications
> > > > and libraries to integrate rte_rcu library.
> > > >
> > > > Signed-off-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > Reviewed-by: Ola Liljedhal <ola.liljedhal@arm.com>
> > > > Reviewed-by: Ruifeng Wang <ruifeng.wang@arm.com>
> > > > ---
> > > > app/test/test_rcu_qsbr.c | 291 ++++++++++++++++++++++++++++-
> > > > lib/librte_rcu/meson.build | 2 +
> > > > lib/librte_rcu/rte_rcu_qsbr.c | 185 ++++++++++++++++++
> > > > lib/librte_rcu/rte_rcu_qsbr.h | 169 +++++++++++++++++
> > > > lib/librte_rcu/rte_rcu_qsbr_pvt.h | 46 +++++
> > > > lib/librte_rcu/rte_rcu_version.map | 4 +
> > > > lib/meson.build | 6 +-
> > > > 7 files changed, 700 insertions(+), 3 deletions(-) create mode
> > > > 100644 lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > >
> > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > b/lib/librte_rcu/rte_rcu_qsbr.c index ce7f93dd3..76814f50b 100644
> > > > --- a/lib/librte_rcu/rte_rcu_qsbr.c
> > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.c
> > > > @@ -21,6 +21,7 @@
> > > > #include <rte_errno.h>
> > > >
> > > > #include "rte_rcu_qsbr.h"
> > > > +#include "rte_rcu_qsbr_pvt.h"
> > > >
> > > > /* Get the memory size of QSBR variable */ size_t @@ -267,6
> > > > +268,190 @@ rte_rcu_qsbr_dump(FILE *f, struct rte_rcu_qsbr *v)
> > > > return 0;
> > > > }
> > > >
> > > > +/* Create a queue used to store the data structure elements that
> > > > +can
> > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > + */
> > > > +struct rte_rcu_qsbr_dq *
> > > > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > > > +*params) {
> > > > + struct rte_rcu_qsbr_dq *dq;
> > > > + uint32_t qs_fifo_size;
> > > > +
> > > > + if (params == NULL || params->f == NULL ||
> > > > + params->v == NULL || params->name == NULL ||
> > > > + params->size == 0 || params->esize == 0 ||
> > > > + (params->esize % 8 != 0)) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): Invalid input parameter\n", __func__);
> > > > + rte_errno = EINVAL;
> > > > +
> > > > + return NULL;
> > > > + }
> > > > +
> > > > + dq = rte_zmalloc(NULL,
> > > > + (sizeof(struct rte_rcu_qsbr_dq) + params->esize),
> > > > + RTE_CACHE_LINE_SIZE);
> > > > + if (dq == NULL) {
> > > > + rte_errno = ENOMEM;
> > > > +
> > > > + return NULL;
> > > > + }
> > > > +
> > > > + /* round up qs_fifo_size to next power of two that is not less than
> > > > + * max_size.
> > > > + */
> > > > + qs_fifo_size = rte_align32pow2((((params->esize/8) + 1)
> > > > + * params->size) + 1);
> > > > + dq->r = rte_ring_create(params->name, qs_fifo_size,
> > > > + SOCKET_ID_ANY, 0);
> > >
> > > If it is going to be not MT safe, then why not to create the ring
> > > with (RING_F_SP_ENQ | RING_F_SC_DEQ) flags set?
> > Agree.
> >
> > > Though I think it could be changed to allow MT safe multiple
> > > enqeue/single dequeue, see below.
> > The MT safe issue is due to reclaim code. The reclaim code has the following
> sequence:
> >
> > rte_ring_peek
> > rte_rcu_qsbr_check
> > rte_ring_dequeue
> >
> > This entire sequence needs to be atomic as the entry cannot be dequeued
> without knowing that the grace period for that entry is over.
>
> I understand that, though I believe at least it should be possible to support
> multiple-enqueue/single dequeuer and reclaim mode.
> With serialized dequeue() even multiple dequeue should be possible.
Agreed. Please see the response on the other thread.
>
> > Note that due to optimizations in rte_rcu_qsbr_check API, this
> > sequence should not be large in most cases. I do not have ideas on how to
> make this sequence lock-free.
> >
> > If the writer is on the control plane, most use cases will use mutex
> > locks for synchronization if they are multi-threaded. That lock should be
> enough to provide the thread safety for these APIs.
>
> In that is case, why do we need ring at all?
> For sure people can create their own queue quite easily with mutex and TAILQ.
> If performance is not an issue, they can even add pthread_cond to it, and have
> an ability for the consumer to sleep/wakeup on empty/full queue.
>
> >
> > If the writer is multi-threaded and lock-free, then one should use per thread
> defer queue.
>
> If that's the only working model, then the question is why do we need that API
> at all?
> Just simple array with counter or linked-list should do for majority of cases.
Please see the other thread.
>
> >
> > >
> > > > + if (dq->r == NULL) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): defer queue create failed\n", __func__);
> > > > + rte_free(dq);
> > > > + return NULL;
> > > > + }
> > > > +
> > > > + dq->v = params->v;
> > > > + dq->size = params->size;
> > > > + dq->esize = params->esize;
> > > > + dq->f = params->f;
> > > > + dq->p = params->p;
> > > > +
> > > > + return dq;
> > > > +}
> > > > +
> > > > +/* Enqueue one resource to the defer queue to free after the
> > > > +grace
> > > > + * period is over.
> > > > + */
> > > > +int rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e) {
> > > > + uint64_t token;
> > > > + uint64_t *tmp;
> > > > + uint32_t i;
> > > > + uint32_t cur_size, free_size;
> > > > +
> > > > + if (dq == NULL || e == NULL) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): Invalid input parameter\n", __func__);
> > > > + rte_errno = EINVAL;
> > > > +
> > > > + return 1;
> > >
> > > Why just not to return -EINVAL straightway?
> > > I think there is no much point to set rte_errno in that function at
> > > all, just return value should do.
> > I am trying to keep these consistent with the existing APIs. They return 0 or 1
> and set the rte_errno.
>
> A lot of public DPDK API functions do use return value to return status code (0,
> or some positive numbers of success, negative errno values on failure), I am
> not inventing anything new here.
Agree, you are not proposing a new thing here. May be I was not clear. I really do not have an opinion on how this should be done. But, I do have an opinion on consistency. These new APIs follow what has been done in the existing RCU APIs. I think we have 2 options here.
1) Either we change existing RCU APIs to get rid of rte_errno (is it an ABI change?) or
2) The new APIs follow what has been done in the existing RCU APIs.
I want to make sure we are consistent at least within RCU APIs.
>
> >
> > >
> > > > + }
> > > > +
> > > > + /* Start the grace period */
> > > > + token = rte_rcu_qsbr_start(dq->v);
> > > > +
> > > > + /* Reclaim resources if the queue is 1/8th full. This helps
> > > > + * the queue from growing too large and allows time for reader
> > > > + * threads to report their quiescent state.
> > > > + */
> > > > + cur_size = rte_ring_count(dq->r) / (dq->esize/8 + 1);
> > >
> > > Probably would be a bit easier if you just store in dq->esize (elt
> > > size + token
> > > size) / 8.
> > Agree
> >
> > >
> > > > + if (cur_size > (dq->size >> RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT)) {
> > >
> > > Why to make this threshold value hard-coded?
> > > Why either not to put it into create parameter, or just return a
> > > special return value, to indicate that threshold is reached?
> > My thinking was to keep the programming interface easy to use. The
> > more the parameters, the more painful it is for the user. IMO, the
> > constants chosen should be good enough for most cases. More advanced
> users could modify the constants. However, we could make these as part of the
> parameters, but make them optional for the user. For ex: if they set them to 0,
> default values can be used.
> >
> > > Or even return number of filled/free entroes on success, so caller
> > > can decide to reclaim or not based on that information on his own?
> > This means more code on the user side.
>
> I personally think it it really wouldn't be that big problem to the user to pass
> extra parameter to the function.
I will convert the 2 constants into optional parameters (user can set them to 0 to make the algorithm use default values)
> Again what if user doesn't want to reclaim() in enqueue() thread at all?
'enqueue' has to do reclamation if the defer queue is full. I do not think this is trivial.
In the current design, reclamation in enqueue is also done on regular basis (automatic triggering of reclamation when the queue reaches certain limit) to keep the queue from growing too large. This is required when we implement a dynamically adjusting defer queue. The current algorithm keeps the cost of reclamation spread across multiple calls and puts an upper bound on cycles for delete API by reclaiming a fixed number of entries.
This algorithm is proven to work in the LPM integration performance tests at a very low performance over head (~1%). So, I do not know why a user would not want to use this. The 2 additional parameters should give the user more flexibility.
However, if the user wants his own algorithm, he can create one with the base APIs provided.
>
> > I think adding these to parameters seems like a better option.
> >
> > >
> > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > + "%s(): Triggering reclamation\n", __func__);
> > > > + rte_rcu_qsbr_dq_reclaim(dq);
> > > > + }
> > > > +
> > > > + /* Check if there is space for atleast for 1 resource */
> > > > + free_size = rte_ring_free_count(dq->r) / (dq->esize/8 + 1);
> > > > + if (!free_size) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): Defer queue is full\n", __func__);
> > > > + rte_errno = ENOSPC;
> > > > + return 1;
> > > > + }
> > > > +
> > > > + /* Enqueue the resource */
> > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)token);
> > > > +
> > > > + /* The resource to enqueue needs to be a multiple of 64b
> > > > + * due to the limitation of the rte_ring implementation.
> > > > + */
> > > > + for (i = 0, tmp = (uint64_t *)e; i < dq->esize/8; i++, tmp++)
> > > > + rte_ring_sp_enqueue(dq->r, (void *)(uintptr_t)*tmp);
> > >
> > >
> > > That whole construction above looks a bit clumsy and error prone...
> > > I suppose just:
> > >
> > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t free, n; ...
> > > n = rte_ring_enqueue_bulk(dq->r, e, nb_elt, &free); if (n == 0)
> > Yes, bulk enqueue can be used. But note that once the flexible element size
> ring patch is done, this code will use that.
>
> Well, when it will be in the mainline, and it would provide a better way, for sure
> this code can be updated to use new API (if it is provide some improvements).
> But as I udenrstand, right now it is not there, while bulk enqueue/dequeue are.
Apologies, I was not clear. I agree we can go with bulk APIs for now.
>
> >
> > > return -ENOSPC;
> > > return free;
> > >
> > > That way I think you can have MT-safe version of that function.
> > Please see the description of MT safe issue above.
> >
> > >
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > +/* Reclaim resources from the defer queue. */ int
> > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq) {
> > > > + uint32_t max_cnt;
> > > > + uint32_t cnt;
> > > > + void *token;
> > > > + uint64_t *tmp;
> > > > + uint32_t i;
> > > > +
> > > > + if (dq == NULL) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): Invalid input parameter\n", __func__);
> > > > + rte_errno = EINVAL;
> > > > +
> > > > + return 1;
> > >
> > > Same story as above - I think rte_errno is excessive in this function.
> > > Just return value should be enough.
> > >
> > >
> > > > + }
> > > > +
> > > > + /* Anything to reclaim? */
> > > > + if (rte_ring_count(dq->r) == 0)
> > > > + return 0;
> > >
> > > Not sure you need that, see below.
> > >
> > > > +
> > > > + /* Reclaim at the max 1/16th the total number of entries. */
> > > > + max_cnt = dq->size >> RTE_RCU_QSBR_MAX_RECLAIM_LIMIT;
> > > > + max_cnt = (max_cnt == 0) ? dq->size : max_cnt;
> > >
> > > Again why not to make max_cnt a configurable at create() parameter?
> > I think making this as an optional parameter for creating defer queue is a
> better option.
> >
> > > Or even a parameter for that function?
> > >
> > > > + cnt = 0;
> > > > +
> > > > + /* Check reader threads quiescent state and reclaim resources */
> > > > + while ((cnt < max_cnt) && (rte_ring_peek(dq->r, &token) == 0) &&
> > > > + (rte_rcu_qsbr_check(dq->v, (uint64_t)((uintptr_t)token), false)
> > > > + == 1)) {
> > >
> > >
> > > > + (void)rte_ring_sc_dequeue(dq->r, &token);
> > > > + /* The resource to dequeue needs to be a multiple of 64b
> > > > + * due to the limitation of the rte_ring implementation.
> > > > + */
> > > > + for (i = 0, tmp = (uint64_t *)dq->e; i < dq->esize/8;
> > > > + i++, tmp++)
> > > > + (void)rte_ring_sc_dequeue(dq->r,
> > > > + (void *)(uintptr_t)tmp);
> > >
> > > Again, no need for such constructs with multiple dequeuer I believe.
> > > Just:
> > >
> > > const uint32_t nb_elt = dq->elt_size/8 + 1; uint32_t n; uintptr_t
> > > elt[nb_elt]; ...
> > > n = rte_ring_dequeue_bulk(dq->r, elt, nb_elt, NULL); if (n != 0)
> > > {dq->f(dq->p, elt);}
> > Agree on bulk API use.
> >
> > >
> > > Seems enough.
> > > Again in that case you can have enqueue/reclaim running in different
> > > threads simultaneously, plus you don't need dq->e at all.
> > Will check on dq->e
> >
> > >
> > > > + dq->f(dq->p, dq->e);
> > > > +
> > > > + cnt++;
> > > > + }
> > > > +
> > > > + rte_log(RTE_LOG_INFO, rte_rcu_log_type,
> > > > + "%s(): Reclaimed %u resources\n", __func__, cnt);
> > > > +
> > > > + if (cnt == 0) {
> > > > + /* No resources were reclaimed */
> > > > + rte_errno = EAGAIN;
> > > > + return 1;
> > > > + }
> > > > +
> > > > + return 0;
> > >
> > > I'd suggest to return cnt on success.
> > I am trying to keep the APIs simple. I do not see much use for 'cnt'
> > as return value to the user. It exposes more details which I think are internal
> to the library.
>
> Not sure what is the hassle to return number of completed reclamaitions?
> If user doesn't need that information, he simply wouldn't use it.
> But might be it would be usefull - he can decide should he try another attempt
> of reclaim() immediately or is it ok to do something else.
There is no hassle to return that information.
As per the current design, user calls 'reclaim' when it is out of resources while adding an entry to the data structure. At that point the user wants to know if at least 1 resource was reclaimed because the user has to allocate 1 resource. He does not have a use for the number of resources reclaimed.
If this API returns 0, then the user can decide to repeat the call or return failure. But that decision depends on the length of the grace period which is under user's control.
>
> >
> > >
> > > > +}
> > > > +
> > > > +/* Delete a defer queue. */
> > > > +int
> > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq) {
> > > > + if (dq == NULL) {
> > > > + rte_log(RTE_LOG_ERR, rte_rcu_log_type,
> > > > + "%s(): Invalid input parameter\n", __func__);
> > > > + rte_errno = EINVAL;
> > > > +
> > > > + return 1;
> > > > + }
> > > > +
> > > > + /* Reclaim all the resources */
> > > > + if (rte_rcu_qsbr_dq_reclaim(dq) != 0)
> > > > + /* Error number is already set by the reclaim API */
> > > > + return 1;
> > >
> > > How do you know that you have reclaimed everything?
> > Good point, will come back with a different solution.
> >
> > >
> > > > +
> > > > + rte_ring_free(dq->r);
> > > > + rte_free(dq);
> > > > +
> > > > + return 0;
> > > > +}
> > > > +
> > > > int rte_rcu_log_type;
> > > >
> > > > RTE_INIT(rte_rcu_register)
> > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > b/lib/librte_rcu/rte_rcu_qsbr.h index c80f15c00..185d4b50a 100644
> > > > --- a/lib/librte_rcu/rte_rcu_qsbr.h
> > > > +++ b/lib/librte_rcu/rte_rcu_qsbr.h
> > > > @@ -34,6 +34,7 @@ extern "C" {
> > > > #include <rte_lcore.h>
> > > > #include <rte_debug.h>
> > > > #include <rte_atomic.h>
> > > > +#include <rte_ring.h>
> > > >
> > > > extern int rte_rcu_log_type;
> > > >
> > > > @@ -109,6 +110,67 @@ struct rte_rcu_qsbr {
> > > > */
> > > > } __rte_cache_aligned;
> > > >
> > > > +/**
> > > > + * Call back function called to free the resources.
> > > > + *
> > > > + * @param p
> > > > + * Pointer provided while creating the defer queue
> > > > + * @param e
> > > > + * Pointer to the resource data stored on the defer queue
> > > > + *
> > > > + * @return
> > > > + * None
> > > > + */
> > > > +typedef void (*rte_rcu_qsbr_free_resource)(void *p, void *e);
> > >
> > > Stylish thing - usually in DPDK we have typedf newtype_t ...
> > > Though I am not sure you need a new typedef at all - just a function
> > > pointer inside the struct seems enough.
> > Other libraries (for ex: rte_hash) use this approach. I think it is better to keep
> it out of the structure to allow for better commenting.
>
> I am saying majority of DPDK code use _t suffix for typedef:
> typedef void (*rte_rcu_qsbr_free_resource_t)(void *p, void *e);
Apologies, got it, will change.
>
> >
> > >
> > > > +
> > > > +#define RTE_RCU_QSBR_DQ_NAMESIZE RTE_RING_NAMESIZE
> > > > +
> > > > +/**
> > > > + * Trigger automatic reclamation after 1/8th the defer queue is full.
> > > > + */
> > > > +#define RTE_RCU_QSBR_AUTO_RECLAIM_LIMIT 3
> > > > +
> > > > +/**
> > > > + * Reclaim at the max 1/16th the total number of resources.
> > > > + */
> > > > +#define RTE_RCU_QSBR_MAX_RECLAIM_LIMIT 4
> > >
> > >
> > > As I said above, I don't think these thresholds need to be hardcoded.
> > > In any case, there seems not much point to put them in the public header
> file.
> > >
> > > > +
> > > > +/**
> > > > + * Parameters used when creating the defer queue.
> > > > + */
> > > > +struct rte_rcu_qsbr_dq_parameters {
> > > > + const char *name;
> > > > + /**< Name of the queue. */
> > > > + uint32_t size;
> > > > + /**< Number of entries in queue. Typically, this will be
> > > > + * the same as the maximum number of entries supported in the
> > > > + * lock free data structure.
> > > > + * Data structures with unbounded number of entries is not
> > > > + * supported currently.
> > > > + */
> > > > + uint32_t esize;
> > > > + /**< Size (in bytes) of each element in the defer queue.
> > > > + * This has to be multiple of 8B as the rte_ring APIs
> > > > + * support 8B element sizes only.
> > > > + */
> > > > + rte_rcu_qsbr_free_resource f;
> > > > + /**< Function to call to free the resource. */
> > > > + void *p;
> > >
> > > Style nit again - I like short names myself, but that seems a bit
> > > extreme... :) Might be at least:
> > > void (*reclaim)(void *, void *);
> > May be 'free_fn'?
> >
> > > void * reclaim_data;
> > > ?
> > This is the pointer to the data structure to free the resource into. For ex: In
> LPM data structure, it will be pointer to LPM. 'reclaim_data'
> > does not convey the meaning correctly.
>
> Ok, please free to comeup with your own names.
> I just wanted to say that 'f' and 'p' are a bit an extreme for public API.
ok, this is the hardest thing to do 😊
>
> >
> > >
> > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > + * pointer to the data structure to which the resource to free
> > > > + * belongs. This can be NULL.
> > > > + */
> > > > + struct rte_rcu_qsbr *v;
> > >
> > > Does it need to be inside that struct?
> > > Might be better:
> > > rte_rcu_qsbr_dq_create(struct rte_rcu_qsbr *v, const struct
> > > rte_rcu_qsbr_dq_parameters *params);
> > The API takes a parameter structure as input anyway, why to add
> > another argument to the function? QSBR variable is also another parameter.
> >
> > >
> > > Another alternative: make both reclaim() and enqueue() to take v as
> > > a parameter.
> > But both of them need access to some of the parameters provided in
> > rte_rcu_qsbr_dq_create API. We would end up passing 2 arguments to the
> functions.
>
> Pure stylish thing.
> From my perspective it just provides better visibility what is going in the code:
> For QSBR var 'v' create a new deferred queue.
> But no strong opinion here.
>
> >
> > >
> > > > + /**< RCU QSBR variable to use for this defer queue */ };
> > > > +
> > > > +/* RTE defer queue structure.
> > > > + * This structure holds the defer queue. The defer queue is used
> > > > +to
> > > > + * hold the deleted entries from the data structure that are not
> > > > + * yet freed.
> > > > + */
> > > > +struct rte_rcu_qsbr_dq;
> > > > +
> > > > /**
> > > > * @warning
> > > > * @b EXPERIMENTAL: this API may change without prior notice @@
> > > > -648,6 +710,113 @@ __rte_experimental int rte_rcu_qsbr_dump(FILE
> > > > *f, struct rte_rcu_qsbr *v);
> > > >
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > + *
> > > > + * Create a queue used to store the data structure elements that
> > > > +can
> > > > + * be freed later. This queue is referred to as 'defer queue'.
> > > > + *
> > > > + * @param params
> > > > + * Parameters to create a defer queue.
> > > > + * @return
> > > > + * On success - Valid pointer to defer queue
> > > > + * On error - NULL
> > > > + * Possible rte_errno codes are:
> > > > + * - EINVAL - NULL parameters are passed
> > > > + * - ENOMEM - Not enough memory
> > > > + */
> > > > +__rte_experimental
> > > > +struct rte_rcu_qsbr_dq *
> > > > +rte_rcu_qsbr_dq_create(const struct rte_rcu_qsbr_dq_parameters
> > > > +*params);
> > > > +
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > + *
> > > > + * Enqueue one resource to the defer queue and start the grace period.
> > > > + * The resource will be freed later after at least one grace
> > > > +period
> > > > + * is over.
> > > > + *
> > > > + * If the defer queue is full, it will attempt to reclaim resources.
> > > > + * It will also reclaim resources at regular intervals to avoid
> > > > + * the defer queue from growing too big.
> > > > + *
> > > > + * This API is not multi-thread safe. It is expected that the
> > > > +caller
> > > > + * provides multi-thread safety by locking a mutex or some other means.
> > > > + *
> > > > + * A lock free multi-thread writer algorithm could achieve
> > > > +multi-thread
> > > > + * safety by creating and using one defer queue per thread.
> > > > + *
> > > > + * @param dq
> > > > + * Defer queue to allocate an entry from.
> > > > + * @param e
> > > > + * Pointer to resource data to copy to the defer queue. The size of
> > > > + * the data to copy is equal to the element size provided when the
> > > > + * defer queue was created.
> > > > + * @return
> > > > + * On success - 0
> > > > + * On error - 1 with rte_errno set to
> > > > + * - EINVAL - NULL parameters are passed
> > > > + * - ENOSPC - Defer queue is full. This condition can not happen
> > > > + * if the defer queue size is equal (or larger) than the
> > > > + * number of elements in the data structure.
> > > > + */
> > > > +__rte_experimental
> > > > +int
> > > > +rte_rcu_qsbr_dq_enqueue(struct rte_rcu_qsbr_dq *dq, void *e);
> > > > +
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > + *
> > > > + * Reclaim resources from the defer queue.
> > > > + *
> > > > + * This API is not multi-thread safe. It is expected that the
> > > > +caller
> > > > + * provides multi-thread safety by locking a mutex or some other means.
> > > > + *
> > > > + * A lock free multi-thread writer algorithm could achieve
> > > > +multi-thread
> > > > + * safety by creating and using one defer queue per thread.
> > > > + *
> > > > + * @param dq
> > > > + * Defer queue to reclaim an entry from.
> > > > + * @return
> > > > + * On successful reclamation of at least 1 resource - 0
> > > > + * On error - 1 with rte_errno set to
> > > > + * - EINVAL - NULL parameters are passed
> > > > + * - EAGAIN - None of the resources have completed at least 1 grace
> > > period,
> > > > + * try again.
> > > > + */
> > > > +__rte_experimental
> > > > +int
> > > > +rte_rcu_qsbr_dq_reclaim(struct rte_rcu_qsbr_dq *dq);
> > > > +
> > > > +/**
> > > > + * @warning
> > > > + * @b EXPERIMENTAL: this API may change without prior notice
> > > > + *
> > > > + * Delete a defer queue.
> > > > + *
> > > > + * It tries to reclaim all the resources on the defer queue.
> > > > + * If any of the resources have not completed the grace period
> > > > + * the reclamation stops and returns immediately. The rest of
> > > > + * the resources are not reclaimed and the defer queue is not
> > > > + * freed.
> > > > + *
> > > > + * @param dq
> > > > + * Defer queue to delete.
> > > > + * @return
> > > > + * On success - 0
> > > > + * On error - 1
> > > > + * Possible rte_errno codes are:
> > > > + * - EINVAL - NULL parameters are passed
> > > > + * - EAGAIN - Some of the resources have not completed at least 1
> grace
> > > > + * period, try again.
> > > > + */
> > > > +__rte_experimental
> > > > +int
> > > > +rte_rcu_qsbr_dq_delete(struct rte_rcu_qsbr_dq *dq);
> > > > +
> > > > #ifdef __cplusplus
> > > > }
> > > > #endif
> > > > diff --git a/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > > > new file mode 100644
> > > > index 000000000..2122bc36a
> > > > --- /dev/null
> > > > +++ b/lib/librte_rcu/rte_rcu_qsbr_pvt.h
> > >
> > > Again style suggestion: as it is not public header - don't use rte_
> > > prefix for naming.
> > > From my perspective - easier to relalize for reader what is public
> > > header, what is not.
> > Looks like the guidelines are not defined very well. I see one private
> > file with rte_ prefix. I see Stephen not using rte_ prefix. I do not have any
> preference. But, a consistent approach is required.
>
> That's just a suggestion.
> For me (and I hope for others) it would be a bit easier.
> When looking at the code for first time I had to look a t meson.build to check is
> it a public header or not.
> If the file doesn't have 'rte_' prefix, I assume that it is an internal one
> straightway.
> But , as you said, there is no exact guidelines here, so up to you to decide.
I think it makes sense to remove 'rte_' prefix. I will also change the file name to have '_private' suffix.
There are some inconsistencies in the existing code, will send a patch to correct them to follow this approach.
>
> >
> > >
> > > > @@ -0,0 +1,46 @@
> > > > +/* SPDX-License-Identifier: BSD-3-Clause
> > > > + * Copyright (c) 2019 Arm Limited */
> > > > +
> > > > +#ifndef _RTE_RCU_QSBR_PVT_H_
> > > > +#define _RTE_RCU_QSBR_PVT_H_
> > > > +
> > > > +/**
> > > > + * This file is private to the RCU library. It should not be
> > > > +included
> > > > + * by the user of this library.
> > > > + */
> > > > +
> > > > +#ifdef __cplusplus
> > > > +extern "C" {
> > > > +#endif
> > > > +
> > > > +#include "rte_rcu_qsbr.h"
> > > > +
> > > > +/* RTE defer queue structure.
> > > > + * This structure holds the defer queue. The defer queue is used
> > > > +to
> > > > + * hold the deleted entries from the data structure that are not
> > > > + * yet freed.
> > > > + */
> > > > +struct rte_rcu_qsbr_dq {
> > > > + struct rte_rcu_qsbr *v; /**< RCU QSBR variable used by this queue.*/
> > > > + struct rte_ring *r; /**< RCU QSBR defer queue. */
> > > > + uint32_t size;
> > > > + /**< Number of elements in the defer queue */
> > > > + uint32_t esize;
> > > > + /**< Size (in bytes) of data stored on the defer queue */
> > > > + rte_rcu_qsbr_free_resource f;
> > > > + /**< Function to call to free the resource. */
> > > > + void *p;
> > > > + /**< Pointer passed to the free function. Typically, this is the
> > > > + * pointer to the data structure to which the resource to free
> > > > + * belongs.
> > > > + */
> > > > + char e[0];
> > > > + /**< Temporary storage to copy the defer queue element. */
> > >
> > > Do you really need 'e' at all?
> > > Can't it be just temporary stack variable?
> > Ok, will check.
> >
> > >
> > > > +};
> > > > +
> > > > +#ifdef __cplusplus
> > > > +}
> > > > +#endif
> > > > +
> > > > +#endif /* _RTE_RCU_QSBR_PVT_H_ */
> > > > diff --git a/lib/librte_rcu/rte_rcu_version.map
> > > > b/lib/librte_rcu/rte_rcu_version.map
> > > > index f8b9ef2ab..dfac88a37 100644
> > > > --- a/lib/librte_rcu/rte_rcu_version.map
> > > > +++ b/lib/librte_rcu/rte_rcu_version.map
> > > > @@ -8,6 +8,10 @@ EXPERIMENTAL {
> > > > rte_rcu_qsbr_synchronize;
> > > > rte_rcu_qsbr_thread_register;
> > > > rte_rcu_qsbr_thread_unregister;
> > > > + rte_rcu_qsbr_dq_create;
> > > > + rte_rcu_qsbr_dq_enqueue;
> > > > + rte_rcu_qsbr_dq_reclaim;
> > > > + rte_rcu_qsbr_dq_delete;
> > > >
> > > > local: *;
> > > > };
> > > > diff --git a/lib/meson.build b/lib/meson.build index
> > > > e5ff83893..0e1be8407 100644
> > > > --- a/lib/meson.build
> > > > +++ b/lib/meson.build
> > > > @@ -11,7 +11,9 @@
> > > > libraries = [
> > > > 'kvargs', # eal depends on kvargs
> > > > 'eal', # everything depends on eal
> > > > - 'ring', 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > + 'ring',
> > > > + 'rcu', # rcu depends on ring
> > > > + 'mempool', 'mbuf', 'net', 'meter', 'ethdev', 'pci', # core
> > > > 'cmdline',
> > > > 'metrics', # bitrate/latency stats depends on this
> > > > 'hash', # efd depends on this
> > > > @@ -22,7 +24,7 @@ libraries = [
> > > > 'gro', 'gso', 'ip_frag', 'jobstats',
> > > > 'kni', 'latencystats', 'lpm', 'member',
> > > > 'power', 'pdump', 'rawdev',
> > > > - 'rcu', 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > + 'reorder', 'sched', 'security', 'stack', 'vhost',
> > > > # ipsec lib depends on net, crypto and security
> > > > 'ipsec',
> > > > # add pkt framework libs which use other libs from above
> > > > --
> > > > 2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 01/13] ethdev: support setup function for hairpin queue
@ 2019-10-03 17:46 3% ` Ori Kam
0 siblings, 0 replies; 200+ results
From: Ori Kam @ 2019-10-03 17:46 UTC (permalink / raw)
To: Andrew Rybchenko, Thomas Monjalon, Ferruh Yigit; +Cc: dev, jingjing.wu, stephen
Hi Andrew,
@Thomas Monjalon, @Ferruh Yigit
Please comment if you have any issues with my answer.
Thanks,
Ori
> -----Original Message-----
> From: Andrew Rybchenko <arybchenko@solarflare.com>
> Sent: Thursday, October 3, 2019 4:26 PM
> To: Ori Kam <orika@mellanox.com>; Thomas Monjalon
> <thomas@monjalon.net>; Ferruh Yigit <ferruh.yigit@intel.com>
> Cc: dev@dpdk.org; jingjing.wu@intel.com; stephen@networkplumber.org
> Subject: Re: [dpdk-dev] [PATCH 01/13] ethdev: support setup function for
> hairpin queue
>
> Hi Ori,
>
> @Thomas, @Ferruh, please, see question below.
>
> On 10/2/19 3:19 PM, Ori Kam wrote:
> > Hi Andrew,
> >
> > Sorry it took me some time to responded, (I'm on vacation 😊)
> > I think we are in most cases in agreement. The only open issue is the
> > checks so please see my comments below.
> > As soon as we get to understanding about this issue, I will start working on V2.
> >
> > Thanks,
> > Ori
>
> [snip]
>
> >>>>>>> @@ -1769,6 +1793,60 @@ int rte_eth_rx_queue_setup(uint16_t
> port_id,
> >>>>>> uint16_t rx_queue_id,
> >>>>>>> struct rte_mempool *mb_pool);
> >>>>>>>
> >>>>>>> /**
> >>>>>>> + * @warning
> >>>>>>> + * @b EXPERIMENTAL: this API may change, or be removed, without
> prior
> >>>>>>> + notice
> >>>>>>> + *
> >>>>>>> + * Allocate and set up a hairpin receive queue for an Ethernet device.
> >>>>>>> + *
> >>>>>>> + * The function set up the selected queue to be used in hairpin.
> >>>>>>> + *
> >>>>>>> + * @param port_id
> >>>>>>> + * The port identifier of the Ethernet device.
> >>>>>>> + * @param rx_queue_id
> >>>>>>> + * The index of the receive queue to set up.
> >>>>>>> + * The value must be in the range [0, nb_rx_queue - 1] previously
> supplied
> >>>>>>> + * to rte_eth_dev_configure().
> >>>>>> Is any Rx queue may be setup as hairpin queue?
> >>>>>> Can it be still used for regular traffic?
> >>>>>>
> >>>>> No if a queue is used as hairpin it can't be used for normal traffic.
> >>>>> This is also why I like the idea of two different functions, in order to
> create
> >>>>> This distinction.
> >>>> If so, do we need at least debug-level checks in Tx/Rx burst functions?
> >>>> Is it required to patch rte flow RSS action to ensure that Rx queues of
> >>>> only one kind are specified?
> >>>> What about attempt to add Rx/Tx callbacks for hairpin queues?
> >>>>
> >>> I think the checks should be done in PMD level. Since from high level they
> are the
> >>> same.
> >> Sorry, I don't understand why. If something could be checked on generic
> level,
> >> it should be done to avoid duplication in all drivers.
> > The issue with this approach is that at the ethdev level we don't know
> anything about the queue.
> > This will mean that we will need to add extra functions to query the queue
> type for each PMD.
> > We could also assume that if to get type function exist in the pmd then the
> queue is always standard queue.
> > So my suggestion if you would like to move the checks is to add queue type
> enum in the ethdev level, and add
> > function call to query the queue type. What do you think?
>
> I would consider to use dev_data rx_queue_state and tx_queue_state to
> keep the information to have it directly available without extra function
> calls. Or add extra information. dev_data is internal and it looks like not
> a problem. What do you think?
>
I like the new state idea, it will save some memory in the dev_data, compared to having it
in the dev_data. Will also avoid extra ABI change.
> >>> Call backs for Rx/Tx doesn't make sense, since the idea is to bypass the
> CPU.
> >> If so, I think rte_eth_add_tx_callback() should be patched to return an
> >> error
> >> if specified queue is hairpin. Same for Rx.
> >> Any other cases?
> >>
> > Same answer as above.
>
> [snip]
>
> Andrew.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-10-01 14:49 0% ` Ananyev, Konstantin
@ 2019-10-03 13:24 0% ` Akhil Goyal
2019-10-07 12:53 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-10-03 13:24 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon'
Cc: Zhang, Roy Fan, Doherty, Declan, 'Anoob Joseph'
Hi Konstantin,
>
> Hi Akhil,
>
> > > > > > > > > > > > > > This action type allows the burst of symmetric crypto
> > > workload
> > > > > using
> > > > > > > > the
> > > > > > > > > > > > same
> > > > > > > > > > > > > > algorithm, key, and direction being processed by CPU
> cycles
> > > > > > > > > > synchronously.
> > > > > > > > > > > > > > This flexible action type does not require external
> hardware
> > > > > > > > involvement,
> > > > > > > > > > > > > > having the crypto workload processed synchronously,
> and is
> > > > > more
> > > > > > > > > > > > performant
> > > > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on
> removed
> > > > > "async
> > > > > > > > > > mode
> > > > > > > > > > > > > > simulation" as well as 3 cacheline access of the crypto
> ops.
> > > > > > > > > > > > >
> > > > > > > > > > > > > Does that mean application will not call the
> > > > > cryptodev_enqueue_burst
> > > > > > > > and
> > > > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > > > >
> > > > > > > > > > > > Yes, instead it just call
> rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > > > >
> > > > > > > > > > > > > It would be a new API something like process_packets and
> it
> > > will
> > > > > have
> > > > > > > > the
> > > > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > > > >
> > > > > > > > > > > > Yes, though the plan is that API will operate on raw data
> buffers,
> > > > > not
> > > > > > > > mbufs.
> > > > > > > > > > > >
> > > > > > > > > > > > >
> > > > > > > > > > > > > I still do not understand why we cannot do with the
> > > conventional
> > > > > > > > crypto lib
> > > > > > > > > > > > only.
> > > > > > > > > > > > > As far as I can understand, you are not doing any protocol
> > > > > processing
> > > > > > > > or
> > > > > > > > > > any
> > > > > > > > > > > > value add
> > > > > > > > > > > > > To the crypto processing. IMO, you just need a
> synchronous
> > > > > crypto
> > > > > > > > > > processing
> > > > > > > > > > > > API which
> > > > > > > > > > > > > Can be defined in cryptodev, you don't need to re-create a
> > > crypto
> > > > > > > > session
> > > > > > > > > > in
> > > > > > > > > > > > the name of
> > > > > > > > > > > > > Security session in the driver just to do a synchronous
> > > processing.
> > > > > > > > > > > >
> > > > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > > > The main reason is that would require disruptive changes in
> > > existing
> > > > > > > > > > cryptodev
> > > > > > > > > > > > API
> > > > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> need
> > > > > some
> > > > > > > > extra
> > > > > > > > > > > > information
> > > > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > > > (cipher offset from the start of the buffer, might be
> something
> > > extra
> > > > > in
> > > > > > > > > > future).
> > > > > > > > > > >
> > > > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > > > >
> > > > > > > > > > fill/read (+ alloc/free) is one of the main things that slowdown
> > > current
> > > > > > > > crypto-op
> > > > > > > > > > approach.
> > > > > > > > > > That's why the general idea - have all data that wouldn't change
> > > from
> > > > > packet
> > > > > > > > to
> > > > > > > > > > packet
> > > > > > > > > > included into the session and setup it once at session_init().
> > > > > > > > >
> > > > > > > > > I agree that you cannot use crypto-op.
> > > > > > > > > You can have the new API in crypto.
> > > > > > > > > As per the current patch, you only need cipher_offset which you
> can
> > > have
> > > > > it as
> > > > > > > > a parameter until
> > > > > > > > > You get it approved in the crypto xform. I believe it will be
> beneficial
> > > in
> > > > > case of
> > > > > > > > other crypto cases as well.
> > > > > > > > > We can have cipher offset at both places(crypto-op and
> > > cipher_xform). It
> > > > > will
> > > > > > > > give flexibility to the user to
> > > > > > > > > override it.
> > > > > > > >
> > > > > > > > After having another thought on your proposal:
> > > > > > > > Probably we can introduce new rte_crypto_sym_xform_types for
> CPU
> > > > > related
> > > > > > > > stuff here?
> > > > > > >
> > > > > > > I also thought of adding new xforms, but that wont serve the purpose
> for
> > > > > may be all the cases.
> > > > > > > You would be needing all information currently available in the
> current
> > > > > xforms.
> > > > > > > So if you are adding new fields in the new xform, the size will be more
> > > than
> > > > > that of the union of xforms.
> > > > > > > ABI breakage would still be there.
> > > > > > >
> > > > > > > If you think a valid compression of the AEAD xform can be done, then
> > > that
> > > > > can be done for each of the
> > > > > > > Xforms and we can have a solution to this issue.
> > > > > >
> > > > > > I think that we can re-use iv.offset for our purposes (for crypto offset).
> > > > > > So for now we can make that path work without any ABI breakage.
> > > > > > Fan, please feel free to correct me here, if I missed something.
> > > > > > If in future we would need to add some extra information it might
> > > > > > require ABI breakage, though by now I don't envision anything
> particular to
> > > > > add.
> > > > > > Anyway, if there is no objection to go that way, we can try to make
> > > > > > these changes for v2.
> > > > > >
> > > > >
> > > > > Actually, after looking at it more deeply it appears not that easy as I
> thought
> > > it
> > > > > would be :)
> > > > > Below is a very draft version of proposed API additions.
> > > > > I think it avoids ABI breakages right now and provides enough flexibility
> for
> > > > > future extensions (if any).
> > > > > For now, it doesn't address your comments about naming conventions
> > > (_CPU_
> > > > > vs _SYNC_) , etc.
> > > > > but I suppose is comprehensive enough to provide a main idea beyond it.
> > > > > Akhil and other interested parties, please try to review and provide
> feedback
> > > > > ASAP,
> > > > > as related changes would take some time and we still like to hit 19.11
> > > deadline.
> > > > > Konstantin
> > > > >
> > > > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > index bc8da2466..c03069e23 100644
> > > > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > > > *
> > > > > * This structure contains data relating to Cipher (Encryption and
> Decryption)
> > > > > * use to create a session.
> > > > > + * Actually I was wrong saying that we don't have free space inside
> xforms.
> > > > > + * Making key struct packed (see below) allow us to regain 6B that could
> be
> > > > > + * used for future extensions.
> > > > > */
> > > > > struct rte_crypto_cipher_xform {
> > > > > enum rte_crypto_cipher_operation op;
> > > > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > > > struct {
> > > > > const uint8_t *data; /**< pointer to key data */
> > > > > uint16_t length; /**< key length in bytes */
> > > > > - } key;
> > > > > + } __attribute__((__packed__)) key;
> > > > > +
> > > > > + /**
> > > > > + * offset for cipher to start within user provided data buffer.
> > > > > + * Fan suggested another (and less space consuming way) -
> > > > > + * reuse iv.offset space below, by changing:
> > > > > + * struct {uint16_t offset, length;} iv;
> > > > > + * to uunamed union:
> > > > > + * union {
> > > > > + * struct {uint16_t offset, length;} iv;
> > > > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > > > + * };
> > > > > + * Both approaches seems ok to me in general.
> > > >
> > > > No strong opinions here. OK with this one.
> > > >
> > > > > + * Comments/suggestions are welcome.
> > > > > + */
> > > > > + uint16_t offset;
> > >
> > > After another thought - it is probably a bit better to have offset as a separate
> > > field.
> > > In that case we can use the same xforms to create both type of sessions.
> > ok
> > >
> > > > > +
> > > > > + uint8_t reserved1[4];
> > > > > +
> > > > > /**< Cipher key
> > > > > *
> > > > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation,
> key.data
> > > will
> > > > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > > > struct {
> > > > > const uint8_t *data; /**< pointer to key data */
> > > > > uint16_t length; /**< key length in bytes */
> > > > > - } key;
> > > > > + } __attribute__((__packed__)) key;
> > > > > /**< Authentication key data.
> > > > > * The authentication key length MUST be less than or equal to the
> > > > > * block size of the algorithm. It is the callers responsibility to
> > > > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > > > * (for example RFC 2104, FIPS 198a).
> > > > > */
> > > > >
> > > > > + uint8_t reserved1[6];
> > > > > +
> > > > > struct {
> > > > > uint16_t offset;
> > > > > /**< Starting point for Initialisation Vector or Counter,
> > > > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > > > struct {
> > > > > const uint8_t *data; /**< pointer to key data */
> > > > > uint16_t length; /**< key length in bytes */
> > > > > - } key;
> > > > > + } __attribute__((__packed__)) key;
> > > > > +
> > > > > + /** offset for cipher to start within data buffer */
> > > > > + uint16_t cipher_offset;
> > > > > +
> > > > > + uint8_t reserved1[4];
> > > > >
> > > > > struct {
> > > > > uint16_t offset;
> > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > index e175b838c..c0c7bfed7 100644
> > > > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > > > @@ -1272,6 +1272,101 @@ void *
> > > > > rte_cryptodev_sym_session_get_user_data(
> > > > > struct rte_cryptodev_sym_session *sess);
> > > > >
> > > > > +/*
> > > > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > > > + * introduce an extentsion to it via new fully opaque
> > > > > + * struct rte_crypto_cpu_sym_session and additional related API.
> > > >
> > > >
> > > > What all things do we need to squeeze?
> > > > In this proposal I do not see the new struct cpu_sym_session defined here.
> > >
> > > The plan is to have it totally opaque to the user, i.e. just:
> > > struct rte_crypto_cpu_sym_session;
> > > in public header files.
> > >
> > > > I believe you will have same lib API/struct for cpu_sym_session and
> > > sym_session.
> > >
> > > I thought about such way, but there are few things that looks clumsy to me:
> > > 1. Right now there is no 'type' (or so) field inside rte_cryptodev_sym_session,
> > > so it is not possible to easy distinguish what session do you have: lksd_sym or
> > > cpu_sym.
> > > In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we can
> add
> > > some extra field
> > > here, but in that case we wouldn't be able to use the same xform for both
> > > lksd_sym or cpu_sym
> > > (which seems really plausible thing for me).
> > > 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary for
> > > rte_crypto_cpu_sym_session:
> > > sess_data[], opaque_data, user_data, nb_drivers.
> > > All that consumes space, that could be used somewhere else instead.
> > > 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> > > breakages I can't foresee right now.
> > > From other side - if we'll add new functions/structs for cpu_sym_session we
> can
> > > mark it
> > > and keep it for some time as experimental, so further changes (if needed)
> would
> > > still be possible.
> > >
> >
> > OK let us assume that you have a separate structure. But I have a few queries:
> > 1. how can multiple drivers use a same session
>
> As a short answer: they can't.
> It is pretty much the same approach as with rte_security - each device needs to
> create/init its own session.
> So upper layer would need to maintain its own array (or so) for such case.
> Though the question is why would you like to have same session over multiple
> SW backed devices?
> As it would be anyway just a synchronous function call that will be executed on
> the same cpu.
I may have single FAT tunnel which may be distributed over multiple
Cores, and each core is affined to a different SW device.
So a single session may be accessed by multiple devices.
One more example would be depending on packet sizes, I may switch between
HW/SW PMDs with the same session.
>
> > 2. Can somebody use the scheduler pmd for scheduling the different type of
> payloads for the same session?
>
> In theory yes.
> Though for that scheduler pmd should have inside it's
> rte_crypto_cpu_sym_session an array of pointers to
> the underlying devices sessions.
>
> >
> > With your proposal the APIs would be very specific to your use case only.
>
> Yes in some way.
> I consider that API specific for SW backed crypto PMDs.
> I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will benefit
> from it.
> Current crypto-op API is very much HW oriented.
> Which is ok, that's for it was intended for, but I think we also need one that
> would be designed
> for SW backed implementation in mind.
We may re-use your API for HW PMDs as well which do not have requirement of
Crypto-op/mbuf etc.
The return type of your new process API may have a status which say 'processed'
Or can be say 'enqueued'. So if it is 'enqueued', we may have a new API for raw
Bufs dequeue as well.
This requirement can be for any hardware PMDs like QAT as well.
That is why a dev-ops would be a better option.
>
> > When you would add more functionality to this sync API/struct, it will end up
> being the same API/struct.
> >
> > Let us see how close/ far we are from the existing APIs when the actual
> implementation is done.
> >
> > > > I am not sure if that would be needed.
> > > > It would be internal to the driver that if synchronous processing is
> > > supported(from feature flag) and
> > > > Have relevant fields in xform(the newly added ones which are packed as
> per
> > > your suggestions) set,
> > > > It will create that type of session.
> > > >
> > > >
> > > > > + * Main points:
> > > > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > > + * new sync API is new one and probably would require extra changes.
> > > > > + * Having it as a new one allows to mark it as experimental, without
> > > > > + * affecting existing one.
> > > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > > + * to the PMD writers and again allows to avoid ABI breakages in future.
> > > > > + * - process() function per set of xforms
> > > > > + * allows to expose different process() functions for different
> > > > > + * xform combinations. PMD writer can decide, does he wants to
> > > > > + * push all supported algorithms into one process() function,
> > > > > + * or spread it across several ones.
> > > > > + * I.E. More flexibility for PMD writer.
> > > >
> > > > Which process function should be chosen is internal to PMD, how would
> that
> > > info
> > > > be visible to the application or the library. These will get stored in the
> session
> > > private
> > > > data. It would be upto the PMD writer, to store the per session process
> > > function in
> > > > the session private data.
> > > >
> > > > Process function would be a dev ops just like enc/deq operations and it
> should
> > > call
> > > > The respective process API stored in the session private data.
> > >
> > > That model (via devops) is possible, but has several drawbacks from my
> > > perspective:
> > >
> > > 1. It means we'll need to pass dev_id as a parameter to process() function.
> > > Though in fact dev_id is not a relevant information for us here
> > > (all we need is pointer to the session and pointer to the fuction to call)
> > > and I tried to avoid using it in data-path functions for that API.
> >
> > You have a single vdev, but someone may have multiple vdevs for each thread,
> or may
> > Have same dev with multiple queues for each core.
>
> That's fine. As I said above it is a SW backed implementation.
> Each session has to be a separate entity that contains all necessary information
> (keys, alg/mode info, etc.) to process input buffers.
> Plus we need the actual function pointer to call.
> I just don't see what for we need a dev_id in that situation.
To iterate the session private data in the session.
> Again, here we don't need care about queues and their pinning to cores.
> If let say someone would like to process buffers from the same IPsec SA on 2
> different cores in parallel, he can just create 2 sessions for the same xform,
> give one to thread #1 and second to thread #2.
> After that both threads are free to call process(this_thread_ses, ...) at will.
Say you have a 16core device to handle 100G of traffic on a single tunnel.
Will we make 16 sessions with same parameters?
>
> >
> > > 2. As you pointed in that case it will be just one process() function per device.
> > > So if PMD would like to have several process() functions for different type of
> > > sessions
> > > (let say one per alg) first thing it has to do inside it's process() - read session
> data
> > > and
> > > based on that, do a jump/call to particular internal sub-routine.
> > > Something like:
> > > driver_id = get_pmd_driver_id();
> > > priv_ses = ses->sess_data[driver_id];
> > > Then either:
> > > switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> > > OR
> > > priv_ses->process(priv_sess, ...);
> > >
> > > to select and call the proper function.
> > > Looks like totally unnecessary overhead to me.
> > > Though if we'll have ability to query/extract some sort session_ops based on
> the
> > > xform -
> > > we can avoid this extra de-refererence+jump/call thing.
> >
> > What is the issue in the priv_ses->process(); approach?
>
> Nothing at all.
> What I am saying that schema with dev_ops
> dev[dev_id]->dev_ops.process(ses->priv_ses[driver_id], ...)
> |
> |-> priv_ses->process(...)
>
> Has bigger overhead then just:
> process(ses,...);
>
> So what for to introduce extra-level of indirection here?
Explained above.
>
> > I don't understand what are you saving by not doing this.
> > In any case you would need to identify which session correspond to which
> process().
>
> Yes, sure, but I think we can make user to store information that relationship,
> in a way he likes: store process() pointer for each session, or group sessions
> that share the same process() somehow, or...
So whatever relationship that user will make and store will make its life complicated.
If we can hide that information in the driver, then what is the issue in that and user
Will not need to worry. He would just call the process() and driver will choose which
Process need to be called.
I think we should have a POC around this and see the difference in the cycle count.
IMO it would be negligible and we would end up making a generic API set which
can be used by others as well.
>
> > For that you would be doing it somewhere in your data path.
>
> Why at data-path?
> Only once at session creation/initialization time.
> Or might be even once per group of sessions.
>
> >
> > >
> > > >
> > > > I am not sure if you would need a new session init API for this as nothing
> would
> > > be visible to
> > > > the app or lib.
> > > >
> > > > > + * - Not storing process() pointer inside the session -
> > > > > + * Allows user to choose does he want to store a process() pointer
> > > > > + * per session, or per group of sessions for that device that share
> > > > > + * the same input xforms. I.E. extra flexibility for the user,
> > > > > + * plus allows us to keep cpu_sym_session totally opaque, see above.
> > > >
> > > > If multiple sessions need to be processed via the same process function,
> > > > PMD would save the same process in all the sessions, I don't think there
> would
> > > > be any perf overhead with that.
> > >
> > > I think it would, see above.
> > >
> > > >
> > > > > + * Sketched usage model:
> > > > > + * ....
> > > > > + * /* control path, alloc/init session */
> > > > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > > > + * rte_crypto_cpu_sym_process_t process =
> > > > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > > > + * ...
> > > > > + * /* data-path*/
> > > > > + * process(ses, ....);
> > > > > + * ....
> > > > > + * /* control path, termiante/free session */
> > > > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > > > + */
> > > > > +
> > > > > +/**
> > > > > + * vector structure, contains pointer to vector array and the length
> > > > > + * of the array
> > > > > + */
> > > > > +struct rte_crypto_vec {
> > > > > + struct iovec *vec;
> > > > > + uint32_t num;
> > > > > +};
> > > > > +
> > > > > +/*
> > > > > + * Data-path bulk process crypto function.
> > > > > + */
> > > > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > > > + void *digest[], int status[], uint32_t num);
> > > > > +/*
> > > > > + * for given device return process function specific to input xforms
> > > > > + * on error - return NULL and set rte_errno value.
> > > > > + * Note that for same input xfroms for the same device should return
> > > > > + * the same process function.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +rte_crypto_cpu_sym_process_t
> > > > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > +/*
> > > > > + * Return required session size in bytes for given set of xforms.
> > > > > + * if xforms == NULL, then return the max possible session size,
> > > > > + * that would fit session for any supported by the device algorithm.
> > > > > + * if CPU mode is not supported at all, or requeted in xform
> > > > > + * algorithm is not supported, then return -ENOTSUP.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +int
> > > > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > +/*
> > > > > + * Initialize session.
> > > > > + * It is caller responsibility to allocate enough space for it.
> > > > > + * See rte_crypto_cpu_sym_session_size above.
> > > > > + */
> > > > > +__rte_experimental
> > > > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > +__rte_experimental
> > > > > +void
> > > > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > +
> > > > > +
> > > > > #ifdef __cplusplus
> > > > > }
> > > > > #endif
> > > > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > index defe05ea0..ed7e63fab 100644
> > > > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > > @@ -310,6 +310,20 @@ typedef void
> > > (*cryptodev_sym_free_session_t)(struct
> > > > > rte_cryptodev *dev,
> > > > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev
> *dev,
> > > > > struct rte_cryptodev_asym_session *sess);
> > > > >
> > > > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct rte_cryptodev
> > > *dev,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct rte_cryptodev
> > > *dev,
> > > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct rte_cryptodev
> > > *dev,
> > > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > > +
> > > > > +typedef rte_crypto_cpu_sym_process_t
> > > (*cryptodev_cpu_sym_session_func_t)
> > > > > (
> > > > > + struct rte_cryptodev *dev,
> > > > > + const struct rte_crypto_sym_xform *xforms);
> > > > > +
> > > > > /** Crypto device operations function pointer table */
> > > > > struct rte_cryptodev_ops {
> > > > > cryptodev_configure_t dev_configure; /**< Configure device. */
> > > > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > > > /**< Clear a Crypto sessions private data. */
> > > > > cryptodev_asym_free_session_t asym_session_clear;
> > > > > /**< Clear a Crypto sessions private data. */
> > > > > +
> > > > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > > > };
> > > > >
> > > > >
> > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-03 6:45 0% ` Hemant Agrawal
@ 2019-10-03 10:26 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2019-10-03 10:26 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Rao, Nikhil, Nipun Gupta, Jerin Jacob, dpdk-dev, Pavan Nikhilesh,
Sunil Kumar Kori, Richardson, Bruce, Kovacevic, Marko, Ori Kam,
Nicolau, Radu, Kantecki, Tomasz, Van Haaren, Harry
On Thu, Oct 3, 2019 at 12:15 PM Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
> Hi Nikhil,
>
> > -----Original Message-----
> > From: Rao, Nikhil <nikhil.rao@intel.com>
> > Sent: Thursday, October 3, 2019 11:43 AM
> > >
> > > On Wed, Oct 2, 2019 at 8:38 AM Hemant Agrawal
> > <hemant.agrawal@nxp.com>
> > > wrote:
> > > >
> > > > Hi Jerin,
> > >
> > > Hi Hemant,
> > >
> > >
> > > > > > I understand your concern that this shall not be valid on a general
> > cases.
> > > > > >
> > > > > > There are certain use-case (NXP internal) of DPDK event which
> > > > > > have separate event ports/cores dedicated for certain tasks -
> > > > > > and can use the burst functionality for performance according to
> > > > > > the event ports which are used. Not having this at runtime will
> > > > > > limit the flexibility for such
> > > > > applications.
> > > > >
> > > > > If it is specific to NXP internal use case then no more comments
> > > > > on dynamic vs static.
> > > > >
> > > > > @ Nikhil Rao any comments.
> > Hi Jerin, Hemant,
> >
> > Looks like we are trying to give a generic wrapper for the NXP internal use
> > case, do we really need to solve that problem ?
>
> [Hemant] no, that is not the case.
>
> On the argument sake, eth TX adapter is also Marvel/Cavium specific - the idea was to reach consensus and come with generic APIs. NXP does not need ethTX adapter.
> However, here, we are trying to avoid too many code paths for the applications, so that it becomes easy for the application writer.
>
> - We do support RX burst, so TX burst should be supported. I remember Marvel do not support RX burst, but we added it as NXP HW support it. Intel SW can also support it.
> - See existing L3 fwd application, how the burst accumulation is being done on per queue basis.
> - Why the application is not sending all the packets and letting driver do the buffering on per queue basis?
> - The reason is that applications knows which packets can be buffered, which need to be sent immediately. Only application can control the time out and different setting for burst mode. The burst segregation logic can not be pushed into the driver for all these various reasons.
>
> I am not in favor of new APIs and more code paths for the applications. It will not be favorable for the adaptability of the eventdev widely.
> We are only asking for one additional argument to indicate whether application has sent the current burst targeted for single FQ or it has mixed data. It can be set as 0 for the application like l2fwd, who are not doing buffering. However application like l3fwd, who do buffering, will definitely use it.
>
> Note that it is always costly for the driver to internally sort/buffer the packets from the buffer.
After going through l3fwd code, I understand, you want to reuse
segregation logic of send_packets_multi(). So, this makes sense to
me.
>
>
> >
> >
> > > > >
> > > > > One option could be to incorporate NXP internal use case will be
> > > > > introducing a new API, parallel to
> > > > > rte_event_eth_tx_adapter_enqueue as
> > > > > rte_event_eth_tx_adapter_enqueue_same_dest()
> > > > > or something.
> > > > >
> > > > > Two advantage:
> > > > > # Not a major ABI breakage. Only need to add new fast-path
> > > > > function in rte_eventdev.
> > > > > # Even though we add 'zero' in API all the time, the Compiler
> > > > > prologue needs to push to stack or move the value to argument
> > > > > register as there is function pointer indirection. so new API will
> > > > > have zero performance impact for normal cases.
> > > > >
> > > > > Not sure about minor ABI breakage in rte_eventdev(adding a new
> > > > > fastpath function). If everyone is OK as the exception for 19.11
> > > > > then we can introduce a new API.
> > > >
> > > > [Hemant] There are already too many APIs and mode in eventdev. My
> > > suggestion is to minimize the new APIs. Else writing generic
> > > applications will be really difficult and it will not be easy to adapt by the
> > application developers.
> > > > In this particular case, it is better for NXP to go with direct eth
> > > > enque mode
> > > rather than TX adapter. Note that crypto adapter already provide that
> > mode.
> > > However we are trying to adjust so that applications do not become
> > complex.
> > >
> > > Why? If you think direct queue model as use case if you might as well
> > > write "ethdev" driver and internally use atomic schedule type.
> > >
> > >
> > > > In the existing code also we have two modes in the application to
> > > > send the
> > > packets out - one is 'rte_event_enqueue_burst' and other is
> > > 'rte_event_eth_tx_adapter_enqueue'.
> > > > It is still cumbersome for the application to maintain separate
> > > > modes. This
> > > increases when crypto/timer is also being used in event mode.
> > >
> > > I think, we have two things here
> > > a) specialized API for specific work like
> > > rte_event_enqueue_new_burst() or
> > rte_event_enqueue_forward_burst() vs
> > > generic rte_event_enqueue_burst().
> > > I think, that does not NOT any harm as the application can use
> > > optimized routine if required(no separate code path case)
> > >
> > > b) different code path
> > > I agree, this is something I don't like and we would like to avoid.
> > > But this specific case, We took the comprise to avoid any performance
> > > impact for SW or HW model.
> > > It is a public discussion and it is here
> > >
> > >
> > https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> > >
> > es.dpdk.org%2Fpatch%2F40426%2F&data=02%7C01%7Chemant.agrawa
> > l%40nxp
> > >
> > .com%7Cdad3dcb7aa684656d9f508d747c8bac8%7C686ea1d3bc2b4c6fa92cd99
> > c5c30
> > >
> > 1635%7C0%7C0%7C637056799769535589&sdata=iCmksK0xZ%2BYpPaZ9
> > McG1HHuE
> > > mi1No1MaAqdsO2vIkEo%3D&reserved=0
> > >
> > > >
> > > > Why do we not used the 'rte_event->event_type' for TX as well, and
> > > 'rte_event_enqueue_burst', API to internally (in respective event
> > > driver) send the packet to the respective eth/crypto/timer Tx
> > > function? It makes more sense to have a common framework to send
> > > packets, rather than having multiple API's?
> > >
> > > If we make rte_event_enqueue_burst() to send the packet then:
> > > - HW eventdev driver + External PCI network card use case won't work
> > > as you are overriding event driver enqueue which has no clue on the
> > > external PCI network card vs integrated network controller.
> > > - Additional switch cases rte_event_enqueue_burst() in generic
> > > function aka performance impact.
> > > - There are multiple SW eventdev drivers, whose generic enqueue()
> > > function can not be changed to handle Tx adapter enqueue + add new
> > > switch case
> > > - Both SW and HW can use rte_event_eth_tx_adapter_enqueue() to send
> > > the packet to have unified fast path. i.e The callback can be attached
> > > to SW tx adapter or HW routine to send the packet.
> >
> >
> > > But I am not able to recollect, Why Nikhil would like to use the
> > > separate functions. Nikhil could you remind us why
> > > rte_event_eth_tx_adapter_enqueue() can not be used for sending the
> > > packet for SW Tx adapter.
> > >
> > [Nikhil] The goal was to keep the workers using the loop below.
> >
> > while (1) {
> > rte_event_dequeue_burst(...);
> > (event processing)
> > rte_event_enqueue_burst(...);
> > }
We do have specialized functions for specific enqueue use case like
rte_event_enqueue_new_burst() or
rte_event_enqueue_forward_burst() to avoid any performance impact.
Since PMD agruments are same for rte_event_enqueue_burst() and
rte_event_eth_tx_adapter_enqueue()
assigning simple function pointer assignment to
rte_event_eth_tx_adapter_enqueue as dev->txa_enqueue =
dev->enqueue_burst
would have worked to have same Tx function across all platfroms
without peformance overhead.
Offcouse I understand, Slow path direct event enqueue assigment needs
different treatment.
ie in fastpath.
while (1) {
rte_event_dequeue_burst(...);
if (tx_stage)
rte_event_eth_tx_adapter_enqueue()...
}
What do you say?
> >
> [Hemant] So everyone has a different way for sending the packet.
> - intel wants direct event enqueue
> - Marvel/Cavium wants adapters
> - NXP don’t' want to use event for TX path. - but we can use adapter if minor adjustments are made.
OK. Lets add the flag in Tx adapter so that NXP use case also
satsified with single code flow.
I would suggent to use const compiler optimization technique for the
flags like in rte_event_dequeue_burst() so that builtin const case it
has zero overhead.
rte_event_eth_tx_adapter_enqueue(..., const uint8_t flags)
{
if (flag)
dev->txa_enqueue_new_pmd_op(dev->data->ports[port_id], ev, nb_events, flag)
else
dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
}
}
>
> > Thanks,
> > Nikhil
> >
> > > Nothing is set and stone. We can always improve the API if required.
> > >
> > >
> > > >
> > > >
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > Regards,
> > > > > > Nipun
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > > > > > > ---
> > > > > > > > > > > > app/test-eventdev/test_pipeline_common.h | 6
> > +++---
> > > > > > > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12
> > ++++++++--
> > > --
> > > > > > > > > > > > drivers/event/octeontx2/otx2_worker.c | 8
> > ++++++--
> > > > > > > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8
> > ++++++--
> > > > > > > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > > > > > > +++++++++++++--
> > > > > > > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > > > > > > >
> > > > > > > > > > > > diff --git
> > > > > > > > > > > > a/app/test-eventdev/test_pipeline_common.h
> > > > > > > b/app/test-
> > > > > > > > > > > eventdev/test_pipeline_common.h
> > > > > > > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t
> > > > > > > > > > > > dev, const
> > > > > > > > > uint8_t
> > > > > > > > > > > port,
> > > > > > > > > > > > struct rte_event * const ev) {
> > > > > > > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev,
> > port, ev,
> > > > > 1))
> > > > > > > > > > > > + while
> > > > > > > > > > > > + (!rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > > > + port, ev, 1,
> > > > > > > 0))
> > > > > > > > > > > > rte_pause(); }
> > > > > > > > > > > >
> > > > > > > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const
> > > > > > > > > > > > uint8_t
> > > > > > > dev,
> > > > > > > > > const
> > > > > > > > > > > uint8_t port,
> > > > > > > > > > > > {
> > > > > > > > > > > > uint16_t enq;
> > > > > > > > > > > >
> > > > > > > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port,
> > ev,
> > > > > > > nb_rx);
> > > > > > > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > > > + port, ev,
> > > > > > > nb_rx,
> > > > > > > > > 0);
> > > > > > > > > > > > while (enq < nb_rx) {
> > > > > > > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev,
> > port,
> > > > > > > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > > > > > > + ev + enq, nb_rx -
> > > > > > > > > > > > + enq, 0);
> > > > > > > > > > > > }
> > > > > > > > > > > > }
> > > > > > > > > > > >
> > > > > > > > > > > > diff --git
> > > > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rs
> > > > > > > > > > > > t
> > > > > > > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > > > > > > ---
> > > > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rs
> > > > > > > > > > > > t
> > > > > > > > > > > > +++
> > b/doc/guides/prog_guide/event_ethernet_tx_adapter.
> > > > > > > > > > > > +++ rst
> > > > > > > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > > > > > > ``rte_event_enqueue_burst()``
> > > > > > > > > > > function.
> > > > > > > > > > > > if (cap &
> > > > > > > > > > > > RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > > > > > > {
> > > > > > > > > > > >
> > > > > > > > > > > > event.mbuf = m;
> > > > > > > > > > > > + eq_flags = 0;
> > > > > > > > > > > >
> > > > > > > > > > > > m->port = tx_port;
> > > > > > > > > > > > rte_event_eth_tx_adapter_txq_set(m,
> > > > > > > > > > > > tx_queue_id);
> > > > > > > > > > > >
> > > > > > > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id,
> > ev_port,
> > > > > > > &event,
> > > > > > > > > 1);
> > > > > > > > > > > > +
> > > > > > > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id,
> > > > > > > > > > > > + ev_port,
> > > > > > > > > &event, 1,
> > > > > > > > > > > eq_flags);
> > > > > > > > > > > > } else {
> > > > > > > > > > > >
> > > > > > > > > > > > event.queue_id = qid; /* event queue
> > > > > > > > > > > > linked to adapter
> > > > > > > port */
> > > > > > > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct
> > > > > > > > > > > > ssows *ws,
> > > > > > > > > uint8_t
> > > > > > > > > > > queue_id,
> > > > > > > > > > > > ssows_handle_event_t fn, void *arg);
> > > > > > > > > > > > void ssows_reset(struct ssows *ws); uint16_t
> > > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > > + nb_events, uint8_t
> > > > > > > eq_flags);
> > > > > > > > > > > > int ssovf_info(struct ssovf_info *info); void
> > > > > > > > > > > > *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t
> > > > > > > > > > > > bar); int test_eventdev_octeontx(void); diff --git
> > > > > > > > > > > > a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > > > > > > >
> > > > > > > > > > > > uint16_t
> > > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > > + nb_events, uint8_t eq_flags)
> > > > > > > > > > > > {
> > > > > > > > > > > > uint16_t port_id;
> > > > > > > > > > > > uint16_t queue_id; @@ -275,6 +275,7 @@
> > > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > > octeontx_dq_t *dq;
> > > > > > > > > > > >
> > > > > > > > > > > > RTE_SET_USED(nb_events);
> > > > > > > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > > > > > > switch (ev->sched_type) {
> > > > > > > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > > > > > > ssows_swtag_norm(ws, ev->event,
> > > > > > > > > > > > SSO_SYNC_ATOMIC); diff --git
> > > > > > > > > > > > a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > > @@ -333,16 +333,20 @@
> > > > > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > >
> > > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void
> > > > > > > > > > > > *port, struct
> > > > > > > > > rte_event
> > > > > > > > > > > ev[],\
> > > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > > > *port,
> > > > > > > > > \
> > > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > > > > > > > > > name(void *port,
> > > > > > > > > \
> > > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > > > > > > > > > > > name(void
> > > > > > > *port,
> > > > > > > > > > > \
> > > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > >
> > > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC #undef T diff --
> > git
> > > > > > > > > > > > a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > > @@ -270,12 +270,14 @@
> > otx2_ssogws_enq_fwd_burst(void
> > > > > > > > > > > > *port,
> > > > > > > > > const
> > > > > > > > > > > struct rte_event ev[],
> > > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port,
> > > > > > > > > > > > struct rte_event
> > > > > > > > > ev[], \
> > > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > > { \
> > > > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > > > \
> > > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd,
> > > > > > > > > > > > flags);
> > > \
> > > > > > > > > > > > }
> > > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -284,12
> > +286,14
> > > > > @@
> > > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > > > > > > > > > > > struct
> > > > > > > > > rte_event ev[],\
> > > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > > { \
> > > > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > > > 2];
> > > > > \
> > > > > > > > > > > > \
> > > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd,
> > > > > > > > > > > > (flags) |
> > > \
> > > > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > > > }
> > > > > > > > > > > > diff --git
> > > > > > > > > > > > a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > > @@ -310,7 +310,8 @@
> > > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > > > > \
> > > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > > { \
> > > > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_
> > > > > > > > > > > > ##
> > > > > > > > > name(void *port,
> > > > > > > > > > > \
> > > > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > > > \
> > > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd,
> > > > > > > > > > > > flags);
> > > \
> > > > > > > > > > > > }
> > > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -327,7 +329,8
> > > @@
> > > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > > > *port,
> > > > > > > \
> > > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > > { \
> > > > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > > > @@ -335,6 +338,7 @@
> > > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_
> > > > > ##
> > > > > > > > > name(void
> > > > > > > > > > > *port, \
> > > > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > > > 2];
> > > > > \
> > > > > > > > > > > > \
> > > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd,
> > > > > > > > > > > > (flags) |
> > > \
> > > > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > > > }
> > > > > > > > > > > > diff --git
> > > > > > > > > > > > a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > > index c848261c4..98be77568 100644
> > > > > > > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > > @@ -300,6 +300,11 @@
> > > > > > > > > > > > rte_event_eth_tx_adapter_txq_get(struct
> > > > > > > > > rte_mbuf
> > > > > > > > > > > *pkt)
> > > > > > > > > > > > int
> > > > > > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id,
> > > > > > > > > > > > uint8_t
> > > > > > > > > > > *event_port_id);
> > > > > > > > > > > >
> > > > > > > > > > > > +#define
> > > RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > > > 0x1
> > > > > > > > > > > > +/**< This flag is used when all the packets
> > > > > > > > > > > > +enqueued in the tx
> > > > > > > adapter
> > > > > > > > > are
> > > > > > > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > > > > > > + */
> > > > > > > > > > > > +
> > > > > > > > > > > > /**
> > > > > > > > > > > > * Enqueue a burst of events objects or an event
> > > > > > > > > > > > object supplied in
> > > > > > > > > > > *rte_event*
> > > > > > > > > > > > * structure on an event device designated by its
> > > > > > > > > > > > *dev_id* through
> > > > > > > > > the event
> > > > > > > > > > > > @@ -324,6 +329,10 @@
> > > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > > > > > > id, uint8_t *event_port_id);
> > > > > > > > > > > > * The number of event objects to enqueue,
> > > > > > > > > > > > typically number
> > > of
> > > > > > > > > > > > *
> > > > > > >
> > rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > > > > > > * available for this port.
> > > > > > > > > > > > + * @param flags
> > > > > > > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > > > > > > + *
> > #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > > > signifies
> > > > > > > > > that all
> > > > > > > > > > > the packets
> > > > > > > > > > > > + * which are enqueued are destined for the same
> > > > > > > > > > > > + Ethernet device,
> > > > > > > > > queue pair.
> > > > > > > > > > > > *
> > > > > > > > > > > > * @return
> > > > > > > > > > > > * The number of event objects actually enqueued on the
> > > event
> > > > > > > > > device. The
> > > > > > > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > > > > > > uint8_t port_id,
> > > > > > > > > > > > struct rte_event ev[],
> > > > > > > > > > > > - uint16_t nb_events)
> > > > > > > > > > > > + uint16_t nb_events,
> > > > > > > > > > > > + uint8_t flags)
> > > > > > > > > > > > {
> > > > > > > > > > > > const struct rte_eventdev *dev =
> > > > > > > > > > > > &rte_eventdevs[dev_id];
> > > > > > > > > > > >
> > > > > > > > > > > > @@ -359,7 +369,8 @@
> > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > > > > > > dev_id,
> > > > > > > > > > > > return 0;
> > > > > > > > > > > > }
> > > > > > > > > > > > #endif
> > > > > > > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id],
> > ev,
> > > > > > > > > nb_events);
> > > > > > > > > > > > + return dev->txa_enqueue(dev->data-
> > >ports[port_id], ev,
> > > > > > > > > > > > + nb_events, flags);
> > > > > > > > > > > > }
> > > > > > > > > > > >
> > > > > > > > > > > > /**
> > > > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > > @@ -1324,7 +1324,8 @@
> > > > > > > rte_eventdev_find_free_device_index(void)
> > > > > > > > > > > > static uint16_t
> > > > > > > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void
> > *port,
> > > > > > > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > > > > > > + __rte_unused uint8_t flags)
> > > > > > > > > > > > {
> > > > > > > > > > > > rte_errno = ENOTSUP;
> > > > > > > > > > > > return 0;
> > > > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > > > > > > (*event_dequeue_burst_t)(void
> > > > > > > > > > > *port, struct rte_event ev[],
> > > > > > > > > > > > /**< @internal Dequeue burst of events from port of
> > > > > > > > > > > > a device */
> > > > > > > > > > > >
> > > > > > > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void
> > *port,
> > > > > > > > > > > > - struct rte_event ev[], uint16_t
> > nb_events);
> > > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > > + nb_events, uint8_t flags);
> > > > > > > > > > > > /**< @internal Enqueue burst of events on port of a
> > > > > > > > > > > > device */
> > > > > > > > > > > >
> > > > > > > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > > > > > > --
> > > > > > > > > > > > 2.17.1
> > > > > > > > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-03 6:12 0% ` Rao, Nikhil
@ 2019-10-03 6:45 0% ` Hemant Agrawal
2019-10-03 10:26 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2019-10-03 6:45 UTC (permalink / raw)
To: Rao, Nikhil, Jerin Jacob
Cc: Nipun Gupta, Jerin Jacob, dpdk-dev, Pavan Nikhilesh,
Sunil Kumar Kori, Richardson, Bruce, Kovacevic, Marko, Ori Kam,
Nicolau, Radu, Kantecki, Tomasz, Van Haaren, Harry
Hi Nikhil,
> -----Original Message-----
> From: Rao, Nikhil <nikhil.rao@intel.com>
> Sent: Thursday, October 3, 2019 11:43 AM
> >
> > On Wed, Oct 2, 2019 at 8:38 AM Hemant Agrawal
> <hemant.agrawal@nxp.com>
> > wrote:
> > >
> > > Hi Jerin,
> >
> > Hi Hemant,
> >
> >
> > > > > I understand your concern that this shall not be valid on a general
> cases.
> > > > >
> > > > > There are certain use-case (NXP internal) of DPDK event which
> > > > > have separate event ports/cores dedicated for certain tasks -
> > > > > and can use the burst functionality for performance according to
> > > > > the event ports which are used. Not having this at runtime will
> > > > > limit the flexibility for such
> > > > applications.
> > > >
> > > > If it is specific to NXP internal use case then no more comments
> > > > on dynamic vs static.
> > > >
> > > > @ Nikhil Rao any comments.
> Hi Jerin, Hemant,
>
> Looks like we are trying to give a generic wrapper for the NXP internal use
> case, do we really need to solve that problem ?
[Hemant] no, that is not the case.
On the argument sake, eth TX adapter is also Marvel/Cavium specific - the idea was to reach consensus and come with generic APIs. NXP does not need ethTX adapter.
However, here, we are trying to avoid too many code paths for the applications, so that it becomes easy for the application writer.
- We do support RX burst, so TX burst should be supported. I remember Marvel do not support RX burst, but we added it as NXP HW support it. Intel SW can also support it.
- See existing L3 fwd application, how the burst accumulation is being done on per queue basis.
- Why the application is not sending all the packets and letting driver do the buffering on per queue basis?
- The reason is that applications knows which packets can be buffered, which need to be sent immediately. Only application can control the time out and different setting for burst mode. The burst segregation logic can not be pushed into the driver for all these various reasons.
I am not in favor of new APIs and more code paths for the applications. It will not be favorable for the adaptability of the eventdev widely.
We are only asking for one additional argument to indicate whether application has sent the current burst targeted for single FQ or it has mixed data. It can be set as 0 for the application like l2fwd, who are not doing buffering. However application like l3fwd, who do buffering, will definitely use it.
Note that it is always costly for the driver to internally sort/buffer the packets from the buffer.
>
>
> > > >
> > > > One option could be to incorporate NXP internal use case will be
> > > > introducing a new API, parallel to
> > > > rte_event_eth_tx_adapter_enqueue as
> > > > rte_event_eth_tx_adapter_enqueue_same_dest()
> > > > or something.
> > > >
> > > > Two advantage:
> > > > # Not a major ABI breakage. Only need to add new fast-path
> > > > function in rte_eventdev.
> > > > # Even though we add 'zero' in API all the time, the Compiler
> > > > prologue needs to push to stack or move the value to argument
> > > > register as there is function pointer indirection. so new API will
> > > > have zero performance impact for normal cases.
> > > >
> > > > Not sure about minor ABI breakage in rte_eventdev(adding a new
> > > > fastpath function). If everyone is OK as the exception for 19.11
> > > > then we can introduce a new API.
> > >
> > > [Hemant] There are already too many APIs and mode in eventdev. My
> > suggestion is to minimize the new APIs. Else writing generic
> > applications will be really difficult and it will not be easy to adapt by the
> application developers.
> > > In this particular case, it is better for NXP to go with direct eth
> > > enque mode
> > rather than TX adapter. Note that crypto adapter already provide that
> mode.
> > However we are trying to adjust so that applications do not become
> complex.
> >
> > Why? If you think direct queue model as use case if you might as well
> > write "ethdev" driver and internally use atomic schedule type.
> >
> >
> > > In the existing code also we have two modes in the application to
> > > send the
> > packets out - one is 'rte_event_enqueue_burst' and other is
> > 'rte_event_eth_tx_adapter_enqueue'.
> > > It is still cumbersome for the application to maintain separate
> > > modes. This
> > increases when crypto/timer is also being used in event mode.
> >
> > I think, we have two things here
> > a) specialized API for specific work like
> > rte_event_enqueue_new_burst() or
> rte_event_enqueue_forward_burst() vs
> > generic rte_event_enqueue_burst().
> > I think, that does not NOT any harm as the application can use
> > optimized routine if required(no separate code path case)
> >
> > b) different code path
> > I agree, this is something I don't like and we would like to avoid.
> > But this specific case, We took the comprise to avoid any performance
> > impact for SW or HW model.
> > It is a public discussion and it is here
> >
> >
> https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatch
> >
> es.dpdk.org%2Fpatch%2F40426%2F&data=02%7C01%7Chemant.agrawa
> l%40nxp
> >
> .com%7Cdad3dcb7aa684656d9f508d747c8bac8%7C686ea1d3bc2b4c6fa92cd99
> c5c30
> >
> 1635%7C0%7C0%7C637056799769535589&sdata=iCmksK0xZ%2BYpPaZ9
> McG1HHuE
> > mi1No1MaAqdsO2vIkEo%3D&reserved=0
> >
> > >
> > > Why do we not used the 'rte_event->event_type' for TX as well, and
> > 'rte_event_enqueue_burst', API to internally (in respective event
> > driver) send the packet to the respective eth/crypto/timer Tx
> > function? It makes more sense to have a common framework to send
> > packets, rather than having multiple API's?
> >
> > If we make rte_event_enqueue_burst() to send the packet then:
> > - HW eventdev driver + External PCI network card use case won't work
> > as you are overriding event driver enqueue which has no clue on the
> > external PCI network card vs integrated network controller.
> > - Additional switch cases rte_event_enqueue_burst() in generic
> > function aka performance impact.
> > - There are multiple SW eventdev drivers, whose generic enqueue()
> > function can not be changed to handle Tx adapter enqueue + add new
> > switch case
> > - Both SW and HW can use rte_event_eth_tx_adapter_enqueue() to send
> > the packet to have unified fast path. i.e The callback can be attached
> > to SW tx adapter or HW routine to send the packet.
>
>
> > But I am not able to recollect, Why Nikhil would like to use the
> > separate functions. Nikhil could you remind us why
> > rte_event_eth_tx_adapter_enqueue() can not be used for sending the
> > packet for SW Tx adapter.
> >
> [Nikhil] The goal was to keep the workers using the loop below.
>
> while (1) {
> rte_event_dequeue_burst(...);
> (event processing)
> rte_event_enqueue_burst(...);
> }
>
[Hemant] So everyone has a different way for sending the packet.
- intel wants direct event enqueue
- Marvel/Cavium wants adapters
- NXP don’t' want to use event for TX path. - but we can use adapter if minor adjustments are made.
> Thanks,
> Nikhil
>
> > Nothing is set and stone. We can always improve the API if required.
> >
> >
> > >
> > >
> > > >
> > > >
> > > >
> > > > >
> > > > > Regards,
> > > > > Nipun
> > > > >
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > > > > > ---
> > > > > > > > > > > app/test-eventdev/test_pipeline_common.h | 6
> +++---
> > > > > > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12
> ++++++++--
> > --
> > > > > > > > > > > drivers/event/octeontx2/otx2_worker.c | 8
> ++++++--
> > > > > > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8
> ++++++--
> > > > > > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > > > > > +++++++++++++--
> > > > > > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > > > > > >
> > > > > > > > > > > diff --git
> > > > > > > > > > > a/app/test-eventdev/test_pipeline_common.h
> > > > > > b/app/test-
> > > > > > > > > > eventdev/test_pipeline_common.h
> > > > > > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t
> > > > > > > > > > > dev, const
> > > > > > > > uint8_t
> > > > > > > > > > port,
> > > > > > > > > > > struct rte_event * const ev) {
> > > > > > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev,
> port, ev,
> > > > 1))
> > > > > > > > > > > + while
> > > > > > > > > > > + (!rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > > + port, ev, 1,
> > > > > > 0))
> > > > > > > > > > > rte_pause(); }
> > > > > > > > > > >
> > > > > > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const
> > > > > > > > > > > uint8_t
> > > > > > dev,
> > > > > > > > const
> > > > > > > > > > uint8_t port,
> > > > > > > > > > > {
> > > > > > > > > > > uint16_t enq;
> > > > > > > > > > >
> > > > > > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port,
> ev,
> > > > > > nb_rx);
> > > > > > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > > + port, ev,
> > > > > > nb_rx,
> > > > > > > > 0);
> > > > > > > > > > > while (enq < nb_rx) {
> > > > > > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev,
> port,
> > > > > > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > > > > > + ev + enq, nb_rx -
> > > > > > > > > > > + enq, 0);
> > > > > > > > > > > }
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > diff --git
> > > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rs
> > > > > > > > > > > t
> > > > > > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > > > > > ---
> > > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rs
> > > > > > > > > > > t
> > > > > > > > > > > +++
> b/doc/guides/prog_guide/event_ethernet_tx_adapter.
> > > > > > > > > > > +++ rst
> > > > > > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > > > > > ``rte_event_enqueue_burst()``
> > > > > > > > > > function.
> > > > > > > > > > > if (cap &
> > > > > > > > > > > RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > > > > > {
> > > > > > > > > > >
> > > > > > > > > > > event.mbuf = m;
> > > > > > > > > > > + eq_flags = 0;
> > > > > > > > > > >
> > > > > > > > > > > m->port = tx_port;
> > > > > > > > > > > rte_event_eth_tx_adapter_txq_set(m,
> > > > > > > > > > > tx_queue_id);
> > > > > > > > > > >
> > > > > > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id,
> ev_port,
> > > > > > &event,
> > > > > > > > 1);
> > > > > > > > > > > +
> > > > > > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id,
> > > > > > > > > > > + ev_port,
> > > > > > > > &event, 1,
> > > > > > > > > > eq_flags);
> > > > > > > > > > > } else {
> > > > > > > > > > >
> > > > > > > > > > > event.queue_id = qid; /* event queue
> > > > > > > > > > > linked to adapter
> > > > > > port */
> > > > > > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct
> > > > > > > > > > > ssows *ws,
> > > > > > > > uint8_t
> > > > > > > > > > queue_id,
> > > > > > > > > > > ssows_handle_event_t fn, void *arg);
> > > > > > > > > > > void ssows_reset(struct ssows *ws); uint16_t
> > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > + nb_events, uint8_t
> > > > > > eq_flags);
> > > > > > > > > > > int ssovf_info(struct ssovf_info *info); void
> > > > > > > > > > > *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t
> > > > > > > > > > > bar); int test_eventdev_octeontx(void); diff --git
> > > > > > > > > > > a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > > > > > >
> > > > > > > > > > > uint16_t
> > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > + nb_events, uint8_t eq_flags)
> > > > > > > > > > > {
> > > > > > > > > > > uint16_t port_id;
> > > > > > > > > > > uint16_t queue_id; @@ -275,6 +275,7 @@
> > > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > > octeontx_dq_t *dq;
> > > > > > > > > > >
> > > > > > > > > > > RTE_SET_USED(nb_events);
> > > > > > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > > > > > switch (ev->sched_type) {
> > > > > > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > > > > > ssows_swtag_norm(ws, ev->event,
> > > > > > > > > > > SSO_SYNC_ATOMIC); diff --git
> > > > > > > > > > > a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > > @@ -333,16 +333,20 @@
> > > > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > >
> > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void
> > > > > > > > > > > *port, struct
> > > > > > > > rte_event
> > > > > > > > > > ev[],\
> > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > > *port,
> > > > > > > > \
> > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > > > > > > > > name(void *port,
> > > > > > > > \
> > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > > > > > > > > > > name(void
> > > > > > *port,
> > > > > > > > > > \
> > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > >
> > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC #undef T diff --
> git
> > > > > > > > > > > a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > > @@ -270,12 +270,14 @@
> otx2_ssogws_enq_fwd_burst(void
> > > > > > > > > > > *port,
> > > > > > > > const
> > > > > > > > > > struct rte_event ev[],
> > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port,
> > > > > > > > > > > struct rte_event
> > > > > > > > ev[], \
> > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > { \
> > > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > > \
> > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd,
> > > > > > > > > > > flags);
> > \
> > > > > > > > > > > }
> > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -284,12
> +286,14
> > > > @@
> > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > > > > > > > > > > struct
> > > > > > > > rte_event ev[],\
> > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > { \
> > > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > > 2];
> > > > \
> > > > > > > > > > > \
> > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd,
> > > > > > > > > > > (flags) |
> > \
> > > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > > }
> > > > > > > > > > > diff --git
> > > > > > > > > > > a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > > @@ -310,7 +310,8 @@
> > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > > > \
> > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > { \
> > > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_
> > > > > > > > > > > ##
> > > > > > > > name(void *port,
> > > > > > > > > > \
> > > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > > \
> > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd,
> > > > > > > > > > > flags);
> > \
> > > > > > > > > > > }
> > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -327,7 +329,8
> > @@
> > > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > > uint16_t __hot \
> > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > > *port,
> > > > > > \
> > > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > > { \
> > > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > > @@ -335,6 +338,7 @@
> > > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_
> > > > ##
> > > > > > > > name(void
> > > > > > > > > > *port, \
> > > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > > 2];
> > > > \
> > > > > > > > > > > \
> > > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd,
> > > > > > > > > > > (flags) |
> > \
> > > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > > }
> > > > > > > > > > > diff --git
> > > > > > > > > > > a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > index c848261c4..98be77568 100644
> > > > > > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > > @@ -300,6 +300,11 @@
> > > > > > > > > > > rte_event_eth_tx_adapter_txq_get(struct
> > > > > > > > rte_mbuf
> > > > > > > > > > *pkt)
> > > > > > > > > > > int
> > > > > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id,
> > > > > > > > > > > uint8_t
> > > > > > > > > > *event_port_id);
> > > > > > > > > > >
> > > > > > > > > > > +#define
> > RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > > 0x1
> > > > > > > > > > > +/**< This flag is used when all the packets
> > > > > > > > > > > +enqueued in the tx
> > > > > > adapter
> > > > > > > > are
> > > > > > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > > > > > + */
> > > > > > > > > > > +
> > > > > > > > > > > /**
> > > > > > > > > > > * Enqueue a burst of events objects or an event
> > > > > > > > > > > object supplied in
> > > > > > > > > > *rte_event*
> > > > > > > > > > > * structure on an event device designated by its
> > > > > > > > > > > *dev_id* through
> > > > > > > > the event
> > > > > > > > > > > @@ -324,6 +329,10 @@
> > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > > > > > id, uint8_t *event_port_id);
> > > > > > > > > > > * The number of event objects to enqueue,
> > > > > > > > > > > typically number
> > of
> > > > > > > > > > > *
> > > > > >
> rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > > > > > * available for this port.
> > > > > > > > > > > + * @param flags
> > > > > > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > > > > > + *
> #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > > signifies
> > > > > > > > that all
> > > > > > > > > > the packets
> > > > > > > > > > > + * which are enqueued are destined for the same
> > > > > > > > > > > + Ethernet device,
> > > > > > > > queue pair.
> > > > > > > > > > > *
> > > > > > > > > > > * @return
> > > > > > > > > > > * The number of event objects actually enqueued on the
> > event
> > > > > > > > device. The
> > > > > > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > > > > > uint8_t port_id,
> > > > > > > > > > > struct rte_event ev[],
> > > > > > > > > > > - uint16_t nb_events)
> > > > > > > > > > > + uint16_t nb_events,
> > > > > > > > > > > + uint8_t flags)
> > > > > > > > > > > {
> > > > > > > > > > > const struct rte_eventdev *dev =
> > > > > > > > > > > &rte_eventdevs[dev_id];
> > > > > > > > > > >
> > > > > > > > > > > @@ -359,7 +369,8 @@
> > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > > > > > dev_id,
> > > > > > > > > > > return 0;
> > > > > > > > > > > }
> > > > > > > > > > > #endif
> > > > > > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id],
> ev,
> > > > > > > > nb_events);
> > > > > > > > > > > + return dev->txa_enqueue(dev->data-
> >ports[port_id], ev,
> > > > > > > > > > > + nb_events, flags);
> > > > > > > > > > > }
> > > > > > > > > > >
> > > > > > > > > > > /**
> > > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > > @@ -1324,7 +1324,8 @@
> > > > > > rte_eventdev_find_free_device_index(void)
> > > > > > > > > > > static uint16_t
> > > > > > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void
> *port,
> > > > > > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > > > > > + __rte_unused uint8_t flags)
> > > > > > > > > > > {
> > > > > > > > > > > rte_errno = ENOTSUP;
> > > > > > > > > > > return 0;
> > > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > > > > > (*event_dequeue_burst_t)(void
> > > > > > > > > > *port, struct rte_event ev[],
> > > > > > > > > > > /**< @internal Dequeue burst of events from port of
> > > > > > > > > > > a device */
> > > > > > > > > > >
> > > > > > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void
> *port,
> > > > > > > > > > > - struct rte_event ev[], uint16_t
> nb_events);
> > > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > > + nb_events, uint8_t flags);
> > > > > > > > > > > /**< @internal Enqueue burst of events on port of a
> > > > > > > > > > > device */
> > > > > > > > > > >
> > > > > > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > > > > > --
> > > > > > > > > > > 2.17.1
> > > > > > > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-02 7:54 0% ` Jerin Jacob
@ 2019-10-03 6:12 0% ` Rao, Nikhil
2019-10-03 6:45 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Rao, Nikhil @ 2019-10-03 6:12 UTC (permalink / raw)
To: Jerin Jacob, Hemant Agrawal
Cc: Nipun Gupta, Jerin Jacob, dpdk-dev, Pavan Nikhilesh,
Sunil Kumar Kori, Richardson, Bruce, Kovacevic, Marko, Ori Kam,
Nicolau, Radu, Kantecki, Tomasz, Van Haaren, Harry
> -----Original Message-----
> From: Jerin Jacob [mailto:jerinjacobk@gmail.com]
> Sent: Wednesday, October 2, 2019 1:24 PM
> To: Hemant Agrawal <hemant.agrawal@nxp.com>
> Cc: Nipun Gupta <nipun.gupta@nxp.com>; Jerin Jacob <jerinj@marvell.com>;
> dpdk-dev <dev@dpdk.org>; Pavan Nikhilesh <pbhagavatula@marvell.com>;
> Sunil Kumar Kori <skori@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Nicolau, Radu
> <radu.nicolau@intel.com>; Kantecki, Tomasz <tomasz.kantecki@intel.com>;
> Van Haaren, Harry <harry.van.haaren@intel.com>; Rao, Nikhil
> <nikhil.rao@intel.com>
> Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> packets enqueue
>
> On Wed, Oct 2, 2019 at 8:38 AM Hemant Agrawal
> <hemant.agrawal@nxp.com> wrote:
> >
> > Hi Jerin,
>
> Hi Hemant,
>
>
> > > > I understand your concern that this shall not be valid on a general cases.
> > > >
> > > > There are certain use-case (NXP internal) of DPDK event which have
> > > > separate event ports/cores dedicated for certain tasks - and can
> > > > use the burst functionality for performance according to the event
> > > > ports which are used. Not having this at runtime will limit the
> > > > flexibility for such
> > > applications.
> > >
> > > If it is specific to NXP internal use case then no more comments on
> > > dynamic vs static.
> > >
> > > @ Nikhil Rao any comments.
Hi Jerin, Hemant,
Looks like we are trying to give a generic wrapper for the NXP internal use case, do we really need to solve that problem ?
> > >
> > > One option could be to incorporate NXP internal use case will be
> > > introducing a new API, parallel to rte_event_eth_tx_adapter_enqueue
> > > as
> > > rte_event_eth_tx_adapter_enqueue_same_dest()
> > > or something.
> > >
> > > Two advantage:
> > > # Not a major ABI breakage. Only need to add new fast-path function
> > > in rte_eventdev.
> > > # Even though we add 'zero' in API all the time, the Compiler
> > > prologue needs to push to stack or move the value to argument
> > > register as there is function pointer indirection. so new API will
> > > have zero performance impact for normal cases.
> > >
> > > Not sure about minor ABI breakage in rte_eventdev(adding a new
> > > fastpath function). If everyone is OK as the exception for 19.11
> > > then we can introduce a new API.
> >
> > [Hemant] There are already too many APIs and mode in eventdev. My
> suggestion is to minimize the new APIs. Else writing generic applications will be
> really difficult and it will not be easy to adapt by the application developers.
> > In this particular case, it is better for NXP to go with direct eth enque mode
> rather than TX adapter. Note that crypto adapter already provide that mode.
> However we are trying to adjust so that applications do not become complex.
>
> Why? If you think direct queue model as use case if you might as well write
> "ethdev" driver and internally use atomic schedule type.
>
>
> > In the existing code also we have two modes in the application to send the
> packets out - one is 'rte_event_enqueue_burst' and other is
> 'rte_event_eth_tx_adapter_enqueue'.
> > It is still cumbersome for the application to maintain separate modes. This
> increases when crypto/timer is also being used in event mode.
>
> I think, we have two things here
> a) specialized API for specific work like
> rte_event_enqueue_new_burst() or rte_event_enqueue_forward_burst() vs
> generic rte_event_enqueue_burst().
> I think, that does not NOT any harm as the application can use optimized
> routine if required(no separate code path case)
>
> b) different code path
> I agree, this is something I don't like and we would like to avoid.
> But this specific case, We took the comprise to avoid any performance impact
> for SW or HW model.
> It is a public discussion and it is here
>
> http://patches.dpdk.org/patch/40426/
>
> >
> > Why do we not used the 'rte_event->event_type' for TX as well, and
> 'rte_event_enqueue_burst', API to internally (in respective event driver) send
> the packet to the respective eth/crypto/timer Tx function? It makes more sense
> to have a common framework to send packets, rather than having multiple
> API's?
>
> If we make rte_event_enqueue_burst() to send the packet then:
> - HW eventdev driver + External PCI network card use case won't work as you
> are overriding event driver enqueue which has no clue on the external PCI
> network card vs integrated network controller.
> - Additional switch cases rte_event_enqueue_burst() in generic function aka
> performance impact.
> - There are multiple SW eventdev drivers, whose generic enqueue() function
> can not be changed to handle Tx adapter enqueue + add new switch case
> - Both SW and HW can use rte_event_eth_tx_adapter_enqueue() to send the
> packet to have unified fast path. i.e The callback can be attached to SW tx
> adapter or HW routine to send the packet.
> But I am not able to recollect, Why Nikhil would like to use the separate
> functions. Nikhil could you remind us why
> rte_event_eth_tx_adapter_enqueue() can not be used for sending the packet
> for SW Tx adapter.
>
[Nikhil] The goal was to keep the workers using the loop below.
while (1) {
rte_event_dequeue_burst(...);
(event processing)
rte_event_enqueue_burst(...);
}
Thanks,
Nikhil
> Nothing is set and stone. We can always improve the API if required.
>
>
> >
> >
> > >
> > >
> > >
> > > >
> > > > Regards,
> > > > Nipun
> > > >
> > > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > >
> > > > > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > > > > ---
> > > > > > > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++--
> --
> > > > > > > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > > > > +++++++++++++--
> > > > > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > > > > >
> > > > > > > > > > diff --git a/app/test-eventdev/test_pipeline_common.h
> > > > > b/app/test-
> > > > > > > > > eventdev/test_pipeline_common.h
> > > > > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t
> > > > > > > > > > dev, const
> > > > > > > uint8_t
> > > > > > > > > port,
> > > > > > > > > > struct rte_event * const ev) {
> > > > > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > > 1))
> > > > > > > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > + port, ev, 1,
> > > > > 0))
> > > > > > > > > > rte_pause(); }
> > > > > > > > > >
> > > > > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const
> > > > > > > > > > uint8_t
> > > > > dev,
> > > > > > > const
> > > > > > > > > uint8_t port,
> > > > > > > > > > {
> > > > > > > > > > uint16_t enq;
> > > > > > > > > >
> > > > > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > > > > nb_rx);
> > > > > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > > + port, ev,
> > > > > nb_rx,
> > > > > > > 0);
> > > > > > > > > > while (enq < nb_rx) {
> > > > > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > > > > + ev + enq, nb_rx - enq,
> > > > > > > > > > + 0);
> > > > > > > > > > }
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > diff --git
> > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > > > > ---
> > > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.
> > > > > > > > > > +++ rst
> > > > > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > > > > ``rte_event_enqueue_burst()``
> > > > > > > > > function.
> > > > > > > > > > if (cap &
> > > > > > > > > > RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > > > > {
> > > > > > > > > >
> > > > > > > > > > event.mbuf = m;
> > > > > > > > > > + eq_flags = 0;
> > > > > > > > > >
> > > > > > > > > > m->port = tx_port;
> > > > > > > > > > rte_event_eth_tx_adapter_txq_set(m,
> > > > > > > > > > tx_queue_id);
> > > > > > > > > >
> > > > > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > > > > &event,
> > > > > > > 1);
> > > > > > > > > > +
> > > > > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id,
> > > > > > > > > > + ev_port,
> > > > > > > &event, 1,
> > > > > > > > > eq_flags);
> > > > > > > > > > } else {
> > > > > > > > > >
> > > > > > > > > > event.queue_id = qid; /* event queue
> > > > > > > > > > linked to adapter
> > > > > port */
> > > > > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct
> > > > > > > > > > ssows *ws,
> > > > > > > uint8_t
> > > > > > > > > queue_id,
> > > > > > > > > > ssows_handle_event_t fn, void *arg);
> > > > > > > > > > void ssows_reset(struct ssows *ws); uint16_t
> > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > + nb_events, uint8_t
> > > > > eq_flags);
> > > > > > > > > > int ssovf_info(struct ssovf_info *info); void
> > > > > > > > > > *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > > > > > > > > int test_eventdev_octeontx(void); diff --git
> > > > > > > > > > a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > > > > >
> > > > > > > > > > uint16_t
> > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > + nb_events, uint8_t eq_flags)
> > > > > > > > > > {
> > > > > > > > > > uint16_t port_id;
> > > > > > > > > > uint16_t queue_id; @@ -275,6 +275,7 @@
> > > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > > octeontx_dq_t *dq;
> > > > > > > > > >
> > > > > > > > > > RTE_SET_USED(nb_events);
> > > > > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > > > > switch (ev->sched_type) {
> > > > > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > > > > ssows_swtag_norm(ws, ev->event,
> > > > > > > > > > SSO_SYNC_ATOMIC); diff --git
> > > > > > > > > > a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > > @@ -333,16 +333,20 @@
> > > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > >
> > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void
> > > > > > > > > > *port, struct
> > > > > > > rte_event
> > > > > > > > > ev[],\
> > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > *port,
> > > > > > > \
> > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void
> > > > > > > > > > *port,
> > > > > > > \
> > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > > > > > > > > > name(void
> > > > > *port,
> > > > > > > > > \
> > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > >
> > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC #undef T diff --git
> > > > > > > > > > a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void
> > > > > > > > > > *port,
> > > > > > > const
> > > > > > > > > struct rte_event ev[],
> > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > uint16_t __hot \
> > > > > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > > > > > > > > > rte_event
> > > > > > > ev[], \
> > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > { \
> > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > \
> > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags);
> \
> > > > > > > > > > }
> > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -284,12 +286,14
> > > @@
> > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > > uint16_t __hot \
> > > > > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > > > > > > > > > struct
> > > > > > > rte_event ev[],\
> > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > { \
> > > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > 2];
> > > \
> > > > > > > > > > \
> > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) |
> \
> > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > }
> > > > > > > > > > diff --git
> > > > > > > > > > a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > > @@ -310,7 +310,8 @@
> SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > uint16_t __hot \
> > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > > \
> > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > { \
> > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > > > > name(void *port,
> > > > > > > > > \
> > > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > > \
> > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags);
> \
> > > > > > > > > > }
> > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -327,7 +329,8
> @@
> > > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > > uint16_t __hot \
> > > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > > *port,
> > > > > \
> > > > > > > > > > struct rte_event ev[], \
> > > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > > { \
> > > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_
> > > ##
> > > > > > > name(void
> > > > > > > > > *port, \
> > > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS -
> > > > > > > > > > 2];
> > > \
> > > > > > > > > > \
> > > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) |
> \
> > > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > > }
> > > > > > > > > > diff --git
> > > > > > > > > > a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > index c848261c4..98be77568 100644
> > > > > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > > @@ -300,6 +300,11 @@
> > > > > > > > > > rte_event_eth_tx_adapter_txq_get(struct
> > > > > > > rte_mbuf
> > > > > > > > > *pkt)
> > > > > > > > > > int
> > > > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id,
> > > > > > > > > > uint8_t
> > > > > > > > > *event_port_id);
> > > > > > > > > >
> > > > > > > > > > +#define
> RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > 0x1
> > > > > > > > > > +/**< This flag is used when all the packets enqueued
> > > > > > > > > > +in the tx
> > > > > adapter
> > > > > > > are
> > > > > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > > > > + */
> > > > > > > > > > +
> > > > > > > > > > /**
> > > > > > > > > > * Enqueue a burst of events objects or an event
> > > > > > > > > > object supplied in
> > > > > > > > > *rte_event*
> > > > > > > > > > * structure on an event device designated by its
> > > > > > > > > > *dev_id* through
> > > > > > > the event
> > > > > > > > > > @@ -324,6 +329,10 @@
> > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > > > > id, uint8_t *event_port_id);
> > > > > > > > > > * The number of event objects to enqueue, typically number
> of
> > > > > > > > > > *
> > > > > rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > > > > * available for this port.
> > > > > > > > > > + * @param flags
> > > > > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > > signifies
> > > > > > > that all
> > > > > > > > > the packets
> > > > > > > > > > + * which are enqueued are destined for the same
> > > > > > > > > > + Ethernet device,
> > > > > > > queue pair.
> > > > > > > > > > *
> > > > > > > > > > * @return
> > > > > > > > > > * The number of event objects actually enqueued on the
> event
> > > > > > > device. The
> > > > > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > > > > uint8_t port_id,
> > > > > > > > > > struct rte_event ev[],
> > > > > > > > > > - uint16_t nb_events)
> > > > > > > > > > + uint16_t nb_events,
> > > > > > > > > > + uint8_t flags)
> > > > > > > > > > {
> > > > > > > > > > const struct rte_eventdev *dev =
> > > > > > > > > > &rte_eventdevs[dev_id];
> > > > > > > > > >
> > > > > > > > > > @@ -359,7 +369,8 @@
> > > > > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > > > > dev_id,
> > > > > > > > > > return 0;
> > > > > > > > > > }
> > > > > > > > > > #endif
> > > > > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > > nb_events);
> > > > > > > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > > > > > + nb_events, flags);
> > > > > > > > > > }
> > > > > > > > > >
> > > > > > > > > > /**
> > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > > @@ -1324,7 +1324,8 @@
> > > > > rte_eventdev_find_free_device_index(void)
> > > > > > > > > > static uint16_t
> > > > > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > > > > + __rte_unused uint8_t flags)
> > > > > > > > > > {
> > > > > > > > > > rte_errno = ENOTSUP;
> > > > > > > > > > return 0;
> > > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > > > > (*event_dequeue_burst_t)(void
> > > > > > > > > *port, struct rte_event ev[],
> > > > > > > > > > /**< @internal Dequeue burst of events from port of a
> > > > > > > > > > device */
> > > > > > > > > >
> > > > > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > > + struct rte_event ev[], uint16_t
> > > > > > > > > > + nb_events, uint8_t flags);
> > > > > > > > > > /**< @internal Enqueue burst of events on port of a
> > > > > > > > > > device */
> > > > > > > > > >
> > > > > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > > > > --
> > > > > > > > > > 2.17.1
> > > > > > > > > >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v8] eal: make lcore_config private
2019-10-02 8:15 0% ` David Marchand
@ 2019-10-02 19:40 13% ` Stephen Hemminger
2019-10-22 9:05 3% ` David Marchand
1 sibling, 1 reply; 200+ results
From: Stephen Hemminger @ 2019-10-02 19:40 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
The internal structure of lcore_config is no longer be part of
visible API/ABI. Make it private to EAL.
Rearrange and resize the fields in the structure so it takes
less memory (and cache footprint).
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
v8 - update release notes
rearrange to move cpuset to second cache line
doc/guides/rel_notes/deprecation.rst | 4 ----
doc/guides/rel_notes/release_19_11.rst | 2 ++
lib/librte_eal/common/eal_common_launch.c | 2 ++
lib/librte_eal/common/eal_private.h | 24 +++++++++++++++++++++++
lib/librte_eal/common/include/rte_lcore.h | 24 -----------------------
lib/librte_eal/common/rte_service.c | 2 ++
lib/librte_eal/rte_eal_version.map | 1 -
lib/librte_eal/windows/eal/eal_thread.c | 1 +
8 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 0ee8533b133c..89811a622591 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -23,10 +23,6 @@ Deprecation Notices
* eal: The function ``rte_eal_remote_launch`` will return new error codes
after read or write error on the pipe, instead of calling ``rte_panic``.
-* eal: The ``lcore_config`` struct and global symbol will be made private to
- remove it from the externally visible ABI and allow it to be updated in the
- future.
-
* eal: both declaring and identifying devices will be streamlined in v18.11.
New functions will appear to query a specific port from buses, classes of
device and device drivers. Device declaration will be made coherent with the
diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e38c6..e8d4f9d2ba28 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -110,6 +110,8 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* eal: The ``lcore_config`` struct and global symbol are now private.
+
Shared Library Versions
-----------------------
diff --git a/lib/librte_eal/common/eal_common_launch.c b/lib/librte_eal/common/eal_common_launch.c
index fe0ba3f0d617..cf52d717f68e 100644
--- a/lib/librte_eal/common/eal_common_launch.c
+++ b/lib/librte_eal/common/eal_common_launch.c
@@ -15,6 +15,8 @@
#include <rte_per_lcore.h>
#include <rte_lcore.h>
+#include "eal_private.h"
+
/*
* Wait until a lcore finished its job.
*/
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 798ede553b21..e63eaa5d262d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -10,6 +10,30 @@
#include <stdio.h>
#include <rte_dev.h>
+#include <rte_lcore.h>
+
+/**
+ * Structure storing internal configuration (per-lcore)
+ */
+struct lcore_config {
+ pthread_t thread_id; /**< pthread identifier */
+ int pipe_master2slave[2]; /**< communication pipe with master */
+ int pipe_slave2master[2]; /**< communication pipe with master */
+
+ lcore_function_t * volatile f; /**< function to call */
+ void * volatile arg; /**< argument of function */
+ volatile int ret; /**< return value of function */
+
+ uint32_t core_id; /**< core number on socket for this lcore */
+ uint32_t core_index; /**< relative index, starting from 0 */
+ uint16_t socket_id; /**< physical socket id for this lcore */
+ uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
+ uint8_t detected; /**< true if lcore was detected */
+ volatile enum rte_lcore_state_t state; /**< lcore state */
+ rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
+};
+
+extern struct lcore_config lcore_config[RTE_MAX_LCORE];
/**
* Initialize the memzone subsystem (private to eal).
diff --git a/lib/librte_eal/common/include/rte_lcore.h b/lib/librte_eal/common/include/rte_lcore.h
index c86f72eb12a8..0c683919564e 100644
--- a/lib/librte_eal/common/include/rte_lcore.h
+++ b/lib/librte_eal/common/include/rte_lcore.h
@@ -66,30 +66,6 @@ typedef cpuset_t rte_cpuset_t;
} while (0)
#endif
-/**
- * Structure storing internal configuration (per-lcore)
- */
-struct lcore_config {
- unsigned detected; /**< true if lcore was detected */
- pthread_t thread_id; /**< pthread identifier */
- int pipe_master2slave[2]; /**< communication pipe with master */
- int pipe_slave2master[2]; /**< communication pipe with master */
- lcore_function_t * volatile f; /**< function to call */
- void * volatile arg; /**< argument of function */
- volatile int ret; /**< return value of function */
- volatile enum rte_lcore_state_t state; /**< lcore state */
- unsigned socket_id; /**< physical socket id for this lcore */
- unsigned core_id; /**< core number on socket for this lcore */
- int core_index; /**< relative index, starting from 0 */
- rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
- uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
-};
-
-/**
- * Internal configuration (per-lcore)
- */
-extern struct lcore_config lcore_config[RTE_MAX_LCORE];
-
RTE_DECLARE_PER_LCORE(unsigned, _lcore_id); /**< Per thread "lcore id". */
RTE_DECLARE_PER_LCORE(rte_cpuset_t, _cpuset); /**< Per thread "cpuset". */
diff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c
index c3653ebae46c..6e21f549051b 100644
--- a/lib/librte_eal/common/rte_service.c
+++ b/lib/librte_eal/common/rte_service.c
@@ -21,6 +21,8 @@
#include <rte_memory.h>
#include <rte_malloc.h>
+#include "eal_private.h"
+
#define RTE_SERVICE_NUM_MAX 64
#define SERVICE_F_REGISTERED (1 << 0)
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 7cbf82d37b0a..aeedf397764f 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -4,7 +4,6 @@ DPDK_2.0 {
__rte_panic;
eal_parse_sysfs_value;
eal_timer_source;
- lcore_config;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
diff --git a/lib/librte_eal/windows/eal/eal_thread.c b/lib/librte_eal/windows/eal/eal_thread.c
index 906502f90982..0591d4c7fb06 100644
--- a/lib/librte_eal/windows/eal/eal_thread.c
+++ b/lib/librte_eal/windows/eal/eal_thread.c
@@ -12,6 +12,7 @@
#include <rte_common.h>
#include <eal_thread.h>
+#include "eal_private.h"
RTE_DEFINE_PER_LCORE(unsigned int, _lcore_id) = LCORE_ID_ANY;
--
2.20.1
^ permalink raw reply [relevance 13%]
* Re: [dpdk-dev] [RFC] ethdev: add new fields for max LRO session size
@ 2019-10-02 13:58 3% ` Thomas Monjalon
2019-10-18 16:35 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2019-10-02 13:58 UTC (permalink / raw)
To: Matan Azrad
Cc: Ferruh Yigit, dev, Andrew Rybchenko, Konstantin Ananyev, Olivier Matz
24/09/2019 14:03, Matan Azrad:
> From: Ferruh Yigit
> > On 9/15/2019 8:48 AM, Matan Azrad wrote:
> > > Hi Ferruh
> > >
> > > From: Ferruh Yigit <ferruh.yigit@intel.com>
> > >> On 8/29/2019 8:47 AM, Matan Azrad wrote:
> > >>> It may be needed by the user to limit the LRO session packet size.
> > >>> In order to allow the above limitation, add new Rx configuration for
> > >>> the maximum LRO session size.
> > >>>
> > >>> In addition, Add a new capability to expose the maximum LRO session
> > >>> size supported by the port.
> > >>>
> > >>> Signed-off-by: Matan Azrad <matan@mellanox.com>
> > >>
> > >> Hi Matan,
> > >>
> > >> Is there any existing user of this new field?
> > >
> > > All the LRO users need it due to the next reasons:
> > >
> > > 1. If scatter is enabled - The dpdk user can limit the LRO session size created
> > by the HW by this field, if no field like that - there is no way to limit it.
> > > 2. No scatter - the dpdk user may want to limit the LRO packet size in order
> > to save enough tail-room in the mbuf for its own usage.
> > > 3. The limitation of max_rx_pkt_len is not enough - doesn't make sense to
> > limit LRO traffic as single packet.
> > >
> >
> > So should there be more complement patches to this RFC? To update the
> > users of the field with the new field.
>
>
> We already exposed it as ABI breakage in the last deprecation notice.
> We probably cannot complete it for 19.11 version, hopefully for 20.02 it will be completed.
We won't break the ABI in 20.02.
What should be done in 19.11?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7] eal: make lcore_config private
@ 2019-10-02 8:15 0% ` David Marchand
2019-10-02 19:40 13% ` [dpdk-dev] [PATCH v8] " Stephen Hemminger
1 sibling, 0 replies; 200+ results
From: David Marchand @ 2019-10-02 8:15 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Thanks for working on this.
On Wed, Sep 25, 2019 at 6:10 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> The internal structure of lcore_config is no longer be part of
> visible API/ABI. Make it private to EAL.
>
> Rearrange and resize the fields in the structure so it takes
> less memory (and cache footprint).
This patch is missing the release notes update.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> v7 - add eal_private.h to windows
>
> lib/librte_eal/common/eal_common_launch.c | 2 ++
> lib/librte_eal/common/eal_private.h | 22 +++++++++++++++++++++
> lib/librte_eal/common/include/rte_lcore.h | 24 -----------------------
> lib/librte_eal/common/rte_service.c | 2 ++
> lib/librte_eal/rte_eal_version.map | 1 -
> lib/librte_eal/windows/eal/eal_thread.c | 1 +
> 6 files changed, 27 insertions(+), 25 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_common_launch.c b/lib/librte_eal/common/eal_common_launch.c
> index fe0ba3f0d617..cf52d717f68e 100644
> --- a/lib/librte_eal/common/eal_common_launch.c
> +++ b/lib/librte_eal/common/eal_common_launch.c
> @@ -15,6 +15,8 @@
> #include <rte_per_lcore.h>
> #include <rte_lcore.h>
>
> +#include "eal_private.h"
> +
> /*
> * Wait until a lcore finished its job.
> */
> diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
> index 798ede553b21..25e80547904f 100644
> --- a/lib/librte_eal/common/eal_private.h
> +++ b/lib/librte_eal/common/eal_private.h
> @@ -10,6 +10,28 @@
> #include <stdio.h>
>
> #include <rte_dev.h>
> +#include <rte_lcore.h>
> +
> +/**
> + * Structure storing internal configuration (per-lcore)
> + */
> +struct lcore_config {
> + uint32_t core_id; /**< core number on socket for this lcore */
> + uint32_t core_index; /**< relative index, starting from 0 */
> + uint16_t socket_id; /**< physical socket id for this lcore */
> + uint8_t core_role; /**< role of core eg: OFF, RTE, SERVICE */
> + uint8_t detected; /**< true if lcore was detected */
> + volatile enum rte_lcore_state_t state; /**< lcore state */
> + rte_cpuset_t cpuset; /**< cpu set which the lcore affinity to */
> + pthread_t thread_id; /**< pthread identifier */
> + int pipe_master2slave[2]; /**< communication pipe with master */
> + int pipe_slave2master[2]; /**< communication pipe with master */
> + lcore_function_t * volatile f; /**< function to call */
> + void * volatile arg; /**< argument of function */
> + volatile int ret; /**< return value of function */
> +};
> +
> +extern struct lcore_config lcore_config[RTE_MAX_LCORE];
Everything but cpuset can fit in a cache line.
You could just move the cpuset field at the end of the structure and
change detected to uint8_t.
This gives the following layout:
struct lcore_config {
pthread_t thread_id; /* 0 8 */
int pipe_master2slave[2]; /* 8 8 */
int pipe_slave2master[2]; /* 16 8 */
volatile lcore_function_t * f; /* 24 8 */
volatile void * arg; /* 32 8 */
volatile int ret; /* 40 4 */
volatile enum rte_lcore_state_t state; /* 44 4 */
unsigned int socket_id; /* 48 4 */
unsigned int core_id; /* 52 4 */
int core_index; /* 56 4 */
uint8_t detected; /* 60 1 */
uint8_t core_role; /* 61 1 */
/* XXX 2 bytes hole, try to pack */
/* --- cacheline 1 boundary (64 bytes) --- */
rte_cpuset_t cpuset; /* 64 128 */
/* --- cacheline 3 boundary (192 bytes) --- */
/* size: 192, cachelines: 3, members: 13 */
/* sum members: 190, holes: 1, sum holes: 2 */
};
The resulting structure is only two bytes bigger than your proposal
and does not touch existing integer types (avoiding the risk of some
integer conversion on socket_id for example).
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-02 3:08 0% ` Hemant Agrawal
@ 2019-10-02 7:54 0% ` Jerin Jacob
2019-10-03 6:12 0% ` Rao, Nikhil
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-02 7:54 UTC (permalink / raw)
To: Hemant Agrawal
Cc: Nipun Gupta, Jerin Jacob, dpdk-dev, Pavan Nikhilesh,
Sunil Kumar Kori, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
On Wed, Oct 2, 2019 at 8:38 AM Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
> Hi Jerin,
Hi Hemant,
> > > I understand your concern that this shall not be valid on a general cases.
> > >
> > > There are certain use-case (NXP internal) of DPDK event which have
> > > separate event ports/cores dedicated for certain tasks - and can use
> > > the burst functionality for performance according to the event ports
> > > which are used. Not having this at runtime will limit the flexibility for such
> > applications.
> >
> > If it is specific to NXP internal use case then no more comments on dynamic
> > vs static.
> >
> > @ Nikhil Rao any comments.
> >
> > One option could be to incorporate NXP internal use case will be introducing
> > a new API, parallel to rte_event_eth_tx_adapter_enqueue as
> > rte_event_eth_tx_adapter_enqueue_same_dest()
> > or something.
> >
> > Two advantage:
> > # Not a major ABI breakage. Only need to add new fast-path function in
> > rte_eventdev.
> > # Even though we add 'zero' in API all the time, the Compiler prologue needs
> > to push to stack or move the value to argument register as there is function
> > pointer indirection. so new API will have zero performance impact for normal
> > cases.
> >
> > Not sure about minor ABI breakage in rte_eventdev(adding a new fastpath
> > function). If everyone is OK as the exception for 19.11 then we can introduce
> > a new API.
>
> [Hemant] There are already too many APIs and mode in eventdev. My suggestion is to minimize the new APIs. Else writing generic applications will be really difficult and it will not be easy to adapt by the application developers.
> In this particular case, it is better for NXP to go with direct eth enque mode rather than TX adapter. Note that crypto adapter already provide that mode. However we are trying to adjust so that applications do not become complex.
Why? If you think direct queue model as use case if you might as well
write "ethdev" driver and internally use atomic schedule type.
> In the existing code also we have two modes in the application to send the packets out - one is 'rte_event_enqueue_burst' and other is 'rte_event_eth_tx_adapter_enqueue'.
> It is still cumbersome for the application to maintain separate modes. This increases when crypto/timer is also being used in event mode.
I think, we have two things here
a) specialized API for specific work like
rte_event_enqueue_new_burst() or rte_event_enqueue_forward_burst() vs
generic rte_event_enqueue_burst().
I think, that does not NOT any harm as the application can use
optimized routine if required(no separate code path case)
b) different code path
I agree, this is something I don't like and we would like to avoid.
But this specific case, We took the comprise to avoid any performance
impact for SW or HW model.
It is a public discussion and it is here
http://patches.dpdk.org/patch/40426/
>
> Why do we not used the 'rte_event->event_type' for TX as well, and 'rte_event_enqueue_burst', API to internally (in respective event driver) send the packet to the respective eth/crypto/timer Tx function? It makes more sense to have a common framework to send packets, rather than having multiple API's?
If we make rte_event_enqueue_burst() to send the packet then:
- HW eventdev driver + External PCI network card use case won't work
as you are overriding event driver enqueue which has no clue on the
external PCI network card vs integrated network controller.
- Additional switch cases rte_event_enqueue_burst() in generic
function aka performance impact.
- There are multiple SW eventdev drivers, whose generic enqueue()
function can not be changed to handle Tx adapter enqueue + add new
switch case
- Both SW and HW can use rte_event_eth_tx_adapter_enqueue() to send
the packet to have unified fast path. i.e The callback can be attached
to SW tx adapter or HW routine to send the packet.
But I am not able to recollect, Why Nikhil would like to use the
separate functions. Nikhil could you remind us why
rte_event_eth_tx_adapter_enqueue() can not be used for sending the
packet for SW Tx adapter.
Nothing is set and stone. We can always improve the API if required.
>
>
> >
> >
> >
> > >
> > > Regards,
> > > Nipun
> > >
> > > >
> > > >
> > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > >
> > > > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > > > ---
> > > > > > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > > > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > > > +++++++++++++--
> > > > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > > > >
> > > > > > > > > diff --git a/app/test-eventdev/test_pipeline_common.h
> > > > b/app/test-
> > > > > > > > eventdev/test_pipeline_common.h
> > > > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev,
> > > > > > > > > const
> > > > > > uint8_t
> > > > > > > > port,
> > > > > > > > > struct rte_event * const ev) {
> > > > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > 1))
> > > > > > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > > + port, ev, 1,
> > > > 0))
> > > > > > > > > rte_pause(); }
> > > > > > > > >
> > > > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const
> > > > > > > > > uint8_t
> > > > dev,
> > > > > > const
> > > > > > > > uint8_t port,
> > > > > > > > > {
> > > > > > > > > uint16_t enq;
> > > > > > > > >
> > > > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > > > nb_rx);
> > > > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > > > + ev,
> > > > nb_rx,
> > > > > > 0);
> > > > > > > > > while (enq < nb_rx) {
> > > > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > > > + ev + enq, nb_rx - enq, 0);
> > > > > > > > > }
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > diff --git
> > > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > > > ``rte_event_enqueue_burst()``
> > > > > > > > function.
> > > > > > > > > if (cap &
> > > > > > > > > RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > > > {
> > > > > > > > >
> > > > > > > > > event.mbuf = m;
> > > > > > > > > + eq_flags = 0;
> > > > > > > > >
> > > > > > > > > m->port = tx_port;
> > > > > > > > > rte_event_eth_tx_adapter_txq_set(m,
> > > > > > > > > tx_queue_id);
> > > > > > > > >
> > > > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > > > &event,
> > > > > > 1);
> > > > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id,
> > > > > > > > > + ev_port,
> > > > > > &event, 1,
> > > > > > > > eq_flags);
> > > > > > > > > } else {
> > > > > > > > >
> > > > > > > > > event.queue_id = qid; /* event queue
> > > > > > > > > linked to adapter
> > > > port */
> > > > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows
> > > > > > > > > *ws,
> > > > > > uint8_t
> > > > > > > > queue_id,
> > > > > > > > > ssows_handle_event_t fn, void *arg); void
> > > > > > > > > ssows_reset(struct ssows *ws); uint16_t
> > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > > + uint8_t
> > > > eq_flags);
> > > > > > > > > int ssovf_info(struct ssovf_info *info); void
> > > > > > > > > *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar); int
> > > > > > > > > test_eventdev_octeontx(void); diff --git
> > > > > > > > > a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > > > >
> > > > > > > > > uint16_t
> > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > > + uint8_t eq_flags)
> > > > > > > > > {
> > > > > > > > > uint16_t port_id;
> > > > > > > > > uint16_t queue_id; @@ -275,6 +275,7 @@
> > > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > > octeontx_dq_t *dq;
> > > > > > > > >
> > > > > > > > > RTE_SET_USED(nb_events);
> > > > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > > > switch (ev->sched_type) {
> > > > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > > > ssows_swtag_norm(ws, ev->event,
> > > > > > > > > SSO_SYNC_ATOMIC); diff --git
> > > > > > > > > a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > > @@ -333,16 +333,20 @@
> > SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > >
> > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port,
> > > > > > > > > struct
> > > > > > rte_event
> > > > > > > > ev[],\
> > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void
> > > > > > > > > *port,
> > > > > > \
> > > > > > > > > struct rte_event ev[], \
> > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void
> > > > > > > > > *port,
> > > > > > \
> > > > > > > > > struct rte_event ev[], \
> > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > > > *port,
> > > > > > > > \
> > > > > > > > > struct rte_event ev[], \
> > > > > > > > > - uint16_t nb_events); \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags); \
> > > > > > > > >
> > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC #undef T diff --git
> > > > > > > > > a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void
> > > > > > > > > *port,
> > > > > > const
> > > > > > > > struct rte_event ev[],
> > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > uint16_t __hot \
> > > > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > > > > > > > > rte_event
> > > > > > ev[], \
> > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > { \
> > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > \
> > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > > > > > > }
> > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -284,12 +286,14
> > @@
> > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > > uint16_t __hot \
> > > > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> > > > > > rte_event ev[],\
> > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > { \
> > > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> > \
> > > > > > > > > \
> > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > }
> > > > > > > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > uint16_t __hot \
> > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > \
> > > > > > > > > struct rte_event ev[], \
> > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > { \
> > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > > > name(void *port,
> > > > > > > > \
> > > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > > \
> > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > > > > > > }
> > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -327,7 +329,8 @@
> > > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > > uint16_t __hot \
> > > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > > > \
> > > > > > > > > struct rte_event ev[], \
> > > > > > > > > - uint16_t nb_events) \
> > > > > > > > > + uint16_t nb_events, \
> > > > > > > > > + uint8_t eq_flags) \
> > > > > > > > > { \
> > > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_
> > ##
> > > > > > name(void
> > > > > > > > *port, \
> > > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> > \
> > > > > > > > > \
> > > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > > }
> > > > > > > > > diff --git
> > > > > > > > > a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > index c848261c4..98be77568 100644
> > > > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > > @@ -300,6 +300,11 @@
> > > > > > > > > rte_event_eth_tx_adapter_txq_get(struct
> > > > > > rte_mbuf
> > > > > > > > *pkt)
> > > > > > > > > int
> > > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id,
> > > > > > > > > uint8_t
> > > > > > > > *event_port_id);
> > > > > > > > >
> > > > > > > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > 0x1
> > > > > > > > > +/**< This flag is used when all the packets enqueued in
> > > > > > > > > +the tx
> > > > adapter
> > > > > > are
> > > > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > > > + */
> > > > > > > > > +
> > > > > > > > > /**
> > > > > > > > > * Enqueue a burst of events objects or an event object
> > > > > > > > > supplied in
> > > > > > > > *rte_event*
> > > > > > > > > * structure on an event device designated by its
> > > > > > > > > *dev_id* through
> > > > > > the event
> > > > > > > > > @@ -324,6 +329,10 @@
> > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > > > id, uint8_t *event_port_id);
> > > > > > > > > * The number of event objects to enqueue, typically number of
> > > > > > > > > *
> > > > rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > > > * available for this port.
> > > > > > > > > + * @param flags
> > > > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > > signifies
> > > > > > that all
> > > > > > > > the packets
> > > > > > > > > + * which are enqueued are destined for the same Ethernet
> > > > > > > > > + device,
> > > > > > queue pair.
> > > > > > > > > *
> > > > > > > > > * @return
> > > > > > > > > * The number of event objects actually enqueued on the event
> > > > > > device. The
> > > > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > > > uint8_t port_id,
> > > > > > > > > struct rte_event ev[],
> > > > > > > > > - uint16_t nb_events)
> > > > > > > > > + uint16_t nb_events,
> > > > > > > > > + uint8_t flags)
> > > > > > > > > {
> > > > > > > > > const struct rte_eventdev *dev =
> > > > > > > > > &rte_eventdevs[dev_id];
> > > > > > > > >
> > > > > > > > > @@ -359,7 +369,8 @@
> > > > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > > > dev_id,
> > > > > > > > > return 0;
> > > > > > > > > }
> > > > > > > > > #endif
> > > > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > nb_events);
> > > > > > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > > > > + nb_events, flags);
> > > > > > > > > }
> > > > > > > > >
> > > > > > > > > /**
> > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > > @@ -1324,7 +1324,8 @@
> > > > rte_eventdev_find_free_device_index(void)
> > > > > > > > > static uint16_t
> > > > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > > > + __rte_unused uint8_t flags)
> > > > > > > > > {
> > > > > > > > > rte_errno = ENOTSUP;
> > > > > > > > > return 0;
> > > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > > > (*event_dequeue_burst_t)(void
> > > > > > > > *port, struct rte_event ev[],
> > > > > > > > > /**< @internal Dequeue burst of events from port of a
> > > > > > > > > device */
> > > > > > > > >
> > > > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > > + uint8_t flags);
> > > > > > > > > /**< @internal Enqueue burst of events on port of a
> > > > > > > > > device */
> > > > > > > > >
> > > > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > > > --
> > > > > > > > > 2.17.1
> > > > > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO DMA map APIs
2019-10-02 4:53 0% ` Shahaf Shuler
@ 2019-10-02 7:51 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2019-10-02 7:51 UTC (permalink / raw)
To: Shahaf Shuler, Ray Kinsella
Cc: anatoly.burakov, Thomas Monjalon, ferruh.yigit, nhorman,
gaetan.rivet, dev
On Wed, Oct 2, 2019 at 6:53 AM Shahaf Shuler <shahafs@mellanox.com> wrote:
>
> Hi David,
>
> Tuesday, October 1, 2019 6:20 PM, David Marchand:
> > Cc: dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO
> > DMA map APIs
> >
> > Hello Shahaf,
> >
> > On 10/03/2019 09:28, Shahaf Shuler wrote:
> > > As those should be replaced by rte_dev_dma_map and
> > rte_dev_dma_unmap
> > > APIs.
> > >
> > > Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
> > > ---
> > > doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> > > doc/guides/rel_notes/deprecation.rst | 4 ++++
> > > 2 files changed, 5 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst
> > > b/doc/guides/prog_guide/env_abstraction_layer.rst
> > > index 929d76dba7..ec2fe65523 100644
> > > --- a/doc/guides/prog_guide/env_abstraction_layer.rst
> > > +++ b/doc/guides/prog_guide/env_abstraction_layer.rst
> > > @@ -282,7 +282,7 @@ The expected workflow is as follows:
> > > - If IOVA table is not specified, IOVA addresses will be assumed to be
> > > unavailable
> > > - Other processes must attach to the memory area before they can
> > > use it
> > > -* Perform DMA mapping with ``rte_vfio_dma_map`` if needed
> > > +* Perform DMA mapping with ``rte_dev_dma_map`` if needed
> > > * Use the memory area in your application
> > > * If memory area is no longer needed, it can be unregistered
> > > - If the area was mapped for DMA, unmapping must be performed
> > > before diff --git a/doc/guides/rel_notes/deprecation.rst
> > > b/doc/guides/rel_notes/deprecation.rst
> > > index 1b4fcb7e64..48ec4fee88 100644
> > > --- a/doc/guides/rel_notes/deprecation.rst
> > > +++ b/doc/guides/rel_notes/deprecation.rst
> > > @@ -35,6 +35,10 @@ Deprecation Notices
> > >
> > > + ``rte_eal_devargs_type_count``
> > >
> > > +* vfio: removal of ``rte_vfio_dma_map`` and ``rte_vfio_dma_unmap``
> > > +APIs which
> > > + have been replaced with ``rte_dev_dma_map`` and
> > > +``rte_dev_dma_unmap``
> > > + functions. The due date for the removal targets DPDK 20.02.
> > > +
> > > * pci: Several exposed functions are misnamed.
> > > The following functions are deprecated starting from v17.11 and are
> > replaced:
> > >
> > >
> >
> > With the ABI freeze that is going to happen in 19.11, this can't happen in
> > 20.02.
> >
> > What would work best from your pov?
>
> I have no object (even prefer) to remove them at 19.11.
> At the time I sent the deprecation I was requested to provide more time for application to adopt.
>
> >
> > I can't see any in-tree user of rte_vfio_dma_*map, do you know of users of
> > this api?
>
> There is one - VPP. They don't use DPDK memory subsystem at all, rather use they own allocated memory and map all, wrongly, w/ above APIs.
Thanks Shahaf.
I cannot see VPP involved people copied in this thread.
It would have been great to involve them at the time.
Ray, can you reply on this topic (replacement of rte_vfio_dma_map) ?
Or could you serve as a gateway/copy the vpp guys?
Thanks.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO DMA map APIs
2019-10-01 15:20 3% ` David Marchand
@ 2019-10-02 4:53 0% ` Shahaf Shuler
2019-10-02 7:51 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Shahaf Shuler @ 2019-10-02 4:53 UTC (permalink / raw)
To: David Marchand, anatoly.burakov, Yongseok Koh, Thomas Monjalon,
ferruh.yigit, nhorman, gaetan.rivet
Cc: dev
Hi David,
Tuesday, October 1, 2019 6:20 PM, David Marchand:
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO
> DMA map APIs
>
> Hello Shahaf,
>
> On 10/03/2019 09:28, Shahaf Shuler wrote:
> > As those should be replaced by rte_dev_dma_map and
> rte_dev_dma_unmap
> > APIs.
> >
> > Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
> > ---
> > doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> > doc/guides/rel_notes/deprecation.rst | 4 ++++
> > 2 files changed, 5 insertions(+), 1 deletion(-)
> >
> > diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst
> > b/doc/guides/prog_guide/env_abstraction_layer.rst
> > index 929d76dba7..ec2fe65523 100644
> > --- a/doc/guides/prog_guide/env_abstraction_layer.rst
> > +++ b/doc/guides/prog_guide/env_abstraction_layer.rst
> > @@ -282,7 +282,7 @@ The expected workflow is as follows:
> > - If IOVA table is not specified, IOVA addresses will be assumed to be
> > unavailable
> > - Other processes must attach to the memory area before they can
> > use it
> > -* Perform DMA mapping with ``rte_vfio_dma_map`` if needed
> > +* Perform DMA mapping with ``rte_dev_dma_map`` if needed
> > * Use the memory area in your application
> > * If memory area is no longer needed, it can be unregistered
> > - If the area was mapped for DMA, unmapping must be performed
> > before diff --git a/doc/guides/rel_notes/deprecation.rst
> > b/doc/guides/rel_notes/deprecation.rst
> > index 1b4fcb7e64..48ec4fee88 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -35,6 +35,10 @@ Deprecation Notices
> >
> > + ``rte_eal_devargs_type_count``
> >
> > +* vfio: removal of ``rte_vfio_dma_map`` and ``rte_vfio_dma_unmap``
> > +APIs which
> > + have been replaced with ``rte_dev_dma_map`` and
> > +``rte_dev_dma_unmap``
> > + functions. The due date for the removal targets DPDK 20.02.
> > +
> > * pci: Several exposed functions are misnamed.
> > The following functions are deprecated starting from v17.11 and are
> replaced:
> >
> >
>
> With the ABI freeze that is going to happen in 19.11, this can't happen in
> 20.02.
>
> What would work best from your pov?
I have no object (even prefer) to remove them at 19.11.
At the time I sent the deprecation I was requested to provide more time for application to adopt.
>
> I can't see any in-tree user of rte_vfio_dma_*map, do you know of users of
> this api?
There is one - VPP. They don't use DPDK memory subsystem at all, rather use they own allocated memory and map all, wrongly, w/ above APIs.
If all agree - we can remove those now.
>
>
> Thanks.
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 15:35 4% ` Jerin Jacob
@ 2019-10-02 3:08 0% ` Hemant Agrawal
2019-10-02 7:54 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2019-10-02 3:08 UTC (permalink / raw)
To: Jerin Jacob, Nipun Gupta
Cc: Jerin Jacob, dpdk-dev, Pavan Nikhilesh, Sunil Kumar Kori,
Richardson, Bruce, Marko Kovacevic, Ori Kam, Radu Nicolau,
Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
Hi Jerin,
> On Tue, Oct 1, 2019 at 8:36 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > Sent: Tuesday, October 1, 2019 7:50 PM
> > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > Cc: Jerin Jacob <jerinj@marvell.com>; dpdk-dev <dev@dpdk.org>; Pavan
> > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> > > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > > destined packets enqueue
> > >
> > > On Tue, Oct 1, 2019 at 7:32 PM Nipun Gupta <nipun.gupta@nxp.com>
> wrote:
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > > Sent: Tuesday, October 1, 2019 6:40 PM
> > > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>;
> > > > > Pavan Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > > > <skori@marvell.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>;
> > > > > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>;
> Radu
> > > > > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > > > > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > > > > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > > destined
> > > > > packets enqueue
> > > > >
> > > > > On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com>
> > > wrote:
> > > > > >
> > > > > >
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > > > > Sent: Tuesday, October 1, 2019 1:14 PM
> > > > > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob
> > > > > > > <jerinj@marvell.com>;
> > > Pavan
> > > > > > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > > > <skori@marvell.com>;
> > > > > > > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > > > > > > <bruce.richardson@intel.com>; Marko Kovacevic
> > > > > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>;
> > > Radu
> > > > > Nicolau
> > > > > > > <radu.nicolau@intel.com>; Tomasz Kantecki
> > > > > <tomasz.kantecki@intel.com>; Van
> > > > > > > Haaren, Harry <harry.van.haaren@intel.com>;
> > > > > > > nikhil.rao@intel.com
> > > > > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify
> > > > > > > same
> > > > > destined
> > > > > > > packets enqueue
> > > > > > >
> > > > > > > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta
> > > > > > > <nipun.gupta@nxp.com>
> > > > > wrote:
> > > > > > > >
> > > > > > > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > > > > > > Some drivers may support burst functionality only with the
> > > > > > > > packets having same destination device and queue.
> > > > > > > >
> > > > > > > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST`
> > > can
> > > > > be used
> > > > > > > > to indicate this so the underlying driver, for drivers to
> > > > > > > > utilize burst functionality appropriately.
> > > > > > >
> > > > > > > I understand the cost of aggregating packets based on port
> > > > > > > and
> > > queue
> > > > > > > to make it burst.
> > > > > > > But, Could you share the use case where how do you want to
> > > > > > > use this flag? I see two possibilities in eventdev context.
> > > > > > > (Where dequeue can be from any ethdev port)
> > > > > > > a) The application does the aggregation. If so, what would
> > > > > > > the difference be in doing driver or application?
> > > > > > > b) We may use this flag when the system has only one port
> > > > > > > and one
> > > > > queue.
> > > > > > >
> > > > > > > Could you share how do you want to use this flag?
> > > > > >
> > > > > > I would say both the cases you mentioned. I prefer this to
> > > > > > depend on
> > > the
> > > > > smartness of
> > > > > > the application, as it is aware of the number of eth
> > > > > > devices/queues it is
> > > > > using.
> > > > > > This is the reason to avoid in the driver.
> > > > > >
> > > > > > A user can also use separate event ports for separate or a
> > > > > > group of
> > > > > Ethernet
> > > > > > devices/queues, to create easy segregation.
> > > > >
> > > > > If it is specific to _very_ static configuration, you can assume
> > > > > all the events comes from a specific eventdev port, comes only
> > > > > from a specific ethdev port.
> > > >
> > > > Hi Jerin,
> > > >
> > > > If I understand correctly this assumption would be made in the driver?
> > > > But then applications like l2fwd-event will break.
> > >
> > > Yes. What I meant is a specific static configuration only this scheme can
> use.
> > >
> > >
> > > >
> > > > >
> > > > > >
> > > > > > Also the drawback of implementing in the driver, can be that
> > > > > > when the
> > > > > events to
> > > > > > Separate devices and queues are so mixed up, that segregation
> > > > > > does
> > > not
> > > > > make
> > > > > > sense, it shall be overhead for the driver to scan all the events.
> > > > >
> > > > > In the worst case, both, applications need to scan and driver
> > > > > need to iterate over all the events.
> > > >
> > > > Agree, this is what we want to avoid.
> > > >
> > > > >
> > > > >
> > > > > In generic l2fwd-eventdev applications etc, q0 will be connected
> > > > > p0 and
> > > p1
> > > > > etc.
> > > > > This flag will be zero.
> > > >
> > > > Okay.
> > > >
> > > > >
> > > > > But, If you think, there is a specific use case for it we can add this flag.
> > > > >
> > > > >
> > > > > >
> > > > > > A flag would help in providing the decision flexibility to the
> applications.
> > > > > >
> > > > > > >
> > > > > > > And another point is, tx adapter is NOT experimental now, We
> > > > > > > need depreciation notice for ABI change.
> > > > > > > If you share the exact use case, then we could think of
> > > > > > > adding a new symbol instead of breaking ABI and add it for
> > > > > > > next release.
> > > > > >
> > > > > > I have heard the discussion that we may get some exceptions to
> > > > > deprecation
> > > > > > process for 19.11 as the APIs will freeze of 1 year post it.
> > > > > > Anyway, if you have a better way with symbol, please suggest.
> > > > >
> > > > >
> > > > > One option could be (not as bad as changing the enqueue
> > > > > prototype) to add new field in struct rte_event_eth_tx_adapter_conf.
> > > > >
> > > > > Since this scheme can be used ONLY on the static configuration,
> > > > > adding a few fields for Tx adapter configuration would help.
> > > > > If that field is set you can choose dev->txa_enqueue light
> > > > > weight enqueue function if not, the driver can aggregate the
> > > > > buffers and send them.
> > > >
> > > > Thanks for suggesting this, we also thought of it, but would
> > > > prefer having
> > > this as a
> > > > runtime option rather than static option.
> > > > We would not like to have one time configuration restriction.
> > >
> > > Not sure how it can be used in runtime. If q0 is connected p0 and p1
> > > and then it flag has to be cleared. if q0 is only connected to p0
> > > then we can use this scheme.
> > > So it is pretty much static in nature.
> > >
> > > How do you think, it can be used in runtime.
> > >
> > > If we think, If we are planning to use like below in application, it
> > > would be really bad in the worst case.(mbuf cache misses in-app and
> > > driver)
> > >
> > > In app:
> > > const port = event[0].mbuf.port;
> > > const queue = event[0].mbuf.queue;
> > > for (i = i; i < nb_events; i++) {
> > > if (port != event[i].mbuf.port || queue != event[i].mbuf.queue)
> > > break;
> > > }
> > > if (i == nb_events)
> > > flag = 1;
> > > else
> > > flag = 0;
> > >
> >
> > In such case if cache misses are observed which is more than what
> > sending burst of traffic is in the applications use-case, the application shall
> simply not use the flag.
> >
> > But again I think this is to be governed by the application which is
> > the user of the event device, on the basis on the configuration and
> > the memory footprint/utilization; and more than that its performance
> benchmarking.
> >
> > > more over the static scheme does not make any change in other drivers.
> > > If you have the usecase for the dynamic scheme then let us know then
> > > we add dynamic flag breaking the ABI.
> >
> > I understand your concern that this shall not be valid on a general cases.
> >
> > There are certain use-case (NXP internal) of DPDK event which have
> > separate event ports/cores dedicated for certain tasks - and can use
> > the burst functionality for performance according to the event ports
> > which are used. Not having this at runtime will limit the flexibility for such
> applications.
>
> If it is specific to NXP internal use case then no more comments on dynamic
> vs static.
>
> @ Nikhil Rao any comments.
>
> One option could be to incorporate NXP internal use case will be introducing
> a new API, parallel to rte_event_eth_tx_adapter_enqueue as
> rte_event_eth_tx_adapter_enqueue_same_dest()
> or something.
>
> Two advantage:
> # Not a major ABI breakage. Only need to add new fast-path function in
> rte_eventdev.
> # Even though we add 'zero' in API all the time, the Compiler prologue needs
> to push to stack or move the value to argument register as there is function
> pointer indirection. so new API will have zero performance impact for normal
> cases.
>
> Not sure about minor ABI breakage in rte_eventdev(adding a new fastpath
> function). If everyone is OK as the exception for 19.11 then we can introduce
> a new API.
[Hemant] There are already too many APIs and mode in eventdev. My suggestion is to minimize the new APIs. Else writing generic applications will be really difficult and it will not be easy to adapt by the application developers.
In this particular case, it is better for NXP to go with direct eth enque mode rather than TX adapter. Note that crypto adapter already provide that mode. However we are trying to adjust so that applications do not become complex.
In the existing code also we have two modes in the application to send the packets out - one is 'rte_event_enqueue_burst' and other is 'rte_event_eth_tx_adapter_enqueue'.
It is still cumbersome for the application to maintain separate modes. This increases when crypto/timer is also being used in event mode.
Why do we not used the 'rte_event->event_type' for TX as well, and 'rte_event_enqueue_burst', API to internally (in respective event driver) send the packet to the respective eth/crypto/timer Tx function? It makes more sense to have a common framework to send packets, rather than having multiple API's?
>
>
>
> >
> > Regards,
> > Nipun
> >
> > >
> > >
> > > >
> > > > >
> > > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > >
> > > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > > ---
> > > > > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > > +++++++++++++--
> > > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > > >
> > > > > > > > diff --git a/app/test-eventdev/test_pipeline_common.h
> > > b/app/test-
> > > > > > > eventdev/test_pipeline_common.h
> > > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev,
> > > > > > > > const
> > > > > uint8_t
> > > > > > > port,
> > > > > > > > struct rte_event * const ev) {
> > > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> 1))
> > > > > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev,
> > > > > > > > + port, ev, 1,
> > > 0))
> > > > > > > > rte_pause(); }
> > > > > > > >
> > > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const
> > > > > > > > uint8_t
> > > dev,
> > > > > const
> > > > > > > uint8_t port,
> > > > > > > > {
> > > > > > > > uint16_t enq;
> > > > > > > >
> > > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > > nb_rx);
> > > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > > + ev,
> > > nb_rx,
> > > > > 0);
> > > > > > > > while (enq < nb_rx) {
> > > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > > + ev + enq, nb_rx - enq, 0);
> > > > > > > > }
> > > > > > > > }
> > > > > > > >
> > > > > > > > diff --git
> > > > > > > > a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > > ``rte_event_enqueue_burst()``
> > > > > > > function.
> > > > > > > > if (cap &
> > > > > > > > RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > > {
> > > > > > > >
> > > > > > > > event.mbuf = m;
> > > > > > > > + eq_flags = 0;
> > > > > > > >
> > > > > > > > m->port = tx_port;
> > > > > > > > rte_event_eth_tx_adapter_txq_set(m,
> > > > > > > > tx_queue_id);
> > > > > > > >
> > > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > > &event,
> > > > > 1);
> > > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id,
> > > > > > > > + ev_port,
> > > > > &event, 1,
> > > > > > > eq_flags);
> > > > > > > > } else {
> > > > > > > >
> > > > > > > > event.queue_id = qid; /* event queue
> > > > > > > > linked to adapter
> > > port */
> > > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows
> > > > > > > > *ws,
> > > > > uint8_t
> > > > > > > queue_id,
> > > > > > > > ssows_handle_event_t fn, void *arg); void
> > > > > > > > ssows_reset(struct ssows *ws); uint16_t
> > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > + uint8_t
> > > eq_flags);
> > > > > > > > int ssovf_info(struct ssovf_info *info); void
> > > > > > > > *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar); int
> > > > > > > > test_eventdev_octeontx(void); diff --git
> > > > > > > > a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > > >
> > > > > > > > uint16_t
> > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > + uint8_t eq_flags)
> > > > > > > > {
> > > > > > > > uint16_t port_id;
> > > > > > > > uint16_t queue_id; @@ -275,6 +275,7 @@
> > > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > > octeontx_dq_t *dq;
> > > > > > > >
> > > > > > > > RTE_SET_USED(nb_events);
> > > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > > switch (ev->sched_type) {
> > > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > > ssows_swtag_norm(ws, ev->event,
> > > > > > > > SSO_SYNC_ATOMIC); diff --git
> > > > > > > > a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > > @@ -333,16 +333,20 @@
> SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > >
> > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port,
> > > > > > > > struct
> > > > > rte_event
> > > > > > > ev[],\
> > > > > > > > - uint16_t nb_events); \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags); \
> > > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void
> > > > > > > > *port,
> > > > > \
> > > > > > > > struct rte_event ev[], \
> > > > > > > > - uint16_t nb_events); \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags); \
> > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void
> > > > > > > > *port,
> > > > > \
> > > > > > > > struct rte_event ev[], \
> > > > > > > > - uint16_t nb_events); \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags); \
> > > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > > *port,
> > > > > > > \
> > > > > > > > struct rte_event ev[], \
> > > > > > > > - uint16_t nb_events); \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags); \
> > > > > > > >
> > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC #undef T diff --git
> > > > > > > > a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void
> > > > > > > > *port,
> > > > > const
> > > > > > > struct rte_event ev[],
> > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > uint16_t __hot \
> > > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > > > > > > > rte_event
> > > > > ev[], \
> > > > > > > > - uint16_t nb_events) \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags) \
> > > > > > > > { \
> > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > \
> > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > > > > > }
> > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -284,12 +286,14
> @@
> > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > > uint16_t __hot \
> > > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> > > > > rte_event ev[],\
> > > > > > > > - uint16_t nb_events) \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags) \
> > > > > > > > { \
> > > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> \
> > > > > > > > \
> > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > }
> > > > > > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > uint16_t __hot \
> > > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> \
> > > > > > > > struct rte_event ev[], \
> > > > > > > > - uint16_t nb_events) \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags) \
> > > > > > > > { \
> > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > > name(void *port,
> > > > > > > \
> > > > > > > > uint64_t cmd[sz]; \
> > > > > > > > \
> > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > > > > > }
> > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC @@ -327,7 +329,8 @@
> > > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > > uint16_t __hot \
> > > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > > \
> > > > > > > > struct rte_event ev[], \
> > > > > > > > - uint16_t nb_events) \
> > > > > > > > + uint16_t nb_events, \
> > > > > > > > + uint8_t eq_flags) \
> > > > > > > > { \
> > > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > > struct otx2_ssogws *vws = \
> > > > > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_
> ##
> > > > > name(void
> > > > > > > *port, \
> > > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> \
> > > > > > > > \
> > > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > > }
> > > > > > > > diff --git
> > > > > > > > a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > index c848261c4..98be77568 100644
> > > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > > @@ -300,6 +300,11 @@
> > > > > > > > rte_event_eth_tx_adapter_txq_get(struct
> > > > > rte_mbuf
> > > > > > > *pkt)
> > > > > > > > int
> > > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id,
> > > > > > > > uint8_t
> > > > > > > *event_port_id);
> > > > > > > >
> > > > > > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > 0x1
> > > > > > > > +/**< This flag is used when all the packets enqueued in
> > > > > > > > +the tx
> > > adapter
> > > > > are
> > > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > > + */
> > > > > > > > +
> > > > > > > > /**
> > > > > > > > * Enqueue a burst of events objects or an event object
> > > > > > > > supplied in
> > > > > > > *rte_event*
> > > > > > > > * structure on an event device designated by its
> > > > > > > > *dev_id* through
> > > > > the event
> > > > > > > > @@ -324,6 +329,10 @@
> > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > > id, uint8_t *event_port_id);
> > > > > > > > * The number of event objects to enqueue, typically number of
> > > > > > > > *
> > > rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > > * available for this port.
> > > > > > > > + * @param flags
> > > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > > signifies
> > > > > that all
> > > > > > > the packets
> > > > > > > > + * which are enqueued are destined for the same Ethernet
> > > > > > > > + device,
> > > > > queue pair.
> > > > > > > > *
> > > > > > > > * @return
> > > > > > > > * The number of event objects actually enqueued on the event
> > > > > device. The
> > > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > > uint8_t port_id,
> > > > > > > > struct rte_event ev[],
> > > > > > > > - uint16_t nb_events)
> > > > > > > > + uint16_t nb_events,
> > > > > > > > + uint8_t flags)
> > > > > > > > {
> > > > > > > > const struct rte_eventdev *dev =
> > > > > > > > &rte_eventdevs[dev_id];
> > > > > > > >
> > > > > > > > @@ -359,7 +369,8 @@
> > > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > > dev_id,
> > > > > > > > return 0;
> > > > > > > > }
> > > > > > > > #endif
> > > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > nb_events);
> > > > > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > > > + nb_events, flags);
> > > > > > > > }
> > > > > > > >
> > > > > > > > /**
> > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > > @@ -1324,7 +1324,8 @@
> > > rte_eventdev_find_free_device_index(void)
> > > > > > > > static uint16_t
> > > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > > + __rte_unused uint8_t flags)
> > > > > > > > {
> > > > > > > > rte_errno = ENOTSUP;
> > > > > > > > return 0;
> > > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > > (*event_dequeue_burst_t)(void
> > > > > > > *port, struct rte_event ev[],
> > > > > > > > /**< @internal Dequeue burst of events from port of a
> > > > > > > > device */
> > > > > > > >
> > > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > > + struct rte_event ev[], uint16_t nb_events,
> > > > > > > > + uint8_t flags);
> > > > > > > > /**< @internal Enqueue burst of events on port of a
> > > > > > > > device */
> > > > > > > >
> > > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > > --
> > > > > > > > 2.17.1
> > > > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 01/10] security: introduce CPU Crypto action type and API
2019-10-01 15:27 4% ` Ananyev, Konstantin
@ 2019-10-02 2:47 0% ` Hemant Agrawal
0 siblings, 0 replies; 200+ results
From: Hemant Agrawal @ 2019-10-02 2:47 UTC (permalink / raw)
To: Ananyev, Konstantin, Zhang, Roy Fan, dev; +Cc: Doherty, Declan, Akhil Goyal
Hi Konstantin,
> > >>> This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > >>> action type to security library. The type represents performing
> > >>> crypto operation with CPU cycles. The patch also includes a new
> > >>> API to process crypto operations in bulk and the function pointers for
> PMDs.
> > >>>
> > >>> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> > >>> ---
> > >>> lib/librte_security/rte_security.c | 16 +++++++++
> > >>> lib/librte_security/rte_security.h | 51
> +++++++++++++++++++++++++++-
> > >>> lib/librte_security/rte_security_driver.h | 19 +++++++++++
> > >>> lib/librte_security/rte_security_version.map | 1 +
> > >>> 4 files changed, 86 insertions(+), 1 deletion(-)
> > >>>
> > >>> diff --git a/lib/librte_security/rte_security.c
> > >>> b/lib/librte_security/rte_security.c
> > >>> index bc81ce15d..0f85c1b59 100644
> > >>> --- a/lib/librte_security/rte_security.c
> > >>> +++ b/lib/librte_security/rte_security.c
> > >>> @@ -141,3 +141,19 @@ rte_security_capability_get(struct
> > >>> rte_security_ctx *instance,
> > >>>
> > >>> return NULL;
> > >>> }
> > >>> +
> > >>> +void
> > >>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx
> *instance,
> > >>> + struct rte_security_session *sess,
> > >>> + struct rte_security_vec buf[], void *iv[], void *aad[],
> > >>> + void *digest[], int status[], uint32_t num) {
> > >>> + uint32_t i;
> > >>> +
> > >>> + for (i = 0; i < num; i++)
> > >>> + status[i] = -1;
> > >>> +
> > >>> + RTE_FUNC_PTR_OR_RET(*instance->ops->process_cpu_crypto_bulk);
> > >>> + instance->ops->process_cpu_crypto_bulk(sess, buf, iv,
> > >>> + aad, digest, status, num);
> > >>> +}
> > >>> diff --git a/lib/librte_security/rte_security.h
> > >>> b/lib/librte_security/rte_security.h
> > >>> index 96806e3a2..5a0f8901b 100644
> > >>> --- a/lib/librte_security/rte_security.h
> > >>> +++ b/lib/librte_security/rte_security.h
> > >>> @@ -18,6 +18,7 @@ extern "C" {
> > >>> #endif
> > >>>
> > >>> #include <sys/types.h>
> > >>> +#include <sys/uio.h>
> > >>>
> > >>> #include <netinet/in.h>
> > >>> #include <netinet/ip.h>
> > >>> @@ -272,6 +273,20 @@ struct rte_security_pdcp_xform {
> > >>> uint32_t hfn_threshold;
> > >>> };
> > >>>
> > >>> +struct rte_security_cpu_crypto_xform {
> > >>> + /** For cipher/authentication crypto operation the authentication
> may
> > >>> + * cover more content then the cipher. E.g., for IPSec ESP encryption
> > >>> + * with AES-CBC and SHA1-HMAC, the encryption happens after the
> ESP
> > >>> + * header but whole packet (apart from MAC header) is
> authenticated.
> > >>> + * The cipher_offset field is used to deduct the cipher data pointer
> > >>> + * from the buffer to be processed.
> > >>> + *
> > >>> + * NOTE this parameter shall be ignored by AEAD algorithms, since it
> > >>> + * uses the same offset for cipher and authentication.
> > >>> + */
> > >>> + int32_t cipher_offset;
> > >>> +};
> > >>> +
> > >>> /**
> > >>> * Security session action type.
> > >>> */
> > >>> @@ -286,10 +301,14 @@ enum rte_security_session_action_type {
> > >>> /**< All security protocol processing is performed inline during
> > >>> * transmission
> > >>> */
> > >>> - RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL
> > >>> + RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
> > >>> /**< All security protocol processing including crypto is performed
> > >>> * on a lookaside accelerator
> > >>> */
> > >>> + RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> > >>> + /**< Crypto processing for security protocol is processed by CPU
> > >>> + * synchronously
> > >>> + */
> > >> though you are naming it cpu crypto, but it is more like raw packet
> > >> crypto, where you want to skip mbuf/crypto ops and directly wants
> > >> to work on raw buffer.
> > > Yes, but we do wat to do that (skip mbuf/crypto ops and use raw
> > > buffer), because this API is destined for SW backed implementation.
> > > For that case crypto-ops , mbuf, enqueue/dequeue are just unnecessary
> overhead.
> > I agree, we are also planning to take advantage of it for some
> > specific use-cases in future.
> > >>> };
> > >>>
> > >>> /** Security session protocol definition */ @@ -315,6 +334,7 @@
> > >>> struct rte_security_session_conf {
> > >>> struct rte_security_ipsec_xform ipsec;
> > >>> struct rte_security_macsec_xform macsec;
> > >>> struct rte_security_pdcp_xform pdcp;
> > >>> + struct rte_security_cpu_crypto_xform cpucrypto;
> > >>> };
> > >>> /**< Configuration parameters for security session */
> > >>> struct rte_crypto_sym_xform *crypto_xform; @@ -639,6 +659,35
> > >>> @@ const struct rte_security_capability *
> > >>> rte_security_capability_get(struct rte_security_ctx *instance,
> > >>> struct rte_security_capability_idx *idx);
> > >>>
> > >>> +/**
> > >>> + * Security vector structure, contains pointer to vector array
> > >>> +and the length
> > >>> + * of the array
> > >>> + */
> > >>> +struct rte_security_vec {
> > >>> + struct iovec *vec;
> > >>> + uint32_t num;
> > >>> +};
> > >>> +
> > >> Just wondering if you want to change it to *in_vec and *out_vec,
> > >> that will be helpful in future, if the out-of-place processing is
> > >> required for CPU usecase as well?
> > > I suppose this is doable, though right now we don't plan to support such
> model.
> > They will come handy in future. I plan to use it in future and we can
> > skip the API/ABI breakage, if the placeholder are present
> > >
> > >>> +/**
> > >>> + * Processing bulk crypto workload with CPU
> > >>> + *
> > >>> + * @param instance security instance.
> > >>> + * @param sess security session
> > >>> + * @param buf array of buffer SGL vectors
> > >>> + * @param iv array of IV pointers
> > >>> + * @param aad array of AAD pointers
> > >>> + * @param digest array of digest pointers
> > >>> + * @param status array of status for the function to
> return
> > >>> + * @param num number of elements in each array
> > >>> + *
> > >>> + */
> > >>> +__rte_experimental
> > >>> +void
> > >>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx
> *instance,
> > >>> + struct rte_security_session *sess,
> > >>> + struct rte_security_vec buf[], void *iv[], void *aad[],
> > >>> + void *digest[], int status[], uint32_t num);
> > >>> +
> > >> Why not make the return as int, to indicate whether this API
> > >> completely failed or processed or have some valid status to look into?
> > > Good point, will change as suggested.
> >
> > I have another suggestions w.r.t iv, aad, digest etc. Why not put them
> > in a structure, so that you will
> >
> > be able to add/remove the variable without breaking the API prototype.
>
>
> Just to confirm, you are talking about something like:
>
> struct rte_security_vec {
> struct iovec *vec;
> uint32_t num;
> };
[Hemant] My idea is:
struct rte_security_vec {
struct iovec *vec;
struct iovec *out_vec;
uint32_t num_in;
uint32_t num_out;
};
>
> struct rte_security_sym_vec {
> struct rte_security_vec buf;
> void *iv;
> void *aad;
> void *digest;
> };
>
[Hemant] or leave the rte_security_vec altogether and make it part of rte_security_sym_vec itself.
> rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
> struct rte_security_session *sess, struct rte_security_sym_vec buf[],
> int status[], uint32_t num);
>
> ?
> We thought about such way, though for PMD it would be more plausible to
> have same type of params grouped together, i.e. void *in[], void *out[], void
> *digest[], ...
> Another thing - above grouping wouldn't help to avoid ABI breakage, in case
> we'll need to add new field into rte_security_sym_vec (though it might help
> to avoid API breakage).
>
> In theory other way is also possible:
> struct rte_security_sym_vec {
> struct rte_security_vec *buf;
> void **iv;
> void **aad;
> void **digest;
> };
>
> rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
> struct rte_security_session *sess, struct rte_security_sym_vec *buf,
> int status[], uint32_t num);
>
> And that might help for both ABI and API stability, but it looks really weird
> that way (at least to me).
[Hemant] I am fine either way.
> Also this API is experimental and I suppose needs to stay experimental for
> few releases before we are sure nothing important is missing, so probably
> API/ABI stability is not that high concern for it right now.
>
> Konstantin
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/2] build: support building ABI versioned files twice
2019-10-01 13:23 4% ` Andrzej Ostruszka
@ 2019-10-01 16:53 4% ` Bruce Richardson
2019-10-07 15:57 4% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2019-10-01 16:53 UTC (permalink / raw)
To: Andrzej Ostruszka; +Cc: dev, Thomas Monjalon, Ray Kinsella, Neil Horman, bluca
On Tue, Oct 01, 2019 at 03:23:47PM +0200, Andrzej Ostruszka wrote:
> Thanks Bruce for the patch. I like the idea of splitting versioning out
> of rte_compat.h, but I have some comments.
>
> On 9/27/19 10:59 PM, Bruce Richardson wrote:
> [...]
> > --- a/config/common_base
> > +++ b/config/common_base
> > @@ -111,6 +111,7 @@ CONFIG_RTE_MAX_VFIO_CONTAINERS=64
> > CONFIG_RTE_MALLOC_DEBUG=n
> > CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
> > CONFIG_RTE_USE_LIBBSD=n
> > +CONFIG_RTE_USE_FUNCTION_VERSIONING=y
>
> I'm not fond of this config option - it is not really an option to be
> changed by the user. I would prefer to just add flag to CFLAGS in
> mk/target/generic/rte.vars.mk.
>
Ok, that sounds reasonable enough.
> > #
> > # Recognize/ignore the AVX/AVX512 CPU flags for performance/power testing.
> > diff --git a/config/rte_config.h b/config/rte_config.h
> > index 0bbbe274f..b63a2fdea 100644
> > --- a/config/rte_config.h
> > +++ b/config/rte_config.h
> > @@ -31,9 +31,6 @@
> >
> > /****** library defines ********/
> >
> > -/* compat defines */
> > -#define RTE_BUILD_SHARED_LIB
> > -
>
> So now everything builds "as static lib" (but with "-fPIC") apart from
> those libraries that use symbol versioning. I'm OK with that however
> I'd like to note that code might be using RTE_BUILD_SHARED_LIB and do
> different things e.g. app/test-bbdev/test_bbdev_perf.c. I know that was
> already the case - just wanted to say that aloud to make sure we are all
> aware of this :).
Thanks for pointing this out, I wasn't aware of it! Doing a git grep this
seems to be the only place in a C file (other than rte_config.h and
rte_compat.h) where the SHARED_LIB flag is being checked. I'll need to
follow up on that to see what the logic is there, because it seems strange
to require such a check.
>
> > diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
> > index 449b33494..e95a1a2be 100644
> > --- a/doc/guides/contributing/coding_style.rst
> > +++ b/doc/guides/contributing/coding_style.rst
> > @@ -948,6 +948,13 @@ reason
> > built. For missing dependencies this should be of the form
> > ``'missing dependency, "libname"'``.
> >
> > +use_function_versioning
> > + **Default Value = false**.
> > + Specifies if the library in question has ABI versioned functions. If it
> > + has, this value should be set to ensure that the C files are compiled
> > + twice with suitable parameters for each of shared or static library
> > + builds.
> > +
>
> Maybe a different name for this option? In general an "ideal
> theoretical" solution would be for build system to figure out on its own
> that separate build is necessary automatically - but that might incur
> some performance penalty (additional grep'ing of sources or so).
I was thinking about that, and how we can do it automatically. The trouble
is that for correctness we would need to recheck every file after it had
changed, and since the result of the check means that we have different
build steps it would basically mean doing a full reconfiguration for every
file change. That's not really practical, hence this proposed solution.
> So I'm
> fine with this option however I'd like to rename it to actually indicate
> what it's effect is. Like 'separate_build' or 'split_build' or
> 'rebuild_objects' or ...
>
> The intention of using of versioned symbols is already indicated by
> inclusion of the relevant header.
I actually feel the opposite. I'd rather have the name tied in to the fact
that it's related to using function versioning - subject to what is found
on investigating the #ifdef in the bbdev perf test. However, if you feel
strongly about the name something else, I can probably compromise on it :-)
>
> > diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h
> > index ce963d4b1..55e88ffae 100644
> > --- a/lib/librte_eal/common/include/rte_function_versioning.h
> > +++ b/lib/librte_eal/common/include/rte_function_versioning.h
> > @@ -7,6 +7,10 @@
> > #define _RTE_FUNCTION_VERSIONING_H_
> > #include <rte_common.h>
> >
> > +#ifndef RTE_USE_FUNCTION_VERSIONING
> > +#error Use of function versioning disabled, is "use_function_versioning=true" in meson.build?
> > +#endif
>
> If you accept above suggestion then change this message to something
> like: "Function versioning requires 'separate_build=true' in meson.build"
>
Agreed. This obviously needs to be kept in sync with whatever the build
flag is.
> BTW it turned out that this need for separate build for versioned
> symbols is a result of long standing gcc bug:
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200
>
> I'll test this with clang and if this will work then maybe we could
> guard this #if with another check for 'gcc'.
>
> Best regards
> Andrzej
>
> Tested-by: Andrzej Ostruszka <amo@semihalf.com>
Let me know what your testing throws up, thanks.
/Bruce
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 15:06 0% ` Nipun Gupta
@ 2019-10-01 15:35 4% ` Jerin Jacob
2019-10-02 3:08 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-01 15:35 UTC (permalink / raw)
To: Nipun Gupta
Cc: Jerin Jacob, dpdk-dev, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
On Tue, Oct 1, 2019 at 8:36 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Jerin Jacob <jerinjacobk@gmail.com>
> > Sent: Tuesday, October 1, 2019 7:50 PM
> > To: Nipun Gupta <nipun.gupta@nxp.com>
> > Cc: Jerin Jacob <jerinj@marvell.com>; dpdk-dev <dev@dpdk.org>; Pavan
> > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> > packets enqueue
> >
> > On Tue, Oct 1, 2019 at 7:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > Sent: Tuesday, October 1, 2019 6:40 PM
> > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > > <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> > > > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > > > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > > > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > > > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > destined
> > > > packets enqueue
> > > >
> > > > On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com>
> > wrote:
> > > > >
> > > > >
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > > > Sent: Tuesday, October 1, 2019 1:14 PM
> > > > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>;
> > Pavan
> > > > > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > > <skori@marvell.com>;
> > > > > > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > > > > > <bruce.richardson@intel.com>; Marko Kovacevic
> > > > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>;
> > Radu
> > > > Nicolau
> > > > > > <radu.nicolau@intel.com>; Tomasz Kantecki
> > > > <tomasz.kantecki@intel.com>; Van
> > > > > > Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > > > destined
> > > > > > packets enqueue
> > > > > >
> > > > > > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com>
> > > > wrote:
> > > > > > >
> > > > > > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > > > > > Some drivers may support burst functionality only with the packets
> > > > > > > having same destination device and queue.
> > > > > > >
> > > > > > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST`
> > can
> > > > be used
> > > > > > > to indicate this so the underlying driver, for drivers to utilize
> > > > > > > burst functionality appropriately.
> > > > > >
> > > > > > I understand the cost of aggregating packets based on port and
> > queue
> > > > > > to make it burst.
> > > > > > But, Could you share the use case where how do you want to use this
> > > > > > flag? I see two possibilities in eventdev context.
> > > > > > (Where dequeue can be from any ethdev port)
> > > > > > a) The application does the aggregation. If so, what would the
> > > > > > difference be in doing driver or application?
> > > > > > b) We may use this flag when the system has only one port and one
> > > > queue.
> > > > > >
> > > > > > Could you share how do you want to use this flag?
> > > > >
> > > > > I would say both the cases you mentioned. I prefer this to depend on
> > the
> > > > smartness of
> > > > > the application, as it is aware of the number of eth devices/queues it is
> > > > using.
> > > > > This is the reason to avoid in the driver.
> > > > >
> > > > > A user can also use separate event ports for separate or a group of
> > > > Ethernet
> > > > > devices/queues, to create easy segregation.
> > > >
> > > > If it is specific to _very_ static configuration, you can assume all
> > > > the events comes
> > > > from a specific eventdev port, comes only from a specific ethdev port.
> > >
> > > Hi Jerin,
> > >
> > > If I understand correctly this assumption would be made in the driver?
> > > But then applications like l2fwd-event will break.
> >
> > Yes. What I meant is a specific static configuration only this scheme can use.
> >
> >
> > >
> > > >
> > > > >
> > > > > Also the drawback of implementing in the driver, can be that when the
> > > > events to
> > > > > Separate devices and queues are so mixed up, that segregation does
> > not
> > > > make
> > > > > sense, it shall be overhead for the driver to scan all the events.
> > > >
> > > > In the worst case, both, applications need to scan and driver need to
> > > > iterate over
> > > > all the events.
> > >
> > > Agree, this is what we want to avoid.
> > >
> > > >
> > > >
> > > > In generic l2fwd-eventdev applications etc, q0 will be connected p0 and
> > p1
> > > > etc.
> > > > This flag will be zero.
> > >
> > > Okay.
> > >
> > > >
> > > > But, If you think, there is a specific use case for it we can add this flag.
> > > >
> > > >
> > > > >
> > > > > A flag would help in providing the decision flexibility to the applications.
> > > > >
> > > > > >
> > > > > > And another point is, tx adapter is NOT experimental now, We need
> > > > > > depreciation notice for ABI change.
> > > > > > If you share the exact use case, then we could think of adding a new
> > > > > > symbol instead of breaking ABI and
> > > > > > add it for next release.
> > > > >
> > > > > I have heard the discussion that we may get some exceptions to
> > > > deprecation
> > > > > process for 19.11 as the APIs will freeze of 1 year post it.
> > > > > Anyway, if you have a better way with symbol, please suggest.
> > > >
> > > >
> > > > One option could be (not as bad as changing the enqueue prototype) to
> > > > add new field in struct rte_event_eth_tx_adapter_conf.
> > > >
> > > > Since this scheme can be used ONLY on the static configuration, adding
> > > > a few fields
> > > > for Tx adapter configuration would help.
> > > > If that field is set you can choose dev->txa_enqueue light weight
> > > > enqueue function
> > > > if not, the driver can aggregate the buffers and send them.
> > >
> > > Thanks for suggesting this, we also thought of it, but would prefer having
> > this as a
> > > runtime option rather than static option.
> > > We would not like to have one time configuration restriction.
> >
> > Not sure how it can be used in runtime. If q0 is connected p0 and p1 and then
> > it flag has to be cleared. if q0 is only connected to p0 then we can
> > use this scheme.
> > So it is pretty much static in nature.
> >
> > How do you think, it can be used in runtime.
> >
> > If we think, If we are planning to use like below in application, it
> > would be really bad
> > in the worst case.(mbuf cache misses in-app and driver)
> >
> > In app:
> > const port = event[0].mbuf.port;
> > const queue = event[0].mbuf.queue;
> > for (i = i; i < nb_events; i++) {
> > if (port != event[i].mbuf.port || queue != event[i].mbuf.queue)
> > break;
> > }
> > if (i == nb_events)
> > flag = 1;
> > else
> > flag = 0;
> >
>
> In such case if cache misses are observed which is more than what sending burst
> of traffic is in the applications use-case, the application shall simply not use the flag.
>
> But again I think this is to be governed by the application which is the user of the
> event device, on the basis on the configuration and the memory footprint/utilization;
> and more than that its performance benchmarking.
>
> > more over the static scheme does not make any change in other drivers.
> > If you have the usecase for the dynamic scheme then let us know then
> > we add dynamic flag breaking the ABI.
>
> I understand your concern that this shall not be valid on a general cases.
>
> There are certain use-case (NXP internal) of DPDK event which have separate
> event ports/cores dedicated for certain tasks - and can use the burst functionality
> for performance according to the event ports which are used. Not having this at
> runtime will limit the flexibility for such applications.
If it is specific to NXP internal use case then no more comments on
dynamic vs static.
@ Nikhil Rao any comments.
One option could be to incorporate NXP internal use case will be
introducing a new API,
parallel to rte_event_eth_tx_adapter_enqueue as
rte_event_eth_tx_adapter_enqueue_same_dest()
or something.
Two advantage:
# Not a major ABI breakage. Only need to add new fast-path function in
rte_eventdev.
# Even though we add 'zero' in API all the time, the Compiler prologue
needs to push to stack or move
the value to argument register as there is function pointer
indirection. so new API will have zero performance impact
for normal cases.
Not sure about minor ABI breakage in rte_eventdev(adding a new
fastpath function). If everyone is
OK as the exception for 19.11 then we can introduce a new API.
>
> Regards,
> Nipun
>
> >
> >
> > >
> > > >
> > > >
> > > >
> > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > >
> > > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > > ---
> > > > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > > +++++++++++++--
> > > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > > >
> > > > > > > diff --git a/app/test-eventdev/test_pipeline_common.h
> > b/app/test-
> > > > > > eventdev/test_pipeline_common.h
> > > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const
> > > > uint8_t
> > > > > > port,
> > > > > > > struct rte_event * const ev)
> > > > > > > {
> > > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > > > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1,
> > 0))
> > > > > > > rte_pause();
> > > > > > > }
> > > > > > >
> > > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t
> > dev,
> > > > const
> > > > > > uint8_t port,
> > > > > > > {
> > > > > > > uint16_t enq;
> > > > > > >
> > > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > nb_rx);
> > > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> > nb_rx,
> > > > 0);
> > > > > > > while (enq < nb_rx) {
> > > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > > - ev + enq, nb_rx - enq);
> > > > > > > + ev + enq, nb_rx - enq, 0);
> > > > > > > }
> > > > > > > }
> > > > > > >
> > > > > > > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > > @@ -137,11 +137,12 @@ should use the
> > > > ``rte_event_enqueue_burst()``
> > > > > > function.
> > > > > > > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> > {
> > > > > > >
> > > > > > > event.mbuf = m;
> > > > > > > + eq_flags = 0;
> > > > > > >
> > > > > > > m->port = tx_port;
> > > > > > > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> > > > > > >
> > > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > &event,
> > > > 1);
> > > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > > > &event, 1,
> > > > > > eq_flags);
> > > > > > > } else {
> > > > > > >
> > > > > > > event.queue_id = qid; /* event queue linked to adapter
> > port */
> > > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > index 0e622152c..1b156edab 100644
> > > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws,
> > > > uint8_t
> > > > > > queue_id,
> > > > > > > ssows_handle_event_t fn, void *arg);
> > > > > > > void ssows_reset(struct ssows *ws);
> > > > > > > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t
> > eq_flags);
> > > > > > > int ssovf_info(struct ssovf_info *info);
> > > > > > > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > > > > > int test_eventdev_octeontx(void);
> > > > > > > diff --git a/drivers/event/octeontx/ssovf_worker.c
> > > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > > >
> > > > > > > uint16_t
> > > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > > > > > > {
> > > > > > > uint16_t port_id;
> > > > > > > uint16_t queue_id;
> > > > > > > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > > > > > > octeontx_dq_t *dq;
> > > > > > >
> > > > > > > RTE_SET_USED(nb_events);
> > > > > > > + RTE_SET_USED(eq_flags);
> > > > > > > switch (ev->sched_type) {
> > > > > > > case SSO_SYNC_ORDERED:
> > > > > > > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > > > > > > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > >
> > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > > > rte_event
> > > > > > ev[],\
> > > > > > > - uint16_t nb_events); \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags); \
> > > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > > > \
> > > > > > > struct rte_event ev[], \
> > > > > > > - uint16_t nb_events); \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags); \
> > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > > > \
> > > > > > > struct rte_event ev[], \
> > > > > > > - uint16_t nb_events); \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags); \
> > > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > *port,
> > > > > > \
> > > > > > > struct rte_event ev[], \
> > > > > > > - uint16_t nb_events); \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags); \
> > > > > > >
> > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > #undef T
> > > > > > > diff --git a/drivers/event/octeontx2/otx2_worker.c
> > > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > index cd14cd3d2..100e21669 100644
> > > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port,
> > > > const
> > > > > > struct rte_event ev[],
> > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > uint16_t __hot \
> > > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> > > > ev[], \
> > > > > > > - uint16_t nb_events) \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags) \
> > > > > > > { \
> > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > uint64_t cmd[sz]; \
> > > > > > > \
> > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > > > > }
> > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > > uint16_t __hot \
> > > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> > > > rte_event ev[],\
> > > > > > > - uint16_t nb_events) \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags) \
> > > > > > > { \
> > > > > > > struct otx2_ssogws *ws = port; \
> > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > > > \
> > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > }
> > > > > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > index 37c274a54..c3e48da42 100644
> > > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > uint16_t __hot \
> > > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > > > > > struct rte_event ev[], \
> > > > > > > - uint16_t nb_events) \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags) \
> > > > > > > { \
> > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > struct otx2_ssogws *vws = \
> > > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > > > name(void *port,
> > > > > > \
> > > > > > > uint64_t cmd[sz]; \
> > > > > > > \
> > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > > > > }
> > > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > > uint16_t __hot \
> > > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > \
> > > > > > > struct rte_event ev[], \
> > > > > > > - uint16_t nb_events) \
> > > > > > > + uint16_t nb_events, \
> > > > > > > + uint8_t eq_flags) \
> > > > > > > { \
> > > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > > struct otx2_ssogws *vws = \
> > > > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > > > name(void
> > > > > > *port, \
> > > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > > > \
> > > > > > > RTE_SET_USED(nb_events); \
> > > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > > }
> > > > > > > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > index c848261c4..98be77568 100644
> > > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct
> > > > rte_mbuf
> > > > > > *pkt)
> > > > > > > int
> > > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> > > > > > *event_port_id);
> > > > > > >
> > > > > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > 0x1
> > > > > > > +/**< This flag is used when all the packets enqueued in the tx
> > adapter
> > > > are
> > > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > > + */
> > > > > > > +
> > > > > > > /**
> > > > > > > * Enqueue a burst of events objects or an event object supplied in
> > > > > > *rte_event*
> > > > > > > * structure on an event device designated by its *dev_id* through
> > > > the event
> > > > > > > @@ -324,6 +329,10 @@
> > > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > > id, uint8_t *event_port_id);
> > > > > > > * The number of event objects to enqueue, typically number of
> > > > > > > *
> > rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > > * available for this port.
> > > > > > > + * @param flags
> > > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> > signifies
> > > > that all
> > > > > > the packets
> > > > > > > + * which are enqueued are destined for the same Ethernet device,
> > > > queue pair.
> > > > > > > *
> > > > > > > * @return
> > > > > > > * The number of event objects actually enqueued on the event
> > > > device. The
> > > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > > uint8_t port_id,
> > > > > > > struct rte_event ev[],
> > > > > > > - uint16_t nb_events)
> > > > > > > + uint16_t nb_events,
> > > > > > > + uint8_t flags)
> > > > > > > {
> > > > > > > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> > > > > > >
> > > > > > > @@ -359,7 +369,8 @@
> > rte_event_eth_tx_adapter_enqueue(uint8_t
> > > > dev_id,
> > > > > > > return 0;
> > > > > > > }
> > > > > > > #endif
> > > > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > nb_events);
> > > > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > > + nb_events, flags);
> > > > > > > }
> > > > > > >
> > > > > > > /**
> > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > > @@ -1324,7 +1324,8 @@
> > rte_eventdev_find_free_device_index(void)
> > > > > > > static uint16_t
> > > > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > > > __rte_unused struct rte_event ev[],
> > > > > > > - __rte_unused uint16_t nb_events)
> > > > > > > + __rte_unused uint16_t nb_events,
> > > > > > > + __rte_unused uint8_t flags)
> > > > > > > {
> > > > > > > rte_errno = ENOTSUP;
> > > > > > > return 0;
> > > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > > (*event_dequeue_burst_t)(void
> > > > > > *port, struct rte_event ev[],
> > > > > > > /**< @internal Dequeue burst of events from port of a device */
> > > > > > >
> > > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > > > > > > /**< @internal Enqueue burst of events on port of a device */
> > > > > > >
> > > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > > --
> > > > > > > 2.17.1
> > > > > > >
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 01/10] security: introduce CPU Crypto action type and API
2019-09-30 9:43 3% ` Hemant Agrawal
@ 2019-10-01 15:27 4% ` Ananyev, Konstantin
2019-10-02 2:47 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-01 15:27 UTC (permalink / raw)
To: Hemant Agrawal, Zhang, Roy Fan, dev; +Cc: Doherty, Declan, Akhil Goyal
Hi Hemant,
> >>> This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO action type to
> >>> security library. The type represents performing crypto operation with CPU
> >>> cycles. The patch also includes a new API to process crypto operations in
> >>> bulk and the function pointers for PMDs.
> >>>
> >>> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
> >>> ---
> >>> lib/librte_security/rte_security.c | 16 +++++++++
> >>> lib/librte_security/rte_security.h | 51 +++++++++++++++++++++++++++-
> >>> lib/librte_security/rte_security_driver.h | 19 +++++++++++
> >>> lib/librte_security/rte_security_version.map | 1 +
> >>> 4 files changed, 86 insertions(+), 1 deletion(-)
> >>>
> >>> diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
> >>> index bc81ce15d..0f85c1b59 100644
> >>> --- a/lib/librte_security/rte_security.c
> >>> +++ b/lib/librte_security/rte_security.c
> >>> @@ -141,3 +141,19 @@ rte_security_capability_get(struct rte_security_ctx *instance,
> >>>
> >>> return NULL;
> >>> }
> >>> +
> >>> +void
> >>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
> >>> + struct rte_security_session *sess,
> >>> + struct rte_security_vec buf[], void *iv[], void *aad[],
> >>> + void *digest[], int status[], uint32_t num)
> >>> +{
> >>> + uint32_t i;
> >>> +
> >>> + for (i = 0; i < num; i++)
> >>> + status[i] = -1;
> >>> +
> >>> + RTE_FUNC_PTR_OR_RET(*instance->ops->process_cpu_crypto_bulk);
> >>> + instance->ops->process_cpu_crypto_bulk(sess, buf, iv,
> >>> + aad, digest, status, num);
> >>> +}
> >>> diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
> >>> index 96806e3a2..5a0f8901b 100644
> >>> --- a/lib/librte_security/rte_security.h
> >>> +++ b/lib/librte_security/rte_security.h
> >>> @@ -18,6 +18,7 @@ extern "C" {
> >>> #endif
> >>>
> >>> #include <sys/types.h>
> >>> +#include <sys/uio.h>
> >>>
> >>> #include <netinet/in.h>
> >>> #include <netinet/ip.h>
> >>> @@ -272,6 +273,20 @@ struct rte_security_pdcp_xform {
> >>> uint32_t hfn_threshold;
> >>> };
> >>>
> >>> +struct rte_security_cpu_crypto_xform {
> >>> + /** For cipher/authentication crypto operation the authentication may
> >>> + * cover more content then the cipher. E.g., for IPSec ESP encryption
> >>> + * with AES-CBC and SHA1-HMAC, the encryption happens after the ESP
> >>> + * header but whole packet (apart from MAC header) is authenticated.
> >>> + * The cipher_offset field is used to deduct the cipher data pointer
> >>> + * from the buffer to be processed.
> >>> + *
> >>> + * NOTE this parameter shall be ignored by AEAD algorithms, since it
> >>> + * uses the same offset for cipher and authentication.
> >>> + */
> >>> + int32_t cipher_offset;
> >>> +};
> >>> +
> >>> /**
> >>> * Security session action type.
> >>> */
> >>> @@ -286,10 +301,14 @@ enum rte_security_session_action_type {
> >>> /**< All security protocol processing is performed inline during
> >>> * transmission
> >>> */
> >>> - RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL
> >>> + RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
> >>> /**< All security protocol processing including crypto is performed
> >>> * on a lookaside accelerator
> >>> */
> >>> + RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
> >>> + /**< Crypto processing for security protocol is processed by CPU
> >>> + * synchronously
> >>> + */
> >> though you are naming it cpu crypto, but it is more like raw packet
> >> crypto, where you want to skip mbuf/crypto ops and directly wants to
> >> work on raw buffer.
> > Yes, but we do wat to do that (skip mbuf/crypto ops and use raw buffer),
> > because this API is destined for SW backed implementation.
> > For that case crypto-ops , mbuf, enqueue/dequeue are just unnecessary overhead.
> I agree, we are also planning to take advantage of it for some specific
> use-cases in future.
> >>> };
> >>>
> >>> /** Security session protocol definition */
> >>> @@ -315,6 +334,7 @@ struct rte_security_session_conf {
> >>> struct rte_security_ipsec_xform ipsec;
> >>> struct rte_security_macsec_xform macsec;
> >>> struct rte_security_pdcp_xform pdcp;
> >>> + struct rte_security_cpu_crypto_xform cpucrypto;
> >>> };
> >>> /**< Configuration parameters for security session */
> >>> struct rte_crypto_sym_xform *crypto_xform;
> >>> @@ -639,6 +659,35 @@ const struct rte_security_capability *
> >>> rte_security_capability_get(struct rte_security_ctx *instance,
> >>> struct rte_security_capability_idx *idx);
> >>>
> >>> +/**
> >>> + * Security vector structure, contains pointer to vector array and the length
> >>> + * of the array
> >>> + */
> >>> +struct rte_security_vec {
> >>> + struct iovec *vec;
> >>> + uint32_t num;
> >>> +};
> >>> +
> >> Just wondering if you want to change it to *in_vec and *out_vec, that
> >> will be helpful in future, if the out-of-place processing is required
> >> for CPU usecase as well?
> > I suppose this is doable, though right now we don't plan to support such model.
> They will come handy in future. I plan to use it in future and we can
> skip the API/ABI breakage, if the placeholder are present
> >
> >>> +/**
> >>> + * Processing bulk crypto workload with CPU
> >>> + *
> >>> + * @param instance security instance.
> >>> + * @param sess security session
> >>> + * @param buf array of buffer SGL vectors
> >>> + * @param iv array of IV pointers
> >>> + * @param aad array of AAD pointers
> >>> + * @param digest array of digest pointers
> >>> + * @param status array of status for the function to return
> >>> + * @param num number of elements in each array
> >>> + *
> >>> + */
> >>> +__rte_experimental
> >>> +void
> >>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
> >>> + struct rte_security_session *sess,
> >>> + struct rte_security_vec buf[], void *iv[], void *aad[],
> >>> + void *digest[], int status[], uint32_t num);
> >>> +
> >> Why not make the return as int, to indicate whether this API completely
> >> failed or processed or have some valid status to look into?
> > Good point, will change as suggested.
>
> I have another suggestions w.r.t iv, aad, digest etc. Why not put them
> in a structure, so that you will
>
> be able to add/remove the variable without breaking the API prototype.
Just to confirm, you are talking about something like:
struct rte_security_vec {
struct iovec *vec;
uint32_t num;
};
struct rte_security_sym_vec {
struct rte_security_vec buf;
void *iv;
void *aad;
void *digest;
};
rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
struct rte_security_session *sess, struct rte_security_sym_vec buf[],
int status[], uint32_t num);
?
We thought about such way, though for PMD it would be
more plausible to have same type of params grouped together,
i.e. void *in[], void *out[], void *digest[], ...
Another thing - above grouping wouldn't help to avoid ABI breakage,
in case we'll need to add new field into rte_security_sym_vec
(though it might help to avoid API breakage).
In theory other way is also possible:
struct rte_security_sym_vec {
struct rte_security_vec *buf;
void **iv;
void **aad;
void **digest;
};
rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
struct rte_security_session *sess, struct rte_security_sym_vec *buf,
int status[], uint32_t num);
And that might help for both ABI and API stability,
but it looks really weird that way (at least to me).
Also this API is experimental and I suppose needs to stay experimental for
few releases before we are sure nothing important is missing,
so probably API/ABI stability is not that high concern for it right now.
Konstantin
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO DMA map APIs
@ 2019-10-01 15:20 3% ` David Marchand
2019-10-02 4:53 0% ` Shahaf Shuler
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2019-10-01 15:20 UTC (permalink / raw)
To: Shahaf Shuler, anatoly.burakov, yskoh, thomas, ferruh.yigit,
nhorman, gaetan.rivet
Cc: dev
Hello Shahaf,
On 10/03/2019 09:28, Shahaf Shuler wrote:
> As those should be replaced by rte_dev_dma_map and rte_dev_dma_unmap
> APIs.
>
> Signed-off-by: Shahaf Shuler <shahafs@mellanox.com>
> ---
> doc/guides/prog_guide/env_abstraction_layer.rst | 2 +-
> doc/guides/rel_notes/deprecation.rst | 4 ++++
> 2 files changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guides/prog_guide/env_abstraction_layer.rst b/doc/guides/prog_guide/env_abstraction_layer.rst
> index 929d76dba7..ec2fe65523 100644
> --- a/doc/guides/prog_guide/env_abstraction_layer.rst
> +++ b/doc/guides/prog_guide/env_abstraction_layer.rst
> @@ -282,7 +282,7 @@ The expected workflow is as follows:
> - If IOVA table is not specified, IOVA addresses will be assumed to be
> unavailable
> - Other processes must attach to the memory area before they can use it
> -* Perform DMA mapping with ``rte_vfio_dma_map`` if needed
> +* Perform DMA mapping with ``rte_dev_dma_map`` if needed
> * Use the memory area in your application
> * If memory area is no longer needed, it can be unregistered
> - If the area was mapped for DMA, unmapping must be performed before
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 1b4fcb7e64..48ec4fee88 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -35,6 +35,10 @@ Deprecation Notices
>
> + ``rte_eal_devargs_type_count``
>
> +* vfio: removal of ``rte_vfio_dma_map`` and ``rte_vfio_dma_unmap`` APIs which
> + have been replaced with ``rte_dev_dma_map`` and ``rte_dev_dma_unmap``
> + functions. The due date for the removal targets DPDK 20.02.
> +
> * pci: Several exposed functions are misnamed.
> The following functions are deprecated starting from v17.11 and are replaced:
>
>
With the ABI freeze that is going to happen in 19.11, this can't happen
in 20.02.
What would work best from your pov?
I can't see any in-tree user of rte_vfio_dma_*map, do you know of users
of this api?
Thanks.
--
David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 14:42 3% ` Aaron Conole
@ 2019-10-01 15:15 3% ` Nipun Gupta
0 siblings, 0 replies; 200+ results
From: Nipun Gupta @ 2019-10-01 15:15 UTC (permalink / raw)
To: Aaron Conole
Cc: dev, jerinj, pbhagavatula, skori, Hemant Agrawal,
bruce.richardson, marko.kovacevic, orika, radu.nicolau,
tomasz.kantecki, harry.van.haaren, nikhil.rao
> -----Original Message-----
> From: Aaron Conole <aconole@redhat.com>
> Sent: Tuesday, October 1, 2019 8:12 PM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dev@dpdk.org; jerinj@marvell.com; pbhagavatula@marvell.com;
> skori@marvell.com; Hemant Agrawal <hemant.agrawal@nxp.com>;
> bruce.richardson@intel.com; marko.kovacevic@intel.com;
> orika@mellanox.com; radu.nicolau@intel.com; tomasz.kantecki@intel.com;
> harry.van.haaren@intel.com; nikhil.rao@intel.com
> Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> packets enqueue
>
> Nipun Gupta <nipun.gupta@nxp.com> writes:
>
> > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > Some drivers may support burst functionality only with the packets
> > having same destination device and queue.
> >
> > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be
> used
> > to indicate this so the underlying driver, for drivers to utilize
> > burst functionality appropriately.
> >
> > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > ---
>
> In addition to the ABI concerns (which I mirror), you also should
> compile test this patch. It currently doesn't build (for example, see a
> missed adapter_enqueue in
> examples/eventdev_pipeline/pipeline_worker_tx.c)
Thanks for letting me know. I missed compiling the example. Will fix in v2.
w.r.t. the ABI change, as API will freeze for 1 year post this we expect to get some
exception to deprecation process for 19.11.
>
> > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15 +++++++++++++-
> -
> > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > 10 files changed, 44 insertions(+), 18 deletions(-)
> >
> > diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-
> eventdev/test_pipeline_common.h
> > index 0440b9e29..6e73c6ab2 100644
> > --- a/app/test-eventdev/test_pipeline_common.h
> > +++ b/app/test-eventdev/test_pipeline_common.h
> > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t
> port,
> > struct rte_event * const ev)
> > {
> > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> > rte_pause();
> > }
> >
> > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const
> uint8_t port,
> > {
> > uint16_t enq;
> >
> > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
> > while (enq < nb_rx) {
> > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > - ev + enq, nb_rx - enq);
> > + ev + enq, nb_rx - enq, 0);
> > }
> > }
> >
> > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > index 192f9e1cf..a8c13e136 100644
> > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > @@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()``
> function.
> > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
> >
> > event.mbuf = m;
> > + eq_flags = 0;
> >
> > m->port = tx_port;
> > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> >
> > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> &event, 1);
> > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> &event, 1, eq_flags);
> > } else {
> >
> > event.queue_id = qid; /* event queue linked to adapter port
> */
> > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> b/drivers/event/octeontx/ssovf_evdev.h
> > index 0e622152c..1b156edab 100644
> > --- a/drivers/event/octeontx/ssovf_evdev.h
> > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws, uint8_t
> queue_id,
> > ssows_handle_event_t fn, void *arg);
> > void ssows_reset(struct ssows *ws);
> > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > - struct rte_event ev[], uint16_t nb_events);
> > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> > int ssovf_info(struct ssovf_info *info);
> > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > int test_eventdev_octeontx(void);
> > diff --git a/drivers/event/octeontx/ssovf_worker.c
> b/drivers/event/octeontx/ssovf_worker.c
> > index d940b5dd6..1d0467af3 100644
> > --- a/drivers/event/octeontx/ssovf_worker.c
> > +++ b/drivers/event/octeontx/ssovf_worker.c
> > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> >
> > uint16_t
> > sso_event_tx_adapter_enqueue(void *port,
> > - struct rte_event ev[], uint16_t nb_events)
> > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > {
> > uint16_t port_id;
> > uint16_t queue_id;
> > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > octeontx_dq_t *dq;
> >
> > RTE_SET_USED(nb_events);
> > + RTE_SET_USED(eq_flags);
> > switch (ev->sched_type) {
> > case SSO_SYNC_ORDERED:
> > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> b/drivers/event/octeontx2/otx2_evdev.h
> > index 5cd80e3b2..74b749a15 100644
> > --- a/drivers/event/octeontx2/otx2_evdev.h
> > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> >
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> rte_event ev[],\
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> >
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > #undef T
> > diff --git a/drivers/event/octeontx2/otx2_worker.c
> b/drivers/event/octeontx2/otx2_worker.c
> > index cd14cd3d2..100e21669 100644
> > --- a/drivers/event/octeontx2/otx2_worker.c
> > +++ b/drivers/event/octeontx2/otx2_worker.c
> > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port, const
> struct rte_event ev[],
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t __hot
> \
> > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[],
> \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws *ws = port; \
> > uint64_t cmd[sz]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags);
> \
> > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > }
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t __hot
> \
> > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct rte_event
> ev[],\
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws *ws = port; \
> > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags);
> \
> > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > NIX_TX_MULTI_SEG_F); \
> > }
> > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> b/drivers/event/octeontx2/otx2_worker_dual.c
> > index 37c274a54..c3e48da42 100644
> > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > uint16_t __hot
> \
> > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws_dual *ws = port; \
> > struct otx2_ssogws *vws = \
> > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ## name(void
> *port, \
> > uint64_t cmd[sz]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags);
> \
> > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > }
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > uint16_t __hot
> \
> > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws_dual *ws = port; \
> > struct otx2_ssogws *vws = \
> > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> name(void *port, \
> > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2];
> \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags);
> \
> > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > NIX_TX_MULTI_SEG_F); \
> > }
> > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > index c848261c4..98be77568 100644
> > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct
> rte_mbuf *pkt)
> > int
> > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> *event_port_id);
> >
> > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> > +/**< This flag is used when all the packets enqueued in the tx adapter are
> > + * destined for the same Ethernet device, queue pair.
> > + */
> > +
> > /**
> > * Enqueue a burst of events objects or an event object supplied in
> *rte_event*
> > * structure on an event device designated by its *dev_id* through the
> event
> > @@ -324,6 +329,10 @@
> rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> *event_port_id);
> > * The number of event objects to enqueue, typically number of
> > * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > * available for this port.
> > + * @param flags
> > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that
> all the packets
> > + * which are enqueued are destined for the same Ethernet device, queue
> pair.
> > *
> > * @return
> > * The number of event objects actually enqueued on the event device.
> The
> > @@ -343,7 +352,8 @@ static inline uint16_t
> > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > uint8_t port_id,
> > struct rte_event ev[],
> > - uint16_t nb_events)
> > + uint16_t nb_events,
> > + uint8_t flags)
> > {
> > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> >
> > @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t
> dev_id,
> > return 0;
> > }
> > #endif
> > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> nb_events);
> > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > + nb_events, flags);
> > }
> >
> > /**
> > diff --git a/lib/librte_eventdev/rte_eventdev.c
> b/lib/librte_eventdev/rte_eventdev.c
> > index f44c869cb..3bf9d7115 100644
> > --- a/lib/librte_eventdev/rte_eventdev.c
> > +++ b/lib/librte_eventdev/rte_eventdev.c
> > @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> > static uint16_t
> > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > __rte_unused struct rte_event ev[],
> > - __rte_unused uint16_t nb_events)
> > + __rte_unused uint16_t nb_events,
> > + __rte_unused uint8_t flags)
> > {
> > rte_errno = ENOTSUP;
> > return 0;
> > diff --git a/lib/librte_eventdev/rte_eventdev.h
> b/lib/librte_eventdev/rte_eventdev.h
> > index 5044a13d0..2a5643da3 100644
> > --- a/lib/librte_eventdev/rte_eventdev.h
> > +++ b/lib/librte_eventdev/rte_eventdev.h
> > @@ -1227,7 +1227,7 @@ typedef uint16_t
> (*event_dequeue_burst_t)(void *port, struct rte_event ev[],
> > /**< @internal Dequeue burst of events from port of a device */
> >
> > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > - struct rte_event ev[], uint16_t nb_events);
> > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > /**< @internal Enqueue burst of events on port of a device */
> >
> > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 14:20 3% ` Jerin Jacob
@ 2019-10-01 15:06 0% ` Nipun Gupta
2019-10-01 15:35 4% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Nipun Gupta @ 2019-10-01 15:06 UTC (permalink / raw)
To: Jerin Jacob
Cc: Jerin Jacob, dpdk-dev, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
> -----Original Message-----
> From: Jerin Jacob <jerinjacobk@gmail.com>
> Sent: Tuesday, October 1, 2019 7:50 PM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: Jerin Jacob <jerinj@marvell.com>; dpdk-dev <dev@dpdk.org>; Pavan
> Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> <tomasz.kantecki@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> packets enqueue
>
> On Tue, Oct 1, 2019 at 7:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > Sent: Tuesday, October 1, 2019 6:40 PM
> > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> > > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> destined
> > > packets enqueue
> > >
> > > On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com>
> wrote:
> > > >
> > > >
> > > >
> > > > > -----Original Message-----
> > > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > > Sent: Tuesday, October 1, 2019 1:14 PM
> > > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>;
> Pavan
> > > > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > > <skori@marvell.com>;
> > > > > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > > > > <bruce.richardson@intel.com>; Marko Kovacevic
> > > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>;
> Radu
> > > Nicolau
> > > > > <radu.nicolau@intel.com>; Tomasz Kantecki
> > > <tomasz.kantecki@intel.com>; Van
> > > > > Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > > destined
> > > > > packets enqueue
> > > > >
> > > > > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com>
> > > wrote:
> > > > > >
> > > > > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > > > > Some drivers may support burst functionality only with the packets
> > > > > > having same destination device and queue.
> > > > > >
> > > > > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST`
> can
> > > be used
> > > > > > to indicate this so the underlying driver, for drivers to utilize
> > > > > > burst functionality appropriately.
> > > > >
> > > > > I understand the cost of aggregating packets based on port and
> queue
> > > > > to make it burst.
> > > > > But, Could you share the use case where how do you want to use this
> > > > > flag? I see two possibilities in eventdev context.
> > > > > (Where dequeue can be from any ethdev port)
> > > > > a) The application does the aggregation. If so, what would the
> > > > > difference be in doing driver or application?
> > > > > b) We may use this flag when the system has only one port and one
> > > queue.
> > > > >
> > > > > Could you share how do you want to use this flag?
> > > >
> > > > I would say both the cases you mentioned. I prefer this to depend on
> the
> > > smartness of
> > > > the application, as it is aware of the number of eth devices/queues it is
> > > using.
> > > > This is the reason to avoid in the driver.
> > > >
> > > > A user can also use separate event ports for separate or a group of
> > > Ethernet
> > > > devices/queues, to create easy segregation.
> > >
> > > If it is specific to _very_ static configuration, you can assume all
> > > the events comes
> > > from a specific eventdev port, comes only from a specific ethdev port.
> >
> > Hi Jerin,
> >
> > If I understand correctly this assumption would be made in the driver?
> > But then applications like l2fwd-event will break.
>
> Yes. What I meant is a specific static configuration only this scheme can use.
>
>
> >
> > >
> > > >
> > > > Also the drawback of implementing in the driver, can be that when the
> > > events to
> > > > Separate devices and queues are so mixed up, that segregation does
> not
> > > make
> > > > sense, it shall be overhead for the driver to scan all the events.
> > >
> > > In the worst case, both, applications need to scan and driver need to
> > > iterate over
> > > all the events.
> >
> > Agree, this is what we want to avoid.
> >
> > >
> > >
> > > In generic l2fwd-eventdev applications etc, q0 will be connected p0 and
> p1
> > > etc.
> > > This flag will be zero.
> >
> > Okay.
> >
> > >
> > > But, If you think, there is a specific use case for it we can add this flag.
> > >
> > >
> > > >
> > > > A flag would help in providing the decision flexibility to the applications.
> > > >
> > > > >
> > > > > And another point is, tx adapter is NOT experimental now, We need
> > > > > depreciation notice for ABI change.
> > > > > If you share the exact use case, then we could think of adding a new
> > > > > symbol instead of breaking ABI and
> > > > > add it for next release.
> > > >
> > > > I have heard the discussion that we may get some exceptions to
> > > deprecation
> > > > process for 19.11 as the APIs will freeze of 1 year post it.
> > > > Anyway, if you have a better way with symbol, please suggest.
> > >
> > >
> > > One option could be (not as bad as changing the enqueue prototype) to
> > > add new field in struct rte_event_eth_tx_adapter_conf.
> > >
> > > Since this scheme can be used ONLY on the static configuration, adding
> > > a few fields
> > > for Tx adapter configuration would help.
> > > If that field is set you can choose dev->txa_enqueue light weight
> > > enqueue function
> > > if not, the driver can aggregate the buffers and send them.
> >
> > Thanks for suggesting this, we also thought of it, but would prefer having
> this as a
> > runtime option rather than static option.
> > We would not like to have one time configuration restriction.
>
> Not sure how it can be used in runtime. If q0 is connected p0 and p1 and then
> it flag has to be cleared. if q0 is only connected to p0 then we can
> use this scheme.
> So it is pretty much static in nature.
>
> How do you think, it can be used in runtime.
>
> If we think, If we are planning to use like below in application, it
> would be really bad
> in the worst case.(mbuf cache misses in-app and driver)
>
> In app:
> const port = event[0].mbuf.port;
> const queue = event[0].mbuf.queue;
> for (i = i; i < nb_events; i++) {
> if (port != event[i].mbuf.port || queue != event[i].mbuf.queue)
> break;
> }
> if (i == nb_events)
> flag = 1;
> else
> flag = 0;
>
In such case if cache misses are observed which is more than what sending burst
of traffic is in the applications use-case, the application shall simply not use the flag.
But again I think this is to be governed by the application which is the user of the
event device, on the basis on the configuration and the memory footprint/utilization;
and more than that its performance benchmarking.
> more over the static scheme does not make any change in other drivers.
> If you have the usecase for the dynamic scheme then let us know then
> we add dynamic flag breaking the ABI.
I understand your concern that this shall not be valid on a general cases.
There are certain use-case (NXP internal) of DPDK event which have separate
event ports/cores dedicated for certain tasks - and can use the burst functionality
for performance according to the event ports which are used. Not having this at
runtime will limit the flexibility for such applications.
Regards,
Nipun
>
>
> >
> > >
> > >
> > >
> > > >
> > > > >
> > > > >
> > > > >
> > > > >
> > > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > > ---
> > > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > > +++++++++++++--
> > > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > > >
> > > > > > diff --git a/app/test-eventdev/test_pipeline_common.h
> b/app/test-
> > > > > eventdev/test_pipeline_common.h
> > > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const
> > > uint8_t
> > > > > port,
> > > > > > struct rte_event * const ev)
> > > > > > {
> > > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1,
> 0))
> > > > > > rte_pause();
> > > > > > }
> > > > > >
> > > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t
> dev,
> > > const
> > > > > uint8_t port,
> > > > > > {
> > > > > > uint16_t enq;
> > > > > >
> > > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> nb_rx);
> > > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev,
> nb_rx,
> > > 0);
> > > > > > while (enq < nb_rx) {
> > > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > > - ev + enq, nb_rx - enq);
> > > > > > + ev + enq, nb_rx - enq, 0);
> > > > > > }
> > > > > > }
> > > > > >
> > > > > > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > index 192f9e1cf..a8c13e136 100644
> > > > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > > @@ -137,11 +137,12 @@ should use the
> > > ``rte_event_enqueue_burst()``
> > > > > function.
> > > > > > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT)
> {
> > > > > >
> > > > > > event.mbuf = m;
> > > > > > + eq_flags = 0;
> > > > > >
> > > > > > m->port = tx_port;
> > > > > > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> > > > > >
> > > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> &event,
> > > 1);
> > > > > > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > > &event, 1,
> > > > > eq_flags);
> > > > > > } else {
> > > > > >
> > > > > > event.queue_id = qid; /* event queue linked to adapter
> port */
> > > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > index 0e622152c..1b156edab 100644
> > > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws,
> > > uint8_t
> > > > > queue_id,
> > > > > > ssows_handle_event_t fn, void *arg);
> > > > > > void ssows_reset(struct ssows *ws);
> > > > > > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t
> eq_flags);
> > > > > > int ssovf_info(struct ssovf_info *info);
> > > > > > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > > > > int test_eventdev_octeontx(void);
> > > > > > diff --git a/drivers/event/octeontx/ssovf_worker.c
> > > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > > index d940b5dd6..1d0467af3 100644
> > > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > > >
> > > > > > uint16_t
> > > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > > > > > {
> > > > > > uint16_t port_id;
> > > > > > uint16_t queue_id;
> > > > > > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > > > > > octeontx_dq_t *dq;
> > > > > >
> > > > > > RTE_SET_USED(nb_events);
> > > > > > + RTE_SET_USED(eq_flags);
> > > > > > switch (ev->sched_type) {
> > > > > > case SSO_SYNC_ORDERED:
> > > > > > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > > > > > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> > > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > index 5cd80e3b2..74b749a15 100644
> > > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > >
> > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > > rte_event
> > > > > ev[],\
> > > > > > - uint16_t nb_events); \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags); \
> > > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > > \
> > > > > > struct rte_event ev[], \
> > > > > > - uint16_t nb_events); \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags); \
> > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > > \
> > > > > > struct rte_event ev[], \
> > > > > > - uint16_t nb_events); \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags); \
> > > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> *port,
> > > > > \
> > > > > > struct rte_event ev[], \
> > > > > > - uint16_t nb_events); \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags); \
> > > > > >
> > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > #undef T
> > > > > > diff --git a/drivers/event/octeontx2/otx2_worker.c
> > > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > > index cd14cd3d2..100e21669 100644
> > > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port,
> > > const
> > > > > struct rte_event ev[],
> > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > uint16_t __hot \
> > > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> > > ev[], \
> > > > > > - uint16_t nb_events) \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags) \
> > > > > > { \
> > > > > > struct otx2_ssogws *ws = port; \
> > > > > > uint64_t cmd[sz]; \
> > > > > > \
> > > > > > RTE_SET_USED(nb_events); \
> > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > > > }
> > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > > uint16_t __hot \
> > > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> > > rte_event ev[],\
> > > > > > - uint16_t nb_events) \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags) \
> > > > > > { \
> > > > > > struct otx2_ssogws *ws = port; \
> > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > > \
> > > > > > RTE_SET_USED(nb_events); \
> > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > }
> > > > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > index 37c274a54..c3e48da42 100644
> > > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > uint16_t __hot \
> > > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > > > > struct rte_event ev[], \
> > > > > > - uint16_t nb_events) \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags) \
> > > > > > { \
> > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > struct otx2_ssogws *vws = \
> > > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > > name(void *port,
> > > > > \
> > > > > > uint64_t cmd[sz]; \
> > > > > > \
> > > > > > RTE_SET_USED(nb_events); \
> > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > > > }
> > > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > > uint16_t __hot \
> > > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> \
> > > > > > struct rte_event ev[], \
> > > > > > - uint16_t nb_events) \
> > > > > > + uint16_t nb_events, \
> > > > > > + uint8_t eq_flags) \
> > > > > > { \
> > > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > > struct otx2_ssogws *vws = \
> > > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > > name(void
> > > > > *port, \
> > > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > > \
> > > > > > RTE_SET_USED(nb_events); \
> > > > > > + RTE_SET_USED(eq_flags); \
> > > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > > > NIX_TX_MULTI_SEG_F); \
> > > > > > }
> > > > > > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > index c848261c4..98be77568 100644
> > > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct
> > > rte_mbuf
> > > > > *pkt)
> > > > > > int
> > > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> > > > > *event_port_id);
> > > > > >
> > > > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> 0x1
> > > > > > +/**< This flag is used when all the packets enqueued in the tx
> adapter
> > > are
> > > > > > + * destined for the same Ethernet device, queue pair.
> > > > > > + */
> > > > > > +
> > > > > > /**
> > > > > > * Enqueue a burst of events objects or an event object supplied in
> > > > > *rte_event*
> > > > > > * structure on an event device designated by its *dev_id* through
> > > the event
> > > > > > @@ -324,6 +329,10 @@
> > > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > > id, uint8_t *event_port_id);
> > > > > > * The number of event objects to enqueue, typically number of
> > > > > > *
> rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > > * available for this port.
> > > > > > + * @param flags
> > > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST
> signifies
> > > that all
> > > > > the packets
> > > > > > + * which are enqueued are destined for the same Ethernet device,
> > > queue pair.
> > > > > > *
> > > > > > * @return
> > > > > > * The number of event objects actually enqueued on the event
> > > device. The
> > > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > > uint8_t port_id,
> > > > > > struct rte_event ev[],
> > > > > > - uint16_t nb_events)
> > > > > > + uint16_t nb_events,
> > > > > > + uint8_t flags)
> > > > > > {
> > > > > > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> > > > > >
> > > > > > @@ -359,7 +369,8 @@
> rte_event_eth_tx_adapter_enqueue(uint8_t
> > > dev_id,
> > > > > > return 0;
> > > > > > }
> > > > > > #endif
> > > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > nb_events);
> > > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > > + nb_events, flags);
> > > > > > }
> > > > > >
> > > > > > /**
> > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > > index f44c869cb..3bf9d7115 100644
> > > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > > @@ -1324,7 +1324,8 @@
> rte_eventdev_find_free_device_index(void)
> > > > > > static uint16_t
> > > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > > __rte_unused struct rte_event ev[],
> > > > > > - __rte_unused uint16_t nb_events)
> > > > > > + __rte_unused uint16_t nb_events,
> > > > > > + __rte_unused uint8_t flags)
> > > > > > {
> > > > > > rte_errno = ENOTSUP;
> > > > > > return 0;
> > > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > > index 5044a13d0..2a5643da3 100644
> > > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > > (*event_dequeue_burst_t)(void
> > > > > *port, struct rte_event ev[],
> > > > > > /**< @internal Dequeue burst of events from port of a device */
> > > > > >
> > > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > > > > > /**< @internal Enqueue burst of events on port of a device */
> > > > > >
> > > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > > --
> > > > > > 2.17.1
> > > > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-09-30 13:43 0% ` Akhil Goyal
@ 2019-10-01 14:49 0% ` Ananyev, Konstantin
2019-10-03 13:24 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-01 14:49 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon'
Cc: Zhang, Roy Fan, Doherty, Declan, 'Anoob Joseph'
Hi Akhil,
> > > > > > > > > > > > > This action type allows the burst of symmetric crypto
> > workload
> > > > using
> > > > > > > the
> > > > > > > > > > > same
> > > > > > > > > > > > > algorithm, key, and direction being processed by CPU cycles
> > > > > > > > > synchronously.
> > > > > > > > > > > > > This flexible action type does not require external hardware
> > > > > > > involvement,
> > > > > > > > > > > > > having the crypto workload processed synchronously, and is
> > > > more
> > > > > > > > > > > performant
> > > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on removed
> > > > "async
> > > > > > > > > mode
> > > > > > > > > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > > > > > > > > >
> > > > > > > > > > > > Does that mean application will not call the
> > > > cryptodev_enqueue_burst
> > > > > > > and
> > > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > > >
> > > > > > > > > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > > >
> > > > > > > > > > > > It would be a new API something like process_packets and it
> > will
> > > > have
> > > > > > > the
> > > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > > >
> > > > > > > > > > > Yes, though the plan is that API will operate on raw data buffers,
> > > > not
> > > > > > > mbufs.
> > > > > > > > > > >
> > > > > > > > > > > >
> > > > > > > > > > > > I still do not understand why we cannot do with the
> > conventional
> > > > > > > crypto lib
> > > > > > > > > > > only.
> > > > > > > > > > > > As far as I can understand, you are not doing any protocol
> > > > processing
> > > > > > > or
> > > > > > > > > any
> > > > > > > > > > > value add
> > > > > > > > > > > > To the crypto processing. IMO, you just need a synchronous
> > > > crypto
> > > > > > > > > processing
> > > > > > > > > > > API which
> > > > > > > > > > > > Can be defined in cryptodev, you don't need to re-create a
> > crypto
> > > > > > > session
> > > > > > > > > in
> > > > > > > > > > > the name of
> > > > > > > > > > > > Security session in the driver just to do a synchronous
> > processing.
> > > > > > > > > > >
> > > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > > The main reason is that would require disruptive changes in
> > existing
> > > > > > > > > cryptodev
> > > > > > > > > > > API
> > > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need
> > > > some
> > > > > > > extra
> > > > > > > > > > > information
> > > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > > (cipher offset from the start of the buffer, might be something
> > extra
> > > > in
> > > > > > > > > future).
> > > > > > > > > >
> > > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > > >
> > > > > > > > > fill/read (+ alloc/free) is one of the main things that slowdown
> > current
> > > > > > > crypto-op
> > > > > > > > > approach.
> > > > > > > > > That's why the general idea - have all data that wouldn't change
> > from
> > > > packet
> > > > > > > to
> > > > > > > > > packet
> > > > > > > > > included into the session and setup it once at session_init().
> > > > > > > >
> > > > > > > > I agree that you cannot use crypto-op.
> > > > > > > > You can have the new API in crypto.
> > > > > > > > As per the current patch, you only need cipher_offset which you can
> > have
> > > > it as
> > > > > > > a parameter until
> > > > > > > > You get it approved in the crypto xform. I believe it will be beneficial
> > in
> > > > case of
> > > > > > > other crypto cases as well.
> > > > > > > > We can have cipher offset at both places(crypto-op and
> > cipher_xform). It
> > > > will
> > > > > > > give flexibility to the user to
> > > > > > > > override it.
> > > > > > >
> > > > > > > After having another thought on your proposal:
> > > > > > > Probably we can introduce new rte_crypto_sym_xform_types for CPU
> > > > related
> > > > > > > stuff here?
> > > > > >
> > > > > > I also thought of adding new xforms, but that wont serve the purpose for
> > > > may be all the cases.
> > > > > > You would be needing all information currently available in the current
> > > > xforms.
> > > > > > So if you are adding new fields in the new xform, the size will be more
> > than
> > > > that of the union of xforms.
> > > > > > ABI breakage would still be there.
> > > > > >
> > > > > > If you think a valid compression of the AEAD xform can be done, then
> > that
> > > > can be done for each of the
> > > > > > Xforms and we can have a solution to this issue.
> > > > >
> > > > > I think that we can re-use iv.offset for our purposes (for crypto offset).
> > > > > So for now we can make that path work without any ABI breakage.
> > > > > Fan, please feel free to correct me here, if I missed something.
> > > > > If in future we would need to add some extra information it might
> > > > > require ABI breakage, though by now I don't envision anything particular to
> > > > add.
> > > > > Anyway, if there is no objection to go that way, we can try to make
> > > > > these changes for v2.
> > > > >
> > > >
> > > > Actually, after looking at it more deeply it appears not that easy as I thought
> > it
> > > > would be :)
> > > > Below is a very draft version of proposed API additions.
> > > > I think it avoids ABI breakages right now and provides enough flexibility for
> > > > future extensions (if any).
> > > > For now, it doesn't address your comments about naming conventions
> > (_CPU_
> > > > vs _SYNC_) , etc.
> > > > but I suppose is comprehensive enough to provide a main idea beyond it.
> > > > Akhil and other interested parties, please try to review and provide feedback
> > > > ASAP,
> > > > as related changes would take some time and we still like to hit 19.11
> > deadline.
> > > > Konstantin
> > > >
> > > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > index bc8da2466..c03069e23 100644
> > > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > > *
> > > > * This structure contains data relating to Cipher (Encryption and Decryption)
> > > > * use to create a session.
> > > > + * Actually I was wrong saying that we don't have free space inside xforms.
> > > > + * Making key struct packed (see below) allow us to regain 6B that could be
> > > > + * used for future extensions.
> > > > */
> > > > struct rte_crypto_cipher_xform {
> > > > enum rte_crypto_cipher_operation op;
> > > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > > struct {
> > > > const uint8_t *data; /**< pointer to key data */
> > > > uint16_t length; /**< key length in bytes */
> > > > - } key;
> > > > + } __attribute__((__packed__)) key;
> > > > +
> > > > + /**
> > > > + * offset for cipher to start within user provided data buffer.
> > > > + * Fan suggested another (and less space consuming way) -
> > > > + * reuse iv.offset space below, by changing:
> > > > + * struct {uint16_t offset, length;} iv;
> > > > + * to uunamed union:
> > > > + * union {
> > > > + * struct {uint16_t offset, length;} iv;
> > > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > > + * };
> > > > + * Both approaches seems ok to me in general.
> > >
> > > No strong opinions here. OK with this one.
> > >
> > > > + * Comments/suggestions are welcome.
> > > > + */
> > > > + uint16_t offset;
> >
> > After another thought - it is probably a bit better to have offset as a separate
> > field.
> > In that case we can use the same xforms to create both type of sessions.
> ok
> >
> > > > +
> > > > + uint8_t reserved1[4];
> > > > +
> > > > /**< Cipher key
> > > > *
> > > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation, key.data
> > will
> > > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > > struct {
> > > > const uint8_t *data; /**< pointer to key data */
> > > > uint16_t length; /**< key length in bytes */
> > > > - } key;
> > > > + } __attribute__((__packed__)) key;
> > > > /**< Authentication key data.
> > > > * The authentication key length MUST be less than or equal to the
> > > > * block size of the algorithm. It is the callers responsibility to
> > > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > > * (for example RFC 2104, FIPS 198a).
> > > > */
> > > >
> > > > + uint8_t reserved1[6];
> > > > +
> > > > struct {
> > > > uint16_t offset;
> > > > /**< Starting point for Initialisation Vector or Counter,
> > > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > > struct {
> > > > const uint8_t *data; /**< pointer to key data */
> > > > uint16_t length; /**< key length in bytes */
> > > > - } key;
> > > > + } __attribute__((__packed__)) key;
> > > > +
> > > > + /** offset for cipher to start within data buffer */
> > > > + uint16_t cipher_offset;
> > > > +
> > > > + uint8_t reserved1[4];
> > > >
> > > > struct {
> > > > uint16_t offset;
> > > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > > index e175b838c..c0c7bfed7 100644
> > > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > > @@ -1272,6 +1272,101 @@ void *
> > > > rte_cryptodev_sym_session_get_user_data(
> > > > struct rte_cryptodev_sym_session *sess);
> > > >
> > > > +/*
> > > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > > + * introduce an extentsion to it via new fully opaque
> > > > + * struct rte_crypto_cpu_sym_session and additional related API.
> > >
> > >
> > > What all things do we need to squeeze?
> > > In this proposal I do not see the new struct cpu_sym_session defined here.
> >
> > The plan is to have it totally opaque to the user, i.e. just:
> > struct rte_crypto_cpu_sym_session;
> > in public header files.
> >
> > > I believe you will have same lib API/struct for cpu_sym_session and
> > sym_session.
> >
> > I thought about such way, but there are few things that looks clumsy to me:
> > 1. Right now there is no 'type' (or so) field inside rte_cryptodev_sym_session,
> > so it is not possible to easy distinguish what session do you have: lksd_sym or
> > cpu_sym.
> > In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we can add
> > some extra field
> > here, but in that case we wouldn't be able to use the same xform for both
> > lksd_sym or cpu_sym
> > (which seems really plausible thing for me).
> > 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary for
> > rte_crypto_cpu_sym_session:
> > sess_data[], opaque_data, user_data, nb_drivers.
> > All that consumes space, that could be used somewhere else instead.
> > 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> > breakages I can't foresee right now.
> > From other side - if we'll add new functions/structs for cpu_sym_session we can
> > mark it
> > and keep it for some time as experimental, so further changes (if needed) would
> > still be possible.
> >
>
> OK let us assume that you have a separate structure. But I have a few queries:
> 1. how can multiple drivers use a same session
As a short answer: they can't.
It is pretty much the same approach as with rte_security - each device needs to create/init its own session.
So upper layer would need to maintain its own array (or so) for such case.
Though the question is why would you like to have same session over multiple SW backed devices?
As it would be anyway just a synchronous function call that will be executed on the same cpu.
> 2. Can somebody use the scheduler pmd for scheduling the different type of payloads for the same session?
In theory yes.
Though for that scheduler pmd should have inside it's rte_crypto_cpu_sym_session an array of pointers to
the underlying devices sessions.
>
> With your proposal the APIs would be very specific to your use case only.
Yes in some way.
I consider that API specific for SW backed crypto PMDs.
I can hardly see how any 'real HW' PMDs (lksd-none, lksd-proto) will benefit from it.
Current crypto-op API is very much HW oriented.
Which is ok, that's for it was intended for, but I think we also need one that would be designed
for SW backed implementation in mind.
> When you would add more functionality to this sync API/struct, it will end up being the same API/struct.
>
> Let us see how close/ far we are from the existing APIs when the actual implementation is done.
>
> > > I am not sure if that would be needed.
> > > It would be internal to the driver that if synchronous processing is
> > supported(from feature flag) and
> > > Have relevant fields in xform(the newly added ones which are packed as per
> > your suggestions) set,
> > > It will create that type of session.
> > >
> > >
> > > > + * Main points:
> > > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > > + * new sync API is new one and probably would require extra changes.
> > > > + * Having it as a new one allows to mark it as experimental, without
> > > > + * affecting existing one.
> > > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > > + * to the PMD writers and again allows to avoid ABI breakages in future.
> > > > + * - process() function per set of xforms
> > > > + * allows to expose different process() functions for different
> > > > + * xform combinations. PMD writer can decide, does he wants to
> > > > + * push all supported algorithms into one process() function,
> > > > + * or spread it across several ones.
> > > > + * I.E. More flexibility for PMD writer.
> > >
> > > Which process function should be chosen is internal to PMD, how would that
> > info
> > > be visible to the application or the library. These will get stored in the session
> > private
> > > data. It would be upto the PMD writer, to store the per session process
> > function in
> > > the session private data.
> > >
> > > Process function would be a dev ops just like enc/deq operations and it should
> > call
> > > The respective process API stored in the session private data.
> >
> > That model (via devops) is possible, but has several drawbacks from my
> > perspective:
> >
> > 1. It means we'll need to pass dev_id as a parameter to process() function.
> > Though in fact dev_id is not a relevant information for us here
> > (all we need is pointer to the session and pointer to the fuction to call)
> > and I tried to avoid using it in data-path functions for that API.
>
> You have a single vdev, but someone may have multiple vdevs for each thread, or may
> Have same dev with multiple queues for each core.
That's fine. As I said above it is a SW backed implementation.
Each session has to be a separate entity that contains all necessary information
(keys, alg/mode info, etc.) to process input buffers.
Plus we need the actual function pointer to call.
I just don't see what for we need a dev_id in that situation.
Again, here we don't need care about queues and their pinning to cores.
If let say someone would like to process buffers from the same IPsec SA on 2
different cores in parallel, he can just create 2 sessions for the same xform,
give one to thread #1 and second to thread #2.
After that both threads are free to call process(this_thread_ses, ...) at will.
>
> > 2. As you pointed in that case it will be just one process() function per device.
> > So if PMD would like to have several process() functions for different type of
> > sessions
> > (let say one per alg) first thing it has to do inside it's process() - read session data
> > and
> > based on that, do a jump/call to particular internal sub-routine.
> > Something like:
> > driver_id = get_pmd_driver_id();
> > priv_ses = ses->sess_data[driver_id];
> > Then either:
> > switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> > OR
> > priv_ses->process(priv_sess, ...);
> >
> > to select and call the proper function.
> > Looks like totally unnecessary overhead to me.
> > Though if we'll have ability to query/extract some sort session_ops based on the
> > xform -
> > we can avoid this extra de-refererence+jump/call thing.
>
> What is the issue in the priv_ses->process(); approach?
Nothing at all.
What I am saying that schema with dev_ops
dev[dev_id]->dev_ops.process(ses->priv_ses[driver_id], ...)
|
|-> priv_ses->process(...)
Has bigger overhead then just:
process(ses,...);
So what for to introduce extra-level of indirection here?
> I don't understand what are you saving by not doing this.
> In any case you would need to identify which session correspond to which process().
Yes, sure, but I think we can make user to store information that relationship,
in a way he likes: store process() pointer for each session, or group sessions
that share the same process() somehow, or...
> For that you would be doing it somewhere in your data path.
Why at data-path?
Only once at session creation/initialization time.
Or might be even once per group of sessions.
>
> >
> > >
> > > I am not sure if you would need a new session init API for this as nothing would
> > be visible to
> > > the app or lib.
> > >
> > > > + * - Not storing process() pointer inside the session -
> > > > + * Allows user to choose does he want to store a process() pointer
> > > > + * per session, or per group of sessions for that device that share
> > > > + * the same input xforms. I.E. extra flexibility for the user,
> > > > + * plus allows us to keep cpu_sym_session totally opaque, see above.
> > >
> > > If multiple sessions need to be processed via the same process function,
> > > PMD would save the same process in all the sessions, I don't think there would
> > > be any perf overhead with that.
> >
> > I think it would, see above.
> >
> > >
> > > > + * Sketched usage model:
> > > > + * ....
> > > > + * /* control path, alloc/init session */
> > > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > > + * rte_crypto_cpu_sym_process_t process =
> > > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > > + * ...
> > > > + * /* data-path*/
> > > > + * process(ses, ....);
> > > > + * ....
> > > > + * /* control path, termiante/free session */
> > > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > > + */
> > > > +
> > > > +/**
> > > > + * vector structure, contains pointer to vector array and the length
> > > > + * of the array
> > > > + */
> > > > +struct rte_crypto_vec {
> > > > + struct iovec *vec;
> > > > + uint32_t num;
> > > > +};
> > > > +
> > > > +/*
> > > > + * Data-path bulk process crypto function.
> > > > + */
> > > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > > + void *digest[], int status[], uint32_t num);
> > > > +/*
> > > > + * for given device return process function specific to input xforms
> > > > + * on error - return NULL and set rte_errno value.
> > > > + * Note that for same input xfroms for the same device should return
> > > > + * the same process function.
> > > > + */
> > > > +__rte_experimental
> > > > +rte_crypto_cpu_sym_process_t
> > > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > +/*
> > > > + * Return required session size in bytes for given set of xforms.
> > > > + * if xforms == NULL, then return the max possible session size,
> > > > + * that would fit session for any supported by the device algorithm.
> > > > + * if CPU mode is not supported at all, or requeted in xform
> > > > + * algorithm is not supported, then return -ENOTSUP.
> > > > + */
> > > > +__rte_experimental
> > > > +int
> > > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > +/*
> > > > + * Initialize session.
> > > > + * It is caller responsibility to allocate enough space for it.
> > > > + * See rte_crypto_cpu_sym_session_size above.
> > > > + */
> > > > +__rte_experimental
> > > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > +__rte_experimental
> > > > +void
> > > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > +
> > > > +
> > > > #ifdef __cplusplus
> > > > }
> > > > #endif
> > > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > index defe05ea0..ed7e63fab 100644
> > > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > > @@ -310,6 +310,20 @@ typedef void
> > (*cryptodev_sym_free_session_t)(struct
> > > > rte_cryptodev *dev,
> > > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
> > > > struct rte_cryptodev_asym_session *sess);
> > > >
> > > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct rte_cryptodev
> > *dev,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct rte_cryptodev
> > *dev,
> > > > + struct rte_crypto_cpu_sym_session *sess,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct rte_cryptodev
> > *dev,
> > > > + struct rte_crypto_cpu_sym_session *sess);
> > > > +
> > > > +typedef rte_crypto_cpu_sym_process_t
> > (*cryptodev_cpu_sym_session_func_t)
> > > > (
> > > > + struct rte_cryptodev *dev,
> > > > + const struct rte_crypto_sym_xform *xforms);
> > > > +
> > > > /** Crypto device operations function pointer table */
> > > > struct rte_cryptodev_ops {
> > > > cryptodev_configure_t dev_configure; /**< Configure device. */
> > > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > > /**< Clear a Crypto sessions private data. */
> > > > cryptodev_asym_free_session_t asym_session_clear;
> > > > /**< Clear a Crypto sessions private data. */
> > > > +
> > > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > > };
> > > >
> > > >
> > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 7:44 4% ` Jerin Jacob
@ 2019-10-01 14:42 3% ` Aaron Conole
2019-10-01 15:15 3% ` Nipun Gupta
` (3 subsequent siblings)
5 siblings, 1 reply; 200+ results
From: Aaron Conole @ 2019-10-01 14:42 UTC (permalink / raw)
To: Nipun Gupta
Cc: dev, jerinj, pbhagavatula, skori, hemant.agrawal,
bruce.richardson, marko.kovacevic, orika, radu.nicolau,
tomasz.kantecki, harry.van.haaren, nikhil.rao
Nipun Gupta <nipun.gupta@nxp.com> writes:
> This patch introduces a `flag` in the Eth TX adapter enqueue API.
> Some drivers may support burst functionality only with the packets
> having same destination device and queue.
>
> The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> to indicate this so the underlying driver, for drivers to utilize
> burst functionality appropriately.
>
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
In addition to the ABI concerns (which I mirror), you also should
compile test this patch. It currently doesn't build (for example, see a
missed adapter_enqueue in
examples/eventdev_pipeline/pipeline_worker_tx.c)
> app/test-eventdev/test_pipeline_common.h | 6 +++---
> .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> drivers/event/octeontx/ssovf_evdev.h | 2 +-
> drivers/event/octeontx/ssovf_worker.c | 3 ++-
> drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15 +++++++++++++--
> lib/librte_eventdev/rte_eventdev.c | 3 ++-
> lib/librte_eventdev/rte_eventdev.h | 2 +-
> 10 files changed, 44 insertions(+), 18 deletions(-)
>
> diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
> index 0440b9e29..6e73c6ab2 100644
> --- a/app/test-eventdev/test_pipeline_common.h
> +++ b/app/test-eventdev/test_pipeline_common.h
> @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t port,
> struct rte_event * const ev)
> {
> rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> rte_pause();
> }
>
> @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
> {
> uint16_t enq;
>
> - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
> while (enq < nb_rx) {
> enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> - ev + enq, nb_rx - enq);
> + ev + enq, nb_rx - enq, 0);
> }
> }
>
> diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> index 192f9e1cf..a8c13e136 100644
> --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> @@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()`` function.
> if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
>
> event.mbuf = m;
> + eq_flags = 0;
>
> m->port = tx_port;
> rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
>
> - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
> + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags);
> } else {
>
> event.queue_id = qid; /* event queue linked to adapter port */
> diff --git a/drivers/event/octeontx/ssovf_evdev.h b/drivers/event/octeontx/ssovf_evdev.h
> index 0e622152c..1b156edab 100644
> --- a/drivers/event/octeontx/ssovf_evdev.h
> +++ b/drivers/event/octeontx/ssovf_evdev.h
> @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws, uint8_t queue_id,
> ssows_handle_event_t fn, void *arg);
> void ssows_reset(struct ssows *ws);
> uint16_t sso_event_tx_adapter_enqueue(void *port,
> - struct rte_event ev[], uint16_t nb_events);
> + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> int ssovf_info(struct ssovf_info *info);
> void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> int test_eventdev_octeontx(void);
> diff --git a/drivers/event/octeontx/ssovf_worker.c b/drivers/event/octeontx/ssovf_worker.c
> index d940b5dd6..1d0467af3 100644
> --- a/drivers/event/octeontx/ssovf_worker.c
> +++ b/drivers/event/octeontx/ssovf_worker.c
> @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
>
> uint16_t
> sso_event_tx_adapter_enqueue(void *port,
> - struct rte_event ev[], uint16_t nb_events)
> + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> {
> uint16_t port_id;
> uint16_t queue_id;
> @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> octeontx_dq_t *dq;
>
> RTE_SET_USED(nb_events);
> + RTE_SET_USED(eq_flags);
> switch (ev->sched_type) {
> case SSO_SYNC_ORDERED:
> ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> diff --git a/drivers/event/octeontx2/otx2_evdev.h b/drivers/event/octeontx2/otx2_evdev.h
> index 5cd80e3b2..74b749a15 100644
> --- a/drivers/event/octeontx2/otx2_evdev.h
> +++ b/drivers/event/octeontx2/otx2_evdev.h
> @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
>
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[],\
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
>
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> #undef T
> diff --git a/drivers/event/octeontx2/otx2_worker.c b/drivers/event/octeontx2/otx2_worker.c
> index cd14cd3d2..100e21669 100644
> --- a/drivers/event/octeontx2/otx2_worker.c
> +++ b/drivers/event/octeontx2/otx2_worker.c
> @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port, const struct rte_event ev[],
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t __hot \
> otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws *ws = port; \
> uint64_t cmd[sz]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> }
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t __hot \
> otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct rte_event ev[],\
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws *ws = port; \
> uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> NIX_TX_MULTI_SEG_F); \
> }
> diff --git a/drivers/event/octeontx2/otx2_worker_dual.c b/drivers/event/octeontx2/otx2_worker_dual.c
> index 37c274a54..c3e48da42 100644
> --- a/drivers/event/octeontx2/otx2_worker_dual.c
> +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> uint16_t __hot \
> otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws_dual *ws = port; \
> struct otx2_ssogws *vws = \
> @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> uint64_t cmd[sz]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> }
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> uint16_t __hot \
> otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws_dual *ws = port; \
> struct otx2_ssogws *vws = \
> @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> NIX_TX_MULTI_SEG_F); \
> }
> diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> index c848261c4..98be77568 100644
> --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
> int
> rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
>
> +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> +/**< This flag is used when all the packets enqueued in the tx adapter are
> + * destined for the same Ethernet device, queue pair.
> + */
> +
> /**
> * Enqueue a burst of events objects or an event object supplied in *rte_event*
> * structure on an event device designated by its *dev_id* through the event
> @@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
> * The number of event objects to enqueue, typically number of
> * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> * available for this port.
> + * @param flags
> + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
> + * which are enqueued are destined for the same Ethernet device, queue pair.
> *
> * @return
> * The number of event objects actually enqueued on the event device. The
> @@ -343,7 +352,8 @@ static inline uint16_t
> rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> uint8_t port_id,
> struct rte_event ev[],
> - uint16_t nb_events)
> + uint16_t nb_events,
> + uint8_t flags)
> {
> const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
>
> @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> return 0;
> }
> #endif
> - return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
> + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> + nb_events, flags);
> }
>
> /**
> diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
> index f44c869cb..3bf9d7115 100644
> --- a/lib/librte_eventdev/rte_eventdev.c
> +++ b/lib/librte_eventdev/rte_eventdev.c
> @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> static uint16_t
> rte_event_tx_adapter_enqueue(__rte_unused void *port,
> __rte_unused struct rte_event ev[],
> - __rte_unused uint16_t nb_events)
> + __rte_unused uint16_t nb_events,
> + __rte_unused uint8_t flags)
> {
> rte_errno = ENOTSUP;
> return 0;
> diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
> index 5044a13d0..2a5643da3 100644
> --- a/lib/librte_eventdev/rte_eventdev.h
> +++ b/lib/librte_eventdev/rte_eventdev.h
> @@ -1227,7 +1227,7 @@ typedef uint16_t (*event_dequeue_burst_t)(void *port, struct rte_event ev[],
> /**< @internal Dequeue burst of events from port of a device */
>
> typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> - struct rte_event ev[], uint16_t nb_events);
> + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> /**< @internal Enqueue burst of events on port of a device */
>
> #define RTE_EVENTDEV_NAME_MAX_LEN (64)
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 14:02 0% ` Nipun Gupta
@ 2019-10-01 14:20 3% ` Jerin Jacob
2019-10-01 15:06 0% ` Nipun Gupta
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-01 14:20 UTC (permalink / raw)
To: Nipun Gupta
Cc: Jerin Jacob, dpdk-dev, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
On Tue, Oct 1, 2019 at 7:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Jerin Jacob <jerinjacobk@gmail.com>
> > Sent: Tuesday, October 1, 2019 6:40 PM
> > To: Nipun Gupta <nipun.gupta@nxp.com>
> > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> > Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> > <tomasz.kantecki@intel.com>; Van Haaren, Harry
> > <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> > packets enqueue
> >
> > On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > > Sent: Tuesday, October 1, 2019 1:14 PM
> > > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> > <skori@marvell.com>;
> > > > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > > > <bruce.richardson@intel.com>; Marko Kovacevic
> > > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> > Nicolau
> > > > <radu.nicolau@intel.com>; Tomasz Kantecki
> > <tomasz.kantecki@intel.com>; Van
> > > > Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> > destined
> > > > packets enqueue
> > > >
> > > > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com>
> > wrote:
> > > > >
> > > > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > > > Some drivers may support burst functionality only with the packets
> > > > > having same destination device and queue.
> > > > >
> > > > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can
> > be used
> > > > > to indicate this so the underlying driver, for drivers to utilize
> > > > > burst functionality appropriately.
> > > >
> > > > I understand the cost of aggregating packets based on port and queue
> > > > to make it burst.
> > > > But, Could you share the use case where how do you want to use this
> > > > flag? I see two possibilities in eventdev context.
> > > > (Where dequeue can be from any ethdev port)
> > > > a) The application does the aggregation. If so, what would the
> > > > difference be in doing driver or application?
> > > > b) We may use this flag when the system has only one port and one
> > queue.
> > > >
> > > > Could you share how do you want to use this flag?
> > >
> > > I would say both the cases you mentioned. I prefer this to depend on the
> > smartness of
> > > the application, as it is aware of the number of eth devices/queues it is
> > using.
> > > This is the reason to avoid in the driver.
> > >
> > > A user can also use separate event ports for separate or a group of
> > Ethernet
> > > devices/queues, to create easy segregation.
> >
> > If it is specific to _very_ static configuration, you can assume all
> > the events comes
> > from a specific eventdev port, comes only from a specific ethdev port.
>
> Hi Jerin,
>
> If I understand correctly this assumption would be made in the driver?
> But then applications like l2fwd-event will break.
Yes. What I meant is a specific static configuration only this scheme can use.
>
> >
> > >
> > > Also the drawback of implementing in the driver, can be that when the
> > events to
> > > Separate devices and queues are so mixed up, that segregation does not
> > make
> > > sense, it shall be overhead for the driver to scan all the events.
> >
> > In the worst case, both, applications need to scan and driver need to
> > iterate over
> > all the events.
>
> Agree, this is what we want to avoid.
>
> >
> >
> > In generic l2fwd-eventdev applications etc, q0 will be connected p0 and p1
> > etc.
> > This flag will be zero.
>
> Okay.
>
> >
> > But, If you think, there is a specific use case for it we can add this flag.
> >
> >
> > >
> > > A flag would help in providing the decision flexibility to the applications.
> > >
> > > >
> > > > And another point is, tx adapter is NOT experimental now, We need
> > > > depreciation notice for ABI change.
> > > > If you share the exact use case, then we could think of adding a new
> > > > symbol instead of breaking ABI and
> > > > add it for next release.
> > >
> > > I have heard the discussion that we may get some exceptions to
> > deprecation
> > > process for 19.11 as the APIs will freeze of 1 year post it.
> > > Anyway, if you have a better way with symbol, please suggest.
> >
> >
> > One option could be (not as bad as changing the enqueue prototype) to
> > add new field in struct rte_event_eth_tx_adapter_conf.
> >
> > Since this scheme can be used ONLY on the static configuration, adding
> > a few fields
> > for Tx adapter configuration would help.
> > If that field is set you can choose dev->txa_enqueue light weight
> > enqueue function
> > if not, the driver can aggregate the buffers and send them.
>
> Thanks for suggesting this, we also thought of it, but would prefer having this as a
> runtime option rather than static option.
> We would not like to have one time configuration restriction.
Not sure how it can be used in runtime. If q0 is connected p0 and p1 and then
it flag has to be cleared. if q0 is only connected to p0 then we can
use this scheme.
So it is pretty much static in nature.
How do you think, it can be used in runtime.
If we think, If we are planning to use like below in application, it
would be really bad
in the worst case.(mbuf cache misses in-app and driver)
In app:
const port = event[0].mbuf.port;
const queue = event[0].mbuf.queue;
for (i = i; i < nb_events; i++) {
if (port != event[i].mbuf.port || queue != event[i].mbuf.queue)
break;
}
if (i == nb_events)
flag = 1;
else
flag = 0;
more over the static scheme does not make any change in other drivers.
If you have the usecase for the dynamic scheme then let us know then
we add dynamic flag breaking the ABI.
>
> >
> >
> >
> > >
> > > >
> > > >
> > > >
> > > >
> > > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > > ---
> > > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> > +++++++++++++--
> > > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > > >
> > > > > diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-
> > > > eventdev/test_pipeline_common.h
> > > > > index 0440b9e29..6e73c6ab2 100644
> > > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const
> > uint8_t
> > > > port,
> > > > > struct rte_event * const ev)
> > > > > {
> > > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > > > > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> > > > > rte_pause();
> > > > > }
> > > > >
> > > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev,
> > const
> > > > uint8_t port,
> > > > > {
> > > > > uint16_t enq;
> > > > >
> > > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> > > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx,
> > 0);
> > > > > while (enq < nb_rx) {
> > > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > > - ev + enq, nb_rx - enq);
> > > > > + ev + enq, nb_rx - enq, 0);
> > > > > }
> > > > > }
> > > > >
> > > > > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > index 192f9e1cf..a8c13e136 100644
> > > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > > @@ -137,11 +137,12 @@ should use the
> > ``rte_event_enqueue_burst()``
> > > > function.
> > > > > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
> > > > >
> > > > > event.mbuf = m;
> > > > > + eq_flags = 0;
> > > > >
> > > > > m->port = tx_port;
> > > > > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> > > > >
> > > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event,
> > 1);
> > > > > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> > &event, 1,
> > > > eq_flags);
> > > > > } else {
> > > > >
> > > > > event.queue_id = qid; /* event queue linked to adapter port */
> > > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > > index 0e622152c..1b156edab 100644
> > > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws,
> > uint8_t
> > > > queue_id,
> > > > > ssows_handle_event_t fn, void *arg);
> > > > > void ssows_reset(struct ssows *ws);
> > > > > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> > > > > int ssovf_info(struct ssovf_info *info);
> > > > > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > > > int test_eventdev_octeontx(void);
> > > > > diff --git a/drivers/event/octeontx/ssovf_worker.c
> > > > b/drivers/event/octeontx/ssovf_worker.c
> > > > > index d940b5dd6..1d0467af3 100644
> > > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > > >
> > > > > uint16_t
> > > > > sso_event_tx_adapter_enqueue(void *port,
> > > > > - struct rte_event ev[], uint16_t nb_events)
> > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > > > > {
> > > > > uint16_t port_id;
> > > > > uint16_t queue_id;
> > > > > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > > > > octeontx_dq_t *dq;
> > > > >
> > > > > RTE_SET_USED(nb_events);
> > > > > + RTE_SET_USED(eq_flags);
> > > > > switch (ev->sched_type) {
> > > > > case SSO_SYNC_ORDERED:
> > > > > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > > > > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> > > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > > index 5cd80e3b2..74b749a15 100644
> > > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > >
> > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> > rte_event
> > > > ev[],\
> > > > > - uint16_t nb_events); \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags); \
> > > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> > \
> > > > > struct rte_event ev[], \
> > > > > - uint16_t nb_events); \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags); \
> > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > \
> > > > > struct rte_event ev[], \
> > > > > - uint16_t nb_events); \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags); \
> > > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > > > \
> > > > > struct rte_event ev[], \
> > > > > - uint16_t nb_events); \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags); \
> > > > >
> > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > #undef T
> > > > > diff --git a/drivers/event/octeontx2/otx2_worker.c
> > > > b/drivers/event/octeontx2/otx2_worker.c
> > > > > index cd14cd3d2..100e21669 100644
> > > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port,
> > const
> > > > struct rte_event ev[],
> > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > uint16_t __hot \
> > > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> > ev[], \
> > > > > - uint16_t nb_events) \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags) \
> > > > > { \
> > > > > struct otx2_ssogws *ws = port; \
> > > > > uint64_t cmd[sz]; \
> > > > > \
> > > > > RTE_SET_USED(nb_events); \
> > > > > + RTE_SET_USED(eq_flags); \
> > > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > > }
> > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > > uint16_t __hot \
> > > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> > rte_event ev[],\
> > > > > - uint16_t nb_events) \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags) \
> > > > > { \
> > > > > struct otx2_ssogws *ws = port; \
> > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > \
> > > > > RTE_SET_USED(nb_events); \
> > > > > + RTE_SET_USED(eq_flags); \
> > > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > > NIX_TX_MULTI_SEG_F); \
> > > > > }
> > > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > index 37c274a54..c3e48da42 100644
> > > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > uint16_t __hot \
> > > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > > > struct rte_event ev[], \
> > > > > - uint16_t nb_events) \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags) \
> > > > > { \
> > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > struct otx2_ssogws *vws = \
> > > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> > name(void *port,
> > > > \
> > > > > uint64_t cmd[sz]; \
> > > > > \
> > > > > RTE_SET_USED(nb_events); \
> > > > > + RTE_SET_USED(eq_flags); \
> > > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > > }
> > > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > > uint16_t __hot \
> > > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> > > > > struct rte_event ev[], \
> > > > > - uint16_t nb_events) \
> > > > > + uint16_t nb_events, \
> > > > > + uint8_t eq_flags) \
> > > > > { \
> > > > > struct otx2_ssogws_dual *ws = port; \
> > > > > struct otx2_ssogws *vws = \
> > > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> > name(void
> > > > *port, \
> > > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > > \
> > > > > RTE_SET_USED(nb_events); \
> > > > > + RTE_SET_USED(eq_flags); \
> > > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > > NIX_TX_MULTI_SEG_F); \
> > > > > }
> > > > > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > index c848261c4..98be77568 100644
> > > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct
> > rte_mbuf
> > > > *pkt)
> > > > > int
> > > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> > > > *event_port_id);
> > > > >
> > > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> > > > > +/**< This flag is used when all the packets enqueued in the tx adapter
> > are
> > > > > + * destined for the same Ethernet device, queue pair.
> > > > > + */
> > > > > +
> > > > > /**
> > > > > * Enqueue a burst of events objects or an event object supplied in
> > > > *rte_event*
> > > > > * structure on an event device designated by its *dev_id* through
> > the event
> > > > > @@ -324,6 +329,10 @@
> > rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > > id, uint8_t *event_port_id);
> > > > > * The number of event objects to enqueue, typically number of
> > > > > * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > > * available for this port.
> > > > > + * @param flags
> > > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies
> > that all
> > > > the packets
> > > > > + * which are enqueued are destined for the same Ethernet device,
> > queue pair.
> > > > > *
> > > > > * @return
> > > > > * The number of event objects actually enqueued on the event
> > device. The
> > > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > > uint8_t port_id,
> > > > > struct rte_event ev[],
> > > > > - uint16_t nb_events)
> > > > > + uint16_t nb_events,
> > > > > + uint8_t flags)
> > > > > {
> > > > > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> > > > >
> > > > > @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t
> > dev_id,
> > > > > return 0;
> > > > > }
> > > > > #endif
> > > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > nb_events);
> > > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > > + nb_events, flags);
> > > > > }
> > > > >
> > > > > /**
> > > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > > b/lib/librte_eventdev/rte_eventdev.c
> > > > > index f44c869cb..3bf9d7115 100644
> > > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > > @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> > > > > static uint16_t
> > > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > > __rte_unused struct rte_event ev[],
> > > > > - __rte_unused uint16_t nb_events)
> > > > > + __rte_unused uint16_t nb_events,
> > > > > + __rte_unused uint8_t flags)
> > > > > {
> > > > > rte_errno = ENOTSUP;
> > > > > return 0;
> > > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > > b/lib/librte_eventdev/rte_eventdev.h
> > > > > index 5044a13d0..2a5643da3 100644
> > > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> > (*event_dequeue_burst_t)(void
> > > > *port, struct rte_event ev[],
> > > > > /**< @internal Dequeue burst of events from port of a device */
> > > > >
> > > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > > - struct rte_event ev[], uint16_t nb_events);
> > > > > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > > > > /**< @internal Enqueue burst of events on port of a device */
> > > > >
> > > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > > --
> > > > > 2.17.1
> > > > >
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 13:09 0% ` Jerin Jacob
@ 2019-10-01 14:02 0% ` Nipun Gupta
2019-10-01 14:20 3% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Nipun Gupta @ 2019-10-01 14:02 UTC (permalink / raw)
To: Jerin Jacob, Jerin Jacob
Cc: dpdk-dev, Jerin Jacob, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
> -----Original Message-----
> From: Jerin Jacob <jerinjacobk@gmail.com>
> Sent: Tuesday, October 1, 2019 6:40 PM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> <skori@marvell.com>; Hemant Agrawal <hemant.agrawal@nxp.com>;
> Richardson, Bruce <bruce.richardson@intel.com>; Marko Kovacevic
> <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> Nicolau <radu.nicolau@intel.com>; Tomasz Kantecki
> <tomasz.kantecki@intel.com>; Van Haaren, Harry
> <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> packets enqueue
>
> On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> >
> >
> >
> > > -----Original Message-----
> > > From: Jerin Jacob <jerinjacobk@gmail.com>
> > > Sent: Tuesday, October 1, 2019 1:14 PM
> > > To: Nipun Gupta <nipun.gupta@nxp.com>
> > > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori
> <skori@marvell.com>;
> > > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Marko Kovacevic
> > > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu
> Nicolau
> > > <radu.nicolau@intel.com>; Tomasz Kantecki
> <tomasz.kantecki@intel.com>; Van
> > > Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same
> destined
> > > packets enqueue
> > >
> > > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com>
> wrote:
> > > >
> > > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > > Some drivers may support burst functionality only with the packets
> > > > having same destination device and queue.
> > > >
> > > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can
> be used
> > > > to indicate this so the underlying driver, for drivers to utilize
> > > > burst functionality appropriately.
> > >
> > > I understand the cost of aggregating packets based on port and queue
> > > to make it burst.
> > > But, Could you share the use case where how do you want to use this
> > > flag? I see two possibilities in eventdev context.
> > > (Where dequeue can be from any ethdev port)
> > > a) The application does the aggregation. If so, what would the
> > > difference be in doing driver or application?
> > > b) We may use this flag when the system has only one port and one
> queue.
> > >
> > > Could you share how do you want to use this flag?
> >
> > I would say both the cases you mentioned. I prefer this to depend on the
> smartness of
> > the application, as it is aware of the number of eth devices/queues it is
> using.
> > This is the reason to avoid in the driver.
> >
> > A user can also use separate event ports for separate or a group of
> Ethernet
> > devices/queues, to create easy segregation.
>
> If it is specific to _very_ static configuration, you can assume all
> the events comes
> from a specific eventdev port, comes only from a specific ethdev port.
Hi Jerin,
If I understand correctly this assumption would be made in the driver?
But then applications like l2fwd-event will break.
>
> >
> > Also the drawback of implementing in the driver, can be that when the
> events to
> > Separate devices and queues are so mixed up, that segregation does not
> make
> > sense, it shall be overhead for the driver to scan all the events.
>
> In the worst case, both, applications need to scan and driver need to
> iterate over
> all the events.
Agree, this is what we want to avoid.
>
>
> In generic l2fwd-eventdev applications etc, q0 will be connected p0 and p1
> etc.
> This flag will be zero.
Okay.
>
> But, If you think, there is a specific use case for it we can add this flag.
>
>
> >
> > A flag would help in providing the decision flexibility to the applications.
> >
> > >
> > > And another point is, tx adapter is NOT experimental now, We need
> > > depreciation notice for ABI change.
> > > If you share the exact use case, then we could think of adding a new
> > > symbol instead of breaking ABI and
> > > add it for next release.
> >
> > I have heard the discussion that we may get some exceptions to
> deprecation
> > process for 19.11 as the APIs will freeze of 1 year post it.
> > Anyway, if you have a better way with symbol, please suggest.
>
>
> One option could be (not as bad as changing the enqueue prototype) to
> add new field in struct rte_event_eth_tx_adapter_conf.
>
> Since this scheme can be used ONLY on the static configuration, adding
> a few fields
> for Tx adapter configuration would help.
> If that field is set you can choose dev->txa_enqueue light weight
> enqueue function
> if not, the driver can aggregate the buffers and send them.
Thanks for suggesting this, we also thought of it, but would prefer having this as a
runtime option rather than static option.
We would not like to have one time configuration restriction.
>
>
>
> >
> > >
> > >
> > >
> > >
> > > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > > ---
> > > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15
> +++++++++++++--
> > > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > > >
> > > > diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-
> > > eventdev/test_pipeline_common.h
> > > > index 0440b9e29..6e73c6ab2 100644
> > > > --- a/app/test-eventdev/test_pipeline_common.h
> > > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const
> uint8_t
> > > port,
> > > > struct rte_event * const ev)
> > > > {
> > > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > > > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> > > > rte_pause();
> > > > }
> > > >
> > > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev,
> const
> > > uint8_t port,
> > > > {
> > > > uint16_t enq;
> > > >
> > > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> > > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx,
> 0);
> > > > while (enq < nb_rx) {
> > > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > > - ev + enq, nb_rx - enq);
> > > > + ev + enq, nb_rx - enq, 0);
> > > > }
> > > > }
> > > >
> > > > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > index 192f9e1cf..a8c13e136 100644
> > > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > > @@ -137,11 +137,12 @@ should use the
> ``rte_event_enqueue_burst()``
> > > function.
> > > > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
> > > >
> > > > event.mbuf = m;
> > > > + eq_flags = 0;
> > > >
> > > > m->port = tx_port;
> > > > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> > > >
> > > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event,
> 1);
> > > > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port,
> &event, 1,
> > > eq_flags);
> > > > } else {
> > > >
> > > > event.queue_id = qid; /* event queue linked to adapter port */
> > > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > > b/drivers/event/octeontx/ssovf_evdev.h
> > > > index 0e622152c..1b156edab 100644
> > > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws,
> uint8_t
> > > queue_id,
> > > > ssows_handle_event_t fn, void *arg);
> > > > void ssows_reset(struct ssows *ws);
> > > > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > > > - struct rte_event ev[], uint16_t nb_events);
> > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> > > > int ssovf_info(struct ssovf_info *info);
> > > > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > > int test_eventdev_octeontx(void);
> > > > diff --git a/drivers/event/octeontx/ssovf_worker.c
> > > b/drivers/event/octeontx/ssovf_worker.c
> > > > index d940b5dd6..1d0467af3 100644
> > > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > > >
> > > > uint16_t
> > > > sso_event_tx_adapter_enqueue(void *port,
> > > > - struct rte_event ev[], uint16_t nb_events)
> > > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > > > {
> > > > uint16_t port_id;
> > > > uint16_t queue_id;
> > > > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > > > octeontx_dq_t *dq;
> > > >
> > > > RTE_SET_USED(nb_events);
> > > > + RTE_SET_USED(eq_flags);
> > > > switch (ev->sched_type) {
> > > > case SSO_SYNC_ORDERED:
> > > > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > > > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> > > b/drivers/event/octeontx2/otx2_evdev.h
> > > > index 5cd80e3b2..74b749a15 100644
> > > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > >
> > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct
> rte_event
> > > ev[],\
> > > > - uint16_t nb_events); \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags); \
> > > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port,
> \
> > > > struct rte_event ev[], \
> > > > - uint16_t nb_events); \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags); \
> > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> \
> > > > struct rte_event ev[], \
> > > > - uint16_t nb_events); \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags); \
> > > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > > \
> > > > struct rte_event ev[], \
> > > > - uint16_t nb_events); \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags); \
> > > >
> > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > #undef T
> > > > diff --git a/drivers/event/octeontx2/otx2_worker.c
> > > b/drivers/event/octeontx2/otx2_worker.c
> > > > index cd14cd3d2..100e21669 100644
> > > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port,
> const
> > > struct rte_event ev[],
> > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > uint16_t __hot \
> > > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> ev[], \
> > > > - uint16_t nb_events) \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags) \
> > > > { \
> > > > struct otx2_ssogws *ws = port; \
> > > > uint64_t cmd[sz]; \
> > > > \
> > > > RTE_SET_USED(nb_events); \
> > > > + RTE_SET_USED(eq_flags); \
> > > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > > }
> > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > > uint16_t __hot \
> > > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct
> rte_event ev[],\
> > > > - uint16_t nb_events) \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags) \
> > > > { \
> > > > struct otx2_ssogws *ws = port; \
> > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > \
> > > > RTE_SET_USED(nb_events); \
> > > > + RTE_SET_USED(eq_flags); \
> > > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > > NIX_TX_MULTI_SEG_F); \
> > > > }
> > > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > index 37c274a54..c3e48da42 100644
> > > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > > uint16_t __hot \
> > > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > > struct rte_event ev[], \
> > > > - uint16_t nb_events) \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags) \
> > > > { \
> > > > struct otx2_ssogws_dual *ws = port; \
> > > > struct otx2_ssogws *vws = \
> > > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ##
> name(void *port,
> > > \
> > > > uint64_t cmd[sz]; \
> > > > \
> > > > RTE_SET_USED(nb_events); \
> > > > + RTE_SET_USED(eq_flags); \
> > > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > > }
> > > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > > uint16_t __hot \
> > > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> > > > struct rte_event ev[], \
> > > > - uint16_t nb_events) \
> > > > + uint16_t nb_events, \
> > > > + uint8_t eq_flags) \
> > > > { \
> > > > struct otx2_ssogws_dual *ws = port; \
> > > > struct otx2_ssogws *vws = \
> > > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ##
> name(void
> > > *port, \
> > > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > > \
> > > > RTE_SET_USED(nb_events); \
> > > > + RTE_SET_USED(eq_flags); \
> > > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > > NIX_TX_MULTI_SEG_F); \
> > > > }
> > > > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > index c848261c4..98be77568 100644
> > > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct
> rte_mbuf
> > > *pkt)
> > > > int
> > > > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> > > *event_port_id);
> > > >
> > > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> > > > +/**< This flag is used when all the packets enqueued in the tx adapter
> are
> > > > + * destined for the same Ethernet device, queue pair.
> > > > + */
> > > > +
> > > > /**
> > > > * Enqueue a burst of events objects or an event object supplied in
> > > *rte_event*
> > > > * structure on an event device designated by its *dev_id* through
> the event
> > > > @@ -324,6 +329,10 @@
> rte_event_eth_tx_adapter_event_port_get(uint8_t
> > > id, uint8_t *event_port_id);
> > > > * The number of event objects to enqueue, typically number of
> > > > * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > > * available for this port.
> > > > + * @param flags
> > > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies
> that all
> > > the packets
> > > > + * which are enqueued are destined for the same Ethernet device,
> queue pair.
> > > > *
> > > > * @return
> > > > * The number of event objects actually enqueued on the event
> device. The
> > > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > > uint8_t port_id,
> > > > struct rte_event ev[],
> > > > - uint16_t nb_events)
> > > > + uint16_t nb_events,
> > > > + uint8_t flags)
> > > > {
> > > > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> > > >
> > > > @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t
> dev_id,
> > > > return 0;
> > > > }
> > > > #endif
> > > > - return dev->txa_enqueue(dev->data->ports[port_id], ev,
> nb_events);
> > > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > > + nb_events, flags);
> > > > }
> > > >
> > > > /**
> > > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > > b/lib/librte_eventdev/rte_eventdev.c
> > > > index f44c869cb..3bf9d7115 100644
> > > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > > @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> > > > static uint16_t
> > > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > > __rte_unused struct rte_event ev[],
> > > > - __rte_unused uint16_t nb_events)
> > > > + __rte_unused uint16_t nb_events,
> > > > + __rte_unused uint8_t flags)
> > > > {
> > > > rte_errno = ENOTSUP;
> > > > return 0;
> > > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > > b/lib/librte_eventdev/rte_eventdev.h
> > > > index 5044a13d0..2a5643da3 100644
> > > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > > @@ -1227,7 +1227,7 @@ typedef uint16_t
> (*event_dequeue_burst_t)(void
> > > *port, struct rte_event ev[],
> > > > /**< @internal Dequeue burst of events from port of a device */
> > > >
> > > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > > - struct rte_event ev[], uint16_t nb_events);
> > > > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > > > /**< @internal Enqueue burst of events on port of a device */
> > > >
> > > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > > --
> > > > 2.17.1
> > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/2] build: support building ABI versioned files twice
@ 2019-10-01 13:23 4% ` Andrzej Ostruszka
2019-10-01 16:53 4% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Andrzej Ostruszka @ 2019-10-01 13:23 UTC (permalink / raw)
To: Bruce Richardson, dev; +Cc: Thomas Monjalon, Ray Kinsella, Neil Horman, bluca
Thanks Bruce for the patch. I like the idea of splitting versioning out
of rte_compat.h, but I have some comments.
On 9/27/19 10:59 PM, Bruce Richardson wrote:
[...]
> --- a/config/common_base
> +++ b/config/common_base
> @@ -111,6 +111,7 @@ CONFIG_RTE_MAX_VFIO_CONTAINERS=64
> CONFIG_RTE_MALLOC_DEBUG=n
> CONFIG_RTE_EAL_NUMA_AWARE_HUGEPAGES=n
> CONFIG_RTE_USE_LIBBSD=n
> +CONFIG_RTE_USE_FUNCTION_VERSIONING=y
I'm not fond of this config option - it is not really an option to be
changed by the user. I would prefer to just add flag to CFLAGS in
mk/target/generic/rte.vars.mk.
> #
> # Recognize/ignore the AVX/AVX512 CPU flags for performance/power testing.
> diff --git a/config/rte_config.h b/config/rte_config.h
> index 0bbbe274f..b63a2fdea 100644
> --- a/config/rte_config.h
> +++ b/config/rte_config.h
> @@ -31,9 +31,6 @@
>
> /****** library defines ********/
>
> -/* compat defines */
> -#define RTE_BUILD_SHARED_LIB
> -
So now everything builds "as static lib" (but with "-fPIC") apart from
those libraries that use symbol versioning. I'm OK with that however
I'd like to note that code might be using RTE_BUILD_SHARED_LIB and do
different things e.g. app/test-bbdev/test_bbdev_perf.c. I know that was
already the case - just wanted to say that aloud to make sure we are all
aware of this :).
> diff --git a/doc/guides/contributing/coding_style.rst b/doc/guides/contributing/coding_style.rst
> index 449b33494..e95a1a2be 100644
> --- a/doc/guides/contributing/coding_style.rst
> +++ b/doc/guides/contributing/coding_style.rst
> @@ -948,6 +948,13 @@ reason
> built. For missing dependencies this should be of the form
> ``'missing dependency, "libname"'``.
>
> +use_function_versioning
> + **Default Value = false**.
> + Specifies if the library in question has ABI versioned functions. If it
> + has, this value should be set to ensure that the C files are compiled
> + twice with suitable parameters for each of shared or static library
> + builds.
> +
Maybe a different name for this option? In general an "ideal
theoretical" solution would be for build system to figure out on its own
that separate build is necessary automatically - but that might incur
some performance penalty (additional grep'ing of sources or so). So I'm
fine with this option however I'd like to rename it to actually indicate
what it's effect is. Like 'separate_build' or 'split_build' or
'rebuild_objects' or ...
The intention of using of versioned symbols is already indicated by
inclusion of the relevant header.
> diff --git a/lib/librte_eal/common/include/rte_function_versioning.h b/lib/librte_eal/common/include/rte_function_versioning.h
> index ce963d4b1..55e88ffae 100644
> --- a/lib/librte_eal/common/include/rte_function_versioning.h
> +++ b/lib/librte_eal/common/include/rte_function_versioning.h
> @@ -7,6 +7,10 @@
> #define _RTE_FUNCTION_VERSIONING_H_
> #include <rte_common.h>
>
> +#ifndef RTE_USE_FUNCTION_VERSIONING
> +#error Use of function versioning disabled, is "use_function_versioning=true" in meson.build?
> +#endif
If you accept above suggestion then change this message to something
like: "Function versioning requires 'separate_build=true' in meson.build"
BTW it turned out that this need for separate build for versioned
symbols is a result of long standing gcc bug:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=48200
I'll test this with clang and if this will work then maybe we could
guard this #if with another check for 'gcc'.
Best regards
Andrzej
Tested-by: Andrzej Ostruszka <amo@semihalf.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v6 1/4] doc: separate versioning.rst into version and policy
2019-10-01 12:50 3% ` Hemant Agrawal
@ 2019-10-01 13:19 5% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2019-10-01 13:19 UTC (permalink / raw)
To: Hemant Agrawal, dev
Cc: thomas, stephen, bruce.richardson, ferruh.yigit,
konstantin.ananyev, jerinj, olivier.matz, nhorman,
maxime.coquelin, john.mcnamara, marko.kovacevic, ktraynor,
aconole
Hemant,
Patch 1/4 - doc: separate versioning.rst into version and policy.
So it essentially re-organizes the existing policy into two separate
documents, one dealing with the policy and the other dealing with the
mechanics of abi versioning
Patch 2/4 - doc: changes to abi policy introducing major abi versions
Actually details the changes to the policy.
Other comments inline below.
Ray K
On 01/10/2019 13:50, Hemant Agrawal wrote:
> Hi Ray,
>
>> +DPDK ABI/API policy
>> +===================
>> +
>> +Description
>> +-----------
>> +
>> +This document details some methods for handling ABI management in the
>> DPDK.
>> +
>> +General Guidelines
>> +------------------
>> +
>> +#. Whenever possible, ABI should be preserved #. ABI/API may be changed
>> +with a deprecation process #. The modification of symbols can generally
>> +be managed with versioning #. Libraries or APIs marked in
>> +``experimental`` state may change without constraint #. New APIs will
>> +be marked as ``experimental`` for at least one release to allow
>> + any issues found by users of the new API to be fixed quickly #. The
>> +addition of symbols is generally not problematic #. The removal of
>> +symbols generally is an ABI break and requires bumping of the
>> + LIBABIVER macro
>> +#. Updates to the minimum hardware requirements, which drop support
>> for hardware which
>> + was previously supported, should be treated as an ABI change.
>
> [Hemant] You mean the specific HW pmds?
> 1. Why dropping HW PMD is a ABI change?
So this is part of the original policy and you are correct, it isn't
strictly abi - I think the original policy's author, wanted it treated
the same way so that a given ABI version would not drop support for
hardware.
> 2. Even if they are supported across releases, there is no guarantee that they are not broken.
True
>
>> +
>> +What is an ABI
>> +~~~~~~~~~~~~~~
>> +
>> +An ABI (Application Binary Interface) is the set of runtime interfaces
>> +exposed by a library. It is similar to an API (Application Programming
>> +Interface) but is the result of compilation. It is also effectively
>> +cloned when applications link to dynamic libraries. That is to say
>> +when an application is compiled to link against dynamic libraries, it
>> +is assumed that the ABI remains constant between the time the application
>> is compiled/linked, and the time that it runs.
>> +Therefore, in the case of dynamic linking, it is critical that an ABI
>> +is preserved, or (when modified), done in such a way that the
>> +application is unable to behave improperly or in an unexpected fashion.
>> +
>> +
>> +ABI/API Deprecation
>> +-------------------
>> +
>> +The DPDK ABI policy
>> +~~~~~~~~~~~~~~~~~~~
>> +
>> +ABI versions are set at the time of major release labeling, and the ABI
>> +may change multiple times, without warning, between the last release
>> +label and the HEAD label of the git tree.
>> +
>> +ABI versions, once released, are available until such time as their
>> +deprecation has been noted in the Release Notes for at least one major
>> +release cycle. For example consider the case where the ABI for DPDK 2.0
>> +has been shipped and then a decision is made to modify it during the
>> +development of DPDK 2.1. The decision will be recorded in the Release
>> +Notes for the DPDK 2.1 release and the modification will be made available
>> in the DPDK 2.2 release.
>> +
> [Hemant] Is it possible to update the DPDK numbering to current versioning, instead of using old 2.x numbering?
Already done, see Patch 2/4
>> +ABI versions may be deprecated in whole or in part as needed by a given
>> +update.
>> +
>> +Some ABI changes may be too significant to reasonably maintain multiple
>> +versions. In those cases ABI's may be updated without backward
>> +compatibility being provided. The requirements for doing so are:
>> +
>> +#. At least 3 acknowledgments of the need to do so must be made on the
>> + dpdk.org mailing list.
>> +
>> + - The acknowledgment of the maintainer of the component is mandatory,
>> or if
>> + no maintainer is available for the component, the tree/sub-tree
>> maintainer
>> + for that component must acknowledge the ABI change instead.
>> +
>> + - It is also recommended that acknowledgments from different "areas of
>> + interest" be sought for each deprecation, for example: from NIC
>> vendors,
>> + CPU vendors, end-users, etc.
>> +
>> +#. The changes (including an alternative map file) can be included with
>> + deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
>> + to provide more details about oncoming changes.
>> + ``RTE_NEXT_ABI`` wrapper will be removed when it become the default
>> ABI.
>
> [Hemant] The older implementation will or can be removed at this point of time?
Detailed in Patch 2/4.
it says ... At the declaration of the next major ABI version, those ABI
changes then become a formal part of the new ABI and the requirement to
preserve ABI compatibility with the last major ABI version is then
dropped ...
Thanks,
Ray K
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 11:41 0% ` Nipun Gupta
@ 2019-10-01 13:09 0% ` Jerin Jacob
2019-10-01 14:02 0% ` Nipun Gupta
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-01 13:09 UTC (permalink / raw)
To: Nipun Gupta
Cc: dpdk-dev, Jerin Jacob, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
On Tue, Oct 1, 2019 at 5:11 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
>
>
> > -----Original Message-----
> > From: Jerin Jacob <jerinjacobk@gmail.com>
> > Sent: Tuesday, October 1, 2019 1:14 PM
> > To: Nipun Gupta <nipun.gupta@nxp.com>
> > Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> > Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori <skori@marvell.com>;
> > Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> > <bruce.richardson@intel.com>; Marko Kovacevic
> > <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu Nicolau
> > <radu.nicolau@intel.com>; Tomasz Kantecki <tomasz.kantecki@intel.com>; Van
> > Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> > Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> > packets enqueue
> >
> > On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> > >
> > > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > > Some drivers may support burst functionality only with the packets
> > > having same destination device and queue.
> > >
> > > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> > > to indicate this so the underlying driver, for drivers to utilize
> > > burst functionality appropriately.
> >
> > I understand the cost of aggregating packets based on port and queue
> > to make it burst.
> > But, Could you share the use case where how do you want to use this
> > flag? I see two possibilities in eventdev context.
> > (Where dequeue can be from any ethdev port)
> > a) The application does the aggregation. If so, what would the
> > difference be in doing driver or application?
> > b) We may use this flag when the system has only one port and one queue.
> >
> > Could you share how do you want to use this flag?
>
> I would say both the cases you mentioned. I prefer this to depend on the smartness of
> the application, as it is aware of the number of eth devices/queues it is using.
> This is the reason to avoid in the driver.
>
> A user can also use separate event ports for separate or a group of Ethernet
> devices/queues, to create easy segregation.
If it is specific to _very_ static configuration, you can assume all
the events comes
from a specific eventdev port, comes only from a specific ethdev port.
>
> Also the drawback of implementing in the driver, can be that when the events to
> Separate devices and queues are so mixed up, that segregation does not make
> sense, it shall be overhead for the driver to scan all the events.
In the worst case, both, applications need to scan and driver need to
iterate over
all the events.
In generic l2fwd-eventdev applications etc, q0 will be connected p0 and p1 etc.
This flag will be zero.
But, If you think, there is a specific use case for it we can add this flag.
>
> A flag would help in providing the decision flexibility to the applications.
>
> >
> > And another point is, tx adapter is NOT experimental now, We need
> > depreciation notice for ABI change.
> > If you share the exact use case, then we could think of adding a new
> > symbol instead of breaking ABI and
> > add it for next release.
>
> I have heard the discussion that we may get some exceptions to deprecation
> process for 19.11 as the APIs will freeze of 1 year post it.
> Anyway, if you have a better way with symbol, please suggest.
One option could be (not as bad as changing the enqueue prototype) to
add new field in struct rte_event_eth_tx_adapter_conf.
Since this scheme can be used ONLY on the static configuration, adding
a few fields
for Tx adapter configuration would help.
If that field is set you can choose dev->txa_enqueue light weight
enqueue function
if not, the driver can aggregate the buffers and send them.
>
> >
> >
> >
> >
> > > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > > ---
> > > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15 +++++++++++++--
> > > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > > 10 files changed, 44 insertions(+), 18 deletions(-)
> > >
> > > diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-
> > eventdev/test_pipeline_common.h
> > > index 0440b9e29..6e73c6ab2 100644
> > > --- a/app/test-eventdev/test_pipeline_common.h
> > > +++ b/app/test-eventdev/test_pipeline_common.h
> > > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t
> > port,
> > > struct rte_event * const ev)
> > > {
> > > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> > > rte_pause();
> > > }
> > >
> > > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const
> > uint8_t port,
> > > {
> > > uint16_t enq;
> > >
> > > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> > > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
> > > while (enq < nb_rx) {
> > > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > > - ev + enq, nb_rx - enq);
> > > + ev + enq, nb_rx - enq, 0);
> > > }
> > > }
> > >
> > > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > index 192f9e1cf..a8c13e136 100644
> > > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > > @@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()``
> > function.
> > > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
> > >
> > > event.mbuf = m;
> > > + eq_flags = 0;
> > >
> > > m->port = tx_port;
> > > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> > >
> > > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
> > > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1,
> > eq_flags);
> > > } else {
> > >
> > > event.queue_id = qid; /* event queue linked to adapter port */
> > > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> > b/drivers/event/octeontx/ssovf_evdev.h
> > > index 0e622152c..1b156edab 100644
> > > --- a/drivers/event/octeontx/ssovf_evdev.h
> > > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws, uint8_t
> > queue_id,
> > > ssows_handle_event_t fn, void *arg);
> > > void ssows_reset(struct ssows *ws);
> > > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > > - struct rte_event ev[], uint16_t nb_events);
> > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> > > int ssovf_info(struct ssovf_info *info);
> > > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > > int test_eventdev_octeontx(void);
> > > diff --git a/drivers/event/octeontx/ssovf_worker.c
> > b/drivers/event/octeontx/ssovf_worker.c
> > > index d940b5dd6..1d0467af3 100644
> > > --- a/drivers/event/octeontx/ssovf_worker.c
> > > +++ b/drivers/event/octeontx/ssovf_worker.c
> > > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> > >
> > > uint16_t
> > > sso_event_tx_adapter_enqueue(void *port,
> > > - struct rte_event ev[], uint16_t nb_events)
> > > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > > {
> > > uint16_t port_id;
> > > uint16_t queue_id;
> > > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > > octeontx_dq_t *dq;
> > >
> > > RTE_SET_USED(nb_events);
> > > + RTE_SET_USED(eq_flags);
> > > switch (ev->sched_type) {
> > > case SSO_SYNC_ORDERED:
> > > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> > b/drivers/event/octeontx2/otx2_evdev.h
> > > index 5cd80e3b2..74b749a15 100644
> > > --- a/drivers/event/octeontx2/otx2_evdev.h
> > > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > >
> > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> > ev[],\
> > > - uint16_t nb_events); \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags); \
> > > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, \
> > > struct rte_event ev[], \
> > > - uint16_t nb_events); \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags); \
> > > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > struct rte_event ev[], \
> > > - uint16_t nb_events); \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags); \
> > > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> > \
> > > struct rte_event ev[], \
> > > - uint16_t nb_events); \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags); \
> > >
> > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > #undef T
> > > diff --git a/drivers/event/octeontx2/otx2_worker.c
> > b/drivers/event/octeontx2/otx2_worker.c
> > > index cd14cd3d2..100e21669 100644
> > > --- a/drivers/event/octeontx2/otx2_worker.c
> > > +++ b/drivers/event/octeontx2/otx2_worker.c
> > > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port, const
> > struct rte_event ev[],
> > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > uint16_t __hot \
> > > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[], \
> > > - uint16_t nb_events) \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags) \
> > > { \
> > > struct otx2_ssogws *ws = port; \
> > > uint64_t cmd[sz]; \
> > > \
> > > RTE_SET_USED(nb_events); \
> > > + RTE_SET_USED(eq_flags); \
> > > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > > }
> > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > > uint16_t __hot \
> > > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct rte_event ev[],\
> > > - uint16_t nb_events) \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags) \
> > > { \
> > > struct otx2_ssogws *ws = port; \
> > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > \
> > > RTE_SET_USED(nb_events); \
> > > + RTE_SET_USED(eq_flags); \
> > > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > > NIX_TX_MULTI_SEG_F); \
> > > }
> > > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> > b/drivers/event/octeontx2/otx2_worker_dual.c
> > > index 37c274a54..c3e48da42 100644
> > > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > > uint16_t __hot \
> > > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > > struct rte_event ev[], \
> > > - uint16_t nb_events) \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags) \
> > > { \
> > > struct otx2_ssogws_dual *ws = port; \
> > > struct otx2_ssogws *vws = \
> > > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> > \
> > > uint64_t cmd[sz]; \
> > > \
> > > RTE_SET_USED(nb_events); \
> > > + RTE_SET_USED(eq_flags); \
> > > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > > }
> > > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > > uint16_t __hot \
> > > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> > > struct rte_event ev[], \
> > > - uint16_t nb_events) \
> > > + uint16_t nb_events, \
> > > + uint8_t eq_flags) \
> > > { \
> > > struct otx2_ssogws_dual *ws = port; \
> > > struct otx2_ssogws *vws = \
> > > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> > *port, \
> > > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > > \
> > > RTE_SET_USED(nb_events); \
> > > + RTE_SET_USED(eq_flags); \
> > > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > > NIX_TX_MULTI_SEG_F); \
> > > }
> > > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > index c848261c4..98be77568 100644
> > > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf
> > *pkt)
> > > int
> > > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> > *event_port_id);
> > >
> > > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> > > +/**< This flag is used when all the packets enqueued in the tx adapter are
> > > + * destined for the same Ethernet device, queue pair.
> > > + */
> > > +
> > > /**
> > > * Enqueue a burst of events objects or an event object supplied in
> > *rte_event*
> > > * structure on an event device designated by its *dev_id* through the event
> > > @@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t
> > id, uint8_t *event_port_id);
> > > * The number of event objects to enqueue, typically number of
> > > * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > > * available for this port.
> > > + * @param flags
> > > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all
> > the packets
> > > + * which are enqueued are destined for the same Ethernet device, queue pair.
> > > *
> > > * @return
> > > * The number of event objects actually enqueued on the event device. The
> > > @@ -343,7 +352,8 @@ static inline uint16_t
> > > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > uint8_t port_id,
> > > struct rte_event ev[],
> > > - uint16_t nb_events)
> > > + uint16_t nb_events,
> > > + uint8_t flags)
> > > {
> > > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> > >
> > > @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > > return 0;
> > > }
> > > #endif
> > > - return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
> > > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > > + nb_events, flags);
> > > }
> > >
> > > /**
> > > diff --git a/lib/librte_eventdev/rte_eventdev.c
> > b/lib/librte_eventdev/rte_eventdev.c
> > > index f44c869cb..3bf9d7115 100644
> > > --- a/lib/librte_eventdev/rte_eventdev.c
> > > +++ b/lib/librte_eventdev/rte_eventdev.c
> > > @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> > > static uint16_t
> > > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > > __rte_unused struct rte_event ev[],
> > > - __rte_unused uint16_t nb_events)
> > > + __rte_unused uint16_t nb_events,
> > > + __rte_unused uint8_t flags)
> > > {
> > > rte_errno = ENOTSUP;
> > > return 0;
> > > diff --git a/lib/librte_eventdev/rte_eventdev.h
> > b/lib/librte_eventdev/rte_eventdev.h
> > > index 5044a13d0..2a5643da3 100644
> > > --- a/lib/librte_eventdev/rte_eventdev.h
> > > +++ b/lib/librte_eventdev/rte_eventdev.h
> > > @@ -1227,7 +1227,7 @@ typedef uint16_t (*event_dequeue_burst_t)(void
> > *port, struct rte_event ev[],
> > > /**< @internal Dequeue burst of events from port of a device */
> > >
> > > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > > - struct rte_event ev[], uint16_t nb_events);
> > > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > > /**< @internal Enqueue burst of events on port of a device */
> > >
> > > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > > --
> > > 2.17.1
> > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 1/4] doc: separate versioning.rst into version and policy
@ 2019-10-01 12:50 3% ` Hemant Agrawal
2019-10-01 13:19 5% ` Ray Kinsella
2019-10-21 9:53 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Hemant Agrawal @ 2019-10-01 12:50 UTC (permalink / raw)
To: Ray Kinsella, dev
Cc: thomas, stephen, bruce.richardson, ferruh.yigit,
konstantin.ananyev, jerinj, olivier.matz, nhorman,
maxime.coquelin, john.mcnamara, marko.kovacevic, ktraynor,
aconole
Hi Ray,
> +DPDK ABI/API policy
> +===================
> +
> +Description
> +-----------
> +
> +This document details some methods for handling ABI management in the
> DPDK.
> +
> +General Guidelines
> +------------------
> +
> +#. Whenever possible, ABI should be preserved #. ABI/API may be changed
> +with a deprecation process #. The modification of symbols can generally
> +be managed with versioning #. Libraries or APIs marked in
> +``experimental`` state may change without constraint #. New APIs will
> +be marked as ``experimental`` for at least one release to allow
> + any issues found by users of the new API to be fixed quickly #. The
> +addition of symbols is generally not problematic #. The removal of
> +symbols generally is an ABI break and requires bumping of the
> + LIBABIVER macro
> +#. Updates to the minimum hardware requirements, which drop support
> for hardware which
> + was previously supported, should be treated as an ABI change.
[Hemant] You mean the specific HW pmds?
1. Why dropping HW PMD is a ABI change?
2. Even if they are supported across releases, there is no guarantee that they are not broken.
> +
> +What is an ABI
> +~~~~~~~~~~~~~~
> +
> +An ABI (Application Binary Interface) is the set of runtime interfaces
> +exposed by a library. It is similar to an API (Application Programming
> +Interface) but is the result of compilation. It is also effectively
> +cloned when applications link to dynamic libraries. That is to say
> +when an application is compiled to link against dynamic libraries, it
> +is assumed that the ABI remains constant between the time the application
> is compiled/linked, and the time that it runs.
> +Therefore, in the case of dynamic linking, it is critical that an ABI
> +is preserved, or (when modified), done in such a way that the
> +application is unable to behave improperly or in an unexpected fashion.
> +
> +
> +ABI/API Deprecation
> +-------------------
> +
> +The DPDK ABI policy
> +~~~~~~~~~~~~~~~~~~~
> +
> +ABI versions are set at the time of major release labeling, and the ABI
> +may change multiple times, without warning, between the last release
> +label and the HEAD label of the git tree.
> +
> +ABI versions, once released, are available until such time as their
> +deprecation has been noted in the Release Notes for at least one major
> +release cycle. For example consider the case where the ABI for DPDK 2.0
> +has been shipped and then a decision is made to modify it during the
> +development of DPDK 2.1. The decision will be recorded in the Release
> +Notes for the DPDK 2.1 release and the modification will be made available
> in the DPDK 2.2 release.
> +
[Hemant] Is it possible to update the DPDK numbering to current versioning, instead of using old 2.x numbering?
> +ABI versions may be deprecated in whole or in part as needed by a given
> +update.
> +
> +Some ABI changes may be too significant to reasonably maintain multiple
> +versions. In those cases ABI's may be updated without backward
> +compatibility being provided. The requirements for doing so are:
> +
> +#. At least 3 acknowledgments of the need to do so must be made on the
> + dpdk.org mailing list.
> +
> + - The acknowledgment of the maintainer of the component is mandatory,
> or if
> + no maintainer is available for the component, the tree/sub-tree
> maintainer
> + for that component must acknowledge the ABI change instead.
> +
> + - It is also recommended that acknowledgments from different "areas of
> + interest" be sought for each deprecation, for example: from NIC
> vendors,
> + CPU vendors, end-users, etc.
> +
> +#. The changes (including an alternative map file) can be included with
> + deprecation notice, in wrapped way by the ``RTE_NEXT_ABI`` option,
> + to provide more details about oncoming changes.
> + ``RTE_NEXT_ABI`` wrapper will be removed when it become the default
> ABI.
[Hemant] The older implementation will or can be removed at this point of time?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
2019-10-01 7:44 4% ` Jerin Jacob
@ 2019-10-01 11:41 0% ` Nipun Gupta
2019-10-01 13:09 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Nipun Gupta @ 2019-10-01 11:41 UTC (permalink / raw)
To: Jerin Jacob
Cc: dpdk-dev, Jerin Jacob, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
> -----Original Message-----
> From: Jerin Jacob <jerinjacobk@gmail.com>
> Sent: Tuesday, October 1, 2019 1:14 PM
> To: Nipun Gupta <nipun.gupta@nxp.com>
> Cc: dpdk-dev <dev@dpdk.org>; Jerin Jacob <jerinj@marvell.com>; Pavan
> Nikhilesh <pbhagavatula@marvell.com>; Sunil Kumar Kori <skori@marvell.com>;
> Hemant Agrawal <hemant.agrawal@nxp.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Marko Kovacevic
> <marko.kovacevic@intel.com>; Ori Kam <orika@mellanox.com>; Radu Nicolau
> <radu.nicolau@intel.com>; Tomasz Kantecki <tomasz.kantecki@intel.com>; Van
> Haaren, Harry <harry.van.haaren@intel.com>; nikhil.rao@intel.com
> Subject: Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined
> packets enqueue
>
> On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
> >
> > This patch introduces a `flag` in the Eth TX adapter enqueue API.
> > Some drivers may support burst functionality only with the packets
> > having same destination device and queue.
> >
> > The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> > to indicate this so the underlying driver, for drivers to utilize
> > burst functionality appropriately.
>
> I understand the cost of aggregating packets based on port and queue
> to make it burst.
> But, Could you share the use case where how do you want to use this
> flag? I see two possibilities in eventdev context.
> (Where dequeue can be from any ethdev port)
> a) The application does the aggregation. If so, what would the
> difference be in doing driver or application?
> b) We may use this flag when the system has only one port and one queue.
>
> Could you share how do you want to use this flag?
I would say both the cases you mentioned. I prefer this to depend on the smartness of
the application, as it is aware of the number of eth devices/queues it is using.
This is the reason to avoid in the driver.
A user can also use separate event ports for separate or a group of Ethernet
devices/queues, to create easy segregation.
Also the drawback of implementing in the driver, can be that when the events to
Separate devices and queues are so mixed up, that segregation does not make
sense, it shall be overhead for the driver to scan all the events.
A flag would help in providing the decision flexibility to the applications.
>
> And another point is, tx adapter is NOT experimental now, We need
> depreciation notice for ABI change.
> If you share the exact use case, then we could think of adding a new
> symbol instead of breaking ABI and
> add it for next release.
I have heard the discussion that we may get some exceptions to deprecation
process for 19.11 as the APIs will freeze of 1 year post it.
Anyway, if you have a better way with symbol, please suggest.
>
>
>
>
> > Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> > ---
> > app/test-eventdev/test_pipeline_common.h | 6 +++---
> > .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> > drivers/event/octeontx/ssovf_evdev.h | 2 +-
> > drivers/event/octeontx/ssovf_worker.c | 3 ++-
> > drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> > drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> > drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> > lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15 +++++++++++++--
> > lib/librte_eventdev/rte_eventdev.c | 3 ++-
> > lib/librte_eventdev/rte_eventdev.h | 2 +-
> > 10 files changed, 44 insertions(+), 18 deletions(-)
> >
> > diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-
> eventdev/test_pipeline_common.h
> > index 0440b9e29..6e73c6ab2 100644
> > --- a/app/test-eventdev/test_pipeline_common.h
> > +++ b/app/test-eventdev/test_pipeline_common.h
> > @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t
> port,
> > struct rte_event * const ev)
> > {
> > rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> > - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> > + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> > rte_pause();
> > }
> >
> > @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const
> uint8_t port,
> > {
> > uint16_t enq;
> >
> > - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> > + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
> > while (enq < nb_rx) {
> > enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> > - ev + enq, nb_rx - enq);
> > + ev + enq, nb_rx - enq, 0);
> > }
> > }
> >
> > diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > index 192f9e1cf..a8c13e136 100644
> > --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> > @@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()``
> function.
> > if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
> >
> > event.mbuf = m;
> > + eq_flags = 0;
> >
> > m->port = tx_port;
> > rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
> >
> > - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
> > + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1,
> eq_flags);
> > } else {
> >
> > event.queue_id = qid; /* event queue linked to adapter port */
> > diff --git a/drivers/event/octeontx/ssovf_evdev.h
> b/drivers/event/octeontx/ssovf_evdev.h
> > index 0e622152c..1b156edab 100644
> > --- a/drivers/event/octeontx/ssovf_evdev.h
> > +++ b/drivers/event/octeontx/ssovf_evdev.h
> > @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws, uint8_t
> queue_id,
> > ssows_handle_event_t fn, void *arg);
> > void ssows_reset(struct ssows *ws);
> > uint16_t sso_event_tx_adapter_enqueue(void *port,
> > - struct rte_event ev[], uint16_t nb_events);
> > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> > int ssovf_info(struct ssovf_info *info);
> > void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> > int test_eventdev_octeontx(void);
> > diff --git a/drivers/event/octeontx/ssovf_worker.c
> b/drivers/event/octeontx/ssovf_worker.c
> > index d940b5dd6..1d0467af3 100644
> > --- a/drivers/event/octeontx/ssovf_worker.c
> > +++ b/drivers/event/octeontx/ssovf_worker.c
> > @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
> >
> > uint16_t
> > sso_event_tx_adapter_enqueue(void *port,
> > - struct rte_event ev[], uint16_t nb_events)
> > + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> > {
> > uint16_t port_id;
> > uint16_t queue_id;
> > @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> > octeontx_dq_t *dq;
> >
> > RTE_SET_USED(nb_events);
> > + RTE_SET_USED(eq_flags);
> > switch (ev->sched_type) {
> > case SSO_SYNC_ORDERED:
> > ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> > diff --git a/drivers/event/octeontx2/otx2_evdev.h
> b/drivers/event/octeontx2/otx2_evdev.h
> > index 5cd80e3b2..74b749a15 100644
> > --- a/drivers/event/octeontx2/otx2_evdev.h
> > +++ b/drivers/event/octeontx2/otx2_evdev.h
> > @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> >
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event
> ev[],\
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> > uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port,
> \
> > struct rte_event ev[], \
> > - uint16_t nb_events); \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags); \
> >
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > #undef T
> > diff --git a/drivers/event/octeontx2/otx2_worker.c
> b/drivers/event/octeontx2/otx2_worker.c
> > index cd14cd3d2..100e21669 100644
> > --- a/drivers/event/octeontx2/otx2_worker.c
> > +++ b/drivers/event/octeontx2/otx2_worker.c
> > @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port, const
> struct rte_event ev[],
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t __hot \
> > otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[], \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws *ws = port; \
> > uint64_t cmd[sz]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags); \
> > return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> > }
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> > uint16_t __hot \
> > otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct rte_event ev[],\
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws *ws = port; \
> > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags); \
> > return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> > NIX_TX_MULTI_SEG_F); \
> > }
> > diff --git a/drivers/event/octeontx2/otx2_worker_dual.c
> b/drivers/event/octeontx2/otx2_worker_dual.c
> > index 37c274a54..c3e48da42 100644
> > --- a/drivers/event/octeontx2/otx2_worker_dual.c
> > +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> > @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> > uint16_t __hot \
> > otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> > struct rte_event ev[], \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws_dual *ws = port; \
> > struct otx2_ssogws *vws = \
> > @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port,
> \
> > uint64_t cmd[sz]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags); \
> > return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> > }
> > SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> > uint16_t __hot \
> > otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> > struct rte_event ev[], \
> > - uint16_t nb_events) \
> > + uint16_t nb_events, \
> > + uint8_t eq_flags) \
> > { \
> > struct otx2_ssogws_dual *ws = port; \
> > struct otx2_ssogws *vws = \
> > @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void
> *port, \
> > uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> > \
> > RTE_SET_USED(nb_events); \
> > + RTE_SET_USED(eq_flags); \
> > return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> > NIX_TX_MULTI_SEG_F); \
> > }
> > diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > index c848261c4..98be77568 100644
> > --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> > @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf
> *pkt)
> > int
> > rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t
> *event_port_id);
> >
> > +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> > +/**< This flag is used when all the packets enqueued in the tx adapter are
> > + * destined for the same Ethernet device, queue pair.
> > + */
> > +
> > /**
> > * Enqueue a burst of events objects or an event object supplied in
> *rte_event*
> > * structure on an event device designated by its *dev_id* through the event
> > @@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t
> id, uint8_t *event_port_id);
> > * The number of event objects to enqueue, typically number of
> > * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> > * available for this port.
> > + * @param flags
> > + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> > + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all
> the packets
> > + * which are enqueued are destined for the same Ethernet device, queue pair.
> > *
> > * @return
> > * The number of event objects actually enqueued on the event device. The
> > @@ -343,7 +352,8 @@ static inline uint16_t
> > rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > uint8_t port_id,
> > struct rte_event ev[],
> > - uint16_t nb_events)
> > + uint16_t nb_events,
> > + uint8_t flags)
> > {
> > const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
> >
> > @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> > return 0;
> > }
> > #endif
> > - return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
> > + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> > + nb_events, flags);
> > }
> >
> > /**
> > diff --git a/lib/librte_eventdev/rte_eventdev.c
> b/lib/librte_eventdev/rte_eventdev.c
> > index f44c869cb..3bf9d7115 100644
> > --- a/lib/librte_eventdev/rte_eventdev.c
> > +++ b/lib/librte_eventdev/rte_eventdev.c
> > @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> > static uint16_t
> > rte_event_tx_adapter_enqueue(__rte_unused void *port,
> > __rte_unused struct rte_event ev[],
> > - __rte_unused uint16_t nb_events)
> > + __rte_unused uint16_t nb_events,
> > + __rte_unused uint8_t flags)
> > {
> > rte_errno = ENOTSUP;
> > return 0;
> > diff --git a/lib/librte_eventdev/rte_eventdev.h
> b/lib/librte_eventdev/rte_eventdev.h
> > index 5044a13d0..2a5643da3 100644
> > --- a/lib/librte_eventdev/rte_eventdev.h
> > +++ b/lib/librte_eventdev/rte_eventdev.h
> > @@ -1227,7 +1227,7 @@ typedef uint16_t (*event_dequeue_burst_t)(void
> *port, struct rte_event ev[],
> > /**< @internal Dequeue burst of events from port of a device */
> >
> > typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> > - struct rte_event ev[], uint16_t nb_events);
> > + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> > /**< @internal Enqueue burst of events on port of a device */
> >
> > #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> > --
> > 2.17.1
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] mbuf: support dynamic fields and flags
@ 2019-10-01 10:49 0% ` Ananyev, Konstantin
2019-10-17 7:54 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-10-01 10:49 UTC (permalink / raw)
To: Olivier Matz, dev
Cc: Thomas Monjalon, Wang, Haiyue, Stephen Hemminger,
Andrew Rybchenko, Wiles, Keith, Jerin Jacob Kollanukkaran
Hi Olivier,
> Many features require to store data inside the mbuf. As the room in mbuf
> structure is limited, it is not possible to have a field for each
> feature. Also, changing fields in the mbuf structure can break the API
> or ABI.
>
> This commit addresses these issues, by enabling the dynamic registration
> of fields or flags:
>
> - a dynamic field is a named area in the rte_mbuf structure, with a
> given size (>= 1 byte) and alignment constraint.
> - a dynamic flag is a named bit in the rte_mbuf structure.
>
> The typical use case is a PMD that registers space for an offload
> feature, when the application requests to enable this feature. As
> the space in mbuf is limited, the space should only be reserved if it
> is going to be used (i.e when the application explicitly asks for it).
>
> The registration can be done at any moment, but it is not possible
> to unregister fields or flags for now.
Looks ok to me in general.
Some comments/suggestions inline.
Konstantin
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> Acked-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>
> rfc -> v1
>
> * Rebase on top of master
> * Change registration API to use a structure instead of
> variables, getting rid of #defines (Stephen's comment)
> * Update flag registration to use a similar API as fields.
> * Change max name length from 32 to 64 (sugg. by Thomas)
> * Enhance API documentation (Haiyue's and Andrew's comments)
> * Add a debug log at registration
> * Add some words in release note
> * Did some performance tests (sugg. by Andrew):
> On my platform, reading a dynamic field takes ~3 cycles more
> than a static field, and ~2 cycles more for writing.
>
> app/test/test_mbuf.c | 114 ++++++-
> doc/guides/rel_notes/release_19_11.rst | 7 +
> lib/librte_mbuf/Makefile | 2 +
> lib/librte_mbuf/meson.build | 6 +-
> lib/librte_mbuf/rte_mbuf.h | 25 +-
> lib/librte_mbuf/rte_mbuf_dyn.c | 408 +++++++++++++++++++++++++
> lib/librte_mbuf/rte_mbuf_dyn.h | 163 ++++++++++
> lib/librte_mbuf/rte_mbuf_version.map | 4 +
> 8 files changed, 724 insertions(+), 5 deletions(-)
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.c
> create mode 100644 lib/librte_mbuf/rte_mbuf_dyn.h
>
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -198,9 +198,12 @@ extern "C" {
> #define PKT_RX_OUTER_L4_CKSUM_GOOD (1ULL << 22)
> #define PKT_RX_OUTER_L4_CKSUM_INVALID ((1ULL << 21) | (1ULL << 22))
>
> -/* add new RX flags here */
> +/* add new RX flags here, don't forget to update PKT_FIRST_FREE */
>
> -/* add new TX flags here */
> +#define PKT_FIRST_FREE (1ULL << 23)
> +#define PKT_LAST_FREE (1ULL << 39)
> +
> +/* add new TX flags here, don't forget to update PKT_LAST_FREE */
>
> /**
> * Indicate that the metadata field in the mbuf is in use.
> @@ -738,6 +741,8 @@ struct rte_mbuf {
> */
> struct rte_mbuf_ext_shared_info *shinfo;
>
> + uint64_t dynfield1; /**< Reserved for dynamic fields. */
> + uint64_t dynfield2; /**< Reserved for dynamic fields. */
Wonder why just not one field:
union {
uint8_t u8[16];
...
uint64_t u64[2];
} dyn_field1;
?
Probably would be a bit handy, to refer, register, etc. no?
> } __rte_cache_aligned;
>
> /**
> @@ -1684,6 +1689,21 @@ rte_pktmbuf_attach_extbuf(struct rte_mbuf *m, void *buf_addr,
> */
> #define rte_pktmbuf_detach_extbuf(m) rte_pktmbuf_detach(m)
>
> +/**
> + * Copy dynamic fields from m_src to m_dst.
> + *
> + * @param m_dst
> + * The destination mbuf.
> + * @param m_src
> + * The source mbuf.
> + */
> +static inline void
> +rte_mbuf_dynfield_copy(struct rte_mbuf *m_dst, const struct rte_mbuf *m_src)
> +{
> + m_dst->dynfield1 = m_src->dynfield1;
> + m_dst->dynfield2 = m_src->dynfield2;
> +}
> +
> /**
> * Attach packet mbuf to another packet mbuf.
> *
> @@ -1732,6 +1752,7 @@ static inline void rte_pktmbuf_attach(struct rte_mbuf *mi, struct rte_mbuf *m)
> mi->vlan_tci_outer = m->vlan_tci_outer;
> mi->tx_offload = m->tx_offload;
> mi->hash = m->hash;
> + rte_mbuf_dynfield_copy(mi, m);
>
> mi->next = NULL;
> mi->pkt_len = mi->data_len;
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.c b/lib/librte_mbuf/rte_mbuf_dyn.c
> new file mode 100644
> index 000000000..13b8742d0
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.c
> @@ -0,0 +1,408 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#include <sys/queue.h>
> +
> +#include <rte_common.h>
> +#include <rte_eal.h>
> +#include <rte_eal_memconfig.h>
> +#include <rte_tailq.h>
> +#include <rte_errno.h>
> +#include <rte_malloc.h>
> +#include <rte_string_fns.h>
> +#include <rte_mbuf.h>
> +#include <rte_mbuf_dyn.h>
> +
> +#define RTE_MBUF_DYN_MZNAME "rte_mbuf_dyn"
> +
> +struct mbuf_dynfield_elt {
> + TAILQ_ENTRY(mbuf_dynfield_elt) next;
> + struct rte_mbuf_dynfield params;
> + int offset;
Why not 'size_t offset', to avoid any explicit conversions, etc?
> +};
> +TAILQ_HEAD(mbuf_dynfield_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynfield_tailq = {
> + .name = "RTE_MBUF_DYNFIELD",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynfield_tailq);
> +
> +struct mbuf_dynflag_elt {
> + TAILQ_ENTRY(mbuf_dynflag_elt) next;
> + struct rte_mbuf_dynflag params;
> + int bitnum;
> +};
> +TAILQ_HEAD(mbuf_dynflag_list, rte_tailq_entry);
> +
> +static struct rte_tailq_elem mbuf_dynflag_tailq = {
> + .name = "RTE_MBUF_DYNFLAG",
> +};
> +EAL_REGISTER_TAILQ(mbuf_dynflag_tailq);
> +
> +struct mbuf_dyn_shm {
> + /** For each mbuf byte, free_space[i] == 1 if space is free. */
> + uint8_t free_space[sizeof(struct rte_mbuf)];
> + /** Bitfield of available flags. */
> + uint64_t free_flags;
> +};
> +static struct mbuf_dyn_shm *shm;
> +
> +/* allocate and initialize the shared memory */
> +static int
> +init_shared_mem(void)
> +{
> + const struct rte_memzone *mz;
> + uint64_t mask;
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + mz = rte_memzone_reserve_aligned(RTE_MBUF_DYN_MZNAME,
> + sizeof(struct mbuf_dyn_shm),
> + SOCKET_ID_ANY, 0,
> + RTE_CACHE_LINE_SIZE);
> + } else {
> + mz = rte_memzone_lookup(RTE_MBUF_DYN_MZNAME);
> + }
> + if (mz == NULL)
> + return -1;
> +
> + shm = mz->addr;
> +
> +#define mark_free(field) \
> + memset(&shm->free_space[offsetof(struct rte_mbuf, field)], \
> + 0xff, sizeof(((struct rte_mbuf *)0)->field))
I think you can avoid defining/unedifying macros here by something like that:
static const struct {
size_t offset;
size_t size;
} dyn_syms[] = {
[0] = {.offset = offsetof(struct rte_mbuf, dynfield1), sizeof((struct rte_mbuf *)0)->dynfield1),
[1] = {.offset = offsetof(struct rte_mbuf, dynfield2), sizeof((struct rte_mbuf *)0)->dynfield2),
};
...
for (i = 0; i != RTE_DIM(dyn_syms); i++)
memset(shm->free_space + dym_syms[i].offset, UINT8_MAX, dym_syms[i].size);
> +
> + if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
> + /* init free_space, keep it sync'd with
> + * rte_mbuf_dynfield_copy().
> + */
> + memset(shm, 0, sizeof(*shm));
> + mark_free(dynfield1);
> + mark_free(dynfield2);
> +
> + /* init free_flags */
> + for (mask = PKT_FIRST_FREE; mask <= PKT_LAST_FREE; mask <<= 1)
> + shm->free_flags |= mask;
> + }
> +#undef mark_free
> +
> + return 0;
> +}
> +
> +/* check if this offset can be used */
> +static int
> +check_offset(size_t offset, size_t size, size_t align, unsigned int flags)
> +{
> + size_t i;
> +
> + (void)flags;
We have RTE_SET_USED() for such cases...
Though as it is an internal function probably better not to introduce
unused parameters at all.
> +
> + if ((offset & (align - 1)) != 0)
> + return -1;
> + if (offset + size > sizeof(struct rte_mbuf))
> + return -1;
> +
> + for (i = 0; i < size; i++) {
> + if (!shm->free_space[i + offset])
> + return -1;
> + }
> +
> + return 0;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynfield_elt *
> +__mbuf_dynfield_lookup(const char *name)
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynfield_list, next) {
> + mbuf_dynfield = (struct mbuf_dynfield_elt *)te->data;
> + if (strcmp(name, mbuf_dynfield->params.name) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynfield;
> +}
> +
> +int
> +rte_mbuf_dynfield_lookup(const char *name, struct rte_mbuf_dynfield *params)
> +{
> + struct mbuf_dynfield_elt *mbuf_dynfield;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynfield = __mbuf_dynfield_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynfield == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynfield->params, sizeof(*params));
> +
> + return mbuf_dynfield->offset;
> +}
> +
> +static int mbuf_dynfield_cmp(const struct rte_mbuf_dynfield *params1,
> + const struct rte_mbuf_dynfield *params2)
> +{
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->size != params2->size)
> + return -1;
> + if (params1->align != params2->align)
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +int
> +rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params)
What I meant at user-space - if we can also have another function that would allow
user to specify required offset for dynfield explicitly, then user can define it as constant
value and let compiler do optimization work and hopefully generate faster code to access
this field.
Something like that:
int rte_mbuf_dynfiled_register_offset(const struct rte_mbuf_dynfield *params, size_t offset);
#define RTE_MBUF_DYNFIELD_OFFSET(fld, off) (offsetof(struct rte_mbuf, fld) + (off))
And then somewhere in user code:
/* to let say reserve first 4B in dynfield1*/
#define MBUF_DYNFIELD_A RTE_MBUF_DYNFIELD_OFFSET(dynfiled1, 0)
...
params.name = RTE_STR(MBUF_DYNFIELD_A);
params.size = sizeof(uint32_t);
params.align = sizeof(uint32_t);
ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_A);
if (ret != MBUF_DYNFIELD_A) {
/* handle it somehow, probably just terminate gracefully... */
}
...
/* to let say reserve last 2B in dynfield2*/
#define MBUF_DYNFIELD_B RTE_MBUF_DYNFIELD_OFFSET(dynfiled2, 6)
...
params.name = RTE_STR(MBUF_DYNFIELD_B);
params.size = sizeof(uint16_t);
params.align = sizeof(uint16_t);
ret = rte_mbuf_dynfiled_register_offset(¶ms, MBUF_DYNFIELD_B);
After that user can use constant offsets MBUF_DYNFIELD_A/ MBUF_DYNFIELD_B
to access these fields.
Same thoughts for DYNFLAG.
> +{
> + struct mbuf_dynfield_list *mbuf_dynfield_list;
> + struct mbuf_dynfield_elt *mbuf_dynfield = NULL;
> + struct rte_tailq_entry *te = NULL;
> + int offset, ret;
size_t offset
to avoid explicit conversions, etc.?
> + size_t i;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + goto fail;
As I understand, here you allocate/initialize your shm without any lock protection,
though later you protect it via rte_mcfg_tailq_write_lock().
That seems a bit flakey to me.
Why not to store information about free dynfield bytes inside mbuf_dynfield_tailq?
Let say at init() create and add an entry into that list with some reserved name.
Then at register - grab mcfg_tailq_write_lock and do lookup
for such entry and then read/update it as needed.
It would help to avoid racing problem, plus you wouldn't need to
allocate/lookup for memzone.
> + if (params->size >= sizeof(struct rte_mbuf)) {
> + rte_errno = EINVAL;
> + goto fail;
> + }
> + if (!rte_is_power_of_2(params->align)) {
> + rte_errno = EINVAL;
> + goto fail;
> + }
> + if (params->flags != 0) {
> + rte_errno = EINVAL;
> + goto fail;
> + }
> +
> + rte_mcfg_tailq_write_lock();
> +
I think it probably would be cleaner and easier to read/maintain, if you'll put actual
code under lock protection into a separate function - as you did for __mbuf_dynfield_lookup().
> + mbuf_dynfield = __mbuf_dynfield_lookup(params->name);
> + if (mbuf_dynfield != NULL) {
> + if (mbuf_dynfield_cmp(params, &mbuf_dynfield->params) < 0) {
> + rte_errno = EEXIST;
> + goto fail_unlock;
> + }
> + offset = mbuf_dynfield->offset;
> + goto out_unlock;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + goto fail_unlock;
> + }
> +
> + for (offset = 0;
> + offset < (int)sizeof(struct rte_mbuf);
> + offset++) {
> + if (check_offset(offset, params->size, params->align,
> + params->flags) == 0)
> + break;
> + }
> +
> + if (offset == sizeof(struct rte_mbuf)) {
> + rte_errno = ENOENT;
> + goto fail_unlock;
> + }
> +
> + mbuf_dynfield_list = RTE_TAILQ_CAST(
> + mbuf_dynfield_tailq.head, mbuf_dynfield_list);
> +
> + te = rte_zmalloc("MBUF_DYNFIELD_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + goto fail_unlock;
> +
> + mbuf_dynfield = rte_zmalloc("mbuf_dynfield", sizeof(*mbuf_dynfield), 0);
> + if (mbuf_dynfield == NULL)
> + goto fail_unlock;
> +
> + ret = strlcpy(mbuf_dynfield->params.name, params->name,
> + sizeof(mbuf_dynfield->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynfield->params.name)) {
> + rte_errno = ENAMETOOLONG;
> + goto fail_unlock;
> + }
> + memcpy(&mbuf_dynfield->params, params, sizeof(mbuf_dynfield->params));
> + mbuf_dynfield->offset = offset;
> + te->data = mbuf_dynfield;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynfield_list, te, next);
> +
> + for (i = offset; i < offset + params->size; i++)
> + shm->free_space[i] = 0;
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic field %s (sz=%zu, al=%zu, fl=0x%x) -> %d\n",
> + params->name, params->size, params->align, params->flags,
> + offset);
> +
> +out_unlock:
> + rte_mcfg_tailq_write_unlock();
> +
> + return offset;
> +
> +fail_unlock:
> + rte_mcfg_tailq_write_unlock();
> +fail:
> + rte_free(mbuf_dynfield);
> + rte_free(te);
> + return -1;
> +}
> +
> +/* assume tailq is locked */
> +static struct mbuf_dynflag_elt *
> +__mbuf_dynflag_lookup(const char *name)
> +{
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> + struct rte_tailq_entry *te;
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + TAILQ_FOREACH(te, mbuf_dynflag_list, next) {
> + mbuf_dynflag = (struct mbuf_dynflag_elt *)te->data;
> + if (strncmp(name, mbuf_dynflag->params.name,
> + RTE_MBUF_DYN_NAMESIZE) == 0)
> + break;
> + }
> +
> + if (te == NULL) {
> + rte_errno = ENOENT;
> + return NULL;
> + }
> +
> + return mbuf_dynflag;
> +}
> +
> +int
> +rte_mbuf_dynflag_lookup(const char *name,
> + struct rte_mbuf_dynflag *params)
> +{
> + struct mbuf_dynflag_elt *mbuf_dynflag;
> +
> + if (shm == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + rte_mcfg_tailq_read_lock();
> + mbuf_dynflag = __mbuf_dynflag_lookup(name);
> + rte_mcfg_tailq_read_unlock();
> +
> + if (mbuf_dynflag == NULL) {
> + rte_errno = ENOENT;
> + return -1;
> + }
> +
> + if (params != NULL)
> + memcpy(params, &mbuf_dynflag->params, sizeof(*params));
> +
> + return mbuf_dynflag->bitnum;
> +}
> +
> +static int mbuf_dynflag_cmp(const struct rte_mbuf_dynflag *params1,
> + const struct rte_mbuf_dynflag *params2)
> +{
> + if (strcmp(params1->name, params2->name))
> + return -1;
> + if (params1->flags != params2->flags)
> + return -1;
> + return 0;
> +}
> +
> +int
> +rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params)
> +{
> + struct mbuf_dynflag_list *mbuf_dynflag_list;
> + struct mbuf_dynflag_elt *mbuf_dynflag = NULL;
> + struct rte_tailq_entry *te = NULL;
> + int bitnum, ret;
> +
> + if (shm == NULL && init_shared_mem() < 0)
> + goto fail;
> +
> + rte_mcfg_tailq_write_lock();
> +
> + mbuf_dynflag = __mbuf_dynflag_lookup(params->name);
> + if (mbuf_dynflag != NULL) {
> + if (mbuf_dynflag_cmp(params, &mbuf_dynflag->params) < 0) {
> + rte_errno = EEXIST;
> + goto fail_unlock;
> + }
> + bitnum = mbuf_dynflag->bitnum;
> + goto out_unlock;
> + }
> +
> + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> + rte_errno = EPERM;
> + goto fail_unlock;
> + }
> +
> + if (shm->free_flags == 0) {
> + rte_errno = ENOENT;
> + goto fail_unlock;
> + }
> + bitnum = rte_bsf64(shm->free_flags);
> +
> + mbuf_dynflag_list = RTE_TAILQ_CAST(
> + mbuf_dynflag_tailq.head, mbuf_dynflag_list);
> +
> + te = rte_zmalloc("MBUF_DYNFLAG_TAILQ_ENTRY", sizeof(*te), 0);
> + if (te == NULL)
> + goto fail_unlock;
> +
> + mbuf_dynflag = rte_zmalloc("mbuf_dynflag", sizeof(*mbuf_dynflag), 0);
> + if (mbuf_dynflag == NULL)
> + goto fail_unlock;
> +
> + ret = strlcpy(mbuf_dynflag->params.name, params->name,
> + sizeof(mbuf_dynflag->params.name));
> + if (ret < 0 || ret >= (int)sizeof(mbuf_dynflag->params.name)) {
> + rte_errno = ENAMETOOLONG;
> + goto fail_unlock;
> + }
> + mbuf_dynflag->bitnum = bitnum;
> + te->data = mbuf_dynflag;
> +
> + TAILQ_INSERT_TAIL(mbuf_dynflag_list, te, next);
> +
> + shm->free_flags &= ~(1ULL << bitnum);
> +
> + RTE_LOG(DEBUG, MBUF, "Registered dynamic flag %s (fl=0x%x) -> %u\n",
> + params->name, params->flags, bitnum);
> +
> +out_unlock:
> + rte_mcfg_tailq_write_unlock();
> +
> + return bitnum;
> +
> +fail_unlock:
> + rte_mcfg_tailq_write_unlock();
> +fail:
> + rte_free(mbuf_dynflag);
> + rte_free(te);
> + return -1;
> +}
> diff --git a/lib/librte_mbuf/rte_mbuf_dyn.h b/lib/librte_mbuf/rte_mbuf_dyn.h
> new file mode 100644
> index 000000000..6e2c81654
> --- /dev/null
> +++ b/lib/librte_mbuf/rte_mbuf_dyn.h
> @@ -0,0 +1,163 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright 2019 6WIND S.A.
> + */
> +
> +#ifndef _RTE_MBUF_DYN_H_
> +#define _RTE_MBUF_DYN_H_
> +
> +/**
> + * @file
> + * RTE Mbuf dynamic fields and flags
> + *
> + * Many features require to store data inside the mbuf. As the room in
> + * mbuf structure is limited, it is not possible to have a field for
> + * each feature. Also, changing fields in the mbuf structure can break
> + * the API or ABI.
> + *
> + * This module addresses this issue, by enabling the dynamic
> + * registration of fields or flags:
> + *
> + * - a dynamic field is a named area in the rte_mbuf structure, with a
> + * given size (>= 1 byte) and alignment constraint.
> + * - a dynamic flag is a named bit in the rte_mbuf structure, stored
> + * in mbuf->ol_flags.
> + *
> + * The typical use case is when a specific offload feature requires to
> + * register a dedicated offload field in the mbuf structure, and adding
> + * a static field or flag is not justified.
> + *
> + * Example of use:
> + *
> + * - A rte_mbuf_dynfield structure is defined, containing the parameters
> + * of the dynamic field to be registered:
> + * const struct rte_mbuf_dynfield rte_dynfield_my_feature = { ... };
> + * - The application initializes the PMD, and asks for this feature
> + * at port initialization by passing DEV_RX_OFFLOAD_MY_FEATURE in
> + * rxconf. This will make the PMD to register the field by calling
> + * rte_mbuf_dynfield_register(&rte_dynfield_my_feature). The PMD
> + * stores the returned offset.
> + * - The application that uses the offload feature also registers
> + * the field to retrieve the same offset.
> + * - When the PMD receives a packet, it can set the field:
> + * *RTE_MBUF_DYNFIELD(m, offset, <type *>) = value;
> + * - In the main loop, the application can retrieve the value with
> + * the same macro.
> + *
> + * To avoid wasting space, the dynamic fields or flags must only be
> + * reserved on demand, when an application asks for the related feature.
> + *
> + * The registration can be done at any moment, but it is not possible
> + * to unregister fields or flags for now.
> + *
> + * A dynamic field can be reserved and used by an application only.
> + * It can for instance be a packet mark.
> + */
> +
> +#include <sys/types.h>
> +/**
> + * Maximum length of the dynamic field or flag string.
> + */
> +#define RTE_MBUF_DYN_NAMESIZE 64
> +
> +/**
> + * Structure describing the parameters of a mbuf dynamic field.
> + */
> +struct rte_mbuf_dynfield {
> + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the field. */
> + size_t size; /**< The number of bytes to reserve. */
> + size_t align; /**< The alignment constraint (power of 2). */
> + unsigned int flags; /**< Reserved for future use, must be 0. */
> +};
> +
> +/**
> + * Structure describing the parameters of a mbuf dynamic flag.
> + */
> +struct rte_mbuf_dynflag {
> + char name[RTE_MBUF_DYN_NAMESIZE]; /**< Name of the dynamic flag. */
> + unsigned int flags; /**< Reserved for future use, must be 0. */
> +};
> +
> +/**
> + * Register space for a dynamic field in the mbuf structure.
> + *
> + * If the field is already registered (same name and parameters), its
> + * offset is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters (name, size,
> + * alignment constraint and flags).
> + * @return
> + * The offset in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, or flags).
> + * - EEXIST: this name is already register with different parameters.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: not enough room in mbuf.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name does not ends with \0.
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_register(const struct rte_mbuf_dynfield *params);
> +
> +/**
> + * Lookup for a registered dynamic mbuf field.
> + *
> + * @param name
> + * A string identifying the dynamic field.
> + * @param params
> + * If not NULL, and if the lookup is successful, the structure is
> + * filled with the parameters of the dynamic field.
> + * @return
> + * The offset of this field in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - ENOENT: no dynamic field matches this name.
> + */
> +__rte_experimental
> +int rte_mbuf_dynfield_lookup(const char *name,
> + struct rte_mbuf_dynfield *params);
> +
> +/**
> + * Register a dynamic flag in the mbuf structure.
> + *
> + * If the flag is already registered (same name and parameters), its
> + * offset is returned.
> + *
> + * @param params
> + * A structure containing the requested parameters of the dynamic
> + * flag (name and options).
> + * @return
> + * The number of the reserved bit, or -1 on error.
> + * Possible values for rte_errno:
> + * - EINVAL: invalid parameters (size, align, or flags).
> + * - EEXIST: this name is already register with different parameters.
> + * - EPERM: called from a secondary process.
> + * - ENOENT: no more flag available.
> + * - ENOMEM: allocation failure.
> + * - ENAMETOOLONG: name is longer than RTE_MBUF_DYN_NAMESIZE - 1.
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_register(const struct rte_mbuf_dynflag *params);
> +
> +/**
> + * Lookup for a registered dynamic mbuf flag.
> + *
> + * @param name
> + * A string identifying the dynamic flag.
> + * @param params
> + * If not NULL, and if the lookup is successful, the structure is
> + * filled with the parameters of the dynamic flag.
> + * @return
> + * The offset of this flag in the mbuf structure, or -1 on error.
> + * Possible values for rte_errno:
> + * - ENOENT: no dynamic flag matches this name.
> + */
> +__rte_experimental
> +int rte_mbuf_dynflag_lookup(const char *name,
> + struct rte_mbuf_dynflag *params);
> +
> +/**
> + * Helper macro to access to a dynamic field.
> + */
> +#define RTE_MBUF_DYNFIELD(m, offset, type) ((type)((uintptr_t)(m) + (offset)))
> +
> +#endif
> diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
> index 2662a37bf..a98310570 100644
> --- a/lib/librte_mbuf/rte_mbuf_version.map
> +++ b/lib/librte_mbuf/rte_mbuf_version.map
> @@ -50,4 +50,8 @@ EXPERIMENTAL {
> global:
>
> rte_mbuf_check;
> + rte_mbuf_dynfield_lookup;
> + rte_mbuf_dynfield_register;
> + rte_mbuf_dynflag_lookup;
> + rte_mbuf_dynflag_register;
> } DPDK_18.08;
> --
> 2.20.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue
@ 2019-10-01 7:44 4% ` Jerin Jacob
2019-10-01 11:41 0% ` Nipun Gupta
2019-10-01 14:42 3% ` Aaron Conole
` (4 subsequent siblings)
5 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2019-10-01 7:44 UTC (permalink / raw)
To: Nipun Gupta
Cc: dpdk-dev, Jerin Jacob, Pavan Nikhilesh, Sunil Kumar Kori,
Hemant Agrawal, Richardson, Bruce, Marko Kovacevic, Ori Kam,
Radu Nicolau, Tomasz Kantecki, Van Haaren, Harry, nikhil.rao
On Tue, Oct 1, 2019 at 12:32 PM Nipun Gupta <nipun.gupta@nxp.com> wrote:
>
> This patch introduces a `flag` in the Eth TX adapter enqueue API.
> Some drivers may support burst functionality only with the packets
> having same destination device and queue.
>
> The flag `RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST` can be used
> to indicate this so the underlying driver, for drivers to utilize
> burst functionality appropriately.
I understand the cost of aggregating packets based on port and queue
to make it burst.
But, Could you share the use case where how do you want to use this
flag? I see two possibilities in eventdev context.
(Where dequeue can be from any ethdev port)
a) The application does the aggregation. If so, what would the
difference be in doing driver or application?
b) We may use this flag when the system has only one port and one queue.
Could you share how do you want to use this flag?
And another point is, tx adapter is NOT experimental now, We need
depreciation notice for ABI change.
If you share the exact use case, then we could think of adding a new
symbol instead of breaking ABI and
add it for next release.
> Signed-off-by: Nipun Gupta <nipun.gupta@nxp.com>
> ---
> app/test-eventdev/test_pipeline_common.h | 6 +++---
> .../prog_guide/event_ethernet_tx_adapter.rst | 3 ++-
> drivers/event/octeontx/ssovf_evdev.h | 2 +-
> drivers/event/octeontx/ssovf_worker.c | 3 ++-
> drivers/event/octeontx2/otx2_evdev.h | 12 ++++++++----
> drivers/event/octeontx2/otx2_worker.c | 8 ++++++--
> drivers/event/octeontx2/otx2_worker_dual.c | 8 ++++++--
> lib/librte_eventdev/rte_event_eth_tx_adapter.h | 15 +++++++++++++--
> lib/librte_eventdev/rte_eventdev.c | 3 ++-
> lib/librte_eventdev/rte_eventdev.h | 2 +-
> 10 files changed, 44 insertions(+), 18 deletions(-)
>
> diff --git a/app/test-eventdev/test_pipeline_common.h b/app/test-eventdev/test_pipeline_common.h
> index 0440b9e29..6e73c6ab2 100644
> --- a/app/test-eventdev/test_pipeline_common.h
> +++ b/app/test-eventdev/test_pipeline_common.h
> @@ -106,7 +106,7 @@ pipeline_event_tx(const uint8_t dev, const uint8_t port,
> struct rte_event * const ev)
> {
> rte_event_eth_tx_adapter_txq_set(ev->mbuf, 0);
> - while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1))
> + while (!rte_event_eth_tx_adapter_enqueue(dev, port, ev, 1, 0))
> rte_pause();
> }
>
> @@ -116,10 +116,10 @@ pipeline_event_tx_burst(const uint8_t dev, const uint8_t port,
> {
> uint16_t enq;
>
> - enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx);
> + enq = rte_event_eth_tx_adapter_enqueue(dev, port, ev, nb_rx, 0);
> while (enq < nb_rx) {
> enq += rte_event_eth_tx_adapter_enqueue(dev, port,
> - ev + enq, nb_rx - enq);
> + ev + enq, nb_rx - enq, 0);
> }
> }
>
> diff --git a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> index 192f9e1cf..a8c13e136 100644
> --- a/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> +++ b/doc/guides/prog_guide/event_ethernet_tx_adapter.rst
> @@ -137,11 +137,12 @@ should use the ``rte_event_enqueue_burst()`` function.
> if (cap & RTE_EVENT_ETH_TX_ADAPTER_CAP_INTERNAL_PORT) {
>
> event.mbuf = m;
> + eq_flags = 0;
>
> m->port = tx_port;
> rte_event_eth_tx_adapter_txq_set(m, tx_queue_id);
>
> - rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1);
> + rte_event_eth_tx_adapter_enqueue(dev_id, ev_port, &event, 1, eq_flags);
> } else {
>
> event.queue_id = qid; /* event queue linked to adapter port */
> diff --git a/drivers/event/octeontx/ssovf_evdev.h b/drivers/event/octeontx/ssovf_evdev.h
> index 0e622152c..1b156edab 100644
> --- a/drivers/event/octeontx/ssovf_evdev.h
> +++ b/drivers/event/octeontx/ssovf_evdev.h
> @@ -181,7 +181,7 @@ void ssows_flush_events(struct ssows *ws, uint8_t queue_id,
> ssows_handle_event_t fn, void *arg);
> void ssows_reset(struct ssows *ws);
> uint16_t sso_event_tx_adapter_enqueue(void *port,
> - struct rte_event ev[], uint16_t nb_events);
> + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags);
> int ssovf_info(struct ssovf_info *info);
> void *ssovf_bar(enum ssovf_type, uint8_t id, uint8_t bar);
> int test_eventdev_octeontx(void);
> diff --git a/drivers/event/octeontx/ssovf_worker.c b/drivers/event/octeontx/ssovf_worker.c
> index d940b5dd6..1d0467af3 100644
> --- a/drivers/event/octeontx/ssovf_worker.c
> +++ b/drivers/event/octeontx/ssovf_worker.c
> @@ -264,7 +264,7 @@ ssows_reset(struct ssows *ws)
>
> uint16_t
> sso_event_tx_adapter_enqueue(void *port,
> - struct rte_event ev[], uint16_t nb_events)
> + struct rte_event ev[], uint16_t nb_events, uint8_t eq_flags)
> {
> uint16_t port_id;
> uint16_t queue_id;
> @@ -275,6 +275,7 @@ sso_event_tx_adapter_enqueue(void *port,
> octeontx_dq_t *dq;
>
> RTE_SET_USED(nb_events);
> + RTE_SET_USED(eq_flags);
> switch (ev->sched_type) {
> case SSO_SYNC_ORDERED:
> ssows_swtag_norm(ws, ev->event, SSO_SYNC_ATOMIC);
> diff --git a/drivers/event/octeontx2/otx2_evdev.h b/drivers/event/octeontx2/otx2_evdev.h
> index 5cd80e3b2..74b749a15 100644
> --- a/drivers/event/octeontx2/otx2_evdev.h
> +++ b/drivers/event/octeontx2/otx2_evdev.h
> @@ -333,16 +333,20 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
>
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[],\
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
> uint16_t otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events); \
> + uint16_t nb_events, \
> + uint8_t eq_flags); \
>
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> #undef T
> diff --git a/drivers/event/octeontx2/otx2_worker.c b/drivers/event/octeontx2/otx2_worker.c
> index cd14cd3d2..100e21669 100644
> --- a/drivers/event/octeontx2/otx2_worker.c
> +++ b/drivers/event/octeontx2/otx2_worker.c
> @@ -270,12 +270,14 @@ otx2_ssogws_enq_fwd_burst(void *port, const struct rte_event ev[],
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t __hot \
> otx2_ssogws_tx_adptr_enq_ ## name(void *port, struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws *ws = port; \
> uint64_t cmd[sz]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(ws, ev, cmd, flags); \
> }
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> @@ -284,12 +286,14 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> #define T(name, f4, f3, f2, f1, f0, sz, flags) \
> uint16_t __hot \
> otx2_ssogws_tx_adptr_enq_seg_ ## name(void *port, struct rte_event ev[],\
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws *ws = port; \
> uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(ws, ev, cmd, (flags) | \
> NIX_TX_MULTI_SEG_F); \
> }
> diff --git a/drivers/event/octeontx2/otx2_worker_dual.c b/drivers/event/octeontx2/otx2_worker_dual.c
> index 37c274a54..c3e48da42 100644
> --- a/drivers/event/octeontx2/otx2_worker_dual.c
> +++ b/drivers/event/octeontx2/otx2_worker_dual.c
> @@ -310,7 +310,8 @@ SSO_RX_ADPTR_ENQ_FASTPATH_FUNC
> uint16_t __hot \
> otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws_dual *ws = port; \
> struct otx2_ssogws *vws = \
> @@ -318,6 +319,7 @@ otx2_ssogws_dual_tx_adptr_enq_ ## name(void *port, \
> uint64_t cmd[sz]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(vws, ev, cmd, flags); \
> }
> SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> @@ -327,7 +329,8 @@ SSO_TX_ADPTR_ENQ_FASTPATH_FUNC
> uint16_t __hot \
> otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> struct rte_event ev[], \
> - uint16_t nb_events) \
> + uint16_t nb_events, \
> + uint8_t eq_flags) \
> { \
> struct otx2_ssogws_dual *ws = port; \
> struct otx2_ssogws *vws = \
> @@ -335,6 +338,7 @@ otx2_ssogws_dual_tx_adptr_enq_seg_ ## name(void *port, \
> uint64_t cmd[(sz) + NIX_TX_MSEG_SG_DWORDS - 2]; \
> \
> RTE_SET_USED(nb_events); \
> + RTE_SET_USED(eq_flags); \
> return otx2_ssogws_event_tx(vws, ev, cmd, (flags) | \
> NIX_TX_MULTI_SEG_F); \
> }
> diff --git a/lib/librte_eventdev/rte_event_eth_tx_adapter.h b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> index c848261c4..98be77568 100644
> --- a/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> +++ b/lib/librte_eventdev/rte_event_eth_tx_adapter.h
> @@ -300,6 +300,11 @@ rte_event_eth_tx_adapter_txq_get(struct rte_mbuf *pkt)
> int
> rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
>
> +#define RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST 0x1
> +/**< This flag is used when all the packets enqueued in the tx adapter are
> + * destined for the same Ethernet device, queue pair.
> + */
> +
> /**
> * Enqueue a burst of events objects or an event object supplied in *rte_event*
> * structure on an event device designated by its *dev_id* through the event
> @@ -324,6 +329,10 @@ rte_event_eth_tx_adapter_event_port_get(uint8_t id, uint8_t *event_port_id);
> * The number of event objects to enqueue, typically number of
> * rte_event_port_attr_get(...RTE_EVENT_PORT_ATTR_ENQ_DEPTH...)
> * available for this port.
> + * @param flags
> + * See RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_ flags.
> + * #RTE_EVENT_ETH_TX_ADAPTER_ENQUEUE_SAME_DEST signifies that all the packets
> + * which are enqueued are destined for the same Ethernet device, queue pair.
> *
> * @return
> * The number of event objects actually enqueued on the event device. The
> @@ -343,7 +352,8 @@ static inline uint16_t
> rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> uint8_t port_id,
> struct rte_event ev[],
> - uint16_t nb_events)
> + uint16_t nb_events,
> + uint8_t flags)
> {
> const struct rte_eventdev *dev = &rte_eventdevs[dev_id];
>
> @@ -359,7 +369,8 @@ rte_event_eth_tx_adapter_enqueue(uint8_t dev_id,
> return 0;
> }
> #endif
> - return dev->txa_enqueue(dev->data->ports[port_id], ev, nb_events);
> + return dev->txa_enqueue(dev->data->ports[port_id], ev,
> + nb_events, flags);
> }
>
> /**
> diff --git a/lib/librte_eventdev/rte_eventdev.c b/lib/librte_eventdev/rte_eventdev.c
> index f44c869cb..3bf9d7115 100644
> --- a/lib/librte_eventdev/rte_eventdev.c
> +++ b/lib/librte_eventdev/rte_eventdev.c
> @@ -1324,7 +1324,8 @@ rte_eventdev_find_free_device_index(void)
> static uint16_t
> rte_event_tx_adapter_enqueue(__rte_unused void *port,
> __rte_unused struct rte_event ev[],
> - __rte_unused uint16_t nb_events)
> + __rte_unused uint16_t nb_events,
> + __rte_unused uint8_t flags)
> {
> rte_errno = ENOTSUP;
> return 0;
> diff --git a/lib/librte_eventdev/rte_eventdev.h b/lib/librte_eventdev/rte_eventdev.h
> index 5044a13d0..2a5643da3 100644
> --- a/lib/librte_eventdev/rte_eventdev.h
> +++ b/lib/librte_eventdev/rte_eventdev.h
> @@ -1227,7 +1227,7 @@ typedef uint16_t (*event_dequeue_burst_t)(void *port, struct rte_event ev[],
> /**< @internal Dequeue burst of events from port of a device */
>
> typedef uint16_t (*event_tx_adapter_enqueue)(void *port,
> - struct rte_event ev[], uint16_t nb_events);
> + struct rte_event ev[], uint16_t nb_events, uint8_t flags);
> /**< @internal Enqueue burst of events on port of a device */
>
> #define RTE_EVENTDEV_NAME_MAX_LEN (64)
> --
> 2.17.1
>
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3 0/6] mbuf copy/cloning enhancements
2019-09-30 15:27 3% ` [dpdk-dev] [PATCH v2 0/6] mbuf copy related enhancements Stephen Hemminger
@ 2019-09-30 19:20 3% ` Stephen Hemminger
2019-10-04 21:47 3% ` [dpdk-dev] [PATCH v4 0/4] " Stephen Hemminger
` (2 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-09-30 19:20 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This patch set is all about improving the mbuf related cloning
and copying. They are motivated by seeing issues with mbuf copying
in rte_pdump and realized this a wider and more general problem.
The pdump copy could not handle different size pools and did
not handle meta data, etc.
They cause no functional or ABI changes. The only visible part
to older code is converting a couple of inlines to real functions.
This kind of change confuses checkpatch which thinks these new
functions should be marked experimental when they must not be.
v3 - split linearize into internal/external
copy private data in pktmbuf_copy
v2 - add pdump use of pktmbuf_copy
fix version in map
Stephen Hemminger (6):
mbuf: don't generate invalid mbuf in clone test
mbuf: delinline rte_pktmbuf_linearize
mbuf: deinline rte_pktmbuf_clone
mbuf: add a pktmbuf copy routine
mbuf: add pktmbuf copy test
pdump: use new pktmbuf copy function
app/test/test_mbuf.c | 129 +++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.c | 150 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 100 ++++++------------
lib/librte_mbuf/rte_mbuf_version.map | 8 ++
lib/librte_pdump/rte_pdump.c | 69 +-----------
5 files changed, 321 insertions(+), 135 deletions(-)
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 0/6] mbuf copy related enhancements
@ 2019-09-30 15:27 3% ` Stephen Hemminger
2019-09-30 19:20 3% ` [dpdk-dev] [PATCH v3 0/6] mbuf copy/cloning enhancements Stephen Hemminger
` (3 subsequent siblings)
4 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2019-09-30 15:27 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
This patch set is all about improving the mbuf related cloning
and copying. They are motivated by seeing issues with mbuf copying
in rte_pdump and realized this a wider and more general problem.
The pdump copy could not handle different size pools and did
not handle meta data, etc.
They cause no functional or ABI changes. The only visible part
to older code is converting a couple of inlines to real functions.
This kind of change confuses checkpatch which thinks these new
functions should be marked experimental when they must not be.
v2 - add pdump use of pktmbuf_copy
fix version in map
Stephen Hemminger (6):
mbuf: don't generate invalid mbuf in clone test
mbuf: delinline rte_pktmbuf_linearize
mbuf: deinline rte_pktmbuf_clone
mbuf: add a pktmbuf copy routine
mbuf: add pktmbuf copy test
pdump: use new pktmbuf copy function
app/test/test_mbuf.c | 129 +++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.c | 149 +++++++++++++++++++++++++++
lib/librte_mbuf/rte_mbuf.h | 102 ++++++------------
lib/librte_mbuf/rte_mbuf_version.map | 8 ++
lib/librte_pdump/rte_pdump.c | 69 +------------
5 files changed, 316 insertions(+), 141 deletions(-)
--
2.20.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd
2019-09-30 14:00 3% [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd Xiaoyun wang
@ 2019-09-30 15:06 0% ` Ferruh Yigit
2019-10-08 15:14 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2019-09-30 15:06 UTC (permalink / raw)
To: Xiaoyun wang
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1
On 9/30/2019 3:00 PM, Xiaoyun wang wrote:
> This patch set adds advanced features for Huawei hinic pmd,
> such as VLAN filter and VLAN offload, SR-IOV, FW version get,
> set link down and up, Flow director for LACP, VRRP, BGP and so on.
>
> --
> v2:
> - Fix RSS bugs for vxlan packets inner type
> - Add comments for new added func interface
> - Fix code review comments from patch v1
> - Fix code style problems
> - Remove ceq interfaces and definitions that not used
> - Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
> - Fix bar map bugs for VF Page size larger than PF
> - Modify link state set, add enable or disable fiber in tx direction
> - Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
> - Fix FDIR bugs for VRRP packets
> - Fit ABI changes from dpdk lib
>
> v3:
> - Split hinic.ini and hinic.rst to related feature patches
> - Add min_mtu & max_mtu initialization for hinic_dev_infos_get
> - Fix fdir config patch with net/hinic/base
> - Split link patch into link and fw version getting 2 patches
> - Update pmd doc files to new next version
> - Add comments for cover letter patch
> - Add rxq & txq info getting interfaces
> - Fix load intrinsics for receiving packets
>
> Xiaoyun wang (19):
> net/hinic/base: add mbox command channel for SRIOV
> net/hinic/base: add HW interfaces for SR-IOV
> net/hinic: add VF PMD operation interfaces
> net/hinic: add VLAN filter and offload
> net/hinic: add allmulticast mode and MTU set
> net/hinic: add unicast and multicast MAC set
> net/hinic/base: add fdir config interface
> net/hinic: add fdir validate flow operations
> net/hinic: create and destroy ntuple filter
> net/hinic: create and destroy fdir filter
> net/hinic: flush fdir filter
> net/hinic: set link down and up
> net/hinic: get firmware version
> net/hinic: support inner L3 checksum offload
> net/hinic: support LRO offload
> net/hinic: add hinic PMD doc files
> net/hinic/base: optimize aeq interfaces
> net/hinic: optimize RX performance
> net/hinic: add support for getting rxq or txq info
There is following 32-bit build error because of the log formatting [1], can you
please check it?
[1]
.../drivers/net/hinic/base/hinic_pmd_mbox.c(659):
error #181: argument of type "unsigned long long" is incompatible with format
"%lx", expecting argument of type "unsigned long"
PMD_DRV_LOG(ERR, "Fail to send mbox seg, seq_id: 0x%lx,
err: %d",
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 15/17] net/hinic: add hinic PMD doc files
@ 2019-09-30 14:15 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
0 siblings, 0 replies; 200+ results
From: Wangxiaoyun (Cloud, Network Chip Application Development Dept) @ 2019-09-30 14:15 UTC (permalink / raw)
To: Ferruh Yigit
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1
Hi Ferruh,
Thanks for your comments. I send to you a new patch V3 with the following review comments fixed.
1) I have fixed SR-IOV with unix style;
2) I splited the hinic.ini and hinic.rst into releated feature patches;
3) I have updated the release_19_11.rst with next version.
Best regards
Xiaoyun Wang
在 2019/9/27 2:51, Ferruh Yigit 写道:
> On 9/25/2019 3:30 PM, Xiaoyun wang wrote:
>> Add doc files about new features and modification.
>>
>> Signed-off-by: Xiaoyun wang <cloud.wangxiaoyun@huawei.com>
>> ---
>> doc/guides/nics/features/hinic.ini | 12 ++++++++-
>> doc/guides/nics/hinic.rst | 6 +++++
>> doc/guides/rel_notes/release_19_11.rst | 45 ++++++----------------------------
>> 3 files changed, 25 insertions(+), 38 deletions(-)
>>
>> diff --git a/doc/guides/nics/features/hinic.ini b/doc/guides/nics/features/hinic.ini
>> index fe063d6..dc02b4b 100644
>> --- a/doc/guides/nics/features/hinic.ini
>> +++ b/doc/guides/nics/features/hinic.ini
>> @@ -9,16 +9,22 @@ Link status = Y
>> Link status event = Y
>> Free Tx mbuf on demand = Y
>> Queue start/stop = Y
>> -Jumbo frame = N
>> +MTU update = Y
>> +Jumbo frame = Y
>> Scattered Rx = Y
>> TSO = Y
>> +LRO = Y
>> Promiscuous mode = Y
>> +Allmulticast mode = Y
>> Unicast MAC filter = Y
>> Multicast MAC filter = Y
>> RSS hash = Y
>> RSS key update = Y
>> RSS reta update = Y
>> Inner RSS = Y
>> +SR-IOV = Y
>> +VLAN filter = Y
>> +VLAN offload = Y
>> CRC offload = Y
>> L3 checksum offload = Y
>> L4 checksum offload = Y
>> @@ -27,6 +33,10 @@ Inner L4 checksum = Y
>> Basic stats = Y
>> Extended stats = Y
>> Stats per queue = Y
>> +Flow director = Y
>> +Flow control = Y
>> +FW version = Y
>> +Multiprocess aware = Y
>> Linux UIO = Y
>> Linux VFIO = Y
>> BSD nic_uio = N
>> diff --git a/doc/guides/nics/hinic.rst b/doc/guides/nics/hinic.rst
>> index c9329bc..f036fc5 100644
>> --- a/doc/guides/nics/hinic.rst
>> +++ b/doc/guides/nics/hinic.rst
>> @@ -24,6 +24,12 @@ Features
>> - Link state information
>> - Link flow control
>> - Scattered and gather for TX and RX
>> +- SR�CIOV - Partially supported at this point, VFIO only
> Can you fix the char is SR-IOV?
>
>> +- Allmulticast mode
>> +- Unicast MAC filter
>> +- Multicast MAC filter
>> +- FW version
>> +- Flow director
>>
>> Prerequisites
>> -------------
>> diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
>> index 65361c4..6c6f27f 100644
>> --- a/doc/guides/rel_notes/release_19_11.rst
>> +++ b/doc/guides/rel_notes/release_19_11.rst
>> @@ -56,11 +56,15 @@ New Features
>> Also, make sure to start the actual text at the margin.
>> =========================================================
>>
>> -* **Updated the Intel ice driver.**
>> +* **Updated the Huawei hinic driver.**
>>
>> - Updated the Intel ice driver with new features and improvements, including:
>> + Updated the Huawei hinic driver with new features and improvements, including:
>>
>> - * Added support for device-specific DDP package loading.
>> + * Enabled SR-IOV - Partially supported at this point, VFIO only.
>> + * Supported VLAN filter and VLAN offload.
>> + * Supported Unicast MAC filter and Multicast MAC filter.
>> + * Supported FW version get.
>> + * Supported Flow director for LACP, VRRP, BGP and so on.
>
> Can you please distribute the doc patches in to the related patches that
> introduces the feature, for all three document, it helps by documenting what has
> been added in the patch.
>
>>
>> Removed Items
>> -------------
>> @@ -99,30 +103,6 @@ API Changes
>> Also, make sure to start the actual text at the margin.
>> =========================================================
>>
>> -* ethdev: changed ``rte_eth_dev_infos_get`` return value from ``void`` to
>> - ``int`` to provide a way to report various error conditions.
>> -
>> -* ethdev: changed ``rte_eth_promiscuous_enable`` and
>> - ``rte_eth_promiscuous_disable`` return value from ``void`` to ``int`` to
>> - provide a way to report various error conditions.
>> -
>> -* ethdev: changed ``rte_eth_allmulticast_enable`` and
>> - ``rte_eth_allmulticast_disable`` return value from ``void`` to ``int`` to
>> - provide a way to report various error conditions.
>> -
>> -* ethdev: changed ``rte_eth_dev_xstats_reset`` return value from ``void`` to
>> - ``int`` to provide a way to report various error conditions.
>> -
>> -* ethdev: changed ``rte_eth_link_get`` and ``rte_eth_link_get_nowait``
>> - return value from ``void`` to ``int`` to provide a way to report various
>> - error conditions.
>> -
>> -* ethdev: changed ``rte_eth_macaddr_get`` return value from ``void`` to
>> - ``int`` to provide a way to report various error conditions.
>> -
>> -* ethdev: changed ``rte_eth_dev_owner_delete`` return value from ``void`` to
>> - ``int`` to provide a way to report various error conditions.
>> -
>>
>> ABI Changes
>> -----------
>> @@ -174,7 +154,7 @@ The libraries prepended with a plus sign were incremented in this version.
>> librte_distributor.so.1
>> librte_eal.so.11
>> librte_efd.so.1
>> - + librte_ethdev.so.13
>> + librte_ethdev.so.12
>> librte_eventdev.so.7
>> librte_flow_classify.so.1
>> librte_gro.so.1
>> @@ -252,12 +232,3 @@ Tested Platforms
>> Also, make sure to start the actual text at the margin.
>> =========================================================
>>
>> -* **Updated Mellanox mlx5 driver.**
>> -
>> - Updated Mellanox mlx5 driver with new features and improvements, including:
>> -
>> - * Added support for VLAN pop flow offload command.
>> - * Added support for VLAN push flow offload command.
>> - * Added support for VLAN set PCP offload command.
>> - * Added support for VLAN set VID offload command.
>> -
>>
> I guess above changes are git mistake, please check in next version.
>
> .
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd
@ 2019-09-30 14:00 3% Xiaoyun wang
2019-09-30 15:06 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Xiaoyun wang @ 2019-09-30 14:00 UTC (permalink / raw)
To: ferruh.yigit
Cc: dev, xuanziyang2, shahar.belkar, luoxianjun, tanya.brokhman,
zhouguoyang, wulike1, Xiaoyun wang
This patch set adds advanced features for Huawei hinic pmd,
such as VLAN filter and VLAN offload, SR-IOV, FW version get,
set link down and up, Flow director for LACP, VRRP, BGP and so on.
--
v2:
- Fix RSS bugs for vxlan packets inner type
- Add comments for new added func interface
- Fix code review comments from patch v1
- Fix code style problems
- Remove ceq interfaces and definitions that not used
- Fix aeq init bugs, firstly alloc aeq resource, then set aeq ctrl len
- Fix bar map bugs for VF Page size larger than PF
- Modify link state set, add enable or disable fiber in tx direction
- Fix mbox and mgmt channel sync lock mechanism to reduce CPU usage
- Fix FDIR bugs for VRRP packets
- Fit ABI changes from dpdk lib
v3:
- Split hinic.ini and hinic.rst to related feature patches
- Add min_mtu & max_mtu initialization for hinic_dev_infos_get
- Fix fdir config patch with net/hinic/base
- Split link patch into link and fw version getting 2 patches
- Update pmd doc files to new next version
- Add comments for cover letter patch
- Add rxq & txq info getting interfaces
- Fix load intrinsics for receiving packets
Xiaoyun wang (19):
net/hinic/base: add mbox command channel for SRIOV
net/hinic/base: add HW interfaces for SR-IOV
net/hinic: add VF PMD operation interfaces
net/hinic: add VLAN filter and offload
net/hinic: add allmulticast mode and MTU set
net/hinic: add unicast and multicast MAC set
net/hinic/base: add fdir config interface
net/hinic: add fdir validate flow operations
net/hinic: create and destroy ntuple filter
net/hinic: create and destroy fdir filter
net/hinic: flush fdir filter
net/hinic: set link down and up
net/hinic: get firmware version
net/hinic: support inner L3 checksum offload
net/hinic: support LRO offload
net/hinic: add hinic PMD doc files
net/hinic/base: optimize aeq interfaces
net/hinic: optimize RX performance
net/hinic: add support for getting rxq or txq info
doc/guides/nics/features/hinic.ini | 12 +-
doc/guides/nics/hinic.rst | 10 +
doc/guides/rel_notes/release_19_11.rst | 9 +
drivers/net/hinic/Makefile | 2 +
drivers/net/hinic/base/hinic_compat.h | 62 +-
drivers/net/hinic/base/hinic_csr.h | 29 +-
drivers/net/hinic/base/hinic_pmd_api_cmd.c | 60 +-
drivers/net/hinic/base/hinic_pmd_cfg.c | 35 +
drivers/net/hinic/base/hinic_pmd_cmd.h | 26 +-
drivers/net/hinic/base/hinic_pmd_eqs.c | 245 +--
drivers/net/hinic/base/hinic_pmd_eqs.h | 5 +-
drivers/net/hinic/base/hinic_pmd_hwdev.c | 198 ++-
drivers/net/hinic/base/hinic_pmd_hwdev.h | 9 +-
drivers/net/hinic/base/hinic_pmd_hwif.c | 85 +-
drivers/net/hinic/base/hinic_pmd_hwif.h | 15 +-
drivers/net/hinic/base/hinic_pmd_mbox.c | 938 +++++++++++
drivers/net/hinic/base/hinic_pmd_mbox.h | 93 ++
drivers/net/hinic/base/hinic_pmd_mgmt.c | 83 +-
drivers/net/hinic/base/hinic_pmd_mgmt.h | 2 +-
drivers/net/hinic/base/hinic_pmd_niccfg.c | 777 ++++++++-
drivers/net/hinic/base/hinic_pmd_niccfg.h | 203 +++
drivers/net/hinic/base/hinic_pmd_nicio.c | 15 +-
drivers/net/hinic/base/hinic_pmd_nicio.h | 3 +-
drivers/net/hinic/base/meson.build | 1 +
drivers/net/hinic/hinic_pmd_ethdev.c | 1020 ++++++++++--
drivers/net/hinic/hinic_pmd_ethdev.h | 139 +-
drivers/net/hinic/hinic_pmd_flow.c | 2385 ++++++++++++++++++++++++++++
drivers/net/hinic/hinic_pmd_rx.c | 15 +-
drivers/net/hinic/hinic_pmd_rx.h | 11 +
drivers/net/hinic/hinic_pmd_tx.c | 190 ++-
drivers/net/hinic/meson.build | 1 +
31 files changed, 6050 insertions(+), 628 deletions(-)
create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.c
create mode 100644 drivers/net/hinic/base/hinic_pmd_mbox.h
create mode 100644 drivers/net/hinic/hinic_pmd_flow.c
--
1.8.3.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
2019-09-30 12:22 0% ` Ananyev, Konstantin
@ 2019-09-30 13:43 0% ` Akhil Goyal
2019-10-01 14:49 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2019-09-30 13:43 UTC (permalink / raw)
To: Ananyev, Konstantin, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon'
Cc: Zhang, Roy Fan, Doherty, Declan, 'Anoob Joseph'
Hi Konstantin,
>
> Hi Akhil,
>
> > > > > > > > > > > > This action type allows the burst of symmetric crypto
> workload
> > > using
> > > > > > the
> > > > > > > > > > same
> > > > > > > > > > > > algorithm, key, and direction being processed by CPU cycles
> > > > > > > > synchronously.
> > > > > > > > > > > > This flexible action type does not require external hardware
> > > > > > involvement,
> > > > > > > > > > > > having the crypto workload processed synchronously, and is
> > > more
> > > > > > > > > > performant
> > > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on removed
> > > "async
> > > > > > > > mode
> > > > > > > > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > > > > > > > >
> > > > > > > > > > > Does that mean application will not call the
> > > cryptodev_enqueue_burst
> > > > > > and
> > > > > > > > > > corresponding dequeue burst.
> > > > > > > > > >
> > > > > > > > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > > >
> > > > > > > > > > > It would be a new API something like process_packets and it
> will
> > > have
> > > > > > the
> > > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > > >
> > > > > > > > > > Yes, though the plan is that API will operate on raw data buffers,
> > > not
> > > > > > mbufs.
> > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > I still do not understand why we cannot do with the
> conventional
> > > > > > crypto lib
> > > > > > > > > > only.
> > > > > > > > > > > As far as I can understand, you are not doing any protocol
> > > processing
> > > > > > or
> > > > > > > > any
> > > > > > > > > > value add
> > > > > > > > > > > To the crypto processing. IMO, you just need a synchronous
> > > crypto
> > > > > > > > processing
> > > > > > > > > > API which
> > > > > > > > > > > Can be defined in cryptodev, you don't need to re-create a
> crypto
> > > > > > session
> > > > > > > > in
> > > > > > > > > > the name of
> > > > > > > > > > > Security session in the driver just to do a synchronous
> processing.
> > > > > > > > > >
> > > > > > > > > > I suppose your question is why not to have
> > > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > > The main reason is that would require disruptive changes in
> existing
> > > > > > > > cryptodev
> > > > > > > > > > API
> > > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need
> > > some
> > > > > > extra
> > > > > > > > > > information
> > > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > > (cipher offset from the start of the buffer, might be something
> extra
> > > in
> > > > > > > > future).
> > > > > > > > >
> > > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > > >
> > > > > > > > fill/read (+ alloc/free) is one of the main things that slowdown
> current
> > > > > > crypto-op
> > > > > > > > approach.
> > > > > > > > That's why the general idea - have all data that wouldn't change
> from
> > > packet
> > > > > > to
> > > > > > > > packet
> > > > > > > > included into the session and setup it once at session_init().
> > > > > > >
> > > > > > > I agree that you cannot use crypto-op.
> > > > > > > You can have the new API in crypto.
> > > > > > > As per the current patch, you only need cipher_offset which you can
> have
> > > it as
> > > > > > a parameter until
> > > > > > > You get it approved in the crypto xform. I believe it will be beneficial
> in
> > > case of
> > > > > > other crypto cases as well.
> > > > > > > We can have cipher offset at both places(crypto-op and
> cipher_xform). It
> > > will
> > > > > > give flexibility to the user to
> > > > > > > override it.
> > > > > >
> > > > > > After having another thought on your proposal:
> > > > > > Probably we can introduce new rte_crypto_sym_xform_types for CPU
> > > related
> > > > > > stuff here?
> > > > >
> > > > > I also thought of adding new xforms, but that wont serve the purpose for
> > > may be all the cases.
> > > > > You would be needing all information currently available in the current
> > > xforms.
> > > > > So if you are adding new fields in the new xform, the size will be more
> than
> > > that of the union of xforms.
> > > > > ABI breakage would still be there.
> > > > >
> > > > > If you think a valid compression of the AEAD xform can be done, then
> that
> > > can be done for each of the
> > > > > Xforms and we can have a solution to this issue.
> > > >
> > > > I think that we can re-use iv.offset for our purposes (for crypto offset).
> > > > So for now we can make that path work without any ABI breakage.
> > > > Fan, please feel free to correct me here, if I missed something.
> > > > If in future we would need to add some extra information it might
> > > > require ABI breakage, though by now I don't envision anything particular to
> > > add.
> > > > Anyway, if there is no objection to go that way, we can try to make
> > > > these changes for v2.
> > > >
> > >
> > > Actually, after looking at it more deeply it appears not that easy as I thought
> it
> > > would be :)
> > > Below is a very draft version of proposed API additions.
> > > I think it avoids ABI breakages right now and provides enough flexibility for
> > > future extensions (if any).
> > > For now, it doesn't address your comments about naming conventions
> (_CPU_
> > > vs _SYNC_) , etc.
> > > but I suppose is comprehensive enough to provide a main idea beyond it.
> > > Akhil and other interested parties, please try to review and provide feedback
> > > ASAP,
> > > as related changes would take some time and we still like to hit 19.11
> deadline.
> > > Konstantin
> > >
> > > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > > b/lib/librte_cryptodev/rte_crypto_sym.h
> > > index bc8da2466..c03069e23 100644
> > > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > > *
> > > * This structure contains data relating to Cipher (Encryption and Decryption)
> > > * use to create a session.
> > > + * Actually I was wrong saying that we don't have free space inside xforms.
> > > + * Making key struct packed (see below) allow us to regain 6B that could be
> > > + * used for future extensions.
> > > */
> > > struct rte_crypto_cipher_xform {
> > > enum rte_crypto_cipher_operation op;
> > > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > > struct {
> > > const uint8_t *data; /**< pointer to key data */
> > > uint16_t length; /**< key length in bytes */
> > > - } key;
> > > + } __attribute__((__packed__)) key;
> > > +
> > > + /**
> > > + * offset for cipher to start within user provided data buffer.
> > > + * Fan suggested another (and less space consuming way) -
> > > + * reuse iv.offset space below, by changing:
> > > + * struct {uint16_t offset, length;} iv;
> > > + * to uunamed union:
> > > + * union {
> > > + * struct {uint16_t offset, length;} iv;
> > > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > > + * };
> > > + * Both approaches seems ok to me in general.
> >
> > No strong opinions here. OK with this one.
> >
> > > + * Comments/suggestions are welcome.
> > > + */
> > > + uint16_t offset;
>
> After another thought - it is probably a bit better to have offset as a separate
> field.
> In that case we can use the same xforms to create both type of sessions.
ok
>
> > > +
> > > + uint8_t reserved1[4];
> > > +
> > > /**< Cipher key
> > > *
> > > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation, key.data
> will
> > > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > > struct {
> > > const uint8_t *data; /**< pointer to key data */
> > > uint16_t length; /**< key length in bytes */
> > > - } key;
> > > + } __attribute__((__packed__)) key;
> > > /**< Authentication key data.
> > > * The authentication key length MUST be less than or equal to the
> > > * block size of the algorithm. It is the callers responsibility to
> > > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > > * (for example RFC 2104, FIPS 198a).
> > > */
> > >
> > > + uint8_t reserved1[6];
> > > +
> > > struct {
> > > uint16_t offset;
> > > /**< Starting point for Initialisation Vector or Counter,
> > > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > > struct {
> > > const uint8_t *data; /**< pointer to key data */
> > > uint16_t length; /**< key length in bytes */
> > > - } key;
> > > + } __attribute__((__packed__)) key;
> > > +
> > > + /** offset for cipher to start within data buffer */
> > > + uint16_t cipher_offset;
> > > +
> > > + uint8_t reserved1[4];
> > >
> > > struct {
> > > uint16_t offset;
> > > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > > b/lib/librte_cryptodev/rte_cryptodev.h
> > > index e175b838c..c0c7bfed7 100644
> > > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > > @@ -1272,6 +1272,101 @@ void *
> > > rte_cryptodev_sym_session_get_user_data(
> > > struct rte_cryptodev_sym_session *sess);
> > >
> > > +/*
> > > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > > + * into existing rte_crypto_sym_session structure/API, but instead
> > > + * introduce an extentsion to it via new fully opaque
> > > + * struct rte_crypto_cpu_sym_session and additional related API.
> >
> >
> > What all things do we need to squeeze?
> > In this proposal I do not see the new struct cpu_sym_session defined here.
>
> The plan is to have it totally opaque to the user, i.e. just:
> struct rte_crypto_cpu_sym_session;
> in public header files.
>
> > I believe you will have same lib API/struct for cpu_sym_session and
> sym_session.
>
> I thought about such way, but there are few things that looks clumsy to me:
> 1. Right now there is no 'type' (or so) field inside rte_cryptodev_sym_session,
> so it is not possible to easy distinguish what session do you have: lksd_sym or
> cpu_sym.
> In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we can add
> some extra field
> here, but in that case we wouldn't be able to use the same xform for both
> lksd_sym or cpu_sym
> (which seems really plausible thing for me).
> 2. Majority of rte_cryptodev_sym_session fields I think are unnecessary for
> rte_crypto_cpu_sym_session:
> sess_data[], opaque_data, user_data, nb_drivers.
> All that consumes space, that could be used somewhere else instead.
> 3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any
> breakages I can't foresee right now.
> From other side - if we'll add new functions/structs for cpu_sym_session we can
> mark it
> and keep it for some time as experimental, so further changes (if needed) would
> still be possible.
>
OK let us assume that you have a separate structure. But I have a few queries:
1. how can multiple drivers use a same session
2. Can somebody use the scheduler pmd for scheduling the different type of payloads for the same session?
With your proposal the APIs would be very specific to your use case only.
When you would add more functionality to this sync API/struct, it will end up being the same API/struct.
Let us see how close/ far we are from the existing APIs when the actual implementation is done.
> > I am not sure if that would be needed.
> > It would be internal to the driver that if synchronous processing is
> supported(from feature flag) and
> > Have relevant fields in xform(the newly added ones which are packed as per
> your suggestions) set,
> > It will create that type of session.
> >
> >
> > > + * Main points:
> > > + * - Current crypto-dev API is reasonably mature and it is desirable
> > > + * to keep it unchanged (API/ABI stability). From other side, this
> > > + * new sync API is new one and probably would require extra changes.
> > > + * Having it as a new one allows to mark it as experimental, without
> > > + * affecting existing one.
> > > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > > + * to the PMD writers and again allows to avoid ABI breakages in future.
> > > + * - process() function per set of xforms
> > > + * allows to expose different process() functions for different
> > > + * xform combinations. PMD writer can decide, does he wants to
> > > + * push all supported algorithms into one process() function,
> > > + * or spread it across several ones.
> > > + * I.E. More flexibility for PMD writer.
> >
> > Which process function should be chosen is internal to PMD, how would that
> info
> > be visible to the application or the library. These will get stored in the session
> private
> > data. It would be upto the PMD writer, to store the per session process
> function in
> > the session private data.
> >
> > Process function would be a dev ops just like enc/deq operations and it should
> call
> > The respective process API stored in the session private data.
>
> That model (via devops) is possible, but has several drawbacks from my
> perspective:
>
> 1. It means we'll need to pass dev_id as a parameter to process() function.
> Though in fact dev_id is not a relevant information for us here
> (all we need is pointer to the session and pointer to the fuction to call)
> and I tried to avoid using it in data-path functions for that API.
You have a single vdev, but someone may have multiple vdevs for each thread, or may
Have same dev with multiple queues for each core.
> 2. As you pointed in that case it will be just one process() function per device.
> So if PMD would like to have several process() functions for different type of
> sessions
> (let say one per alg) first thing it has to do inside it's process() - read session data
> and
> based on that, do a jump/call to particular internal sub-routine.
> Something like:
> driver_id = get_pmd_driver_id();
> priv_ses = ses->sess_data[driver_id];
> Then either:
> switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
> OR
> priv_ses->process(priv_sess, ...);
>
> to select and call the proper function.
> Looks like totally unnecessary overhead to me.
> Though if we'll have ability to query/extract some sort session_ops based on the
> xform -
> we can avoid this extra de-refererence+jump/call thing.
What is the issue in the priv_ses->process(); approach?
I don't understand what are you saving by not doing this.
In any case you would need to identify which session correspond to which process().
For that you would be doing it somewhere in your data path.
>
> >
> > I am not sure if you would need a new session init API for this as nothing would
> be visible to
> > the app or lib.
> >
> > > + * - Not storing process() pointer inside the session -
> > > + * Allows user to choose does he want to store a process() pointer
> > > + * per session, or per group of sessions for that device that share
> > > + * the same input xforms. I.E. extra flexibility for the user,
> > > + * plus allows us to keep cpu_sym_session totally opaque, see above.
> >
> > If multiple sessions need to be processed via the same process function,
> > PMD would save the same process in all the sessions, I don't think there would
> > be any perf overhead with that.
>
> I think it would, see above.
>
> >
> > > + * Sketched usage model:
> > > + * ....
> > > + * /* control path, alloc/init session */
> > > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > > + * rte_crypto_cpu_sym_process_t process =
> > > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > > + * ...
> > > + * /* data-path*/
> > > + * process(ses, ....);
> > > + * ....
> > > + * /* control path, termiante/free session */
> > > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > > + */
> > > +
> > > +/**
> > > + * vector structure, contains pointer to vector array and the length
> > > + * of the array
> > > + */
> > > +struct rte_crypto_vec {
> > > + struct iovec *vec;
> > > + uint32_t num;
> > > +};
> > > +
> > > +/*
> > > + * Data-path bulk process crypto function.
> > > + */
> > > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > > + struct rte_crypto_cpu_sym_session *sess,
> > > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > > + void *digest[], int status[], uint32_t num);
> > > +/*
> > > + * for given device return process function specific to input xforms
> > > + * on error - return NULL and set rte_errno value.
> > > + * Note that for same input xfroms for the same device should return
> > > + * the same process function.
> > > + */
> > > +__rte_experimental
> > > +rte_crypto_cpu_sym_process_t
> > > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > +/*
> > > + * Return required session size in bytes for given set of xforms.
> > > + * if xforms == NULL, then return the max possible session size,
> > > + * that would fit session for any supported by the device algorithm.
> > > + * if CPU mode is not supported at all, or requeted in xform
> > > + * algorithm is not supported, then return -ENOTSUP.
> > > + */
> > > +__rte_experimental
> > > +int
> > > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > +/*
> > > + * Initialize session.
> > > + * It is caller responsibility to allocate enough space for it.
> > > + * See rte_crypto_cpu_sym_session_size above.
> > > + */
> > > +__rte_experimental
> > > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > > + struct rte_crypto_cpu_sym_session *sess,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > +__rte_experimental
> > > +void
> > > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > > + struct rte_crypto_cpu_sym_session *sess);
> > > +
> > > +
> > > #ifdef __cplusplus
> > > }
> > > #endif
> > > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > index defe05ea0..ed7e63fab 100644
> > > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > > @@ -310,6 +310,20 @@ typedef void
> (*cryptodev_sym_free_session_t)(struct
> > > rte_cryptodev *dev,
> > > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
> > > struct rte_cryptodev_asym_session *sess);
> > >
> > > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct rte_cryptodev
> *dev,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct rte_cryptodev
> *dev,
> > > + struct rte_crypto_cpu_sym_session *sess,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct rte_cryptodev
> *dev,
> > > + struct rte_crypto_cpu_sym_session *sess);
> > > +
> > > +typedef rte_crypto_cpu_sym_process_t
> (*cryptodev_cpu_sym_session_func_t)
> > > (
> > > + struct rte_cryptodev *dev,
> > > + const struct rte_crypto_sym_xform *xforms);
> > > +
> > > /** Crypto device operations function pointer table */
> > > struct rte_cryptodev_ops {
> > > cryptodev_configure_t dev_configure; /**< Configure device. */
> > > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > > /**< Clear a Crypto sessions private data. */
> > > cryptodev_asym_free_session_t asym_session_clear;
> > > /**< Clear a Crypto sessions private data. */
> > > +
> > > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > > };
> > >
> > >
> > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API
@ 2019-09-30 12:22 0% ` Ananyev, Konstantin
2019-09-30 13:43 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2019-09-30 12:22 UTC (permalink / raw)
To: Akhil Goyal, 'dev@dpdk.org',
De Lara Guarch, Pablo, 'Thomas Monjalon'
Cc: Zhang, Roy Fan, Doherty, Declan, 'Anoob Joseph'
Hi Akhil,
> > > > > > > > > > > This action type allows the burst of symmetric crypto workload
> > using
> > > > > the
> > > > > > > > > same
> > > > > > > > > > > algorithm, key, and direction being processed by CPU cycles
> > > > > > > synchronously.
> > > > > > > > > > > This flexible action type does not require external hardware
> > > > > involvement,
> > > > > > > > > > > having the crypto workload processed synchronously, and is
> > more
> > > > > > > > > performant
> > > > > > > > > > > than Cryptodev SW PMD due to the saved cycles on removed
> > "async
> > > > > > > mode
> > > > > > > > > > > simulation" as well as 3 cacheline access of the crypto ops.
> > > > > > > > > >
> > > > > > > > > > Does that mean application will not call the
> > cryptodev_enqueue_burst
> > > > > and
> > > > > > > > > corresponding dequeue burst.
> > > > > > > > >
> > > > > > > > > Yes, instead it just call rte_security_process_cpu_crypto_bulk(...)
> > > > > > > > >
> > > > > > > > > > It would be a new API something like process_packets and it will
> > have
> > > > > the
> > > > > > > > > crypto processed packets while returning from the API?
> > > > > > > > >
> > > > > > > > > Yes, though the plan is that API will operate on raw data buffers,
> > not
> > > > > mbufs.
> > > > > > > > >
> > > > > > > > > >
> > > > > > > > > > I still do not understand why we cannot do with the conventional
> > > > > crypto lib
> > > > > > > > > only.
> > > > > > > > > > As far as I can understand, you are not doing any protocol
> > processing
> > > > > or
> > > > > > > any
> > > > > > > > > value add
> > > > > > > > > > To the crypto processing. IMO, you just need a synchronous
> > crypto
> > > > > > > processing
> > > > > > > > > API which
> > > > > > > > > > Can be defined in cryptodev, you don't need to re-create a crypto
> > > > > session
> > > > > > > in
> > > > > > > > > the name of
> > > > > > > > > > Security session in the driver just to do a synchronous processing.
> > > > > > > > >
> > > > > > > > > I suppose your question is why not to have
> > > > > > > > > rte_crypot_process_cpu_crypto_bulk(...) instead?
> > > > > > > > > The main reason is that would require disruptive changes in existing
> > > > > > > cryptodev
> > > > > > > > > API
> > > > > > > > > (would cause ABI/API breakage).
> > > > > > > > > Session for RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO need
> > some
> > > > > extra
> > > > > > > > > information
> > > > > > > > > that normal crypto_sym_xform doesn't contain
> > > > > > > > > (cipher offset from the start of the buffer, might be something extra
> > in
> > > > > > > future).
> > > > > > > >
> > > > > > > > Cipher offset will be part of rte_crypto_op.
> > > > > > >
> > > > > > > fill/read (+ alloc/free) is one of the main things that slowdown current
> > > > > crypto-op
> > > > > > > approach.
> > > > > > > That's why the general idea - have all data that wouldn't change from
> > packet
> > > > > to
> > > > > > > packet
> > > > > > > included into the session and setup it once at session_init().
> > > > > >
> > > > > > I agree that you cannot use crypto-op.
> > > > > > You can have the new API in crypto.
> > > > > > As per the current patch, you only need cipher_offset which you can have
> > it as
> > > > > a parameter until
> > > > > > You get it approved in the crypto xform. I believe it will be beneficial in
> > case of
> > > > > other crypto cases as well.
> > > > > > We can have cipher offset at both places(crypto-op and cipher_xform). It
> > will
> > > > > give flexibility to the user to
> > > > > > override it.
> > > > >
> > > > > After having another thought on your proposal:
> > > > > Probably we can introduce new rte_crypto_sym_xform_types for CPU
> > related
> > > > > stuff here?
> > > >
> > > > I also thought of adding new xforms, but that wont serve the purpose for
> > may be all the cases.
> > > > You would be needing all information currently available in the current
> > xforms.
> > > > So if you are adding new fields in the new xform, the size will be more than
> > that of the union of xforms.
> > > > ABI breakage would still be there.
> > > >
> > > > If you think a valid compression of the AEAD xform can be done, then that
> > can be done for each of the
> > > > Xforms and we can have a solution to this issue.
> > >
> > > I think that we can re-use iv.offset for our purposes (for crypto offset).
> > > So for now we can make that path work without any ABI breakage.
> > > Fan, please feel free to correct me here, if I missed something.
> > > If in future we would need to add some extra information it might
> > > require ABI breakage, though by now I don't envision anything particular to
> > add.
> > > Anyway, if there is no objection to go that way, we can try to make
> > > these changes for v2.
> > >
> >
> > Actually, after looking at it more deeply it appears not that easy as I thought it
> > would be :)
> > Below is a very draft version of proposed API additions.
> > I think it avoids ABI breakages right now and provides enough flexibility for
> > future extensions (if any).
> > For now, it doesn't address your comments about naming conventions (_CPU_
> > vs _SYNC_) , etc.
> > but I suppose is comprehensive enough to provide a main idea beyond it.
> > Akhil and other interested parties, please try to review and provide feedback
> > ASAP,
> > as related changes would take some time and we still like to hit 19.11 deadline.
> > Konstantin
> >
> > diff --git a/lib/librte_cryptodev/rte_crypto_sym.h
> > b/lib/librte_cryptodev/rte_crypto_sym.h
> > index bc8da2466..c03069e23 100644
> > --- a/lib/librte_cryptodev/rte_crypto_sym.h
> > +++ b/lib/librte_cryptodev/rte_crypto_sym.h
> > @@ -103,6 +103,9 @@ rte_crypto_cipher_operation_strings[];
> > *
> > * This structure contains data relating to Cipher (Encryption and Decryption)
> > * use to create a session.
> > + * Actually I was wrong saying that we don't have free space inside xforms.
> > + * Making key struct packed (see below) allow us to regain 6B that could be
> > + * used for future extensions.
> > */
> > struct rte_crypto_cipher_xform {
> > enum rte_crypto_cipher_operation op;
> > @@ -116,7 +119,25 @@ struct rte_crypto_cipher_xform {
> > struct {
> > const uint8_t *data; /**< pointer to key data */
> > uint16_t length; /**< key length in bytes */
> > - } key;
> > + } __attribute__((__packed__)) key;
> > +
> > + /**
> > + * offset for cipher to start within user provided data buffer.
> > + * Fan suggested another (and less space consuming way) -
> > + * reuse iv.offset space below, by changing:
> > + * struct {uint16_t offset, length;} iv;
> > + * to uunamed union:
> > + * union {
> > + * struct {uint16_t offset, length;} iv;
> > + * struct {uint16_t iv_len, crypto_offset} cpu_crypto_param;
> > + * };
> > + * Both approaches seems ok to me in general.
>
> No strong opinions here. OK with this one.
>
> > + * Comments/suggestions are welcome.
> > + */
> > + uint16_t offset;
After another thought - it is probably a bit better to have offset as a separate field.
In that case we can use the same xforms to create both type of sessions.
> > +
> > + uint8_t reserved1[4];
> > +
> > /**< Cipher key
> > *
> > * For the RTE_CRYPTO_CIPHER_AES_F8 mode of operation, key.data will
> > @@ -284,7 +305,7 @@ struct rte_crypto_auth_xform {
> > struct {
> > const uint8_t *data; /**< pointer to key data */
> > uint16_t length; /**< key length in bytes */
> > - } key;
> > + } __attribute__((__packed__)) key;
> > /**< Authentication key data.
> > * The authentication key length MUST be less than or equal to the
> > * block size of the algorithm. It is the callers responsibility to
> > @@ -292,6 +313,8 @@ struct rte_crypto_auth_xform {
> > * (for example RFC 2104, FIPS 198a).
> > */
> >
> > + uint8_t reserved1[6];
> > +
> > struct {
> > uint16_t offset;
> > /**< Starting point for Initialisation Vector or Counter,
> > @@ -376,7 +399,12 @@ struct rte_crypto_aead_xform {
> > struct {
> > const uint8_t *data; /**< pointer to key data */
> > uint16_t length; /**< key length in bytes */
> > - } key;
> > + } __attribute__((__packed__)) key;
> > +
> > + /** offset for cipher to start within data buffer */
> > + uint16_t cipher_offset;
> > +
> > + uint8_t reserved1[4];
> >
> > struct {
> > uint16_t offset;
> > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > b/lib/librte_cryptodev/rte_cryptodev.h
> > index e175b838c..c0c7bfed7 100644
> > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > @@ -1272,6 +1272,101 @@ void *
> > rte_cryptodev_sym_session_get_user_data(
> > struct rte_cryptodev_sym_session *sess);
> >
> > +/*
> > + * After several thoughts decided not to try to squeeze CPU_CRYPTO
> > + * into existing rte_crypto_sym_session structure/API, but instead
> > + * introduce an extentsion to it via new fully opaque
> > + * struct rte_crypto_cpu_sym_session and additional related API.
>
>
> What all things do we need to squeeze?
> In this proposal I do not see the new struct cpu_sym_session defined here.
The plan is to have it totally opaque to the user, i.e. just:
struct rte_crypto_cpu_sym_session;
in public header files.
> I believe you will have same lib API/struct for cpu_sym_session and sym_session.
I thought about such way, but there are few things that looks clumsy to me:
1. Right now there is no 'type' (or so) field inside rte_cryptodev_sym_session,
so it is not possible to easy distinguish what session do you have: lksd_sym or cpu_sym.
In theory, there is a hole of 4B inside rte_cryptodev_sym_session, so we can add some extra field
here, but in that case we wouldn't be able to use the same xform for both lksd_sym or cpu_sym
(which seems really plausible thing for me).
2. Majority of rte_cryptodev_sym_session fields I think are unnecessary for rte_crypto_cpu_sym_session:
sess_data[], opaque_data, user_data, nb_drivers.
All that consumes space, that could be used somewhere else instead.
3. I am a bit reluctant to touch existing rte_cryptodev API - to avoid any breakages I can't foresee right now.
From other side - if we'll add new functions/structs for cpu_sym_session we can mark it
and keep it for some time as experimental, so further changes (if needed) would still be possible.
> I am not sure if that would be needed.
> It would be internal to the driver that if synchronous processing is supported(from feature flag) and
> Have relevant fields in xform(the newly added ones which are packed as per your suggestions) set,
> It will create that type of session.
>
>
> > + * Main points:
> > + * - Current crypto-dev API is reasonably mature and it is desirable
> > + * to keep it unchanged (API/ABI stability). From other side, this
> > + * new sync API is new one and probably would require extra changes.
> > + * Having it as a new one allows to mark it as experimental, without
> > + * affecting existing one.
> > + * - Fully opaque cpu_sym_session structure gives more flexibility
> > + * to the PMD writers and again allows to avoid ABI breakages in future.
> > + * - process() function per set of xforms
> > + * allows to expose different process() functions for different
> > + * xform combinations. PMD writer can decide, does he wants to
> > + * push all supported algorithms into one process() function,
> > + * or spread it across several ones.
> > + * I.E. More flexibility for PMD writer.
>
> Which process function should be chosen is internal to PMD, how would that info
> be visible to the application or the library. These will get stored in the session private
> data. It would be upto the PMD writer, to store the per session process function in
> the session private data.
>
> Process function would be a dev ops just like enc/deq operations and it should call
> The respective process API stored in the session private data.
That model (via devops) is possible, but has several drawbacks from my perspective:
1. It means we'll need to pass dev_id as a parameter to process() function.
Though in fact dev_id is not a relevant information for us here
(all we need is pointer to the session and pointer to the fuction to call)
and I tried to avoid using it in data-path functions for that API.
2. As you pointed in that case it will be just one process() function per device.
So if PMD would like to have several process() functions for different type of sessions
(let say one per alg) first thing it has to do inside it's process() - read session data and
based on that, do a jump/call to particular internal sub-routine.
Something like:
driver_id = get_pmd_driver_id();
priv_ses = ses->sess_data[driver_id];
Then either:
switch(priv_sess->alg) {case XXX: process_XXX(priv_sess, ...);break;...}
OR
priv_ses->process(priv_sess, ...);
to select and call the proper function.
Looks like totally unnecessary overhead to me.
Though if we'll have ability to query/extract some sort session_ops based on the xform -
we can avoid this extra de-refererence+jump/call thing.
>
> I am not sure if you would need a new session init API for this as nothing would be visible to
> the app or lib.
>
> > + * - Not storing process() pointer inside the session -
> > + * Allows user to choose does he want to store a process() pointer
> > + * per session, or per group of sessions for that device that share
> > + * the same input xforms. I.E. extra flexibility for the user,
> > + * plus allows us to keep cpu_sym_session totally opaque, see above.
>
> If multiple sessions need to be processed via the same process function,
> PMD would save the same process in all the sessions, I don't think there would
> be any perf overhead with that.
I think it would, see above.
>
> > + * Sketched usage model:
> > + * ....
> > + * /* control path, alloc/init session */
> > + * int32_t sz = rte_crypto_cpu_sym_session_size(dev_id, &xform);
> > + * struct rte_crypto_cpu_sym_session *ses = user_alloc(..., sz);
> > + * rte_crypto_cpu_sym_process_t process =
> > + * rte_crypto_cpu_sym_session_func(dev_id, &xform);
> > + * rte_crypto_cpu_sym_session_init(dev_id, ses, &xform);
> > + * ...
> > + * /* data-path*/
> > + * process(ses, ....);
> > + * ....
> > + * /* control path, termiante/free session */
> > + * rte_crypto_cpu_sym_session_fini(dev_id, ses);
> > + */
> > +
> > +/**
> > + * vector structure, contains pointer to vector array and the length
> > + * of the array
> > + */
> > +struct rte_crypto_vec {
> > + struct iovec *vec;
> > + uint32_t num;
> > +};
> > +
> > +/*
> > + * Data-path bulk process crypto function.
> > + */
> > +typedef void (*rte_crypto_cpu_sym_process_t)(
> > + struct rte_crypto_cpu_sym_session *sess,
> > + struct rte_crypto_vec buf[], void *iv[], void *aad[],
> > + void *digest[], int status[], uint32_t num);
> > +/*
> > + * for given device return process function specific to input xforms
> > + * on error - return NULL and set rte_errno value.
> > + * Note that for same input xfroms for the same device should return
> > + * the same process function.
> > + */
> > +__rte_experimental
> > +rte_crypto_cpu_sym_process_t
> > +rte_crypto_cpu_sym_session_func(uint8_t dev_id,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > +/*
> > + * Return required session size in bytes for given set of xforms.
> > + * if xforms == NULL, then return the max possible session size,
> > + * that would fit session for any supported by the device algorithm.
> > + * if CPU mode is not supported at all, or requeted in xform
> > + * algorithm is not supported, then return -ENOTSUP.
> > + */
> > +__rte_experimental
> > +int
> > +rte_crypto_cpu_sym_session_size(uint8_t dev_id,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > +/*
> > + * Initialize session.
> > + * It is caller responsibility to allocate enough space for it.
> > + * See rte_crypto_cpu_sym_session_size above.
> > + */
> > +__rte_experimental
> > +int rte_crypto_cpu_sym_session_init(uint8_t dev_id,
> > + struct rte_crypto_cpu_sym_session *sess,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > +__rte_experimental
> > +void
> > +rte_crypto_cpu_sym_session_fini(uint8_t dev_id,
> > + struct rte_crypto_cpu_sym_session *sess);
> > +
> > +
> > #ifdef __cplusplus
> > }
> > #endif
> > diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > index defe05ea0..ed7e63fab 100644
> > --- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
> > @@ -310,6 +310,20 @@ typedef void (*cryptodev_sym_free_session_t)(struct
> > rte_cryptodev *dev,
> > typedef void (*cryptodev_asym_free_session_t)(struct rte_cryptodev *dev,
> > struct rte_cryptodev_asym_session *sess);
> >
> > +typedef int (*cryptodev_cpu_sym_session_size_t) (struct rte_cryptodev *dev,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > +typedef int (*cryptodev_cpu_sym_session_init_t) (struct rte_cryptodev *dev,
> > + struct rte_crypto_cpu_sym_session *sess,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > +typedef void (*cryptodev_cpu_sym_session_fini_t) (struct rte_cryptodev *dev,
> > + struct rte_crypto_cpu_sym_session *sess);
> > +
> > +typedef rte_crypto_cpu_sym_process_t (*cryptodev_cpu_sym_session_func_t)
> > (
> > + struct rte_cryptodev *dev,
> > + const struct rte_crypto_sym_xform *xforms);
> > +
> > /** Crypto device operations function pointer table */
> > struct rte_cryptodev_ops {
> > cryptodev_configure_t dev_configure; /**< Configure device. */
> > @@ -343,6 +357,11 @@ struct rte_cryptodev_ops {
> > /**< Clear a Crypto sessions private data. */
> > cryptodev_asym_free_session_t asym_session_clear;
> > /**< Clear a Crypto sessions private data. */
> > +
> > + cryptodev_cpu_sym_session_size_t sym_cpu_session_get_size;
> > + cryptodev_cpu_sym_session_func_t sym_cpu_session_get_func;
> > + cryptodev_cpu_sym_session_init_t sym_cpu_session_init;
> > + cryptodev_cpu_sym_session_fini_t sym_cpu_session_fini;
> > };
> >
> >
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 3/8] buildtools: add ABI versioning check script
@ 2019-09-30 10:27 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2019-09-30 10:27 UTC (permalink / raw)
To: Marcin Baran; +Cc: dev, ray.kinsella, Pawel Modrak
On Mon, Sep 30, 2019 at 11:21:34AM +0200, Marcin Baran wrote:
> The script 'check-abi-version.sh' should be used
> to check whether built libraries are versioned
> with correct ABI number (provided ABI, provided
> ABI+1 or EXPERIMENTAL).
>
> Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
> Signed-off-by: Pawel Modrak <pawelx.modrak@intel.com>
> ---
> buildtools/check-abi-version.sh | 46 +++++++++++++++++++++++++++++++++
> buildtools/update_abi.sh | 41 +++++++++++++++++++++++++++++
> 2 files changed, 87 insertions(+)
> create mode 100755 buildtools/check-abi-version.sh
> create mode 100755 buildtools/update_abi.sh
>
This patch also includes an "update_abi.sh" script, which is not referred
to in the log. It should probably have it's own patch and explanation.
[Also, one script name uses "-" between words, the other "_", maybe
standardize]
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 01/10] security: introduce CPU Crypto action type and API
@ 2019-09-30 9:43 3% ` Hemant Agrawal
2019-10-01 15:27 4% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2019-09-30 9:43 UTC (permalink / raw)
To: Ananyev, Konstantin, Zhang, Roy Fan, dev; +Cc: Doherty, Declan, Akhil Goyal
Hi Konstantin,
n 06-Sep-19 6:43 PM, Fan Zhang wrote:
>>> This patch introduce new RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO action type to
>>> security library. The type represents performing crypto operation with CPU
>>> cycles. The patch also includes a new API to process crypto operations in
>>> bulk and the function pointers for PMDs.
>>>
>>> Signed-off-by: Fan Zhang <roy.fan.zhang@intel.com>
>>> ---
>>> lib/librte_security/rte_security.c | 16 +++++++++
>>> lib/librte_security/rte_security.h | 51 +++++++++++++++++++++++++++-
>>> lib/librte_security/rte_security_driver.h | 19 +++++++++++
>>> lib/librte_security/rte_security_version.map | 1 +
>>> 4 files changed, 86 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
>>> index bc81ce15d..0f85c1b59 100644
>>> --- a/lib/librte_security/rte_security.c
>>> +++ b/lib/librte_security/rte_security.c
>>> @@ -141,3 +141,19 @@ rte_security_capability_get(struct rte_security_ctx *instance,
>>>
>>> return NULL;
>>> }
>>> +
>>> +void
>>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
>>> + struct rte_security_session *sess,
>>> + struct rte_security_vec buf[], void *iv[], void *aad[],
>>> + void *digest[], int status[], uint32_t num)
>>> +{
>>> + uint32_t i;
>>> +
>>> + for (i = 0; i < num; i++)
>>> + status[i] = -1;
>>> +
>>> + RTE_FUNC_PTR_OR_RET(*instance->ops->process_cpu_crypto_bulk);
>>> + instance->ops->process_cpu_crypto_bulk(sess, buf, iv,
>>> + aad, digest, status, num);
>>> +}
>>> diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
>>> index 96806e3a2..5a0f8901b 100644
>>> --- a/lib/librte_security/rte_security.h
>>> +++ b/lib/librte_security/rte_security.h
>>> @@ -18,6 +18,7 @@ extern "C" {
>>> #endif
>>>
>>> #include <sys/types.h>
>>> +#include <sys/uio.h>
>>>
>>> #include <netinet/in.h>
>>> #include <netinet/ip.h>
>>> @@ -272,6 +273,20 @@ struct rte_security_pdcp_xform {
>>> uint32_t hfn_threshold;
>>> };
>>>
>>> +struct rte_security_cpu_crypto_xform {
>>> + /** For cipher/authentication crypto operation the authentication may
>>> + * cover more content then the cipher. E.g., for IPSec ESP encryption
>>> + * with AES-CBC and SHA1-HMAC, the encryption happens after the ESP
>>> + * header but whole packet (apart from MAC header) is authenticated.
>>> + * The cipher_offset field is used to deduct the cipher data pointer
>>> + * from the buffer to be processed.
>>> + *
>>> + * NOTE this parameter shall be ignored by AEAD algorithms, since it
>>> + * uses the same offset for cipher and authentication.
>>> + */
>>> + int32_t cipher_offset;
>>> +};
>>> +
>>> /**
>>> * Security session action type.
>>> */
>>> @@ -286,10 +301,14 @@ enum rte_security_session_action_type {
>>> /**< All security protocol processing is performed inline during
>>> * transmission
>>> */
>>> - RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL
>>> + RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL,
>>> /**< All security protocol processing including crypto is performed
>>> * on a lookaside accelerator
>>> */
>>> + RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
>>> + /**< Crypto processing for security protocol is processed by CPU
>>> + * synchronously
>>> + */
>> though you are naming it cpu crypto, but it is more like raw packet
>> crypto, where you want to skip mbuf/crypto ops and directly wants to
>> work on raw buffer.
> Yes, but we do wat to do that (skip mbuf/crypto ops and use raw buffer),
> because this API is destined for SW backed implementation.
> For that case crypto-ops , mbuf, enqueue/dequeue are just unnecessary overhead.
I agree, we are also planning to take advantage of it for some specific
use-cases in future.
>>> };
>>>
>>> /** Security session protocol definition */
>>> @@ -315,6 +334,7 @@ struct rte_security_session_conf {
>>> struct rte_security_ipsec_xform ipsec;
>>> struct rte_security_macsec_xform macsec;
>>> struct rte_security_pdcp_xform pdcp;
>>> + struct rte_security_cpu_crypto_xform cpucrypto;
>>> };
>>> /**< Configuration parameters for security session */
>>> struct rte_crypto_sym_xform *crypto_xform;
>>> @@ -639,6 +659,35 @@ const struct rte_security_capability *
>>> rte_security_capability_get(struct rte_security_ctx *instance,
>>> struct rte_security_capability_idx *idx);
>>>
>>> +/**
>>> + * Security vector structure, contains pointer to vector array and the length
>>> + * of the array
>>> + */
>>> +struct rte_security_vec {
>>> + struct iovec *vec;
>>> + uint32_t num;
>>> +};
>>> +
>> Just wondering if you want to change it to *in_vec and *out_vec, that
>> will be helpful in future, if the out-of-place processing is required
>> for CPU usecase as well?
> I suppose this is doable, though right now we don't plan to support such model.
They will come handy in future. I plan to use it in future and we can
skip the API/ABI breakage, if the placeholder are present
>
>>> +/**
>>> + * Processing bulk crypto workload with CPU
>>> + *
>>> + * @param instance security instance.
>>> + * @param sess security session
>>> + * @param buf array of buffer SGL vectors
>>> + * @param iv array of IV pointers
>>> + * @param aad array of AAD pointers
>>> + * @param digest array of digest pointers
>>> + * @param status array of status for the function to return
>>> + * @param num number of elements in each array
>>> + *
>>> + */
>>> +__rte_experimental
>>> +void
>>> +rte_security_process_cpu_crypto_bulk(struct rte_security_ctx *instance,
>>> + struct rte_security_session *sess,
>>> + struct rte_security_vec buf[], void *iv[], void *aad[],
>>> + void *digest[], int status[], uint32_t num);
>>> +
>> Why not make the return as int, to indicate whether this API completely
>> failed or processed or have some valid status to look into?
> Good point, will change as suggested.
I have another suggestions w.r.t iv, aad, digest etc. Why not put them
in a structure, so that you will
be able to add/remove the variable without breaking the API prototype.
>
>>
>>> #ifdef __cplusplus
>>> }
>>> #endif
>>> diff --git a/lib/librte_security/rte_security_driver.h b/lib/librte_security/rte_security_driver.h
>>> index 1b561f852..70fcb0c26 100644
>>> --- a/lib/librte_security/rte_security_driver.h
>>> +++ b/lib/librte_security/rte_security_driver.h
>>> @@ -132,6 +132,23 @@ typedef int (*security_get_userdata_t)(void *device,
>>> typedef const struct rte_security_capability *(*security_capabilities_get_t)(
>>> void *device);
>>>
>>> +/**
>>> + * Process security operations in bulk using CPU accelerated method.
>>> + *
>>> + * @param sess Security session structure.
>>> + * @param buf Buffer to the vectors to be processed.
>>> + * @param iv IV pointers.
>>> + * @param aad AAD pointers.
>>> + * @param digest Digest pointers.
>>> + * @param status Array of status value.
>>> + * @param num Number of elements in each array.
>>> + */
>>> +
>>> +typedef void (*security_process_cpu_crypto_bulk_t)(
>>> + struct rte_security_session *sess,
>>> + struct rte_security_vec buf[], void *iv[], void *aad[],
>>> + void *digest[], int status[], uint32_t num);
>>> +
>>> /** Security operations function pointer table */
>>> struct rte_security_ops {
>>> security_session_create_t session_create;
>>> @@ -150,6 +167,8 @@ struct rte_security_ops {
>>> /**< Get userdata associated with session which processed the packet. */
>>> security_capabilities_get_t capabilities_get;
>>> /**< Get security capabilities. */
>>> + security_process_cpu_crypto_bulk_t process_cpu_crypto_bulk;
>>> + /**< Process data in bulk. */
>>> };
>>>
>>> #ifdef __cplusplus
>>> diff --git a/lib/librte_security/rte_security_version.map b/lib/librte_security/rte_security_version.map
>>> index 53267bf3c..2132e7a00 100644
>>> --- a/lib/librte_security/rte_security_version.map
>>> +++ b/lib/librte_security/rte_security_version.map
>>> @@ -18,4 +18,5 @@ EXPERIMENTAL {
>>> rte_security_get_userdata;
>>> rte_security_session_stats_get;
>>> rte_security_session_update;
>>> + rte_security_process_cpu_crypto_bulk;
>>> };
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH 7/8] lib: remove dead code from distributor
2019-09-30 9:21 1% ` [dpdk-dev] [PATCH 6/8] lib: remove dead code from lpm Marcin Baran
@ 2019-09-30 9:21 2% ` Marcin Baran
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
` (9 subsequent siblings)
12 siblings, 0 replies; 200+ results
From: Marcin Baran @ 2019-09-30 9:21 UTC (permalink / raw)
To: dev, bruce.richardson, ray.kinsella; +Cc: Marcin Baran
After updating ABI policy old and unused
code needs to be removed and all libraries
symbols version should be set to v20.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
---
lib/librte_distributor/rte_distributor.c | 56 +++--------------
.../rte_distributor_v1705.h | 61 -------------------
2 files changed, 9 insertions(+), 108 deletions(-)
delete mode 100644 lib/librte_distributor/rte_distributor_v1705.h
diff --git a/lib/librte_distributor/rte_distributor.c b/lib/librte_distributor/rte_distributor.c
index edc942317..ca3f21b83 100644
--- a/lib/librte_distributor/rte_distributor.c
+++ b/lib/librte_distributor/rte_distributor.c
@@ -19,7 +19,6 @@
#include "rte_distributor_private.h"
#include "rte_distributor.h"
#include "rte_distributor_v20.h"
-#include "rte_distributor_v1705.h"
TAILQ_HEAD(rte_dist_burst_list, rte_distributor);
@@ -33,7 +32,7 @@ EAL_REGISTER_TAILQ(rte_dist_burst_tailq)
/**** Burst Packet APIs called by workers ****/
void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
+rte_distributor_request_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt,
unsigned int count)
{
@@ -78,14 +77,9 @@ rte_distributor_request_pkt_v1705(struct rte_distributor *d,
*/
*retptr64 |= RTE_DISTRIB_GET_BUF;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_request_pkt, _v1705, 20.0);
-MAP_STATIC_SYMBOL(void rte_distributor_request_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count),
- rte_distributor_request_pkt_v1705);
int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
+rte_distributor_poll_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -119,13 +113,9 @@ rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_poll_pkt, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_poll_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts),
- rte_distributor_poll_pkt_v1705);
int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
+rte_distributor_get_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **pkts,
struct rte_mbuf **oldpkt, unsigned int return_count)
{
@@ -153,14 +143,9 @@ rte_distributor_get_pkt_v1705(struct rte_distributor *d,
}
return count;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_get_pkt, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_get_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int return_count),
- rte_distributor_get_pkt_v1705);
int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
+rte_distributor_return_pkt(struct rte_distributor *d,
unsigned int worker_id, struct rte_mbuf **oldpkt, int num)
{
struct rte_distributor_buffer *buf = &d->bufs[worker_id];
@@ -187,10 +172,6 @@ rte_distributor_return_pkt_v1705(struct rte_distributor *d,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_return_pkt, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_return_pkt(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num),
- rte_distributor_return_pkt_v1705);
/**** APIs called on distributor core ***/
@@ -336,7 +317,7 @@ release(struct rte_distributor *d, unsigned int wkr)
/* process a set of packets to distribute them to workers */
int
-rte_distributor_process_v1705(struct rte_distributor *d,
+rte_distributor_process(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int num_mbufs)
{
unsigned int next_idx = 0;
@@ -470,14 +451,10 @@ rte_distributor_process_v1705(struct rte_distributor *d,
return num_mbufs;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_process, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_process(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs),
- rte_distributor_process_v1705);
/* return to the caller, packets returned from workers */
int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
+rte_distributor_returned_pkts(struct rte_distributor *d,
struct rte_mbuf **mbufs, unsigned int max_mbufs)
{
struct rte_distributor_returned_pkts *returns = &d->returns;
@@ -502,10 +479,6 @@ rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
return retval;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_returned_pkts, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_returned_pkts(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs),
- rte_distributor_returned_pkts_v1705);
/*
* Return the number of packets in-flight in a distributor, i.e. packets
@@ -527,7 +500,7 @@ total_outstanding(const struct rte_distributor *d)
* queued up.
*/
int
-rte_distributor_flush_v1705(struct rte_distributor *d)
+rte_distributor_flush(struct rte_distributor *d)
{
unsigned int flushed;
unsigned int wkr;
@@ -556,13 +529,10 @@ rte_distributor_flush_v1705(struct rte_distributor *d)
return flushed;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_flush, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_distributor_flush(struct rte_distributor *d),
- rte_distributor_flush_v1705);
/* clears the internal returns array in the distributor */
void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d)
+rte_distributor_clear_returns(struct rte_distributor *d)
{
unsigned int wkr;
@@ -576,13 +546,10 @@ rte_distributor_clear_returns_v1705(struct rte_distributor *d)
for (wkr = 0; wkr < d->num_workers; wkr++)
d->bufs[wkr].retptr64[0] = 0;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_clear_returns, _v1705, 20.0);
-MAP_STATIC_SYMBOL(void rte_distributor_clear_returns(struct rte_distributor *d),
- rte_distributor_clear_returns_v1705);
/* creates a distributor instance */
struct rte_distributor *
-rte_distributor_create_v1705(const char *name,
+rte_distributor_create(const char *name,
unsigned int socket_id,
unsigned int num_workers,
unsigned int alg_type)
@@ -656,8 +623,3 @@ rte_distributor_create_v1705(const char *name,
return d;
}
-BIND_DEFAULT_SYMBOL(rte_distributor_create, _v1705, 20.0);
-MAP_STATIC_SYMBOL(struct rte_distributor *rte_distributor_create(
- const char *name, unsigned int socket_id,
- unsigned int num_workers, unsigned int alg_type),
- rte_distributor_create_v1705);
diff --git a/lib/librte_distributor/rte_distributor_v1705.h b/lib/librte_distributor/rte_distributor_v1705.h
deleted file mode 100644
index df4d9e815..000000000
--- a/lib/librte_distributor/rte_distributor_v1705.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2017 Intel Corporation
- */
-
-#ifndef _RTE_DISTRIB_V1705_H_
-#define _RTE_DISTRIB_V1705_H_
-
-/**
- * @file
- * RTE distributor
- *
- * The distributor is a component which is designed to pass packets
- * one-at-a-time to workers, with dynamic load balancing.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct rte_distributor *
-rte_distributor_create_v1705(const char *name, unsigned int socket_id,
- unsigned int num_workers,
- unsigned int alg_type);
-
-int
-rte_distributor_process_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int num_mbufs);
-
-int
-rte_distributor_returned_pkts_v1705(struct rte_distributor *d,
- struct rte_mbuf **mbufs, unsigned int max_mbufs);
-
-int
-rte_distributor_flush_v1705(struct rte_distributor *d);
-
-void
-rte_distributor_clear_returns_v1705(struct rte_distributor *d);
-
-int
-rte_distributor_get_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **pkts,
- struct rte_mbuf **oldpkt, unsigned int retcount);
-
-int
-rte_distributor_return_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt, int num);
-
-void
-rte_distributor_request_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **oldpkt,
- unsigned int count);
-
-int
-rte_distributor_poll_pkt_v1705(struct rte_distributor *d,
- unsigned int worker_id, struct rte_mbuf **mbufs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
--
2.22.0.windows.1
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH 6/8] lib: remove dead code from lpm
@ 2019-09-30 9:21 1% ` Marcin Baran
2019-09-30 9:21 2% ` [dpdk-dev] [PATCH 7/8] lib: remove dead code from distributor Marcin Baran
` (10 subsequent siblings)
12 siblings, 0 replies; 200+ results
From: Marcin Baran @ 2019-09-30 9:21 UTC (permalink / raw)
To: dev, bruce.richardson, ray.kinsella; +Cc: Marcin Baran
After updating ABI policy old and unused
code needs to be removed and all libraries
symbols version should be set to v20.
Signed-off-by: Marcin Baran <marcinx.baran@intel.com>
---
lib/librte_lpm/rte_lpm.c | 995 ++------------------------------------
lib/librte_lpm/rte_lpm.h | 88 ----
lib/librte_lpm/rte_lpm6.c | 128 +----
lib/librte_lpm/rte_lpm6.h | 25 -
4 files changed, 51 insertions(+), 1185 deletions(-)
diff --git a/lib/librte_lpm/rte_lpm.c b/lib/librte_lpm/rte_lpm.c
index ce4681b79..268756419 100644
--- a/lib/librte_lpm/rte_lpm.c
+++ b/lib/librte_lpm/rte_lpm.c
@@ -89,33 +89,8 @@ depth_to_range(uint8_t depth)
/*
* Find an existing lpm table and return a pointer to it.
*/
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name)
-{
- struct rte_lpm_v20 *l = NULL;
- struct rte_tailq_entry *te;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_read_lock();
- TAILQ_FOREACH(te, lpm_list, next) {
- l = te->data;
- if (strncmp(name, l->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
- rte_mcfg_tailq_read_unlock();
-
- if (te == NULL) {
- rte_errno = ENOENT;
- return NULL;
- }
-
- return l;
-}
-
struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name)
+rte_lpm_find_existing(const char *name)
{
struct rte_lpm *l = NULL;
struct rte_tailq_entry *te;
@@ -138,87 +113,12 @@ rte_lpm_find_existing_v1604(const char *name)
return l;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_find_existing, _v1604, 20.0);
-MAP_STATIC_SYMBOL(struct rte_lpm *rte_lpm_find_existing(const char *name),
- rte_lpm_find_existing_v1604);
/*
* Allocates memory for LPM object
*/
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules,
- __rte_unused int flags)
-{
- char mem_name[RTE_LPM_NAMESIZE];
- struct rte_lpm_v20 *lpm = NULL;
- struct rte_tailq_entry *te;
- uint32_t mem_size;
- struct rte_lpm_list *lpm_list;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- RTE_BUILD_BUG_ON(sizeof(struct rte_lpm_tbl_entry_v20) != 2);
-
- /* Check user arguments. */
- if ((name == NULL) || (socket_id < -1) || (max_rules == 0)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
- snprintf(mem_name, sizeof(mem_name), "LPM_%s", name);
-
- /* Determine the amount of memory to allocate. */
- mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
-
- rte_mcfg_tailq_write_lock();
-
- /* guarantee there's no existing */
- TAILQ_FOREACH(te, lpm_list, next) {
- lpm = te->data;
- if (strncmp(name, lpm->name, RTE_LPM_NAMESIZE) == 0)
- break;
- }
-
- if (te != NULL) {
- lpm = NULL;
- rte_errno = EEXIST;
- goto exit;
- }
-
- /* allocate tailq entry */
- te = rte_zmalloc("LPM_TAILQ_ENTRY", sizeof(*te), 0);
- if (te == NULL) {
- RTE_LOG(ERR, LPM, "Failed to allocate tailq entry\n");
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Allocate memory to store the LPM data structures. */
- lpm = rte_zmalloc_socket(mem_name, mem_size,
- RTE_CACHE_LINE_SIZE, socket_id);
- if (lpm == NULL) {
- RTE_LOG(ERR, LPM, "LPM memory allocation failed\n");
- rte_free(te);
- rte_errno = ENOMEM;
- goto exit;
- }
-
- /* Save user arguments. */
- lpm->max_rules = max_rules;
- strlcpy(lpm->name, name, sizeof(lpm->name));
-
- te->data = lpm;
-
- TAILQ_INSERT_TAIL(lpm_list, te, next);
-
-exit:
- rte_mcfg_tailq_write_unlock();
-
- return lpm;
-}
-
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
+rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config)
{
char mem_name[RTE_LPM_NAMESIZE];
@@ -318,44 +218,12 @@ rte_lpm_create_v1604(const char *name, int socket_id,
return lpm;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_create, _v1604, 20.0);
-MAP_STATIC_SYMBOL(
- struct rte_lpm *rte_lpm_create(const char *name, int socket_id,
- const struct rte_lpm_config *config), rte_lpm_create_v1604);
/*
* Deallocates memory for given LPM table.
*/
void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm)
-{
- struct rte_lpm_list *lpm_list;
- struct rte_tailq_entry *te;
-
- /* Check user arguments. */
- if (lpm == NULL)
- return;
-
- lpm_list = RTE_TAILQ_CAST(rte_lpm_tailq.head, rte_lpm_list);
-
- rte_mcfg_tailq_write_lock();
-
- /* find our tailq entry */
- TAILQ_FOREACH(te, lpm_list, next) {
- if (te->data == (void *) lpm)
- break;
- }
- if (te != NULL)
- TAILQ_REMOVE(lpm_list, te, next);
-
- rte_mcfg_tailq_write_unlock();
-
- rte_free(lpm);
- rte_free(te);
-}
-
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm)
+rte_lpm_free(struct rte_lpm *lpm)
{
struct rte_lpm_list *lpm_list;
struct rte_tailq_entry *te;
@@ -383,9 +251,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm)
rte_free(lpm);
rte_free(te);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_free, _v1604, 20.0);
-MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
- rte_lpm_free_v1604);
/*
* Adds a rule to the rule table.
@@ -398,79 +263,7 @@ MAP_STATIC_SYMBOL(void rte_lpm_free(struct rte_lpm *lpm),
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t rule_gindex, rule_index, last_rule;
- int i;
-
- VERIFY_DEPTH(depth);
-
- /* Scan through rule group to see if rule already exists. */
- if (lpm->rule_info[depth - 1].used_rules > 0) {
-
- /* rule_gindex stands for rule group index. */
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- /* Initialise rule_index to point to start of rule group. */
- rule_index = rule_gindex;
- /* Last rule = Last used rule in this rule group. */
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- for (; rule_index < last_rule; rule_index++) {
-
- /* If rule already exists update its next_hop and return. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked) {
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- return rule_index;
- }
- }
-
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
- } else {
- /* Calculate the position in which the rule will be stored. */
- rule_index = 0;
-
- for (i = depth - 1; i > 0; i--) {
- if (lpm->rule_info[i - 1].used_rules > 0) {
- rule_index = lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules;
- break;
- }
- }
- if (rule_index == lpm->max_rules)
- return -ENOSPC;
-
- lpm->rule_info[depth - 1].first_rule = rule_index;
- }
-
- /* Make room for the new rule in the array. */
- for (i = RTE_LPM_MAX_DEPTH; i > depth; i--) {
- if (lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules == lpm->max_rules)
- return -ENOSPC;
-
- if (lpm->rule_info[i - 1].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i - 1].first_rule
- + lpm->rule_info[i - 1].used_rules]
- = lpm->rules_tbl[lpm->rule_info[i - 1].first_rule];
- lpm->rule_info[i - 1].first_rule++;
- }
- }
-
- /* Add the new rule. */
- lpm->rules_tbl[rule_index].ip = ip_masked;
- lpm->rules_tbl[rule_index].next_hop = next_hop;
-
- /* Increment the used rules counter for this rule group. */
- lpm->rule_info[depth - 1].used_rules++;
-
- return rule_index;
-}
-
-static int32_t
-rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+rule_add(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
uint32_t rule_gindex, rule_index, last_rule;
@@ -546,30 +339,7 @@ rule_add_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static void
-rule_delete_v20(struct rte_lpm_v20 *lpm, int32_t rule_index, uint8_t depth)
-{
- int i;
-
- VERIFY_DEPTH(depth);
-
- lpm->rules_tbl[rule_index] =
- lpm->rules_tbl[lpm->rule_info[depth - 1].first_rule
- + lpm->rule_info[depth - 1].used_rules - 1];
-
- for (i = depth; i < RTE_LPM_MAX_DEPTH; i++) {
- if (lpm->rule_info[i].used_rules > 0) {
- lpm->rules_tbl[lpm->rule_info[i].first_rule - 1] =
- lpm->rules_tbl[lpm->rule_info[i].first_rule
- + lpm->rule_info[i].used_rules - 1];
- lpm->rule_info[i].first_rule--;
- }
- }
-
- lpm->rule_info[depth - 1].used_rules--;
-}
-
-static void
-rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
+rule_delete(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
{
int i;
@@ -596,28 +366,7 @@ rule_delete_v1604(struct rte_lpm *lpm, int32_t rule_index, uint8_t depth)
* NOTE: Valid range for depth parameter is 1 .. 32 inclusive.
*/
static int32_t
-rule_find_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth)
-{
- uint32_t rule_gindex, last_rule, rule_index;
-
- VERIFY_DEPTH(depth);
-
- rule_gindex = lpm->rule_info[depth - 1].first_rule;
- last_rule = rule_gindex + lpm->rule_info[depth - 1].used_rules;
-
- /* Scan used rules at given depth to find rule. */
- for (rule_index = rule_gindex; rule_index < last_rule; rule_index++) {
- /* If rule is found return the rule index. */
- if (lpm->rules_tbl[rule_index].ip == ip_masked)
- return rule_index;
- }
-
- /* If rule is not found return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
+rule_find(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
{
uint32_t rule_gindex, last_rule, rule_index;
@@ -641,42 +390,7 @@ rule_find_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth)
* Find, clean and allocate a tbl8.
*/
static int32_t
-tbl8_alloc_v20(struct rte_lpm_tbl_entry_v20 *tbl8)
-{
- uint32_t group_idx; /* tbl8 group index. */
- struct rte_lpm_tbl_entry_v20 *tbl8_entry;
-
- /* Scan through tbl8 to find a free (i.e. INVALID) tbl8 group. */
- for (group_idx = 0; group_idx < RTE_LPM_TBL8_NUM_GROUPS;
- group_idx++) {
- tbl8_entry = &tbl8[group_idx * RTE_LPM_TBL8_GROUP_NUM_ENTRIES];
- /* If a free tbl8 group is found clean it and set as VALID. */
- if (!tbl8_entry->valid_group) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = VALID,
- };
- new_tbl8_entry.next_hop = 0;
-
- memset(&tbl8_entry[0], 0,
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES *
- sizeof(tbl8_entry[0]));
-
- __atomic_store(tbl8_entry, &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- /* Return group index for allocated tbl8 group. */
- return group_idx;
- }
- }
-
- /* If there are no tbl8 groups free then return error. */
- return -ENOSPC;
-}
-
-static int32_t
-tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
+tbl8_alloc(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
{
uint32_t group_idx; /* tbl8 group index. */
struct rte_lpm_tbl_entry *tbl8_entry;
@@ -710,104 +424,18 @@ tbl8_alloc_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t number_tbl8s)
}
static void
-tbl8_free_v20(struct rte_lpm_tbl_entry_v20 *tbl8, uint32_t tbl8_group_start)
+tbl8_free(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
{
/* Set tbl8 group invalid*/
- struct rte_lpm_tbl_entry_v20 zero_tbl8_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = INVALID,
- };
- zero_tbl8_entry.next_hop = 0;
+ struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
__atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
__ATOMIC_RELAXED);
}
-static void
-tbl8_free_v1604(struct rte_lpm_tbl_entry *tbl8, uint32_t tbl8_group_start)
-{
- /* Set tbl8 group invalid*/
- struct rte_lpm_tbl_entry zero_tbl8_entry = {0};
-
- __atomic_store(&tbl8[tbl8_group_start], &zero_tbl8_entry,
- __ATOMIC_RELAXED);
-}
-
-static __rte_noinline int32_t
-add_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index, tbl24_range, tbl8_index, tbl8_group_end, i, j;
-
- /* Calculate the index into Table24. */
- tbl24_index = ip >> 8;
- tbl24_range = depth_to_range(depth);
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
- /*
- * For invalid OR valid and non-extended tbl 24 entries set
- * entry.
- */
- if (!lpm->tbl24[i].valid || (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth)) {
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .valid = VALID,
- .valid_group = 0,
- .depth = depth,
- };
- new_tbl24_entry.next_hop = next_hop;
-
- /* Setting tbl24 entry in one go to avoid race
- * conditions
- */
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- continue;
- }
-
- if (lpm->tbl24[i].valid_group == 1) {
- /* If tbl24 entry is valid and extended calculate the
- * index into tbl8.
- */
- tbl8_index = lpm->tbl24[i].group_idx *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < tbl8_group_end; j++) {
- if (!lpm->tbl8[j].valid ||
- lpm->tbl8[j].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = depth,
- };
- new_tbl8_entry.next_hop = next_hop;
-
- /*
- * Setting tbl8 entry in one go to avoid
- * race conditions
- */
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint32_t next_hop)
+static __rte_noinline int32_t
+add_depth_small(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+ uint32_t next_hop)
{
#define group_idx next_hop
uint32_t tbl24_index, tbl24_range, tbl8_index, tbl8_group_end, i, j;
@@ -878,150 +506,7 @@ add_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
static __rte_noinline int32_t
-add_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked, uint8_t depth,
- uint8_t next_hop)
-{
- uint32_t tbl24_index;
- int32_t tbl8_group_index, tbl8_group_start, tbl8_group_end, tbl8_index,
- tbl8_range, i;
-
- tbl24_index = (ip_masked >> 8);
- tbl8_range = depth_to_range(depth);
-
- if (!lpm->tbl24[tbl24_index].valid) {
- /* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- /* Check tbl8 allocation was successful. */
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- /* Find index into tbl8 and range. */
- tbl8_index = (tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES) +
- (ip_masked & 0xFF);
-
- /* Set tbl8 entry. */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } /* If valid entry but not extended calculate the index into Table8. */
- else if (lpm->tbl24[tbl24_index].valid_group == 0) {
- /* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v20(lpm->tbl8);
-
- if (tbl8_group_index < 0) {
- return tbl8_group_index;
- }
-
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_group_end = tbl8_group_start +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /* Populate new tbl8 with tbl24 value. */
- for (i = tbl8_group_start; i < tbl8_group_end; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = lpm->tbl24[tbl24_index].depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop =
- lpm->tbl24[tbl24_index].next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- /* Insert new rule into the tbl8 entry. */
- for (i = tbl8_index; i < tbl8_index + tbl8_range; i++) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
-
- /*
- * Update tbl24 entry to point to new tbl8 entry. Note: The
- * ext_flag and tbl8_index need to be updated simultaneously,
- * so assign whole structure in one go.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .group_idx = (uint8_t)tbl8_group_index,
- .valid = VALID,
- .valid_group = 1,
- .depth = 0,
- };
-
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELEASE);
-
- } else { /*
- * If it is valid, extended entry calculate the index into tbl8.
- */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
-
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
-
- if (!lpm->tbl8[i].valid ||
- lpm->tbl8[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = depth,
- .valid_group = lpm->tbl8[i].valid_group,
- };
- new_tbl8_entry.next_hop = next_hop;
- /*
- * Setting tbl8 entry in one go to avoid race
- * condition
- */
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
-
- continue;
- }
- }
- }
-
- return 0;
-}
-
-static __rte_noinline int32_t
-add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
+add_depth_big(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
uint32_t next_hop)
{
#define group_idx next_hop
@@ -1034,7 +519,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
if (!lpm->tbl24[tbl24_index].valid) {
/* Search for a free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
/* Check tbl8 allocation was successful. */
if (tbl8_group_index < 0) {
@@ -1080,7 +565,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
} /* If valid entry but not extended calculate the index into Table8. */
else if (lpm->tbl24[tbl24_index].valid_group == 0) {
/* Search for free tbl8 group. */
- tbl8_group_index = tbl8_alloc_v1604(lpm->tbl8, lpm->number_tbl8s);
+ tbl8_group_index = tbl8_alloc(lpm->tbl8, lpm->number_tbl8s);
if (tbl8_group_index < 0) {
return tbl8_group_index;
@@ -1174,47 +659,7 @@ add_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked, uint8_t depth,
* Add a route
*/
int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop)
-{
- int32_t rule_index, status = 0;
- uint32_t ip_masked;
-
- /* Check user arguments. */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- ip_masked = ip & depth_to_mask(depth);
-
- /* Add the rule to the rule table. */
- rule_index = rule_add_v20(lpm, ip_masked, depth, next_hop);
-
- /* If the is no space available for new rule return error. */
- if (rule_index < 0) {
- return rule_index;
- }
-
- if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v20(lpm, ip_masked, depth, next_hop);
- } else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v20(lpm, ip_masked, depth, next_hop);
-
- /*
- * If add fails due to exhaustion of tbl8 extensions delete
- * rule that was added to rule table.
- */
- if (status < 0) {
- rule_delete_v20(lpm, rule_index, depth);
-
- return status;
- }
- }
-
- return 0;
-}
-
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t next_hop)
{
int32_t rule_index, status = 0;
@@ -1227,7 +672,7 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
ip_masked = ip & depth_to_mask(depth);
/* Add the rule to the rule table. */
- rule_index = rule_add_v1604(lpm, ip_masked, depth, next_hop);
+ rule_index = rule_add(lpm, ip_masked, depth, next_hop);
/* If the is no space available for new rule return error. */
if (rule_index < 0) {
@@ -1235,16 +680,16 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
}
if (depth <= MAX_DEPTH_TBL24) {
- status = add_depth_small_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_small(lpm, ip_masked, depth, next_hop);
} else { /* If depth > RTE_LPM_MAX_DEPTH_TBL24 */
- status = add_depth_big_v1604(lpm, ip_masked, depth, next_hop);
+ status = add_depth_big(lpm, ip_masked, depth, next_hop);
/*
* If add fails due to exhaustion of tbl8 extensions delete
* rule that was added to rule table.
*/
if (status < 0) {
- rule_delete_v1604(lpm, rule_index, depth);
+ rule_delete(lpm, rule_index, depth);
return status;
}
@@ -1252,41 +697,12 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_add, _v1604, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm_add(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t next_hop), rte_lpm_add_v1604);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop)
-{
- uint32_t ip_masked;
- int32_t rule_index;
-
- /* Check user arguments. */
- if ((lpm == NULL) ||
- (next_hop == NULL) ||
- (depth < 1) || (depth > RTE_LPM_MAX_DEPTH))
- return -EINVAL;
-
- /* Look for the rule using rule_find. */
- ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v20(lpm, ip_masked, depth);
-
- if (rule_index >= 0) {
- *next_hop = lpm->rules_tbl[rule_index].next_hop;
- return 1;
- }
-
- /* If rule is not found return 0. */
- return 0;
-}
-
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
+rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop)
{
uint32_t ip_masked;
@@ -1300,7 +716,7 @@ uint32_t *next_hop)
/* Look for the rule using rule_find. */
ip_masked = ip & depth_to_mask(depth);
- rule_index = rule_find_v1604(lpm, ip_masked, depth);
+ rule_index = rule_find(lpm, ip_masked, depth);
if (rule_index >= 0) {
*next_hop = lpm->rules_tbl[rule_index].next_hop;
@@ -1310,12 +726,9 @@ uint32_t *next_hop)
/* If rule is not found return 0. */
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm_is_rule_present, _v1604, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth, uint32_t *next_hop), rte_lpm_is_rule_present_v1604);
static int32_t
-find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
+find_previous_rule(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint8_t *sub_rule_depth)
{
int32_t rule_index;
@@ -1325,7 +738,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
ip_masked = ip & depth_to_mask(prev_depth);
- rule_index = rule_find_v20(lpm, ip_masked, prev_depth);
+ rule_index = rule_find(lpm, ip_masked, prev_depth);
if (rule_index >= 0) {
*sub_rule_depth = prev_depth;
@@ -1337,133 +750,7 @@ find_previous_rule_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
}
static int32_t
-find_previous_rule_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint8_t *sub_rule_depth)
-{
- int32_t rule_index;
- uint32_t ip_masked;
- uint8_t prev_depth;
-
- for (prev_depth = (uint8_t)(depth - 1); prev_depth > 0; prev_depth--) {
- ip_masked = ip & depth_to_mask(prev_depth);
-
- rule_index = rule_find_v1604(lpm, ip_masked, prev_depth);
-
- if (rule_index >= 0) {
- *sub_rule_depth = prev_depth;
- return rule_index;
- }
- }
-
- return -1;
-}
-
-static int32_t
-delete_depth_small_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_range, tbl24_index, tbl8_group_index, tbl8_index, i, j;
-
- /* Calculate the range and index into Table24. */
- tbl24_range = depth_to_range(depth);
- tbl24_index = (ip_masked >> 8);
-
- /*
- * Firstly check the sub_rule_index. A -1 indicates no replacement rule
- * and a positive number indicates a sub_rule_index.
- */
- if (sub_rule_index < 0) {
- /*
- * If no replacement rule exists then invalidate entries
- * associated with this rule.
- */
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- struct rte_lpm_tbl_entry_v20
- zero_tbl24_entry = {
- .valid = INVALID,
- .depth = 0,
- .valid_group = 0,
- };
- zero_tbl24_entry.next_hop = 0;
- __atomic_store(&lpm->tbl24[i],
- &zero_tbl24_entry, __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- lpm->tbl8[j].valid = INVALID;
- }
- }
- }
- } else {
- /*
- * If a replacement rule exists then modify entries
- * associated with this rule.
- */
-
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->rules_tbl[sub_rule_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = sub_rule_depth,
- };
-
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .valid_group = VALID,
- .depth = sub_rule_depth,
- };
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
-
- for (i = tbl24_index; i < (tbl24_index + tbl24_range); i++) {
-
- if (lpm->tbl24[i].valid_group == 0 &&
- lpm->tbl24[i].depth <= depth) {
- __atomic_store(&lpm->tbl24[i], &new_tbl24_entry,
- __ATOMIC_RELEASE);
- } else if (lpm->tbl24[i].valid_group == 1) {
- /*
- * If TBL24 entry is extended, then there has
- * to be a rule with depth >= 25 in the
- * associated TBL8 group.
- */
-
- tbl8_group_index = lpm->tbl24[i].group_idx;
- tbl8_index = tbl8_group_index *
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- for (j = tbl8_index; j < (tbl8_index +
- RTE_LPM_TBL8_GROUP_NUM_ENTRIES); j++) {
-
- if (lpm->tbl8[j].depth <= depth)
- __atomic_store(&lpm->tbl8[j],
- &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
- }
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_small(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1570,54 +857,7 @@ delete_depth_small_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* thus can be recycled
*/
static int32_t
-tbl8_recycle_check_v20(struct rte_lpm_tbl_entry_v20 *tbl8,
- uint32_t tbl8_group_start)
-{
- uint32_t tbl8_group_end, i;
- tbl8_group_end = tbl8_group_start + RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
-
- /*
- * Check the first entry of the given tbl8. If it is invalid we know
- * this tbl8 does not contain any rule with a depth < RTE_LPM_MAX_DEPTH
- * (As they would affect all entries in a tbl8) and thus this table
- * can not be recycled.
- */
- if (tbl8[tbl8_group_start].valid) {
- /*
- * If first entry is valid check if the depth is less than 24
- * and if so check the rest of the entries to verify that they
- * are all of this depth.
- */
- if (tbl8[tbl8_group_start].depth <= MAX_DEPTH_TBL24) {
- for (i = (tbl8_group_start + 1); i < tbl8_group_end;
- i++) {
-
- if (tbl8[i].depth !=
- tbl8[tbl8_group_start].depth) {
-
- return -EEXIST;
- }
- }
- /* If all entries are the same return the tb8 index */
- return tbl8_group_start;
- }
-
- return -EEXIST;
- }
- /*
- * If the first entry is invalid check if the rest of the entries in
- * the tbl8 are invalid.
- */
- for (i = (tbl8_group_start + 1); i < tbl8_group_end; i++) {
- if (tbl8[i].valid)
- return -EEXIST;
- }
- /* If no valid entries are found then return -EINVAL. */
- return -EINVAL;
-}
-
-static int32_t
-tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
+tbl8_recycle_check(struct rte_lpm_tbl_entry *tbl8,
uint32_t tbl8_group_start)
{
uint32_t tbl8_group_end, i;
@@ -1664,93 +904,7 @@ tbl8_recycle_check_v1604(struct rte_lpm_tbl_entry *tbl8,
}
static int32_t
-delete_depth_big_v20(struct rte_lpm_v20 *lpm, uint32_t ip_masked,
- uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
-{
- uint32_t tbl24_index, tbl8_group_index, tbl8_group_start, tbl8_index,
- tbl8_range, i;
- int32_t tbl8_recycle_index;
-
- /*
- * Calculate the index into tbl24 and range. Note: All depths larger
- * than MAX_DEPTH_TBL24 are associated with only one tbl24 entry.
- */
- tbl24_index = ip_masked >> 8;
-
- /* Calculate the index into tbl8 and range. */
- tbl8_group_index = lpm->tbl24[tbl24_index].group_idx;
- tbl8_group_start = tbl8_group_index * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- tbl8_index = tbl8_group_start + (ip_masked & 0xFF);
- tbl8_range = depth_to_range(depth);
-
- if (sub_rule_index < 0) {
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be removed or modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- lpm->tbl8[i].valid = INVALID;
- }
- } else {
- /* Set new tbl8 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl8_entry = {
- .valid = VALID,
- .depth = sub_rule_depth,
- .valid_group = lpm->tbl8[tbl8_group_start].valid_group,
- };
-
- new_tbl8_entry.next_hop =
- lpm->rules_tbl[sub_rule_index].next_hop;
- /*
- * Loop through the range of entries on tbl8 for which the
- * rule_to_delete must be modified.
- */
- for (i = tbl8_index; i < (tbl8_index + tbl8_range); i++) {
- if (lpm->tbl8[i].depth <= depth)
- __atomic_store(&lpm->tbl8[i], &new_tbl8_entry,
- __ATOMIC_RELAXED);
- }
- }
-
- /*
- * Check if there are any valid entries in this tbl8 group. If all
- * tbl8 entries are invalid we can free the tbl8 and invalidate the
- * associated tbl24 entry.
- */
-
- tbl8_recycle_index = tbl8_recycle_check_v20(lpm->tbl8, tbl8_group_start);
-
- if (tbl8_recycle_index == -EINVAL) {
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- lpm->tbl24[tbl24_index].valid = 0;
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- } else if (tbl8_recycle_index > -1) {
- /* Update tbl24 entry. */
- struct rte_lpm_tbl_entry_v20 new_tbl24_entry = {
- .next_hop = lpm->tbl8[tbl8_recycle_index].next_hop,
- .valid = VALID,
- .valid_group = 0,
- .depth = lpm->tbl8[tbl8_recycle_index].depth,
- };
-
- /* Set tbl24 before freeing tbl8 to avoid race condition.
- * Prevent the free of the tbl8 group from hoisting.
- */
- __atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
- __ATOMIC_RELAXED);
- __atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v20(lpm->tbl8, tbl8_group_start);
- }
-
- return 0;
-}
-
-static int32_t
-delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
+delete_depth_big(struct rte_lpm *lpm, uint32_t ip_masked,
uint8_t depth, int32_t sub_rule_index, uint8_t sub_rule_depth)
{
#define group_idx next_hop
@@ -1805,7 +959,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* associated tbl24 entry.
*/
- tbl8_recycle_index = tbl8_recycle_check_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_recycle_index = tbl8_recycle_check(lpm->tbl8, tbl8_group_start);
if (tbl8_recycle_index == -EINVAL) {
/* Set tbl24 before freeing tbl8 to avoid race condition.
@@ -1813,7 +967,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
*/
lpm->tbl24[tbl24_index].valid = 0;
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
} else if (tbl8_recycle_index > -1) {
/* Update tbl24 entry. */
struct rte_lpm_tbl_entry new_tbl24_entry = {
@@ -1829,7 +983,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
__atomic_store(&lpm->tbl24[tbl24_index], &new_tbl24_entry,
__ATOMIC_RELAXED);
__atomic_thread_fence(__ATOMIC_RELEASE);
- tbl8_free_v1604(lpm->tbl8, tbl8_group_start);
+ tbl8_free(lpm->tbl8, tbl8_group_start);
}
#undef group_idx
return 0;
@@ -1839,60 +993,7 @@ delete_depth_big_v1604(struct rte_lpm *lpm, uint32_t ip_masked,
* Deletes a rule
*/
int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth)
-{
- int32_t rule_to_delete_index, sub_rule_index;
- uint32_t ip_masked;
- uint8_t sub_rule_depth;
- /*
- * Check input arguments. Note: IP must be a positive integer of 32
- * bits in length therefore it need not be checked.
- */
- if ((lpm == NULL) || (depth < 1) || (depth > RTE_LPM_MAX_DEPTH)) {
- return -EINVAL;
- }
-
- ip_masked = ip & depth_to_mask(depth);
-
- /*
- * Find the index of the input rule, that needs to be deleted, in the
- * rule table.
- */
- rule_to_delete_index = rule_find_v20(lpm, ip_masked, depth);
-
- /*
- * Check if rule_to_delete_index was found. If no rule was found the
- * function rule_find returns -EINVAL.
- */
- if (rule_to_delete_index < 0)
- return -EINVAL;
-
- /* Delete the rule from the rule table. */
- rule_delete_v20(lpm, rule_to_delete_index, depth);
-
- /*
- * Find rule to replace the rule_to_delete. If there is no rule to
- * replace the rule_to_delete we return -1 and invalidate the table
- * entries associated with this rule.
- */
- sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v20(lpm, ip, depth, &sub_rule_depth);
-
- /*
- * If the input depth value is less than 25 use function
- * delete_depth_small otherwise use delete_depth_big.
- */
- if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v20(lpm, ip_masked, depth,
- sub_rule_index, sub_rule_depth);
- } else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v20(lpm, ip_masked, depth, sub_rule_index,
- sub_rule_depth);
- }
-}
-
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
+rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
{
int32_t rule_to_delete_index, sub_rule_index;
uint32_t ip_masked;
@@ -1911,7 +1012,7 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
* Find the index of the input rule, that needs to be deleted, in the
* rule table.
*/
- rule_to_delete_index = rule_find_v1604(lpm, ip_masked, depth);
+ rule_to_delete_index = rule_find(lpm, ip_masked, depth);
/*
* Check if rule_to_delete_index was found. If no rule was found the
@@ -1921,7 +1022,7 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
return -EINVAL;
/* Delete the rule from the rule table. */
- rule_delete_v1604(lpm, rule_to_delete_index, depth);
+ rule_delete(lpm, rule_to_delete_index, depth);
/*
* Find rule to replace the rule_to_delete. If there is no rule to
@@ -1929,45 +1030,26 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth)
* entries associated with this rule.
*/
sub_rule_depth = 0;
- sub_rule_index = find_previous_rule_v1604(lpm, ip, depth, &sub_rule_depth);
+ sub_rule_index = find_previous_rule(lpm, ip, depth, &sub_rule_depth);
/*
* If the input depth value is less than 25 use function
* delete_depth_small otherwise use delete_depth_big.
*/
if (depth <= MAX_DEPTH_TBL24) {
- return delete_depth_small_v1604(lpm, ip_masked, depth,
+ return delete_depth_small(lpm, ip_masked, depth,
sub_rule_index, sub_rule_depth);
} else { /* If depth > MAX_DEPTH_TBL24 */
- return delete_depth_big_v1604(lpm, ip_masked, depth, sub_rule_index,
+ return delete_depth_big(lpm, ip_masked, depth, sub_rule_index,
sub_rule_depth);
}
}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete, _v1604, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip,
- uint8_t depth), rte_lpm_delete_v1604);
/*
* Delete all rules from the LPM table.
*/
void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm)
-{
- /* Zero rule information. */
- memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
-
- /* Zero tbl24. */
- memset(lpm->tbl24, 0, sizeof(lpm->tbl24));
-
- /* Zero tbl8. */
- memset(lpm->tbl8, 0, sizeof(lpm->tbl8));
-
- /* Delete all rules form the rules table. */
- memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
-}
-
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
+rte_lpm_delete_all(struct rte_lpm *lpm)
{
/* Zero rule information. */
memset(lpm->rule_info, 0, sizeof(lpm->rule_info));
@@ -1982,6 +1064,3 @@ rte_lpm_delete_all_v1604(struct rte_lpm *lpm)
/* Delete all rules form the rules table. */
memset(lpm->rules_tbl, 0, sizeof(lpm->rules_tbl[0]) * lpm->max_rules);
}
-BIND_DEFAULT_SYMBOL(rte_lpm_delete_all, _v1604, 20.0);
-MAP_STATIC_SYMBOL(void rte_lpm_delete_all(struct rte_lpm *lpm),
- rte_lpm_delete_all_v1604);
diff --git a/lib/librte_lpm/rte_lpm.h b/lib/librte_lpm/rte_lpm.h
index 906ec4483..ca9627a14 100644
--- a/lib/librte_lpm/rte_lpm.h
+++ b/lib/librte_lpm/rte_lpm.h
@@ -65,31 +65,6 @@ extern "C" {
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- /**
- * Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
- * a group index pointing to a tbl8 structure (tbl24 only, when
- * valid_group is set)
- */
- RTE_STD_C11
- union {
- uint8_t next_hop;
- uint8_t group_idx;
- };
- /* Using single uint8_t to store 3 values. */
- uint8_t valid :1; /**< Validation flag. */
- /**
- * For tbl24:
- * - valid_group == 0: entry stores a next hop
- * - valid_group == 1: entry stores a group_index pointing to a tbl8
- * For tbl8:
- * - valid_group indicates whether the current tbl8 is in use or not
- */
- uint8_t valid_group :1;
- uint8_t depth :6; /**< Rule depth. */
-} __rte_aligned(sizeof(uint16_t));
-
__extension__
struct rte_lpm_tbl_entry {
/**
@@ -112,16 +87,6 @@ struct rte_lpm_tbl_entry {
};
#else
-__extension__
-struct rte_lpm_tbl_entry_v20 {
- uint8_t depth :6;
- uint8_t valid_group :1;
- uint8_t valid :1;
- union {
- uint8_t group_idx;
- uint8_t next_hop;
- };
-} __rte_aligned(sizeof(uint16_t));
__extension__
struct rte_lpm_tbl_entry {
@@ -142,11 +107,6 @@ struct rte_lpm_config {
};
/** @internal Rule structure. */
-struct rte_lpm_rule_v20 {
- uint32_t ip; /**< Rule IP address. */
- uint8_t next_hop; /**< Rule next hop. */
-};
-
struct rte_lpm_rule {
uint32_t ip; /**< Rule IP address. */
uint32_t next_hop; /**< Rule next hop. */
@@ -159,21 +119,6 @@ struct rte_lpm_rule_info {
};
/** @internal LPM structure. */
-struct rte_lpm_v20 {
- /* LPM metadata. */
- char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
- uint32_t max_rules; /**< Max. balanced rules per lpm. */
- struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
-
- /* LPM Tables. */
- struct rte_lpm_tbl_entry_v20 tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry_v20 tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule_v20 rules_tbl[]
- __rte_cache_aligned; /**< LPM rules. */
-};
-
struct rte_lpm {
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
@@ -210,11 +155,6 @@ struct rte_lpm {
struct rte_lpm *
rte_lpm_create(const char *name, int socket_id,
const struct rte_lpm_config *config);
-struct rte_lpm_v20 *
-rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
-struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id,
- const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
@@ -228,10 +168,6 @@ rte_lpm_create_v1604(const char *name, int socket_id,
*/
struct rte_lpm *
rte_lpm_find_existing(const char *name);
-struct rte_lpm_v20 *
-rte_lpm_find_existing_v20(const char *name);
-struct rte_lpm *
-rte_lpm_find_existing_v1604(const char *name);
/**
* Free an LPM object.
@@ -243,10 +179,6 @@ rte_lpm_find_existing_v1604(const char *name);
*/
void
rte_lpm_free(struct rte_lpm *lpm);
-void
-rte_lpm_free_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_free_v1604(struct rte_lpm *lpm);
/**
* Add a rule to the LPM table.
@@ -264,12 +196,6 @@ rte_lpm_free_v1604(struct rte_lpm *lpm);
*/
int
rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop);
-int
-rte_lpm_add_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -289,12 +215,6 @@ rte_lpm_add_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
int
rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm_is_rule_present_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth,
-uint8_t *next_hop);
-int
-rte_lpm_is_rule_present_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth,
-uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -310,10 +230,6 @@ uint32_t *next_hop);
*/
int
rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v20(struct rte_lpm_v20 *lpm, uint32_t ip, uint8_t depth);
-int
-rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
/**
* Delete all rules from the LPM table.
@@ -323,10 +239,6 @@ rte_lpm_delete_v1604(struct rte_lpm *lpm, uint32_t ip, uint8_t depth);
*/
void
rte_lpm_delete_all(struct rte_lpm *lpm);
-void
-rte_lpm_delete_all_v20(struct rte_lpm_v20 *lpm);
-void
-rte_lpm_delete_all_v1604(struct rte_lpm *lpm);
/**
* Lookup an IP into the LPM table.
diff --git a/lib/librte_lpm/rte_lpm6.c b/lib/librte_lpm/rte_lpm6.c
index 44828f72c..b981e4071 100644
--- a/lib/librte_lpm/rte_lpm6.c
+++ b/lib/librte_lpm/rte_lpm6.c
@@ -808,17 +808,6 @@ add_step(struct rte_lpm6 *lpm, struct rte_lpm6_tbl_entry *tbl,
return 1;
}
-/*
- * Add a route
- */
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop)
-{
- return rte_lpm6_add_v1705(lpm, ip, depth, next_hop);
-}
-
-
/*
* Simulate adding a route to LPM
*
@@ -840,7 +829,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
/* Inspect the first three bytes through tbl24 on the first step. */
ret = simulate_add_step(lpm, lpm->tbl24, &tbl_next, masked_ip,
- ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
+ ADD_FIRST_BYTE, 1, depth, &need_tbl_nb);
total_need_tbl_nb = need_tbl_nb;
/*
* Inspect one by one the rest of the bytes until
@@ -849,7 +838,7 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && ret == 1; i++) {
tbl = tbl_next;
ret = simulate_add_step(lpm, tbl, &tbl_next, masked_ip, 1,
- (uint8_t)(i+1), depth, &need_tbl_nb);
+ (uint8_t)(i + 1), depth, &need_tbl_nb);
total_need_tbl_nb += need_tbl_nb;
}
@@ -860,9 +849,12 @@ simulate_add(struct rte_lpm6 *lpm, const uint8_t *masked_ip, uint8_t depth)
return 0;
}
+/*
+ * Add a route
+ */
int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop)
+rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+ uint32_t next_hop)
{
struct rte_lpm6_tbl_entry *tbl;
struct rte_lpm6_tbl_entry *tbl_next = NULL;
@@ -894,8 +886,8 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
/* Inspect the first three bytes through tbl24 on the first step. */
tbl = lpm->tbl24;
status = add_step(lpm, tbl, TBL24_IND, &tbl_next, &tbl_next_num,
- masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
- is_new_rule);
+ masked_ip, ADD_FIRST_BYTE, 1, depth, next_hop,
+ is_new_rule);
assert(status >= 0);
/*
@@ -905,17 +897,13 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
for (i = ADD_FIRST_BYTE; i < RTE_LPM6_IPV6_ADDR_SIZE && status == 1; i++) {
tbl = tbl_next;
status = add_step(lpm, tbl, tbl_next_num, &tbl_next,
- &tbl_next_num, masked_ip, 1, (uint8_t)(i+1),
- depth, next_hop, is_new_rule);
+ &tbl_next_num, masked_ip, 1, (uint8_t)(i + 1),
+ depth, next_hop, is_new_rule);
assert(status >= 0);
}
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_add, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip,
- uint8_t depth, uint32_t next_hop),
- rte_lpm6_add_v1705);
/*
* Takes a pointer to a table entry and inspect one level.
@@ -954,24 +942,7 @@ lookup_step(const struct rte_lpm6 *lpm, const struct rte_lpm6_tbl_entry *tbl,
* Looks up an IP
*/
int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_lookup_v1705(lpm, ip, &next_hop32);
- if (status == 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-}
-
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
+rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
uint32_t *next_hop)
{
const struct rte_lpm6_tbl_entry *tbl;
@@ -998,55 +969,12 @@ rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
return status;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop), rte_lpm6_lookup_v1705);
/*
* Looks up a group of IP addresses
*/
int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t * next_hops, unsigned n)
-{
- unsigned i;
- const struct rte_lpm6_tbl_entry *tbl;
- const struct rte_lpm6_tbl_entry *tbl_next = NULL;
- uint32_t tbl24_index, next_hop;
- uint8_t first_byte;
- int status;
-
- /* DEBUG: Check user input arguments. */
- if ((lpm == NULL) || (ips == NULL) || (next_hops == NULL))
- return -EINVAL;
-
- for (i = 0; i < n; i++) {
- first_byte = LOOKUP_FIRST_BYTE;
- tbl24_index = (ips[i][0] << BYTES2_SIZE) |
- (ips[i][1] << BYTE_SIZE) | ips[i][2];
-
- /* Calculate pointer to the first entry to be inspected */
- tbl = &lpm->tbl24[tbl24_index];
-
- do {
- /* Continue inspecting following levels until success or failure */
- status = lookup_step(lpm, tbl, &tbl_next, ips[i], first_byte++,
- &next_hop);
- tbl = tbl_next;
- } while (status == 1);
-
- if (status < 0)
- next_hops[i] = -1;
- else
- next_hops[i] = (int16_t)next_hop;
- }
-
- return 0;
-}
-
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
+rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n)
{
@@ -1086,36 +1014,12 @@ rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
return 0;
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_lookup_bulk_func, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n),
- rte_lpm6_lookup_bulk_func_v1705);
/*
* Look for a rule in the high-level rules table
*/
int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop)
-{
- uint32_t next_hop32 = 0;
- int32_t status;
-
- /* DEBUG: Check user input arguments. */
- if (next_hop == NULL)
- return -EINVAL;
-
- status = rte_lpm6_is_rule_present_v1705(lpm, ip, depth, &next_hop32);
- if (status > 0)
- *next_hop = (uint8_t)next_hop32;
-
- return status;
-
-}
-
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
+rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop)
{
uint8_t masked_ip[RTE_LPM6_IPV6_ADDR_SIZE];
@@ -1131,10 +1035,6 @@ rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
return rule_find(lpm, masked_ip, depth, next_hop);
}
-BIND_DEFAULT_SYMBOL(rte_lpm6_is_rule_present, _v1705, 20.0);
-MAP_STATIC_SYMBOL(int rte_lpm6_is_rule_present(struct rte_lpm6 *lpm,
- uint8_t *ip, uint8_t depth, uint32_t *next_hop),
- rte_lpm6_is_rule_present_v1705);
/*
* Delete a rule from the rule table.
diff --git a/lib/librte_lpm/rte_lpm6.h b/lib/librte_lpm/rte_lpm6.h
index 5d59ccb1f..37dfb2024 100644
--- a/lib/librte_lpm/rte_lpm6.h
+++ b/lib/librte_lpm/rte_lpm6.h
@@ -96,12 +96,6 @@ rte_lpm6_free(struct rte_lpm6 *lpm);
int
rte_lpm6_add(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t next_hop);
-int
-rte_lpm6_add_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t next_hop);
-int
-rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t next_hop);
/**
* Check if a rule is present in the LPM table,
@@ -121,12 +115,6 @@ rte_lpm6_add_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
int
rte_lpm6_is_rule_present(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
uint32_t *next_hop);
-int
-rte_lpm6_is_rule_present_v20(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint8_t *next_hop);
-int
-rte_lpm6_is_rule_present_v1705(struct rte_lpm6 *lpm, uint8_t *ip, uint8_t depth,
- uint32_t *next_hop);
/**
* Delete a rule from the LPM table.
@@ -184,11 +172,6 @@ rte_lpm6_delete_all(struct rte_lpm6 *lpm);
*/
int
rte_lpm6_lookup(const struct rte_lpm6 *lpm, uint8_t *ip, uint32_t *next_hop);
-int
-rte_lpm6_lookup_v20(const struct rte_lpm6 *lpm, uint8_t *ip, uint8_t *next_hop);
-int
-rte_lpm6_lookup_v1705(const struct rte_lpm6 *lpm, uint8_t *ip,
- uint32_t *next_hop);
/**
* Lookup multiple IP addresses in an LPM table.
@@ -210,14 +193,6 @@ int
rte_lpm6_lookup_bulk_func(const struct rte_lpm6 *lpm,
uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
int32_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v20(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int16_t *next_hops, unsigned int n);
-int
-rte_lpm6_lookup_bulk_func_v1705(const struct rte_lpm6 *lpm,
- uint8_t ips[][RTE_LPM6_IPV6_ADDR_SIZE],
- int32_t *next_hops, unsigned int n);
#ifdef __cplusplus
}
--
2.22.0.windows.1
^ permalink raw reply [relevance 1%]
Results 7201-7400 of ~18000 next (older) | prev (newer) | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2019-03-05 13:59 [dpdk-dev] [PATCH v3 0/6] introduce DMA memory mapping for external memory Shahaf Shuler
2019-03-10 8:27 ` [dpdk-dev] [PATCH v4 " Shahaf Shuler
2019-03-10 8:28 ` [dpdk-dev] [PATCH v4 6/6] doc: deprecation notice for VFIO DMA map APIs Shahaf Shuler
2019-10-01 15:20 3% ` David Marchand
2019-10-02 4:53 0% ` Shahaf Shuler
2019-10-02 7:51 0% ` David Marchand
2019-06-03 21:32 [dpdk-dev] [RFC 1/3] ethdev: extend flow metadata Yongseok Koh
2019-07-10 10:07 ` [dpdk-dev] [PATCH] " Olivier Matz
2019-07-10 12:01 ` Bruce Richardson
2019-07-10 12:26 ` Thomas Monjalon
2019-07-10 16:37 ` Yongseok Koh
2019-07-11 7:44 ` Adrien Mazarguil
2019-07-14 11:46 ` Andrew Rybchenko
2019-07-29 15:06 ` Adrien Mazarguil
2019-10-08 12:51 0% ` Yigit, Ferruh
2019-10-08 13:17 0% ` Slava Ovsiienko
2019-07-10 9:29 [dpdk-dev] [RFC] mbuf: support dynamic fields and flags Olivier Matz
2019-09-18 16:54 ` [dpdk-dev] [PATCH] " Olivier Matz
2019-10-01 10:49 0% ` Ananyev, Konstantin
2019-10-17 7:54 0% ` Olivier Matz
2019-10-17 11:58 0% ` Ananyev, Konstantin
2019-10-17 12:58 0% ` Olivier Matz
2019-10-17 14:42 3% ` [dpdk-dev] [PATCH v2] " Olivier Matz
2019-10-18 2:47 0% ` Wang, Haiyue
2019-10-18 7:53 0% ` Olivier Matz
2019-10-18 8:28 0% ` Wang, Haiyue
2019-10-18 9:47 0% ` Olivier Matz
2019-10-18 11:24 0% ` Wang, Haiyue
2019-10-22 22:51 0% ` Ananyev, Konstantin
2019-10-23 3:16 0% ` Wang, Haiyue
2019-10-23 10:21 0% ` Olivier Matz
2019-10-23 15:00 0% ` Stephen Hemminger
2019-10-23 10:19 0% ` Olivier Matz
2019-10-23 12:00 0% ` Shahaf Shuler
2019-10-23 13:33 0% ` Olivier Matz
2019-07-23 7:05 [dpdk-dev] [PATCH v8 1/3] eal/arm64: add 128-bit atomic compare exchange jerinj
2019-08-14 8:27 ` [dpdk-dev] [PATCH v9 " Phil Yang
2019-10-14 15:43 0% ` David Marchand
2019-10-15 11:32 ` Phil Yang (Arm Technology China)
2019-10-15 12:16 ` David Marchand
2019-10-16 9:04 4% ` Phil Yang (Arm Technology China)
2019-10-17 12:45 0% ` David Marchand
2019-10-15 11:38 2% ` [dpdk-dev] [PATCH v10 " Phil Yang
2019-10-18 11:21 4% ` [dpdk-dev] [PATCH v11 " Phil Yang
2019-08-22 8:42 [dpdk-dev] [PATCH v3] timer: use rte_mp_msg to get freq from primary process Jim Harris
2019-10-07 15:28 3% ` [dpdk-dev] [PATCH v6 RESEND] eal: add tsc_hz to rte_mem_config Jim Harris
2019-10-08 8:38 0% ` Bruce Richardson
2019-10-21 8:23 0% ` David Marchand
2019-08-29 7:47 [dpdk-dev] [RFC] ethdev: add new fields for max LRO session size Matan Azrad
2019-09-16 15:37 ` Ferruh Yigit
2019-09-24 12:03 ` Matan Azrad
2019-10-02 13:58 3% ` Thomas Monjalon
2019-10-18 16:35 0% ` Ferruh Yigit
2019-10-18 18:05 0% ` Ananyev, Konstantin
2019-10-22 12:56 0% ` Andrew Rybchenko
2019-09-03 15:40 [dpdk-dev] [RFC PATCH 0/9] security: add software synchronous crypto process Fan Zhang
2019-09-03 15:40 ` [dpdk-dev] [RFC PATCH 1/9] security: introduce CPU Crypto action type and API Fan Zhang
2019-09-04 10:32 ` Akhil Goyal
2019-09-04 13:06 ` Zhang, Roy Fan
2019-09-06 9:01 ` Akhil Goyal
2019-09-06 13:27 ` Ananyev, Konstantin
2019-09-10 10:44 ` Akhil Goyal
2019-09-11 12:29 ` Ananyev, Konstantin
2019-09-12 14:12 ` Akhil Goyal
2019-09-16 14:53 ` Ananyev, Konstantin
2019-09-17 6:02 ` Akhil Goyal
2019-09-18 7:44 ` Ananyev, Konstantin
2019-09-25 18:24 ` Ananyev, Konstantin
2019-09-27 9:26 ` Akhil Goyal
2019-09-30 12:22 0% ` Ananyev, Konstantin
2019-09-30 13:43 0% ` Akhil Goyal
2019-10-01 14:49 0% ` Ananyev, Konstantin
2019-10-03 13:24 0% ` Akhil Goyal
2019-10-07 12:53 0% ` Ananyev, Konstantin
2019-10-09 7:20 0% ` Akhil Goyal
2019-10-09 13:43 0% ` Ananyev, Konstantin
2019-10-11 13:23 0% ` Akhil Goyal
2019-10-13 23:07 0% ` Zhang, Roy Fan
2019-10-14 11:10 0% ` Ananyev, Konstantin
2019-10-16 22:07 3% ` Ananyev, Konstantin
2019-10-17 12:49 0% ` Ananyev, Konstantin
2019-10-18 13:17 4% ` Akhil Goyal
2019-10-21 13:47 4% ` Ananyev, Konstantin
2019-10-22 13:31 4% ` Akhil Goyal
2019-10-22 17:44 0% ` Ananyev, Konstantin
2019-10-22 22:21 0% ` Ananyev, Konstantin
2019-10-23 10:05 0% ` Akhil Goyal
2019-09-06 13:13 ` [dpdk-dev] [PATCH 00/10] security: add software synchronous crypto process Fan Zhang
2019-09-06 13:13 ` [dpdk-dev] [PATCH 01/10] security: introduce CPU Crypto action type and API Fan Zhang
2019-09-29 6:00 ` Hemant Agrawal
2019-09-29 16:59 ` Ananyev, Konstantin
2019-09-30 9:43 3% ` Hemant Agrawal
2019-10-01 15:27 4% ` Ananyev, Konstantin
2019-10-02 2:47 0% ` Hemant Agrawal
2019-09-06 9:45 [dpdk-dev] [PATCH v2 0/6] RCU integration with LPM library Ruifeng Wang
2019-10-01 6:29 ` [dpdk-dev] [PATCH v3 0/3] Add RCU reclamation APIs Honnappa Nagarahalli
2019-10-01 6:29 ` [dpdk-dev] [PATCH v3 2/3] lib/rcu: add resource " Honnappa Nagarahalli
2019-10-02 17:39 ` Ananyev, Konstantin
2019-10-03 6:29 ` Honnappa Nagarahalli
2019-10-03 12:26 ` Ananyev, Konstantin
2019-10-04 6:07 3% ` Honnappa Nagarahalli
2019-10-07 10:46 0% ` Ananyev, Konstantin
2019-10-13 4:35 0% ` Honnappa Nagarahalli
2019-10-01 18:28 ` [dpdk-dev] [PATCH v3 0/3] RCU integration with LPM library Honnappa Nagarahalli
2019-10-01 18:28 ` [dpdk-dev] [PATCH v3 1/3] lib/lpm: integrate RCU QSBR Honnappa Nagarahalli
2019-10-07 9:21 ` Ananyev, Konstantin
2019-10-13 4:36 3% ` Honnappa Nagarahalli
2019-10-15 11:15 0% ` Ananyev, Konstantin
2019-10-18 3:32 0% ` Honnappa Nagarahalli
2019-09-17 9:09 [dpdk-dev] [PATCH v2 1/3] net/ifcvf: add multiqueue configuration Andy Pei
2019-09-17 9:09 ` [dpdk-dev] [PATCH v2 2/3] vhost: call vDPA callback at the end of vring enable handler Andy Pei
2019-09-23 8:12 ` Tiwei Bie
2019-10-18 16:54 0% ` Ferruh Yigit
2019-09-19 16:36 [dpdk-dev] [PATCH v2 01/16] vhost: add single packet enqueue function Marvin Liu
2019-09-25 17:13 ` [dpdk-dev] [PATCH v3 00/15] vhost packed ring performance optimization Marvin Liu
2019-09-25 17:13 ` [dpdk-dev] [PATCH v3 13/15] vhost: cache address translation result Marvin Liu
2019-09-26 5:32 ` Tiwei Bie
2019-10-09 2:08 0% ` Liu, Yong
2019-10-09 13:38 3% ` [dpdk-dev] [PATCH v4 00/14] vhost packed ring performance optimization Marvin Liu
2019-10-15 14:30 3% ` [dpdk-dev] [PATCH v5 00/13] " Marvin Liu
2019-10-15 16:07 3% ` [dpdk-dev] [PATCH v6 " Marvin Liu
2019-10-17 7:31 0% ` Maxime Coquelin
2019-10-17 7:32 0% ` Liu, Yong
2019-10-21 15:40 3% ` [dpdk-dev] [PATCH v7 " Marvin Liu
2019-10-21 22:08 3% ` [dpdk-dev] [PATCH v8 " Marvin Liu
2019-09-25 14:26 [dpdk-dev] [PATCH v2 00/17] Add advanced features for Huawei hinic pmd Xiaoyun wang
2019-09-25 14:30 ` [dpdk-dev] [PATCH v2 15/17] net/hinic: add hinic PMD doc files Xiaoyun wang
2019-09-26 18:51 ` Ferruh Yigit
2019-09-30 14:15 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
2019-09-25 16:10 [dpdk-dev] [PATCH v7] eal: make lcore_config private Stephen Hemminger
2019-10-02 8:15 0% ` David Marchand
2019-10-02 19:40 13% ` [dpdk-dev] [PATCH v8] " Stephen Hemminger
2019-10-22 9:05 3% ` David Marchand
2019-10-22 16:30 0% ` Stephen Hemminger
2019-10-22 16:49 0% ` David Marchand
2019-09-26 6:28 [dpdk-dev] [PATCH 00/13] add hairpin feature Ori Kam
2019-09-26 6:28 ` [dpdk-dev] [PATCH 01/13] ethdev: support setup function for hairpin queue Ori Kam
2019-09-26 12:18 ` Andrew Rybchenko
[not found] ` <AM0PR0502MB4019A2FEADE5F9DCD0D9DDFED2860@AM0PR0502MB4019.eurprd05.prod.outlook.com>
2019-09-26 15:58 ` Ori Kam
2019-09-26 17:24 ` Andrew Rybchenko
2019-09-28 15:19 ` Ori Kam
2019-09-29 12:10 ` Andrew Rybchenko
2019-10-02 12:19 ` Ori Kam
2019-10-03 13:26 ` Andrew Rybchenko
2019-10-03 17:46 3% ` Ori Kam
2019-09-26 8:52 [dpdk-dev] [PATCH v3 00/15] sched: subport level configuration of pipe nodes Jasvinder Singh
2019-10-14 12:09 ` [dpdk-dev] [PATCH v4 00/17] " Jasvinder Singh
2019-10-14 12:09 2% ` [dpdk-dev] [PATCH v4 17/17] sched: modify internal structs and functions for 64 bit values Jasvinder Singh
2019-10-14 17:23 ` [dpdk-dev] [PATCH v5 00/15] sched: subport level configuration of pipe nodes Jasvinder Singh
2019-10-14 17:23 4% ` [dpdk-dev] [PATCH v5 15/15] sched: remove redundant code Jasvinder Singh
2019-09-27 16:54 [dpdk-dev] [PATCH v6 0/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-09-27 16:54 ` [dpdk-dev] [PATCH v6 1/4] doc: separate versioning.rst into version and policy Ray Kinsella
2019-10-01 12:50 3% ` Hemant Agrawal
2019-10-01 13:19 5% ` Ray Kinsella
2019-10-21 9:53 0% ` Thomas Monjalon
2019-09-27 16:54 ` [dpdk-dev] [PATCH v6 2/4] doc: changes to abi policy introducing major abi versions Ray Kinsella
2019-10-15 15:11 5% ` David Marchand
2019-10-21 9:50 5% ` [dpdk-dev] [PATCH v6 0/4] " Thomas Monjalon
2019-10-21 10:10 10% ` Ray Kinsella
2019-10-21 14:38 5% ` Thomas Monjalon
2019-10-22 8:12 5% ` Ray Kinsella
2019-09-27 19:49 [dpdk-dev] [PATCH 0/2] Improve function versioning meson support Bruce Richardson
2019-09-27 20:59 ` [dpdk-dev] [PATCH v2 " Bruce Richardson
2019-09-27 20:59 ` [dpdk-dev] [PATCH v2 2/2] build: support building ABI versioned files twice Bruce Richardson
2019-10-01 13:23 4% ` Andrzej Ostruszka
2019-10-01 16:53 4% ` Bruce Richardson
2019-10-07 15:57 4% ` Bruce Richardson
2019-10-07 15:45 3% ` [dpdk-dev] [PATCH v3 0/2] Improve function versioning meson support Bruce Richardson
2019-10-07 15:45 10% ` [dpdk-dev] [PATCH v3 1/2] eal: split compat header file Bruce Richardson
2019-10-07 15:45 15% ` [dpdk-dev] [PATCH v3 2/2] build: support building ABI versioned files twice Bruce Richardson
2019-10-09 22:59 0% ` [dpdk-dev] [PATCH 0/2] Improve function versioning meson support Stephen Hemminger
2019-09-28 0:37 [dpdk-dev] [PATCH 0/5] mbuf related patches Stephen Hemminger
2019-09-30 15:27 3% ` [dpdk-dev] [PATCH v2 0/6] mbuf copy related enhancements Stephen Hemminger
2019-09-30 19:20 3% ` [dpdk-dev] [PATCH v3 0/6] mbuf copy/cloning enhancements Stephen Hemminger
2019-10-04 21:47 3% ` [dpdk-dev] [PATCH v4 0/4] " Stephen Hemminger
2019-10-07 15:43 3% ` [dpdk-dev] [PATCH v5 0/5] " Stephen Hemminger
2019-10-08 16:33 3% ` [dpdk-dev] [PATCH v6 0/5] mbuf: " Stephen Hemminger
2019-09-30 9:21 [dpdk-dev] [PATCH 1/8] config: change ABI versioning for global Marcin Baran
2019-09-30 9:21 ` [dpdk-dev] [PATCH 3/8] buildtools: add ABI versioning check script Marcin Baran
2019-09-30 10:27 4% ` Bruce Richardson
2019-09-30 9:21 1% ` [dpdk-dev] [PATCH 6/8] lib: remove dead code from lpm Marcin Baran
2019-09-30 9:21 2% ` [dpdk-dev] [PATCH 7/8] lib: remove dead code from distributor Marcin Baran
2019-10-16 12:43 8% ` [dpdk-dev] [PATCH v2 00/10] Implement the new ABI policy and add helper scripts Anatoly Burakov
2019-10-16 17:03 8% ` [dpdk-dev] [PATCH v3 0/9] " Anatoly Burakov
2019-10-17 8:50 4% ` Bruce Richardson
2019-10-17 14:31 8% ` [dpdk-dev] [PATCH v4 00/10] " Anatoly Burakov
2019-10-17 14:31 7% ` [dpdk-dev] [PATCH v4 01/10] config: change ABI versioning to global Anatoly Burakov
2019-10-17 14:31 14% ` [dpdk-dev] [PATCH v4 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
2019-10-17 14:31 23% ` [dpdk-dev] [PATCH v4 03/10] buildtools: add ABI update shell script Anatoly Burakov
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 04/10] timer: remove deprecated code Anatoly Burakov
2019-10-17 21:04 0% ` Carrillo, Erik G
2019-10-21 13:24 3% ` Kevin Traynor
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 05/10] lpm: " Anatoly Burakov
2019-10-17 14:31 4% ` [dpdk-dev] [PATCH v4 06/10] distributor: " Anatoly Burakov
2019-10-17 15:59 0% ` Hunt, David
2019-10-17 14:31 6% ` [dpdk-dev] [PATCH v4 07/10] distributor: rename v2.0 ABI to _single suffix Anatoly Burakov
2019-10-17 16:00 4% ` Hunt, David
2019-10-17 14:31 3% ` [dpdk-dev] [PATCH v4 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
2019-10-17 14:31 2% ` [dpdk-dev] [PATCH v4 09/10] build: change ABI version to 20.0 Anatoly Burakov
2019-10-17 14:32 23% ` [dpdk-dev] [PATCH v4 10/10] buildtools: add ABI versioning check script Anatoly Burakov
2019-10-16 17:03 7% ` [dpdk-dev] [PATCH v3 1/9] config: change ABI versioning to global Anatoly Burakov
2019-10-17 8:44 9% ` Bruce Richardson
2019-10-17 10:25 4% ` Burakov, Anatoly
2019-10-17 14:09 8% ` Luca Boccassi
2019-10-17 14:12 4% ` Bruce Richardson
2019-10-18 10:07 7% ` Kevin Traynor
2019-10-16 17:03 14% ` [dpdk-dev] [PATCH v3 2/9] buildtools: add script for updating symbols abi version Anatoly Burakov
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 3/9] buildtools: add ABI update shell script Anatoly Burakov
2019-10-16 17:03 4% ` [dpdk-dev] [PATCH v3 4/9] timer: remove deprecated code Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 5/9] lpm: " Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 6/9] distributor: " Anatoly Burakov
2019-10-17 10:53 0% ` Hunt, David
2019-10-16 17:03 3% ` [dpdk-dev] [PATCH v3 7/9] drivers/octeontx: add missing public symbol Anatoly Burakov
2019-10-16 17:03 2% ` [dpdk-dev] [PATCH v3 8/9] build: change ABI version to 20.0 Anatoly Burakov
2019-10-16 17:03 23% ` [dpdk-dev] [PATCH v3 9/9] buildtools: add ABI versioning check script Anatoly Burakov
2019-10-16 12:43 7% ` [dpdk-dev] [PATCH v2 01/10] config: change ABI versioning for global Anatoly Burakov
2019-10-16 13:22 4% ` Bruce Richardson
2019-10-16 12:43 14% ` [dpdk-dev] [PATCH v2 02/10] buildtools: add script for updating symbols abi version Anatoly Burakov
2019-10-16 13:25 4% ` Bruce Richardson
2019-10-16 12:43 22% ` [dpdk-dev] [PATCH v2 03/10] buildtools: add ABI update shell script Anatoly Burakov
2019-10-16 13:33 4% ` Bruce Richardson
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 04/10] timer: remove deprecated code Anatoly Burakov
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 05/10] lpm: " Anatoly Burakov
2019-10-16 12:43 4% ` [dpdk-dev] [PATCH v2 06/10] distributor: " Anatoly Burakov
2019-10-16 12:43 3% ` [dpdk-dev] [PATCH v2 08/10] drivers/octeontx: add missing public symbol Anatoly Burakov
2019-10-16 12:43 2% ` [dpdk-dev] [PATCH v2 09/10] build: change ABI version to 20.0 Anatoly Burakov
2019-10-16 12:43 23% ` [dpdk-dev] [PATCH v2 10/10] buildtools: add ABI versioning check script Anatoly Burakov
2019-09-30 14:00 3% [dpdk-dev] [PATCH v3 00/19] Add advanced features for Huawei hinic pmd Xiaoyun wang
2019-09-30 15:06 0% ` Ferruh Yigit
2019-10-08 15:14 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
2019-10-08 15:33 0% ` Ferruh Yigit
2019-10-11 2:50 0% ` Wangxiaoyun (Cloud, Network Chip Application Development Dept)
2019-10-01 6:46 [dpdk-dev] [PATCH] eventdev: flag to identify same destined packets enqueue Nipun Gupta
2019-10-01 7:44 4% ` Jerin Jacob
2019-10-01 11:41 0% ` Nipun Gupta
2019-10-01 13:09 0% ` Jerin Jacob
2019-10-01 14:02 0% ` Nipun Gupta
2019-10-01 14:20 3% ` Jerin Jacob
2019-10-01 15:06 0% ` Nipun Gupta
2019-10-01 15:35 4% ` Jerin Jacob
2019-10-02 3:08 0% ` Hemant Agrawal
2019-10-02 7:54 0% ` Jerin Jacob
2019-10-03 6:12 0% ` Rao, Nikhil
2019-10-03 6:45 0% ` Hemant Agrawal
2019-10-03 10:26 0% ` Jerin Jacob
2019-10-01 14:42 3% ` Aaron Conole
2019-10-01 15:15 3% ` Nipun Gupta
2019-10-04 6:55 ` [dpdk-dev] [PATCH v2] " Nipun Gupta
2019-10-04 8:21 4% ` Jerin Jacob
2019-10-04 10:47 2% ` [dpdk-dev] [PATCH v3] " Nipun Gupta
2019-10-05 16:23 0% ` Jerin Jacob
2019-10-09 7:32 6% ` [dpdk-dev] [PATCH v4] " Nipun Gupta
2019-10-11 13:03 6% ` [dpdk-dev] [PATCH v5] " Nipun Gupta
2019-10-03 22:57 [dpdk-dev] [PATCH] crypto/armv8: enable meson build Dharmik Thakkar
2019-10-05 15:28 ` Jerin Jacob
2019-10-06 18:06 ` Thomas Monjalon
2019-10-07 10:19 ` Jerin Jacob
2019-10-08 7:18 ` Jerin Jacob
2019-10-10 4:46 ` Honnappa Nagarahalli
2019-10-10 5:24 ` Jerin Jacob
2019-10-11 19:13 2% ` Honnappa Nagarahalli
2019-10-11 20:02 0% ` Jerin Jacob
2019-10-11 20:14 2% ` Honnappa Nagarahalli
2019-10-11 20:33 0% ` Jerin Jacob
2019-10-10 7:35 4% [dpdk-dev] DPDK techboard minutes of October 9 Ferruh Yigit
2019-10-10 10:06 4% [dpdk-dev] DPDK Release Status Meeting 10/10/2019 Ferruh Yigit
2019-10-10 10:46 4% [dpdk-dev] [PATCH] ether: remove packing and set two-byte alignment Bruce Richardson
2019-10-10 14:51 3% [dpdk-dev] [PATCH v4 00/19] Add advanced features for Huawei hinic pmd Xiaoyun wang
2019-10-11 9:26 0% ` Ferruh Yigit
2019-10-14 17:24 [dpdk-dev] [PATCH 1/2] sched: add support for 64 bit values Jasvinder Singh
2019-10-14 17:24 ` [dpdk-dev] [PATCH 2/2] sched: modify internal structs and functions " Jasvinder Singh
2019-10-15 15:47 4% ` Dumitrescu, Cristian
2019-10-15 16:01 0% ` Singh, Jasvinder
2019-10-17 9:59 3% [dpdk-dev] DPDK Release Status Meeting 17/10/2019 Ferruh Yigit
2019-10-22 9:32 8% [dpdk-dev] [PATCH 0/8] EAL and PCI ABI changes for 19.11 David Marchand
2019-10-22 9:32 12% ` [dpdk-dev] [PATCH 1/8] eal: make lcore config private David Marchand
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 2/8] eal: remove deprecated CPU flags check function David Marchand
2019-10-22 9:32 5% ` [dpdk-dev] [PATCH 3/8] eal: remove deprecated malloc virt2phys function David Marchand
2019-10-22 9:32 4% ` [dpdk-dev] [PATCH 6/8] pci: remove deprecated functions David Marchand
2019-10-22 9:32 3% ` [dpdk-dev] [PATCH 8/8] log: hide internal log structure David Marchand
2019-10-22 16:35 0% ` Stephen Hemminger
2019-10-23 13:02 0% ` David Marchand
2019-10-23 1:07 9% [dpdk-dev] [RFC 0/6] Add ABI compatibility checks to the meson build Kevin Laatz
2019-10-23 1:07 3% ` [dpdk-dev] [RFC 1/6] build: enable debug info by default in meson builds Kevin Laatz
2019-10-23 1:07 22% ` [dpdk-dev] [RFC 3/6] devtools: add abi dump generation script Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 4/6] build: add meson option for abi related checks Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 5/6] build: add lib abi checks to meson Kevin Laatz
2019-10-23 1:07 14% ` [dpdk-dev] [RFC 6/6] build: add drivers " Kevin Laatz
2019-10-23 8:51 [dpdk-dev] [PATCH 0/3] net definitions fixes David Marchand
2019-10-23 12:12 ` Ferruh Yigit
2019-10-23 12:57 3% ` David Marchand
2019-10-23 13:00 0% ` David Marchand
2019-10-23 13:19 0% ` Ferruh Yigit
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).